summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/DHT')
-rw-r--r--src/Network/BitTorrent/DHT/Session.hs27
1 files changed, 21 insertions, 6 deletions
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