summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/DHT.hs9
-rw-r--r--src/Network/BitTorrent/DHT/Session.hs27
2 files changed, 23 insertions, 13 deletions
diff --git a/src/Network/BitTorrent/DHT.hs b/src/Network/BitTorrent/DHT.hs
index 41a76886..5cf7468e 100644
--- a/src/Network/BitTorrent/DHT.hs
+++ b/src/Network/BitTorrent/DHT.hs
@@ -35,7 +35,6 @@ import Data.List as L
35import Data.Monoid 35import Data.Monoid
36import Data.Text as T 36import Data.Text as T
37import Network.Socket (PortNumber) 37import Network.Socket (PortNumber)
38import System.Timeout.Lifted
39import Text.PrettyPrint as PP hiding ((<>)) 38import Text.PrettyPrint as PP hiding ((<>))
40import Text.PrettyPrint.Class 39import Text.PrettyPrint.Class
41 40
@@ -103,16 +102,12 @@ bootstrap startNodes = do
103 where 102 where
104 insertClosest addr = do 103 insertClosest addr = do
105 nid <- getNodeId 104 nid <- getNodeId
106 result <- try $ timeout 1000000 $ FindNode nid <@> addr 105 result <- try $ FindNode nid <@> addr
107 case result of 106 case result of
108 Left e -> do 107 Left e -> do
109 $(logWarnS) "bootstrap" $ T.pack $ show (e :: IOError) 108 $(logWarnS) "bootstrap" $ T.pack $ show (e :: IOError)
110 109
111 Right Nothing -> do 110 Right (NodeFound closest) -> do
112 $(logWarnS) "bootstrap" $ "not responding @ "
113 <> T.pack (show (pretty addr))
114
115 Right (Just (NodeFound closest)) -> do
116 $(logDebug) ("Get a list of closest nodes: " <> 111 $(logDebug) ("Get a list of closest nodes: " <>
117 T.pack (PP.render (pretty closest))) 112 T.pack (PP.render (pretty closest)))
118 forM_ (L.take 2 closest) $ \ info @ NodeInfo {..} -> do 113 forM_ (L.take 2 closest) $ \ info @ NodeInfo {..} -> do
diff --git a/src/Network/BitTorrent/DHT/Session.hs b/src/Network/BitTorrent/DHT/Session.hs
index ac285bdc..a76880d7 100644
--- a/src/Network/BitTorrent/DHT/Session.hs
+++ b/src/Network/BitTorrent/DHT/Session.hs
@@ -48,6 +48,7 @@ import Control.Monad.Reader
48import Control.Monad.Trans.Control 48import Control.Monad.Trans.Control
49import Control.Monad.Trans.Resource 49import Control.Monad.Trans.Resource
50import Data.Default 50import Data.Default
51import Data.Fixed
51import Data.Hashable 52import Data.Hashable
52import Data.List as L 53import Data.List as L
53import Data.Monoid 54import Data.Monoid
@@ -57,6 +58,7 @@ import Data.Time
57import Data.Time.Clock.POSIX 58import Data.Time.Clock.POSIX
58import System.Log.FastLogger 59import System.Log.FastLogger
59import System.Random (randomIO) 60import System.Random (randomIO)
61import System.Timeout.Lifted
60import Text.PrettyPrint as PP hiding ((<>)) 62import Text.PrettyPrint as PP hiding ((<>))
61import Text.PrettyPrint.Class 63import Text.PrettyPrint.Class
62 64
@@ -101,6 +103,11 @@ instance Default Options where
101 , optTimeout = 5 -- seconds 103 , optTimeout = 5 -- seconds
102 } 104 }
103 105
106milliseconds :: NominalDiffTime -> Int
107milliseconds dt = fromEnum millis
108 where
109 millis = realToFrac dt :: Milli
110
104{----------------------------------------------------------------------- 111{-----------------------------------------------------------------------
105-- Tokens policy 112-- Tokens policy
106-----------------------------------------------------------------------} 113-----------------------------------------------------------------------}
@@ -185,11 +192,9 @@ runDHT handlers opts naddr action = runResourceT $ do
185-- Routing 192-- Routing
186-----------------------------------------------------------------------} 193-----------------------------------------------------------------------}
187 194
188-- TODO fork?
189routing :: Address ip => Routing ip a -> DHT ip (Maybe a) 195routing :: Address ip => Routing ip a -> DHT ip (Maybe a)
190routing = runRouting ping refreshNodes getTimestamp 196routing = runRouting ping refreshNodes getTimestamp
191 197
192-- TODO add timeout
193ping :: Address ip => NodeAddr ip -> DHT ip Bool 198ping :: Address ip => NodeAddr ip -> DHT ip Bool
194ping addr = do 199ping addr = do
195 $(logDebugS) "routing.questionable_node" (T.pack (render (pretty addr))) 200 $(logDebugS) "routing.questionable_node" (T.pack (render (pretty addr)))
@@ -250,6 +255,7 @@ getTable = do
250 var <- asks routingTable 255 var <- asks routingTable
251 liftIO (readMVar var) 256 liftIO (readMVar var)
252 257
258-- FIXME no blocking
253getNodeId :: DHT ip NodeId 259getNodeId :: DHT ip NodeId
254getNodeId = thisId <$> getTable 260getNodeId = thisId <$> getTable
255 261
@@ -305,6 +311,7 @@ getPeerList ih = do
305-- Messaging 311-- Messaging
306-----------------------------------------------------------------------} 312-----------------------------------------------------------------------}
307 313
314-- | Throws exception if node is not responding.
308(<@>) :: forall a b ip. Address ip => KRPC (Query a) (Response b) 315(<@>) :: forall a b ip. Address ip => KRPC (Query a) (Response b)
309 => a -> NodeAddr ip -> DHT ip b 316 => a -> NodeAddr ip -> DHT ip b
310q <@> addr = do 317q <@> addr = do
@@ -313,11 +320,19 @@ q <@> addr = do
313 let Method name = method :: Method (Query a) (Response b) 320 let Method name = method :: Method (Query a) (Response b)
314 let signature = T.decodeUtf8 name <> " @ " <> T.pack (render (pretty addr)) 321 let signature = T.decodeUtf8 name <> " @ " <> T.pack (render (pretty addr))
315 $(logDebugS) "queryNode" $ "Query sent | " <> signature 322 $(logDebugS) "queryNode" $ "Query sent | " <> signature
316 Response remoteId r <- query (toSockAddr addr) (Query nid q)
317 $(logDebugS) "queryNode" $ "Query recv | " <> signature
318 323
319 insertNode (NodeInfo remoteId addr) 324 interval <- asks (milliseconds . optTimeout . options)
320 return r 325 result <- timeout interval $ query (toSockAddr addr) (Query nid q)
326 case result of
327 Nothing -> do
328 $(logWarnS) "queryNode" $ "not responding @ "
329 <> T.pack (show (pretty addr))
330 throwIO $ KError GenericError "timeout expired" ""
331
332 Just (Response remoteId r) -> do
333 $(logDebugS) "queryNode" $ "Query recv | " <> signature
334 insertNode (NodeInfo remoteId addr)
335 return r
321 336
322type NodeHandler ip = Handler (DHT ip) 337type NodeHandler ip = Handler (DHT ip)
323 338