github.com/tumi8/quic-go@v0.37.4-tum/send_conn.go (about) 1 package quic 2 3 import ( 4 "math" 5 "net" 6 7 "github.com/tumi8/quic-go/noninternal/protocol" 8 ) 9 10 // A sendConn allows sending using a simple Write() on a non-connected packet conn. 11 type sendConn interface { 12 Write(b []byte, size protocol.ByteCount) error 13 Close() error 14 LocalAddr() net.Addr 15 RemoteAddr() net.Addr 16 17 capabilities() connCapabilities 18 } 19 20 type sconn struct { 21 rawConn 22 23 remoteAddr net.Addr 24 info packetInfo 25 oob []byte 26 } 27 28 var _ sendConn = &sconn{} 29 30 func newSendConn(c rawConn, remote net.Addr) *sconn { 31 sc := &sconn{ 32 rawConn: c, 33 remoteAddr: remote, 34 } 35 if c.capabilities().GSO { 36 // add 32 bytes, so we can add the UDP_SEGMENT msg 37 sc.oob = make([]byte, 0, 32) 38 } 39 return sc 40 } 41 42 func newSendConnWithPacketInfo(c rawConn, remote net.Addr, info packetInfo) *sconn { 43 oob := info.OOB() 44 if c.capabilities().GSO { 45 // add 32 bytes, so we can add the UDP_SEGMENT msg 46 l := len(oob) 47 oob = append(oob, make([]byte, 32)...) 48 oob = oob[:l] 49 } 50 return &sconn{ 51 rawConn: c, 52 remoteAddr: remote, 53 info: info, 54 oob: oob, 55 } 56 } 57 58 func (c *sconn) Write(p []byte, size protocol.ByteCount) error { 59 if size > math.MaxUint16 { 60 panic("size overflow") 61 } 62 _, err := c.WritePacket(p, uint16(size), c.remoteAddr, c.oob) 63 return err 64 } 65 66 func (c *sconn) RemoteAddr() net.Addr { 67 return c.remoteAddr 68 } 69 70 func (c *sconn) LocalAddr() net.Addr { 71 addr := c.rawConn.LocalAddr() 72 if c.info.addr.IsValid() { 73 if udpAddr, ok := addr.(*net.UDPAddr); ok { 74 addrCopy := *udpAddr 75 addrCopy.IP = c.info.addr.AsSlice() 76 addr = &addrCopy 77 } 78 } 79 return addr 80 }