[client] Add flag to configure MTU (#4213)

This commit is contained in:
Viktor Liu
2025-08-26 16:00:14 +02:00
committed by GitHub
parent 9f84165763
commit f063866ce8
54 changed files with 710 additions and 434 deletions

View File

@@ -5,14 +5,16 @@ import (
"os"
"os/signal"
"github.com/netbirdio/netbird/sharedsock"
log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/client/iface"
"github.com/netbirdio/netbird/sharedsock"
)
func main() {
port := 51820
rawSock, err := sharedsock.Listen(port, sharedsock.NewIncomingSTUNFilter())
rawSock, err := sharedsock.Listen(port, sharedsock.NewIncomingSTUNFilter(), iface.DefaultMTU)
if err != nil {
panic(err)
}

View File

@@ -36,6 +36,7 @@ type SharedSocket struct {
conn4 *socket.Conn
conn6 *socket.Conn
port int
mtu uint16
routerMux sync.RWMutex
router routing.Router
packetDemux chan rcvdPacket
@@ -56,12 +57,19 @@ var writeSerializerOptions = gopacket.SerializeOptions{
FixLengths: true,
}
// Maximum overhead for IP + UDP headers on raw socket
// IPv4: max 60 bytes (20 base + 40 options) + UDP 8 bytes = 68 bytes
// IPv6: 40 bytes + UDP 8 bytes = 48 bytes
// We use the maximum (68) for both IPv4 and IPv6
const maxIPUDPOverhead = 68
// Listen creates an IPv4 and IPv6 raw sockets, starts a reader and routing table routines
func Listen(port int, filter BPFFilter) (_ net.PacketConn, err error) {
func Listen(port int, filter BPFFilter, mtu uint16) (_ net.PacketConn, err error) {
ctx, cancel := context.WithCancel(context.Background())
rawSock := &SharedSocket{
ctx: ctx,
cancel: cancel,
mtu: mtu,
port: port,
packetDemux: make(chan rcvdPacket),
}
@@ -222,8 +230,10 @@ func (s *SharedSocket) Close() error {
// read start a read loop for a specific receiver and sends the packet to the packetDemux channel
func (s *SharedSocket) read(receiver receiver) {
// Buffer reuse is safe: packetDemux is unbuffered, so read() blocks until
// ReadFrom() synchronously processes the packet before next iteration
buf := make([]byte, s.mtu+maxIPUDPOverhead)
for {
buf := make([]byte, 1500)
n, addr, err := receiver(s.ctx, buf, 0)
select {
case <-s.ctx.Done():

View File

@@ -21,7 +21,7 @@ func TestShouldReadSTUNOnReadFrom(t *testing.T) {
// create raw socket on a port
testingPort := 51821
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter())
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter(), 1280)
require.NoError(t, err, "received an error while creating STUN listener, error: %s", err)
err = rawSock.SetReadDeadline(time.Now().Add(3 * time.Second))
require.NoError(t, err, "unable to set deadline, error: %s", err)
@@ -76,7 +76,7 @@ func TestShouldReadSTUNOnReadFrom(t *testing.T) {
func TestShouldNotReadNonSTUNPackets(t *testing.T) {
testingPort := 39439
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter())
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter(), 1280)
require.NoError(t, err, "received an error while creating STUN listener, error: %s", err)
defer rawSock.Close()
@@ -110,7 +110,7 @@ func TestWriteTo(t *testing.T) {
defer udpListener.Close()
testingPort := 39440
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter())
rawSock, err := Listen(testingPort, NewIncomingSTUNFilter(), 1280)
require.NoError(t, err, "received an error while creating STUN listener, error: %s", err)
defer rawSock.Close()
@@ -144,7 +144,7 @@ func TestWriteTo(t *testing.T) {
}
func TestSharedSocket_Close(t *testing.T) {
rawSock, err := Listen(39440, NewIncomingSTUNFilter())
rawSock, err := Listen(39440, NewIncomingSTUNFilter(), 1280)
require.NoError(t, err, "received an error while creating STUN listener, error: %s", err)
errGrp := errgroup.Group{}

View File

@@ -9,6 +9,6 @@ import (
)
// Listen is not supported on other platforms then Linux
func Listen(port int, filter BPFFilter) (net.PacketConn, error) {
func Listen(port int, filter BPFFilter, mtu uint16) (net.PacketConn, error) {
return nil, fmt.Errorf("not supported OS %s. SharedSocket is only supported on Linux", runtime.GOOS)
}