diff options
Diffstat (limited to 'examples')
-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 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 | ||
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 |
@@ -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 |