summaryrefslogtreecommitdiff
path: root/examples/dhtd.hs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r--examples/dhtd.hs121
1 files changed, 87 insertions, 34 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs
index f9dce3bc..c0330657 100644
--- a/examples/dhtd.hs
+++ b/examples/dhtd.hs
@@ -113,24 +113,24 @@ data DHTQuery nid ni = forall addr r tok.
113 , Typeable ni 113 , Typeable ni
114 ) => DHTQuery 114 ) => DHTQuery
115 { qsearch :: Search nid addr tok ni r 115 { qsearch :: Search nid addr tok ni r
116 , qhandler :: ni -> nid -> IO ([ni], [r], tok) -- ^ Invoked on local node, when there is no query destination. 116 , qhandler :: ni -> nid -> IO ([ni], [r], Maybe tok) -- ^ Invoked on local node, when there is no query destination.
117 , qshowR :: r -> String 117 , qshowR :: r -> String
118 , qshowTok :: tok -> Maybe String 118 , qshowTok :: tok -> Maybe String
119 , qresultAddr :: r -> nid
120 } 119 }
121 120
122data DHTAnnouncable = forall dta tok ni r. 121data DHTAnnouncable nid = forall dta tok ni r.
123 ( Show r 122 ( Show r
124 , Typeable dta 123 , Typeable dta
125 , Typeable tok 124 , Typeable tok
126 , Typeable ni
127 , Typeable r 125 , Typeable r
126 , Typeable ni
128 ) => DHTAnnouncable 127 ) => DHTAnnouncable
129 { announceParseData :: String -> Either String dta 128 { announceParseData :: String -> Either String dta
130 , announceParseToken :: dta -> String -> Either String tok 129 , announceParseToken :: dta -> String -> Either String tok
131 , announceParseAddress :: String -> Either String ni 130 , announceParseAddress :: String -> Either String ni
132 , announceSendData :: dta -> tok -> Maybe ni -> IO (Maybe r) 131 , announceSendData :: dta -> tok -> Maybe ni -> IO (Maybe r)
133 , announceInterval :: POSIXTime 132 , announceInterval :: POSIXTime
133 , qresultAddr :: dta -> nid
134 } 134 }
135 135
136data DHTLink = forall status linkid params. 136data DHTLink = forall status linkid params.
@@ -177,7 +177,7 @@ data DHT = forall nid ni. ( Show ni
177 , dhtSecretKey :: STM (Maybe SecretKey) 177 , dhtSecretKey :: STM (Maybe SecretKey)
178 , dhtPing :: Map.Map String (DHTPing ni) 178 , dhtPing :: Map.Map String (DHTPing ni)
179 , dhtQuery :: Map.Map String (DHTQuery nid ni) 179 , dhtQuery :: Map.Map String (DHTQuery nid ni)
180 , dhtAnnouncables :: Map.Map String DHTAnnouncable 180 , dhtAnnouncables :: Map.Map String (DHTAnnouncable nid)
181 , dhtLinks :: Map.Map String DHTLink 181 , dhtLinks :: Map.Map String DHTLink
182 , dhtParseId :: String -> Either String nid 182 , dhtParseId :: String -> Either String nid
183 , dhtSearches :: TVar (Map.Map (String,nid) (DHTSearch nid ni)) 183 , dhtSearches :: TVar (Map.Map (String,nid) (DHTSearch nid ni))
@@ -254,7 +254,7 @@ reportResult ::
254 -> (tok -> Maybe String) 254 -> (tok -> Maybe String)
255 -> (ni -> String) 255 -> (ni -> String)
256 -> Handle 256 -> Handle
257 -> Either String ([ni],[r],tok) 257 -> Either String ([ni],[r],Maybe tok)
258 -> IO () 258 -> IO ()
259reportResult meth showR showTok showN h (Left e) = hPutClient h e 259reportResult meth showR showTok showN h (Left e) = hPutClient h e
260reportResult meth showR showTok showN h (Right (ns,rs,tok)) = do 260reportResult meth showR showTok showN h (Right (ns,rs,tok)) = do
@@ -262,7 +262,7 @@ reportResult meth showR showTok showN h (Right (ns,rs,tok)) = do
262 where 262 where
263 report = intercalate [("","")] [ tok_r , node_r , result_r ] 263 report = intercalate [("","")] [ tok_r , node_r , result_r ]
264 264
265 tok_r = maybe [] (pure . ("token:",)) $ showTok tok 265 tok_r = maybe [] (pure . ("token:",)) $ showTok =<< tok
266 266
267 node_r = map ( ("n",) . showN ) ns 267 node_r = map ( ("n",) . showN ) ns
268 268
@@ -344,9 +344,9 @@ reportSearchResults meth h DHTSearch{searchShowTok,searchState,searchResults} =
344 rs = Set.toList rset 344 rs = Set.toList rset
345 return (ns,rs) 345 return (ns,rs)
346 let n'width = succ $ maximum $ map (length . show . fst) ns 346 let n'width = succ $ maximum $ map (length . show . fst) ns
347 showN (n,tok) = take n'width (show n ++ repeat ' ') ++ (fromMaybe "" $ searchShowTok tok) 347 showN (n,tok) = take n'width (show n ++ repeat ' ') ++ (fromMaybe "" $ searchShowTok =<< tok)
348 ns' = map showN ns 348 ns' = map showN ns
349 reportResult meth id (const Nothing) id h (Right (ns',rs,())) 349 reportResult meth id (const Nothing) id h (Right (ns',rs, Just ()))
350 350
351data Session = Session 351data Session = Session
352 { netname :: String 352 { netname :: String
@@ -601,38 +601,81 @@ clientSession s@Session{..} sock cnum h = do
601 (dtastr,ys) = break isSpace $ dropWhile isSpace xs 601 (dtastr,ys) = break isSpace $ dropWhile isSpace xs
602 a = Map.lookup method dhtAnnouncables 602 a = Map.lookup method dhtAnnouncables
603 q = Map.lookup method dhtQuery 603 q = Map.lookup method dhtQuery
604 doit :: Char -> proxy ni -> Announcer -> AnnounceKey -> AnnounceMethod r -> r -> IO () 604 doit :: Char -> Announcer -> AnnounceKey -> AnnounceMethod r -> r -> IO ()
605 doit '+' _ = schedule 605 doit '+' = schedule
606 doit '-' _ = cancel 606 doit '-' = cancel
607 doit _ _ = \_ _ _ _ -> hPutClient h "Starting(+) or canceling(-)?" 607 doit _ = \_ _ _ _ -> hPutClient h "Starting(+) or canceling(-)?"
608 matchingResult :: 608 matchingResult ::
609 ( Typeable sr 609 ( Typeable stok
610 , Typeable stok 610 , Typeable ptok
611 , Typeable sni
612 , Typeable pni )
613 => Search nid addr stok sni sr
614 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
615 -> Maybe (stok :~: ptok, sni :~: pni)
616 matchingResult _ _ = liftA2 (,) eqT eqT
617 matchingTok ::
618 ( Typeable stok
619 , Typeable ptok
611 , Typeable sni 620 , Typeable sni
612 , Typeable pr 621 , Typeable pni )
622 => Search nid addr stok sni sr
623 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
624 -> Maybe (stok :~: ptok)
625 matchingTok _ _ = eqT
626 matchingNI ::
627 ( Typeable stok
613 , Typeable ptok 628 , Typeable ptok
629 , Typeable sni
614 , Typeable pni ) 630 , Typeable pni )
615 => Search nid addr stok sni sr 631 => Search nid addr stok sni sr
616 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr)) 632 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
617 -> Maybe (sr :~: pr, stok :~: ptok, sni :~: pni ) 633 -> Maybe (sni :~: pni)
618 matchingResult _ _ = liftA3 (\a b c -> (a,b,c)) eqT eqT eqT 634 matchingNI _ _ = eqT
635 chktok :: Maybe ()
636 chktok = do
637 DHTAnnouncable { announceSendData
638 , announceParseData
639 , announceInterval
640 , qresultAddr } <- a
641 DHTQuery { qsearch } <- q
642 Refl <- matchingTok qsearch announceSendData
643 return ()
644 chkni :: Maybe ()
645 chkni = do
646 DHTAnnouncable { announceSendData
647 , announceParseData
648 , announceInterval
649 , qresultAddr } <- a
650 DHTQuery { qsearch } <- q
651 Refl <- matchingNI qsearch announceSendData
652 return ()
619 mameth = do 653 mameth = do
620 DHTAnnouncable { announceSendData 654 DHTAnnouncable { announceSendData
621 , announceParseData 655 , announceParseData
622 , announceInterval } <- a 656 , announceInterval
623 DHTQuery { qsearch 657 , qresultAddr } <- a
624 , qresultAddr } <- q 658 DHTQuery { qsearch } <- q
625 (Refl,Refl,nr@Refl) <- matchingResult qsearch announceSendData 659 (Refl, Refl) <- matchingResult qsearch announceSendData
660 -- return $ hPutClient h "Type matches."
626 dta <- either (const Nothing) Just $ announceParseData dtastr 661 dta <- either (const Nothing) Just $ announceParseData dtastr
627 return $ do 662 return $ do
628 akey <- atomically $ packAnnounceKey announcer (method ++ ":" ++ dtastr) 663 akey <- atomically $ packAnnounceKey announcer (method ++ ":" ++ dtastr)
629 doit op nr announcer 664 doit op announcer
630 akey 665 akey
631 (AnnounceMethod qsearch announceSendData dhtBuckets 666 (AnnounceMethod qsearch announceSendData dhtBuckets
632 (qresultAddr dta) 667 (qresultAddr dta)
633 announceInterval) 668 announceInterval)
634 dta 669 dta
635 fromMaybe (hPutClient h "error.") mameth 670 let aerror = unlines
671 [ "announce error."
672 , "method = " ++ method
673 , "query = " ++ maybe "nil" (const "ok") q
674 , "publish = " ++ maybe "nil" (const "ok") a
675 , "chktok = " ++ maybe "nil" (const "ok") chktok -- chktok = nil
676 , "chkni = " ++ maybe "nil" (const "ok") chkni
677 ]
678 fromMaybe (hPutClient h aerror) mameth
636 679
637 ("s", s) | Just dht@DHT{..} <- Map.lookup netname dhts 680 ("s", s) | Just dht@DHT{..} <- Map.lookup netname dhts
638 -> cmd0 $ do 681 -> cmd0 $ do
@@ -837,8 +880,11 @@ main = do
837 . flip Mainline.FindNode (Just Want_Both)) 880 . flip Mainline.FindNode (Just Want_Both))
838 , qshowR = show 881 , qshowR = show
839 , qshowTok = (const Nothing) 882 , qshowTok = (const Nothing)
840 , qresultAddr = Mainline.nodeId
841 }) 883 })
884 -- Maybe (sr :~: pr, stok :~: ptok, sni :~: pni )
885 -- sr = InfoHash
886 -- stok = Token
887 -- sni = NodeInfo
842 , ("peer", DHTQuery 888 , ("peer", DHTQuery
843 { qsearch = (Mainline.peerSearch bt) 889 { qsearch = (Mainline.peerSearch bt)
844 , qhandler = (\ni -> fmap Mainline.unwrapPeers 890 , qhandler = (\ni -> fmap Mainline.unwrapPeers
@@ -847,13 +893,17 @@ main = do
847 . (read . show)) -- TODO: InfoHash -> NodeId 893 . (read . show)) -- TODO: InfoHash -> NodeId
848 , qshowR = (show . pPrint) 894 , qshowR = (show . pPrint)
849 , qshowTok = (Just . show) 895 , qshowTok = (Just . show)
850 , qresultAddr = (read . show) -- TODO: InfoHash -> NodeId
851 }) 896 })
852 ] 897 ]
853 , dhtParseId = readEither :: String -> Either String Mainline.NodeId 898 , dhtParseId = readEither :: String -> Either String Mainline.NodeId
854 , dhtSearches = mainlineSearches 899 , dhtSearches = mainlineSearches
855 , dhtFallbackNodes = Mainline.bootstrapNodes wantip 900 , dhtFallbackNodes = Mainline.bootstrapNodes wantip
856 , dhtAnnouncables = Map.fromList 901 , dhtAnnouncables = Map.fromList
902 -- Maybe (sr :~: pr, stok :~: ptok, sni :~: pni )
903 -- dta = Announce
904 -- pr = Announced
905 -- ptok = Token
906 -- pni = NodeInfo
857 [ ("peer", DHTAnnouncable { announceSendData = \ih tok -> \case 907 [ ("peer", DHTAnnouncable { announceSendData = \ih tok -> \case
858 Just ni -> do 908 Just ni -> do
859 port <- atomically $ readTVar peerPort 909 port <- atomically $ readTVar peerPort
@@ -864,6 +914,7 @@ main = do
864 , announceParseData = readEither 914 , announceParseData = readEither
865 , announceParseToken = const $ readEither 915 , announceParseToken = const $ readEither
866 , announceInterval = 60 -- TODO: Is one minute good? 916 , announceInterval = 60 -- TODO: Is one minute good?
917 , qresultAddr = (read . show) -- TODO: InfoHash -> NodeId -- peer
867 }) 918 })
868 , ("port", DHTAnnouncable { announceParseData = readEither 919 , ("port", DHTAnnouncable { announceParseData = readEither
869 , announceParseToken = \_ _ -> return () 920 , announceParseToken = \_ _ -> return ()
@@ -874,6 +925,7 @@ main = do
874 Just _ -> return Nothing 925 Just _ -> return Nothing
875 , announceInterval = 0 -- TODO: The "port" setting should probably 926 , announceInterval = 0 -- TODO: The "port" setting should probably
876 -- be a command rather than an announcement. 927 -- be a command rather than an announcement.
928 , qresultAddr = const $ Mainline.zeroID
877 })] 929 })]
878 930
879 , dhtLinks = Map.fromList 931 , dhtLinks = Map.fromList
@@ -930,7 +982,6 @@ main = do
930 . Tox.GetNodes) 982 . Tox.GetNodes)
931 , qshowR = show -- NodeInfo 983 , qshowR = show -- NodeInfo
932 , qshowTok = (const Nothing) 984 , qshowTok = (const Nothing)
933 , qresultAddr = Tox.nodeId
934 }) 985 })
935 , ("toxid", DHTQuery 986 , ("toxid", DHTQuery
936 { qsearch = (Tox.toxidSearch (Tox.onionTimeout tox) 987 { qsearch = (Tox.toxidSearch (Tox.onionTimeout tox)
@@ -946,8 +997,7 @@ main = do
946 (Tox.OnionDestination Tox.SearchingAlias ni Nothing) 997 (Tox.OnionDestination Tox.SearchingAlias ni Nothing)
947 (Tox.AnnounceRequest zeros32 nid Tox.zeroID)) 998 (Tox.AnnounceRequest zeros32 nid Tox.zeroID))
948 , qshowR = show -- Rendezvous 999 , qshowR = show -- Rendezvous
949 , qshowTok = (fmap show) -- Nonce32 1000 , qshowTok = Just . show -- Nonce32
950 , qresultAddr = Tox.key2id . Tox.rendezvousKey
951 }) 1001 })
952 ] 1002 ]
953 , dhtParseId = readEither :: String -> Either String Tox.NodeId 1003 , dhtParseId = readEither :: String -> Either String Tox.NodeId
@@ -967,6 +1017,7 @@ main = do
967 , announceParseAddress = readEither 1017 , announceParseAddress = readEither
968 , announceParseToken = const $ readEither 1018 , announceParseToken = const $ readEither
969 , announceParseData = fmap Tox.id2key . readEither 1019 , announceParseData = fmap Tox.id2key . readEither
1020 , qresultAddr = Tox.key2id -- toxid
970 1021
971 -- For peers we are announcing ourselves to, if we are not 1022 -- For peers we are announcing ourselves to, if we are not
972 -- announced to them toxcore tries every 3 seconds to 1023 -- announced to them toxcore tries every 3 seconds to
@@ -995,6 +1046,7 @@ main = do
995 , announceParseAddress = readEither 1046 , announceParseAddress = readEither
996 , announceParseToken = \_ _ -> return () 1047 , announceParseToken = \_ _ -> return ()
997 , announceParseData = fmap Tox.id2key . readEither 1048 , announceParseData = fmap Tox.id2key . readEither
1049 , qresultAddr = Tox.key2id
998 1050
999 -- We send this packet every 30 seconds if there is more 1051 -- We send this packet every 30 seconds if there is more
1000 -- than one peer (in the 8) that says they our friend is 1052 -- than one peer (in the 8) that says they our friend is
@@ -1032,6 +1084,7 @@ main = do
1032 (Tox.verifyChecksum pubkey) 1084 (Tox.verifyChecksum pubkey)
1033 chksum 1085 chksum
1034 return nospam 1086 return nospam
1087 , qresultAddr = Tox.key2id
1035 1088
1036 -- Friend requests are sent with exponentially increasing 1089 -- Friend requests are sent with exponentially increasing
1037 -- interval of 2 seconds, 4 seconds, 8 seconds, etc... in 1090 -- interval of 2 seconds, 4 seconds, 8 seconds, etc... in