Skip to content

Commit

Permalink
fix for windows/macos
Browse files Browse the repository at this point in the history
  • Loading branch information
jkralik committed Nov 13, 2023
1 parent 164d34e commit dad3c79
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 40 deletions.
47 changes: 23 additions & 24 deletions net/connUDP.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ type UDPConn struct {
}

type ControlMessage struct {
Dst net.IP // destination address, receiving only
Src net.IP // source address, specifying only
// For connection oriented packetConn the ControlMessage fields are ignored, only linux supports set control message.

Dst net.IP // destination address of the packet
Src net.IP // source address of the packet
IfIndex int // interface index, 0 means any interface
}

Expand Down Expand Up @@ -72,18 +74,11 @@ type packetConnIPv4 struct {
supportsControlMessage bool
}

func isNotImplemented(err error) bool {
return strings.Contains(err.Error(), "not implemented on")
}

func newPacketConnIPv4(p *ipv4.PacketConn) (*packetConnIPv4, error) {
func newPacketConnIPv4(p *ipv4.PacketConn) *packetConnIPv4 {
if err := p.SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface|ipv4.FlagSrc, true); err != nil {
if isNotImplemented(err) {
return &packetConnIPv4{packetConn: p, supportsControlMessage: false}, nil
}
return nil, err
return &packetConnIPv4{packetConn: p, supportsControlMessage: false}
}
return &packetConnIPv4{packetConn: p, supportsControlMessage: true}, nil
return &packetConnIPv4{packetConn: p, supportsControlMessage: true}
}

func (p *packetConnIPv4) SupportsControlMessage() bool {
Expand Down Expand Up @@ -150,14 +145,11 @@ type packetConnIPv6 struct {
supportsControlMessage bool
}

func newPacketConnIPv6(p *ipv6.PacketConn) (*packetConnIPv6, error) {
func newPacketConnIPv6(p *ipv6.PacketConn) *packetConnIPv6 {
if err := p.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface|ipv6.FlagSrc, true); err != nil {
if isNotImplemented(err) {
return &packetConnIPv6{packetConn: p, supportsControlMessage: false}, nil
}
return nil, err
return &packetConnIPv6{packetConn: p, supportsControlMessage: false}
}
return &packetConnIPv6{packetConn: p, supportsControlMessage: true}, nil
return &packetConnIPv6{packetConn: p, supportsControlMessage: true}
}

func (p *packetConnIPv6) SupportsControlMessage() bool {
Expand Down Expand Up @@ -265,12 +257,9 @@ func newPacketConnWithAddr(addr *net.UDPAddr, c *net.UDPConn) (packetConn, error
var pc packetConn
var err error
if IsIPv6(addr.IP) {
pc, err = newPacketConnIPv6(ipv6.NewPacketConn(c))
if err != nil {
return nil, fmt.Errorf("invalid UDPv6 connection: %w", err)
}
pc = newPacketConnIPv6(ipv6.NewPacketConn(c))
} else {
pc, err = newPacketConnIPv4(ipv4.NewPacketConn(c))
pc = newPacketConnIPv4(ipv4.NewPacketConn(c))
if err != nil {
return nil, fmt.Errorf("invalid UDPv4 connection: %w", err)
}
Expand Down Expand Up @@ -524,6 +513,16 @@ func (c *UDPConn) writeMulticast(ctx context.Context, raddr *net.UDPAddr, buffer
return nil
}

func (c *UDPConn) writeTo(raddr *net.UDPAddr, cm *ControlMessage, buffer []byte) (int, error) {
if !supportsOverrideRemoteAddr(c.connection) {
// If the remote address is set, we can use it as the destination address
// because the connection is already established.
// Note: Overwriting the destination address is only supported on Linux.
return c.connection.Write(buffer)
}
return c.packetConn.WriteTo(buffer, cm, raddr)
}

// WriteWithContext writes data with context.
func (c *UDPConn) WriteWithContext(ctx context.Context, raddr *net.UDPAddr, cm *ControlMessage, buffer []byte) error {
if raddr == nil {
Expand All @@ -538,7 +537,7 @@ func (c *UDPConn) WriteWithContext(ctx context.Context, raddr *net.UDPAddr, cm *
if c.closed.Load() {
return ErrConnectionIsClosed
}
n, err := c.packetConn.WriteTo(buffer, cm, raddr)
n, err := c.writeTo(raddr, cm, buffer)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion net/connUDP_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,20 +369,25 @@ func TestUDPConnWriteToAddr(t *testing.T) {
}
}

func TestPacketConnIPv4ReadFrom(t *testing.T) {
func TestPacketConnReadFrom(t *testing.T) {
readUDP4Conn, err := net.ListenUDP("udp4", &net.UDPAddr{Port: 1234})
require.NoError(t, err)
defer func() {
errC := readUDP4Conn.Close()
require.NoError(t, errC)
}()

require.Nil(t, readUDP4Conn.RemoteAddr())

writeUDP4Conn, err := net.DialUDP("udp4", nil, readUDP4Conn.LocalAddr().(*net.UDPAddr))
require.NoError(t, err)
defer func() {
errC := writeUDP4Conn.Close()
require.NoError(t, errC)
}()

require.NotNil(t, writeUDP4Conn.RemoteAddr())

readUDP6Conn, err := net.ListenUDP("udp6", &net.UDPAddr{Port: 1235})
require.NoError(t, err)
defer func() {
Expand Down
9 changes: 9 additions & 0 deletions net/supportsOverrideRemoteAddr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !linux

package net

import "net"

func supportsOverrideRemoteAddr(c *net.UDPConn) bool {
return c.RemoteAddr() == nil
}
7 changes: 7 additions & 0 deletions net/supportsOverrideRemoteAddr_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net

import "net"

func supportsOverrideRemoteAddr(*net.UDPConn) bool {
return true
}
15 changes: 0 additions & 15 deletions net/udp.go

This file was deleted.

0 comments on commit dad3c79

Please sign in to comment.