mirror of
https://github.com/golang/net.git
synced 2026-03-31 02:17:08 +09:00
ipv4: work around FreeBSD 11.3 or 12 kernel running COMPAT_FREEBSD32
On FreeBSD 11.3 or 12 kernel running COMPAT_FREEBSD32, it looks like the system call recvmsg always returns an incorrect length for the out-of-band data. This change adjusts the length when it looks incorrect and the running kernel is FreeBSD 11.3 or above. Fixes golang/go#30899. Change-Id: Ia58d8b4bd4caf3783d2e38161ee4afd1a64ca522 Reviewed-on: https://go-review.googlesource.com/c/net/+/168297 Run-TryBot: Mikio Hara <mikioh.public.networking@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
@@ -89,6 +89,9 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
|
||||
n = 0
|
||||
err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
|
||||
}
|
||||
if compatFreeBSD32 && ms[0].NN > 0 {
|
||||
adjustFreeBSD32(&ms[0])
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
@@ -152,6 +155,9 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
|
||||
n = 0
|
||||
err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
|
||||
}
|
||||
if compatFreeBSD32 && ms[0].NN > 0 {
|
||||
adjustFreeBSD32(&ms[0])
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/net/internal/socket"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -23,9 +25,20 @@ var (
|
||||
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
|
||||
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
|
||||
freebsdVersion uint32
|
||||
freebsdVersion uint32
|
||||
compatFreeBSD32 bool // 386 emulation on amd64
|
||||
)
|
||||
|
||||
// See golang.org/issue/30899.
|
||||
func adjustFreeBSD32(m *socket.Message) {
|
||||
if freebsdVersion >= 1103000 {
|
||||
l := (m.NN + 4 - 1) &^ (4 - 1)
|
||||
if m.NN < l && l <= len(m.OOB) {
|
||||
m.NN = l
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func boolint(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
|
||||
@@ -46,6 +46,9 @@ func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMess
|
||||
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
|
||||
}
|
||||
if m.NN > 0 {
|
||||
if compatFreeBSD32 {
|
||||
adjustFreeBSD32(&m)
|
||||
}
|
||||
cm = new(ControlMessage)
|
||||
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
|
||||
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
|
||||
|
||||
@@ -49,6 +49,9 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
|
||||
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
|
||||
}
|
||||
if m.NN > 0 {
|
||||
if compatFreeBSD32 {
|
||||
adjustFreeBSD32(&m)
|
||||
}
|
||||
cm = new(ControlMessage)
|
||||
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
|
||||
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
|
||||
|
||||
@@ -13,8 +13,6 @@ import (
|
||||
"golang.org/x/net/internal/socket"
|
||||
)
|
||||
|
||||
var compatFreeBSD32 bool // 386 emulation on amd64
|
||||
|
||||
func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
|
||||
var gr groupReq
|
||||
if ifi != nil {
|
||||
|
||||
Reference in New Issue
Block a user