summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Connection/Tox.hs10
-rw-r--r--ToxManager.hs32
-rw-r--r--ToxToXMPP.hs28
-rw-r--r--examples/dhtd.hs8
-rw-r--r--src/Network/Tox.hs22
-rw-r--r--src/Network/Tox/ContactInfo.hs52
-rw-r--r--src/Network/Tox/DHT/Transport.hs2
7 files changed, 85 insertions, 69 deletions
diff --git a/Connection/Tox.hs b/Connection/Tox.hs
index 0c2f281f..03ffbc25 100644
--- a/Connection/Tox.hs
+++ b/Connection/Tox.hs
@@ -35,10 +35,10 @@ import System.IO
35 35
36 36
37 37
38data Parameters = Parameters 38data Parameters extra = Parameters
39 { -- | Various Tox transports and clients. 39 { -- | Various Tox transports and clients.
40 dhtRouting :: Routing 40 dhtRouting :: Routing
41 , roster :: ContactInfo 41 , roster :: ContactInfo extra
42 , sessions :: NetCryptoSessions 42 , sessions :: NetCryptoSessions
43 , dhtClient :: DHT.Client 43 , dhtClient :: DHT.Client
44 -- | Thread to be forked when a connection is established. 44 -- | Thread to be forked when a connection is established.
@@ -127,7 +127,7 @@ lookupForPolicyChange conmap k policy = do
127callbackId :: Int 127callbackId :: Int
128callbackId = 1 128callbackId = 1
129 129
130lookupContact :: Key -> ContactInfo -> STM (Maybe (SecretKey,Contact)) 130lookupContact :: Key -> ContactInfo extra -> STM (Maybe (SecretKey,Contact))
131lookupContact (Key me them) ContactInfo{accounts} = do 131lookupContact (Key me them) ContactInfo{accounts} = do
132 acnts <- readTVar accounts 132 acnts <- readTVar accounts
133 fmap join $ forM (HashMap.lookup me acnts) $ \Account{userSecret,contacts} -> do 133 fmap join $ forM (HashMap.lookup me acnts) $ \Account{userSecret,contacts} -> do
@@ -136,7 +136,7 @@ lookupContact (Key me them) ContactInfo{accounts} = do
136 return (userSecret,c) 136 return (userSecret,c)
137 137
138-- | This function will fork threads as necessary. 138-- | This function will fork threads as necessary.
139setToxPolicy :: Parameters 139setToxPolicy :: Parameters extra
140 -> TVar (Map.Map Key SessionState) 140 -> TVar (Map.Map Key SessionState)
141 -> Key 141 -> Key
142 -> Policy 142 -> Policy
@@ -249,7 +249,7 @@ stringToKey_ s = let (xs,ys) = break (==':') s
249 them <- readMaybe (drop 1 ys) 249 them <- readMaybe (drop 1 ys)
250 return $ Key me them 250 return $ Key me them
251 251
252toxManager :: Parameters -> IO (Manager ToxProgress Key) 252toxManager :: Parameters extra -> IO (Manager ToxProgress Key)
253toxManager params = do 253toxManager params = do
254 conmap <- newTVarIO Map.empty 254 conmap <- newTVarIO Map.empty
255 return Manager 255 return Manager
diff --git a/ToxManager.hs b/ToxManager.hs
index 460b2fe5..cd835983 100644
--- a/ToxManager.hs
+++ b/ToxManager.hs
@@ -11,8 +11,8 @@ import Control.Concurrent.STM
11import Control.Monad 11import Control.Monad
12import Crypto.Tox 12import Crypto.Tox
13import qualified Data.HashMap.Strict as HashMap 13import qualified Data.HashMap.Strict as HashMap
14import qualified Data.Map as Map
14import Data.Maybe 15import Data.Maybe
15import qualified Data.Set as Set
16import qualified Data.Text as T 16import qualified Data.Text as T
17import Data.Time.Clock.POSIX 17import Data.Time.Clock.POSIX
18import Network.Address 18import Network.Address
@@ -38,10 +38,11 @@ import Control.Concurrent.Lifted
38import GHC.Conc (labelThread) 38import GHC.Conc (labelThread)
39#endif 39#endif
40 40
41toxAnnounceSendData :: Tox.Tox -> PublicKey 41toxAnnounceSendData :: Tox.Tox JabberClients
42 -> Nonce32 42 -> PublicKey
43 -> Maybe Tox.NodeInfo 43 -> Nonce32
44 -> IO (Maybe (Tox.Rendezvous, Tox.AnnounceResponse)) 44 -> Maybe Tox.NodeInfo
45 -> IO (Maybe (Tox.Rendezvous, Tox.AnnounceResponse))
45toxAnnounceSendData tox pubkey token = \case 46toxAnnounceSendData tox pubkey token = \case
46 Just ni -> Tox.putRendezvous (Tox.onionTimeout tox) 47 Just ni -> Tox.putRendezvous (Tox.onionTimeout tox)
47 (Tox.toxCryptoKeys tox) 48 (Tox.toxCryptoKeys tox)
@@ -56,7 +57,11 @@ toxAnnounceSendData tox pubkey token = \case
56-- 57--
57-- These hooks will be invoked in order to connect to *.tox hosts in a user's 58-- These hooks will be invoked in order to connect to *.tox hosts in a user's
58-- XMPP roster. 59-- XMPP roster.
59toxman :: Announcer -> [(String,TVar (BucketList Tox.NodeInfo))] -> Tox.Tox -> PresenceState -> ToxManager ConnectionKey 60toxman :: Announcer
61 -> [(String,TVar (BucketList Tox.NodeInfo))]
62 -> Tox.Tox JabberClients
63 -> PresenceState
64 -> ToxManager ConnectionKey
60toxman announcer toxbkts tox presence = ToxManager 65toxman announcer toxbkts tox presence = ToxManager
61 { activateAccount = \k pubname seckey -> do 66 { activateAccount = \k pubname seckey -> do
62 hPutStrLn stderr $ "toxman ACTIVATE " ++ show (Tox.key2id $ toPublic seckey) 67 hPutStrLn stderr $ "toxman ACTIVATE " ++ show (Tox.key2id $ toPublic seckey)
@@ -65,11 +70,12 @@ toxman announcer toxbkts tox presence = ToxManager
65 pubid = Tox.key2id pub 70 pubid = Tox.key2id pub
66 (acnt,newlyActive) <- atomically $ do 71 (acnt,newlyActive) <- atomically $ do
67 macnt <- HashMap.lookup pubid <$> readTVar accounts 72 macnt <- HashMap.lookup pubid <$> readTVar accounts
68 acnt <- maybe (newAccount seckey) return macnt 73 acnt <- maybe (newAccount seckey Map.empty) return macnt
69 rs <- readTVar $ clientRefs acnt 74 rs <- readTVar $ accountExtra acnt
70 writeTVar (clientRefs acnt) $! Set.insert k rs 75 perclient <- initPerClient
76 writeTVar (accountExtra acnt) $! Map.insert k perclient rs
71 modifyTVar accounts (HashMap.insert pubid acnt) 77 modifyTVar accounts (HashMap.insert pubid acnt)
72 if not (Set.null rs) 78 if not (Map.null rs)
73 then return (acnt,Nothing) 79 then return (acnt,Nothing)
74 else return (acnt,Just $ \nid -> foldr interweave [] 80 else return (acnt,Just $ \nid -> foldr interweave []
75 . map (R.kclosest (searchSpace (toxQSearch tox)) 81 . map (R.kclosest (searchSpace (toxQSearch tox))
@@ -101,11 +107,11 @@ toxman announcer toxbkts tox presence = ToxManager
101 forM mpubid $ \pubid -> do 107 forM mpubid $ \pubid -> do
102 refs <- do 108 refs <- do
103 macnt <- HashMap.lookup pubid <$> readTVar accounts 109 macnt <- HashMap.lookup pubid <$> readTVar accounts
104 rs <- fromMaybe Set.empty <$> mapM (readTVar . clientRefs) macnt 110 rs <- fromMaybe Map.empty <$> mapM (readTVar . accountExtra) macnt
105 forM_ macnt $ \acnt -> do 111 forM_ macnt $ \acnt -> do
106 modifyTVar' (clientRefs acnt) $ Set.delete k 112 modifyTVar' (accountExtra acnt) $ Map.delete k
107 return rs 113 return rs
108 if (Set.null $ refs Set.\\ Set.singleton k) then do 114 if (Map.null $ Map.delete k refs) then do
109 -- TODO 115 -- TODO
110 -- If this is the last reference to a non-connected contact: 116 -- If this is the last reference to a non-connected contact:
111 -- Stop the recurring search for that contact 117 -- Stop the recurring search for that contact
diff --git a/ToxToXMPP.hs b/ToxToXMPP.hs
index 9391a232..5495f5ad 100644
--- a/ToxToXMPP.hs
+++ b/ToxToXMPP.hs
@@ -100,11 +100,21 @@ 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
103type JabberClients = Map.Map ConnectionKey PerClient
104
105data PerClient = PerClient
106 {
107 }
108
109initPerClient :: STM PerClient
110initPerClient = do
111 return PerClient {}
112
103data ToxToXMPP = ToxToXMPP 113data ToxToXMPP = ToxToXMPP
104 { txAnnouncer :: Announcer 114 { txAnnouncer :: Announcer
105 , txAccount :: Account 115 , txAccount :: Account JabberClients
106 , txPresence :: PresenceState 116 , txPresence :: PresenceState
107 , txTox :: Tox 117 , txTox :: Tox JabberClients
108 } 118 }
109 119
110dispatch :: ToxToXMPP -> ContactEvent -> IO () 120dispatch :: ToxToXMPP -> ContactEvent -> IO ()
@@ -119,8 +129,8 @@ dispatch tx (OnionRouted theirkey (OnionFriendRequest fr) ) = do
119 , txAccount = acnt 129 , txAccount = acnt
120 , txPresence = st } = tx 130 , txPresence = st } = tx
121 k2c <- atomically $ do 131 k2c <- atomically $ do
122 refs <- readTVar (clientRefs acnt) 132 refs <- readTVar (accountExtra acnt)
123 k2c <- Map.filterWithKey (\k _ -> k `Set.member` refs) <$> readTVar (keyToChan st) 133 k2c <- Map.filterWithKey (\k _ -> isJust $ k `Map.lookup` refs) <$> readTVar (keyToChan st)
124 clients <- readTVar (clients st) 134 clients <- readTVar (clients st)
125 return $ Map.intersectionWith (,) k2c clients 135 return $ Map.intersectionWith (,) k2c clients
126 -- TODO: Below we're using a hard coded default as their jabber user id. 136 -- TODO: Below we're using a hard coded default as their jabber user id.
@@ -204,7 +214,7 @@ stopConnecting ToxToXMPP{txAnnouncer=announcer,txAccount=acnt} them = do
204 akey <- akeyDHTKeyShare announcer me them 214 akey <- akeyDHTKeyShare announcer me them
205 cancel announcer akey 215 cancel announcer akey
206 216
207forkAccountWatcher :: Account -> Tox -> PresenceState -> Announcer -> IO ThreadId 217forkAccountWatcher :: Account JabberClients -> Tox JabberClients -> PresenceState -> Announcer -> IO ThreadId
208forkAccountWatcher acc tox st announcer = forkIO $ do 218forkAccountWatcher acc tox st announcer = forkIO $ do
209 myThreadId >>= flip labelThread ("tox-xmpp:" 219 myThreadId >>= flip labelThread ("tox-xmpp:"
210 ++ show (key2id $ toPublic $ userSecret acc)) 220 ++ show (key2id $ toPublic $ userSecret acc))
@@ -220,13 +230,13 @@ forkAccountWatcher acc tox st announcer = forkIO $ do
220 forM_ (HashMap.toList cs) $ \(them,c) -> do 230 forM_ (HashMap.toList cs) $ \(them,c) -> do
221 startConnecting0 tx (id2key them) c 231 startConnecting0 tx (id2key them) c
222 232
223 -- Loop endlessly until clientRefs is null. 233 -- Loop endlessly until accountExtra is null.
224 fix $ \loop -> do 234 fix $ \loop -> do
225 mev <- atomically $ 235 mev <- atomically $
226 (Just <$> readTChan chan) 236 (Just <$> readTChan chan)
227 `orElse` do 237 `orElse` do
228 refs <- readTVar $ clientRefs acc 238 refs <- readTVar $ accountExtra acc
229 check $ Set.null refs 239 check $ Map.null refs
230 return Nothing 240 return Nothing
231 241
232 forM_ mev $ \ev -> dispatch tx ev >> loop 242 forM_ mev $ \ev -> dispatch tx ev >> loop
@@ -236,7 +246,7 @@ forkAccountWatcher acc tox st announcer = forkIO $ do
236 stopConnecting tx (id2key them) 246 stopConnecting tx (id2key them)
237 247
238 248
239toxQSearch :: Tox.Tox -> Search Tox.NodeId (IP, PortNumber) Nonce32 Tox.NodeInfo Tox.Rendezvous 249toxQSearch :: Tox extra -> Search Tox.NodeId (IP, PortNumber) Nonce32 Tox.NodeInfo Tox.Rendezvous
240toxQSearch tox = Tox.toxidSearch (Tox.onionTimeout tox) (Tox.toxCryptoKeys tox) (Tox.toxOnion tox) 250toxQSearch tox = Tox.toxidSearch (Tox.onionTimeout tox) (Tox.toxCryptoKeys tox) (Tox.toxOnion tox)
241 251
242toxAnnounceInterval :: POSIXTime 252toxAnnounceInterval :: POSIXTime
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index d4216dae..d0d8678d 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -312,13 +312,13 @@ data Session = Session
312 , swarms :: Mainline.SwarmsDatabase 312 , swarms :: Mainline.SwarmsDatabase
313 , cryptosessions :: Tox.NetCryptoSessions 313 , cryptosessions :: Tox.NetCryptoSessions
314 , toxkeys :: TVar Tox.AnnouncedKeys 314 , toxkeys :: TVar Tox.AnnouncedKeys
315 , roster :: Tox.ContactInfo 315 , roster :: Tox.ContactInfo JabberClients
316 , announceToLan :: IO () 316 , announceToLan :: IO ()
317 , connectionManager :: Maybe ConnectionManager 317 , connectionManager :: Maybe ConnectionManager
318 , onionRouter :: OnionRouter 318 , onionRouter :: OnionRouter
319 , announcer :: Announcer 319 , announcer :: Announcer
320 , signalQuit :: IO () 320 , signalQuit :: IO ()
321 , mbTox :: Maybe Tox.Tox 321 , mbTox :: Maybe (Tox.Tox JabberClients)
322 } 322 }
323 323
324exceptionsToClient :: ClientHandle -> IO () -> IO () 324exceptionsToClient :: ClientHandle -> IO () -> IO ()
@@ -555,7 +555,7 @@ clientSession s@Session{..} sock cnum h = do
555 let pubkey = toPublic secret 555 let pubkey = toPublic secret
556 oldks <- atomically $ do 556 oldks <- atomically $ do
557 ks <- myKeyPairs roster 557 ks <- myKeyPairs roster
558 Tox.addContactInfo roster secret 558 Tox.addContactInfo roster secret Map.empty
559 return ks 559 return ks
560 let asString = show . Tox.key2id 560 let asString = show . Tox.key2id
561 hPutClient h $ unlines $ map (mappend " " . show . Tox.key2id . snd) oldks 561 hPutClient h $ unlines $ map (mappend " " . show . Tox.key2id . snd) oldks
@@ -584,7 +584,7 @@ clientSession s@Session{..} sock cnum h = do
584 pairs = map (toPair . f) mbSecs 584 pairs = map (toPair . f) mbSecs
585 oldks <- atomically $ do 585 oldks <- atomically $ do
586 oldks <- myKeyPairs roster 586 oldks <- myKeyPairs roster
587 forM pairs $ \(sk,_) -> Tox.addContactInfo roster sk 587 forM pairs $ \(sk,_) -> Tox.addContactInfo roster sk Map.empty
588 return oldks 588 return oldks
589 hPutClient h $ unlines $ map (mappend " " . show . Tox.key2id . snd) oldks 589 hPutClient h $ unlines $ map (mappend " " . show . Tox.key2id . snd) oldks
590 ++ map (mappend " *" . show . Tox.key2id .snd) pairs 590 ++ map (mappend " *" . show . Tox.key2id .snd) pairs
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 20302343..a13a4f10 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -248,7 +248,7 @@ newClient drg net classify selfAddr handlers modifytbl modifynet = do
248 in client 248 in client
249 return $ either mkclient mkclient tblvar handlers 249 return $ either mkclient mkclient tblvar handlers
250 250
251data Tox = Tox 251data Tox extra = Tox
252 { toxDHT :: DHT.Client 252 { toxDHT :: DHT.Client
253 , toxOnion :: Onion.Client RouteId 253 , toxOnion :: Onion.Client RouteId
254 , toxToRoute :: Transport String Onion.AnnouncedRendezvous (PublicKey,Onion.OnionData) 254 , toxToRoute :: Transport String Onion.AnnouncedRendezvous (PublicKey,Onion.OnionData)
@@ -260,17 +260,17 @@ data Tox = Tox
260 , toxTokens :: TVar SessionTokens 260 , toxTokens :: TVar SessionTokens
261 , toxAnnouncedKeys :: TVar Onion.AnnouncedKeys 261 , toxAnnouncedKeys :: TVar Onion.AnnouncedKeys
262 , toxOnionRoutes :: OnionRouter 262 , toxOnionRoutes :: OnionRouter
263 , toxContactInfo :: ContactInfo 263 , toxContactInfo :: ContactInfo extra
264 , toxAnnounceToLan :: IO () 264 , toxAnnounceToLan :: IO ()
265 , toxMgr :: Manager ToxProgress Key 265 , toxMgr :: Manager ToxProgress Key
266 } 266 }
267 267
268-- | initiate a netcrypto session, blocking 268-- | initiate a netcrypto session, blocking
269netCrypto :: Tox -> SecretKey -> PublicKey{-UserKey -} -> IO [NetCryptoSession] 269netCrypto :: Tox extra -> SecretKey -> PublicKey{-UserKey -} -> IO [NetCryptoSession]
270netCrypto tox myseckey theirpubkey = netCryptoWithBackoff 1000000 tox myseckey theirpubkey 270netCrypto tox myseckey theirpubkey = netCryptoWithBackoff 1000000 tox myseckey theirpubkey
271 271
272-- | helper for 'netCrypto', initiate a netcrypto session, retry after specified millisecs 272-- | helper for 'netCrypto', initiate a netcrypto session, retry after specified millisecs
273netCryptoWithBackoff :: Int -> Tox -> SecretKey -> PublicKey -> IO [NetCryptoSession] 273netCryptoWithBackoff :: Int -> Tox extra -> SecretKey -> PublicKey -> IO [NetCryptoSession]
274netCryptoWithBackoff millisecs tox myseckey theirpubkey = do 274netCryptoWithBackoff millisecs tox myseckey theirpubkey = do
275 let mykeyAsId = key2id (toPublic myseckey) 275 let mykeyAsId = key2id (toPublic myseckey)
276 -- TODO: check status of connection here: 276 -- TODO: check status of connection here:
@@ -358,7 +358,7 @@ netCryptoWithBackoff millisecs tox myseckey theirpubkey = do
358 return [] 358 return []
359 359
360-- | Create a DHTPublicKey packet to send to a remote contact. 360-- | Create a DHTPublicKey packet to send to a remote contact.
361getContactInfo :: Tox -> IO DHT.DHTPublicKey 361getContactInfo :: Tox extra -> IO DHT.DHTPublicKey
362getContactInfo Tox{toxCryptoKeys,toxRouting} = join $ atomically $ do 362getContactInfo Tox{toxCryptoKeys,toxRouting} = join $ atomically $ do
363 r4 <- readTVar $ DHT.routing4 toxRouting 363 r4 <- readTVar $ DHT.routing4 toxRouting
364 r6 <- readTVar $ DHT.routing6 toxRouting 364 r6 <- readTVar $ DHT.routing6 toxRouting
@@ -416,7 +416,7 @@ newTox :: TVar Onion.AnnouncedKeys -- ^ Store of announced keys we are a rende
416 -> SockAddr -- ^ Bind-address to listen on. 416 -> SockAddr -- ^ Bind-address to listen on.
417 -> Maybe NetCryptoSessions -- ^ State of all one-on-one Tox links. 417 -> Maybe NetCryptoSessions -- ^ State of all one-on-one Tox links.
418 -> Maybe SecretKey -- ^ Optional DHT secret key to use. 418 -> Maybe SecretKey -- ^ Optional DHT secret key to use.
419 -> IO Tox 419 -> IO (Tox extra)
420newTox keydb addr mbSessionsState suppliedDHTKey = do 420newTox keydb addr mbSessionsState suppliedDHTKey = do
421 (udp,sock) <- {- addVerbosity <$> -} udpTransport' addr 421 (udp,sock) <- {- addVerbosity <$> -} udpTransport' addr
422 (crypto0,sessionsState0) <- case mbSessionsState of 422 (crypto0,sessionsState0) <- case mbSessionsState of
@@ -506,21 +506,21 @@ newTox keydb addr mbSessionsState suppliedDHTKey = do
506 , toxMgr = mgr 506 , toxMgr = mgr
507 } 507 }
508 508
509onionTimeout :: Tox -> DHT.TransactionId -> Onion.OnionDestination RouteId -> STM (Onion.OnionDestination RouteId, Int) 509onionTimeout :: Tox extra -> DHT.TransactionId -> Onion.OnionDestination RouteId -> STM (Onion.OnionDestination RouteId, Int)
510onionTimeout Tox { toxOnionRoutes = or } (DHT.TransactionId n8 _) od = lookupTimeout or n8 od 510onionTimeout Tox { toxOnionRoutes = or } (DHT.TransactionId n8 _) od = lookupTimeout or n8 od
511 511
512routing4nodeInfo :: DHT.Routing -> IO NodeInfo 512routing4nodeInfo :: DHT.Routing -> IO NodeInfo
513routing4nodeInfo (DHT.routing4 -> tv) = R.thisNode <$> readTVarIO tv 513routing4nodeInfo (DHT.routing4 -> tv) = R.thisNode <$> readTVarIO tv
514 514
515dnssdAnnounce :: Tox -> IO () 515dnssdAnnounce :: Tox extra -> IO ()
516dnssdAnnounce (toxRouting -> r) = do 516dnssdAnnounce (toxRouting -> r) = do
517 ni <- routing4nodeInfo r 517 ni <- routing4nodeInfo r
518 announceToxService (nodePort ni) (nodeId ni) 518 announceToxService (nodePort ni) (nodeId ni)
519 519
520dnssdDiscover :: Tox -> NodeInfo -> IO () 520dnssdDiscover :: Tox extra -> NodeInfo -> IO ()
521dnssdDiscover (toxDHT -> client) ni = void $ DHT.ping client ni 521dnssdDiscover (toxDHT -> client) ni = void $ DHT.ping client ni
522 522
523forkTox :: Tox -> IO (IO (), [NodeInfo] -> [NodeInfo] -> IO (), [NodeInfo] -> [NodeInfo] -> IO ()) 523forkTox :: Tox extra -> IO (IO (), [NodeInfo] -> [NodeInfo] -> IO (), [NodeInfo] -> [NodeInfo] -> IO ())
524forkTox tox = do 524forkTox tox = do
525 _ <- forkListener "toxHandshakes" (toxHandshakes tox) 525 _ <- forkListener "toxHandshakes" (toxHandshakes tox)
526 _ <- forkListener "toxToRoute" (toxToRoute tox) 526 _ <- forkListener "toxToRoute" (toxToRoute tox)
diff --git a/src/Network/Tox/ContactInfo.hs b/src/Network/Tox/ContactInfo.hs
index 9f29d587..64ea861b 100644
--- a/src/Network/Tox/ContactInfo.hs
+++ b/src/Network/Tox/ContactInfo.hs
@@ -19,16 +19,16 @@ import Network.Tox.NodeId (id2key)
19import Network.Tox.Onion.Transport as Onion 19import Network.Tox.Onion.Transport as Onion
20import System.IO 20import System.IO
21 21
22newtype ContactInfo = ContactInfo 22newtype ContactInfo extra = ContactInfo
23 -- | Map our toxid public key to an Account record. 23 -- | Map our toxid public key to an Account record.
24 { accounts :: TVar (HashMap NodeId{-my userkey-} Account) 24 { accounts :: TVar (HashMap NodeId{-my userkey-} (Account extra))
25 } 25 }
26 26
27data Account = Account 27data Account extra = Account
28 { userSecret :: SecretKey -- local secret key 28 { userSecret :: SecretKey -- local secret key
29 , contacts :: TVar (HashMap NodeId{-friend's userkey-} Contact) -- received contact info 29 , contacts :: TVar (HashMap NodeId{-friend's userkey-} Contact) -- received contact info
30 , clientRefs :: TVar (Set ConnectionKey) -- reference count so we know when to send offline etc 30 , accountExtra :: TVar extra
31 , eventChan :: TChan ContactEvent 31 , eventChan :: TChan ContactEvent
32 } 32 }
33 33
34data ContactEvent = OnionRouted { contact :: PublicKey, onionRouted :: OnionData } 34data ContactEvent = OnionRouted { contact :: PublicKey, onionRouted :: OnionData }
@@ -44,16 +44,16 @@ data Contact = Contact
44 , contactPolicy :: TVar (Maybe Connection.Policy) 44 , contactPolicy :: TVar (Maybe Connection.Policy)
45 } 45 }
46 46
47newContactInfo :: IO ContactInfo 47newContactInfo :: IO (ContactInfo extra)
48newContactInfo = atomically $ ContactInfo <$> newTVar HashMap.empty 48newContactInfo = atomically $ ContactInfo <$> newTVar HashMap.empty
49 49
50myKeyPairs :: ContactInfo -> STM [(SecretKey,PublicKey)] 50myKeyPairs :: ContactInfo extra -> STM [(SecretKey,PublicKey)]
51myKeyPairs (ContactInfo accounts) = do 51myKeyPairs (ContactInfo accounts) = do
52 acnts <- readTVar accounts 52 acnts <- readTVar accounts
53 forM (HashMap.toList acnts) $ \(nid, Account{userSecret}) -> do 53 forM (HashMap.toList acnts) $ \(nid, Account{userSecret}) -> do
54 return (userSecret,id2key nid) 54 return (userSecret,id2key nid)
55 55
56updateContactInfo :: ContactInfo -> Onion.AnnouncedRendezvous -> (PublicKey,Onion.OnionData) -> IO () 56updateContactInfo :: ContactInfo extra -> Onion.AnnouncedRendezvous -> (PublicKey,Onion.OnionData) -> IO ()
57updateContactInfo roster Onion.AnnouncedRendezvous{remoteUserKey} (localUserKey,omsg) = do 57updateContactInfo roster Onion.AnnouncedRendezvous{remoteUserKey} (localUserKey,omsg) = do
58 hPutStrLn stderr "updateContactInfo!!!" 58 hPutStrLn stderr "updateContactInfo!!!"
59 now <- getPOSIXTime 59 now <- getPOSIXTime
@@ -69,7 +69,7 @@ initContact = Contact <$> newTVar Nothing
69 <*> newTVar Nothing 69 <*> newTVar Nothing
70 <*> newTVar Nothing 70 <*> newTVar Nothing
71 71
72updateAccount' :: PublicKey -> Account -> (Contact -> STM ()) -> STM () 72updateAccount' :: PublicKey -> Account extra -> (Contact -> STM ()) -> STM ()
73updateAccount' remoteUserKey acc updater = do 73updateAccount' remoteUserKey acc updater = do
74 let rkey = key2id remoteUserKey 74 let rkey = key2id remoteUserKey
75 cmap <- readTVar (contacts acc) 75 cmap <- readTVar (contacts acc)
@@ -80,7 +80,7 @@ updateAccount' remoteUserKey acc updater = do
80 return contact 80 return contact
81 updater contact 81 updater contact
82 82
83updateAccount :: POSIXTime -> PublicKey -> Onion.OnionData -> Account -> STM () 83updateAccount :: POSIXTime -> PublicKey -> Onion.OnionData -> Account extra -> STM ()
84updateAccount now remoteUserKey omsg acc = do 84updateAccount now remoteUserKey omsg acc = do
85 updateAccount' remoteUserKey acc $ onionUpdate now omsg 85 updateAccount' remoteUserKey acc $ onionUpdate now omsg
86 writeTChan (eventChan acc) $ OnionRouted remoteUserKey omsg 86 writeTChan (eventChan acc) $ OnionRouted remoteUserKey omsg
@@ -97,39 +97,39 @@ policyUpdate policy contact = writeTVar (contactPolicy contact) $ Just policy
97addrUpdate :: POSIXTime -> SockAddr -> Contact -> STM () 97addrUpdate :: POSIXTime -> SockAddr -> Contact -> STM ()
98addrUpdate now addr contact = writeTVar (contactLastSeenAddr contact) $ Just (now,addr) 98addrUpdate now addr contact = writeTVar (contactLastSeenAddr contact) $ Just (now,addr)
99 99
100setContactPolicy :: PublicKey -> Policy -> Account -> STM () 100setContactPolicy :: PublicKey -> Policy -> Account extra -> STM ()
101setContactPolicy remoteUserKey policy acc = do 101setContactPolicy remoteUserKey policy acc = do
102 updateAccount' remoteUserKey acc $ policyUpdate policy 102 updateAccount' remoteUserKey acc $ policyUpdate policy
103 writeTChan (eventChan acc) $ PolicyChange remoteUserKey policy 103 writeTChan (eventChan acc) $ PolicyChange remoteUserKey policy
104 104
105setContactAddr :: POSIXTime -> PublicKey -> SockAddr -> Account -> STM () 105setContactAddr :: POSIXTime -> PublicKey -> SockAddr -> Account extra -> STM ()
106setContactAddr now remoteUserKey addr acc = do 106setContactAddr now remoteUserKey addr acc = do
107 updateAccount' remoteUserKey acc $ addrUpdate now addr 107 updateAccount' remoteUserKey acc $ addrUpdate now addr
108 writeTChan (eventChan acc) $ AddrChange remoteUserKey addr 108 writeTChan (eventChan acc) $ AddrChange remoteUserKey addr
109 109
110setEstablished :: POSIXTime -> PublicKey -> Account -> STM () 110setEstablished :: POSIXTime -> PublicKey -> Account extra -> STM ()
111setEstablished now remoteUserKey acc = 111setEstablished now remoteUserKey acc =
112 writeTChan (eventChan acc) $ SessionEstablished remoteUserKey 112 writeTChan (eventChan acc) $ SessionEstablished remoteUserKey
113 113
114setTerminated :: POSIXTime -> PublicKey -> Account -> STM () 114setTerminated :: POSIXTime -> PublicKey -> Account extra -> STM ()
115setTerminated now remoteUserKey acc = 115setTerminated now remoteUserKey acc =
116 writeTChan (eventChan acc) $ SessionTerminated remoteUserKey 116 writeTChan (eventChan acc) $ SessionTerminated remoteUserKey
117 117
118 118
119addContactInfo :: ContactInfo -> SecretKey -> STM () 119addContactInfo :: ContactInfo extra -> SecretKey -> extra -> STM ()
120addContactInfo (ContactInfo as) sk = do 120addContactInfo (ContactInfo as) sk extra = do
121 a <- newAccount sk 121 a <- newAccount sk extra
122 modifyTVar' as $ HashMap.insert (key2id $ toPublic sk) a 122 modifyTVar' as $ HashMap.insert (key2id $ toPublic sk) a
123 123
124delContactInfo :: ContactInfo -> PublicKey -> STM () 124delContactInfo :: ContactInfo extra -> PublicKey -> STM ()
125delContactInfo (ContactInfo as) pk = modifyTVar' as $ HashMap.delete (key2id pk) 125delContactInfo (ContactInfo as) pk = modifyTVar' as $ HashMap.delete (key2id pk)
126 126
127newAccount :: SecretKey -> STM Account 127newAccount :: SecretKey -> extra -> STM (Account extra)
128newAccount sk = Account sk <$> newTVar HashMap.empty 128newAccount sk extra = Account sk <$> newTVar HashMap.empty
129 <*> newTVar Set.empty 129 <*> newTVar extra
130 <*> newBroadcastTChan 130 <*> newBroadcastTChan
131 131
132dnsPresentation :: ContactInfo -> STM String 132dnsPresentation :: ContactInfo extra -> STM String
133dnsPresentation (ContactInfo accsvar) = do 133dnsPresentation (ContactInfo accsvar) = do
134 accs <- readTVar accsvar 134 accs <- readTVar accsvar
135 ms <- forM accs $ \Account { userSecret = sec, contacts = cvar } -> do 135 ms <- forM accs $ \Account { userSecret = sec, contacts = cvar } -> do
@@ -150,7 +150,7 @@ dnsPresentation1 (nid,dk) = unlines
150type LocalKey = NodeId 150type LocalKey = NodeId
151type RemoteKey = NodeId 151type RemoteKey = NodeId
152 152
153friendRequests :: ContactInfo -> STM (HashMap LocalKey [(RemoteKey,DHT.FriendRequest)]) 153friendRequests :: ContactInfo extra -> STM (HashMap LocalKey [(RemoteKey,DHT.FriendRequest)])
154friendRequests (ContactInfo roster) = do 154friendRequests (ContactInfo roster) = do
155 accs <- readTVar roster 155 accs <- readTVar roster
156 forM accs $ \Account { userSecret = sec, contacts = cvar } -> do 156 forM accs $ \Account { userSecret = sec, contacts = cvar } -> do
diff --git a/src/Network/Tox/DHT/Transport.hs b/src/Network/Tox/DHT/Transport.hs
index 5fdcd252..9ff1839c 100644
--- a/src/Network/Tox/DHT/Transport.hs
+++ b/src/Network/Tox/DHT/Transport.hs
@@ -262,7 +262,7 @@ data FriendRequest = FriendRequest
262 { friendNoSpam :: Word32 262 { friendNoSpam :: Word32
263 , friendRequestText :: ByteString -- UTF8 263 , friendRequestText :: ByteString -- UTF8
264 } 264 }
265 deriving (Eq, Show) 265 deriving (Eq, Ord, Show)
266 266
267 267
268-- When sent as a DHT request packet (this is the data sent in the DHT request 268-- When sent as a DHT request packet (this is the data sent in the DHT request