mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Change IPv6 reassembly timeout to 60s
It was originally set to 30s for IPv6 (same as IPv4) but this is not what RFC 8200 prescibes. Linux also defaults to 60s [1]. [1] https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/include/net/ipv6.h#L456 PiperOrigin-RevId: 336034636
This commit is contained in:
@@ -29,9 +29,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultReassembleTimeout is based on the linux stack: net.ipv4.ipfrag_time.
|
||||
DefaultReassembleTimeout = 30 * time.Second
|
||||
|
||||
// HighFragThreshold is the threshold at which we start trimming old
|
||||
// fragmented packets. Linux uses a default value of 4 MB. See
|
||||
// net.ipv4.ipfrag_high_thresh for more information.
|
||||
|
||||
@@ -26,6 +26,10 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/testutil"
|
||||
)
|
||||
|
||||
// reassembleTimeout is dummy timeout used for testing, where the clock never
|
||||
// advances.
|
||||
const reassembleTimeout = 1
|
||||
|
||||
// vv is a helper to build VectorisedView from different strings.
|
||||
func vv(size int, pieces ...string) buffer.VectorisedView {
|
||||
views := make([]buffer.View, len(pieces))
|
||||
@@ -98,7 +102,7 @@ var processTestCases = []struct {
|
||||
func TestFragmentationProcess(t *testing.T) {
|
||||
for _, c := range processTestCases {
|
||||
t.Run(c.comment, func(t *testing.T) {
|
||||
f := NewFragmentation(minBlockSize, 1024, 512, DefaultReassembleTimeout, &faketime.NullClock{})
|
||||
f := NewFragmentation(minBlockSize, 1024, 512, reassembleTimeout, &faketime.NullClock{})
|
||||
firstFragmentProto := c.in[0].proto
|
||||
for i, in := range c.in {
|
||||
vv, proto, done, err := f.Process(in.id, in.first, in.last, in.more, in.proto, in.vv)
|
||||
@@ -253,7 +257,7 @@ func TestReassemblingTimeout(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMemoryLimits(t *testing.T) {
|
||||
f := NewFragmentation(minBlockSize, 3, 1, DefaultReassembleTimeout, &faketime.NullClock{})
|
||||
f := NewFragmentation(minBlockSize, 3, 1, reassembleTimeout, &faketime.NullClock{})
|
||||
// Send first fragment with id = 0.
|
||||
f.Process(FragmentID{ID: 0}, 0, 0, true, 0xFF, vv(1, "0"))
|
||||
// Send first fragment with id = 1.
|
||||
@@ -277,7 +281,7 @@ func TestMemoryLimits(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMemoryLimitsIgnoresDuplicates(t *testing.T) {
|
||||
f := NewFragmentation(minBlockSize, 1, 0, DefaultReassembleTimeout, &faketime.NullClock{})
|
||||
f := NewFragmentation(minBlockSize, 1, 0, reassembleTimeout, &faketime.NullClock{})
|
||||
// Send first fragment with id = 0.
|
||||
f.Process(FragmentID{}, 0, 0, true, 0xFF, vv(1, "0"))
|
||||
// Send the same packet again.
|
||||
@@ -372,7 +376,7 @@ func TestErrors(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
f := NewFragmentation(test.blockSize, HighFragThreshold, LowFragThreshold, DefaultReassembleTimeout, &faketime.NullClock{})
|
||||
f := NewFragmentation(test.blockSize, HighFragThreshold, LowFragThreshold, reassembleTimeout, &faketime.NullClock{})
|
||||
_, _, done, err := f.Process(FragmentID{}, test.first, test.last, test.more, 0, vv(len(test.data), test.data))
|
||||
if !errors.Is(err, test.err) {
|
||||
t.Errorf("got Process(_, %d, %d, %t, _, %q) = (_, _, _, %v), want = (_, _, _, %v)", test.first, test.last, test.more, test.data, err, test.err)
|
||||
|
||||
@@ -18,6 +18,7 @@ package ipv4
|
||||
import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -30,6 +31,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// As per RFC 791 section 3.2:
|
||||
// The current recommendation for the initial timer setting is 15 seconds.
|
||||
// This may be changed as experience with this protocol accumulates.
|
||||
//
|
||||
// Considering that it is an old recommendation, we use the same reassembly
|
||||
// timeout that linux defines, which is 30 seconds:
|
||||
// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/include/net/ip.h#L138
|
||||
reassembleTimeout = 30 * time.Second
|
||||
|
||||
// ProtocolNumber is the ipv4 protocol number.
|
||||
ProtocolNumber = header.IPv4ProtocolNumber
|
||||
|
||||
@@ -785,7 +795,7 @@ func NewProtocol(s *stack.Stack) stack.NetworkProtocol {
|
||||
ids: ids,
|
||||
hashIV: hashIV,
|
||||
defaultTTL: DefaultTTL,
|
||||
fragmentation: fragmentation.NewFragmentation(fragmentblockSize, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout, s.Clock()),
|
||||
fragmentation: fragmentation.NewFragmentation(fragmentblockSize, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, reassembleTimeout, s.Clock()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"hash/fnv"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -33,6 +34,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// As per RFC 8200 section 4.5:
|
||||
// If insufficient fragments are received to complete reassembly of a packet
|
||||
// within 60 seconds of the reception of the first-arriving fragment of that
|
||||
// packet, reassembly of that packet must be abandoned.
|
||||
//
|
||||
// Linux also uses 60 seconds for reassembly timeout:
|
||||
// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/include/net/ipv6.h#L456
|
||||
reassembleTimeout = 60 * time.Second
|
||||
|
||||
// ProtocolNumber is the ipv6 protocol number.
|
||||
ProtocolNumber = header.IPv6ProtocolNumber
|
||||
|
||||
@@ -1459,7 +1469,7 @@ func NewProtocolWithOptions(opts Options) stack.NetworkProtocolFactory {
|
||||
return func(s *stack.Stack) stack.NetworkProtocol {
|
||||
p := &protocol{
|
||||
stack: s,
|
||||
fragmentation: fragmentation.NewFragmentation(header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout, s.Clock()),
|
||||
fragmentation: fragmentation.NewFragmentation(header.IPv6FragmentExtHdrFragmentOffsetBytesPerUnit, fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, reassembleTimeout, s.Clock()),
|
||||
ids: ids,
|
||||
hashIV: hashIV,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user