summaryrefslogtreecommitdiff
path: root/Roster.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Roster.hs')
-rw-r--r--Roster.hs100
1 files changed, 0 insertions, 100 deletions
diff --git a/Roster.hs b/Roster.hs
deleted file mode 100644
index 7c40e371..00000000
--- a/Roster.hs
+++ /dev/null
@@ -1,100 +0,0 @@
1{-# LANGUAGE NamedFieldPuns #-}
2module Roster where
3
4import Control.Concurrent.STM
5import Control.Monad
6import Crypto.PubKey.Curve25519
7import qualified Data.HashMap.Strict as HashMap
8 ;import Data.HashMap.Strict (HashMap)
9import Data.Maybe
10import Network.Tox.DHT.Transport as DHT
11import Network.Tox.NodeId
12import Network.Tox.Onion.Transport as Onion
13import System.IO
14
15newtype Roster = Roster { accounts :: TVar (HashMap NodeId Account) }
16
17data Account = Account
18 { userSecret :: SecretKey -- local secret key
19 , contacts :: TVar (HashMap NodeId Contact) -- received contact info
20 }
21
22data Contact = Contact
23 { contactKeyPacket :: Maybe (DHT.DHTPublicKey)
24 , contactFriendRequest :: Maybe (DHT.FriendRequest)
25 }
26
27mergeContact :: Contact -> Maybe Contact -> Maybe Contact
28mergeContact (Contact newk newf) (Just (Contact oldk oldf)) =
29 Just (Contact mergek mergef)
30 where
31 mergek = mplus oldk $ do
32 n <- newk
33 stamp <- fmap DHT.dhtpkNonce oldk `mplus` return minBound
34 guard (stamp <= DHT.dhtpkNonce n)
35 return n
36 mergef = mplus oldf newf
37mergeContact new Nothing = Just new
38
39newRoster :: IO Roster
40newRoster = atomically $ Roster <$> newTVar HashMap.empty
41
42newAccount :: SecretKey -> STM Account
43newAccount sk = Account sk <$> newTVar HashMap.empty
44
45addRoster :: Roster -> SecretKey -> STM ()
46addRoster (Roster as) sk = do
47 a <- newAccount sk
48 modifyTVar' as $ HashMap.insert (key2id $ toPublic sk) a
49
50delRoster :: Roster -> PublicKey -> STM ()
51delRoster (Roster as) pk = modifyTVar' as $ HashMap.delete (key2id pk)
52
53updateRoster :: Roster -> Onion.AnnouncedRendezvous -> (PublicKey,Onion.OnionData) -> IO ()
54updateRoster roster Onion.AnnouncedRendezvous{remoteUserKey} (localUserKey,omsg) = do
55 hPutStrLn stderr "updateRoster!!!"
56 atomically $ do
57 as <- readTVar (accounts roster)
58 maybe (return ())
59 (updateAccount remoteUserKey omsg)
60 $ HashMap.lookup (key2id localUserKey) as
61
62
63updateAccount :: PublicKey -> Onion.OnionData -> Account -> STM ()
64updateAccount remoteUserKey (Onion.OnionDHTPublicKey dhtpk) acc = do
65 modifyTVar' (contacts acc) $ HashMap.alter (mergeContact $ Contact (Just dhtpk) Nothing)
66 (key2id remoteUserKey)
67
68updateAccount remoteUserKey (Onion.OnionFriendRequest fr) acc = do
69 modifyTVar' (contacts acc) $ HashMap.alter (mergeContact $ Contact Nothing (Just fr))
70 (key2id remoteUserKey)
71
72dnsPresentation :: Roster -> STM String
73dnsPresentation (Roster accsvar) = do
74 accs <- readTVar accsvar
75 ms <- forM accs $ \Account { userSecret = sec, contacts = cvar } -> do
76 cs <- readTVar cvar
77 return $
78 "; local key = " ++ show (key2id $ toPublic sec) ++ "\n"
79 ++ concatMap dnsPresentation1
80 (mapMaybe (\(nid,m) -> ((,) nid) <$> contactKeyPacket m)
81 $ HashMap.toList cs)
82 return $ concat ms
83
84dnsPresentation1 :: (NodeId,DHTPublicKey) -> String
85dnsPresentation1 (nid,dk) = unlines
86 [ concat [ show nid, ".tox. IN CNAME ", show (key2id $ dhtpk dk), ".dht." ]
87 ]
88
89type LocalKey = NodeId
90type RemoteKey = NodeId
91
92friendRequests :: Roster -> STM (HashMap LocalKey [(RemoteKey,DHT.FriendRequest)])
93friendRequests (Roster roster) = do
94 accs <- readTVar roster
95 forM accs $ \Account { userSecret = sec, contacts = cvar } -> do
96 cs <- readTVar cvar
97 let remotes = mapMaybe (\(nid,m) -> ((,) nid) <$> contactFriendRequest m)
98 $ HashMap.toList cs
99 return remotes
100