diff --git a/conn.go b/conn.go index 39e299a..b9ff90c 100644 --- a/conn.go +++ b/conn.go @@ -1598,7 +1598,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) { defer cancel() if c.quic != nil { - c.quic.cancelc = handshakeCtx.Done() + c.quic.ctx = handshakeCtx c.quic.cancel = cancel } else if ctx.Done() != nil { // Close the connection if ctx is canceled before the function returns. diff --git a/quic.go b/quic.go index 83a5feb..04e9f90 100644 --- a/quic.go +++ b/quic.go @@ -162,7 +162,7 @@ type quicState struct { started bool signalc chan struct{} // handshake data is available to be read blockedc chan struct{} // handshake is waiting for data, closed when done - cancelc <-chan struct{} // handshake has been canceled + ctx context.Context // handshake context cancel context.CancelFunc waitingForDrain bool @@ -262,10 +262,11 @@ func (q *QUICConn) NextEvent() QUICEvent { // Close closes the connection and stops any in-progress handshake. func (q *QUICConn) Close() error { - if q.conn.quic.cancel == nil { + if q.conn.quic.ctx == nil { return nil // never started } q.conn.quic.cancel() + <-q.conn.quic.signalc for range q.conn.quic.blockedc { // Wait for the handshake goroutine to return. } @@ -512,20 +513,16 @@ func (c *Conn) quicWaitForSignal() error { // Send on blockedc to notify the QUICConn that the handshake is blocked. // Exported methods of QUICConn wait for the handshake to become blocked // before returning to the user. - select { - case c.quic.blockedc <- struct{}{}: - case <-c.quic.cancelc: - return c.sendAlertLocked(alertCloseNotify) - } + c.quic.blockedc <- struct{}{} // The QUICConn reads from signalc to notify us that the handshake may // be able to proceed. (The QUICConn reads, because we close signalc to // indicate that the handshake has completed.) - select { - case c.quic.signalc <- struct{}{}: - c.hand.Write(c.quic.readbuf) - c.quic.readbuf = nil - case <-c.quic.cancelc: + c.quic.signalc <- struct{}{} + if c.quic.ctx.Err() != nil { + // The connection has been canceled. return c.sendAlertLocked(alertCloseNotify) } + c.hand.Write(c.quic.readbuf) + c.quic.readbuf = nil return nil } \ No newline at end of file