summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ToxToXMPP.hs91
1 files changed, 61 insertions, 30 deletions
diff --git a/ToxToXMPP.hs b/ToxToXMPP.hs
index d6a31f1e..cc3b929d 100644
--- a/ToxToXMPP.hs
+++ b/ToxToXMPP.hs
@@ -100,13 +100,23 @@ key2jid nospam key = T.pack $ show $ NoSpamId nsp key
100 nlo = fromIntegral (0x0FFFF .&. nospam) :: Word16 100 nlo = fromIntegral (0x0FFFF .&. nospam) :: Word16
101 nhi = fromIntegral (0x0FFFF .&. (nospam `shiftR` 16)) :: Word16 101 nhi = fromIntegral (0x0FFFF .&. (nospam `shiftR` 16)) :: Word16
102 102
103dispatch :: Announcer -> Account -> PresenceState -> ContactEvent -> IO () 103data ToxToXMPP = ToxToXMPP
104dispatch acr acnt st (SessionEstablished theirKey) = return () 104 { txAnnouncer :: Announcer
105dispatch acr acnt st (SessionTerminated theirKey) = return () 105 , txAccount :: Account
106dispatch acr acnt st (AddrChange theirkey saddr) = return () -- todo 106 , txPresence :: PresenceState
107dispatch acr acnt st (PolicyChange theirkey policy ) = return () -- todo 107 , txTox :: Tox
108dispatch acr acnt st (OnionRouted theirkey (OnionDHTPublicKey pkey)) = return () -- todo 108 }
109dispatch acr acnt st (OnionRouted theirkey (OnionFriendRequest fr) ) = do 109
110dispatch :: ToxToXMPP -> ContactEvent -> IO ()
111dispatch tx (SessionEstablished theirKey) = stopConnecting tx theirKey
112dispatch tx (SessionTerminated theirKey) = startConnecting tx theirKey
113dispatch tx (AddrChange theirkey saddr) = return () -- todo
114dispatch tx (PolicyChange theirkey policy ) = return () -- todo
115dispatch tx (OnionRouted theirkey (OnionDHTPublicKey pkey)) = return () -- todo
116dispatch tx (OnionRouted theirkey (OnionFriendRequest fr) ) = do
117 let ToxToXMPP { txAnnouncer = acr
118 , txAccount = acnt
119 , txPresence = st } = tx
110 k2c <- atomically $ do 120 k2c <- atomically $ do
111 refs <- readTVar (clientRefs acnt) 121 refs <- readTVar (clientRefs acnt)
112 k2c <- Map.filterWithKey (\k _ -> k `Set.member` refs) <$> readTVar (keyToChan st) 122 k2c <- Map.filterWithKey (\k _ -> k `Set.member` refs) <$> readTVar (keyToChan st)
@@ -134,28 +144,20 @@ akeyDHTKeyShare announcer me them = atomically $ do
134akeyConnect announcer me them = atomically $ do 144akeyConnect announcer me them = atomically $ do
135 packAnnounceKey announcer $ "connect:" ++ (take 8 $ show me) ++ ":" ++ show them 145 packAnnounceKey announcer $ "connect:" ++ (take 8 $ show me) ++ ":" ++ show them
136 146
137forkAccountWatcher :: Account -> Tox -> PresenceState -> Announcer -> IO ThreadId 147startConnecting0 :: ToxToXMPP -> PublicKey -> Contact -> IO ()
138forkAccountWatcher acc tox st announcer = forkIO $ do 148startConnecting0 tx them contact = do
139 myThreadId >>= flip labelThread ("tox-xmpp:" 149 let ToxToXMPP { txTox = tox
140 ++ show (key2id $ toPublic $ userSecret acc)) 150 , txAnnouncer = announcer
141 (chan,contacts) <- atomically $ do 151 , txAccount = acnt } = tx
142 chan <- dupTChan $ eventChan acc -- duplicate broadcast channel for reading. 152 let nearNodes nid = do
143 contacts <- readTVar (contacts acc) 153 bkts4 <- readTVar $ routing4 $ toxRouting tox
144 return (chan,contacts) 154 bkts6 <- readTVar $ routing6 $ toxRouting tox
145 -- TODO: process information in contacts HashMap. 155 let nss = map (R.kclosest (searchSpace (toxQSearch tox)) searchK nid)
146 156 [bkts4,bkts6]
147 let nearNodes nid = do 157 return $ foldr interweave [] nss
148 bkts4 <- readTVar $ routing4 $ toxRouting tox 158 wanted <- atomically $ (==Just TryingToConnect) <$> readTVar (contactPolicy contact)
149 bkts6 <- readTVar $ routing6 $ toxRouting tox
150 let nss = map (R.kclosest (searchSpace (toxQSearch tox)) searchK nid)
151 [bkts4,bkts6]
152 return $ foldr interweave [] nss
153
154
155 forM_ (HashMap.toList contacts) $ \(them,Contact{contactPolicy}) -> do
156 wanted <- atomically $ (==Just TryingToConnect) <$> readTVar contactPolicy
157 when wanted $ do 159 when wanted $ do
158 let pub = toPublic $ userSecret acc 160 let pub = toPublic $ userSecret acnt
159 me = key2id pub 161 me = key2id pub
160 akey <- akeyDHTKeyShare announcer me them 162 akey <- akeyDHTKeyShare announcer me them
161 -- We send this packet every 30 seconds if there is more 163 -- We send this packet every 30 seconds if there is more
@@ -183,12 +185,40 @@ forkAccountWatcher acc tox st announcer = forkIO $ do
183 (Tox.AnnouncedRendezvous theirkey rendezvous) 185 (Tox.AnnouncedRendezvous theirkey rendezvous)
184 (pub,Tox.OnionDHTPublicKey dkey)) 186 (pub,Tox.OnionDHTPublicKey dkey))
185 nearNodes 187 nearNodes
186 them 188 (key2id them)
187 30) -- every 30 seconds 189 30) -- every 30 seconds
188 pub 190 pub
189 191
192startConnecting :: ToxToXMPP -> PublicKey -> IO ()
193startConnecting tx them = do
194 mc <- atomically $ HashMap.lookup (key2id them)
195 <$> readTVar (contacts $ txAccount tx)
196 forM_ mc $ startConnecting0 tx them
190 197
191 198
199stopConnecting :: ToxToXMPP -> PublicKey -> IO ()
200stopConnecting ToxToXMPP{txAnnouncer=announcer,txAccount=acnt} them = do
201 let pub = toPublic $ userSecret acnt
202 me = key2id pub
203 akey <- akeyDHTKeyShare announcer me them
204 cancel announcer akey
205
206forkAccountWatcher :: Account -> Tox -> PresenceState -> Announcer -> IO ThreadId
207forkAccountWatcher acc tox st announcer = forkIO $ do
208 myThreadId >>= flip labelThread ("tox-xmpp:"
209 ++ show (key2id $ toPublic $ userSecret acc))
210 (chan,contacts) <- atomically $ do
211 chan <- dupTChan $ eventChan acc -- duplicate broadcast channel for reading.
212 contacts <- readTVar (contacts acc)
213 return (chan,contacts)
214 let tx = ToxToXMPP { txAnnouncer = announcer
215 , txAccount = acc
216 , txPresence = st
217 , txTox = tox
218 }
219 forM_ (HashMap.toList contacts) $ \(them,c) -> do
220 startConnecting0 tx (id2key them) c
221
192 -- Loop endlessly until clientRefs is null. 222 -- Loop endlessly until clientRefs is null.
193 fix $ \loop -> do 223 fix $ \loop -> do
194 mev <- atomically $ 224 mev <- atomically $
@@ -197,7 +227,8 @@ forkAccountWatcher acc tox st announcer = forkIO $ do
197 refs <- readTVar $ clientRefs acc 227 refs <- readTVar $ clientRefs acc
198 check $ Set.null refs 228 check $ Set.null refs
199 return Nothing 229 return Nothing
200 forM_ mev $ \ev -> dispatch announcer acc st ev >> loop 230
231 forM_ mev $ \ev -> dispatch tx ev >> loop
201 232
202toxQSearch :: Tox.Tox -> Search Tox.NodeId (IP, PortNumber) Nonce32 Tox.NodeInfo Tox.Rendezvous 233toxQSearch :: Tox.Tox -> Search Tox.NodeId (IP, PortNumber) Nonce32 Tox.NodeInfo Tox.Rendezvous
203toxQSearch tox = Tox.toxidSearch (Tox.onionTimeout tox) (Tox.toxCryptoKeys tox) (Tox.toxOnion tox) 234toxQSearch tox = Tox.toxidSearch (Tox.onionTimeout tox) (Tox.toxCryptoKeys tox) (Tox.toxOnion tox)