diff --git a/conn/bind_std.go b/conn/bind_std.go index 46df7fd..7381069 100644 --- a/conn/bind_std.go +++ b/conn/bind_std.go @@ -46,6 +46,14 @@ type StdNetBind struct { blackhole4 bool blackhole6 bool + + receiverCreator ReceiverCreator +} + +func NewStdNetBindWithReceiverCreator(receiverCreator ReceiverCreator) *StdNetBind { + b, _ := NewStdNetBind().(*StdNetBind) + b.receiverCreator = receiverCreator + return b } func NewStdNetBind() Bind { @@ -65,7 +73,7 @@ func NewStdNetBind() Bind { msgs := make([]ipv6.Message, IdealBatchSize) for i := range msgs { msgs[i].Buffers = make(net.Buffers, 1) - msgs[i].OOB = make([]byte, 0, stickyControlSize+gsoControlSize) + msgs[i].OOB = make([]byte, 0, StickyControlSize+gsoControlSize) } return &msgs }, @@ -179,7 +187,12 @@ again: v4pc = ipv4.NewPacketConn(v4conn) s.ipv4PC = v4pc } - fns = append(fns, s.makeReceiveIPv4(v4pc, v4conn, s.ipv4RxOffload)) + if s.receiverCreator != nil { + // Todo: check if this still works + fns = append(fns, s.receiverCreator.CreateIPv4ReceiverFn(&s.msgsPool, v4pc, v4conn)) + } else { + fns = append(fns, s.makeReceiveIPv4(v4pc, v4conn, s.ipv4RxOffload)) + } s.ipv4 = v4conn } if v6conn != nil { @@ -271,7 +284,7 @@ func (s *StdNetBind) receiveIP( } addrPort := msg.Addr.(*net.UDPAddr).AddrPort() ep := &StdNetEndpoint{AddrPort: addrPort} // TODO: remove allocation - getSrcFromControl(msg.OOB[:msg.NN], ep) + GetSrcFromControl(msg.OOB[:msg.NN], ep) eps[i] = ep } return numMsgs, nil diff --git a/conn/receiver_creator.go b/conn/receiver_creator.go new file mode 100644 index 0000000..fd99148 --- /dev/null +++ b/conn/receiver_creator.go @@ -0,0 +1,12 @@ +package conn + +import ( + "net" + "sync" + + "golang.org/x/net/ipv4" +) + +type ReceiverCreator interface { + CreateIPv4ReceiverFn(msgPool *sync.Pool, pc *ipv4.PacketConn, conn *net.UDPConn) ReceiveFunc +} diff --git a/conn/sticky_default.go b/conn/sticky_default.go index 0b21386..6758edd 100644 --- a/conn/sticky_default.go +++ b/conn/sticky_default.go @@ -25,9 +25,9 @@ func (e *StdNetEndpoint) SrcToString() string { // {get,set}srcControl feature set, but use alternatively named flags and need // ports and require testing. -// getSrcFromControl parses the control for PKTINFO and if found updates ep with +// GetSrcFromControl parses the control for PKTINFO and if found updates ep with // the source information found. -func getSrcFromControl(control []byte, ep *StdNetEndpoint) { +func GetSrcFromControl(control []byte, ep *StdNetEndpoint) { } // setSrcControl parses the control for PKTINFO and if found updates ep with @@ -35,8 +35,8 @@ func getSrcFromControl(control []byte, ep *StdNetEndpoint) { func setSrcControl(control *[]byte, ep *StdNetEndpoint) { } -// stickyControlSize returns the recommended buffer size for pooling sticky +// StickyControlSize returns the recommended buffer size for pooling sticky // offloading control data. -const stickyControlSize = 0 +const StickyControlSize = 0 const StdNetSupportsStickySockets = false diff --git a/conn/sticky_linux.go b/conn/sticky_linux.go index 8e206e9..3a7c801 100644 --- a/conn/sticky_linux.go +++ b/conn/sticky_linux.go @@ -45,9 +45,9 @@ func (e *StdNetEndpoint) SrcToString() string { return e.SrcIP().String() } -// getSrcFromControl parses the control for PKTINFO and if found updates ep with +// GetSrcFromControl parses the control for PKTINFO and if found updates ep with // the source information found. -func getSrcFromControl(control []byte, ep *StdNetEndpoint) { +func GetSrcFromControl(control []byte, ep *StdNetEndpoint) { ep.ClearSrc() var ( @@ -105,8 +105,8 @@ func setSrcControl(control *[]byte, ep *StdNetEndpoint) { *control = append(*control, ep.src...) } -// stickyControlSize returns the recommended buffer size for pooling sticky +// StickyControlSize returns the recommended buffer size for pooling sticky // offloading control data. -var stickyControlSize = unix.CmsgSpace(unix.SizeofInet6Pktinfo) +var StickyControlSize = unix.CmsgSpace(unix.SizeofInet6Pktinfo) const StdNetSupportsStickySockets = true diff --git a/conn/sticky_linux_test.go b/conn/sticky_linux_test.go index d2bd584..f36e84c 100644 --- a/conn/sticky_linux_test.go +++ b/conn/sticky_linux_test.go @@ -60,7 +60,7 @@ func Test_setSrcControl(t *testing.T) { } setSrc(ep, netip.MustParseAddr("127.0.0.1"), 5) - control := make([]byte, stickyControlSize) + control := make([]byte, StickyControlSize) setSrcControl(&control, ep) @@ -89,7 +89,7 @@ func Test_setSrcControl(t *testing.T) { } setSrc(ep, netip.MustParseAddr("::1"), 5) - control := make([]byte, stickyControlSize) + control := make([]byte, StickyControlSize) setSrcControl(&control, ep) @@ -113,7 +113,7 @@ func Test_setSrcControl(t *testing.T) { }) t.Run("ClearOnNoSrc", func(t *testing.T) { - control := make([]byte, stickyControlSize) + control := make([]byte, StickyControlSize) hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0])) hdr.Level = 1 hdr.Type = 2 @@ -129,7 +129,7 @@ func Test_setSrcControl(t *testing.T) { func Test_getSrcFromControl(t *testing.T) { t.Run("IPv4", func(t *testing.T) { - control := make([]byte, stickyControlSize) + control := make([]byte, StickyControlSize) hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0])) hdr.Level = unix.IPPROTO_IP hdr.Type = unix.IP_PKTINFO @@ -139,7 +139,7 @@ func Test_getSrcFromControl(t *testing.T) { info.Ifindex = 5 ep := &StdNetEndpoint{} - getSrcFromControl(control, ep) + GetSrcFromControl(control, ep) if ep.SrcIP() != netip.MustParseAddr("127.0.0.1") { t.Errorf("unexpected address: %v", ep.SrcIP()) @@ -149,7 +149,7 @@ func Test_getSrcFromControl(t *testing.T) { } }) t.Run("IPv6", func(t *testing.T) { - control := make([]byte, stickyControlSize) + control := make([]byte, StickyControlSize) hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0])) hdr.Level = unix.IPPROTO_IPV6 hdr.Type = unix.IPV6_PKTINFO @@ -159,7 +159,7 @@ func Test_getSrcFromControl(t *testing.T) { info.Ifindex = 5 ep := &StdNetEndpoint{} - getSrcFromControl(control, ep) + GetSrcFromControl(control, ep) if ep.SrcIP() != netip.MustParseAddr("::1") { t.Errorf("unexpected address: %v", ep.SrcIP()) @@ -173,7 +173,7 @@ func Test_getSrcFromControl(t *testing.T) { ep := &StdNetEndpoint{} setSrc(ep, netip.MustParseAddr("::1"), 5) - getSrcFromControl(control, ep) + GetSrcFromControl(control, ep) if ep.SrcIP().IsValid() { t.Errorf("unexpected address: %v", ep.SrcIP()) } @@ -200,7 +200,7 @@ func Test_getSrcFromControl(t *testing.T) { combined = append(combined, control...) ep := &StdNetEndpoint{} - getSrcFromControl(combined, ep) + GetSrcFromControl(combined, ep) if ep.SrcIP() != netip.MustParseAddr("127.0.0.1") { t.Errorf("unexpected address: %v", ep.SrcIP()) diff --git a/device/queueconstants_windows.go b/device/queueconstants_windows.go index 1eee32b..e085f3b 100644 --- a/device/queueconstants_windows.go +++ b/device/queueconstants_windows.go @@ -10,6 +10,6 @@ const ( QueueOutboundSize = 1024 QueueInboundSize = 1024 QueueHandshakeSize = 1024 - MaxSegmentSize = 2048 - 32 // largest possible UDP datagram - PreallocatedBuffersPerPool = 0 // Disable and allow for infinite memory growth + MaxSegmentSize = 65535 // Match with WINTUN_MAX_IP_PACKET_SIZE macro definition + PreallocatedBuffersPerPool = 0 // Disable and allow for infinite memory growth )