conn.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package quic
  2. import (
  3. "io"
  4. "net"
  5. "syscall"
  6. "time"
  7. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  8. "github.com/Psiphon-Labs/quic-go/internal/utils"
  9. )
  10. type connection interface {
  11. ReadPacket() (*receivedPacket, error)
  12. WritePacket(b []byte, addr net.Addr, oob []byte) (int, error)
  13. LocalAddr() net.Addr
  14. io.Closer
  15. }
  16. // If the PacketConn passed to Dial or Listen satisfies this interface, quic-go will read the ECN bits from the IP header.
  17. // In this case, ReadMsgUDP() will be used instead of ReadFrom() to read packets.
  18. type OOBCapablePacketConn interface {
  19. net.PacketConn
  20. SyscallConn() (syscall.RawConn, error)
  21. ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
  22. WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
  23. }
  24. var _ OOBCapablePacketConn = &net.UDPConn{}
  25. func wrapConn(pc net.PacketConn) (connection, error) {
  26. conn, ok := pc.(interface {
  27. SyscallConn() (syscall.RawConn, error)
  28. })
  29. if ok {
  30. rawConn, err := conn.SyscallConn()
  31. if err != nil {
  32. return nil, err
  33. }
  34. err = setDF(rawConn)
  35. if err != nil {
  36. return nil, err
  37. }
  38. }
  39. c, ok := pc.(OOBCapablePacketConn)
  40. if !ok {
  41. utils.DefaultLogger.Infof("PacketConn is not a net.UDPConn. Disabling optimizations possible on UDP connections.")
  42. return &basicConn{PacketConn: pc}, nil
  43. }
  44. return newConn(c)
  45. }
  46. type basicConn struct {
  47. net.PacketConn
  48. }
  49. var _ connection = &basicConn{}
  50. func (c *basicConn) ReadPacket() (*receivedPacket, error) {
  51. buffer := getPacketBuffer()
  52. // The packet size should not exceed protocol.MaxPacketBufferSize bytes
  53. // If it does, we only read a truncated packet, which will then end up undecryptable
  54. buffer.Data = buffer.Data[:protocol.MaxPacketBufferSize]
  55. n, addr, err := c.PacketConn.ReadFrom(buffer.Data)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &receivedPacket{
  60. remoteAddr: addr,
  61. rcvTime: time.Now(),
  62. data: buffer.Data[:n],
  63. buffer: buffer,
  64. }, nil
  65. }
  66. func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte) (n int, err error) {
  67. return c.PacketConn.WriteTo(b, addr)
  68. }