summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/dhtd.hs16
-rw-r--r--src/Network/Tox/ContactInfo.hs35
2 files changed, 40 insertions, 11 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index 04de4056..8fc986a5 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -1078,8 +1078,20 @@ toxman tox = ToxManager
1078 -- Stop the recurring search for that contact 1078 -- Stop the recurring search for that contact
1079 return () 1079 return ()
1080 , setToxConnectionPolicy = \me them -> \case 1080 , setToxConnectionPolicy = \me them -> \case
1081 TryingToConnect -> return () -- Add a contact. 1081 TryingToConnect -> do
1082 _ -> return () -- Remove contact. 1082 let db@ContactInfo{ accounts } = Tox.toxContactInfo tox
1083 sequence_ $ do
1084 meid <- readMaybe $ T.unpack $ T.take 43 me
1085 themid <- readMaybe $ T.unpack $ T.take 43 them
1086 Just $ atomically $ do
1087 accs <- readTVar accounts
1088 case HashMap.lookup meid accs of
1089 Nothing -> return () -- Unknown account.
1090 Just acc -> modifyTVar' (contacts acc)
1091 $ HashMap.alter (mergeContact nullContact { contactPolicy = Just TryingToConnect })
1092 themid
1093 -- If unscheduled and unconnected, schedule recurring search for this contact.
1094 _ -> return () -- Remove contact.
1083 } 1095 }
1084 1096
1085#ifdef XMPP 1097#ifdef XMPP
diff --git a/src/Network/Tox/ContactInfo.hs b/src/Network/Tox/ContactInfo.hs
index 0d8a9f8a..6cadc944 100644
--- a/src/Network/Tox/ContactInfo.hs
+++ b/src/Network/Tox/ContactInfo.hs
@@ -2,6 +2,7 @@
2module Network.Tox.ContactInfo where 2module Network.Tox.ContactInfo where
3 3
4import ConnectionKey 4import ConnectionKey
5import Connection
5 6
6import Control.Concurrent.STM 7import Control.Concurrent.STM
7import Control.Monad 8import Control.Monad
@@ -16,7 +17,10 @@ import Network.Tox.NodeId
16import Network.Tox.Onion.Transport as Onion 17import Network.Tox.Onion.Transport as Onion
17import System.IO 18import System.IO
18 19
19newtype ContactInfo = ContactInfo { accounts :: TVar (HashMap NodeId Account) } 20newtype ContactInfo = ContactInfo
21 -- | Map our toxid public key to an Account record.
22 { accounts :: TVar (HashMap NodeId Account)
23 }
20 24
21data Account = Account 25data Account = Account
22 { userSecret :: SecretKey -- local secret key 26 { userSecret :: SecretKey -- local secret key
@@ -27,18 +31,29 @@ data Account = Account
27data Contact = Contact 31data Contact = Contact
28 { contactKeyPacket :: Maybe (DHT.DHTPublicKey) 32 { contactKeyPacket :: Maybe (DHT.DHTPublicKey)
29 , contactFriendRequest :: Maybe (DHT.FriendRequest) 33 , contactFriendRequest :: Maybe (DHT.FriendRequest)
34 , contactPolicy :: Maybe (Connection.Policy)
35 }
36
37nullContact :: Contact
38nullContact = Contact
39 { contactKeyPacket = Nothing
40 , contactFriendRequest = Nothing
41 , contactPolicy = Nothing
30 } 42 }
31 43
32mergeContact :: Contact -> Maybe Contact -> Maybe Contact 44mergeContact :: Contact -> Maybe Contact -> Maybe Contact
33mergeContact (Contact newk newf) (Just (Contact oldk oldf)) = 45mergeContact (Contact newk newf newp) (Just (Contact oldk oldf oldp)) =
34 Just (Contact mergek mergef) 46 Just $ Contact mergek -- Prefer newer public key packet as long as its stamp
47 -- is later than the stored one.
48 (mplus newf oldf) -- Prefer newer friend request.
49 (mplus newp oldp) -- Prefer newer connection policy.
35 where 50 where
36 mergek = mplus oldk $ do 51 mergek = flip mplus oldk $ do
37 n <- newk 52 n <- newk
38 stamp <- fmap DHT.dhtpkNonce oldk `mplus` return minBound 53 stamp <- fmap DHT.dhtpkNonce oldk `mplus` return minBound
39 guard (stamp <= DHT.dhtpkNonce n) 54 guard (stamp <= DHT.dhtpkNonce n)
40 return n 55 return n
41 mergef = mplus oldf newf 56
42mergeContact new Nothing = Just new 57mergeContact new Nothing = Just new
43 58
44newContactInfo :: IO ContactInfo 59newContactInfo :: IO ContactInfo
@@ -68,12 +83,14 @@ updateContactInfo roster Onion.AnnouncedRendezvous{remoteUserKey} (localUserKey,
68 83
69updateAccount :: PublicKey -> Onion.OnionData -> Account -> STM () 84updateAccount :: PublicKey -> Onion.OnionData -> Account -> STM ()
70updateAccount remoteUserKey (Onion.OnionDHTPublicKey dhtpk) acc = do 85updateAccount remoteUserKey (Onion.OnionDHTPublicKey dhtpk) acc = do
71 modifyTVar' (contacts acc) $ HashMap.alter (mergeContact $ Contact (Just dhtpk) Nothing) 86 modifyTVar' (contacts acc)
72 (key2id remoteUserKey) 87 $ HashMap.alter (mergeContact nullContact { contactKeyPacket = Just dhtpk })
88 (key2id remoteUserKey)
73 89
74updateAccount remoteUserKey (Onion.OnionFriendRequest fr) acc = do 90updateAccount remoteUserKey (Onion.OnionFriendRequest fr) acc = do
75 modifyTVar' (contacts acc) $ HashMap.alter (mergeContact $ Contact Nothing (Just fr)) 91 modifyTVar' (contacts acc)
76 (key2id remoteUserKey) 92 $ HashMap.alter (mergeContact nullContact { contactFriendRequest = Just fr })
93 (key2id remoteUserKey)
77 94
78dnsPresentation :: ContactInfo -> STM String 95dnsPresentation :: ContactInfo -> STM String
79dnsPresentation (ContactInfo accsvar) = do 96dnsPresentation (ContactInfo accsvar) = do