mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Use opaque types to represent time
Introduce tcpip.MonotonicTime; replace int64 in tcpip.Clock method returns with time.Time and MonotonicTime to improve type safety and ensure that monotonic clock readings are never compared to wall clock readings. PiperOrigin-RevId: 375775907
This commit is contained in:
committed by
gVisor bot
parent
b8052176db
commit
4f2439fb0e
@@ -1553,22 +1553,23 @@ func (k *Kernel) SetSaveError(err error) {
|
||||
|
||||
var _ tcpip.Clock = (*Kernel)(nil)
|
||||
|
||||
// NowNanoseconds implements tcpip.Clock.NowNanoseconds.
|
||||
func (k *Kernel) NowNanoseconds() int64 {
|
||||
now, err := k.timekeeper.GetTime(sentrytime.Realtime)
|
||||
// Now implements tcpip.Clock.NowNanoseconds.
|
||||
func (k *Kernel) Now() time.Time {
|
||||
nsec, err := k.timekeeper.GetTime(sentrytime.Realtime)
|
||||
if err != nil {
|
||||
panic("Kernel.NowNanoseconds: " + err.Error())
|
||||
panic("timekeeper.GetTime(sentrytime.Realtime): " + err.Error())
|
||||
}
|
||||
return now
|
||||
return time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// NowMonotonic implements tcpip.Clock.NowMonotonic.
|
||||
func (k *Kernel) NowMonotonic() int64 {
|
||||
now, err := k.timekeeper.GetTime(sentrytime.Monotonic)
|
||||
func (k *Kernel) NowMonotonic() tcpip.MonotonicTime {
|
||||
nsec, err := k.timekeeper.GetTime(sentrytime.Monotonic)
|
||||
if err != nil {
|
||||
panic("Kernel.NowMonotonic: " + err.Error())
|
||||
panic("timekeeper.GetTime(sentrytime.Monotonic): " + err.Error())
|
||||
}
|
||||
return now
|
||||
var mt tcpip.MonotonicTime
|
||||
return mt.Add(time.Duration(nsec) * time.Nanosecond)
|
||||
}
|
||||
|
||||
// AfterFunc implements tcpip.Clock.AfterFunc.
|
||||
|
||||
@@ -29,14 +29,14 @@ type NullClock struct{}
|
||||
|
||||
var _ tcpip.Clock = (*NullClock)(nil)
|
||||
|
||||
// NowNanoseconds implements tcpip.Clock.NowNanoseconds.
|
||||
func (*NullClock) NowNanoseconds() int64 {
|
||||
return 0
|
||||
// Now implements tcpip.Clock.Now.
|
||||
func (*NullClock) Now() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// NowMonotonic implements tcpip.Clock.NowMonotonic.
|
||||
func (*NullClock) NowMonotonic() int64 {
|
||||
return 0
|
||||
func (*NullClock) NowMonotonic() tcpip.MonotonicTime {
|
||||
return tcpip.MonotonicTime{}
|
||||
}
|
||||
|
||||
// AfterFunc implements tcpip.Clock.AfterFunc.
|
||||
@@ -118,16 +118,17 @@ func NewManualClock() *ManualClock {
|
||||
|
||||
var _ tcpip.Clock = (*ManualClock)(nil)
|
||||
|
||||
// NowNanoseconds implements tcpip.Clock.NowNanoseconds.
|
||||
func (mc *ManualClock) NowNanoseconds() int64 {
|
||||
// Now implements tcpip.Clock.Now.
|
||||
func (mc *ManualClock) Now() time.Time {
|
||||
mc.mu.RLock()
|
||||
defer mc.mu.RUnlock()
|
||||
return mc.mu.now.UnixNano()
|
||||
return mc.mu.now
|
||||
}
|
||||
|
||||
// NowMonotonic implements tcpip.Clock.NowMonotonic.
|
||||
func (mc *ManualClock) NowMonotonic() int64 {
|
||||
return mc.NowNanoseconds()
|
||||
func (mc *ManualClock) NowMonotonic() tcpip.MonotonicTime {
|
||||
var mt tcpip.MonotonicTime
|
||||
return mt.Add(mc.Now().Sub(time.Unix(0, 0)))
|
||||
}
|
||||
|
||||
// AfterFunc implements tcpip.Clock.AfterFunc.
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestManualClockAdvance(t *testing.T) {
|
||||
clock := faketime.NewManualClock()
|
||||
start := clock.NowMonotonic()
|
||||
clock.Advance(timeout)
|
||||
if got, want := time.Duration(clock.NowMonotonic()-start)*time.Nanosecond, timeout; got != want {
|
||||
if got, want := clock.NowMonotonic().Sub(start), timeout; got != want {
|
||||
t.Errorf("got = %d, want = %d", got, want)
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func TestManualClockAfterFunc(t *testing.T) {
|
||||
if got, want := counter2, test.wantCounter2; got != want {
|
||||
t.Errorf("got counter2 = %d, want = %d", got, want)
|
||||
}
|
||||
if got, want := time.Duration(clock.NowMonotonic()-start)*time.Nanosecond, test.advance; got != want {
|
||||
if got, want := clock.NowMonotonic().Sub(start), test.advance; got != want {
|
||||
t.Errorf("got elapsed = %d, want = %d", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -17,6 +17,7 @@ package header
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
)
|
||||
@@ -813,9 +814,12 @@ const (
|
||||
|
||||
// ipv4TimestampTime provides the current time as specified in RFC 791.
|
||||
func ipv4TimestampTime(clock tcpip.Clock) uint32 {
|
||||
const millisecondsPerDay = 24 * 3600 * 1000
|
||||
const nanoPerMilli = 1000000
|
||||
return uint32((clock.NowNanoseconds() / nanoPerMilli) % millisecondsPerDay)
|
||||
// Per RFC 791 page 21:
|
||||
// The Timestamp is a right-justified, 32-bit timestamp in
|
||||
// milliseconds since midnight UT.
|
||||
now := clock.Now().UTC()
|
||||
midnight := now.Truncate(24 * time.Hour)
|
||||
return uint32(now.Sub(midnight).Milliseconds())
|
||||
}
|
||||
|
||||
// IP Timestamp option fields.
|
||||
|
||||
@@ -126,7 +126,7 @@ func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.Neighbo
|
||||
func (d *arpDispatcher) waitForEvent(ctx context.Context, want eventInfo) error {
|
||||
select {
|
||||
case got := <-d.C:
|
||||
if diff := cmp.Diff(want, got, cmp.AllowUnexported(got), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAtNanos")); diff != "" {
|
||||
if diff := cmp.Diff(want, got, cmp.AllowUnexported(got), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAt")); diff != "" {
|
||||
return fmt.Errorf("got invalid event (-want +got):\n%s", diff)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
|
||||
@@ -251,7 +251,7 @@ func (f *Fragmentation) releaseReassemblersLocked() {
|
||||
// The list is empty.
|
||||
break
|
||||
}
|
||||
elapsed := time.Duration(now-r.creationTime) * time.Nanosecond
|
||||
elapsed := now.Sub(r.createdAt)
|
||||
if f.timeout > elapsed {
|
||||
// If the oldest reassembler has not expired, schedule the release
|
||||
// job so that this function is called back when it has expired.
|
||||
|
||||
@@ -35,21 +35,21 @@ type hole struct {
|
||||
|
||||
type reassembler struct {
|
||||
reassemblerEntry
|
||||
id FragmentID
|
||||
memSize int
|
||||
proto uint8
|
||||
mu sync.Mutex
|
||||
holes []hole
|
||||
filled int
|
||||
done bool
|
||||
creationTime int64
|
||||
pkt *stack.PacketBuffer
|
||||
id FragmentID
|
||||
memSize int
|
||||
proto uint8
|
||||
mu sync.Mutex
|
||||
holes []hole
|
||||
filled int
|
||||
done bool
|
||||
createdAt tcpip.MonotonicTime
|
||||
pkt *stack.PacketBuffer
|
||||
}
|
||||
|
||||
func newReassembler(id FragmentID, clock tcpip.Clock) *reassembler {
|
||||
r := &reassembler{
|
||||
id: id,
|
||||
creationTime: clock.NowMonotonic(),
|
||||
id: id,
|
||||
createdAt: clock.NowMonotonic(),
|
||||
}
|
||||
r.holes = append(r.holes, hole{
|
||||
first: 0,
|
||||
|
||||
@@ -611,7 +611,7 @@ func (g *GenericMulticastProtocolState) setDelayTimerForAddressRLocked(groupAddr
|
||||
// If a timer for any address is already running, it is reset to the new
|
||||
// random value only if the requested Maximum Response Delay is less than
|
||||
// the remaining value of the running timer.
|
||||
now := time.Unix(0 /* seconds */, g.opts.Clock.NowNanoseconds())
|
||||
now := g.opts.Clock.Now()
|
||||
if info.state == delayingMember {
|
||||
if info.delayedReportJobFiresAt.IsZero() {
|
||||
panic(fmt.Sprintf("delayed report unscheduled while in the delaying member state; group = %s", groupAddress))
|
||||
|
||||
@@ -293,10 +293,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: removedEntry.Addr,
|
||||
LinkAddr: removedEntry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: removedEntry.Addr,
|
||||
LinkAddr: removedEntry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -305,10 +305,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -339,10 +339,10 @@ func addReachableEntryWithRemoved(nudDisp *testNUDDispatcher, clock *faketime.Ma
|
||||
EventType: entryTestChanged,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -411,10 +411,10 @@ func TestNeighborCacheRemoveEntry(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -492,12 +492,12 @@ func (c *testContext) overflowCache(opts overflowOptions) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("got c.linkRes.entries.entry(%d) = _, false, want = true", i)
|
||||
}
|
||||
durationReachableNanos := int64(c.linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
|
||||
durationReachableNanos := time.Duration(c.linkRes.entries.size()-i-1) * typicalLatency
|
||||
wantEntry := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds() - durationReachableNanos,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: c.clock.Now().Add(-durationReachableNanos),
|
||||
}
|
||||
wantUnorderedEntries = append(wantUnorderedEntries, wantEntry)
|
||||
}
|
||||
@@ -563,10 +563,10 @@ func TestNeighborCacheRemoveEntryThenOverflow(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -608,10 +608,10 @@ func TestNeighborCacheDuplicateStaticEntryWithSameLinkAddress(t *testing.T) {
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -655,10 +655,10 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -681,10 +681,10 @@ func TestNeighborCacheDuplicateStaticEntryWithDifferentLinkAddress(t *testing.T)
|
||||
EventType: entryTestChanged,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -725,10 +725,10 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -750,10 +750,10 @@ func TestNeighborCacheRemoveStaticEntryThenOverflow(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -806,20 +806,20 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
{
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -836,10 +836,10 @@ func TestNeighborCacheOverwriteWithStaticEntryThenOverflow(t *testing.T) {
|
||||
startAtEntryIndex: 1,
|
||||
wantStaticEntries: []NeighborEntry{
|
||||
{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: staticLinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -867,10 +867,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
|
||||
t.Errorf("unexpected error from c.linkRes.neigh.entry(%s, \"\", nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
}
|
||||
if diff := cmp.Diff(want, e); diff != "" {
|
||||
t.Errorf("c.linkRes.neigh.entry(%s, \"\", nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
|
||||
@@ -882,10 +882,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -902,10 +902,10 @@ func TestNeighborCacheAddStaticEntryThenOverflow(t *testing.T) {
|
||||
startAtEntryIndex: 1,
|
||||
wantStaticEntries: []NeighborEntry{
|
||||
{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -939,10 +939,10 @@ func TestNeighborCacheClear(t *testing.T) {
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Static,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Static,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -965,20 +965,20 @@ func TestNeighborCacheClear(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
{
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Static,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Static,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1019,10 +1019,10 @@ func TestNeighborCacheClearThenOverflow(t *testing.T) {
|
||||
EventType: entryTestRemoved,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: c.clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: c.clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1054,7 +1054,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
clock := faketime.NewManualClock()
|
||||
linkRes := newTestNeighborResolver(&nudDisp, config, clock)
|
||||
|
||||
startedAt := clock.NowNanoseconds()
|
||||
startedAt := clock.Now()
|
||||
|
||||
// The following logic is very similar to overflowCache, but
|
||||
// periodically refreshes the frequently used entry.
|
||||
@@ -1110,7 +1110,7 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
State: Reachable,
|
||||
// Can be inferred since the frequently used entry is the first to
|
||||
// be created and transitioned to Reachable.
|
||||
UpdatedAtNanos: startedAt + typicalLatency.Nanoseconds(),
|
||||
UpdatedAt: startedAt.Add(typicalLatency),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1119,12 +1119,12 @@ func TestNeighborCacheKeepFrequentlyUsed(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("got linkRes.entries.entry(%d) = _, false, want = true", i)
|
||||
}
|
||||
durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
|
||||
durationReachableNanos := time.Duration(linkRes.entries.size()-i-1) * typicalLatency
|
||||
wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now().Add(-durationReachableNanos),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1182,12 +1182,12 @@ func TestNeighborCacheConcurrent(t *testing.T) {
|
||||
if !ok {
|
||||
t.Errorf("got linkRes.entries.entry(%d) = _, false, want = true", i)
|
||||
}
|
||||
durationReachableNanos := int64(linkRes.entries.size()-i-1) * typicalLatency.Nanoseconds()
|
||||
durationReachableNanos := time.Duration(linkRes.entries.size()-i-1) * typicalLatency
|
||||
wantUnsortedEntries = append(wantUnsortedEntries, NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds() - durationReachableNanos,
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now().Add(-durationReachableNanos),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1236,10 +1236,10 @@ func TestNeighborCacheReplace(t *testing.T) {
|
||||
t.Fatalf("linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Delay,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Delay,
|
||||
UpdatedAt: clock.Now(),
|
||||
}
|
||||
if diff := cmp.Diff(want, e); diff != "" {
|
||||
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
|
||||
@@ -1255,10 +1255,10 @@ func TestNeighborCacheReplace(t *testing.T) {
|
||||
t.Errorf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: updatedLinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
}
|
||||
if diff := cmp.Diff(want, e); diff != "" {
|
||||
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
|
||||
@@ -1293,10 +1293,10 @@ func TestNeighborCacheResolutionFailed(t *testing.T) {
|
||||
t.Fatalf("unexpected error from linkRes.neigh.entry(%s, '', nil): %s", entry.Addr, err)
|
||||
}
|
||||
want := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("linkRes.neigh.entry(%s, '', nil) mismatch (-want, +got):\n%s", entry.Addr, diff)
|
||||
@@ -1397,10 +1397,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
EventType: entryTestAdded,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1428,10 +1428,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Unreachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Unreachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1447,10 +1447,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
{
|
||||
wantEntries := []NeighborEntry{
|
||||
{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Unreachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Unreachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
}
|
||||
if diff := cmp.Diff(linkRes.neigh.entries(), wantEntries, unorderedEntriesDiffOpts()...); diff != "" {
|
||||
@@ -1480,10 +1480,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: "",
|
||||
State: Incomplete,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1510,10 +1510,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: 1,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1533,10 +1533,10 @@ func TestNeighborCacheRetryResolution(t *testing.T) {
|
||||
}
|
||||
|
||||
wantEntry := NeighborEntry{
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entry.Addr,
|
||||
LinkAddr: entry.LinkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
}
|
||||
if diff := cmp.Diff(gotEntry, wantEntry); diff != "" {
|
||||
t.Fatalf("neighbor entry mismatch (-got, +want):\n%s", diff)
|
||||
|
||||
@@ -31,10 +31,10 @@ const (
|
||||
|
||||
// NeighborEntry describes a neighboring device in the local network.
|
||||
type NeighborEntry struct {
|
||||
Addr tcpip.Address
|
||||
LinkAddr tcpip.LinkAddress
|
||||
State NeighborState
|
||||
UpdatedAtNanos int64
|
||||
Addr tcpip.Address
|
||||
LinkAddr tcpip.LinkAddress
|
||||
State NeighborState
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// NeighborState defines the state of a NeighborEntry within the Neighbor
|
||||
@@ -138,10 +138,10 @@ func newNeighborEntry(cache *neighborCache, remoteAddr tcpip.Address, nudState *
|
||||
// calling `setStateLocked`.
|
||||
func newStaticNeighborEntry(cache *neighborCache, addr tcpip.Address, linkAddr tcpip.LinkAddress, state *NUDState) *neighborEntry {
|
||||
entry := NeighborEntry{
|
||||
Addr: addr,
|
||||
LinkAddr: linkAddr,
|
||||
State: Static,
|
||||
UpdatedAtNanos: cache.nic.stack.clock.NowNanoseconds(),
|
||||
Addr: addr,
|
||||
LinkAddr: linkAddr,
|
||||
State: Static,
|
||||
UpdatedAt: cache.nic.stack.clock.Now(),
|
||||
}
|
||||
n := &neighborEntry{
|
||||
cache: cache,
|
||||
@@ -224,7 +224,7 @@ func (e *neighborEntry) cancelTimerLocked() {
|
||||
//
|
||||
// Precondition: e.mu MUST be locked.
|
||||
func (e *neighborEntry) removeLocked() {
|
||||
e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
|
||||
e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
|
||||
e.dispatchRemoveEventLocked()
|
||||
e.cancelTimerLocked()
|
||||
// TODO(https://gvisor.dev/issues/5583): test the case where this function is
|
||||
@@ -246,7 +246,7 @@ func (e *neighborEntry) setStateLocked(next NeighborState) {
|
||||
|
||||
prev := e.mu.neigh.State
|
||||
e.mu.neigh.State = next
|
||||
e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
|
||||
e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
|
||||
config := e.nudState.Config()
|
||||
|
||||
switch next {
|
||||
@@ -354,7 +354,7 @@ func (e *neighborEntry) handlePacketQueuedLocked(localAddr tcpip.Address) {
|
||||
case Unknown, Unreachable:
|
||||
prev := e.mu.neigh.State
|
||||
e.mu.neigh.State = Incomplete
|
||||
e.mu.neigh.UpdatedAtNanos = e.cache.nic.stack.clock.NowNanoseconds()
|
||||
e.mu.neigh.UpdatedAt = e.cache.nic.stack.clock.Now()
|
||||
|
||||
switch prev {
|
||||
case Unknown:
|
||||
|
||||
@@ -349,10 +349,10 @@ func unknownToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *
|
||||
EventType: entryTestAdded,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Incomplete,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Incomplete,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -410,10 +410,10 @@ func unknownToStale(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entry
|
||||
EventType: entryTestAdded,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -441,7 +441,7 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
|
||||
|
||||
// UpdatedAt should remain the same during address resolution.
|
||||
e.mu.Lock()
|
||||
startedAt := e.mu.neigh.UpdatedAtNanos
|
||||
startedAt := e.mu.neigh.UpdatedAt
|
||||
e.mu.Unlock()
|
||||
|
||||
// Wait for the rest of the reachability probe transmissions, signifying
|
||||
@@ -465,7 +465,7 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
if got, want := e.mu.neigh.UpdatedAtNanos, startedAt; got != want {
|
||||
if got, want := e.mu.neigh.UpdatedAt, startedAt; got != want {
|
||||
t.Errorf("got e.mu.neigh.UpdatedAt = %q, want = %q", got, want)
|
||||
}
|
||||
e.mu.Unlock()
|
||||
@@ -480,10 +480,10 @@ func TestEntryIncompleteToIncompleteDoesNotChangeUpdatedAt(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Unreachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Unreachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -542,10 +542,10 @@ func incompleteToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -639,10 +639,10 @@ func TestEntryIncompleteToStaleWhenUnsolicitedConfirmation(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -673,10 +673,10 @@ func TestEntryIncompleteToStaleWhenProbe(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -752,10 +752,10 @@ func incompleteToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *tes
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Unreachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Unreachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -938,10 +938,10 @@ func reachableToStale(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDis
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -993,10 +993,10 @@ func TestEntryReachableToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1045,10 +1045,10 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddress(t *testing.T)
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1097,10 +1097,10 @@ func TestEntryReachableToStaleWhenConfirmationWithDifferentAddressAndOverride(t
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1186,10 +1186,10 @@ func TestEntryStaleToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1238,10 +1238,10 @@ func TestEntryStaleToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1279,10 +1279,10 @@ func TestEntryStaleToStaleWhenOverrideConfirmation(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1327,10 +1327,10 @@ func TestEntryStaleToStaleWhenProbeUpdateAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1386,10 +1386,10 @@ func staleToDelay(e *neighborEntry, nudDisp *testNUDDispatcher, linkRes *entryTe
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Delay,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Delay,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1438,10 +1438,10 @@ func TestEntryDelayToReachableWhenUpperLevelConfirmation(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1493,10 +1493,10 @@ func TestEntryDelayToReachableWhenSolicitedOverrideConfirmation(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1548,10 +1548,10 @@ func TestEntryDelayToReachableWhenSolicitedConfirmationWithoutAddress(t *testing
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1640,10 +1640,10 @@ func TestEntryDelayToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1692,10 +1692,10 @@ func TestEntryDelayToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1765,10 +1765,10 @@ func delayToProbe(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDDispatc
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Probe,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Probe,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1822,10 +1822,10 @@ func TestEntryProbeToStaleWhenProbeWithDifferentAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1877,10 +1877,10 @@ func TestEntryProbeToStaleWhenConfirmationWithDifferentAddress(t *testing.T) {
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr2,
|
||||
State: Stale,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1998,10 +1998,10 @@ func probeToReachableWithFlags(e *neighborEntry, nudDisp *testNUDDispatcher, lin
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: linkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: linkAddr,
|
||||
State: Reachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -2150,10 +2150,10 @@ func probeToUnreachable(c NUDConfigurations, e *neighborEntry, nudDisp *testNUDD
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Unreachable,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: entryTestLinkAddr1,
|
||||
State: Unreachable,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -2222,10 +2222,10 @@ func unreachableToIncomplete(e *neighborEntry, nudDisp *testNUDDispatcher, linkR
|
||||
EventType: entryTestChanged,
|
||||
NICID: entryTestNICID,
|
||||
Entry: NeighborEntry{
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Incomplete,
|
||||
UpdatedAtNanos: clock.NowNanoseconds(),
|
||||
Addr: entryTestAddr1,
|
||||
LinkAddr: tcpip.LinkAddress(""),
|
||||
State: Incomplete,
|
||||
UpdatedAt: clock.Now(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func TestNUDFunctions(t *testing.T) {
|
||||
t.Errorf("s.Neigbors(%d, %d) error mismatch (-want +got):\n%s", test.nicID, ipv6.ProtocolNumber, diff)
|
||||
} else if test.expectedErr == nil {
|
||||
if diff := cmp.Diff(
|
||||
[]stack.NeighborEntry{{Addr: llAddr2, LinkAddr: linkAddr1, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
|
||||
[]stack.NeighborEntry{{Addr: llAddr2, LinkAddr: linkAddr1, State: stack.Static, UpdatedAt: clock.Now()}},
|
||||
neighbors,
|
||||
); diff != "" {
|
||||
t.Errorf("neighbors mismatch (-want +got):\n%s", diff)
|
||||
|
||||
@@ -4427,7 +4427,7 @@ func TestClearNeighborCacheOnNICDisable(t *testing.T) {
|
||||
if neighbors, err := s.Neighbors(nicID, addr.proto); err != nil {
|
||||
t.Fatalf("s.Neighbors(%d, %d): %s", nicID, addr.proto, err)
|
||||
} else if diff := cmp.Diff(
|
||||
[]stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAtNanos: clock.NowNanoseconds()}},
|
||||
[]stack.NeighborEntry{{Addr: addr.addr, LinkAddr: linkAddr, State: stack.Static, UpdatedAt: clock.Now()}},
|
||||
neighbors,
|
||||
); diff != "" {
|
||||
t.Fatalf("proto=%d neighbors mismatch (-want +got):\n%s", addr.proto, diff)
|
||||
|
||||
@@ -60,11 +60,11 @@ type stdClock struct {
|
||||
// monotonicOffset is assigned maxMonotonic after restore so that the
|
||||
// monotonic time will continue from where it "left off" before saving as part
|
||||
// of S/R.
|
||||
monotonicOffset int64 `state:"nosave"`
|
||||
monotonicOffset MonotonicTime `state:"nosave"`
|
||||
|
||||
// monotonicMU protects maxMonotonic.
|
||||
monotonicMU sync.Mutex `state:"nosave"`
|
||||
maxMonotonic int64
|
||||
maxMonotonic MonotonicTime
|
||||
}
|
||||
|
||||
// NewStdClock returns an instance of a clock that uses the time package.
|
||||
@@ -76,25 +76,25 @@ func NewStdClock() Clock {
|
||||
|
||||
var _ Clock = (*stdClock)(nil)
|
||||
|
||||
// NowNanoseconds implements Clock.NowNanoseconds.
|
||||
func (*stdClock) NowNanoseconds() int64 {
|
||||
return time.Now().UnixNano()
|
||||
// Now implements Clock.Now.
|
||||
func (*stdClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// NowMonotonic implements Clock.NowMonotonic.
|
||||
func (s *stdClock) NowMonotonic() int64 {
|
||||
func (s *stdClock) NowMonotonic() MonotonicTime {
|
||||
sinceBase := time.Since(s.baseTime)
|
||||
if sinceBase < 0 {
|
||||
panic(fmt.Sprintf("got negative duration = %s since base time = %s", sinceBase, s.baseTime))
|
||||
}
|
||||
|
||||
monotonicValue := sinceBase.Nanoseconds() + s.monotonicOffset
|
||||
monotonicValue := s.monotonicOffset.Add(sinceBase)
|
||||
|
||||
s.monotonicMU.Lock()
|
||||
defer s.monotonicMU.Unlock()
|
||||
|
||||
// Monotonic time values must never decrease.
|
||||
if monotonicValue > s.maxMonotonic {
|
||||
if s.maxMonotonic.Before(monotonicValue) {
|
||||
s.maxMonotonic = monotonicValue
|
||||
}
|
||||
|
||||
|
||||
+30
-5
@@ -64,17 +64,42 @@ func (e *ErrSaveRejection) Error() string {
|
||||
return "save rejected due to unsupported networking state: " + e.Err.Error()
|
||||
}
|
||||
|
||||
// MonotonicTime is a monotonic clock reading.
|
||||
//
|
||||
// +stateify savable
|
||||
type MonotonicTime struct {
|
||||
nanoseconds int64
|
||||
}
|
||||
|
||||
// Before reports whether the monotonic clock reading mt is before u.
|
||||
func (mt MonotonicTime) Before(u MonotonicTime) bool {
|
||||
return mt.nanoseconds < u.nanoseconds
|
||||
}
|
||||
|
||||
// Add returns the monotonic clock reading mt+d.
|
||||
func (mt MonotonicTime) Add(d time.Duration) MonotonicTime {
|
||||
return MonotonicTime{
|
||||
nanoseconds: time.Unix(0, mt.nanoseconds).Add(d).Sub(time.Unix(0, 0)).Nanoseconds(),
|
||||
}
|
||||
}
|
||||
|
||||
// Sub returns the duration mt-u. If the result exceeds the maximum (or minimum)
|
||||
// value that can be stored in a Duration, the maximum (or minimum) duration
|
||||
// will be returned. To compute t-d for a duration d, use t.Add(-d).
|
||||
func (mt MonotonicTime) Sub(u MonotonicTime) time.Duration {
|
||||
return time.Unix(0, mt.nanoseconds).Sub(time.Unix(0, u.nanoseconds))
|
||||
}
|
||||
|
||||
// A Clock provides the current time and schedules work for execution.
|
||||
//
|
||||
// Times returned by a Clock should always be used for application-visible
|
||||
// time. Only monotonic times should be used for netstack internal timekeeping.
|
||||
type Clock interface {
|
||||
// NowNanoseconds returns the current real time as a number of
|
||||
// nanoseconds since the Unix epoch.
|
||||
NowNanoseconds() int64
|
||||
// Now returns the current local time.
|
||||
Now() time.Time
|
||||
|
||||
// NowMonotonic returns a monotonic time value at nanosecond resolution.
|
||||
NowMonotonic() int64
|
||||
// NowMonotonic returns the current monotonic clock reading.
|
||||
NowMonotonic() MonotonicTime
|
||||
|
||||
// AfterFunc waits for the duration to elapse and then calls f in its own
|
||||
// goroutine. It returns a Timer that can be used to cancel the call using
|
||||
|
||||
@@ -1034,7 +1034,7 @@ func (d *nudDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.Neighbo
|
||||
}
|
||||
|
||||
func (d *nudDispatcher) waitForEvent(want eventInfo) error {
|
||||
if diff := cmp.Diff(want, <-d.c, cmp.AllowUnexported(eventInfo{}), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAtNanos")); diff != "" {
|
||||
if diff := cmp.Diff(want, <-d.c, cmp.AllowUnexported(eventInfo{}), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAt")); diff != "" {
|
||||
return fmt.Errorf("got invalid event (-want +got):\n%s", diff)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package tcpip_test
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -22,6 +23,67 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
)
|
||||
|
||||
func TestMonotonicTimeBefore(t *testing.T) {
|
||||
var mt tcpip.MonotonicTime
|
||||
if mt.Before(mt) {
|
||||
t.Errorf("%#v.Before(%#v)", mt, mt)
|
||||
}
|
||||
|
||||
one := mt.Add(1)
|
||||
if one.Before(mt) {
|
||||
t.Errorf("%#v.Before(%#v)", one, mt)
|
||||
}
|
||||
if !mt.Before(one) {
|
||||
t.Errorf("!%#v.Before(%#v)", mt, one)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonotonicTimeAddSub(t *testing.T) {
|
||||
var mt tcpip.MonotonicTime
|
||||
if one, two := mt.Add(2), mt.Add(1).Add(1); one != two {
|
||||
t.Errorf("mt.Add(2) != mt.Add(1).Add(1) (%#v != %#v)", one, two)
|
||||
}
|
||||
|
||||
min := mt.Add(math.MinInt64)
|
||||
max := mt.Add(math.MaxInt64)
|
||||
|
||||
if overflow := mt.Add(1).Add(math.MaxInt64); overflow != max {
|
||||
t.Errorf("mt.Add(math.MaxInt64) != mt.Add(1).Add(math.MaxInt64) (%#v != %#v)", max, overflow)
|
||||
}
|
||||
if underflow := mt.Add(-1).Add(math.MinInt64); underflow != min {
|
||||
t.Errorf("mt.Add(math.MinInt64) != mt.Add(-1).Add(math.MinInt64) (%#v != %#v)", min, underflow)
|
||||
}
|
||||
|
||||
if got, want := min.Sub(min), time.Duration(0); want != got {
|
||||
t.Errorf("got min.Sub(min) = %d, want %d", got, want)
|
||||
}
|
||||
if got, want := max.Sub(max), time.Duration(0); want != got {
|
||||
t.Errorf("got max.Sub(max) = %d, want %d", got, want)
|
||||
}
|
||||
|
||||
if overflow, want := max.Sub(min), time.Duration(math.MaxInt64); overflow != want {
|
||||
t.Errorf("mt.Add(math.MaxInt64).Sub(mt.Add(math.MinInt64) != %s (%#v)", want, overflow)
|
||||
}
|
||||
if underflow, want := min.Sub(max), time.Duration(math.MinInt64); underflow != want {
|
||||
t.Errorf("mt.Add(math.MinInt64).Sub(mt.Add(math.MaxInt64) != %s (%#v)", want, underflow)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonotonicTimeSub(t *testing.T) {
|
||||
var mt tcpip.MonotonicTime
|
||||
|
||||
if one, two := mt.Add(2), mt.Add(1).Add(1); one != two {
|
||||
t.Errorf("mt.Add(2) != mt.Add(1).Add(1) (%#v != %#v)", one, two)
|
||||
}
|
||||
|
||||
if max, overflow := mt.Add(math.MaxInt64), mt.Add(1).Add(math.MaxInt64); max != overflow {
|
||||
t.Errorf("mt.Add(math.MaxInt64) != mt.Add(1).Add(math.MaxInt64) (%#v != %#v)", max, overflow)
|
||||
}
|
||||
if max, underflow := mt.Add(math.MinInt64), mt.Add(-1).Add(math.MinInt64); max != underflow {
|
||||
t.Errorf("mt.Add(math.MinInt64) != mt.Add(-1).Add(math.MinInt64) (%#v != %#v)", max, underflow)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
shortDuration = 1 * time.Nanosecond
|
||||
middleDuration = 100 * time.Millisecond
|
||||
|
||||
@@ -16,6 +16,7 @@ package icmp
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -33,7 +34,7 @@ type icmpPacket struct {
|
||||
icmpPacketEntry
|
||||
senderAddress tcpip.FullAddress
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
timestamp int64
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
}
|
||||
|
||||
type endpointState int
|
||||
@@ -193,7 +194,7 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
|
||||
Total: p.data.Size(),
|
||||
ControlMessages: tcpip.ControlMessages{
|
||||
HasTimestamp: true,
|
||||
Timestamp: p.timestamp,
|
||||
Timestamp: p.receivedAt.UnixNano(),
|
||||
},
|
||||
}
|
||||
if opts.NeedRemoteAddr {
|
||||
@@ -800,7 +801,7 @@ func (e *endpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketB
|
||||
e.rcvList.PushBack(packet)
|
||||
e.rcvBufSize += packet.data.Size()
|
||||
|
||||
packet.timestamp = e.stack.Clock().NowNanoseconds()
|
||||
packet.receivedAt = e.stack.Clock().Now()
|
||||
|
||||
e.rcvMu.Unlock()
|
||||
e.stats.PacketsReceived.Increment()
|
||||
|
||||
@@ -15,11 +15,23 @@
|
||||
package icmp
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
// saveReceivedAt is invoked by stateify.
|
||||
func (p *icmpPacket) saveReceivedAt() int64 {
|
||||
return p.receivedAt.UnixNano()
|
||||
}
|
||||
|
||||
// loadReceivedAt is invoked by stateify.
|
||||
func (p *icmpPacket) loadReceivedAt(nsec int64) {
|
||||
p.receivedAt = time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// saveData saves icmpPacket.data field.
|
||||
func (p *icmpPacket) saveData() buffer.VectorisedView {
|
||||
// We cannot save p.data directly as p.data.views may alias to p.views,
|
||||
|
||||
@@ -27,6 +27,7 @@ package packet
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
@@ -41,9 +42,8 @@ type packet struct {
|
||||
packetEntry
|
||||
// data holds the actual packet data, including any headers and
|
||||
// payload.
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
// timestampNS is the unix time at which the packet was received.
|
||||
timestampNS int64
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
// senderAddr is the network address of the sender.
|
||||
senderAddr tcpip.FullAddress
|
||||
// packetInfo holds additional information like the protocol
|
||||
@@ -189,7 +189,7 @@ func (ep *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResul
|
||||
Total: packet.data.Size(),
|
||||
ControlMessages: tcpip.ControlMessages{
|
||||
HasTimestamp: true,
|
||||
Timestamp: packet.timestampNS,
|
||||
Timestamp: packet.receivedAt.UnixNano(),
|
||||
},
|
||||
}
|
||||
if opts.NeedRemoteAddr {
|
||||
@@ -451,7 +451,7 @@ func (ep *endpoint) HandlePacket(nicID tcpip.NICID, localAddr tcpip.LinkAddress,
|
||||
packet.data = buffer.NewVectorisedView(pkt.Size(), pkt.Views())
|
||||
}
|
||||
}
|
||||
packet.timestampNS = ep.stack.Clock().NowNanoseconds()
|
||||
packet.receivedAt = ep.stack.Clock().Now()
|
||||
|
||||
ep.rcvList.PushBack(&packet)
|
||||
ep.rcvBufSize += packet.data.Size()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user