@@ -34,13 +34,11 @@ import Control.Monad (unless, when)
3434import Data.Bifunctor (Bifunctor (first ))
3535import Data.Binary qualified as Binary (decodeOrFail )
3636import Data.ByteString (ByteString , fromStrict )
37- import Data.Foldable (forM_ )
3837import Data.Function ((&) )
3938import Data.Functor ((<&>) )
4039import Data.IORef (newIORef , readIORef , writeIORef )
4140import Data.List.NonEmpty (NonEmpty )
4241import Data.Map.Strict qualified as Map
43- import Data.Maybe (isNothing )
4442import Lens.Micro.Platform ((+~) )
4543import Network.QUIC qualified as QUIC
4644import Network.TLS (Credential )
@@ -62,8 +60,7 @@ import Network.Transport
6260 )
6361import Network.Transport.QUIC.Internal.Configuration (credentialLoadX509 )
6462import Network.Transport.QUIC.Internal.Messaging
65- ( ClientConnId ,
66- MessageReceived (.. ),
63+ ( MessageReceived (.. ),
6764 createConnectionId ,
6865 decodeMessage ,
6966 encodeMessage ,
@@ -101,7 +98,6 @@ import Network.Transport.QUIC.Internal.QUICTransport
10198 nextSelfConnOutId ,
10299 remoteEndPointAddress ,
103100 remoteEndPointState ,
104- remoteIncoming ,
105101 remoteServerConnId ,
106102 remoteStream ,
107103 transportConfig ,
@@ -182,17 +178,15 @@ handleNewStream quicTransport stream = do
182178 (remoteEndPoint, _) <- either throwIO pure =<< createRemoteEndPoint ourEndPoint remoteAddress Incoming
183179 doneMVar <- newEmptyMVar
184180
185- clientConnId <- either (throwIO . userError ) (pure . fromIntegral ) =<< recvWord32 stream
186181 let serverConnId = remoteServerConnId remoteEndPoint
187- connectionId = createConnectionId serverConnId clientConnId
182+ -- One logical connection per stream; clientConnId is always 0.
183+ connectionId = createConnectionId serverConnId 0
188184
189185 let st =
190186 RemoteEndPointValid $
191187 ValidRemoteEndPointState
192188 { _remoteStream = stream,
193- _remoteStreamIsClosed = doneMVar,
194- _remoteIncoming = Just clientConnId,
195- _remoteNextConnOutId = 0
189+ _remoteStreamIsClosed = doneMVar
196190 }
197191 modifyMVar_
198192 (remoteEndPoint ^. remoteEndPointState)
@@ -253,12 +247,8 @@ handleIncomingMessages ourEndPoint remoteEndPoint =
253247 release (Left err) = closeRemoteEndPoint Incoming remoteEndPoint >> prematureExit err
254248 release (Right _) = closeRemoteEndPoint Incoming remoteEndPoint
255249
256- connectionId = createConnectionId serverConnId
257-
258- writeConnectionClosedSTM connId =
259- writeTQueue
260- ourQueue
261- (ConnectionClosed (connectionId connId))
250+ -- One logical connection per stream; clientConnId is always 0.
251+ connectionId = createConnectionId serverConnId 0
262252
263253 go = either prematureExit loop
264254
@@ -268,34 +258,31 @@ handleIncomingMessages ourEndPoint remoteEndPoint =
268258 Left errmsg -> do
269259 -- Throwing will trigger 'prematureExit'
270260 throwIO $ userError $ " (handleIncomingMessages) Failed with: " <> errmsg
271- Right (Message connId bytes) -> handleMessage connId bytes >> loop stream
261+ Right (Message bytes) -> handleMessage bytes >> loop stream
272262 Right StreamClosed -> throwIO $ userError " (handleIncomingMessages) Stream closed"
273- Right ( CloseConnection connId) -> do
274- atomically (writeConnectionClosedSTM connId )
263+ Right CloseConnection -> do
264+ atomically (writeTQueue ourQueue ( ConnectionClosed connectionId) )
275265 mAct <- modifyMVar (remoteEndPoint ^. remoteEndPointState) $ \ case
276266 RemoteEndPointInit -> pure (RemoteEndPointClosed , Nothing )
277267 RemoteEndPointClosed -> pure (RemoteEndPointClosed , Nothing )
278- RemoteEndPointValid (ValidRemoteEndPointState _ isClosed _ _ ) -> do
268+ RemoteEndPointValid (ValidRemoteEndPointState _ isClosed) -> do
279269 pure (RemoteEndPointClosed , Just $ putMVar isClosed () )
280270 case mAct of
281271 Nothing -> pure ()
282272 Just cleanup -> cleanup
283273 Right CloseEndPoint -> do
284- connIds <- modifyMVar (remoteEndPoint ^. remoteEndPointState) $ \ case
285- RemoteEndPointValid vst -> do
286- pure (RemoteEndPointClosed , vst ^. remoteIncoming)
287- other -> pure (other, Nothing )
288- unless
289- (isNothing connIds)
290- ( atomically $
291- forM_
292- connIds
293- (writeTQueue ourQueue . ConnectionClosed . connectionId)
294- )
274+ -- handleIncomingMessages only runs on incoming remote endpoints, so if
275+ -- the state was still Valid there is exactly one logical connection to
276+ -- surface as closed.
277+ wasValid <- modifyMVar (remoteEndPoint ^. remoteEndPointState) $ \ case
278+ RemoteEndPointValid _ -> pure (RemoteEndPointClosed , True )
279+ other -> pure (other, False )
280+ when wasValid $
281+ atomically $ writeTQueue ourQueue (ConnectionClosed connectionId)
295282
296- handleMessage :: ClientConnId -> [ByteString ] -> IO ()
297- handleMessage clientConnId payload =
298- atomically (writeTQueue ourQueue (Received ( connectionId clientConnId) payload))
283+ handleMessage :: [ByteString ] -> IO ()
284+ handleMessage payload =
285+ atomically (writeTQueue ourQueue (Received connectionId payload))
299286
300287 prematureExit :: IOException -> IO ()
301288 prematureExit exc = do
@@ -363,24 +350,24 @@ newConnection ourEndPoint creds validateCreds remoteAddress _reliability _connec
363350 else
364351 createConnectionTo creds validateCreds ourEndPoint remoteAddress >>= \ case
365352 Left err -> pure $ Left err
366- Right ( remoteEndPoint, connId) -> do
353+ Right remoteEndPoint -> do
367354 connAlive <- newIORef True
368355 pure
369356 . Right
370357 $ Connection
371- { send = sendConn remoteEndPoint connAlive connId ,
372- close = closeConn remoteEndPoint connAlive connId
358+ { send = sendConn remoteEndPoint connAlive,
359+ close = closeConn remoteEndPoint connAlive
373360 }
374361 where
375362 ourAddress = ourEndPoint ^. localAddress
376- sendConn remoteEndPoint connAlive connId packets =
363+ sendConn remoteEndPoint connAlive packets =
377364 readMVar (remoteEndPoint ^. remoteEndPointState) >>= \ case
378365 RemoteEndPointInit -> undefined
379366 RemoteEndPointValid vst ->
380367 readIORef connAlive >>= \ case
381368 False -> pure . Left $ TransportError SendClosed " Connection closed"
382369 True ->
383- sendMessage (vst ^. remoteStream) connId packets
370+ sendMessage (vst ^. remoteStream) packets
384371 <&> first (TransportError SendFailed . show )
385372 RemoteEndPointClosed -> do
386373 readIORef connAlive >>= \ case
@@ -390,9 +377,9 @@ newConnection ourEndPoint creds validateCreds remoteAddress _reliability _connec
390377 -- 'connAlive' IORefs.
391378 False -> pure . Left $ TransportError SendClosed " Connection closed"
392379 True -> pure . Left $ TransportError SendFailed " Remote endpoint closed"
393- closeConn remoteEndPoint connAlive connId = do
380+ closeConn remoteEndPoint connAlive = do
394381 mCleanup <- modifyMVar (remoteEndPoint ^. remoteEndPointState) $ \ case
395- RemoteEndPointValid vst@ (ValidRemoteEndPointState stream isClosed _ _ ) -> do
382+ RemoteEndPointValid vst@ (ValidRemoteEndPointState stream isClosed) -> do
396383 readIORef connAlive >>= \ case
397384 False -> pure (RemoteEndPointValid vst, Nothing )
398385 True -> do
@@ -401,7 +388,7 @@ newConnection ourEndPoint creds validateCreds remoteAddress _reliability _connec
401388 -- safe against races with the finally in streamToEndpoint that can
402389 -- also signal isClosed on QUIC.Client.run exit.
403390 let cleanup = do
404- _ <- sendCloseConnection connId stream
391+ _ <- sendCloseConnection stream
405392 _ <- tryPutMVar isClosed ()
406393 pure ()
407394 pure (RemoteEndPointClosed , Just cleanup)
0 commit comments