diff options
Diffstat (limited to 'src/Network/BitTorrent/Exchange/Wire.hs')
-rw-r--r-- | src/Network/BitTorrent/Exchange/Wire.hs | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/Network/BitTorrent/Exchange/Wire.hs b/src/Network/BitTorrent/Exchange/Wire.hs index 1fca6a66..8873546d 100644 --- a/src/Network/BitTorrent/Exchange/Wire.hs +++ b/src/Network/BitTorrent/Exchange/Wire.hs | |||
@@ -15,7 +15,8 @@ | |||
15 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 15 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
16 | module Network.BitTorrent.Exchange.Wire | 16 | module Network.BitTorrent.Exchange.Wire |
17 | ( -- * Wire | 17 | ( -- * Wire |
18 | Wire | 18 | Connected |
19 | , Wire | ||
19 | 20 | ||
20 | -- ** Exceptions | 21 | -- ** Exceptions |
21 | , ChannelSide (..) | 22 | , ChannelSide (..) |
@@ -38,12 +39,14 @@ module Network.BitTorrent.Exchange.Wire | |||
38 | 39 | ||
39 | -- ** Connection | 40 | -- ** Connection |
40 | , Connection | 41 | , Connection |
42 | , connRemoteAddr | ||
41 | , connProtocol | 43 | , connProtocol |
42 | , connCaps | 44 | , connCaps |
43 | , connTopic | 45 | , connTopic |
44 | , connRemotePeerId | 46 | , connRemotePeerId |
45 | , connThisPeerId | 47 | , connThisPeerId |
46 | , connOptions | 48 | , connOptions |
49 | , connSession | ||
47 | 50 | ||
48 | -- ** Setup | 51 | -- ** Setup |
49 | , runWire | 52 | , runWire |
@@ -55,6 +58,7 @@ module Network.BitTorrent.Exchange.Wire | |||
55 | , recvMessage | 58 | , recvMessage |
56 | , sendMessage | 59 | , sendMessage |
57 | , filterQueue | 60 | , filterQueue |
61 | , getAdvertisedQueueLength | ||
58 | 62 | ||
59 | -- ** Query | 63 | -- ** Query |
60 | , getConnection | 64 | , getConnection |
@@ -93,6 +97,7 @@ import Network.Socket.ByteString as BS | |||
93 | import Text.PrettyPrint as PP hiding (($$), (<>)) | 97 | import Text.PrettyPrint as PP hiding (($$), (<>)) |
94 | import Text.PrettyPrint.Class | 98 | import Text.PrettyPrint.Class |
95 | import Text.Show.Functions | 99 | import Text.Show.Functions |
100 | import System.Log.FastLogger (ToLogStr(..)) | ||
96 | import System.Timeout | 101 | import System.Timeout |
97 | 102 | ||
98 | import Data.BEncode as BE | 103 | import Data.BEncode as BE |
@@ -190,13 +195,15 @@ errorPenalty (DisallowedMessage _ _) = 1 | |||
190 | 195 | ||
191 | -- | Exceptions used to interrupt the current P2P session. | 196 | -- | Exceptions used to interrupt the current P2P session. |
192 | data WireFailure | 197 | data WireFailure |
198 | = ConnectionRefused IOError | ||
199 | |||
193 | -- | Force termination of wire connection. | 200 | -- | Force termination of wire connection. |
194 | -- | 201 | -- |
195 | -- Normally you should throw only this exception from event loop | 202 | -- Normally you should throw only this exception from event loop |
196 | -- using 'disconnectPeer', other exceptions are thrown | 203 | -- using 'disconnectPeer', other exceptions are thrown |
197 | -- automatically by functions from this module. | 204 | -- automatically by functions from this module. |
198 | -- | 205 | -- |
199 | = DisconnectPeer | 206 | | DisconnectPeer |
200 | 207 | ||
201 | -- | A peer not responding and did not send a 'KeepAlive' message | 208 | -- | A peer not responding and did not send a 'KeepAlive' message |
202 | -- for a specified period of time. | 209 | -- for a specified period of time. |
@@ -464,10 +471,12 @@ makeLenses ''ConnectionState | |||
464 | 471 | ||
465 | -- | Connection keep various info about both peers. | 472 | -- | Connection keep various info about both peers. |
466 | data Connection s = Connection | 473 | data Connection s = Connection |
467 | { -- | /Both/ peers handshaked with this protocol string. The only | 474 | { connRemoteAddr :: !(PeerAddr IP) |
475 | |||
476 | -- | /Both/ peers handshaked with this protocol string. The only | ||
468 | -- value is \"Bittorrent Protocol\" but this can be changed in | 477 | -- value is \"Bittorrent Protocol\" but this can be changed in |
469 | -- future. | 478 | -- future. |
470 | connProtocol :: !ProtocolName | 479 | , connProtocol :: !ProtocolName |
471 | 480 | ||
472 | -- | Set of enabled core extensions, i.e. the pre BEP10 extension | 481 | -- | Set of enabled core extensions, i.e. the pre BEP10 extension |
473 | -- mechanism. This value is used to check if a message is allowed | 482 | -- mechanism. This value is used to check if a message is allowed |
@@ -503,6 +512,17 @@ data Connection s = Connection | |||
503 | instance Pretty (Connection s) where | 512 | instance Pretty (Connection s) where |
504 | pretty Connection {..} = "Connection" | 513 | pretty Connection {..} = "Connection" |
505 | 514 | ||
515 | instance ToLogStr (Connection s) where | ||
516 | toLogStr Connection {..} = mconcat | ||
517 | [ toLogStr (show connRemoteAddr) | ||
518 | , toLogStr (show connProtocol) | ||
519 | , toLogStr (show connCaps) | ||
520 | , toLogStr (show connTopic) | ||
521 | , toLogStr (show connRemotePeerId) | ||
522 | , toLogStr (show connThisPeerId) | ||
523 | , toLogStr (show connOptions) | ||
524 | ] | ||
525 | |||
506 | -- TODO check extended messages too | 526 | -- TODO check extended messages too |
507 | isAllowed :: Connection s -> Message -> Bool | 527 | isAllowed :: Connection s -> Message -> Bool |
508 | isAllowed Connection {..} msg | 528 | isAllowed Connection {..} msg |
@@ -592,6 +612,15 @@ getConnection = lift ask | |||
592 | getSession :: Wire s s | 612 | getSession :: Wire s s |
593 | getSession = lift (asks connSession) | 613 | getSession = lift (asks connSession) |
594 | 614 | ||
615 | -- TODO configurable | ||
616 | defQueueLength :: Int | ||
617 | defQueueLength = 1 | ||
618 | |||
619 | getAdvertisedQueueLength :: Wire s Int | ||
620 | getAdvertisedQueueLength = do | ||
621 | ExtendedHandshake {..} <- getRemoteEhs | ||
622 | return $ fromMaybe defQueueLength ehsQueueLength | ||
623 | |||
595 | {----------------------------------------------------------------------- | 624 | {----------------------------------------------------------------------- |
596 | -- Wrapper | 625 | -- Wrapper |
597 | -----------------------------------------------------------------------} | 626 | -----------------------------------------------------------------------} |
@@ -685,8 +714,9 @@ reconnect = undefined | |||
685 | -- | 714 | -- |
686 | connectWire :: s -> Handshake -> PeerAddr IP -> ExtendedCaps -> Chan Message | 715 | connectWire :: s -> Handshake -> PeerAddr IP -> ExtendedCaps -> Chan Message |
687 | -> Wire s () -> IO () | 716 | -> Wire s () -> IO () |
688 | connectWire session hs addr extCaps chan wire = | 717 | connectWire session hs addr extCaps chan wire = do |
689 | bracket (peerSocket Stream addr) close $ \ sock -> do | 718 | let catchRefusal m = try m >>= either (throwIO . ConnectionRefused) return |
719 | bracket (catchRefusal (peerSocket Stream addr)) close $ \ sock -> do | ||
690 | hs' <- initiateHandshake sock hs | 720 | hs' <- initiateHandshake sock hs |
691 | 721 | ||
692 | Prelude.mapM_ (\(t,e) -> unless t $ throwIO $ ProtocolError e) [ | 722 | Prelude.mapM_ (\(t,e) -> unless t $ throwIO $ ProtocolError e) [ |
@@ -723,7 +753,8 @@ connectWire session hs addr extCaps chan wire = | |||
723 | (forkIO $ sourceChan kaInterval chan $= conduitPut S.put $$ sinkSocket sock) | 753 | (forkIO $ sourceChan kaInterval chan $= conduitPut S.put $$ sinkSocket sock) |
724 | (killThread) $ \ _ -> | 754 | (killThread) $ \ _ -> |
725 | runWire wire' sock chan $ Connection | 755 | runWire wire' sock chan $ Connection |
726 | { connProtocol = hsProtocol hs | 756 | { connRemoteAddr = addr |
757 | , connProtocol = hsProtocol hs | ||
727 | , connCaps = caps | 758 | , connCaps = caps |
728 | , connTopic = hsInfoHash hs | 759 | , connTopic = hsInfoHash hs |
729 | , connRemotePeerId = hsPeerId hs' | 760 | , connRemotePeerId = hsPeerId hs' |