diff options
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r-- | examples/dhtd.hs | 121 |
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 | ||
122 | data DHTAnnouncable = forall dta tok ni r. | 121 | data 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 | ||
136 | data DHTLink = forall status linkid params. | 136 | data 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 () |
259 | reportResult meth showR showTok showN h (Left e) = hPutClient h e | 259 | reportResult meth showR showTok showN h (Left e) = hPutClient h e |
260 | reportResult meth showR showTok showN h (Right (ns,rs,tok)) = do | 260 | reportResult 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 | ||
351 | data Session = Session | 351 | data 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 |