{-# LANGUAGE OverloadedStrings #-}
module FuncTorrent.Peer
- (Peer(..),
- PieceMap,
+ (PieceMap,
handlePeerMsgs
) where
dlstate (pm ! index) == Have
connectToPeer :: Peer -> IO Handle
-connectToPeer (Peer _ ip port) = do
+connectToPeer (Peer ip port) = do
h <- connectTo ip (PortNumber (fromIntegral port))
hSetBuffering h LineBuffering
return h
import FuncTorrent.Utils (toIP, toPort)
--- | Peer is a PeerID, IP address, port tuple
-data Peer = Peer ID IP Port
+-- | Peer is a IP address, port tuple
+data Peer = Peer IP Port
deriving (Show, Eq)
type ID = String
bsToInt x = fromIntegral (runGet getWord32be (fromChunks (return x)))
makePeer :: ByteString -> Peer
-makePeer peer = Peer "" (toIP ip') (toPort port')
+makePeer peer = Peer (toIP ip') (toPort port')
where (ip', port') = splitAt 4 peer
import System.IO (hSetBuffering, BufferMode ( NoBuffering ))
import FuncTorrent.Metainfo (Metainfo)
-import FuncTorrent.Peer (handlePeerMsgs, Peer(..), PieceMap)
+import FuncTorrent.Peer (handlePeerMsgs, PieceMap)
+import FuncTorrent.PeerMsgs (Peer(..))
import qualified FuncTorrent.FileSystem as FS (MsgChannel)
-- server is listening on any port from 6881 - 6889
run :: Socket -> String -> Metainfo -> PieceMap -> FS.MsgChannel -> IO ()
run listenSock peerid m pieceMap c = forever $ do
(handle, ip, port) <- accept listenSock
- let peer = Peer "" ip (fromIntegral port)
+ let peer = Peer ip (fromIntegral port)
hSetBuffering handle NoBuffering
forkIO $ handlePeerMsgs peer peerid m pieceMap False c
import FuncTorrent.Tracker.Types (TState(..), TrackerEventState(..), TrackerProtocol(..), TrackerMsg(..))
import FuncTorrent.Utils (Port, toPort, getHostname)
import qualified FuncTorrent.FileSystem as FS (MsgChannel)
-import FuncTorrent.Peer (Peer)
+import FuncTorrent.PeerMsgs (Peer)
type MsgChannel = Chan TrackerMsg
(trackerLoop
) where
-import Prelude hiding (lookup, splitAt)
+import Prelude hiding (lookup)
import Control.Concurrent (threadDelay)
import Control.Concurrent.MVar (readMVar, putMVar, isEmptyMVar, swapMVar)
import Control.Monad (forever, void)
import qualified Data.ByteString.Base16 as B16 (encode)
import Data.ByteString (ByteString)
-import Data.ByteString.Char8 as BC (pack, unpack, splitAt)
+import Data.ByteString.Char8 as BC (pack, unpack)
import Data.Char (chr)
-import Data.List (intercalate)
import Data.Map as M (lookup)
import Network (PortNumber)
import Network.HTTP.Base (urlEncode)
import FuncTorrent.Bencode (BVal(..))
import qualified FuncTorrent.FileSystem as FS (MsgChannel, Stats(..), getStats)
import FuncTorrent.Network (sendGetRequest)
-import FuncTorrent.PeerMsgs (Peer(..), makePeer)
+import FuncTorrent.PeerMsgs (makePeer)
import FuncTorrent.Utils (splitN, IP, Port)
import FuncTorrent.Tracker.Types(TState(..), TrackerResponse(..))
trackerLoop :: String -> PortNumber -> String -> ByteString -> FS.MsgChannel -> TState -> IO ()
trackerLoop url sport peerId infohash fschan tstate = forever $ do
- st' <- FS.getStats fschan
- st <- readMVar st'
- let up = FS.bytesRead st
- down = FS.bytesWritten st
+ st <- readMVar <$> FS.getStats fschan
+ up <- fmap FS.bytesRead st
+ down <- fmap FS.bytesWritten st
resp <- sendGetRequest url $ mkArgs sport peerId up down (left tstate) infohash
case Benc.decode resp of
Left e ->
import Data.ByteString (ByteString)
import Control.Concurrent.MVar (MVar)
-import FuncTorrent.Peer (Peer(..))
+import FuncTorrent.PeerMsgs (Peer)
data TrackerProtocol = Http
| Udp
import System.Random (randomIO)
import System.Timeout (timeout)
-import FuncTorrent.Peer (Peer(..))
+import FuncTorrent.PeerMsgs (Peer(..))
import FuncTorrent.Tracker.Types (TrackerEventState(..), TState(..))
import FuncTorrent.Utils (IP, Port, toIP, toPort, getHostname, getPort)
import qualified FuncTorrent.FileSystem as FS (MsgChannel, Stats(..), getStats)
ip <- toIP <$> getByteString 4
port <- toPort <$> getByteString 2
ipportpairs <- getIPPortPairs
- return $ (Peer "" ip port) : ipportpairs
+ return $ (Peer ip port) : ipportpairs
startSession :: String -> Port -> IO UDPTrackerHandle
startSession host port = do
trackerLoop :: String -> Port -> String -> ByteString -> FS.MsgChannel -> TState -> IO ()
trackerLoop url sport peerId infohash fschan tstate = forever $ do
- st <- fmap readMVar $ FS.getStats fschan
+ st <- readMVar <$> FS.getStats fschan
up <- fmap FS.bytesRead st
down <- fmap FS.bytesWritten st
handle <- startSession host port