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 c8929e89..f54c5249 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
@@ -602,38 +602,81 @@ clientSession s@Session{..} sock cnum h = do
602 (dtastr,ys) = break isSpace $ dropWhile isSpace xs 602 (dtastr,ys) = break isSpace $ dropWhile isSpace xs
603 a = Map.lookup method dhtAnnouncables 603 a = Map.lookup method dhtAnnouncables
604 q = Map.lookup method dhtQuery 604 q = Map.lookup method dhtQuery
605 doit :: Char -> proxy ni -> Announcer -> AnnounceKey -> AnnounceMethod r -> r -> IO () 605 doit :: Char -> Announcer -> AnnounceKey -> AnnounceMethod r -> r -> IO ()
606 doit '+' _ = schedule 606 doit '+' = schedule
607 doit '-' _ = cancel 607 doit '-' = cancel
608 doit _ _ = \_ _ _ _ -> hPutClient h "Starting(+) or canceling(-)?" 608 doit _ = \_ _ _ _ -> hPutClient h "Starting(+) or canceling(-)?"
609 matchingResult :: 609 matchingResult ::
610 ( Typeable sr 610 ( Typeable stok
611 , Typeable stok 611 , Typeable ptok
612 , Typeable sni
613 , Typeable pni )
614 => Search nid addr stok sni sr
615 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
616 -> Maybe (stok :~: ptok, sni :~: pni)
617 matchingResult _ _ = liftA2 (,) eqT eqT
618 matchingTok ::
619 ( Typeable stok
620 , Typeable ptok
612 , Typeable sni 621 , Typeable sni
613 , Typeable pr 622 , Typeable pni )
623 => Search nid addr stok sni sr
624 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
625 -> Maybe (stok :~: ptok)
626 matchingTok _ _ = eqT
627 matchingNI ::
628 ( Typeable stok
614 , Typeable ptok 629 , Typeable ptok
630 , Typeable sni
615 , Typeable pni ) 631 , Typeable pni )
616 => Search nid addr stok sni sr 632 => Search nid addr stok sni sr
617 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr)) 633 -> (pr -> ptok -> Maybe pni -> IO (Maybe pubr))
618 -> Maybe (sr :~: pr, stok :~: ptok, sni :~: pni ) 634 -> Maybe (sni :~: pni)
619 matchingResult _ _ = liftA3 (\a b c -> (a,b,c)) eqT eqT eqT 635 matchingNI _ _ = eqT
636 chktok :: Maybe ()
637 chktok = do
638 DHTAnnouncable { announceSendData
639 , announceParseData
640 , announceInterval
641 , qresultAddr } <- a
642 DHTQuery { qsearch } <- q
643 Refl <- matchingTok qsearch announceSendData
644 return ()
645 chkni :: Maybe ()
646 chkni = do
647 DHTAnnouncable { announceSendData
648 , announceParseData
649 , announceInterval
650 , qresultAddr } <- a
651 DHTQuery { qsearch } <- q
652 Refl <- matchingNI qsearch announceSendData
653 return ()
620 mameth = do 654 mameth = do
621 DHTAnnouncable { announceSendData 655 DHTAnnouncable { announceSendData
622 , announceParseData 656 , announceParseData
623 , announceInterval } <- a 657 , announceInterval
624 DHTQuery { qsearch 658 , qresultAddr } <- a
625 , qresultAddr } <- q 659 DHTQuery { qsearch } <- q
626 (Refl,Refl,nr@Refl) <- matchingResult qsearch announceSendData 660 (Refl, Refl) <- matchingResult qsearch announceSendData
661 -- return $ hPutClient h "Type matches."
627 dta <- either (const Nothing) Just $ announceParseData dtastr 662 dta <- either (const Nothing) Just $ announceParseData dtastr
628 return $ do 663 return $ do
629 akey <- atomically $ packAnnounceKey announcer (method ++ ":" ++ dtastr) 664 akey <- atomically $ packAnnounceKey announcer (method ++ ":" ++ dtastr)
630 doit op nr announcer 665 doit op announcer
631 akey 666 akey
632 (AnnounceMethod qsearch announceSendData dhtBuckets 667 (AnnounceMethod qsearch announceSendData dhtBuckets
633 (qresultAddr dta) 668 (qresultAddr dta)
634 announceInterval) 669 announceInterval)
635 dta 670 dta
636 fromMaybe (hPutClient h "error.") mameth 671 let aerror = unlines
672 [ "announce error."
673 , "method = " ++ method
674 , "query = " ++ maybe "nil" (const "ok") q
675 , "publish = " ++ maybe "nil" (const "ok") a
676 , "chktok = " ++ maybe "nil" (const "ok") chktok -- chktok = nil
677 , "chkni = " ++ maybe "nil" (const "ok") chkni
678 ]
679 fromMaybe (hPutClient h aerror) mameth
637 680
638 ("s", s) | Just dht@DHT{..} <- Map.lookup netname dhts 681 ("s", s) | Just dht@DHT{..} <- Map.lookup netname dhts
639 -> cmd0 $ do 682 -> cmd0 $ do
@@ -838,8 +881,11 @@ main = do
838 . flip Mainline.FindNode (Just Want_Both)) 881 . flip Mainline.FindNode (Just Want_Both))
839 , qshowR = show 882 , qshowR = show
840 , qshowTok = (const Nothing) 883 , qshowTok = (const Nothing)
841 , qresultAddr = Mainline.nodeId
842 }) 884 })
885 -- Maybe (sr :~: pr, stok :~: ptok, sni :~: pni )
886 -- sr = InfoHash
887 -- stok = Token
888 -- sni = NodeInfo
843 , ("peer", DHTQuery 889 , ("peer", DHTQuery
844 { qsearch = (Mainline.peerSearch bt) 890 { qsearch = (Mainline.peerSearch bt)
845 , qhandler = (\ni -> fmap Mainline.unwrapPeers 891 , qhandler = (\ni -> fmap Mainline.unwrapPeers
@@ -848,13 +894,17 @@ main = do
848 . (read . show)) -- TODO: InfoHash -> NodeId 894 . (read . show)) -- TODO: InfoHash -> NodeId
849 , qshowR = (show . pPrint) 895 , qshowR = (show . pPrint)
850 , qshowTok = (Just . show) 896 , qshowTok = (Just . show)
851 , qresultAddr = (read . show) -- TODO: InfoHash -> NodeId
852 }) 897 })
853 ] 898 ]
854 , dhtParseId = readEither :: String -> Either String Mainline.NodeId 899 , dhtParseId = readEither :: String -> Either String Mainline.NodeId
855 , dhtSearches = mainlineSearches 900 , dhtSearches = mainlineSearches
856 , dhtFallbackNodes = Mainline.bootstrapNodes wantip 901 , dhtFallbackNodes = Mainline.bootstrapNodes wantip
857 , dhtAnnouncables = Map.fromList 902 , dhtAnnouncables = Map.fromList
903 -- Maybe (sr :~: pr, stok :~: ptok, sni :~: pni )
904 -- dta = Announce
905 -- pr = Announced
906 -- ptok = Token
907 -- pni = NodeInfo
858 [ ("peer", DHTAnnouncable { announceSendData = \ih tok -> \case 908 [ ("peer", DHTAnnouncable { announceSendData = \ih tok -> \case
859 Just ni -> do 909 Just ni -> do
860 port <- atomically $ readTVar peerPort 910 port <- atomically $ readTVar peerPort
@@ -865,6 +915,7 @@ main = do
865 , announceParseData = readEither 915 , announceParseData = readEither
866 , announceParseToken = const $ readEither 916 , announceParseToken = const $ readEither
867 , announceInterval = 60 -- TODO: Is one minute good? 917 , announceInterval = 60 -- TODO: Is one minute good?
918 , qresultAddr = (read . show) -- TODO: InfoHash -> NodeId -- peer
868 }) 919 })
869 , ("port", DHTAnnouncable { announceParseData = readEither 920 , ("port", DHTAnnouncable { announceParseData = readEither
870 , announceParseToken = \_ _ -> return () 921 , announceParseToken = \_ _ -> return ()
@@ -875,6 +926,7 @@ main = do
875 Just _ -> return Nothing 926 Just _ -> return Nothing
876 , announceInterval = 0 -- TODO: The "port" setting should probably 927 , announceInterval = 0 -- TODO: The "port" setting should probably
877 -- be a command rather than an announcement. 928 -- be a command rather than an announcement.
929 , qresultAddr = const $ Mainline.zeroID
878 })] 930 })]
879 931
880 , dhtLinks = Map.fromList 932 , dhtLinks = Map.fromList
@@ -932,7 +984,6 @@ main = do
932 . Tox.GetNodes) 984 . Tox.GetNodes)
933 , qshowR = show -- NodeInfo 985 , qshowR = show -- NodeInfo
934 , qshowTok = (const Nothing) 986 , qshowTok = (const Nothing)
935 , qresultAddr = Tox.nodeId
936 }) 987 })
937 , ("toxid", DHTQuery 988 , ("toxid", DHTQuery
938 { qsearch = (Tox.toxidSearch (Tox.onionTimeout tox) 989 { qsearch = (Tox.toxidSearch (Tox.onionTimeout tox)
@@ -948,8 +999,7 @@ main = do
948 (Tox.OnionDestination Tox.SearchingAlias ni Nothing) 999 (Tox.OnionDestination Tox.SearchingAlias ni Nothing)
949 (Tox.AnnounceRequest zeros32 nid Tox.zeroID)) 1000 (Tox.AnnounceRequest zeros32 nid Tox.zeroID))
950 , qshowR = show -- Rendezvous 1001 , qshowR = show -- Rendezvous
951 , qshowTok = (fmap show) -- Nonce32 1002 , qshowTok = Just . show -- Nonce32
952 , qresultAddr = Tox.key2id . Tox.rendezvousKey
953 }) 1003 })
954 ] 1004 ]
955 , dhtParseId = readEither :: String -> Either String Tox.NodeId 1005 , dhtParseId = readEither :: String -> Either String Tox.NodeId
@@ -969,6 +1019,7 @@ main = do
969 , announceParseAddress = readEither 1019 , announceParseAddress = readEither
970 , announceParseToken = const $ readEither 1020 , announceParseToken = const $ readEither
971 , announceParseData = fmap Tox.id2key . readEither 1021 , announceParseData = fmap Tox.id2key . readEither
1022 , qresultAddr = Tox.key2id -- toxid
972 1023
973 -- For peers we are announcing ourselves to, if we are not 1024 -- For peers we are announcing ourselves to, if we are not
974 -- announced to them toxcore tries every 3 seconds to 1025 -- announced to them toxcore tries every 3 seconds to
@@ -997,6 +1048,7 @@ main = do
997 , announceParseAddress = readEither 1048 , announceParseAddress = readEither
998 , announceParseToken = \_ _ -> return () 1049 , announceParseToken = \_ _ -> return ()
999 , announceParseData = fmap Tox.id2key . readEither 1050 , announceParseData = fmap Tox.id2key . readEither
1051 , qresultAddr = Tox.key2id
1000 1052
1001 -- We send this packet every 30 seconds if there is more 1053 -- We send this packet every 30 seconds if there is more
1002 -- than one peer (in the 8) that says they our friend is 1054 -- than one peer (in the 8) that says they our friend is
@@ -1034,6 +1086,7 @@ main = do
1034 (Tox.verifyChecksum pubkey) 1086 (Tox.verifyChecksum pubkey)
1035 chksum 1087 chksum
1036 return nospam 1088 return nospam
1089 , qresultAddr = Tox.key2id
1037 1090
1038 -- Friend requests are sent with exponentially increasing 1091 -- Friend requests are sent with exponentially increasing
1039 -- interval of 2 seconds, 4 seconds, 8 seconds, etc... in 1092 -- interval of 2 seconds, 4 seconds, 8 seconds, etc... in