cache the serialized OOB in the conn, not in the packet info

We're allocating a lot of packetInfo structs during the lifetime of a
connection. It's better to keep that struct as small as possible.
This commit is contained in:
Marten Seemann 2021-03-16 13:54:19 +08:00
parent 1186a3ed79
commit 162cb16b31
8 changed files with 23 additions and 19 deletions

View file

@ -12,7 +12,7 @@ import (
type connection interface {
ReadPacket() (*receivedPacket, error)
WritePacket(b []byte, addr net.Addr, info *packetInfo) (int, error)
WritePacket(b []byte, addr net.Addr, oob []byte) (int, error)
LocalAddr() net.Addr
io.Closer
}
@ -60,6 +60,6 @@ func (c *basicConn) ReadPacket() (*receivedPacket, error) {
}, nil
}
func (c *basicConn) WritePacket(b []byte, addr net.Addr, info *packetInfo) (n int, err error) {
func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte) (n int, err error) {
return c.PacketConn.WriteTo(b, addr)
}

View file

@ -11,3 +11,5 @@ func newConn(c net.PacketConn) (connection, error) {
func inspectReadBuffer(interface{}) (int, error) {
return 0, nil
}
func (i *packetInfo) OOB() []byte { return nil }

View file

@ -171,8 +171,8 @@ func (c *oobConn) ReadPacket() (*receivedPacket, error) {
}, nil
}
func (c *oobConn) WritePacket(b []byte, addr net.Addr, info *packetInfo) (n int, err error) {
n, _, err = c.OOBCapablePacketConn.WriteMsgUDP(b, info.OOB(), addr.(*net.UDPAddr))
func (c *oobConn) WritePacket(b []byte, addr net.Addr, oob []byte) (n int, err error) {
n, _, err = c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr))
return n, err
}
@ -180,11 +180,6 @@ func (info *packetInfo) OOB() []byte {
if info == nil {
return nil
}
info.once.Do(info.computeOOB)
return info.oob
}
func (info *packetInfo) computeOOB() {
if ip4 := info.addr.To4(); ip4 != nil {
// struct in_pktinfo {
// unsigned int ipi_ifindex; /* Interface index */
@ -208,7 +203,7 @@ func (info *packetInfo) computeOOB() {
off += 4
}
copy(oob[off:], ip4)
info.oob = oob
return oob
} else if len(info.addr) == 16 {
// struct in6_pktinfo {
// struct in6_addr ipi6_addr; /* src/dst IPv6 address */
@ -224,8 +219,9 @@ func (info *packetInfo) computeOOB() {
off := cmsgLen(0)
off += copy(oob[off:], info.addr)
binary.LittleEndian.PutUint32(oob[off:], info.ifIndex)
info.oob = oob
return oob
}
return nil
}
func cmsgLen(datalen int) int {

View file

@ -35,3 +35,5 @@ func inspectReadBuffer(c net.PacketConn) (int, error) {
}
return size, serr
}
func (i *packetInfo) OOB() []byte { return nil }

View file

@ -469,7 +469,7 @@ func (h *packetHandlerMap) maybeSendStatelessReset(p *receivedPacket, connID pro
rand.Read(data)
data[0] = (data[0] & 0x7f) | 0x40
data = append(data, token[:]...)
if _, err := h.conn.WritePacket(data, p.remoteAddr, p.info); err != nil {
if _, err := h.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil {
h.logger.Debugf("Error sending Stateless Reset: %s", err)
}
}

View file

@ -17,16 +17,22 @@ type sconn struct {
remoteAddr net.Addr
info *packetInfo
oob []byte
}
var _ sendConn = &sconn{}
func newSendConn(c connection, remote net.Addr, info *packetInfo) sendConn {
return &sconn{connection: c, remoteAddr: remote, info: info}
return &sconn{
connection: c,
remoteAddr: remote,
info: info,
oob: info.OOB(),
}
}
func (c *sconn) Write(p []byte) error {
_, err := c.WritePacket(p, c.remoteAddr, c.info)
_, err := c.WritePacket(p, c.remoteAddr, c.oob)
return err
}

View file

@ -556,7 +556,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info *pack
if s.config.Tracer != nil {
s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(buf.Len()), nil)
}
_, err = s.conn.WritePacket(buf.Bytes(), remoteAddr, info)
_, err = s.conn.WritePacket(buf.Bytes(), remoteAddr, info.OOB())
return err
}
@ -633,7 +633,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han
if s.config.Tracer != nil {
s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(raw)), []logging.Frame{ccf})
}
_, err := s.conn.WritePacket(raw, remoteAddr, info)
_, err := s.conn.WritePacket(raw, remoteAddr, info.OOB())
return err
}
@ -656,7 +656,7 @@ func (s *baseServer) sendVersionNegotiationPacket(p *receivedPacket, hdr *wire.H
nil,
)
}
if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info); err != nil {
if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil {
s.logger.Debugf("Error sending Version Negotiation: %s", err)
}
}

View file

@ -62,8 +62,6 @@ type cryptoStreamHandler interface {
type packetInfo struct {
addr net.IP
ifIndex uint32
once sync.Once
oob []byte
}
type receivedPacket struct {