From: Ramakrishnan Muthukrishnan Date: Sat, 21 Feb 2015 02:41:42 +0000 (+0530) Subject: refactor PeerID and associated functions. X-Git-Url: https://git.rkrishnan.org/specifications/%5B/%5D%20/%3C?a=commitdiff_plain;h=1cc8e5407ac77fed52b8237f42fe2bf5cba61611;p=functorrent.git refactor PeerID and associated functions. Until now we were hashing peer id string to get a 20-byte hash. But that's not needed. Peer ID is just a 20-byte string that needs to be unique per client and sent to the tracker (and peers). --- diff --git a/functorrent.cabal b/functorrent.cabal index 77df828..b55644c 100644 --- a/functorrent.cabal +++ b/functorrent.cabal @@ -27,7 +27,8 @@ executable functorrent base16-bytestring, doctest, HTTP, - cryptohash + cryptohash, + binary hs-source-dirs: src ghc-options: -Wall -fwarn-incomplete-patterns default-language: Haskell2010 \ No newline at end of file diff --git a/src/Main.hs b/src/Main.hs index 015c323..bb50a8b 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -13,8 +13,8 @@ import Data.Functor printError :: Parsec.ParseError -> IO () printError e = putStrLn $ "parse error: " ++ show e -genPeerId :: String -genPeerId = "-HS0001-20150215" +peerId :: String +peerId = "-HS0001-*-*-20150215" exit :: IO BC.ByteString exit = exitSuccess @@ -37,7 +37,7 @@ main = do Nothing -> putStrLn "parse error" Just m -> do let len = MInfo.lengthInBytes (MInfo.info m) - body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId len) + body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d peerId len) print (P.getPeers (P.getPeerResponse body)) Left e -> printError e putStrLn "done" diff --git a/src/Peer.hs b/src/Peer.hs index 1660999..52cc03f 100644 --- a/src/Peer.hs +++ b/src/Peer.hs @@ -58,6 +58,6 @@ handShakeMsg m peer_id = let pstrlen = BC.concat $ BL.toChunks $ Bin.encode (19 pstr = BC.pack "BitTorrent protocol" reserved = BC.replicate 8 '\0' infoH = T.infoHash m - peerH = T.peerHash peer_id + peerID = BC.pack peer_id in - BC.concat [pstrlen, pstr, reserved, infoH, peerH] + BC.concat [pstrlen, pstr, reserved, infoH, peerID] diff --git a/src/Tracker.hs b/src/Tracker.hs index c523683..599c293 100644 --- a/src/Tracker.hs +++ b/src/Tracker.hs @@ -4,22 +4,23 @@ import qualified Data.ByteString.Char8 as BC import qualified Data.Map as M import qualified Data.List as List import qualified Network.HTTP as HTTP +import qualified Network.HTTP.Base as HB import qualified Bencode as Benc import qualified Crypto.Hash.SHA1 as SHA1 import qualified Data.ByteString.Base16 as B16 import qualified Utils as U import Data.Char --- import Network.HTTP + type Url = String --- | urlEncode +-- | urlEncodeHash -- --- >>> urlEncode $ BC.pack "123456789abcdef123456789abcdef123456789a" +-- >>> urlEncodeHash $ BC.pack "123456789abcdef123456789abcdef123456789a" -- "%124Vx%9a%bc%de%f1%23Eg%89%ab%cd%ef%124Vx%9a" -urlEncode :: BC.ByteString -> String -urlEncode bs = concatMap (encode . BC.unpack) (U.splitN 2 bs) +urlEncodeHash :: BC.ByteString -> String +urlEncodeHash bs = concatMap (encode . BC.unpack) (U.splitN 2 bs) where encode b@[c1, c2] = let c = chr (read ("0x" ++ b)) in escape c c1 c2 @@ -35,13 +36,10 @@ infoHash :: M.Map Benc.BVal Benc.BVal -> BC.ByteString infoHash m = let info = m M.! Benc.Bstr (BC.pack "info") in (B16.encode . SHA1.hash . BC.pack . Benc.encode) info -peerHash :: String -> BC.ByteString -peerHash = B16.encode . SHA1.hash . BC.pack - prepareRequest :: Benc.BVal -> String -> Integer -> String prepareRequest (Benc.Bdict d) peer_id len = - let p = [("info_hash", urlEncode (infoHash d)), - ("peer_id", urlEncode (peerHash peer_id)), + let p = [("info_hash", urlEncodeHash (infoHash d)), + ("peer_id", HB.urlEncode peer_id), ("port", "6881"), ("uploaded", "0"), ("downloaded", "0"),