diff options
author | Ian Gudger <igudger@google.com> | 2018-05-17 12:49:16 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-05-17 12:50:22 -0700 |
commit | a8d7cee3e819f0e278c8da9ff2e7d72fbe0e82b8 (patch) | |
tree | 3da0e396c5738007dcd5e418c1fb4cdc67c4843a /pkg/tcpip/transport/udp/endpoint.go | |
parent | 31386185fe7c2079ee412a411e536a5bf9e9eb25 (diff) |
Fix sendto for dual stack UDP sockets
Previously, dual stack UDP sockets bound to an IPv4 address could not use
sendto to communicate with IPv4 addresses. Further, dual stack UDP sockets
bound to an IPv6 address could use sendto to communicate with IPv4 addresses.
Neither of these behaviors are consistent with Linux.
PiperOrigin-RevId: 197036024
Change-Id: Ic3713efc569f26196e35bb41e6ad63f23675fc90
Diffstat (limited to 'pkg/tcpip/transport/udp/endpoint.go')
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index f86fc6d5a..6fcddd028 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -62,7 +62,6 @@ type endpoint struct { id stack.TransportEndpointID state endpointState bindNICID tcpip.NICID - bindAddr tcpip.Address regNICID tcpip.NICID route stack.Route `state:"manual"` dstPort uint16 @@ -267,13 +266,13 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc toCopy := *to to = &toCopy - netProto, err := e.checkV4Mapped(to, true) + netProto, err := e.checkV4Mapped(to, false) if err != nil { return 0, err } // Find the enpoint. - r, err := e.stack.FindRoute(nicid, e.bindAddr, to.Addr, netProto) + r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, to.Addr, netProto) if err != nil { return 0, err } @@ -439,11 +438,16 @@ func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress, allowMismatch bool) (t if addr.Addr == "\x00\x00\x00\x00" { addr.Addr = "" } + + // Fail if we are bound to an IPv6 address. + if !allowMismatch && len(e.id.LocalAddress) == 16 { + return 0, tcpip.ErrNetworkUnreachable + } } // Fail if we're bound to an address length different from the one we're // checking. - if l := len(e.id.LocalAddress); !allowMismatch && l != 0 && l != len(addr.Addr) { + if l := len(e.id.LocalAddress); l != 0 && l != len(addr.Addr) { return 0, tcpip.ErrInvalidEndpointState } @@ -485,7 +489,7 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error { } // Find a route to the desired destination. - r, err := e.stack.FindRoute(nicid, e.bindAddr, addr.Addr, netProto) + r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, addr.Addr, netProto) if err != nil { return err } @@ -605,7 +609,7 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error return tcpip.ErrInvalidEndpointState } - netProto, err := e.checkV4Mapped(&addr, false) + netProto, err := e.checkV4Mapped(&addr, true) if err != nil { return err } @@ -670,7 +674,6 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcp } e.bindNICID = addr.NIC - e.bindAddr = addr.Addr return nil } |