diff options
author | joe <joe@jerkface.net> | 2018-06-18 06:14:11 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-06-18 06:14:11 -0400 |
commit | 19364a287f7083fc60beed2d6eae3dd71d27e737 (patch) | |
tree | bb784eeb3c8acb25fd8b656142d92aac2dd096ca /ToxToXMPP.hs | |
parent | 2dbb1e710d6d58fc00126d84763ec3597d92437d (diff) |
tox: Automatically share dhtkey with roster contacts.
Diffstat (limited to 'ToxToXMPP.hs')
-rw-r--r-- | ToxToXMPP.hs | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/ToxToXMPP.hs b/ToxToXMPP.hs index edbf35ca..ac24ce6d 100644 --- a/ToxToXMPP.hs +++ b/ToxToXMPP.hs | |||
@@ -1,5 +1,6 @@ | |||
1 | {-# LANGUAGE CPP #-} | 1 | {-# LANGUAGE CPP #-} |
2 | {-# LANGUAGE LambdaCase #-} | 2 | {-# LANGUAGE LambdaCase #-} |
3 | {-# LANGUAGE NamedFieldPuns #-} | ||
3 | module ToxToXMPP where | 4 | module ToxToXMPP where |
4 | 5 | ||
5 | import Data.Conduit as C | 6 | import Data.Conduit as C |
@@ -9,23 +10,52 @@ import Network.Tox.Crypto.Transport as Tox | |||
9 | import XMPPServer as XMPP | 10 | import XMPPServer as XMPP |
10 | import EventUtil | 11 | import EventUtil |
11 | 12 | ||
13 | import Announcer | ||
14 | import Announcer.Tox | ||
15 | import Connection | ||
16 | import Network.QueryResponse | ||
17 | -- import Control.Concurrent | ||
18 | import Control.Concurrent.STM | ||
19 | import Control.Monad | ||
20 | import Crypto.Tox | ||
21 | import qualified Data.HashMap.Strict as HashMap | ||
22 | import Data.Maybe | ||
23 | import qualified Data.Set as Set | ||
24 | import qualified Data.Text as T | ||
25 | import Data.Time.Clock.POSIX | ||
26 | import Network.Address | ||
27 | import Network.Kademlia.Search | ||
28 | import qualified Network.Tox as Tox | ||
29 | import Network.Tox.ContactInfo as Tox | ||
30 | import qualified Network.Tox.Crypto.Handlers as Tox | ||
31 | -- import qualified Network.Tox.DHT.Handlers as Tox | ||
32 | import Announcer | ||
12 | import ClientState | 33 | import ClientState |
13 | import Control.Concurrent.STM | 34 | import Control.Concurrent.STM |
14 | import Control.Monad | 35 | import Control.Monad |
15 | import Crypto.Tox | 36 | import Crypto.Tox |
16 | import Data.Bits | 37 | import Data.Bits |
17 | import Data.Function | 38 | import Data.Function |
18 | import qualified Data.Map as Map | 39 | import qualified Data.Map as Map |
19 | import qualified Data.Set as Set | 40 | import qualified Data.Set as Set |
20 | import qualified Data.Text as T | 41 | import qualified Data.Text as T |
21 | ;import Data.Text (Text) | 42 | ;import Data.Text (Text) |
22 | import Data.Word | 43 | import Data.Word |
44 | import qualified Network.Kademlia.Routing as R | ||
23 | import Network.Tox | 45 | import Network.Tox |
24 | import Network.Tox.ContactInfo | 46 | import Network.Tox.ContactInfo |
25 | import Network.Tox.DHT.Transport (FriendRequest (..)) | 47 | import Network.Tox.DHT.Handlers |
48 | import qualified Network.Tox.DHT.Transport as Tox | ||
49 | ;import Network.Tox.DHT.Transport (FriendRequest (..)) | ||
26 | import Network.Tox.NodeId | 50 | import Network.Tox.NodeId |
27 | import Network.Tox.Onion.Transport (OnionData (..)) | 51 | import qualified Network.Tox.Onion.Handlers as Tox |
52 | import qualified Network.Tox.Onion.Transport as Tox | ||
53 | ;import Network.Tox.Onion.Transport (OnionData (..)) | ||
54 | import Presence | ||
28 | import Presence | 55 | import Presence |
56 | import System.IO | ||
57 | import Text.Read | ||
58 | import XMPPServer (ConnectionKey) | ||
29 | #ifdef THREAD_DEBUG | 59 | #ifdef THREAD_DEBUG |
30 | import Control.Concurrent.Lifted.Instrument | 60 | import Control.Concurrent.Lifted.Instrument |
31 | #else | 61 | #else |
@@ -93,8 +123,13 @@ dispatch acnt st (OnionRouted theirkey (OnionFriendRequest fr) ) = do | |||
93 | -- embed it in the stanza as a <status> element. | 123 | -- embed it in the stanza as a <status> element. |
94 | sendModifiedStanzaToClient ask (connChan conn) | 124 | sendModifiedStanzaToClient ask (connChan conn) |
95 | 125 | ||
96 | forkAccountWatcher :: Account -> Tox -> PresenceState -> IO ThreadId | 126 | interweave :: [a] -> [a] -> [a] |
97 | forkAccountWatcher acc tox st = forkIO $ do | 127 | interweave [] ys = ys |
128 | interweave (x:xs) ys = x : interweave ys xs | ||
129 | |||
130 | |||
131 | forkAccountWatcher :: Account -> Tox -> PresenceState -> Announcer -> IO ThreadId | ||
132 | forkAccountWatcher acc tox st announcer = forkIO $ do | ||
98 | myThreadId >>= flip labelThread ("tox-xmpp:" | 133 | myThreadId >>= flip labelThread ("tox-xmpp:" |
99 | ++ show (key2id $ toPublic $ userSecret acc)) | 134 | ++ show (key2id $ toPublic $ userSecret acc)) |
100 | (chan,contacts) <- atomically $ do | 135 | (chan,contacts) <- atomically $ do |
@@ -103,6 +138,49 @@ forkAccountWatcher acc tox st = forkIO $ do | |||
103 | return (chan,contacts) | 138 | return (chan,contacts) |
104 | -- TODO: process information in contacts HashMap. | 139 | -- TODO: process information in contacts HashMap. |
105 | 140 | ||
141 | let nearNodes nid = do | ||
142 | bkts4 <- readTVar $ routing4 $ toxRouting tox | ||
143 | bkts6 <- readTVar $ routing6 $ toxRouting tox | ||
144 | let nss = map (R.kclosest (searchSpace (toxQSearch tox)) searchK nid) | ||
145 | [bkts4,bkts6] | ||
146 | return $ foldr interweave [] nss | ||
147 | |||
148 | |||
149 | forM_ (HashMap.toList contacts) $ \(them,Contact{contactPolicy}) -> do | ||
150 | wanted <- atomically $ (==Just TryingToConnect) <$> readTVar contactPolicy | ||
151 | when wanted $ do | ||
152 | let pub = toPublic $ userSecret acc | ||
153 | akey <- atomically $ packAnnounceKey announcer $ "dhtkey:" ++ show them | ||
154 | -- We send this packet every 30 seconds if there is more | ||
155 | -- than one peer (in the 8) that says they our friend is | ||
156 | -- announced on them. This packet can also be sent through | ||
157 | -- the DHT module as a DHT request packet (see DHT) if we | ||
158 | -- know the DHT public key of the friend and are looking | ||
159 | -- for them in the DHT but have not connected to them yet. | ||
160 | -- 30 second is a reasonable timeout to not flood the | ||
161 | -- network with too many packets while making sure the | ||
162 | -- other will eventually receive the packet. Since packets | ||
163 | -- are sent through every peer that knows the friend, | ||
164 | -- resending it right away without waiting has a high | ||
165 | -- likelihood of failure as the chances of packet loss | ||
166 | -- happening to all (up to to 8) packets sent is low. | ||
167 | -- | ||
168 | schedule announcer | ||
169 | akey | ||
170 | (AnnounceMethod (toxQSearch tox) | ||
171 | (Left $ \theirkey rendezvous -> do | ||
172 | dkey <- Tox.getContactInfo tox | ||
173 | sendMessage | ||
174 | (Tox.toxToRoute tox) | ||
175 | (Tox.AnnouncedRendezvous theirkey rendezvous) | ||
176 | (pub,Tox.OnionDHTPublicKey dkey)) | ||
177 | nearNodes | ||
178 | them | ||
179 | 30) -- every 30 seconds | ||
180 | pub | ||
181 | |||
182 | |||
183 | |||
106 | -- Loop endlessly until clientRefs is null. | 184 | -- Loop endlessly until clientRefs is null. |
107 | fix $ \loop -> do | 185 | fix $ \loop -> do |
108 | mev <- atomically $ | 186 | mev <- atomically $ |
@@ -113,3 +191,9 @@ forkAccountWatcher acc tox st = forkIO $ do | |||
113 | return Nothing | 191 | return Nothing |
114 | forM_ mev $ \ev -> dispatch acc st ev >> loop | 192 | forM_ mev $ \ev -> dispatch acc st ev >> loop |
115 | 193 | ||
194 | toxQSearch :: Tox.Tox -> Search Tox.NodeId (IP, PortNumber) Nonce32 Tox.NodeInfo Tox.Rendezvous | ||
195 | toxQSearch tox = Tox.toxidSearch (Tox.onionTimeout tox) (Tox.toxCryptoKeys tox) (Tox.toxOnion tox) | ||
196 | |||
197 | toxAnnounceInterval :: POSIXTime | ||
198 | toxAnnounceInterval = 15 | ||
199 | |||