forked from quic-go/quic-go
introduce a OptimizeConn function to manually enable UDP optimizations
This commit is contained in:
19
sys_conn.go
19
sys_conn.go
@@ -15,13 +15,30 @@ import (
|
|||||||
type OOBCapablePacketConn interface {
|
type OOBCapablePacketConn interface {
|
||||||
net.PacketConn
|
net.PacketConn
|
||||||
SyscallConn() (syscall.RawConn, error)
|
SyscallConn() (syscall.RawConn, error)
|
||||||
|
SetReadBuffer(int) error
|
||||||
ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
|
ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
|
||||||
WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
|
WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ OOBCapablePacketConn = &net.UDPConn{}
|
var _ OOBCapablePacketConn = &net.UDPConn{}
|
||||||
|
|
||||||
func wrapConn(pc net.PacketConn) (rawConn, error) {
|
// OptimizeConn takes a net.PacketConn and attempts to enable various optimizations that will improve QUIC performance:
|
||||||
|
// 1. It enables the Don't Fragment (DF) bit on the IP header.
|
||||||
|
// This allows us to do DPLPMTUD (Path MTU Discovery).
|
||||||
|
// 2. It enables reading of the ECN bits from the IP header.
|
||||||
|
// This allows the remote node to speed up its loss detection and recovery.
|
||||||
|
// 3. It uses batched syscalls (recvmmsg) to more efficiently receive packets from the socket.
|
||||||
|
//
|
||||||
|
// For this to work, the connection needs to implement the OOBCapablePacketConn interface (as a *net.UDPConn does).
|
||||||
|
func OptimizeConn(c net.PacketConn) (net.PacketConn, error) {
|
||||||
|
return wrapConn(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapConn(pc net.PacketConn) (interface {
|
||||||
|
net.PacketConn
|
||||||
|
rawConn
|
||||||
|
}, error,
|
||||||
|
) {
|
||||||
conn, ok := pc.(interface {
|
conn, ok := pc.(interface {
|
||||||
SyscallConn() (syscall.RawConn, error)
|
SyscallConn() (syscall.RawConn, error)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package quic
|
|||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|
||||||
func newConn(c net.PacketConn, supportsDF bool) (rawConn, error) {
|
func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) {
|
||||||
return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil
|
return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConn(c OOBCapablePacketConn, supportsDF bool) (rawConn, error) {
|
func newConn(c OOBCapablePacketConn, supportsDF bool) (*basicConn, error) {
|
||||||
return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil
|
return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
transport.go
15
transport.go
@@ -30,10 +30,8 @@ type Transport struct {
|
|||||||
// A single net.PacketConn can only be handled by one Transport.
|
// A single net.PacketConn can only be handled by one Transport.
|
||||||
// Bad things will happen if passed to multiple Transports.
|
// Bad things will happen if passed to multiple Transports.
|
||||||
//
|
//
|
||||||
// If the connection satisfies the OOBCapablePacketConn interface
|
// If not done by the user, the connection is passed through OptimizeConn to enable a number of optimizations.
|
||||||
// (as a net.UDPConn does), ECN and packet info support will be enabled.
|
// After passing the connection to the Transport, its invalid to call ReadFrom and WriteTo.
|
||||||
// In this case, optimized syscalls might be used, skipping the
|
|
||||||
// ReadFrom and WriteTo calls to read / write packets.
|
|
||||||
Conn net.PacketConn
|
Conn net.PacketConn
|
||||||
|
|
||||||
// The length of the connection ID in bytes.
|
// The length of the connection ID in bytes.
|
||||||
@@ -180,11 +178,18 @@ func (t *Transport) init(isServer bool) error {
|
|||||||
t.initOnce.Do(func() {
|
t.initOnce.Do(func() {
|
||||||
getMultiplexer().AddConn(t.Conn)
|
getMultiplexer().AddConn(t.Conn)
|
||||||
|
|
||||||
conn, err := wrapConn(t.Conn)
|
var conn rawConn
|
||||||
|
if c, ok := t.Conn.(rawConn); ok {
|
||||||
|
conn = c
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
conn, err = wrapConn(t.Conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.initErr = err
|
t.initErr = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
t.conn = conn
|
||||||
|
|
||||||
t.logger = utils.DefaultLogger // TODO: make this configurable
|
t.logger = utils.DefaultLogger // TODO: make this configurable
|
||||||
t.conn = conn
|
t.conn = conn
|
||||||
|
|||||||
Reference in New Issue
Block a user