summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2014-02-25 14:52:40 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2014-02-25 14:52:40 +0400
commit7627d4dda31ddbececa4c80b340026da9e06c80e (patch)
tree086ad7d20f843759dcf12dfc7a1f9e56b70a5436
parente5a007173eda61ed8a2865aba2638eaf4cc783ef (diff)
Implement getConnectionConfig
-rw-r--r--src/Network/BitTorrent/Exchange/Session.hs79
-rw-r--r--src/Network/BitTorrent/Exchange/Wire.hs35
-rw-r--r--tests/Network/BitTorrent/Exchange/WireSpec.hs4
3 files changed, 66 insertions, 52 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
77cache s = Cached s (BE.encode s) 77cache s = Cached s (BE.encode s)
78 78
79data Session = Session 79data 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
93instance Ord IP 99instance Ord IP
@@ -101,6 +107,7 @@ newSession :: LogFun
101 -> InfoDict -- ^ torrent info dictionary; 107 -> InfoDict -- ^ torrent info dictionary;
102 -> IO Session -- ^ 108 -> IO Session -- ^
103newSession logFun addr rootPath dict = do 109newSession 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
123closeSession :: Session -> IO () 132closeSession :: Session -> IO ()
@@ -152,12 +161,12 @@ logEvent = logInfoN
152 161
153pendingConnection :: PeerAddr IP -> Session -> IO Bool 162pendingConnection :: PeerAddr IP -> Session -> IO Bool
154pendingConnection addr Session {..} = atomically $ do 163pendingConnection 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
163establishedConnection :: Connected Session () 172establishedConnection :: 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.
173closedConnection :: PeerAddr IP -> Session -> IO () 182closedConnection :: PeerAddr IP -> Session -> IO ()
174closedConnection addr Session {..} = atomically $ do 183closedConnection 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
192getConnectionConfig :: Session -> IO (ConnectionConfig Session) 201getConnectionConfig :: Session -> IO (ConnectionConfig Session)
193getConnectionConfig s @ Session {..} = undefined --ConnectionConfig 202getConnectionConfig 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
204insert :: PeerAddr IP -> Session -> IO () 217insert :: PeerAddr IP -> Session -> IO ()
205insert addr ses @ Session {..} = void $ forkIO (action `finally` cleanup) 218insert 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
753normalize :: ConnectionPrefs -> ConnectionPrefs 753normalize :: ConnectionPrefs -> ConnectionPrefs
754normalize = undefined 754normalize = undefined
755 755
756data ConnectionSession s = ConnectionSession 756-- | Bridge between 'Connection' and 'Network.BitTorrent.Exchange.Session'.
757 { sessionTopic :: !(InfoHash) 757data 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
764data ConnectionConfig s = ConnectionConfig 765data 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
771configHandshake ConnectionConfig {..} = Handshake 772configHandshake 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
841afterHandshaking initiator addr sock 842afterHandshaking 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
897acceptWire :: PendingConnection -> ConnectionConfig s -> IO () 898acceptWire :: PendingConnection -> ConnectionConfig s -> IO ()
898acceptWire pc @ PendingConnection {..} cfg = do 899acceptWire 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
diff --git a/tests/Network/BitTorrent/Exchange/WireSpec.hs b/tests/Network/BitTorrent/Exchange/WireSpec.hs
index 550c20f9..293e1bd6 100644
--- a/tests/Network/BitTorrent/Exchange/WireSpec.hs
+++ b/tests/Network/BitTorrent/Exchange/WireSpec.hs
@@ -16,8 +16,8 @@ import Network.BitTorrent.Exchange.Wire
16import Config 16import Config
17import Network.BitTorrent.Exchange.MessageSpec () 17import Network.BitTorrent.Exchange.MessageSpec ()
18 18
19nullSession :: InfoHash -> PeerId -> ConnectionSession () 19nullSession :: InfoHash -> PeerId -> SessionLink ()
20nullSession ih pid = ConnectionSession ih pid Nothing Nothing () 20nullSession ih pid = SessionLink ih pid Nothing Nothing ()
21 21
22instance Arbitrary Options where 22instance Arbitrary Options where
23 arbitrary = return def 23 arbitrary = return def