Move netstack's isTCP/UDP/ICMPSocket methods into socket package.

They are useful across other socket implementations.

PiperOrigin-RevId: 510699847
This commit is contained in:
Nicolas Lacasse
2023-02-18 13:27:45 -08:00
committed by gVisor bot
parent 0650bd1a5c
commit c020e2de83
3 changed files with 48 additions and 25 deletions
+1
View File
@@ -32,6 +32,7 @@ const (
IPPROTO_GRE = 47
IPPROTO_ESP = 50
IPPROTO_AH = 51
IPPROTO_ICMPV6 = 58
IPPROTO_MTP = 92
IPPROTO_BEETPH = 94
IPPROTO_ENCAP = 98
+11 -25
View File
@@ -1055,7 +1055,7 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family
// This option is only viable for TCP endpoints.
var v bool
if _, skType, skProto := s.Type(); isTCPSocket(skType, skProto) {
if socket.IsTCP(s) {
v = tcp.EndpointState(ep.State()) == tcp.StateListen
}
vP := primitive.Int32(boolToInt32(v))
@@ -1074,8 +1074,7 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family
// getSockOptTCP implements GetSockOpt when level is SOL_TCP.
func getSockOptTCP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name, outLen int) (marshal.Marshallable, *syserr.Error) {
if _, skType, skProto := s.Type(); !isTCPSocket(skType, skProto) {
log.Warningf("SOL_TCP options are only supported on TCP sockets: skType, skProto = %v, %d", skType, skProto)
if !socket.IsTCP(s) {
return nil, syserr.ErrUnknownProtocolOption
}
@@ -1975,8 +1974,7 @@ func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i
// setSockOptTCP implements SetSockOpt when level is SOL_TCP.
func setSockOptTCP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int, optVal []byte) *syserr.Error {
if _, skType, skProto := s.Type(); !isTCPSocket(skType, skProto) {
log.Warningf("SOL_TCP options are only supported on TCP sockets: skType, skProto = %v, %d", skType, skProto)
if !socket.IsTCP(s) {
return syserr.ErrUnknownProtocolOption
}
@@ -2144,7 +2142,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
return syserr.ErrUnknownProtocolOption
}
family, skType, skProto := s.Type()
family, _, _ := s.Type()
if family != linux.AF_INET6 {
return syserr.ErrUnknownProtocolOption
}
@@ -2164,9 +2162,9 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
return syserr.ErrInvalidArgument
}
if isTCPSocket(skType, skProto) && tcp.EndpointState(ep.State()) != tcp.StateInitial {
if socket.IsTCP(s) && tcp.EndpointState(ep.State()) != tcp.StateInitial {
return syserr.ErrInvalidEndpointState
} else if isUDPSocket(skType, skProto) && transport.DatagramEndpointState(ep.State()) != transport.DatagramEndpointStateInitial {
} else if socket.IsUDP(s) && transport.DatagramEndpointState(ep.State()) != transport.DatagramEndpointStateInitial {
return syserr.ErrInvalidEndpointState
}
@@ -2286,7 +2284,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
}
// Only valid for raw IPv6 sockets.
if skType != linux.SOCK_RAW {
if !socket.IsRaw(s) {
return syserr.ErrProtocolNotAvailable
}
@@ -3319,18 +3317,6 @@ func nicStateFlagsToLinux(f stack.NICStateFlags) uint32 {
return rv
}
func isTCPSocket(skType linux.SockType, skProto int) bool {
return skType == linux.SOCK_STREAM && (skProto == 0 || skProto == unix.IPPROTO_TCP)
}
func isUDPSocket(skType linux.SockType, skProto int) bool {
return skType == linux.SOCK_DGRAM && (skProto == 0 || skProto == unix.IPPROTO_UDP)
}
func isICMPSocket(skType linux.SockType, skProto int) bool {
return skType == linux.SOCK_DGRAM && (skProto == unix.IPPROTO_ICMP || skProto == unix.IPPROTO_ICMPV6)
}
// State implements socket.Socket.State. State translates the internal state
// returned by netstack to values defined by Linux.
func (s *sock) State() uint32 {
@@ -3340,7 +3326,7 @@ func (s *sock) State() uint32 {
}
switch {
case isTCPSocket(s.skType, s.protocol):
case socket.IsTCP(s):
// TCP socket.
switch tcp.EndpointState(s.Endpoint.State()) {
case tcp.StateEstablished:
@@ -3369,7 +3355,7 @@ func (s *sock) State() uint32 {
// Internal or unknown state.
return 0
}
case isUDPSocket(s.skType, s.protocol):
case socket.IsUDP(s):
// UDP socket.
switch transport.DatagramEndpointState(s.Endpoint.State()) {
case transport.DatagramEndpointStateInitial, transport.DatagramEndpointStateBound, transport.DatagramEndpointStateClosed:
@@ -3379,9 +3365,9 @@ func (s *sock) State() uint32 {
default:
return 0
}
case isICMPSocket(s.skType, s.protocol):
case socket.IsICMP(s):
// TODO(b/112063468): Export states for ICMP sockets.
case s.skType == linux.SOCK_RAW:
case socket.IsRaw(s):
// TODO(b/112063468): Export states for raw sockets.
default:
// Unknown transport protocol, how did we make this socket?
+36
View File
@@ -610,3 +610,39 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
return tcpip.FullAddress{}, 0, syserr.ErrAddressFamilyNotSupported
}
}
// IsTCP returns true if the socket is a TCP socket.
func IsTCP(s Socket) bool {
fam, typ, proto := s.Type()
if fam != linux.AF_INET && fam != linux.AF_INET6 {
return false
}
return typ == linux.SOCK_STREAM && (proto == 0 || proto == linux.IPPROTO_TCP)
}
// IsUDP returns true if the socket is a UDP socket.
func IsUDP(s Socket) bool {
fam, typ, proto := s.Type()
if fam != linux.AF_INET && fam != linux.AF_INET6 {
return false
}
return typ == linux.SOCK_DGRAM && (proto == 0 || proto == linux.IPPROTO_UDP)
}
// IsICMP returns true if the socket is an ICMP socket.
func IsICMP(s Socket) bool {
fam, typ, proto := s.Type()
if fam != linux.AF_INET && fam != linux.AF_INET6 {
return false
}
return typ == linux.SOCK_DGRAM && (proto == linux.IPPROTO_ICMP || proto == linux.IPPROTO_ICMPV6)
}
// IsRaw returns true if the socket is a raw socket.
func IsRaw(s Socket) bool {
fam, typ, _ := s.Type()
if fam != linux.AF_INET && fam != linux.AF_INET6 {
return false
}
return typ == linux.SOCK_RAW
}