closed_conn.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package quic
  2. import (
  3. "math/bits"
  4. "net"
  5. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  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 uint32
  13. perspective protocol.Perspective
  14. logger utils.Logger
  15. sendPacket func(net.Addr, packetInfo)
  16. }
  17. var _ packetHandler = &closedLocalConn{}
  18. // newClosedLocalConn creates a new closedLocalConn and runs it.
  19. func newClosedLocalConn(sendPacket func(net.Addr, packetInfo), pers protocol.Perspective, logger utils.Logger) packetHandler {
  20. return &closedLocalConn{
  21. sendPacket: sendPacket,
  22. perspective: pers,
  23. logger: logger,
  24. }
  25. }
  26. func (c *closedLocalConn) handlePacket(p receivedPacket) {
  27. c.counter++
  28. // exponential backoff
  29. // only send a CONNECTION_CLOSE for the 1st, 2nd, 4th, 8th, 16th, ... packet arriving
  30. if bits.OnesCount32(c.counter) != 1 {
  31. return
  32. }
  33. c.logger.Debugf("Received %d packets after sending CONNECTION_CLOSE. Retransmitting.", c.counter)
  34. c.sendPacket(p.remoteAddr, p.info)
  35. }
  36. func (c *closedLocalConn) shutdown() {}
  37. func (c *closedLocalConn) destroy(error) {}
  38. func (c *closedLocalConn) getPerspective() protocol.Perspective { return c.perspective }
  39. // A closedRemoteConn is a connection that was closed remotely.
  40. // For such a connection, we might receive reordered packets that were sent before the CONNECTION_CLOSE.
  41. // We can just ignore those packets.
  42. type closedRemoteConn struct {
  43. perspective protocol.Perspective
  44. }
  45. var _ packetHandler = &closedRemoteConn{}
  46. func newClosedRemoteConn(pers protocol.Perspective) packetHandler {
  47. return &closedRemoteConn{perspective: pers}
  48. }
  49. func (s *closedRemoteConn) handlePacket(receivedPacket) {}
  50. func (s *closedRemoteConn) shutdown() {}
  51. func (s *closedRemoteConn) destroy(error) {}
  52. func (s *closedRemoteConn) getPerspective() protocol.Perspective { return s.perspective }