import Data.ByteString.Lazy (fromStrict, fromChunks, toStrict)
import Data.ByteString.Char8 as BC (splitAt)
import qualified Data.ByteString.Char8 as BC (replicate, pack)
-import Control.Monad (replicateM, liftM)
+import Control.Monad (replicateM)
import Control.Applicative (liftA3)
import Data.Binary (Binary(..), decode, encode)
| PieceMsg Integer Integer ByteString
| CancelMsg Integer Integer Integer
| PortMsg Port
+ | ExtendedMsg Integer ByteString
deriving (Show)
instance Binary PeerMsg where
PortMsg p -> do putWord32be 3
putWord8 9
putWord16be (fromIntegral p)
+ ExtendedHandshakeMsg t b-> do putWord32be msgLen
+ putWord8 20
+ putWord8 t -- 0 => handshake msg
+ -- actual extension msg follows
+ mapM_ putWord8 blockList
+ where blockList = unpack b
+ blockLen = length blockList
+
+
where putIndexOffsetLength i o l = do
putWord32be (fromIntegral i)
putWord32be (fromIntegral o)
where bsMsg = toStrict $ encode msg
genHandshakeMsg :: ByteString -> String -> ByteString
-genHandshakeMsg infoHash peer_id = concat [pstrlen, pstr, reserved, infoHash, peerID]
+genHandshakeMsg infoHash peer_id = concat [pstrlen, pstr, reserved1, reserved2, reserved3, infoHash, peerID]
where pstrlen = singleton 19
pstr = BC.pack "BitTorrent protocol"
- reserved = BC.replicate 8 '\0'
+ reserved1 = BC.replicate 4 '\0'
+ reserved2 = singleton 0x10 -- support extension protocol
+ reserved3 = BC.replicate 3 '\0'
peerID = BC.pack peer_id
bsToInt :: ByteString -> Int