summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-12-11 09:38:59 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-12-11 09:38:59 +0400
commit8e4d3bc8f70f10a45ef86a1a3ec3403d1a78d41c (patch)
treeee1ab220b3d5f5e9b3191a33775670a4f7a66367 /src/Network/BitTorrent
parent0fc63838689b0bc35ea511137bb0fe31b528090e (diff)
Add basic options datatype
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/Exchange/Wire.hs79
1 files changed, 74 insertions, 5 deletions
diff --git a/src/Network/BitTorrent/Exchange/Wire.hs b/src/Network/BitTorrent/Exchange/Wire.hs
index baf76e5f..9b83590a 100644
--- a/src/Network/BitTorrent/Exchange/Wire.hs
+++ b/src/Network/BitTorrent/Exchange/Wire.hs
@@ -29,6 +29,9 @@ module Network.BitTorrent.Exchange.Wire
29 -- ** Flood detection 29 -- ** Flood detection
30 , FloodDetector (..) 30 , FloodDetector (..)
31 31
32 -- ** Options
33 , Options (..)
34
32 -- ** Connection 35 -- ** Connection
33 , Connection 36 , Connection
34 , connProtocol 37 , connProtocol
@@ -36,6 +39,7 @@ module Network.BitTorrent.Exchange.Wire
36 , connTopic 39 , connTopic
37 , connRemotePeerId 40 , connRemotePeerId
38 , connThisPeerId 41 , connThisPeerId
42 , connOptions
39 43
40 -- ** Setup 44 -- ** Setup
41 , runWire 45 , runWire
@@ -136,7 +140,7 @@ data ProtocolError
136 -- | 'Network.BitTorrent.Exchange.Message.Bitfield' message MUST 140 -- | 'Network.BitTorrent.Exchange.Message.Bitfield' message MUST
137 -- be send either once or zero times, but either this peer or 141 -- be send either once or zero times, but either this peer or
138 -- remote peer send a bitfield message the second time. 142 -- remote peer send a bitfield message the second time.
139 | BitfieldAlreadySend ChannelSide 143 | BitfieldAlreadySent ChannelSide
140 144
141 -- | Capabilities violation. For example this exception can occur 145 -- | Capabilities violation. For example this exception can occur
142 -- when a peer have sent 'Port' message but 'ExtDHT' is not 146 -- when a peer have sent 'Port' message but 'ExtDHT' is not
@@ -331,20 +335,81 @@ data FloodDetector = FloodDetector
331 , floodThreshold :: {-# UNPACK #-} !Int 335 , floodThreshold :: {-# UNPACK #-} !Int
332 336
333 -- | Flood predicate on the /current/ 'ConnectionStats'. 337 -- | Flood predicate on the /current/ 'ConnectionStats'.
334 , floodDetector :: Detector ConnectionStats 338 , floodPredicate :: Detector ConnectionStats
335 } deriving Show 339 } deriving Show
336 340
337 341-- | Flood detector with very permissive options.
338instance Default FloodDetector where 342instance Default FloodDetector where
339 def = FloodDetector 343 def = FloodDetector
340 { floodFactor = defaultFloodFactor 344 { floodFactor = defaultFloodFactor
341 , floodThreshold = defaultFloodThreshold 345 , floodThreshold = defaultFloodThreshold
342 , floodDetector = defaultDetector 346 , floodPredicate = defaultDetector
343 } 347 }
344 348
345-- | This peer might drop connection if the detector gives positive answer. 349-- | This peer might drop connection if the detector gives positive answer.
346runDetector :: FloodDetector -> ConnectionStats -> Bool 350runDetector :: FloodDetector -> ConnectionStats -> Bool
347runDetector FloodDetector {..} = floodDetector floodFactor floodThreshold 351runDetector FloodDetector {..} = floodPredicate floodFactor floodThreshold
352
353{-----------------------------------------------------------------------
354-- Options
355-----------------------------------------------------------------------}
356
357-- | Various connection settings and limits.
358data Options = Options
359 { -- | How often /this/ peer should send 'KeepAlive' messages.
360 keepaliveInterval :: {-# UNPACK #-} !Int
361
362 -- | /This/ peer will drop connection if a /remote/ peer did not
363 -- send any message for this period of time.
364 , keepaliveTimeout :: {-# UNPACK #-} !Int
365
366 -- | Used to protect against flood attacks.
367 , floodDetector :: FloodDetector
368
369 -- | Used to protect against flood attacks in /metadata
370 -- exchange/. Normally, a requesting peer should request each
371 -- 'InfoDict' piece only one time, but a malicious peer can
372 -- saturate wire with 'MetadataRequest' messages thus flooding
373 -- responding peer.
374 --
375 -- This value set upper bound for number of 'MetadataRequests'
376 -- for each piece.
377 --
378 , metadataFactor :: {-# UNPACK #-} !Int
379
380 -- | Used to protect against out-of-memory attacks: malicious peer
381 -- can claim that 'totalSize' is, say, 100TB and send some random
382 -- data instead of infodict pieces. Since requesting peer unable
383 -- to check not completed infodict via the infohash, the
384 -- accumulated pieces will allocate the all available memory.
385 --
386 -- This limit set upper bound for 'InfoDict' size. See
387 -- 'ExtendedMetadata' for more info.
388 --
389 , maxInfoDictSize :: {-# UNPACK #-} !Int
390 } deriving Show
391
392-- | Allows a requesting peer to send 2 'MetadataRequest's for the
393-- each piece.
394defaultMetadataFactor :: Int
395defaultMetadataFactor = 2
396
397-- | Usually torrent size do not exceed 1MB. This value limit torrent
398-- /content/ size to about 8TB. See 'maxInfoDictSize' for explanation
399-- why do we need this limit.
400defaultMaxInfoDictSize :: Int
401defaultMaxInfoDictSize = 10 * 1024 * 1024
402
403-- | Permissive default parameters, most likely you don't need to
404-- change them.
405instance Default Options where
406 def = Options
407 { keepaliveInterval = defaultKeepAliveInterval
408 , keepaliveTimeout = defaultKeepAliveTimeout
409 , floodDetector = def
410 , metadataFactor = defaultMetadataFactor
411 , maxInfoDictSize = defaultMaxInfoDictSize
412 }
348 413
349{----------------------------------------------------------------------- 414{-----------------------------------------------------------------------
350-- Connection 415-- Connection
@@ -372,6 +437,9 @@ data Connection = Connection
372 -- | Typically extracted from handshake. 437 -- | Typically extracted from handshake.
373 , connThisPeerId :: !PeerId 438 , connThisPeerId :: !PeerId
374 439
440 -- |
441 , connOptions :: !Options
442
375 -- | If @not (allowed ExtExtended connCaps)@ then this set is 443 -- | If @not (allowed ExtExtended connCaps)@ then this set is
376 -- always empty. Otherwise it has extension protocol 'MessageId' 444 -- always empty. Otherwise it has extension protocol 'MessageId'
377 -- map. 445 -- map.
@@ -581,6 +649,7 @@ connectWire hs addr extCaps wire =
581 , connTopic = hsInfoHash hs 649 , connTopic = hsInfoHash hs
582 , connRemotePeerId = hsPeerId hs' 650 , connRemotePeerId = hsPeerId hs'
583 , connThisPeerId = hsPeerId hs 651 , connThisPeerId = hsPeerId hs
652 , connOptions = def
584 , connExtCaps = extCapsRef 653 , connExtCaps = extCapsRef
585 , connStats = statsRef 654 , connStats = statsRef
586 } 655 }