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.hs56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/Network/BitTorrent/Peer.hs b/src/Network/BitTorrent/Peer.hs
new file mode 100644
index 00000000..e16329d2
--- /dev/null
+++ b/src/Network/BitTorrent/Peer.hs
@@ -0,0 +1,56 @@
1-- |
2-- Copyright : (c) Sam T. 2013
3-- License : MIT
4-- Maintainer : pxqr.sta@gmail.com
5-- Stability : experimental
6-- Portability : non-portable
7--
8module Network.BitTorrent.Peer
9 ( Peer(..)
10 , peerSockAddr, connectToPeer
11 , ppPeer
12 ) where
13
14import Control.Applicative
15import Data.Word
16import Data.Bits
17import Network
18import Network.Socket
19
20import Network.BitTorrent.PeerID
21import Network.BitTorrent.PeerWire.ClientInfo
22
23
24data Peer = Peer {
25 peerID :: Maybe PeerID
26 , peerIP :: HostAddress
27 , peerPort :: PortNumber
28 } deriving Show
29
30-- TODO make platform independent, clarify htonl
31-- | Convert peer info from tracker response to socket address.
32-- Used for establish connection between peers.
33--
34peerSockAddr :: Peer -> SockAddr
35peerSockAddr = SockAddrInet <$> (g . peerPort) <*> (htonl . peerIP)
36 where
37 htonl :: Word32 -> Word32
38 htonl d =
39 ((d .&. 0xff) `shiftL` 24) .|.
40 (((d `shiftR` 8 ) .&. 0xff) `shiftL` 16) .|.
41 (((d `shiftR` 16) .&. 0xff) `shiftL` 8) .|.
42 ((d `shiftR` 24) .&. 0xff)
43
44 g :: PortNumber -> PortNumber
45 g = id
46
47-- | Tries to connect to peer using reasonable default parameters.
48connectToPeer :: Peer -> IO Socket
49connectToPeer p = do
50 sock <- socket AF_INET Stream Network.Socket.defaultProtocol
51 connect sock (peerSockAddr p)
52 return sock
53
54ppPeer :: Peer -> String
55ppPeer p = maybe "" (++ " at ") ((ppClientInfo . clientInfo) <$> peerID p)
56 ++ show (peerSockAddr p)