diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT.hs | 58 |
1 files changed, 16 insertions, 42 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs index 7f1fa295..7c892349 100644 --- a/src/Network/BitTorrent/DHT.hs +++ b/src/Network/BitTorrent/DHT.hs | |||
@@ -77,20 +77,6 @@ handlers :: Address ip => [NodeHandler ip] | |||
77 | handlers = [pingH, findNodeH, getPeersH, announceH] | 77 | handlers = [pingH, findNodeH, getPeersH, announceH] |
78 | 78 | ||
79 | {----------------------------------------------------------------------- | 79 | {----------------------------------------------------------------------- |
80 | -- Query | ||
81 | -----------------------------------------------------------------------} | ||
82 | |||
83 | findNodeQ :: Address ip => NodeId -> Iteration ip NodeAddr NodeInfo | ||
84 | findNodeQ nid addr = do | ||
85 | NodeFound closest <- FindNode nid <@> addr | ||
86 | return $ Right closest | ||
87 | |||
88 | getPeersQ :: Address ip => InfoHash -> Iteration ip NodeInfo PeerAddr | ||
89 | getPeersQ topic NodeInfo {..} = do | ||
90 | GotPeers {..} <- GetPeers topic <@> nodeAddr | ||
91 | return peers | ||
92 | |||
93 | {----------------------------------------------------------------------- | ||
94 | -- DHT operations | 80 | -- DHT operations |
95 | -----------------------------------------------------------------------} | 81 | -----------------------------------------------------------------------} |
96 | 82 | ||
@@ -107,48 +93,36 @@ dht = runDHT handlers | |||
107 | -- usually obtained from 'Data.Torrent.tNodes' field. Bootstrapping | 93 | -- usually obtained from 'Data.Torrent.tNodes' field. Bootstrapping |
108 | -- process can take up to 5 minutes. | 94 | -- process can take up to 5 minutes. |
109 | -- | 95 | -- |
110 | -- (TODO) This operation is asynchronous and do not block. | 96 | -- This operation is synchronous and do block, use 'async' if needed. |
111 | -- | 97 | -- |
112 | bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () | 98 | bootstrap :: Address ip => [NodeAddr ip] -> DHT ip () |
113 | bootstrap startNodes = do | 99 | bootstrap startNodes = do |
114 | $(logInfoS) "bootstrap" "Start node bootstrapping" | 100 | $(logInfoS) "bootstrap" "Start node bootstrapping" |
115 | M.mapM_ insertClosest startNodes | 101 | nid <- getNodeId |
116 | $(logInfoS) "bootstrap" "Node bootstrapping finished" | 102 | aliveNodes <- queryParallel (ping <$> startNodes) |
117 | where | 103 | _ <- sourceList [aliveNodes] $= search nid (findNodeQ nid) $$ C.consume |
118 | insertClosest addr = do | 104 | $(logInfoS) "bootstrap" "Node bootstrapping finished" |
119 | t <- getTable | 105 | -- t <- getTable |
120 | unless (full t) $ do | 106 | -- unless (full t) $ do |
121 | nid <- getNodeId | 107 | -- nid <- getNodeId |
122 | result <- try $ FindNode nid <@> addr | ||
123 | case result of | ||
124 | Left e -> do | ||
125 | $(logWarnS) "bootstrap" $ T.pack $ show (e :: QueryFailure) | ||
126 | |||
127 | Right (NodeFound closest) -> do | ||
128 | $(logDebug) $ "Get a list of closest nodes: " <> | ||
129 | T.pack (PP.render (pretty closest)) | ||
130 | forM_ closest $ \ info @ NodeInfo {..} -> do | ||
131 | let prettyAddr = T.pack (show (pretty nodeAddr)) | ||
132 | $(logInfoS) "bootstrap" $ "table detalization" <> prettyAddr | ||
133 | insertClosest nodeAddr | ||
134 | 108 | ||
135 | -- | Get list of peers which downloading this torrent. | 109 | -- | Get list of peers which downloading this torrent. |
136 | -- | 110 | -- |
137 | -- (TODO) This operation is synchronous and do block. | 111 | -- This operation is incremental and do block. |
138 | -- | 112 | -- |
139 | lookup :: Address ip => InfoHash -> DHT ip `Source` [PeerAddr ip] | 113 | lookup :: Address ip => InfoHash -> DHT ip `Source` [PeerAddr ip] |
140 | lookup topic = do -- TODO retry getClosestHash if bucket is empty | 114 | lookup topic = do -- TODO retry getClosest if bucket is empty |
141 | closest <- lift $ getClosestHash topic | 115 | closest <- lift $ getClosest topic |
142 | sourceList [closest] $= search (getPeersQ topic) | 116 | sourceList [closest] $= search topic (getPeersQ topic) |
143 | 117 | ||
144 | -- | Announce that /this/ peer may have some pieces of the specified | 118 | -- | Announce that /this/ peer may have some pieces of the specified |
145 | -- torrent. | 119 | -- torrent. |
146 | -- | 120 | -- |
147 | -- (TODO) This operation is asynchronous and do not block. | 121 | -- This operation is synchronous and do block, use 'async' if needed. |
148 | -- | 122 | -- |
149 | insert :: Address ip => InfoHash -> PortNumber -> DHT ip () | 123 | insert :: Address ip => InfoHash -> PortNumber -> DHT ip () |
150 | insert ih port = do | 124 | insert ih port = do |
151 | nodes <- getClosestHash ih | 125 | nodes <- getClosest ih |
152 | forM_ (nodeAddr <$> nodes) $ \ addr -> do | 126 | forM_ (nodeAddr <$> nodes) $ \ addr -> do |
153 | -- GotPeers {..} <- GetPeers ih <@> addr | 127 | -- GotPeers {..} <- GetPeers ih <@> addr |
154 | -- Announced <- Announce False ih undefined grantedToken <@> addr | 128 | -- Announced <- Announce False ih undefined grantedToken <@> addr |
@@ -156,7 +130,7 @@ insert ih port = do | |||
156 | 130 | ||
157 | -- | Stop announcing /this/ peer for the specified torrent. | 131 | -- | Stop announcing /this/ peer for the specified torrent. |
158 | -- | 132 | -- |
159 | -- This operation is atomic and do not block. | 133 | -- This operation is atomic and may block for a while. |
160 | -- | 134 | -- |
161 | delete :: Address ip => InfoHash -> DHT ip () | 135 | delete :: Address ip => InfoHash -> DHT ip () |
162 | delete = error "DHT.delete: not implemented" \ No newline at end of file | 136 | delete = error "DHT.delete: not implemented" \ No newline at end of file |