diff options
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r-- | src/Network/BitTorrent/MainlineDHT.hs | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/Network/BitTorrent/MainlineDHT.hs b/src/Network/BitTorrent/MainlineDHT.hs index 83865c98..89851e88 100644 --- a/src/Network/BitTorrent/MainlineDHT.hs +++ b/src/Network/BitTorrent/MainlineDHT.hs | |||
@@ -563,7 +563,7 @@ newClient swarms addr = do | |||
563 | -- We defer initializing the refreshSearch and refreshPing until we | 563 | -- We defer initializing the refreshSearch and refreshPing until we |
564 | -- have a client to send queries with. | 564 | -- have a client to send queries with. |
565 | let nullPing = const $ return False | 565 | let nullPing = const $ return False |
566 | nullSearch = mainlineSearch $ \_ _ -> return Nothing | 566 | nullSearch = mainlineSearch $ Left $ \_ _ -> return Nothing |
567 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info R.defaultBucketCount | 567 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info R.defaultBucketCount |
568 | refresher4 <- newBucketRefresher tbl4 nullSearch nullPing | 568 | refresher4 <- newBucketRefresher tbl4 nullSearch nullPing |
569 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount | 569 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount |
@@ -1035,13 +1035,36 @@ mainlineSend :: ( BEncode a | |||
1035 | -> NodeInfo | 1035 | -> NodeInfo |
1036 | -> IO (Maybe b) | 1036 | -> IO (Maybe b) |
1037 | mainlineSend meth unwrap msg client nid addr = do | 1037 | mainlineSend meth unwrap msg client nid addr = do |
1038 | reply <- sendQuery client serializer (msg nid) addr | 1038 | reply <- sendQuery client (mainlineSerializeer meth unwrap client) (msg nid) addr |
1039 | -- sendQuery will return (Just (Left _)) on a parse error. We're going to | 1039 | -- sendQuery will return (Just (Left _)) on a parse error. We're going to |
1040 | -- blow it away with the join-either sequence. | 1040 | -- blow it away with the join-either sequence. |
1041 | -- TODO: Do something with parse errors. | 1041 | -- TODO: Do something with parse errors. |
1042 | return $ join $ either (const Nothing) Just <$> reply | 1042 | return $ join $ either (const Nothing) Just <$> reply |
1043 | where | 1043 | |
1044 | serializer = MethodSerializer | 1044 | mainlineAsync :: (BEncode a1, BEncode a2) => |
1045 | Method | ||
1046 | -> (a2 -> a3) | ||
1047 | -> (t -> a1) | ||
1048 | -> Client String Method TransactionId NodeInfo (Message BValue) | ||
1049 | -> t | ||
1050 | -> NodeInfo | ||
1051 | -> (Maybe a3 -> IO ()) | ||
1052 | -> IO () | ||
1053 | mainlineAsync meth unwrap msg client nid addr onresult = do | ||
1054 | asyncQuery client (mainlineSerializeer meth unwrap client) (msg nid) addr | ||
1055 | $ \reply -> | ||
1056 | -- sendQuery will return (Just (Left _)) on a parse error. We're going to | ||
1057 | -- blow it away with the join-either sequence. | ||
1058 | -- TODO: Do something with parse errors. | ||
1059 | onresult $ join $ either (const Nothing) Just <$> reply | ||
1060 | |||
1061 | mainlineSerializeer :: (BEncode a2, BEncode a1) => | ||
1062 | Method | ||
1063 | -> (a2 -> b) | ||
1064 | -> MainlineClient | ||
1065 | -> MethodSerializer | ||
1066 | TransactionId NodeInfo (Message BValue) Method a1 (Either Error b) | ||
1067 | mainlineSerializeer meth unwrap client = MethodSerializer | ||
1045 | { methodTimeout = \_ ni -> return (ni, 5000000) | 1068 | { methodTimeout = \_ ni -> return (ni, 5000000) |
1046 | , method = meth | 1069 | , method = meth |
1047 | , wrapQuery = encodeQueryPayload meth (isReadonlyClient client) | 1070 | , wrapQuery = encodeQueryPayload meth (isReadonlyClient client) |
@@ -1060,30 +1083,45 @@ ping client addr = | |||
1060 | getNodes :: MainlineClient -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) | 1083 | getNodes :: MainlineClient -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) |
1061 | getNodes = mainlineSend (Method "find_node") unwrapNodes $ flip FindNode (Just Want_Both) | 1084 | getNodes = mainlineSend (Method "find_node") unwrapNodes $ flip FindNode (Just Want_Both) |
1062 | 1085 | ||
1086 | asyncGetNodes :: Client String Method TransactionId NodeInfo (Message BValue) | ||
1087 | -> NodeId | ||
1088 | -> NodeInfo | ||
1089 | -> (Maybe ([NodeInfo], [NodeInfo], Maybe ()) -> IO ()) | ||
1090 | -> IO () | ||
1091 | asyncGetNodes = mainlineAsync (Method "find_node") unwrapNodes $ flip FindNode (Just Want_Both) | ||
1092 | |||
1063 | unwrapNodes :: NodeFound -> ([NodeInfo], [NodeInfo], Maybe ()) | 1093 | unwrapNodes :: NodeFound -> ([NodeInfo], [NodeInfo], Maybe ()) |
1064 | unwrapNodes (NodeFound ns4 ns6) = (ns4++ns6, ns4++ns6, Just ()) | 1094 | unwrapNodes (NodeFound ns4 ns6) = (ns4++ns6, ns4++ns6, Just ()) |
1065 | 1095 | ||
1066 | getPeers :: MainlineClient -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[PeerAddr],Maybe Token)) | 1096 | getPeers :: MainlineClient -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[PeerAddr],Maybe Token)) |
1067 | getPeers = mainlineSend (Method "get_peers") unwrapPeers $ flip GetPeers (Just Want_Both) . coerce | 1097 | getPeers = mainlineSend (Method "get_peers") unwrapPeers $ flip GetPeers (Just Want_Both) . coerce |
1068 | 1098 | ||
1099 | asyncGetPeers :: Client String Method TransactionId NodeInfo (Message BValue) | ||
1100 | -> NodeId | ||
1101 | -> NodeInfo | ||
1102 | -> (Maybe ([NodeInfo], [PeerAddr], Maybe Token) -> IO ()) | ||
1103 | -> IO () | ||
1104 | asyncGetPeers = mainlineAsync (Method "get_peers") unwrapPeers $ flip GetPeers (Just Want_Both) . coerce | ||
1105 | |||
1069 | unwrapPeers :: GotPeers -> ([NodeInfo], [PeerAddr], Maybe Token) | 1106 | unwrapPeers :: GotPeers -> ([NodeInfo], [PeerAddr], Maybe Token) |
1070 | unwrapPeers (GotPeers ps (NodeFound ns4 ns6) tok) = (ns4++ns6, ps, Just tok) | 1107 | unwrapPeers (GotPeers ps (NodeFound ns4 ns6) tok) = (ns4++ns6, ps, Just tok) |
1071 | 1108 | ||
1072 | mainlineSearch :: (NodeId -> NodeInfo -> IO (Maybe ([NodeInfo], [r], Maybe tok))) | 1109 | mainlineSearch :: Either (NodeId -> NodeInfo -> IO (Maybe ([NodeInfo], [r], Maybe tok))) |
1110 | (NodeId -> NodeInfo -> (Maybe ([NodeInfo], [r], Maybe tok) -> IO ()) -> IO ()) | ||
1073 | -> Search NodeId (IP, PortNumber) tok NodeInfo r | 1111 | -> Search NodeId (IP, PortNumber) tok NodeInfo r |
1074 | mainlineSearch qry = Search | 1112 | mainlineSearch qry = Search |
1075 | { searchSpace = mainlineSpace | 1113 | { searchSpace = mainlineSpace |
1076 | , searchNodeAddress = nodeIP &&& nodePort | 1114 | , searchNodeAddress = nodeIP &&& nodePort |
1077 | , searchQuery = Left qry | 1115 | , searchQuery = qry |
1078 | , searchAlpha = 8 | 1116 | , searchAlpha = 8 |
1079 | , searchK = 16 | 1117 | , searchK = 16 |
1080 | } | 1118 | } |
1081 | 1119 | ||
1082 | nodeSearch :: MainlineClient -> Search NodeId (IP, PortNumber) () NodeInfo NodeInfo | 1120 | nodeSearch :: MainlineClient -> Search NodeId (IP, PortNumber) () NodeInfo NodeInfo |
1083 | nodeSearch client = mainlineSearch (getNodes client) | 1121 | nodeSearch client = mainlineSearch (Right $ asyncGetNodes client) |
1084 | 1122 | ||
1085 | peerSearch :: MainlineClient -> Search NodeId (IP, PortNumber) Token NodeInfo PeerAddr | 1123 | peerSearch :: MainlineClient -> Search NodeId (IP, PortNumber) Token NodeInfo PeerAddr |
1086 | peerSearch client = mainlineSearch (getPeers client) | 1124 | peerSearch client = mainlineSearch (Right $ asyncGetPeers client) |
1087 | 1125 | ||
1088 | -- | List of bootstrap nodes maintained by different bittorrent | 1126 | -- | List of bootstrap nodes maintained by different bittorrent |
1089 | -- software authors. | 1127 | -- software authors. |