-instance Binary PeerMsg where
- put msg = case msg of
- KeepAliveMsg -> putWord32be 0
- ChokeMsg -> do putWord32be 1
- putWord8 0
- UnChokeMsg -> do putWord32be 1
- putWord8 1
- InterestedMsg -> do putWord32be 1
- putWord8 2
- NotInterestedMsg -> do putWord32be 1
- putWord8 3
- HaveMsg i -> do putWord32be 5
- putWord8 4
- putWord32be (fromIntegral i)
- BitFieldMsg bf -> do putWord32be $ fromIntegral (1 + bfListLen)
- putWord8 5
- mapM_ putWord8 bfList
- where bfList = unpack bf
- bfListLen = length bfList
- RequestMsg i o l -> do putWord32be 13
- putWord8 6
- putWord32be (fromIntegral i)
- putWord32be (fromIntegral o)
- putWord32be (fromIntegral l)
- PieceMsg i o b -> do putWord32be $ fromIntegral (9 + blocklen)
- putWord8 7
- putWord32be (fromIntegral i)
- putWord32be (fromIntegral o)
- mapM_ putWord8 blockList
- where blockList = unpack b
- blocklen = length blockList
- CancelMsg i o l -> do putWord32be 13
- putWord8 8
- putWord32be (fromIntegral i)
- putWord32be (fromIntegral o)
- putWord32be (fromIntegral l)
- PortMsg p -> do putWord32be 3
- putWord8 9
- putWord16be (fromIntegral p)
- get = do
- l <- getWord32be
- msgid <- getWord8
- case msgid of
- 0 -> return ChokeMsg
- 1 -> return UnChokeMsg
- 2 -> return InterestedMsg
- 3 -> return NotInterestedMsg
- 4 -> liftM (HaveMsg . fromIntegral) getWord32be
- 5 -> liftM (BitFieldMsg . pack) (replicateM (fromIntegral l - 1) getWord8)
- 6 -> liftA3 RequestMsg getInteger getInteger getInteger
- where getInteger = fromIntegral <$> getWord32be
- 7 -> liftA3 PieceMsg getInteger getInteger (pack <$> replicateM (fromIntegral l - 9) getWord8)
- where getInteger = fromIntegral <$> getWord32be
- 8 -> liftA3 CancelMsg getInteger getInteger getInteger
- where getInteger = fromIntegral <$> getWord32be
- 9 -> liftM (PortMsg . fromIntegral) getWord16be
- _ -> error ("unknown message ID: " ++ show msgid)
-
-getMsg :: Handle -> IO PeerMsg
-getMsg h = do
- lBS <- hGet h 4
- let l = bsToInt lBS
- if l == 0
- then return KeepAliveMsg
+doHandshake :: Bool -> Handle -> Peer -> ByteString -> String -> IO ()
+doHandshake True h p infohash peerid = do
+ let hs = genHandshakeMsg infohash peerid
+ hPut h hs
+ putStrLn $ "--> handhake to peer: " ++ show p
+ _ <- hGet h (length (unpack hs))
+ putStrLn $ "<-- handshake from peer: " ++ show p
+ return ()
+doHandshake False h p infohash peerid = do
+ let hs = genHandshakeMsg infohash peerid
+ putStrLn "waiting for a handshake"
+ hsMsg <- hGet h (length (unpack hs))
+ putStrLn $ "<-- handshake from peer: " ++ show p
+ let rxInfoHash = take 20 $ drop 28 hsMsg
+ if rxInfoHash /= infohash
+ then do
+ putStrLn "infoHashes does not match"
+ hClose h
+ return ()