1 {-# LANGUAGE OverloadedStrings #-}
2 module FuncTorrent.Peer
7 import Prelude hiding (lookup, concat, replicate, splitAt)
10 import Data.ByteString (ByteString, unpack, concat, hGet, hPut, singleton)
11 import Data.ByteString.Char8 (replicate, pack)
12 import Network (connectTo, PortID(..))
18 data PeerState = PeerState { am_choking :: Bool
19 , am_interested :: Bool
20 , peer_choking :: Bool
21 , peer_interested :: Bool }
23 -- | Peer is a PeerID, IP address, port tuple
24 data Peer = Peer ID IP Port
27 data Msg = HandShakeMsg ByteString ID
35 | RequestMsg Integer Integer Integer
36 | PieceMsg Integer Integer Integer
37 | CancelMsg Integer Integer Integer
41 genHandShakeMsg :: ByteString -> String -> ByteString
42 genHandShakeMsg infoHash peer_id = concat [pstrlen, pstr, reserved, infoHash, peerID]
43 where pstrlen = singleton 19
44 pstr = pack "BitTorrent protocol"
45 reserved = replicate 8 '\0'
48 handShake :: Peer -> ByteString -> String -> IO ByteString
49 handShake (Peer _ ip port) infoHash peerid = do
50 let hs = genHandShakeMsg infoHash peerid
51 handle <- connectTo ip (PortNumber (fromIntegral port))
52 hSetBuffering handle LineBuffering
54 rlenBS <- hGet handle 1
55 let rlen = fromIntegral $ (unpack rlenBS) !! 0
58 -- sendMsg :: Peer -> Handle -> PeerMsg -> IO ()
59 -- recvMsg :: Peer -> Handle -> Msg