mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add default TTL test for udp and tcp endpoints
Simplify the retrieval of the default TTL and include multicast flow in the UDP SetTTL tests. Add IPv6 protocol coverage for the TCP TTL tests PiperOrigin-RevId: 417429943
This commit is contained in:
@@ -3403,33 +3403,104 @@ func TestSendGreaterThanMTU(t *testing.T) {
|
||||
testBrokenUpWrite(t, c, maxPayload)
|
||||
}
|
||||
|
||||
func TestSetTTL(t *testing.T) {
|
||||
for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
|
||||
t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
|
||||
func TestDefaultTTL(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
protoNum tcpip.NetworkProtocolNumber
|
||||
addr tcpip.Address
|
||||
}{
|
||||
{"ipv4", ipv4.ProtocolNumber, context.TestAddr},
|
||||
{"ipv6", ipv6.ProtocolNumber, context.TestV6Addr},
|
||||
} {
|
||||
t.Run(fmt.Sprint(test.name), func(t *testing.T) {
|
||||
c := context.New(t, 65535)
|
||||
defer c.Cleanup()
|
||||
|
||||
var err tcpip.Error
|
||||
c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &waiter.Queue{})
|
||||
c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, test.protoNum, &waiter.Queue{})
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %s", err)
|
||||
}
|
||||
|
||||
if err := c.EP.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
|
||||
t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
|
||||
proto := c.Stack().NetworkProtocolInstance(test.protoNum)
|
||||
if proto == nil {
|
||||
t.Fatalf("c.s.NetworkProtocolInstance(flow.netProto()) did not return a protocol")
|
||||
}
|
||||
|
||||
var initialDefaultTTL tcpip.DefaultTTLOption
|
||||
if err := proto.Option(&initialDefaultTTL); err != nil {
|
||||
t.Fatalf("proto.Option(&initialDefaultTTL) (%T) failed: %s", initialDefaultTTL, err)
|
||||
}
|
||||
|
||||
{
|
||||
err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestAddr, Port: context.TestPort})
|
||||
err := c.EP.Connect(tcpip.FullAddress{Addr: test.addr, Port: context.TestPort})
|
||||
if d := cmp.Diff(&tcpip.ErrConnectStarted{}, err); d != "" {
|
||||
t.Fatalf("c.EP.Connect(...) mismatch (-want +got):\n%s", d)
|
||||
}
|
||||
}
|
||||
|
||||
// Receive SYN packet.
|
||||
b := c.GetPacket()
|
||||
checkTTL := func(ttl uint8) {
|
||||
if test.protoNum == ipv4.ProtocolNumber {
|
||||
checker.IPv4(t, c.GetPacket(), checker.TTL(ttl))
|
||||
} else {
|
||||
checker.IPv6(t, c.GetV6Packet(), checker.TTL(ttl))
|
||||
}
|
||||
}
|
||||
|
||||
checker.IPv4(t, b, checker.TTL(wantTTL))
|
||||
// Receive SYN packet.
|
||||
checkTTL(uint8(initialDefaultTTL))
|
||||
|
||||
newDefaultTTL := tcpip.DefaultTTLOption(initialDefaultTTL + 1)
|
||||
if err := proto.SetOption(&newDefaultTTL); err != nil {
|
||||
t.Fatalf("proto.SetOption(&%T(%d))) failed: %s", newDefaultTTL, newDefaultTTL, err)
|
||||
}
|
||||
|
||||
// Receive retransmitted SYN packet.
|
||||
checkTTL(uint8(newDefaultTTL))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetTTL(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
protoNum tcpip.NetworkProtocolNumber
|
||||
addr tcpip.Address
|
||||
}{
|
||||
{"ipv4", ipv4.ProtocolNumber, context.TestAddr},
|
||||
{"ipv6", ipv6.ProtocolNumber, context.TestV6Addr},
|
||||
} {
|
||||
t.Run(fmt.Sprint(test.name), func(t *testing.T) {
|
||||
for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
|
||||
t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
|
||||
c := context.New(t, 65535)
|
||||
defer c.Cleanup()
|
||||
|
||||
var err tcpip.Error
|
||||
c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, test.protoNum, &waiter.Queue{})
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %s", err)
|
||||
}
|
||||
|
||||
if err := c.EP.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
|
||||
t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
|
||||
}
|
||||
|
||||
{
|
||||
err := c.EP.Connect(tcpip.FullAddress{Addr: test.addr, Port: context.TestPort})
|
||||
if d := cmp.Diff(&tcpip.ErrConnectStarted{}, err); d != "" {
|
||||
t.Fatalf("c.EP.Connect(...) mismatch (-want +got):\n%s", d)
|
||||
}
|
||||
}
|
||||
|
||||
// Receive SYN packet.
|
||||
if test.protoNum == ipv4.ProtocolNumber {
|
||||
checker.IPv4(t, c.GetPacket(), checker.TTL(wantTTL))
|
||||
} else {
|
||||
checker.IPv6(t, c.GetV6Packet(), checker.TTL(wantTTL))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +287,13 @@ func (flow testFlow) isReverseMulticast() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (flow testFlow) ttlOption() tcpip.SockOptInt {
|
||||
if flow.isMulticast() {
|
||||
return tcpip.MulticastTTLOption
|
||||
}
|
||||
return tcpip.TTLOption
|
||||
}
|
||||
|
||||
type testContext struct {
|
||||
t *testing.T
|
||||
linkEP *channel.Endpoint
|
||||
@@ -1608,48 +1615,35 @@ func (*testInterface) Enabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestTTL(t *testing.T) {
|
||||
for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6} {
|
||||
func TestNonMulticastDefaultTTL(t *testing.T) {
|
||||
for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6} {
|
||||
t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
|
||||
c := newDualTestContext(t, defaultMTU)
|
||||
defer c.cleanup()
|
||||
|
||||
c.createEndpointForFlow(flow)
|
||||
|
||||
const multicastTTL = 42
|
||||
if err := c.ep.SetSockOptInt(tcpip.MulticastTTLOption, multicastTTL); err != nil {
|
||||
c.t.Fatalf("SetSockOptInt failed: %s", err)
|
||||
proto := c.s.NetworkProtocolInstance(flow.netProto())
|
||||
if proto == nil {
|
||||
t.Fatalf("c.s.NetworkProtocolInstance(flow.netProto()) did not return a protocol")
|
||||
}
|
||||
|
||||
var wantTTL uint8
|
||||
if flow.isMulticast() {
|
||||
wantTTL = multicastTTL
|
||||
} else {
|
||||
var p stack.NetworkProtocolFactory
|
||||
var n tcpip.NetworkProtocolNumber
|
||||
if flow.isV4() {
|
||||
p = ipv4.NewProtocol
|
||||
n = ipv4.ProtocolNumber
|
||||
} else {
|
||||
p = ipv6.NewProtocol
|
||||
n = ipv6.ProtocolNumber
|
||||
}
|
||||
s := stack.New(stack.Options{
|
||||
NetworkProtocols: []stack.NetworkProtocolFactory{p},
|
||||
Clock: &faketime.NullClock{},
|
||||
})
|
||||
ep := s.NetworkProtocolInstance(n).NewEndpoint(&testInterface{}, nil)
|
||||
wantTTL = ep.DefaultTTL()
|
||||
ep.Close()
|
||||
var initialDefaultTTL tcpip.DefaultTTLOption
|
||||
if err := proto.Option(&initialDefaultTTL); err != nil {
|
||||
t.Fatalf("proto.Option(&initialDefaultTTL) (%T) failed: %s", initialDefaultTTL, err)
|
||||
}
|
||||
testWrite(c, flow, checker.TTL(uint8(initialDefaultTTL)))
|
||||
|
||||
testWrite(c, flow, checker.TTL(wantTTL))
|
||||
newDefaultTTL := tcpip.DefaultTTLOption(initialDefaultTTL + 1)
|
||||
if err := proto.SetOption(&newDefaultTTL); err != nil {
|
||||
c.t.Fatalf("proto.SetOption(&%T(%d))) failed: %s", newDefaultTTL, newDefaultTTL, err)
|
||||
}
|
||||
testWrite(c, flow, checker.TTL(uint8(newDefaultTTL)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetTTL(t *testing.T) {
|
||||
for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, broadcast, broadcastIn6} {
|
||||
for _, flow := range []testFlow{unicastV4, unicastV4in6, unicastV6, unicastV6Only, multicastV4, multicastV4in6, multicastV6, broadcast, broadcastIn6} {
|
||||
t.Run(fmt.Sprintf("flow:%s", flow), func(t *testing.T) {
|
||||
for _, wantTTL := range []uint8{1, 2, 50, 64, 128, 254, 255} {
|
||||
t.Run(fmt.Sprintf("TTL:%d", wantTTL), func(t *testing.T) {
|
||||
@@ -1658,8 +1652,9 @@ func TestSetTTL(t *testing.T) {
|
||||
|
||||
c.createEndpointForFlow(flow)
|
||||
|
||||
if err := c.ep.SetSockOptInt(tcpip.TTLOption, int(wantTTL)); err != nil {
|
||||
c.t.Fatalf("SetSockOptInt(TTLOption, %d) failed: %s", wantTTL, err)
|
||||
opt := flow.ttlOption()
|
||||
if err := c.ep.SetSockOptInt(opt, int(wantTTL)); err != nil {
|
||||
c.t.Fatalf("SetSockOptInt(%d, %d) failed: %s", opt, wantTTL, err)
|
||||
}
|
||||
|
||||
testWrite(c, flow, checker.TTL(wantTTL))
|
||||
|
||||
Reference in New Issue
Block a user