Browse Source

x/net/ipv4: enable IP_STRIPHDR sticky socket option on latest darwin kernels

This reduces allocation and copy ops with net.IPConn-based
ipv4.PacketConn on latest darwin kernels.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/184770043
Mikio Hara 11 years ago
parent
commit
5c9495a327
4 changed files with 23 additions and 8 deletions
  1. 7 1
      ipv4/endpoint.go
  2. 12 6
      ipv4/payload_cmsg.go
  3. 2 1
      ipv4/sockopt.go
  4. 2 0
      ipv4/sys_darwin.go

+ 7 - 1
ipv4/endpoint.go

@@ -97,11 +97,17 @@ func (c *PacketConn) Close() error {
 // NewPacketConn returns a new PacketConn using c as its underlying
 // transport.
 func NewPacketConn(c net.PacketConn) *PacketConn {
-	return &PacketConn{
+	p := &PacketConn{
 		genericOpt:     genericOpt{Conn: c.(net.Conn)},
 		dgramOpt:       dgramOpt{PacketConn: c},
 		payloadHandler: payloadHandler{PacketConn: c},
 	}
+	if _, ok := c.(*net.IPConn); ok && sockOpts[ssoStripHeader].name > 0 {
+		if fd, err := p.payloadHandler.sysfd(); err == nil {
+			setInt(fd, &sockOpts[ssoStripHeader], boolint(true))
+		}
+	}
+	return p
 }
 
 // A RawConn represents a packet network endpoint that uses the IPv4

+ 12 - 6
ipv4/payload_cmsg.go

@@ -27,13 +27,19 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
 			return 0, nil, nil, err
 		}
 	case *net.IPConn:
-		nb := make([]byte, maxHeaderLen+len(b))
-		if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil {
-			return 0, nil, nil, err
+		if sockOpts[ssoStripHeader].name > 0 {
+			if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
+				return 0, nil, nil, err
+			}
+		} else {
+			nb := make([]byte, maxHeaderLen+len(b))
+			if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil {
+				return 0, nil, nil, err
+			}
+			hdrlen := int(nb[0]&0x0f) << 2
+			copy(b, nb[hdrlen:])
+			n -= hdrlen
 		}
-		hdrlen := int(nb[0]&0x0f) << 2
-		copy(b, nb[hdrlen:])
-		n -= hdrlen
 	default:
 		return 0, nil, nil, errInvalidConnType
 	}

+ 2 - 1
ipv4/sockopt.go

@@ -15,7 +15,8 @@ const (
 	ssoReceiveDst                // header field on received packet
 	ssoReceiveInterface          // inbound interface on received packet
 	ssoPacketInfo                // incbound or outbound packet path
-	ssoHeaderPrepend             // ipv4 header
+	ssoHeaderPrepend             // ipv4 header prepend
+	ssoStripHeader               // strip ipv4 header
 	ssoJoinGroup                 // any-source multicast
 	ssoLeaveGroup                // any-source multicast
 	ssoJoinSourceGroup           // source-specific multicast

+ 2 - 0
ipv4/sys_darwin.go

@@ -58,6 +58,8 @@ func init() {
 		ctlOpts[ctlPacketInfo].parse = parsePacketInfo
 		sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
 		sockOpts[ssoPacketInfo].typ = ssoTypeInt
+		sockOpts[ssoStripHeader].name = sysIP_STRIPHDR
+		sockOpts[ssoStripHeader].typ = ssoTypeInt
 		sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
 		sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
 		sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq