summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Peer.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Peer.hs')
-rw-r--r--src/Network/BitTorrent/Peer.hs33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/Network/BitTorrent/Peer.hs b/src/Network/BitTorrent/Peer.hs
index 9aa924d3..41630c6d 100644
--- a/src/Network/BitTorrent/Peer.hs
+++ b/src/Network/BitTorrent/Peer.hs
@@ -44,12 +44,14 @@ module Network.BitTorrent.Peer
44 44
45 -- ** Generation 45 -- ** Generation
46 , newPeerID, timestampByteString 46 , newPeerID, timestampByteString
47
47 -- ** Extra 48 -- ** Extra
48 , byteStringPadded 49 , byteStringPadded
49 50
50 -- * Peer address 51 -- * Peer address
51 , PeerAddr(..) 52 , PeerAddr(..)
52 , peerSockAddr, connectToPeer 53 , peerSockAddr
54 , connectToPeer, forkListener
53 , ppPeer 55 , ppPeer
54 56
55 -- * Client version detection 57 -- * Client version detection
@@ -66,6 +68,8 @@ module Network.BitTorrent.Peer
66 68
67 69
68import Control.Applicative 70import Control.Applicative
71import Control.Concurrent
72import Control.Exception
69import Data.BEncode 73import Data.BEncode
70import Data.Bits 74import Data.Bits
71import Data.Word 75import Data.Word
@@ -84,7 +88,7 @@ import Data.Time.Format (formatTime)
84import Text.PrettyPrint (text, Doc, (<+>)) 88import Text.PrettyPrint (text, Doc, (<+>))
85import System.Locale (defaultTimeLocale) 89import System.Locale (defaultTimeLocale)
86 90
87import Network 91import Network hiding (accept)
88import Network.Socket 92import Network.Socket
89 93
90 94
@@ -489,7 +493,8 @@ data PeerAddr = PeerAddr {
489 , peerIP :: HostAddress 493 , peerIP :: HostAddress
490 , peerPort :: PortNumber 494 , peerPort :: PortNumber
491 } deriving (Show, Eq, Ord) 495 } deriving (Show, Eq, Ord)
492 -- TODO verify semantic of ord and eq instances 496
497-- TODO check semantic of ord and eq instances
493 498
494instance BEncodable PortNumber where 499instance BEncodable PortNumber where
495 toBEncode = toBEncode . fromEnum 500 toBEncode = toBEncode . fromEnum
@@ -535,6 +540,28 @@ connectToPeer p = do
535 connect sock (peerSockAddr p) 540 connect sock (peerSockAddr p)
536 return sock 541 return sock
537 542
543
544forkListener :: ((PeerAddr, Socket) -> IO ()) -> IO PortNumber
545forkListener action = do
546 sock <- socket AF_INET Stream defaultProtocol
547 bindSocket sock (SockAddrInet 0 0)
548 listen sock 1
549 addr <- getSocketName sock
550 case addr of
551 SockAddrInet port _ -> do
552 forkIO (loop sock)
553 return port
554 _ -> do
555 throwIO $ userError "listener: impossible happened"
556 where
557 loop sock = do
558 (conn, addr) <- accept sock
559 case addr of
560 SockAddrInet port host ->
561 action (PeerAddr Nothing host port, conn)
562 _ -> return ()
563 loop sock
564
538-- | Pretty print peer address in human readable form. 565-- | Pretty print peer address in human readable form.
539ppPeer :: PeerAddr -> Doc 566ppPeer :: PeerAddr -> Doc
540ppPeer p @ PeerAddr {..} = case peerID of 567ppPeer p @ PeerAddr {..} = case peerID of