closed_conn.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package quic
  2. import (
  3. "math/bits"
  4. "net"
  5. "sync/atomic"
  6. "github.com/Psiphon-Labs/quic-go/internal/utils"
  7. )
  8. // A closedLocalConn is a connection that we closed locally.
  9. // When receiving packets for such a connection, we need to retransmit the packet containing the CONNECTION_CLOSE frame,
  10. // with an exponential backoff.
  11. type closedLocalConn struct {
  12. counter atomic.Uint32
  13. logger utils.Logger
  14. sendPacket func(net.Addr, packetInfo)
  15. }
  16. var _ packetHandler = &closedLocalConn{}
  17. // newClosedLocalConn creates a new closedLocalConn and runs it.
  18. func newClosedLocalConn(sendPacket func(net.Addr, packetInfo), logger utils.Logger) packetHandler {
  19. return &closedLocalConn{
  20. sendPacket: sendPacket,
  21. logger: logger,
  22. }
  23. }
  24. func (c *closedLocalConn) handlePacket(p receivedPacket) {
  25. n := c.counter.Add(1)
  26. // exponential backoff
  27. // only send a CONNECTION_CLOSE for the 1st, 2nd, 4th, 8th, 16th, ... packet arriving
  28. if bits.OnesCount32(n) != 1 {
  29. return
  30. }
  31. c.logger.Debugf("Received %d packets after sending CONNECTION_CLOSE. Retransmitting.", n)
  32. c.sendPacket(p.remoteAddr, p.info)
  33. }
  34. func (c *closedLocalConn) destroy(error) {}
  35. func (c *closedLocalConn) closeWithTransportError(TransportErrorCode) {}
  36. // A closedRemoteConn is a connection that was closed remotely.
  37. // For such a connection, we might receive reordered packets that were sent before the CONNECTION_CLOSE.
  38. // We can just ignore those packets.
  39. type closedRemoteConn struct{}
  40. var _ packetHandler = &closedRemoteConn{}
  41. func newClosedRemoteConn() packetHandler {
  42. return &closedRemoteConn{}
  43. }
  44. func (c *closedRemoteConn) handlePacket(receivedPacket) {}
  45. func (c *closedRemoteConn) destroy(error) {}
  46. func (c *closedRemoteConn) closeWithTransportError(TransportErrorCode) {}