multiplexer.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package quic
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "github.com/lucas-clemente/quic-go/internal/utils"
  7. )
  8. var (
  9. connMuxerOnce sync.Once
  10. connMuxer multiplexer
  11. )
  12. type multiplexer interface {
  13. AddConn(net.PacketConn, int) (packetHandlerManager, error)
  14. }
  15. type connManager struct {
  16. connIDLen int
  17. manager packetHandlerManager
  18. }
  19. // The connMultiplexer listens on multiple net.PacketConns and dispatches
  20. // incoming packets to the session handler.
  21. type connMultiplexer struct {
  22. mutex sync.Mutex
  23. conns map[net.PacketConn]connManager
  24. newPacketHandlerManager func(net.PacketConn, int, utils.Logger) packetHandlerManager // so it can be replaced in the tests
  25. logger utils.Logger
  26. }
  27. var _ multiplexer = &connMultiplexer{}
  28. func getMultiplexer() multiplexer {
  29. connMuxerOnce.Do(func() {
  30. connMuxer = &connMultiplexer{
  31. conns: make(map[net.PacketConn]connManager),
  32. logger: utils.DefaultLogger.WithPrefix("muxer"),
  33. newPacketHandlerManager: newPacketHandlerMap,
  34. }
  35. })
  36. return connMuxer
  37. }
  38. func (m *connMultiplexer) AddConn(c net.PacketConn, connIDLen int) (packetHandlerManager, error) {
  39. m.mutex.Lock()
  40. defer m.mutex.Unlock()
  41. p, ok := m.conns[c]
  42. if !ok {
  43. manager := m.newPacketHandlerManager(c, connIDLen, m.logger)
  44. p = connManager{connIDLen: connIDLen, manager: manager}
  45. m.conns[c] = p
  46. }
  47. if p.connIDLen != connIDLen {
  48. return nil, fmt.Errorf("cannot use %d byte connection IDs on a connection that is already using %d byte connction IDs", connIDLen, p.connIDLen)
  49. }
  50. return p.manager, nil
  51. }