Enable IP_RECVTOS socket option for datagram sockets

Added the ability to get/set the IP_RECVTOS socket option on UDP endpoints. If
enabled, TOS from the incoming Network Header passed as ancillary data in the
ControlMessages.

Test:
* Added unit test to udp_test.go that tests getting/setting as well as
verifying that we receive expected TOS from incoming packet.
* Added a syscall test
PiperOrigin-RevId: 287029703
This commit is contained in:
Ryan Heacock
2019-12-24 08:49:39 -08:00
committed by gVisor bot
parent 574e988f2b
commit e013c48c78
11 changed files with 201 additions and 19 deletions
+41 -1
View File
@@ -1323,6 +1323,21 @@ func getSockOptIP(t *kernel.Task, ep commonEndpoint, name, outLen int, family in
}
return int32(v), nil
case linux.IP_RECVTOS:
if outLen < sizeOfInt32 {
return nil, syserr.ErrInvalidArgument
}
var v tcpip.ReceiveTOSOption
if err := ep.GetSockOpt(&v); err != nil {
return nil, syserr.TranslateNetstackError(err)
}
if v {
return int32(1), nil
}
return int32(0), nil
default:
emitUnimplementedEventIP(t, name)
}
@@ -1808,6 +1823,16 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s
}
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.IPv4TOSOption(v)))
case linux.IP_RECVTOS:
v, err := parseIntOrChar(optVal)
if err != nil {
return err
}
return syserr.TranslateNetstackError(ep.SetSockOpt(
tcpip.ReceiveTOSOption(v != 0),
))
case linux.IP_ADD_SOURCE_MEMBERSHIP,
linux.IP_BIND_ADDRESS_NO_PORT,
linux.IP_BLOCK_SOURCE,
@@ -1828,7 +1853,6 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s
linux.IP_RECVFRAGSIZE,
linux.IP_RECVOPTS,
linux.IP_RECVORIGDSTADDR,
linux.IP_RECVTOS,
linux.IP_RECVTTL,
linux.IP_RETOPTS,
linux.IP_TRANSPARENT,
@@ -2139,6 +2163,21 @@ func (s *SocketOperations) fillCmsgInq(cmsg *socket.ControlMessages) {
cmsg.IP.Inq = int32(len(s.readView) + rcvBufUsed)
}
func (s *SocketOperations) fillCmsgTOS(cmsg *socket.ControlMessages) {
if s.skType != linux.SOCK_DGRAM {
return
}
var receiveTOS tcpip.ReceiveTOSOption
if err := s.Endpoint.GetSockOpt(&receiveTOS); err != nil {
return
}
if !receiveTOS {
return
}
cmsg.IP.HasTOS = s.readCM.HasTOS
cmsg.IP.TOS = s.readCM.TOS
}
// nonBlockingRead issues a non-blocking read.
//
// TODO(b/78348848): Support timestamps for stream sockets.
@@ -2244,6 +2283,7 @@ func (s *SocketOperations) nonBlockingRead(ctx context.Context, dst usermem.IOSe
cmsg := s.controlMessages()
s.fillCmsgInq(&cmsg)
s.fillCmsgTOS(&cmsg)
return n, flags, addr, addrLen, cmsg, syserr.FromError(err)
}