diff options
Diffstat (limited to 'src/Network')
-rw-r--r-- | src/Network/BitTorrent/Exchange/Session.hs | 79 | ||||
-rw-r--r-- | src/Network/BitTorrent/Exchange/Wire.hs | 35 |
2 files changed, 64 insertions, 50 deletions
diff --git a/src/Network/BitTorrent/Exchange/Session.hs b/src/Network/BitTorrent/Exchange/Session.hs index 1537efe1..8cbce4e3 100644 --- a/src/Network/BitTorrent/Exchange/Session.hs +++ b/src/Network/BitTorrent/Exchange/Session.hs | |||
@@ -77,17 +77,23 @@ cache :: BEncode a => a -> Cached a | |||
77 | cache s = Cached s (BE.encode s) | 77 | cache s = Cached s (BE.encode s) |
78 | 78 | ||
79 | data Session = Session | 79 | data Session = Session |
80 | { tpeerId :: PeerId | 80 | { sessionPeerId :: !(PeerId) |
81 | , infohash :: InfoHash | 81 | , sessionTopic :: !(InfoHash) |
82 | , metadata :: MVar Metadata.Status | 82 | |
83 | , storage :: Storage | 83 | , metadata :: !(MVar Metadata.Status) |
84 | , status :: MVar SessionStatus | 84 | , infodict :: !(MVar (Cached InfoDict)) |
85 | , unchoked :: [PeerAddr IP] | 85 | |
86 | , pendingConnections :: TVar (Set (PeerAddr IP)) | 86 | , status :: !(MVar SessionStatus) |
87 | , establishedConnections :: TVar (Map (PeerAddr IP) (Connection Session)) | 87 | , storage :: !(Storage) |
88 | , broadcast :: Chan Message | 88 | |
89 | , logger :: LogFun | 89 | , broadcast :: !(Chan Message) |
90 | , infodict :: MVar (Cached InfoDict) | 90 | |
91 | , unchoked :: [PeerAddr IP] | ||
92 | , connectionsPrefs :: !ConnectionPrefs | ||
93 | , connectionsPending :: !(TVar (Set (PeerAddr IP))) | ||
94 | , connectionsEstablished :: !(TVar (Map (PeerAddr IP) (Connection Session))) | ||
95 | |||
96 | , logger :: !(LogFun) | ||
91 | } | 97 | } |
92 | 98 | ||
93 | instance Ord IP | 99 | instance Ord IP |
@@ -101,6 +107,7 @@ newSession :: LogFun | |||
101 | -> InfoDict -- ^ torrent info dictionary; | 107 | -> InfoDict -- ^ torrent info dictionary; |
102 | -> IO Session -- ^ | 108 | -> IO Session -- ^ |
103 | newSession logFun addr rootPath dict = do | 109 | newSession logFun addr rootPath dict = do |
110 | pid <- maybe genPeerId return (peerId addr) | ||
104 | pconnVar <- newTVarIO S.empty | 111 | pconnVar <- newTVarIO S.empty |
105 | econnVar <- newTVarIO M.empty | 112 | econnVar <- newTVarIO M.empty |
106 | store <- openInfoDict ReadWriteEx rootPath dict | 113 | store <- openInfoDict ReadWriteEx rootPath dict |
@@ -108,16 +115,18 @@ newSession logFun addr rootPath dict = do | |||
108 | (piPieceLength (idPieceInfo dict)) | 115 | (piPieceLength (idPieceInfo dict)) |
109 | chan <- newChan | 116 | chan <- newChan |
110 | return Session | 117 | return Session |
111 | { tpeerId = fromMaybe (error "newSession: impossible") | 118 | { sessionPeerId = pid |
112 | (peerId addr) | 119 | , sessionTopic = idInfoHash dict |
113 | , infohash = idInfoHash dict | ||
114 | , status = statusVar | 120 | , status = statusVar |
115 | , storage = store | 121 | , storage = store |
116 | , unchoked = [] | 122 | , unchoked = [] |
117 | , pendingConnections = pconnVar | 123 | , connectionsPrefs = def |
118 | , establishedConnections = econnVar | 124 | , connectionsPending = pconnVar |
119 | , broadcast = chan | 125 | , connectionsEstablished = econnVar |
120 | , logger = logFun | 126 | , broadcast = chan |
127 | , logger = logFun | ||
128 | , metadata = undefined | ||
129 | , infodict = undefined | ||
121 | } | 130 | } |
122 | 131 | ||
123 | closeSession :: Session -> IO () | 132 | closeSession :: Session -> IO () |
@@ -152,12 +161,12 @@ logEvent = logInfoN | |||
152 | 161 | ||
153 | pendingConnection :: PeerAddr IP -> Session -> IO Bool | 162 | pendingConnection :: PeerAddr IP -> Session -> IO Bool |
154 | pendingConnection addr Session {..} = atomically $ do | 163 | pendingConnection addr Session {..} = atomically $ do |
155 | pSet <- readTVar pendingConnections | 164 | pSet <- readTVar connectionsPending |
156 | eSet <- readTVar establishedConnections | 165 | eSet <- readTVar connectionsEstablished |
157 | if (addr `S.member` pSet) || (addr `M.member` eSet) | 166 | if (addr `S.member` pSet) || (addr `M.member` eSet) |
158 | then return False | 167 | then return False |
159 | else do | 168 | else do |
160 | modifyTVar' pendingConnections (S.insert addr) | 169 | modifyTVar' connectionsPending (S.insert addr) |
161 | return True | 170 | return True |
162 | 171 | ||
163 | establishedConnection :: Connected Session () | 172 | establishedConnection :: Connected Session () |
@@ -172,8 +181,8 @@ finishedConnection = return () | |||
172 | -- | There are no state for this connection, remove it. | 181 | -- | There are no state for this connection, remove it. |
173 | closedConnection :: PeerAddr IP -> Session -> IO () | 182 | closedConnection :: PeerAddr IP -> Session -> IO () |
174 | closedConnection addr Session {..} = atomically $ do | 183 | closedConnection addr Session {..} = atomically $ do |
175 | modifyTVar pendingConnections $ S.delete addr | 184 | modifyTVar connectionsPending $ S.delete addr |
176 | modifyTVar establishedConnections $ M.delete addr | 185 | modifyTVar connectionsEstablished $ M.delete addr |
177 | 186 | ||
178 | {----------------------------------------------------------------------- | 187 | {----------------------------------------------------------------------- |
179 | -- Connections | 188 | -- Connections |
@@ -190,16 +199,20 @@ mainWire = do | |||
190 | lift finishedConnection | 199 | lift finishedConnection |
191 | 200 | ||
192 | getConnectionConfig :: Session -> IO (ConnectionConfig Session) | 201 | getConnectionConfig :: Session -> IO (ConnectionConfig Session) |
193 | getConnectionConfig s @ Session {..} = undefined --ConnectionConfig | 202 | getConnectionConfig s @ Session {..} = do |
194 | -- let caps = def | 203 | chan <- dupChan broadcast |
195 | -- let ecaps = def | 204 | let sessionLink = SessionLink { |
196 | -- let hs = Handshake def caps infohash tpeerId | 205 | linkTopic = sessionTopic |
197 | -- chan <- dupChan broadcast | 206 | , linkPeerId = sessionPeerId |
198 | 207 | , linkMetadataSize = Nothing | |
199 | -- { cfgPrefs = undefined | 208 | , linkOutputChan = Just chan |
200 | -- , cfgSession = ConnectionSession undefined undefined s | 209 | , linkSession = s |
201 | -- , cfgWire = mainWire | 210 | } |
202 | -- } | 211 | return ConnectionConfig |
212 | { cfgPrefs = connectionsPrefs | ||
213 | , cfgSession = sessionLink | ||
214 | , cfgWire = mainWire | ||
215 | } | ||
203 | 216 | ||
204 | insert :: PeerAddr IP -> Session -> IO () | 217 | insert :: PeerAddr IP -> Session -> IO () |
205 | insert addr ses @ Session {..} = void $ forkIO (action `finally` cleanup) | 218 | insert addr ses @ Session {..} = void $ forkIO (action `finally` cleanup) |
diff --git a/src/Network/BitTorrent/Exchange/Wire.hs b/src/Network/BitTorrent/Exchange/Wire.hs index 4ddade66..53c9afb2 100644 --- a/src/Network/BitTorrent/Exchange/Wire.hs +++ b/src/Network/BitTorrent/Exchange/Wire.hs | |||
@@ -50,9 +50,9 @@ module Network.BitTorrent.Exchange.Wire | |||
50 | , connStats | 50 | , connStats |
51 | 51 | ||
52 | -- * Setup | 52 | -- * Setup |
53 | , ConnectionPrefs (..) | 53 | , ConnectionPrefs (..) |
54 | , ConnectionSession (..) | 54 | , SessionLink (..) |
55 | , ConnectionConfig (..) | 55 | , ConnectionConfig (..) |
56 | 56 | ||
57 | -- ** Initiate | 57 | -- ** Initiate |
58 | , connectWire | 58 | , connectWire |
@@ -753,17 +753,18 @@ instance Default ConnectionPrefs where | |||
753 | normalize :: ConnectionPrefs -> ConnectionPrefs | 753 | normalize :: ConnectionPrefs -> ConnectionPrefs |
754 | normalize = undefined | 754 | normalize = undefined |
755 | 755 | ||
756 | data ConnectionSession s = ConnectionSession | 756 | -- | Bridge between 'Connection' and 'Network.BitTorrent.Exchange.Session'. |
757 | { sessionTopic :: !(InfoHash) | 757 | data SessionLink s = SessionLink |
758 | , sessionPeerId :: !(PeerId) | 758 | { linkTopic :: !(InfoHash) |
759 | , metadataSize :: !(Maybe Int) | 759 | , linkPeerId :: !(PeerId) |
760 | , outputChan :: !(Maybe (Chan Message)) | 760 | , linkMetadataSize :: !(Maybe Int) |
761 | , connectionSession :: !(s) | 761 | , linkOutputChan :: !(Maybe (Chan Message)) |
762 | , linkSession :: !(s) | ||
762 | } | 763 | } |
763 | 764 | ||
764 | data ConnectionConfig s = ConnectionConfig | 765 | data ConnectionConfig s = ConnectionConfig |
765 | { cfgPrefs :: !(ConnectionPrefs) | 766 | { cfgPrefs :: !(ConnectionPrefs) |
766 | , cfgSession :: !(ConnectionSession s) | 767 | , cfgSession :: !(SessionLink s) |
767 | , cfgWire :: !(Wire s ()) | 768 | , cfgWire :: !(Wire s ()) |
768 | } | 769 | } |
769 | 770 | ||
@@ -771,8 +772,8 @@ configHandshake :: ConnectionConfig s -> Handshake | |||
771 | configHandshake ConnectionConfig {..} = Handshake | 772 | configHandshake ConnectionConfig {..} = Handshake |
772 | { hsProtocol = prefProtocol cfgPrefs | 773 | { hsProtocol = prefProtocol cfgPrefs |
773 | , hsReserved = prefCaps cfgPrefs | 774 | , hsReserved = prefCaps cfgPrefs |
774 | , hsInfoHash = sessionTopic cfgSession | 775 | , hsInfoHash = linkTopic cfgSession |
775 | , hsPeerId = sessionPeerId cfgSession | 776 | , hsPeerId = linkPeerId cfgSession |
776 | } | 777 | } |
777 | 778 | ||
778 | {----------------------------------------------------------------------- | 779 | {----------------------------------------------------------------------- |
@@ -841,13 +842,13 @@ afterHandshaking :: ChannelSide -> PeerAddr IP -> Socket -> HandshakePair | |||
841 | afterHandshaking initiator addr sock | 842 | afterHandshaking initiator addr sock |
842 | hpair @ (HandshakePair hs hs') | 843 | hpair @ (HandshakePair hs hs') |
843 | (ConnectionConfig | 844 | (ConnectionConfig |
844 | { cfgPrefs = ConnectionPrefs {..} | 845 | { cfgPrefs = ConnectionPrefs {..} |
845 | , cfgSession = ConnectionSession {..} | 846 | , cfgSession = SessionLink {..} |
846 | , cfgWire = wire | 847 | , cfgWire = wire |
847 | }) = do | 848 | }) = do |
848 | let caps = hsReserved hs <> hsReserved hs' | 849 | let caps = hsReserved hs <> hsReserved hs' |
849 | cstate <- newIORef def { _connStats = establishedStats hpair } | 850 | cstate <- newIORef def { _connStats = establishedStats hpair } |
850 | chan <- maybe newChan return outputChan | 851 | chan <- maybe newChan return linkOutputChan |
851 | let conn = Connection { | 852 | let conn = Connection { |
852 | connInitiatedBy = initiator | 853 | connInitiatedBy = initiator |
853 | , connRemoteAddr = addr | 854 | , connRemoteAddr = addr |
@@ -858,7 +859,7 @@ afterHandshaking initiator addr sock | |||
858 | , connThisPeerId = hsPeerId hs | 859 | , connThisPeerId = hsPeerId hs |
859 | , connOptions = def | 860 | , connOptions = def |
860 | , connState = cstate | 861 | , connState = cstate |
861 | , connSession = connectionSession | 862 | , connSession = linkSession |
862 | , connChan = chan | 863 | , connChan = chan |
863 | } | 864 | } |
864 | 865 | ||
@@ -897,7 +898,7 @@ connectWire addr cfg = do | |||
897 | acceptWire :: PendingConnection -> ConnectionConfig s -> IO () | 898 | acceptWire :: PendingConnection -> ConnectionConfig s -> IO () |
898 | acceptWire pc @ PendingConnection {..} cfg = do | 899 | acceptWire pc @ PendingConnection {..} cfg = do |
899 | bracket (return pendingSock) close $ \ _ -> do | 900 | bracket (return pendingSock) close $ \ _ -> do |
900 | unless (sessionTopic (cfgSession cfg) == pendingTopic) $ do | 901 | unless (linkTopic (cfgSession cfg) == pendingTopic) $ do |
901 | throwIO (ProtocolError (UnexpectedTopic pendingTopic)) | 902 | throwIO (ProtocolError (UnexpectedTopic pendingTopic)) |
902 | 903 | ||
903 | let hs = configHandshake cfg | 904 | let hs = configHandshake cfg |