diff options
-rw-r--r-- | examples/dhtd.hs | 16 | ||||
-rw-r--r-- | src/Network/Tox/ContactInfo.hs | 35 |
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 @@ | |||
2 | module Network.Tox.ContactInfo where | 2 | module Network.Tox.ContactInfo where |
3 | 3 | ||
4 | import ConnectionKey | 4 | import ConnectionKey |
5 | import Connection | ||
5 | 6 | ||
6 | import Control.Concurrent.STM | 7 | import Control.Concurrent.STM |
7 | import Control.Monad | 8 | import Control.Monad |
@@ -16,7 +17,10 @@ import Network.Tox.NodeId | |||
16 | import Network.Tox.Onion.Transport as Onion | 17 | import Network.Tox.Onion.Transport as Onion |
17 | import System.IO | 18 | import System.IO |
18 | 19 | ||
19 | newtype ContactInfo = ContactInfo { accounts :: TVar (HashMap NodeId Account) } | 20 | newtype ContactInfo = ContactInfo |
21 | -- | Map our toxid public key to an Account record. | ||
22 | { accounts :: TVar (HashMap NodeId Account) | ||
23 | } | ||
20 | 24 | ||
21 | data Account = Account | 25 | data Account = Account |
22 | { userSecret :: SecretKey -- local secret key | 26 | { userSecret :: SecretKey -- local secret key |
@@ -27,18 +31,29 @@ data Account = Account | |||
27 | data Contact = Contact | 31 | data 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 | |||
37 | nullContact :: Contact | ||
38 | nullContact = Contact | ||
39 | { contactKeyPacket = Nothing | ||
40 | , contactFriendRequest = Nothing | ||
41 | , contactPolicy = Nothing | ||
30 | } | 42 | } |
31 | 43 | ||
32 | mergeContact :: Contact -> Maybe Contact -> Maybe Contact | 44 | mergeContact :: Contact -> Maybe Contact -> Maybe Contact |
33 | mergeContact (Contact newk newf) (Just (Contact oldk oldf)) = | 45 | mergeContact (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 | |
42 | mergeContact new Nothing = Just new | 57 | mergeContact new Nothing = Just new |
43 | 58 | ||
44 | newContactInfo :: IO ContactInfo | 59 | newContactInfo :: IO ContactInfo |
@@ -68,12 +83,14 @@ updateContactInfo roster Onion.AnnouncedRendezvous{remoteUserKey} (localUserKey, | |||
68 | 83 | ||
69 | updateAccount :: PublicKey -> Onion.OnionData -> Account -> STM () | 84 | updateAccount :: PublicKey -> Onion.OnionData -> Account -> STM () |
70 | updateAccount remoteUserKey (Onion.OnionDHTPublicKey dhtpk) acc = do | 85 | updateAccount 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 | ||
74 | updateAccount remoteUserKey (Onion.OnionFriendRequest fr) acc = do | 90 | updateAccount 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 | ||
78 | dnsPresentation :: ContactInfo -> STM String | 95 | dnsPresentation :: ContactInfo -> STM String |
79 | dnsPresentation (ContactInfo accsvar) = do | 96 | dnsPresentation (ContactInfo accsvar) = do |