]> git.feebdaed.xyz Git - 0xmirror/quic-go.git/commitdiff
implement a memory-optimized time.Time replacement (#5334)
authorMarten Seemann <martenseemann@gmail.com>
Sun, 14 Sep 2025 06:12:10 +0000 (14:12 +0800)
committerGitHub <noreply@github.com>
Sun, 14 Sep 2025 06:12:10 +0000 (08:12 +0200)
* implement a memory-optimized time.Time replacement

* monotime: properly handle systems with bad timer resolution (Windows)

* monotime: simplify Since

75 files changed:
conn_id_generator.go
conn_id_generator_test.go
connection.go
connection_test.go
connection_timer.go
connection_timer_test.go
framer.go
framer_test.go
fuzzing/handshake/fuzz.go
integrationtests/tools/proxy/proxy.go
integrationtests/tools/proxy/proxy_test.go
internal/ackhandler/interfaces.go
internal/ackhandler/mock_sent_packet_tracker_test.go
internal/ackhandler/packet.go
internal/ackhandler/received_packet_handler.go
internal/ackhandler/received_packet_handler_test.go
internal/ackhandler/received_packet_tracker.go
internal/ackhandler/received_packet_tracker_test.go
internal/ackhandler/sent_packet_handler.go
internal/ackhandler/sent_packet_handler_test.go
internal/ackhandler/sent_packet_history_test.go
internal/congestion/clock.go
internal/congestion/cubic.go
internal/congestion/cubic_sender.go
internal/congestion/cubic_sender_test.go
internal/congestion/cubic_test.go
internal/congestion/interface.go
internal/congestion/pacer.go
internal/congestion/pacer_test.go
internal/flowcontrol/base_flow_controller.go
internal/flowcontrol/connection_flow_controller.go
internal/flowcontrol/connection_flow_controller_test.go
internal/flowcontrol/interface.go
internal/flowcontrol/stream_flow_controller.go
internal/flowcontrol/stream_flow_controller_test.go
internal/handshake/interface.go
internal/handshake/updatable_aead.go
internal/handshake/updatable_aead_test.go
internal/mocks/ackhandler/received_packet_handler.go
internal/mocks/ackhandler/sent_packet_handler.go
internal/mocks/congestion.go
internal/mocks/short_header_opener.go
internal/mocks/stream_flow_controller.go
internal/monotime/time.go [new file with mode: 0644]
internal/monotime/time_test.go [new file with mode: 0644]
internal/utils/timer.go
internal/utils/timer_test.go
mock_ack_frame_source_test.go
mock_frame_source_test.go
mock_mtu_discoverer_test.go
mock_packer_test.go
mock_stream_control_frame_getter_test.go
mock_unpacker_test.go
mtu_discoverer.go
mtu_discoverer_test.go
packet_packer.go
packet_packer_test.go
packet_unpacker.go
packet_unpacker_test.go
path_manager.go
path_manager_test.go
receive_stream.go
receive_stream_test.go
send_stream.go
send_stream_test.go
server.go
server_test.go
stream.go
stream_test.go
streams_map.go
streams_map_test.go
sys_conn.go
sys_conn_oob.go
sys_conn_oob_test.go
sys_conn_test.go

index f1a0c92c06ab220fa5e3b0999a214b571381b560..c2b354505263f490fe2fad223bba19d97220f811 100644 (file)
@@ -5,6 +5,7 @@ import (
        "slices"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -38,7 +39,7 @@ func (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte, e
 }
 
 type connIDToRetire struct {
-       t      time.Time
+       t      monotime.Time
        connID protocol.ConnectionID
 }
 
@@ -95,7 +96,7 @@ func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error {
        return nil
 }
 
-func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.ConnectionID, expiry time.Time) error {
+func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.ConnectionID, expiry monotime.Time) error {
        if seq > m.highestSeq {
                return &qerr.TransportError{
                        ErrorCode:    qerr.ProtocolViolation,
@@ -123,7 +124,7 @@ func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.Connect
        return m.issueNewConnID()
 }
 
-func (m *connIDGenerator) queueConnIDForRetiring(connID protocol.ConnectionID, expiry time.Time) {
+func (m *connIDGenerator) queueConnIDForRetiring(connID protocol.ConnectionID, expiry monotime.Time) {
        idx := slices.IndexFunc(m.connIDsToRetire, func(c connIDToRetire) bool {
                return c.t.After(expiry)
        })
@@ -149,21 +150,21 @@ func (m *connIDGenerator) issueNewConnID() error {
        return nil
 }
 
-func (m *connIDGenerator) SetHandshakeComplete(connIDExpiry time.Time) {
+func (m *connIDGenerator) SetHandshakeComplete(connIDExpiry monotime.Time) {
        if m.initialClientDestConnID != nil {
                m.queueConnIDForRetiring(*m.initialClientDestConnID, connIDExpiry)
                m.initialClientDestConnID = nil
        }
 }
 
-func (m *connIDGenerator) NextRetireTime() time.Time {
+func (m *connIDGenerator) NextRetireTime() monotime.Time {
        if len(m.connIDsToRetire) == 0 {
-               return time.Time{}
+               return 0
        }
        return m.connIDsToRetire[0].t
 }
 
-func (m *connIDGenerator) RemoveRetiredConnIDs(now time.Time) {
+func (m *connIDGenerator) RemoveRetiredConnIDs(now monotime.Time) {
        if len(m.connIDsToRetire) == 0 {
                return
        }
index 6d171652295a8186726cdb3b60671ce0526a7b23..be531ba9b7a5c3c3c1dacbdff6fbd27c171a552b 100644 (file)
@@ -5,6 +5,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -65,7 +66,7 @@ func testConnIDGeneratorIssueAndRetire(t *testing.T, hasInitialClientDestConnID
        // completing the handshake retires the initial client destination connection ID
        added = added[:0]
        queuedFrames = queuedFrames[:0]
-       now := time.Now()
+       now := monotime.Now()
        g.SetHandshakeComplete(now)
        require.Empty(t, added)
        require.Empty(t, queuedFrames)
@@ -79,17 +80,17 @@ func testConnIDGeneratorIssueAndRetire(t *testing.T, hasInitialClientDestConnID
        }
 
        // it's invalid to retire a connection ID that hasn't been issued yet
-       err := g.Retire(4, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), time.Now())
+       err := g.Retire(4, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), monotime.Now())
        require.ErrorIs(t, &qerr.TransportError{ErrorCode: qerr.ProtocolViolation}, err)
        require.ErrorContains(t, err, "retired connection ID 4 (highest issued: 3)")
        // it's invalid to retire a connection ID in a packet that uses that connection ID
-       err = g.Retire(3, connIDs[3], time.Now())
+       err = g.Retire(3, connIDs[3], monotime.Now())
        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.ProtocolViolation})
        require.ErrorContains(t, err, "was used as the Destination Connection ID on this packet")
 
        // retiring a connection ID makes us issue a new one
-       require.NoError(t, g.Retire(2, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), time.Now()))
-       g.RemoveRetiredConnIDs(time.Now())
+       require.NoError(t, g.Retire(2, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), monotime.Now()))
+       g.RemoveRetiredConnIDs(monotime.Now())
        require.Equal(t, []protocol.ConnectionID{connIDs[2]}, removed)
        require.Len(t, queuedFrames, 1)
        require.EqualValues(t, 4, queuedFrames[0].(*wire.NewConnectionIDFrame).SequenceNumber)
@@ -97,8 +98,8 @@ func testConnIDGeneratorIssueAndRetire(t *testing.T, hasInitialClientDestConnID
        removed = removed[:0]
 
        // duplicate retirements don't do anything
-       require.NoError(t, g.Retire(2, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), time.Now()))
-       g.RemoveRetiredConnIDs(time.Now())
+       require.NoError(t, g.Retire(2, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), monotime.Now()))
+       g.RemoveRetiredConnIDs(monotime.Now())
        require.Empty(t, queuedFrames)
        require.Empty(t, removed)
 }
@@ -123,9 +124,9 @@ func TestConnIDGeneratorRetiring(t *testing.T) {
        require.Empty(t, removed)
        require.Len(t, added, 5)
 
-       now := time.Now()
+       now := monotime.Now()
 
-       retirements := map[protocol.ConnectionID]time.Time{}
+       retirements := map[protocol.ConnectionID]monotime.Time{}
        t1 := now.Add(time.Duration(rand.IntN(1000)) * time.Millisecond)
        retirements[initialConnID] = t1
        g.SetHandshakeComplete(t1)
@@ -134,7 +135,7 @@ func TestConnIDGeneratorRetiring(t *testing.T) {
                require.NoError(t, g.Retire(uint64(i+1), protocol.ParseConnectionID([]byte{9, 9, 9, 9}), t2))
                retirements[added[i]] = t2
 
-               var nextRetirement time.Time
+               var nextRetirement monotime.Time
                for _, r := range retirements {
                        if nextRetirement.IsZero() || r.Before(nextRetirement) {
                                nextRetirement = r
@@ -248,8 +249,8 @@ func testConnIDGeneratorReplaceWithClosed(t *testing.T, hasInitialClientDestConn
        require.Len(t, added, protocol.MaxIssuedConnectionIDs-1)
        // Retire two of these connection ID.
        // This makes us issue two more connection IDs.
-       require.NoError(t, g.Retire(3, protocol.ParseConnectionID([]byte{1, 1, 1, 1}), time.Now()))
-       require.NoError(t, g.Retire(4, protocol.ParseConnectionID([]byte{1, 1, 1, 1}), time.Now()))
+       require.NoError(t, g.Retire(3, protocol.ParseConnectionID([]byte{1, 1, 1, 1}), monotime.Now()))
+       require.NoError(t, g.Retire(4, protocol.ParseConnectionID([]byte{1, 1, 1, 1}), monotime.Now()))
        require.Len(t, added, protocol.MaxIssuedConnectionIDs+1)
 
        g.ReplaceWithClosed([]byte("foobar"), time.Second)
@@ -333,15 +334,15 @@ func TestConnIDGeneratorAddConnRunner(t *testing.T) {
        connIDToRetire = ncid.ConnectionID
        seqToRetire = ncid.SequenceNumber
 
-       require.NoError(t, g.Retire(seqToRetire, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), time.Now()))
-       g.RemoveRetiredConnIDs(time.Now())
+       require.NoError(t, g.Retire(seqToRetire, protocol.ParseConnectionID([]byte{3, 3, 3, 3}), monotime.Now()))
+       g.RemoveRetiredConnIDs(monotime.Now())
        require.Equal(t, []protocol.ConnectionID{connIDToRetire}, tracker1.removed)
        require.Equal(t, []protocol.ConnectionID{connIDToRetire}, tracker2.removed)
 
        tracker1.removed = nil
        tracker2.removed = nil
-       g.SetHandshakeComplete(time.Now())
-       g.RemoveRetiredConnIDs(time.Now())
+       g.SetHandshakeComplete(monotime.Now())
+       g.RemoveRetiredConnIDs(monotime.Now())
        require.Equal(t, []protocol.ConnectionID{clientDestConnID}, tracker1.removed)
        require.Equal(t, []protocol.ConnectionID{clientDestConnID}, tracker2.removed)
 
index 1560bb15110ebe263f1275ed179515b403a80354..50c2d8328d9be880da9a74d82f3c1cdc98f2e534 100644 (file)
@@ -17,6 +17,7 @@ import (
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
        "github.com/quic-go/quic-go/internal/handshake"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -27,7 +28,7 @@ import (
 
 type unpacker interface {
        UnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error)
-       UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)
+       UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)
 }
 
 type cryptoStreamHandler interface {
@@ -47,7 +48,7 @@ type receivedPacket struct {
        buffer *packetBuffer
 
        remoteAddr net.Addr
-       rcvTime    time.Time
+       rcvTime    monotime.Time
        data       []byte
 
        ecn protocol.ECN
@@ -179,13 +180,13 @@ type Conn struct {
 
        // the minimum of the max_idle_timeout values advertised by both endpoints
        idleTimeout  time.Duration
-       creationTime time.Time
+       creationTime monotime.Time
        // The idle timeout is set based on the max of the time we received the last packet...
-       lastPacketReceivedTime time.Time
+       lastPacketReceivedTime monotime.Time
        // ... and the time we sent a new ack-eliciting packet after receiving a packet.
-       firstAckElicitingPacketAfterIdleSentTime time.Time
+       firstAckElicitingPacketAfterIdleSentTime monotime.Time
        // pacingDeadline is the time when the next packet should be sent
-       pacingDeadline time.Time
+       pacingDeadline monotime.Time
 
        peerParams *wire.TransportParameters
 
@@ -508,7 +509,7 @@ func (c *Conn) preSetup() {
        c.sendingScheduled = make(chan struct{}, 1)
        c.handshakeCompleteChan = make(chan struct{})
 
-       now := time.Now()
+       now := monotime.Now()
        c.lastPacketReceivedTime = now
        c.creationTime = now
 
@@ -537,7 +538,7 @@ func (c *Conn) run() (err error) {
        if err := c.cryptoStreamHandler.StartHandshake(c.ctx); err != nil {
                return err
        }
-       if err := c.handleHandshakeEvents(time.Now()); err != nil {
+       if err := c.handleHandshakeEvents(monotime.Now()); err != nil {
                return err
        }
        go func() {
@@ -632,7 +633,7 @@ runLoop:
 
                // Check for loss detection timeout.
                // This could cause packets to be declared lost, and retransmissions to be enqueued.
-               now := time.Now()
+               now := monotime.Now()
                if timeout := c.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && timeout.Before(now) {
                        if err := c.sentPacketHandler.OnLossDetectionTimeout(now); err != nil {
                                c.setCloseError(&closeError{err: err})
@@ -673,7 +674,7 @@ runLoop:
                        // The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.
                        sendQueueAvailable = c.sendQueue.Available()
                        // Cancel the pacing timer, as we can't send any more packets until the send queue is available again.
-                       c.pacingDeadline = time.Time{}
+                       c.pacingDeadline = 0
                        continue
                }
 
@@ -689,7 +690,7 @@ runLoop:
                        // The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.
                        sendQueueAvailable = c.sendQueue.Available()
                        // Cancel the pacing timer, as we can't send any more packets until the send queue is available again.
-                       c.pacingDeadline = time.Time{}
+                       c.pacingDeadline = 0
                } else {
                        sendQueueAvailable = nil
                }
@@ -792,23 +793,23 @@ func (c *Conn) ConnectionStats() ConnectionStats {
 }
 
 // Time when the connection should time out
-func (c *Conn) nextIdleTimeoutTime() time.Time {
+func (c *Conn) nextIdleTimeoutTime() monotime.Time {
        idleTimeout := max(c.idleTimeout, c.rttStats.PTO(true)*3)
        return c.idleTimeoutStartTime().Add(idleTimeout)
 }
 
 // Time when the next keep-alive packet should be sent.
 // It returns a zero time if no keep-alive should be sent.
-func (c *Conn) nextKeepAliveTime() time.Time {
+func (c *Conn) nextKeepAliveTime() monotime.Time {
        if c.config.KeepAlivePeriod == 0 || c.keepAlivePingSent {
-               return time.Time{}
+               return 0
        }
        keepAliveInterval := max(c.keepAliveInterval, c.rttStats.PTO(true)*3/2)
        return c.lastPacketReceivedTime.Add(keepAliveInterval)
 }
 
 func (c *Conn) maybeResetTimer() {
-       var deadline time.Time
+       var deadline monotime.Time
        if !c.handshakeComplete {
                deadline = c.creationTime.Add(c.config.handshakeTimeout())
                if t := c.idleTimeoutStartTime().Add(c.config.HandshakeIdleTimeout); t.Before(deadline) {
@@ -831,7 +832,7 @@ func (c *Conn) maybeResetTimer() {
        )
 }
 
-func (c *Conn) idleTimeoutStartTime() time.Time {
+func (c *Conn) idleTimeoutStartTime() monotime.Time {
        startTime := c.lastPacketReceivedTime
        if t := c.firstAckElicitingPacketAfterIdleSentTime; t.After(startTime) {
                startTime = t
@@ -839,7 +840,7 @@ func (c *Conn) idleTimeoutStartTime() time.Time {
        return startTime
 }
 
-func (c *Conn) switchToNewPath(tr *Transport, now time.Time) {
+func (c *Conn) switchToNewPath(tr *Transport, now monotime.Time) {
        initialPacketSize := protocol.ByteCount(c.config.InitialPacketSize)
        c.sentPacketHandler.MigratedPath(now, initialPacketSize)
        maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)
@@ -857,7 +858,7 @@ func (c *Conn) switchToNewPath(tr *Transport, now time.Time) {
        }()
 }
 
-func (c *Conn) handleHandshakeComplete(now time.Time) error {
+func (c *Conn) handleHandshakeComplete(now monotime.Time) error {
        defer close(c.handshakeCompleteChan)
        // Once the handshake completes, we have derived 1-RTT keys.
        // There's no point in queueing undecryptable packets for later decryption anymore.
@@ -903,7 +904,7 @@ func (c *Conn) handleHandshakeComplete(now time.Time) error {
        return nil
 }
 
-func (c *Conn) handleHandshakeConfirmed(now time.Time) error {
+func (c *Conn) handleHandshakeConfirmed(now monotime.Time) error {
        if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
                return err
        }
@@ -1268,7 +1269,7 @@ func (c *Conn) handleUnpackError(err error, p receivedPacket, pt logging.PacketT
        }
 }
 
-func (c *Conn) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime time.Time) bool /* was this a valid Retry */ {
+func (c *Conn) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime monotime.Time) bool /* was this a valid Retry */ {
        if c.perspective == protocol.PerspectiveServer {
                if c.tracer != nil && c.tracer.DroppedPacket != nil {
                        c.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
@@ -1384,7 +1385,7 @@ func (c *Conn) handleVersionNegotiationPacket(p receivedPacket) {
 func (c *Conn) handleUnpackedLongHeaderPacket(
        packet *unpackedPacket,
        ecn protocol.ECN,
-       rcvTime time.Time,
+       rcvTime monotime.Time,
        packetSize protocol.ByteCount, // only for logging
 ) error {
        if !c.receivedFirstPacket {
@@ -1437,7 +1438,7 @@ func (c *Conn) handleUnpackedLongHeaderPacket(
        }
 
        c.lastPacketReceivedTime = rcvTime
-       c.firstAckElicitingPacketAfterIdleSentTime = time.Time{}
+       c.firstAckElicitingPacketAfterIdleSentTime = 0
        c.keepAlivePingSent = false
 
        if packet.hdr.Type == protocol.PacketType0RTT {
@@ -1462,11 +1463,11 @@ func (c *Conn) handleUnpackedShortHeaderPacket(
        pn protocol.PacketNumber,
        data []byte,
        ecn protocol.ECN,
-       rcvTime time.Time,
+       rcvTime monotime.Time,
        log func([]logging.Frame),
 ) (isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {
        c.lastPacketReceivedTime = rcvTime
-       c.firstAckElicitingPacketAfterIdleSentTime = time.Time{}
+       c.firstAckElicitingPacketAfterIdleSentTime = 0
        c.keepAlivePingSent = false
 
        isAckEliciting, isNonProbing, pathChallenge, err := c.handleFrames(data, destConnID, protocol.Encryption1RTT, log, rcvTime)
@@ -1486,7 +1487,7 @@ func (c *Conn) handleFrames(
        destConnID protocol.ConnectionID,
        encLevel protocol.EncryptionLevel,
        log func([]logging.Frame),
-       rcvTime time.Time,
+       rcvTime monotime.Time,
 ) (isAckEliciting, isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {
        // Only used for tracing.
        // If we're not tracing, this slice will always remain empty.
@@ -1619,7 +1620,7 @@ func (c *Conn) handleFrame(
        f wire.Frame,
        encLevel protocol.EncryptionLevel,
        destConnID protocol.ConnectionID,
-       rcvTime time.Time,
+       rcvTime monotime.Time,
 ) (pathChallenge *wire.PathChallengeFrame, _ error) {
        var err error
        wire.LogFrame(c.logger, f, false)
@@ -1699,7 +1700,7 @@ func (c *Conn) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) erro
        }
 }
 
-func (c *Conn) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {
+func (c *Conn) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error {
        if err := c.cryptoStreamManager.HandleCryptoFrame(frame, encLevel); err != nil {
                return err
        }
@@ -1715,7 +1716,7 @@ func (c *Conn) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.Encr
        return c.handleHandshakeEvents(rcvTime)
 }
 
-func (c *Conn) handleHandshakeEvents(now time.Time) error {
+func (c *Conn) handleHandshakeEvents(now monotime.Time) error {
        for {
                ev := c.cryptoStreamHandler.NextEvent()
                var err error
@@ -1802,7 +1803,7 @@ func (c *Conn) handleNewTokenFrame(frame *wire.NewTokenFrame) error {
        return nil
 }
 
-func (c *Conn) handleHandshakeDoneFrame(rcvTime time.Time) error {
+func (c *Conn) handleHandshakeDoneFrame(rcvTime monotime.Time) error {
        if c.perspective == protocol.PerspectiveServer {
                return &qerr.TransportError{
                        ErrorCode:    qerr.ProtocolViolation,
@@ -1815,7 +1816,7 @@ func (c *Conn) handleHandshakeDoneFrame(rcvTime time.Time) error {
        return nil
 }
 
-func (c *Conn) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {
+func (c *Conn) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error {
        acked1RTTPacket, err := c.sentPacketHandler.ReceivedAck(frame, encLevel, c.lastPacketReceivedTime)
        if err != nil {
                return err
@@ -1977,7 +1978,7 @@ func (c *Conn) handleCloseError(closeErr *closeError) {
        c.connIDGenerator.ReplaceWithClosed(connClosePacket, 3*c.rttStats.PTO(false))
 }
 
-func (c *Conn) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now time.Time) error {
+func (c *Conn) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now monotime.Time) error {
        if c.tracer != nil && c.tracer.DroppedEncryptionLevel != nil {
                c.tracer.DroppedEncryptionLevel(encLevel)
        }
@@ -2109,8 +2110,8 @@ func (c *Conn) applyTransportParameters() {
        )
 }
 
-func (c *Conn) triggerSending(now time.Time) error {
-       c.pacingDeadline = time.Time{}
+func (c *Conn) triggerSending(now monotime.Time) error {
+       c.pacingDeadline = 0
 
        sendMode := c.sentPacketHandler.SendMode(now)
        switch sendMode {
@@ -2147,7 +2148,7 @@ func (c *Conn) triggerSending(now time.Time) error {
        }
 }
 
-func (c *Conn) sendPackets(now time.Time) error {
+func (c *Conn) sendPackets(now monotime.Time) error {
        if c.perspective == protocol.PerspectiveClient && c.handshakeConfirmed {
                if pm := c.pathManagerOutgoing.Load(); pm != nil {
                        connID, frame, tr, ok := pm.NextPathToProbe()
@@ -2218,7 +2219,7 @@ func (c *Conn) sendPackets(now time.Time) error {
        return c.sendPacketsWithoutGSO(now)
 }
 
-func (c *Conn) sendPacketsWithoutGSO(now time.Time) error {
+func (c *Conn) sendPacketsWithoutGSO(now monotime.Time) error {
        for {
                buf := getPacketBuffer()
                ecn := c.sentPacketHandler.ECNMode(true)
@@ -2254,7 +2255,7 @@ func (c *Conn) sendPacketsWithoutGSO(now time.Time) error {
        }
 }
 
-func (c *Conn) sendPacketsWithGSO(now time.Time) error {
+func (c *Conn) sendPacketsWithGSO(now monotime.Time) error {
        buf := getLargePacketBuffer()
        maxSize := c.maxPacketSize()
 
@@ -2326,7 +2327,7 @@ func (c *Conn) resetPacingDeadline() {
        c.pacingDeadline = deadline
 }
 
-func (c *Conn) maybeSendAckOnlyPacket(now time.Time) error {
+func (c *Conn) maybeSendAckOnlyPacket(now monotime.Time) error {
        if !c.handshakeConfirmed {
                ecn := c.sentPacketHandler.ECNMode(false)
                packet, err := c.packer.PackCoalescedPacket(true, c.maxPacketSize(), now, c.version)
@@ -2353,7 +2354,7 @@ func (c *Conn) maybeSendAckOnlyPacket(now time.Time) error {
        return nil
 }
 
-func (c *Conn) sendProbePacket(sendMode ackhandler.SendMode, now time.Time) error {
+func (c *Conn) sendProbePacket(sendMode ackhandler.SendMode, now monotime.Time) error {
        var encLevel protocol.EncryptionLevel
        //nolint:exhaustive // We only need to handle the PTO send modes here.
        switch sendMode {
@@ -2394,7 +2395,7 @@ func (c *Conn) sendProbePacket(sendMode ackhandler.SendMode, now time.Time) erro
 
 // appendOneShortHeaderPacket appends a new packet to the given packetBuffer.
 // If there was nothing to pack, the returned size is 0.
-func (c *Conn) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now time.Time) (protocol.ByteCount, error) {
+func (c *Conn) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now monotime.Time) (protocol.ByteCount, error) {
        startLen := buf.Len()
        p, err := c.packer.AppendPacket(buf, maxSize, now, c.version)
        if err != nil {
@@ -2406,7 +2407,7 @@ func (c *Conn) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.By
        return size, nil
 }
 
-func (c *Conn) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now time.Time) {
+func (c *Conn) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now monotime.Time) {
        if p.IsPathProbePacket {
                c.sentPacketHandler.SentPacket(
                        now,
@@ -2445,7 +2446,7 @@ func (c *Conn) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol
        c.connIDManager.SentPacket()
 }
 
-func (c *Conn) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now time.Time) error {
+func (c *Conn) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now monotime.Time) error {
        c.logCoalescedPacket(packet, ecn)
        for _, p := range packet.longHdrPackets {
                if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
index 30d7dd8c15c42bf2560f27be4c2b573ed79189cd..65802f61b0e33001a90895b636000bb7ff7ee493 100644 (file)
@@ -18,6 +18,7 @@ import (
        "github.com/quic-go/quic-go/internal/mocks"
        mockackhandler "github.com/quic-go/quic-go/internal/mocks/ackhandler"
        mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -227,7 +228,7 @@ func TestConnectionHandleStreamRelatedFrames(t *testing.T) {
                        tc := newServerTestConnection(t, gomock.NewController(t), nil, false)
                        data, err := test.frame.Append(nil, protocol.Version1)
                        require.NoError(t, err)
-                       _, _, _, err = tc.conn.handleFrames(data, connID, protocol.Encryption1RTT, nil, time.Now())
+                       _, _, _, err = tc.conn.handleFrames(data, connID, protocol.Encryption1RTT, nil, monotime.Now())
                        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.StreamStateError})
                })
        }
@@ -238,7 +239,7 @@ func TestConnectionHandleConnectionFlowControlFrames(t *testing.T) {
        connFC := flowcontrol.NewConnectionFlowController(0, 0, nil, &utils.RTTStats{}, utils.DefaultLogger)
        require.Zero(t, connFC.SendWindowSize())
        tc := newServerTestConnection(t, mockCtrl, nil, false, connectionOptConnFlowController(connFC))
-       now := time.Now()
+       now := monotime.Now()
        connID := protocol.ConnectionID{}
        // MAX_DATA frame
        _, err := tc.conn.handleFrame(&wire.MaxDataFrame{MaximumData: 1337}, protocol.Encryption1RTT, connID, now)
@@ -262,7 +263,7 @@ func TestConnectionServerInvalidFrames(t *testing.T) {
                {Name: "PATH_RESPONSE", Frame: &wire.PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}}},
        } {
                t.Run(test.Name, func(t *testing.T) {
-                       _, err := tc.conn.handleFrame(test.Frame, protocol.Encryption1RTT, protocol.ConnectionID{}, time.Now())
+                       _, err := tc.conn.handleFrame(test.Frame, protocol.Encryption1RTT, protocol.ConnectionID{}, monotime.Now())
                        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.ProtocolViolation})
                })
        }
@@ -367,7 +368,7 @@ func getLongHeaderPacket(t *testing.T, remoteAddr net.Addr, extHdr *wire.Extende
                remoteAddr: remoteAddr,
                data:       append(b, data...),
                buffer:     getPacketBuffer(),
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
        }
 }
 
@@ -379,7 +380,7 @@ func getShortHeaderPacket(t *testing.T, remoteAddr net.Addr, connID protocol.Con
                remoteAddr: remoteAddr,
                data:       append(b, data...),
                buffer:     getPacketBuffer(),
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
        }
 }
 
@@ -510,7 +511,7 @@ func TestConnectionUnpacking(t *testing.T) {
        unpackedHdr.PacketNumber = 0x1337
        packet := getLongHeaderPacket(t, tc.remoteAddr, hdr, nil)
        packet.ecn = protocol.ECNCE
-       rcvTime := time.Now().Add(-10 * time.Second)
+       rcvTime := monotime.Now().Add(-10 * time.Second)
        packet.rcvTime = rcvTime
        unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
                encryptionLevel: protocol.EncryptionInitial,
@@ -617,7 +618,7 @@ func TestConnectionUnpackCoalescedPacket(t *testing.T) {
        packet.data = append(packet.data, packet2.data...)
        packet.data = append(packet.data, packet3.data...)
        packet.ecn = protocol.ECT1
-       rcvTime := time.Now()
+       rcvTime := monotime.Now()
        packet.rcvTime = rcvTime
 
        unpacker.EXPECT().UnpackLongHeader(gomock.Any(), gomock.Any()).Return(&unpackedPacket{
@@ -800,7 +801,7 @@ func TestConnectionRemoteClose(t *testing.T) {
        go func() { errChan <- tc.conn.run() }()
 
        p := getShortHeaderPacket(t, tc.remoteAddr, tc.srcConnID, 1, []byte("encrypted"))
-       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: time.Now()})
+       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: monotime.Now()})
 
        select {
        case err := <-errChan:
@@ -849,7 +850,7 @@ func TestConnectionHandshakeIdleTimeout(t *testing.T) {
                &Config{HandshakeIdleTimeout: scaleDuration(25 * time.Millisecond)},
                false,
                connectionOptTracer(tr),
-               func(c *Conn) { c.creationTime = time.Now().Add(-10 * time.Second) },
+               func(c *Conn) { c.creationTime = monotime.Now().Add(-10 * time.Second) },
        )
        tc.packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), gomock.Any(), protocol.Version1).AnyTimes()
        tc.connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
@@ -935,7 +936,7 @@ func TestConnectionHandleMaxStreamsFrame(t *testing.T) {
                &wire.MaxStreamsFrame{Type: protocol.StreamTypeBidi, MaxStreamNum: 10},
                protocol.Encryption1RTT,
                protocol.ConnectionID{},
-               time.Now(),
+               monotime.Now(),
        )
        require.NoError(t, err)
 
@@ -956,7 +957,7 @@ func TestConnectionHandleMaxStreamsFrame(t *testing.T) {
                &wire.MaxStreamsFrame{Type: protocol.StreamTypeUni, MaxStreamNum: 10},
                protocol.Encryption1RTT,
                protocol.ConnectionID{},
-               time.Now(),
+               monotime.Now(),
        )
        require.NoError(t, err)
        select {
@@ -1083,7 +1084,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
        errChan := make(chan error, 1)
        go func() { errChan <- tc.conn.run() }()
        p := getLongHeaderPacket(t, tc.remoteAddr, hdr, nil)
-       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: time.Now()})
+       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: monotime.Now()})
 
        select {
        case <-tc.conn.HandshakeComplete():
@@ -1094,7 +1095,7 @@ func TestConnectionHandshakeServer(t *testing.T) {
        }
 
        var foundSessionTicket, foundHandshakeDone, foundNewToken bool
-       frames, _, _ := tc.conn.framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       frames, _, _ := tc.conn.framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        for _, frame := range frames {
                switch f := frame.Frame.(type) {
                case *wire.CryptoFrame:
@@ -1167,7 +1168,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
                cs.EXPECT().StartHandshake(gomock.Any()),
                cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}),
                tc.packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), gomock.Any(), protocol.Version1).DoAndReturn(
-                       func(b bool, bc protocol.ByteCount, t time.Time, v protocol.Version) (*coalescedPacket, error) {
+                       func(b bool, bc protocol.ByteCount, t monotime.Time, v protocol.Version) (*coalescedPacket, error) {
                                close(packedFirstPacket)
                                return &coalescedPacket{buffer: getPacketBuffer(), longHdrPackets: []*longHeaderPacket{{header: hdr}}}, nil
                        },
@@ -1195,7 +1196,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
        }
 
        p := getLongHeaderPacket(t, tc.remoteAddr, hdr, nil)
-       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: time.Now()})
+       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: monotime.Now()})
 
        select {
        case <-tc.conn.HandshakeComplete():
@@ -1218,7 +1219,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
                ),
                cs.EXPECT().SetHandshakeConfirmed(),
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
+                       func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
                                close(done)
                                return shortHeaderPacket{}, errNothingToPack
                        },
@@ -1226,7 +1227,7 @@ func testConnectionHandshakeClient(t *testing.T, usePreferredAddress bool) {
        )
        tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(shortHeaderPacket{}, errNothingToPack).AnyTimes()
        p = getLongHeaderPacket(t, tc.remoteAddr, hdr, nil)
-       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: time.Now()})
+       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: monotime.Now()})
 
        select {
        case <-done:
@@ -1291,7 +1292,7 @@ func TestConnection0RTTTransportParameters(t *testing.T) {
                cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventRestoredTransportParameters, TransportParameters: restored}),
                cs.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent}),
                tc.packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), gomock.Any(), protocol.Version1).DoAndReturn(
-                       func(b bool, bc protocol.ByteCount, t time.Time, v protocol.Version) (*coalescedPacket, error) {
+                       func(b bool, bc protocol.ByteCount, t monotime.Time, v protocol.Version) (*coalescedPacket, error) {
                                close(packedFirstPacket)
                                return &coalescedPacket{buffer: getPacketBuffer(), longHdrPackets: []*longHeaderPacket{{header: hdr}}}, nil
                        },
@@ -1322,7 +1323,7 @@ func TestConnection0RTTTransportParameters(t *testing.T) {
        }
 
        p := getLongHeaderPacket(t, tc.remoteAddr, hdr, nil)
-       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: time.Now()})
+       tc.conn.handlePacket(receivedPacket{data: p.data, buffer: p.buffer, rcvTime: monotime.Now()})
 
        select {
        case err := <-errChan:
@@ -1366,7 +1367,7 @@ func testConnectionReceivePrioritization(t *testing.T, handshakeComplete bool, n
        var testDone bool
        done := make(chan struct{})
        unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).DoAndReturn(
-               func(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+               func(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
                        counter++
                        if counter == numPackets {
                                testDone = true
@@ -1378,7 +1379,7 @@ func testConnectionReceivePrioritization(t *testing.T, handshakeComplete bool, n
        switch handshakeComplete {
        case false:
                tc.packer.EXPECT().PackCoalescedPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(b bool, bc protocol.ByteCount, t time.Time, v protocol.Version) (*coalescedPacket, error) {
+                       func(b bool, bc protocol.ByteCount, t monotime.Time, v protocol.Version) (*coalescedPacket, error) {
                                events = append(events, "pack")
                                if testDone {
                                        close(done)
@@ -1388,7 +1389,7 @@ func testConnectionReceivePrioritization(t *testing.T, handshakeComplete bool, n
                ).AnyTimes()
        case true:
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(b *packetBuffer, bc protocol.ByteCount, t time.Time, v protocol.Version) (shortHeaderPacket, error) {
+                       func(b *packetBuffer, bc protocol.ByteCount, t monotime.Time, v protocol.Version) (shortHeaderPacket, error) {
                                events = append(events, "pack")
                                if testDone {
                                        close(done)
@@ -1567,7 +1568,7 @@ func TestConnectionPacketPacing(t *testing.T) {
 
        step := scaleDuration(50 * time.Millisecond)
 
-       sph.EXPECT().GetLossDetectionTimeout().Return(time.Now().Add(time.Hour)).AnyTimes()
+       sph.EXPECT().GetLossDetectionTimeout().Return(monotime.Now().Add(time.Hour)).AnyTimes()
        gomock.InOrder(
                // 1. allow 2 packets to be sent
                sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
@@ -1576,31 +1577,31 @@ func TestConnectionPacketPacing(t *testing.T) {
                sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
                sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
                // 2. become pacing limited for 25ms
-               sph.EXPECT().TimeUntilSend().DoAndReturn(func() time.Time { return time.Now().Add(step) }),
+               sph.EXPECT().TimeUntilSend().DoAndReturn(func() monotime.Time { return monotime.Now().Add(step) }),
                // 3. send another packet
                sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny),
                sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
                sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
                // 4. become pacing limited for 25ms...
-               sph.EXPECT().TimeUntilSend().DoAndReturn(func() time.Time { return time.Now().Add(step) }),
+               sph.EXPECT().TimeUntilSend().DoAndReturn(func() monotime.Time { return monotime.Now().Add(step) }),
                // ... but this time we're still pacing limited when waking up.
                // In this case, we can only send an ACK.
                sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited),
                // 5. stop the test by becoming pacing limited forever
-               sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour)),
+               sph.EXPECT().TimeUntilSend().Return(monotime.Now().Add(time.Hour)),
                sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()),
        )
        sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
        for i := 0; i < 3; i++ {
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), Version1).DoAndReturn(
-                       func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
+                       func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
                                buf.Data = append(buf.Data, []byte("packet"+strconv.Itoa(i+1))...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(i + 1)}, nil
                        },
                )
        }
        tc.packer.EXPECT().PackAckOnlyPacket(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(_ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+               func(_ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
                        buf := getPacketBuffer()
                        buf.Data = []byte("ack")
                        return shortHeaderPacket{PacketNumber: 1}, buf, nil
@@ -1609,19 +1610,19 @@ func TestConnectionPacketPacing(t *testing.T) {
        sender.EXPECT().WouldBlock().AnyTimes()
 
        type sentPacket struct {
-               time time.Time
+               time monotime.Time
                data []byte
        }
        sendChan := make(chan sentPacket, 10)
        sender.EXPECT().Send(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
-               sendChan <- sentPacket{time: time.Now(), data: b.Data}
+               sendChan <- sentPacket{time: monotime.Now(), data: b.Data}
        }).Times(4)
 
        errChan := make(chan error, 1)
        go func() { errChan <- tc.conn.run() }()
        tc.conn.scheduleSending()
 
-       var times []time.Time
+       var times []monotime.Time
        for i := 0; i < 3; i++ {
                select {
                case b := <-sendChan:
@@ -1680,13 +1681,13 @@ func TestConnectionPacingAndSendQueue(t *testing.T) {
        sender.EXPECT().Run()
 
        sendQueueAvailable := make(chan struct{})
-       pacingDeadline := time.Now().Add(-time.Millisecond)
+       pacingDeadline := monotime.Now().Add(-time.Millisecond)
        var counter int
        // allow exactly one packet to be sent, then become blocked
        sender.EXPECT().WouldBlock().Return(false)
        sender.EXPECT().WouldBlock().DoAndReturn(func() bool { counter++; return true }).AnyTimes()
        sender.EXPECT().Available().Return(sendQueueAvailable).AnyTimes()
-       sph.EXPECT().GetLossDetectionTimeout().Return(time.Now().Add(time.Hour)).AnyTimes()
+       sph.EXPECT().GetLossDetectionTimeout().Return(monotime.Now().Add(time.Hour)).AnyTimes()
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendPacingLimited).AnyTimes()
        sph.EXPECT().TimeUntilSend().Return(pacingDeadline).AnyTimes()
        sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECNNon).AnyTimes()
@@ -1736,11 +1737,11 @@ func TestConnectionIdleTimeout(t *testing.T) {
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
        sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
-       var lastSendTime time.Time
+       var lastSendTime monotime.Time
        tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
+               func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
                        buf.Data = append(buf.Data, []byte("foobar")...)
-                       lastSendTime = time.Now()
+                       lastSendTime = monotime.Now()
                        return shortHeaderPacket{Frames: []ackhandler.Frame{{Frame: &wire.PingFrame{}}}, Length: 6}, nil
                },
        )
@@ -1757,7 +1758,7 @@ func TestConnectionIdleTimeout(t *testing.T) {
                require.ErrorIs(t, err, &IdleTimeoutError{})
                require.NotZero(t, lastSendTime)
                require.InDelta(t,
-                       time.Since(lastSendTime).Seconds(),
+                       monotime.Since(lastSendTime).Seconds(),
                        idleTimeout.Seconds(),
                        scaleDuration(10*time.Millisecond).Seconds(),
                )
@@ -1808,11 +1809,11 @@ func testConnectionKeepAlive(t *testing.T, enable, expectKeepAlive bool) {
        errChan := make(chan error, 1)
        go func() { errChan <- tc.conn.run() }()
 
-       var unpackTime, packTime time.Time
+       var unpackTime, packTime monotime.Time
        done := make(chan struct{})
        unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).DoAndReturn(
-               func(t time.Time, bytes []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
-                       unpackTime = time.Now()
+               func(t monotime.Time, bytes []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+                       unpackTime = monotime.Now()
                        return protocol.PacketNumber(1), protocol.PacketNumberLen1, protocol.KeyPhaseZero, []byte{0} /* PADDING */, nil
                },
        )
@@ -1822,13 +1823,13 @@ func testConnectionKeepAlive(t *testing.T, enable, expectKeepAlive bool) {
        case true:
                // record the time of the keep-alive is sent
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
-                               packTime = time.Now()
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
+                               packTime = monotime.Now()
                                close(done)
                                return shortHeaderPacket{}, errNothingToPack
                        },
                )
-               tc.conn.handlePacket(receivedPacket{data: buf.Data, buffer: buf, rcvTime: time.Now(), remoteAddr: tc.remoteAddr})
+               tc.conn.handlePacket(receivedPacket{data: buf.Data, buffer: buf, rcvTime: monotime.Now(), remoteAddr: tc.remoteAddr})
                select {
                case <-done:
                        // the keep-alive packet should be sent after half the idle timeout
@@ -1839,7 +1840,7 @@ func testConnectionKeepAlive(t *testing.T, enable, expectKeepAlive bool) {
                }
        case false: // if keep-alives are disabled, the connection will run into an idle timeout
                tc.connRunner.EXPECT().Remove(gomock.Any()).AnyTimes()
-               tc.conn.handlePacket(receivedPacket{data: buf.Data, buffer: buf, rcvTime: time.Now(), remoteAddr: tc.remoteAddr})
+               tc.conn.handlePacket(receivedPacket{data: buf.Data, buffer: buf, rcvTime: monotime.Now(), remoteAddr: tc.remoteAddr})
                select {
                case <-time.After(3 * time.Second):
                        t.Fatal("timeout")
@@ -1883,30 +1884,30 @@ func TestConnectionACKTimer(t *testing.T) {
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
        sph.EXPECT().ECNMode(gomock.Any()).AnyTimes()
-       rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(time.Hour))
+       rph.EXPECT().GetAlarmTimeout().Return(monotime.Now().Add(time.Hour))
        tc.sendConn.EXPECT().Write(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
 
-       var times []time.Time
+       var times []monotime.Time
        done := make(chan struct{}, 5)
        var calls []any
        for i := 0; i < 2; i++ {
                calls = append(calls, tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
+                       func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
                                buf.Data = append(buf.Data, []byte("foobar")...)
-                               times = append(times, time.Now())
+                               times = append(times, monotime.Now())
                                return shortHeaderPacket{Frames: []ackhandler.Frame{{Frame: &wire.PingFrame{}}}, Length: 6}, nil
                        },
                ))
                calls = append(calls, tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buf *packetBuffer, _ protocol.ByteCount, _ time.Time, _ protocol.Version) (shortHeaderPacket, error) {
+                       func(buf *packetBuffer, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) (shortHeaderPacket, error) {
                                done <- struct{}{}
                                return shortHeaderPacket{}, errNothingToPack
                        },
                ))
                if i == 0 {
-                       calls = append(calls, rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(alarmTimeout)))
+                       calls = append(calls, rph.EXPECT().GetAlarmTimeout().Return(monotime.Now().Add(alarmTimeout)))
                } else {
-                       calls = append(calls, rph.EXPECT().GetAlarmTimeout().Return(time.Now().Add(time.Hour)).MaxTimes(1))
+                       calls = append(calls, rph.EXPECT().GetAlarmTimeout().Return(monotime.Now().Add(time.Hour)).MaxTimes(1))
                }
        }
        gomock.InOrder(calls...)
@@ -1950,9 +1951,9 @@ func TestConnectionGSOBatch(t *testing.T) {
 
        // allow packets to be sent
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
-       sph.EXPECT().TimeUntilSend().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().TimeUntilSend().AnyTimes()
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
-       sph.EXPECT().GetLossDetectionTimeout().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
        sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT1).AnyTimes()
 
        maxPacketSize := tc.conn.maxPacketSize()
@@ -1962,7 +1963,7 @@ func TestConnectionGSOBatch(t *testing.T) {
                expectedData = append(expectedData, data...)
 
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, data...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(i)}, nil
                        },
@@ -2009,9 +2010,9 @@ func TestConnectionGSOBatchPacketSize(t *testing.T) {
 
        // allow packets to be sent
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
-       sph.EXPECT().TimeUntilSend().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().TimeUntilSend().AnyTimes()
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
-       sph.EXPECT().GetLossDetectionTimeout().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
        sph.EXPECT().ECNMode(gomock.Any()).Return(protocol.ECT1).AnyTimes()
 
        maxPacketSize := tc.conn.maxPacketSize()
@@ -2027,7 +2028,7 @@ func TestConnectionGSOBatchPacketSize(t *testing.T) {
                expectedData = append(expectedData, data...)
 
                calls = append(calls, tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, data...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(10 + i)}, nil
                        },
@@ -2037,7 +2038,7 @@ func TestConnectionGSOBatchPacketSize(t *testing.T) {
        // We therefore send a "foobar", so we can check that we're actually generating two GSO batches.
        calls = append(calls,
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, []byte("foobar")...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(14)}, nil
                        },
@@ -2089,9 +2090,9 @@ func TestConnectionGSOBatchECN(t *testing.T) {
        // allow packets to be sent
        ecnMode := protocol.ECT1
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).AnyTimes()
-       sph.EXPECT().TimeUntilSend().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().TimeUntilSend().AnyTimes()
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
-       sph.EXPECT().GetLossDetectionTimeout().Return(time.Time{}).AnyTimes()
+       sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
        sph.EXPECT().ECNMode(gomock.Any()).DoAndReturn(func(bool) protocol.ECN { return ecnMode }).AnyTimes()
 
        // 3. Send a GSO batch, until the ECN marking changes.
@@ -2103,7 +2104,7 @@ func TestConnectionGSOBatchECN(t *testing.T) {
                expectedData = append(expectedData, data...)
 
                calls = append(calls, tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, data...)
                                if i == 2 {
                                        ecnMode = protocol.ECNCE
@@ -2116,7 +2117,7 @@ func TestConnectionGSOBatchECN(t *testing.T) {
        // We therefore send a "foobar", so we can check that we're actually generating two GSO batches.
        calls = append(calls,
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, []byte("foobar")...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(24)}, nil
                        },
@@ -2195,7 +2196,7 @@ func testConnectionPTOProbePackets(t *testing.T, encLevel protocol.EncryptionLev
        sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
 
        tc.packer.EXPECT().PackPTOProbePacket(encLevel, gomock.Any(), true, gomock.Any(), protocol.Version1).DoAndReturn(
-               func(protocol.EncryptionLevel, protocol.ByteCount, bool, time.Time, protocol.Version) (*coalescedPacket, error) {
+               func(protocol.EncryptionLevel, protocol.ByteCount, bool, monotime.Time, protocol.Version) (*coalescedPacket, error) {
                        return &coalescedPacket{
                                buffer:         getPacketBuffer(),
                                shortHdrPacket: &shortHeaderPacket{PacketNumber: 1},
@@ -2249,7 +2250,7 @@ func TestConnectionCongestionControl(t *testing.T) {
        // Since we're already sending out packets, we don't expect any calls to PackAckOnlyPacket
        for i := 0; i < 2; i++ {
                tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-                       func(buffer *packetBuffer, count protocol.ByteCount, t time.Time, version protocol.Version) (shortHeaderPacket, error) {
+                       func(buffer *packetBuffer, count protocol.ByteCount, t monotime.Time, version protocol.Version) (shortHeaderPacket, error) {
                                buffer.Data = append(buffer.Data, []byte("foobar")...)
                                return shortHeaderPacket{PacketNumber: protocol.PacketNumber(i)}, nil
                        },
@@ -2275,7 +2276,7 @@ func TestConnectionCongestionControl(t *testing.T) {
        done2 := make(chan struct{})
        sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAck)
        tc.packer.EXPECT().PackAckOnlyPacket(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+               func(protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
                        close(done2)
                        return shortHeaderPacket{}, nil, errNothingToPack
                },
@@ -2361,7 +2362,7 @@ func testConnectionSendQueue(t *testing.T, enableGSO bool) {
        sender.EXPECT().WouldBlock().AnyTimes()
        unblocked := make(chan struct{})
        tc.packer.EXPECT().AppendPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(*packetBuffer, protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, error) {
+               func(*packetBuffer, protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, error) {
                        close(unblocked)
                        return shortHeaderPacket{}, errNothingToPack
                },
@@ -2392,7 +2393,7 @@ func getVersionNegotiationPacket(src, dest protocol.ConnectionID, versions []pro
                versions,
        )
        return receivedPacket{
-               rcvTime: time.Now(),
+               rcvTime: monotime.Now(),
                data:    b,
                buffer:  getPacketBuffer(),
        }
@@ -2519,7 +2520,7 @@ func getRetryPacket(t *testing.T, src, dest, origDest protocol.ConnectionID, tok
        tag := handshake.GetRetryIntegrityTag(b, origDest, protocol.Version1)
        b = append(b, tag[:]...)
        return receivedPacket{
-               rcvTime: time.Now(),
+               rcvTime: monotime.Now(),
                data:    b,
                buffer:  getPacketBuffer(),
        }
@@ -2581,7 +2582,7 @@ func TestConnectionRetryAfterReceivedPacket(t *testing.T) {
        wasProcessed, err := tc.conn.handleOnePacket(receivedPacket{
                data:       regular,
                buffer:     getPacketBuffer(),
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
                remoteAddr: tc.remoteAddr,
        })
        require.NoError(t, err)
@@ -2684,7 +2685,7 @@ func testConnectionConnectionIDChanges(t *testing.T, sendRetry bool) {
                ),
        )
 
-       tc.conn.handlePacket(receivedPacket{data: makeInitialPacket(t, &hdr1), buffer: getPacketBuffer(), rcvTime: time.Now(), remoteAddr: tc.remoteAddr})
+       tc.conn.handlePacket(receivedPacket{data: makeInitialPacket(t, &hdr1), buffer: getPacketBuffer(), rcvTime: monotime.Now(), remoteAddr: tc.remoteAddr})
 
        select {
        case <-receivedFirst:
@@ -2701,7 +2702,7 @@ func testConnectionConnectionIDChanges(t *testing.T, sendRetry bool) {
                },
        )
 
-       tc.conn.handlePacket(receivedPacket{data: makeInitialPacket(t, &hdr2), buffer: getPacketBuffer(), rcvTime: time.Now(), remoteAddr: tc.remoteAddr})
+       tc.conn.handlePacket(receivedPacket{data: makeInitialPacket(t, &hdr2), buffer: getPacketBuffer(), rcvTime: monotime.Now(), remoteAddr: tc.remoteAddr})
        select {
        case <-dropped:
                // the connection ID should not have changed
@@ -2820,7 +2821,7 @@ func testConnectionPathValidation(t *testing.T, isNATRebinding bool) {
                data:       make([]byte, 10),
                buffer:     getPacketBuffer(),
                remoteAddr: newRemoteAddr,
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
        })
 
        select {
@@ -2863,7 +2864,7 @@ func testConnectionPathValidation(t *testing.T, isNATRebinding bool) {
                data:       make([]byte, 100),
                buffer:     getPacketBuffer(),
                remoteAddr: addr,
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
        })
 
        if !isNATRebinding {
@@ -2893,7 +2894,7 @@ func testConnectionPathValidation(t *testing.T, isNATRebinding bool) {
                        data:       make([]byte, 100),
                        buffer:     getPacketBuffer(),
                        remoteAddr: newRemoteAddr,
-                       rcvTime:    time.Now(),
+                       rcvTime:    monotime.Now(),
                })
        }
 
@@ -2967,7 +2968,7 @@ func testConnectionMigration(t *testing.T, enabled bool) {
        _, err = tc.conn.handleFrame(&wire.NewConnectionIDFrame{
                SequenceNumber: 1,
                ConnectionID:   protocol.ParseConnectionID([]byte{1, 2, 3, 4}),
-       }, protocol.EncryptionInitial, tc.destConnID, time.Now())
+       }, protocol.EncryptionInitial, tc.destConnID, monotime.Now())
        require.NoError(t, err)
        errChan := make(chan error, 1)
        go func() { errChan <- tc.conn.run() }()
@@ -3015,7 +3016,7 @@ func testConnectionDatagrams(t *testing.T, enabled bool) {
        require.NoError(t, err)
        data, err = (&wire.DatagramFrame{Data: []byte("bar")}).Append(data, protocol.Version1)
        require.NoError(t, err)
-       _, _, _, err = tc.conn.handleFrames(data, protocol.ConnectionID{}, protocol.Encryption1RTT, nil, time.Now())
+       _, _, _, err = tc.conn.handleFrames(data, protocol.ConnectionID{}, protocol.Encryption1RTT, nil, monotime.Now())
 
        if !enabled {
                require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.FrameEncodingError, FrameType: uint64(wire.FrameTypeDatagramWithLength)})
index 0fdc8cb8b979724f2ca01a2c5246aa7b0b614935..b7e5629767daaa193d86d4015a2069682061c6d8 100644 (file)
@@ -3,14 +3,15 @@ package quic
 import (
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/utils"
 )
 
-var deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine
+var deadlineSendImmediately = monotime.Time(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine
 
 type connectionTimer struct {
        timer *utils.Timer
-       last  time.Time
+       last  monotime.Time
 }
 
 func newTimer() *connectionTimer {
@@ -32,7 +33,7 @@ func (t *connectionTimer) Chan() <-chan time.Time {
 // It makes sure that the deadline is strictly increasing.
 // This prevents busy-looping in cases where the timer fires, but we can't actually send out a packet.
 // This doesn't apply to the pacing deadline, which can be set multiple times to deadlineSendImmediately.
-func (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, connIDRetirement, ackAlarm, lossTime, pacing time.Time) {
+func (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, connIDRetirement, ackAlarm, lossTime, pacing monotime.Time) {
        deadline := idleTimeoutOrKeepAlive
        if !connIDRetirement.IsZero() && connIDRetirement.Before(deadline) && connIDRetirement.After(t.last) {
                deadline = connIDRetirement
index 5f01b1bc2cf9e5e788064c6084021ef94f2bd591..1cf5fd9edcfd056181564812a3d4eb0e7757db5d 100644 (file)
@@ -4,52 +4,53 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/stretchr/testify/require"
 )
 
-func (t *connectionTimer) Deadline() time.Time { return t.timer.Deadline() }
+func (t *connectionTimer) Deadline() monotime.Time { return t.timer.Deadline() }
 
 func TestConnectionTimerModes(t *testing.T) {
-       now := time.Now()
+       now := monotime.Now()
 
        t.Run("idle timeout", func(t *testing.T) {
                timer := newTimer()
-               timer.SetTimer(now.Add(time.Hour), time.Time{}, time.Time{}, time.Time{}, time.Time{})
+               timer.SetTimer(now.Add(time.Hour), 0, 0, 0, 0)
                require.Equal(t, now.Add(time.Hour), timer.Deadline())
        })
 
        t.Run("connection ID expiry", func(t *testing.T) {
                timer := newTimer()
-               timer.SetTimer(now.Add(time.Hour), now.Add(time.Minute), time.Time{}, time.Time{}, time.Time{})
+               timer.SetTimer(now.Add(time.Hour), now.Add(time.Minute), 0, 0, 0)
                require.Equal(t, now.Add(time.Minute), timer.Deadline())
        })
 
        t.Run("ACK timer", func(t *testing.T) {
                timer := newTimer()
-               timer.SetTimer(now.Add(time.Hour), time.Time{}, now.Add(time.Minute), time.Time{}, time.Time{})
+               timer.SetTimer(now.Add(time.Hour), 0, now.Add(time.Minute), 0, 0)
                require.Equal(t, now.Add(time.Minute), timer.Deadline())
        })
 
        t.Run("loss timer", func(t *testing.T) {
                timer := newTimer()
-               timer.SetTimer(now.Add(time.Hour), time.Time{}, now.Add(time.Minute), now.Add(time.Second), time.Time{})
+               timer.SetTimer(now.Add(time.Hour), 0, now.Add(time.Minute), now.Add(time.Second), 0)
                require.Equal(t, now.Add(time.Second), timer.Deadline())
        })
 
        t.Run("pacing timer", func(t *testing.T) {
                timer := newTimer()
-               timer.SetTimer(now.Add(time.Hour), time.Time{}, now.Add(time.Minute), now.Add(time.Second), now.Add(time.Millisecond))
+               timer.SetTimer(now.Add(time.Hour), 0, now.Add(time.Minute), now.Add(time.Second), now.Add(time.Millisecond))
                require.Equal(t, now.Add(time.Millisecond), timer.Deadline())
        })
 }
 
 func TestConnectionTimerReset(t *testing.T) {
-       now := time.Now()
+       now := monotime.Now()
        timer := newTimer()
-       timer.SetTimer(now.Add(time.Hour), time.Time{}, now.Add(time.Minute), time.Time{}, time.Time{})
+       timer.SetTimer(now.Add(time.Hour), 0, now.Add(time.Minute), 0, 0)
        require.Equal(t, now.Add(time.Minute), timer.Deadline())
        timer.SetRead()
 
-       timer.SetTimer(now.Add(time.Hour), time.Time{}, now.Add(time.Minute), time.Time{}, time.Time{})
+       timer.SetTimer(now.Add(time.Hour), 0, now.Add(time.Minute), 0, 0)
        require.Equal(t, now.Add(time.Hour), timer.Deadline())
 }
index a331202d02ee12bb1c683943f7ccde795780b5c8..ca23f0aac0c9af72756d0ef98c86f3f11b956262 100644 (file)
--- a/framer.go
+++ b/framer.go
@@ -3,10 +3,10 @@ package quic
 import (
        "slices"
        "sync"
-       "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils/ringbuffer"
        "github.com/quic-go/quic-go/internal/wire"
@@ -27,7 +27,7 @@ type streamFrameGetter interface {
 }
 
 type streamControlFrameGetter interface {
-       getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool)
+       getControlFrame(monotime.Time) (_ ackhandler.Frame, ok, hasMore bool)
 }
 
 type framer struct {
@@ -90,7 +90,7 @@ func (f *framer) Append(
        frames []ackhandler.Frame,
        streamFrames []ackhandler.StreamFrame,
        maxLen protocol.ByteCount,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
        f.controlFrameMutex.Lock()
@@ -157,7 +157,7 @@ func (f *framer) Append(
 func (f *framer) appendControlFrames(
        frames []ackhandler.Frame,
        maxLen protocol.ByteCount,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) ([]ackhandler.Frame, protocol.ByteCount) {
        var length protocol.ByteCount
index 660d0f91c28414545221831c364ad5b0f7d9b45a..7af71a312082700c75fdd2f740b5f1f0619dc462 100644 (file)
@@ -5,10 +5,10 @@ import (
        "encoding/binary"
        "math/rand/v2"
        "testing"
-       "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 
@@ -29,7 +29,7 @@ func TestFramerControlFrames(t *testing.T) {
                []ackhandler.Frame{{Frame: &wire.PingFrame{}}},
                nil,
                protocol.MaxByteCount,
-               time.Now(),
+               monotime.Now(),
                protocol.Version1,
        )
        require.Len(t, frames, 3)
@@ -51,11 +51,11 @@ func TestFramerControlFrameSizing(t *testing.T) {
        for i := 0; i < numFrames+1; i++ {
                framer.QueueControlFrame(bf)
        }
-       frames, _, length := framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+       frames, _, length := framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
        require.Len(t, frames, numFrames)
        require.Greater(t, length, maxSize-bfLen)
        // now make sure that the last frame is also added
-       frames, _, length = framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+       frames, _, length = framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
        require.Len(t, frames, 1)
        require.Equal(t, length, bfLen)
 }
@@ -70,7 +70,7 @@ func TestFramerStreamControlFrames(t *testing.T) {
        framer.QueueControlFrame(ping)
        str := NewMockStreamControlFrameGetter(gomock.NewController(t))
        framer.AddStreamWithControlFrames(streamID, str)
-       now := time.Now()
+       now := monotime.Now()
        str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf1}, true, true)
        str.EXPECT().getControlFrame(now).Return(ackhandler.Frame{Frame: mdf2}, true, false)
        frames, streamFrames, l := framer.Append(nil, nil, protocol.MaxByteCount, now, protocol.Version1)
@@ -91,7 +91,7 @@ func TestFramerStreamControlFramesSizing(t *testing.T) {
        framer := newFramer(flowcontrol.NewConnectionFlowController(0, 0, nil, nil, nil))
        framer.AddStreamWithControlFrames(10, str)
        str.EXPECT().getControlFrame(gomock.Any()).Return(ackhandler.Frame{Frame: mdf1}, true, true).AnyTimes()
-       frames, _, l := framer.Append(nil, nil, 100, time.Now(), protocol.Version1)
+       frames, _, l := framer.Append(nil, nil, 100, monotime.Now(), protocol.Version1)
        require.Equal(t, protocol.ByteCount(len(frames))*mdf1.Length(protocol.Version1), l)
        require.Greater(t, l, protocol.ByteCount(100-maxStreamControlFrameSize))
        require.LessOrEqual(t, l, protocol.ByteCount(100))
@@ -135,7 +135,7 @@ func testFramerStreamDataBlocked(t *testing.T, fits bool) {
        )
 
        const maxSize protocol.ByteCount = 1000
-       frames, streamFrames, l := framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+       frames, streamFrames, l := framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
        require.Len(t, streamFrames, 1)
        dataLen := streamFrames[0].Frame.DataLen()
        if fits {
@@ -144,7 +144,7 @@ func testFramerStreamDataBlocked(t *testing.T, fits bool) {
        } else {
                require.Equal(t, streamFrames[0].Frame.Length(protocol.Version1), l)
                require.Empty(t, frames)
-               frames, streamFrames, l2 := framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+               frames, streamFrames, l2 := framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
                require.Greater(t, l+l2, maxSize)
                require.Empty(t, streamFrames)
                require.Len(t, frames, 1)
@@ -193,7 +193,7 @@ func testFramerDataBlocked(t *testing.T, fits bool) {
        )
 
        const maxSize protocol.ByteCount = 1000
-       frames, streamFrames, l := framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+       frames, streamFrames, l := framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
        require.Len(t, streamFrames, 1)
        if fits {
                require.Len(t, frames, 1)
@@ -201,7 +201,7 @@ func testFramerDataBlocked(t *testing.T, fits bool) {
        } else {
                require.Equal(t, streamFrames[0].Frame.Length(protocol.Version1), l)
                require.Empty(t, frames)
-               frames, streamFrames, l2 := framer.Append(nil, nil, maxSize, time.Now(), protocol.Version1)
+               frames, streamFrames, l2 := framer.Append(nil, nil, maxSize, monotime.Now(), protocol.Version1)
                require.Greater(t, l+l2, maxSize)
                require.Empty(t, streamFrames)
                require.Len(t, frames, 1)
@@ -215,7 +215,7 @@ func TestFramerDetectsFrameDoS(t *testing.T) {
                framer.QueueControlFrame(&wire.PingFrame{})
                framer.QueueControlFrame(&wire.PingFrame{})
                require.False(t, framer.QueuedTooManyControlFrames())
-               frames, _, _ := framer.Append([]ackhandler.Frame{}, nil, 1, time.Now(), protocol.Version1)
+               frames, _, _ := framer.Append([]ackhandler.Frame{}, nil, 1, monotime.Now(), protocol.Version1)
                require.Len(t, frames, 1)
                require.Len(t, framer.controlFrames, i+1)
        }
@@ -238,13 +238,13 @@ func TestFramerDetectsFramePathResponseDoS(t *testing.T) {
        }
        for i := 0; i < maxPathResponses; i++ {
                require.True(t, framer.HasData())
-               frames, _, length := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+               frames, _, length := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
                require.Len(t, frames, 1)
                require.Equal(t, pathResponses[i], frames[0].Frame)
                require.Equal(t, pathResponses[i].Length(protocol.Version1), length)
        }
        require.False(t, framer.HasData())
-       frames, _, length := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       frames, _, length := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, frames)
        require.Zero(t, length)
 }
@@ -260,14 +260,14 @@ func TestFramerPacksSinglePathResponsePerPacket(t *testing.T) {
        framer.QueueControlFrame(cf1)
        framer.QueueControlFrame(cf2)
        // the first packet should contain a single PATH_RESPONSE frame, but all the other control frames
-       frames, _, _ := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       frames, _, _ := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Len(t, frames, 3)
        require.Equal(t, f1, frames[0].Frame)
        require.Contains(t, []wire.Frame{frames[1].Frame, frames[2].Frame}, cf1)
        require.Contains(t, []wire.Frame{frames[1].Frame, frames[2].Frame}, cf2)
        // the second packet should contain the other PATH_RESPONSE frame
        require.True(t, framer.HasData())
-       frames, _, _ = framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       frames, _, _ = framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Len(t, frames, 1)
        require.Equal(t, f2, frames[0].Frame)
        require.False(t, framer.HasData())
@@ -285,7 +285,7 @@ func TestFramerAppendStreamFrames(t *testing.T) {
        framer := newFramer(flowcontrol.NewConnectionFlowController(0, 0, nil, nil, nil))
        require.False(t, framer.HasData())
        // no frames added yet
-       controlFrames, fs, length := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       controlFrames, fs, length := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, controlFrames)
        require.Empty(t, fs)
        require.Zero(t, length)
@@ -304,7 +304,7 @@ func TestFramerAppendStreamFrames(t *testing.T) {
        // Even though the first stream claimed to have more data,
        // we only dequeue a single STREAM frame per call of AppendStreamFrames.
        f0 := ackhandler.StreamFrame{Frame: &wire.StreamFrame{StreamID: 9999}}
-       controlFrames, fs, length = framer.Append([]ackhandler.Frame{}, []ackhandler.StreamFrame{f0}, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       controlFrames, fs, length = framer.Append([]ackhandler.Frame{}, []ackhandler.StreamFrame{f0}, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, controlFrames)
        require.Len(t, fs, 3)
        require.Equal(t, f0, fs[0])
@@ -322,7 +322,7 @@ func TestFramerAppendStreamFrames(t *testing.T) {
 
        // ... but it actually doesn't
        str1.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{}, nil, false)
-       _, fs, length = framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       _, fs, length = framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, fs)
        require.Zero(t, length)
        require.False(t, framer.HasData())
@@ -336,7 +336,7 @@ func TestFramerRemoveActiveStream(t *testing.T) {
        require.True(t, framer.HasData())
        framer.RemoveActiveStream(id) // no calls will be issued to the mock stream
        // we can't assert on framer.HasData here, since it's not removed from the ringbuffer
-       _, frames, _ := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       _, frames, _ := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, frames)
        require.False(t, framer.HasData())
 }
@@ -349,7 +349,7 @@ func TestFramerMinStreamFrameSize(t *testing.T) {
 
        require.True(t, framer.HasData())
        // don't pop frames smaller than the minimum STREAM frame size
-       _, frames, _ := framer.Append(nil, nil, protocol.MinStreamFrameSize-1, time.Now(), protocol.Version1)
+       _, frames, _ := framer.Append(nil, nil, protocol.MinStreamFrameSize-1, monotime.Now(), protocol.Version1)
        require.Empty(t, frames)
 
        // pop frames of the minimum size
@@ -360,7 +360,7 @@ func TestFramerMinStreamFrameSize(t *testing.T) {
                        return ackhandler.StreamFrame{Frame: f}, nil, false
                },
        )
-       _, frames, _ = framer.Append(nil, nil, protocol.MinStreamFrameSize, time.Now(), protocol.Version1)
+       _, frames, _ = framer.Append(nil, nil, protocol.MinStreamFrameSize, monotime.Now(), protocol.Version1)
        require.Len(t, frames, 1)
        // unsetting DataLenPresent on the last frame reduced the size slightly beyond the minimum size
        require.Equal(t, protocol.MinStreamFrameSize-2, frames[0].Frame.Length(protocol.Version1))
@@ -380,7 +380,7 @@ func TestFramerMinStreamFrameSizeMultipleStreamFrames(t *testing.T) {
        }
        str.EXPECT().popStreamFrame(gomock.Any(), protocol.Version1).Return(ackhandler.StreamFrame{Frame: f}, nil, false)
        framer.AddActiveStream(id, str)
-       _, fs, length := framer.Append(nil, nil, 500, time.Now(), protocol.Version1)
+       _, fs, length := framer.Append(nil, nil, 500, monotime.Now(), protocol.Version1)
        require.Len(t, fs, 1)
        require.Equal(t, f, fs[0].Frame)
        require.Equal(t, f.Length(protocol.Version1), length)
@@ -404,7 +404,7 @@ func TestFramerFillPacketOneStream(t *testing.T) {
                        },
                )
                framer.AddActiveStream(id, str)
-               _, frames, _ := framer.Append(nil, nil, i, time.Now(), protocol.Version1)
+               _, frames, _ := framer.Append(nil, nil, i, monotime.Now(), protocol.Version1)
                require.Len(t, frames, 1)
                require.False(t, frames[0].Frame.DataLenPresent)
                // make sure the entire space was filled up
@@ -440,7 +440,7 @@ func TestFramerFillPacketMultipleStreams(t *testing.T) {
                )
                framer.AddActiveStream(id1, stream1)
                framer.AddActiveStream(id2, stream2)
-               _, frames, _ := framer.Append(nil, nil, i, time.Now(), protocol.Version1)
+               _, frames, _ := framer.Append(nil, nil, i, monotime.Now(), protocol.Version1)
                require.Len(t, frames, 2)
                require.True(t, frames[0].Frame.DataLenPresent)
                require.False(t, frames[1].Frame.DataLenPresent)
@@ -467,7 +467,7 @@ func TestFramer0RTTRejection(t *testing.T) {
        framer.AddActiveStream(10, NewMockStreamFrameGetter(gomock.NewController(t)))
 
        framer.Handle0RTTRejection()
-       controlFrames, streamFrames, _ := framer.Append(nil, nil, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       controlFrames, streamFrames, _ := framer.Append(nil, nil, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.Empty(t, streamFrames)
        require.Len(t, controlFrames, 3)
        require.Contains(t, controlFrames, ackhandler.Frame{Frame: pc})
index 27635c197f5aa94a89bf61e87a9eeaf5b456a92f..659eb58d591b109fd93b6fd73c3326fca6eebb0e 100644 (file)
@@ -13,7 +13,6 @@ import (
        "math"
        mrand "math/rand/v2"
        "net"
-       "time"
 
        "github.com/quic-go/quic-go/fuzzing/internal/helper"
        "github.com/quic-go/quic-go/internal/handshake"
@@ -391,7 +390,7 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls.
        }
        const msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        encrypted := sealer.Seal(nil, []byte(msg), 1337, []byte("foobar"))
-       decrypted, err := opener.Open(nil, encrypted, time.Time{}, 1337, protocol.KeyPhaseZero, []byte("foobar"))
+       decrypted, err := opener.Open(nil, encrypted, 0, 1337, protocol.KeyPhaseZero, []byte("foobar"))
        if err != nil {
                panic(fmt.Sprintf("Decrypting message failed: %s", err.Error()))
        }
index be3176e31ae2f52d9df3e1ff2ec9cb3cf6083fc9..18df026b11ecc52e9a1611241cc1125519c7da2e 100644 (file)
@@ -9,6 +9,7 @@ import (
        "sync"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
 )
@@ -27,7 +28,7 @@ type connection struct {
        Outgoing *queue
 }
 
-func (c *connection) queuePacket(t time.Time, b []byte) {
+func (c *connection) queuePacket(t monotime.Time, b []byte) {
        c.incomingPackets <- packetEntry{Time: t, Raw: b}
 }
 
@@ -60,7 +61,7 @@ const (
 )
 
 type packetEntry struct {
-       Time time.Time
+       Time monotime.Time
        Raw  []byte
 }
 
@@ -286,7 +287,7 @@ func (p *Proxy) runProxy() error {
                                return err
                        }
                } else {
-                       now := time.Now()
+                       now := monotime.Now()
                        if p.logger.Debug() {
                                p.logger.Debugf("delaying incoming packet (%d bytes) to %s by %s", len(raw), conn.ServerAddr, delay)
                        }
@@ -331,7 +332,7 @@ func (p *Proxy) runOutgoingConnection(conn *connection) error {
                                        return
                                }
                        } else {
-                               now := time.Now()
+                               now := monotime.Now()
                                if p.logger.Debug() {
                                        p.logger.Debugf("delaying outgoing packet (%d bytes) to %s by %s", len(raw), conn.ClientAddr, delay)
                                }
index 4211512ef6b1be4abf9961d8c4edd1d4ab7ad55c..bb757ea0e6e1d1451e9f7a91aaf625f630796955 100644 (file)
@@ -7,6 +7,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 
@@ -25,7 +26,7 @@ func TestPacketQueue(t *testing.T) {
        }
 
        require.Empty(t, getPackets())
-       now := time.Now()
+       now := monotime.Now()
 
        q.Add(packetEntry{Time: now, Raw: []byte("p3")})
        require.Equal(t, []string{"p3"}, getPackets())
index 5fcce44d2e9dd79c1147db00459f6b282f7ff106..9ee9da7d9989e9c5b544928d49c286323c2c0563 100644 (file)
@@ -1,8 +1,7 @@
 package ackhandler
 
 import (
-       "time"
-
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 )
@@ -10,19 +9,19 @@ import (
 // SentPacketHandler handles ACKs received for outgoing packets
 type SentPacketHandler interface {
        // SentPacket may modify the packet
-       SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool)
+       SentPacket(t monotime.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool)
        // ReceivedAck processes an ACK frame.
        // It does not store a copy of the frame.
-       ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* 1-RTT packet acked */, error)
-       ReceivedBytes(_ protocol.ByteCount, rcvTime time.Time)
-       DropPackets(_ protocol.EncryptionLevel, rcvTime time.Time)
-       ResetForRetry(rcvTime time.Time)
+       ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) (bool /* 1-RTT packet acked */, error)
+       ReceivedBytes(_ protocol.ByteCount, rcvTime monotime.Time)
+       DropPackets(_ protocol.EncryptionLevel, rcvTime monotime.Time)
+       ResetForRetry(rcvTime monotime.Time)
 
        // The SendMode determines if and what kind of packets can be sent.
-       SendMode(now time.Time) SendMode
+       SendMode(now monotime.Time) SendMode
        // TimeUntilSend is the time when the next packet should be sent.
        // It is used for pacing packets.
-       TimeUntilSend() time.Time
+       TimeUntilSend() monotime.Time
        SetMaxDatagramSize(count protocol.ByteCount)
 
        // only to be called once the handshake is complete
@@ -32,23 +31,23 @@ type SentPacketHandler interface {
        PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)
        PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber
 
-       GetLossDetectionTimeout() time.Time
-       OnLossDetectionTimeout(now time.Time) error
+       GetLossDetectionTimeout() monotime.Time
+       OnLossDetectionTimeout(now monotime.Time) error
 
-       MigratedPath(now time.Time, initialMaxPacketSize protocol.ByteCount)
+       MigratedPath(now monotime.Time, initialMaxPacketSize protocol.ByteCount)
 }
 
 type sentPacketTracker interface {
        GetLowestPacketNotConfirmedAcked() protocol.PacketNumber
-       ReceivedPacket(_ protocol.EncryptionLevel, rcvTime time.Time)
+       ReceivedPacket(_ protocol.EncryptionLevel, rcvTime monotime.Time)
 }
 
 // ReceivedPacketHandler handles ACKs needed to send for incoming packets
 type ReceivedPacketHandler interface {
        IsPotentiallyDuplicate(protocol.PacketNumber, protocol.EncryptionLevel) bool
-       ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error
+       ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime monotime.Time, ackEliciting bool) error
        DropPackets(protocol.EncryptionLevel)
 
-       GetAlarmTimeout() time.Time
-       GetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame
+       GetAlarmTimeout() monotime.Time
+       GetAckFrame(_ protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame
 }
index 644046c52b21d021bacd1ba0c2dda26b0788c590..2b2c46660fe4e70867ed10ced7b64b083acf7f97 100644 (file)
@@ -11,8 +11,8 @@ package ackhandler
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -80,7 +80,7 @@ func (c *MockSentPacketTrackerGetLowestPacketNotConfirmedAckedCall) DoAndReturn(
 }
 
 // ReceivedPacket mocks base method.
-func (m *MockSentPacketTracker) ReceivedPacket(arg0 protocol.EncryptionLevel, rcvTime time.Time) {
+func (m *MockSentPacketTracker) ReceivedPacket(arg0 protocol.EncryptionLevel, rcvTime monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "ReceivedPacket", arg0, rcvTime)
 }
@@ -104,13 +104,13 @@ func (c *MockSentPacketTrackerReceivedPacketCall) Return() *MockSentPacketTracke
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketTrackerReceivedPacketCall) Do(f func(protocol.EncryptionLevel, time.Time)) *MockSentPacketTrackerReceivedPacketCall {
+func (c *MockSentPacketTrackerReceivedPacketCall) Do(f func(protocol.EncryptionLevel, monotime.Time)) *MockSentPacketTrackerReceivedPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketTrackerReceivedPacketCall) DoAndReturn(f func(protocol.EncryptionLevel, time.Time)) *MockSentPacketTrackerReceivedPacketCall {
+func (c *MockSentPacketTrackerReceivedPacketCall) DoAndReturn(f func(protocol.EncryptionLevel, monotime.Time)) *MockSentPacketTrackerReceivedPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 1677d4fbc94b22688fe8441f6126d18b8d311afa..f0500e9f2d1b6b8ba3b3d43b2d59e55ff8468243 100644 (file)
@@ -2,8 +2,8 @@ package ackhandler
 
 import (
        "sync"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 )
 
@@ -14,7 +14,7 @@ type packetWithPacketNumber struct {
 
 // A Packet is a packet
 type packet struct {
-       SendTime        time.Time
+       SendTime        monotime.Time
        StreamFrames    []StreamFrame
        Frames          []Frame
        LargestAcked    protocol.PacketNumber // InvalidPacketNumber if the packet doesn't contain an ACK
@@ -41,7 +41,7 @@ func getPacket() *packet {
        p.LargestAcked = 0
        p.Length = 0
        p.EncryptionLevel = protocol.EncryptionLevel(0)
-       p.SendTime = time.Time{}
+       p.SendTime = 0
        p.IsPathMTUProbePacket = false
        p.includedInBytesInFlight = false
        p.declaredLost = false
index 0076b3903a98d60f68d485e87a02357c9b3f7981..7180db85f10767f74537403ca5d2984f4e5d441f 100644 (file)
@@ -2,8 +2,8 @@ package ackhandler
 
 import (
        "fmt"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -35,7 +35,7 @@ func (h *receivedPacketHandler) ReceivedPacket(
        pn protocol.PacketNumber,
        ecn protocol.ECN,
        encLevel protocol.EncryptionLevel,
-       rcvTime time.Time,
+       rcvTime monotime.Time,
        ackEliciting bool,
 ) error {
        h.sentPackets.ReceivedPacket(encLevel, rcvTime)
@@ -83,11 +83,11 @@ func (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
        }
 }
 
-func (h *receivedPacketHandler) GetAlarmTimeout() time.Time {
+func (h *receivedPacketHandler) GetAlarmTimeout() monotime.Time {
        return h.appDataPackets.GetAlarmTimeout()
 }
 
-func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame {
+func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame {
        //nolint:exhaustive // 0-RTT packets can't contain ACK frames.
        switch encLevel {
        case protocol.EncryptionInitial:
index dab478a82283a13e1035953e3fa36aa1b8159c54..bfe7d19530614bad763de5f08798abc535e49282 100644 (file)
@@ -4,6 +4,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -17,7 +18,7 @@ func TestGenerateACKsForPacketNumberSpaces(t *testing.T) {
        sentPackets := NewMockSentPacketTracker(ctrl)
        handler := newReceivedPacketHandler(sentPackets, utils.DefaultLogger)
 
-       now := time.Now()
+       now := monotime.Now()
        sendTime := now.Add(-time.Second)
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().AnyTimes()
        sentPackets.EXPECT().ReceivedPacket(protocol.EncryptionInitial, sendTime).Times(2)
@@ -64,7 +65,7 @@ func TestReceive0RTTAnd1RTT(t *testing.T) {
        sentPackets := NewMockSentPacketTracker(mockCtrl)
        handler := newReceivedPacketHandler(sentPackets, utils.DefaultLogger)
 
-       sendTime := time.Now().Add(-time.Second)
+       sendTime := monotime.Now().Add(-time.Second)
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().AnyTimes()
        sentPackets.EXPECT().ReceivedPacket(protocol.Encryption0RTT, sendTime).AnyTimes()
        sentPackets.EXPECT().ReceivedPacket(protocol.Encryption1RTT, sendTime)
@@ -72,7 +73,7 @@ func TestReceive0RTTAnd1RTT(t *testing.T) {
        require.NoError(t, handler.ReceivedPacket(2, protocol.ECNNon, protocol.Encryption0RTT, sendTime, true))
        require.NoError(t, handler.ReceivedPacket(3, protocol.ECNNon, protocol.Encryption1RTT, sendTime, true))
 
-       ack := handler.GetAckFrame(protocol.Encryption1RTT, time.Now(), true)
+       ack := handler.GetAckFrame(protocol.Encryption1RTT, monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, []wire.AckRange{{Smallest: 2, Largest: 3}}, ack.AckRanges)
 
@@ -89,24 +90,24 @@ func TestDropPackets(t *testing.T) {
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().AnyTimes()
        handler := newReceivedPacketHandler(sentPackets, utils.DefaultLogger)
 
-       sendTime := time.Now().Add(-time.Second)
+       sendTime := monotime.Now().Add(-time.Second)
 
        require.NoError(t, handler.ReceivedPacket(2, protocol.ECNNon, protocol.EncryptionInitial, sendTime, true))
        require.NoError(t, handler.ReceivedPacket(1, protocol.ECNNon, protocol.EncryptionHandshake, sendTime, true))
        require.NoError(t, handler.ReceivedPacket(2, protocol.ECNNon, protocol.Encryption1RTT, sendTime, true))
 
        // Initial
-       require.NotNil(t, handler.GetAckFrame(protocol.EncryptionInitial, time.Now(), true))
+       require.NotNil(t, handler.GetAckFrame(protocol.EncryptionInitial, monotime.Now(), true))
        handler.DropPackets(protocol.EncryptionInitial)
-       require.Nil(t, handler.GetAckFrame(protocol.EncryptionInitial, time.Now(), true))
+       require.Nil(t, handler.GetAckFrame(protocol.EncryptionInitial, monotime.Now(), true))
 
        // Handshake
-       require.NotNil(t, handler.GetAckFrame(protocol.EncryptionHandshake, time.Now(), true))
+       require.NotNil(t, handler.GetAckFrame(protocol.EncryptionHandshake, monotime.Now(), true))
        handler.DropPackets(protocol.EncryptionHandshake)
-       require.Nil(t, handler.GetAckFrame(protocol.EncryptionHandshake, time.Now(), true))
+       require.Nil(t, handler.GetAckFrame(protocol.EncryptionHandshake, monotime.Now(), true))
 
        // 1-RTT
-       require.NotNil(t, handler.GetAckFrame(protocol.Encryption1RTT, time.Now(), true))
+       require.NotNil(t, handler.GetAckFrame(protocol.Encryption1RTT, monotime.Now(), true))
 
        // 0-RTT is a no-op
        handler.DropPackets(protocol.Encryption0RTT)
@@ -119,11 +120,11 @@ func TestAckRangePruning(t *testing.T) {
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().Times(3)
        handler := newReceivedPacketHandler(sentPackets, utils.DefaultLogger)
 
-       sendTime := time.Now()
+       sendTime := monotime.Now()
        require.NoError(t, handler.ReceivedPacket(1, protocol.ECNNon, protocol.Encryption1RTT, sendTime, true))
        require.NoError(t, handler.ReceivedPacket(2, protocol.ECNNon, protocol.Encryption1RTT, sendTime, true))
 
-       ack := handler.GetAckFrame(protocol.Encryption1RTT, time.Now(), true)
+       ack := handler.GetAckFrame(protocol.Encryption1RTT, monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, []wire.AckRange{{Smallest: 1, Largest: 2}}, ack.AckRanges)
 
@@ -131,7 +132,7 @@ func TestAckRangePruning(t *testing.T) {
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().Return(protocol.PacketNumber(2))
        require.NoError(t, handler.ReceivedPacket(4, protocol.ECNNon, protocol.Encryption1RTT, sendTime, true))
 
-       ack = handler.GetAckFrame(protocol.Encryption1RTT, time.Now(), true)
+       ack = handler.GetAckFrame(protocol.Encryption1RTT, monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, []wire.AckRange{{Smallest: 2, Largest: 4}}, ack.AckRanges)
 }
@@ -143,7 +144,7 @@ func TestPacketDuplicateDetection(t *testing.T) {
        sentPackets.EXPECT().GetLowestPacketNotConfirmedAcked().AnyTimes()
 
        handler := newReceivedPacketHandler(sentPackets, utils.DefaultLogger)
-       sendTime := time.Now()
+       sendTime := monotime.Now()
 
        // 1-RTT is tested separately at the end
        encLevels := []protocol.EncryptionLevel{
index c16400063e0fe21a90e343d52657423c4c8b6916..80f154ba86a00506c6e4c0efeb41ac9cd10db6d9 100644 (file)
@@ -4,6 +4,7 @@ import (
        "fmt"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -82,7 +83,7 @@ const packetsBeforeAck = 2
 type appDataReceivedPacketTracker struct {
        receivedPacketTracker
 
-       largestObservedRcvdTime time.Time
+       largestObservedRcvdTime monotime.Time
 
        largestObserved protocol.PacketNumber
        ignoreBelow     protocol.PacketNumber
@@ -91,7 +92,7 @@ type appDataReceivedPacketTracker struct {
        ackQueued   bool // true if we need send a new ACK
 
        ackElicitingPacketsReceivedSinceLastAck int
-       ackAlarm                                time.Time
+       ackAlarm                                monotime.Time
 
        logger utils.Logger
 }
@@ -105,7 +106,7 @@ func newAppDataReceivedPacketTracker(logger utils.Logger) *appDataReceivedPacket
        return h
 }
 
-func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error {
+func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime monotime.Time, ackEliciting bool) error {
        if err := h.receivedPacketTracker.ReceivedPacket(pn, ecn, ackEliciting); err != nil {
                return err
        }
@@ -120,7 +121,7 @@ func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber,
        isMissing := h.isMissing(pn)
        if !h.ackQueued && h.shouldQueueACK(pn, ecn, isMissing) {
                h.ackQueued = true
-               h.ackAlarm = time.Time{} // cancel the ack alarm
+               h.ackAlarm = 0 // cancel the ack alarm
        }
        if !h.ackQueued {
                // No ACK queued, but we'll need to acknowledge the packet after max_ack_delay.
@@ -207,7 +208,7 @@ func (h *appDataReceivedPacketTracker) shouldQueueACK(pn protocol.PacketNumber,
        return false
 }
 
-func (h *appDataReceivedPacketTracker) GetAckFrame(now time.Time, onlyIfQueued bool) *wire.AckFrame {
+func (h *appDataReceivedPacketTracker) GetAckFrame(now monotime.Time, onlyIfQueued bool) *wire.AckFrame {
        if onlyIfQueued && !h.ackQueued {
                if h.ackAlarm.IsZero() || h.ackAlarm.After(now) {
                        return nil
@@ -222,9 +223,9 @@ func (h *appDataReceivedPacketTracker) GetAckFrame(now time.Time, onlyIfQueued b
        }
        ack.DelayTime = max(0, now.Sub(h.largestObservedRcvdTime))
        h.ackQueued = false
-       h.ackAlarm = time.Time{}
+       h.ackAlarm = 0
        h.ackElicitingPacketsReceivedSinceLastAck = 0
        return ack
 }
 
-func (h *appDataReceivedPacketTracker) GetAlarmTimeout() time.Time { return h.ackAlarm }
+func (h *appDataReceivedPacketTracker) GetAlarmTimeout() monotime.Time { return h.ackAlarm }
index ddda9d4397dd520fa80021f762a399ecc91cdba7..76fc4751374cc48e5c6fe42c5dd602b6ba11b255 100644 (file)
@@ -4,6 +4,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -52,17 +53,17 @@ func TestReceivedPacketTrackerGenerateACKs(t *testing.T) {
 func TestAppDataReceivedPacketTrackerECN(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
 
-       require.NoError(t, tr.ReceivedPacket(0, protocol.ECT0, time.Now(), true))
+       require.NoError(t, tr.ReceivedPacket(0, protocol.ECT0, monotime.Now(), true))
        pn := protocol.PacketNumber(1)
        for range 2 {
-               require.NoError(t, tr.ReceivedPacket(pn, protocol.ECT1, time.Now(), true))
+               require.NoError(t, tr.ReceivedPacket(pn, protocol.ECT1, monotime.Now(), true))
                pn++
        }
        for range 3 {
-               require.NoError(t, tr.ReceivedPacket(pn, protocol.ECNCE, time.Now(), true))
+               require.NoError(t, tr.ReceivedPacket(pn, protocol.ECNCE, monotime.Now(), true))
                pn++
        }
-       ack := tr.GetAckFrame(time.Now(), false)
+       ack := tr.GetAckFrame(monotime.Now(), false)
        require.Equal(t, uint64(1), ack.ECT0)
        require.Equal(t, uint64(2), ack.ECT1)
        require.Equal(t, uint64(3), ack.ECNCE)
@@ -71,15 +72,15 @@ func TestAppDataReceivedPacketTrackerECN(t *testing.T) {
 func TestAppDataReceivedPacketTrackerAckEverySecondPacket(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
        // the first packet is always acknowledged
-       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, time.Now(), true))
-       require.NotNil(t, tr.GetAckFrame(time.Now(), true))
+       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, monotime.Now(), true))
+       require.NotNil(t, tr.GetAckFrame(monotime.Now(), true))
        for p := protocol.PacketNumber(1); p <= 20; p++ {
-               require.NoError(t, tr.ReceivedPacket(p, protocol.ECNNon, time.Now(), true))
+               require.NoError(t, tr.ReceivedPacket(p, protocol.ECNNon, monotime.Now(), true))
                switch p % 2 {
                case 0:
-                       require.NotNil(t, tr.GetAckFrame(time.Now(), true))
+                       require.NotNil(t, tr.GetAckFrame(monotime.Now(), true))
                case 1:
-                       require.Nil(t, tr.GetAckFrame(time.Now(), true))
+                       require.Nil(t, tr.GetAckFrame(monotime.Now(), true))
                }
        }
 }
@@ -88,21 +89,21 @@ func TestAppDataReceivedPacketTrackerAlarmTimeout(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
 
        // the first packet is always acknowledged
-       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, time.Now(), true))
-       require.NotNil(t, tr.GetAckFrame(time.Now(), true))
+       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, monotime.Now(), true))
+       require.NotNil(t, tr.GetAckFrame(monotime.Now(), true))
 
-       now := time.Now()
+       now := monotime.Now()
        require.NoError(t, tr.ReceivedPacket(1, protocol.ECNNon, now, false))
-       require.Nil(t, tr.GetAckFrame(time.Now(), true))
+       require.Nil(t, tr.GetAckFrame(monotime.Now(), true))
        require.Zero(t, tr.GetAlarmTimeout())
 
        rcvTime := now.Add(10 * time.Millisecond)
        require.NoError(t, tr.ReceivedPacket(2, protocol.ECNNon, rcvTime, true))
        require.Equal(t, rcvTime.Add(protocol.MaxAckDelay), tr.GetAlarmTimeout())
-       require.Nil(t, tr.GetAckFrame(time.Now(), true))
+       require.Nil(t, tr.GetAckFrame(monotime.Now(), true))
 
        // no timeout after the ACK has been dequeued
-       require.NotNil(t, tr.GetAckFrame(time.Now(), false))
+       require.NotNil(t, tr.GetAckFrame(monotime.Now(), false))
        require.Zero(t, tr.GetAlarmTimeout())
 }
 
@@ -110,11 +111,11 @@ func TestAppDataReceivedPacketTrackerQueuesECNCE(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
 
        // the first packet is always acknowledged
-       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, time.Now(), true))
-       require.NotNil(t, tr.GetAckFrame(time.Now(), true))
+       require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, monotime.Now(), true))
+       require.NotNil(t, tr.GetAckFrame(monotime.Now(), true))
 
-       require.NoError(t, tr.ReceivedPacket(1, protocol.ECNCE, time.Now(), true))
-       ack := tr.GetAckFrame(time.Now(), true)
+       require.NoError(t, tr.ReceivedPacket(1, protocol.ECNCE, monotime.Now(), true))
+       ack := tr.GetAckFrame(monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, protocol.PacketNumber(1), ack.LargestAcked())
        require.EqualValues(t, 1, ack.ECNCE)
@@ -123,7 +124,7 @@ func TestAppDataReceivedPacketTrackerQueuesECNCE(t *testing.T) {
 func TestAppDataReceivedPacketTrackerMissingPackets(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
 
-       now := time.Now()
+       now := monotime.Now()
        // the first packet is always acknowledged
        require.NoError(t, tr.ReceivedPacket(0, protocol.ECNNon, now, true))
        require.NotNil(t, tr.GetAckFrame(now, true))
@@ -152,7 +153,7 @@ func TestAppDataReceivedPacketTrackerMissingPackets(t *testing.T) {
 func TestAppDataReceivedPacketTrackerDelayTime(t *testing.T) {
        tr := newAppDataReceivedPacketTracker(utils.DefaultLogger)
 
-       now := time.Now()
+       now := monotime.Now()
        require.NoError(t, tr.ReceivedPacket(1, protocol.ECNNon, now, true))
        require.NoError(t, tr.ReceivedPacket(2, protocol.ECNNon, now.Add(-1337*time.Millisecond), true))
        ack := tr.GetAckFrame(now, true)
@@ -175,23 +176,23 @@ func TestAppDataReceivedPacketTrackerIgnoreBelow(t *testing.T) {
        require.False(t, tr.IsPotentiallyDuplicate(4))
 
        for i := 5; i <= 10; i++ {
-               require.NoError(t, tr.ReceivedPacket(protocol.PacketNumber(i), protocol.ECNNon, time.Now(), true))
+               require.NoError(t, tr.ReceivedPacket(protocol.PacketNumber(i), protocol.ECNNon, monotime.Now(), true))
        }
-       ack := tr.GetAckFrame(time.Now(), true)
+       ack := tr.GetAckFrame(monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, []wire.AckRange{{Smallest: 5, Largest: 10}}, ack.AckRanges)
 
        tr.IgnoreBelow(7)
 
-       require.NoError(t, tr.ReceivedPacket(11, protocol.ECNNon, time.Now(), true))
-       require.NoError(t, tr.ReceivedPacket(12, protocol.ECNNon, time.Now(), true))
-       ack = tr.GetAckFrame(time.Now(), true)
+       require.NoError(t, tr.ReceivedPacket(11, protocol.ECNNon, monotime.Now(), true))
+       require.NoError(t, tr.ReceivedPacket(12, protocol.ECNNon, monotime.Now(), true))
+       ack = tr.GetAckFrame(monotime.Now(), true)
        require.NotNil(t, ack)
        require.Equal(t, []wire.AckRange{{Smallest: 7, Largest: 12}}, ack.AckRanges)
 
        // make sure that old packets are not accepted
        require.ErrorContains(t,
-               tr.ReceivedPacket(4, protocol.ECNNon, time.Now(), true),
+               tr.ReceivedPacket(4, protocol.ECNNon, monotime.Now(), true),
                "receivedPacketTracker BUG: ReceivedPacket called for old / duplicate packet 4",
        )
 }
index b4a113e310c8bb10228963a37259a93c86f15d19..bf9ff0f962c4b48a07130705119c56b95b496584 100644 (file)
@@ -6,6 +6,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/congestion"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -34,8 +35,8 @@ type packetNumberSpace struct {
        history sentPacketHistory
        pns     packetNumberGenerator
 
-       lossTime                   time.Time
-       lastAckElicitingPacketTime time.Time
+       lossTime                   monotime.Time
+       lastAckElicitingPacketTime monotime.Time
 
        largestAcked protocol.PacketNumber
        largestSent  protocol.PacketNumber
@@ -57,7 +58,7 @@ func newPacketNumberSpace(initialPN protocol.PacketNumber, isAppData bool) *pack
 }
 
 type alarmTimer struct {
-       Time            time.Time
+       Time            monotime.Time
        TimerType       logging.TimerType
        EncryptionLevel protocol.EncryptionLevel
 }
@@ -168,7 +169,7 @@ func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) {
        }
 }
 
-func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now time.Time) {
+func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now monotime.Time) {
        // The server won't await address validation after the handshake is confirmed.
        // This applies even if we didn't receive an ACK for a Handshake packet.
        if h.perspective == protocol.PerspectiveClient && encLevel == protocol.EncryptionHandshake {
@@ -219,7 +220,7 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now t
        h.setLossDetectionTimer(now)
 }
 
-func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t time.Time) {
+func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t monotime.Time) {
        h.connStats.BytesReceived.Add(uint64(n))
        wasAmplificationLimit := h.isAmplificationLimited()
        h.bytesReceived += n
@@ -228,7 +229,7 @@ func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t time.Time) {
        }
 }
 
-func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t time.Time) {
+func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t monotime.Time) {
        h.connStats.PacketsReceived.Add(1)
        if h.perspective == protocol.PerspectiveServer && l == protocol.EncryptionHandshake && !h.peerAddressValidated {
                h.peerAddressValidated = true
@@ -248,7 +249,7 @@ func (h *sentPacketHandler) packetsInFlight() int {
 }
 
 func (h *sentPacketHandler) SentPacket(
-       t time.Time,
+       t monotime.Time,
        pn, largestAcked protocol.PacketNumber,
        streamFrames []StreamFrame,
        frames []Frame,
@@ -334,7 +335,7 @@ func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLev
        }
 }
 
-func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* contained 1-RTT packet */, error) {
+func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) (bool /* contained 1-RTT packet */, error) {
        pnSpace := h.getPacketNumberSpace(encLevel)
 
        largestAcked := ack.LargestAcked()
@@ -518,9 +519,9 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL
        return h.ackedPackets, nil
 }
 
-func (h *sentPacketHandler) getLossTimeAndSpace() (time.Time, protocol.EncryptionLevel) {
+func (h *sentPacketHandler) getLossTimeAndSpace() (monotime.Time, protocol.EncryptionLevel) {
        var encLevel protocol.EncryptionLevel
-       var lossTime time.Time
+       var lossTime monotime.Time
 
        if h.initialPackets != nil {
                lossTime = h.initialPackets.lossTime
@@ -546,7 +547,7 @@ func (h *sentPacketHandler) getScaledPTO(includeMaxAckDelay bool) time.Duration
 }
 
 // same logic as getLossTimeAndSpace, but for lastAckElicitingPacketTime instead of lossTime
-func (h *sentPacketHandler) getPTOTimeAndSpace(now time.Time) (pto time.Time, encLevel protocol.EncryptionLevel) {
+func (h *sentPacketHandler) getPTOTimeAndSpace(now monotime.Time) (pto monotime.Time, encLevel protocol.EncryptionLevel) {
        // We only send application data probe packets once the handshake is confirmed,
        // because before that, we don't have the keys to decrypt ACKs sent in 1-RTT packets.
        if !h.handshakeConfirmed && !h.hasOutstandingCryptoPackets() {
@@ -596,7 +597,7 @@ func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool {
        return false
 }
 
-func (h *sentPacketHandler) setLossDetectionTimer(now time.Time) {
+func (h *sentPacketHandler) setLossDetectionTimer(now monotime.Time) {
        oldAlarm := h.alarm // only needed in case tracing is enabled
        newAlarm := h.lossDetectionTime(now)
        h.alarm = newAlarm
@@ -610,11 +611,11 @@ func (h *sentPacketHandler) setLossDetectionTimer(now time.Time) {
        }
 
        if hasAlarm && h.tracer != nil && h.tracer.SetLossTimer != nil && newAlarm != oldAlarm {
-               h.tracer.SetLossTimer(newAlarm.TimerType, newAlarm.EncryptionLevel, newAlarm.Time)
+               h.tracer.SetLossTimer(newAlarm.TimerType, newAlarm.EncryptionLevel, newAlarm.Time.ToTime())
        }
 }
 
-func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer {
+func (h *sentPacketHandler) lossDetectionTime(now monotime.Time) alarmTimer {
        // cancel the alarm if no packets are outstanding
        if h.peerCompletedAddressValidation && !h.hasOutstandingCryptoPackets() &&
                !h.appDataPackets.history.HasOutstandingPackets() && !h.appDataPackets.history.HasOutstandingPathProbes() {
@@ -626,7 +627,7 @@ func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer {
                return alarmTimer{}
        }
 
-       var pathProbeLossTime time.Time
+       var pathProbeLossTime monotime.Time
        if h.appDataPackets.history.HasOutstandingPathProbes() {
                if _, p := h.appDataPackets.history.FirstOutstandingPathProbe(); p != nil {
                        pathProbeLossTime = p.SendTime.Add(pathProbePacketLossTimeout)
@@ -660,7 +661,7 @@ func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer {
        return alarmTimer{}
 }
 
-func (h *sentPacketHandler) detectLostPathProbes(now time.Time) {
+func (h *sentPacketHandler) detectLostPathProbes(now monotime.Time) {
        if !h.appDataPackets.history.HasOutstandingPathProbes() {
                return
        }
@@ -680,9 +681,9 @@ func (h *sentPacketHandler) detectLostPathProbes(now time.Time) {
        }
 }
 
-func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) {
+func (h *sentPacketHandler) detectLostPackets(now monotime.Time, encLevel protocol.EncryptionLevel) {
        pnSpace := h.getPacketNumberSpace(encLevel)
-       pnSpace.lossTime = time.Time{}
+       pnSpace.lossTime = 0
 
        maxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
        lossDelay := time.Duration(timeThreshold * maxRTT)
@@ -745,7 +746,7 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
        }
 }
 
-func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error {
+func (h *sentPacketHandler) OnLossDetectionTimeout(now monotime.Time) error {
        defer h.setLossDetectionTimer(now)
 
        if h.handshakeConfirmed {
@@ -821,7 +822,7 @@ func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error {
        return nil
 }
 
-func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time {
+func (h *sentPacketHandler) GetLossDetectionTimeout() monotime.Time {
        return h.alarm.Time
 }
 
@@ -855,7 +856,7 @@ func (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) p
        return pn
 }
 
-func (h *sentPacketHandler) SendMode(now time.Time) SendMode {
+func (h *sentPacketHandler) SendMode(now monotime.Time) SendMode {
        numTrackedPackets := h.appDataPackets.history.Len()
        if h.initialPackets != nil {
                numTrackedPackets += h.initialPackets.history.Len()
@@ -900,7 +901,7 @@ func (h *sentPacketHandler) SendMode(now time.Time) SendMode {
        return SendAny
 }
 
-func (h *sentPacketHandler) TimeUntilSend() time.Time {
+func (h *sentPacketHandler) TimeUntilSend() monotime.Time {
        return h.congestion.TimeUntilSend(h.bytesInFlight)
 }
 
@@ -947,9 +948,9 @@ func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) {
        p.Frames = nil
 }
 
-func (h *sentPacketHandler) ResetForRetry(now time.Time) {
+func (h *sentPacketHandler) ResetForRetry(now monotime.Time) {
        h.bytesInFlight = 0
-       var firstPacketSendTime time.Time
+       var firstPacketSendTime monotime.Time
        for _, p := range h.initialPackets.history.Packets() {
                if firstPacketSendTime.IsZero() {
                        firstPacketSendTime = p.SendTime
@@ -993,7 +994,7 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) {
        h.ptoCount = 0
 }
 
-func (h *sentPacketHandler) MigratedPath(now time.Time, initialMaxDatagramSize protocol.ByteCount) {
+func (h *sentPacketHandler) MigratedPath(now monotime.Time, initialMaxDatagramSize protocol.ByteCount) {
        h.rttStats.ResetForPathMigration()
        for pn, p := range h.appDataPackets.history.Packets() {
                h.appDataPackets.history.DeclareLost(pn)
index d02be74f362688797aacd2be5beb411514897014..bb66431ab50188b526eb84eb19e26b83c6784f36 100644 (file)
@@ -10,6 +10,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/mocks"
        mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -120,7 +121,7 @@ func testSentPacketHandlerSendAndAcknowledge(t *testing.T, encLevel protocol.Enc
 
        var packets packetTracker
        var pns []protocol.PacketNumber
-       now := time.Now()
+       now := monotime.Now()
        for i := range 10 {
                e := encLevel
                // also send some 0-RTT packets to make sure they're acknowledged in the same packet number space
@@ -135,7 +136,7 @@ func testSentPacketHandlerSendAndAcknowledge(t *testing.T, encLevel protocol.Enc
        _, err := sph.ReceivedAck(
                &wire.AckFrame{AckRanges: ackRanges(pns[0], pns[1], pns[2], pns[3], pns[4], pns[7], pns[8], pns[9])},
                encLevel,
-               time.Now(),
+               monotime.Now(),
        )
        require.NoError(t, err)
        require.Equal(t, []protocol.PacketNumber{pns[0], pns[1], pns[2], pns[3], pns[4], pns[7], pns[8], pns[9]}, packets.Acked)
@@ -144,7 +145,7 @@ func testSentPacketHandlerSendAndAcknowledge(t *testing.T, encLevel protocol.Enc
        _, err = sph.ReceivedAck(
                &wire.AckFrame{AckRanges: ackRanges(pns[1], pns[2], pns[3])},
                encLevel,
-               time.Now(),
+               monotime.Now(),
        )
        require.NoError(t, err)
        require.Equal(t, []protocol.PacketNumber{pns[0], pns[1], pns[2], pns[3], pns[4], pns[7], pns[8], pns[9]}, packets.Acked)
@@ -153,7 +154,7 @@ func testSentPacketHandlerSendAndAcknowledge(t *testing.T, encLevel protocol.Enc
        _, err = sph.ReceivedAck(
                &wire.AckFrame{AckRanges: ackRanges(pns[7], pns[8], pns[9], pns[9]+1)},
                encLevel,
-               time.Now(),
+               monotime.Now(),
        )
        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.ProtocolViolation})
        require.ErrorContains(t, err, "received ACK for an unsent packet")
@@ -172,7 +173,7 @@ func TestSentPacketHandlerAcknowledgeSkippedPacket(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       now := time.Now()
+       now := monotime.Now()
        lastPN := protocol.InvalidPacketNumber
        skippedPN := protocol.InvalidPacketNumber
        for {
@@ -193,7 +194,7 @@ func TestSentPacketHandlerAcknowledgeSkippedPacket(t *testing.T) {
 
        _, err := sph.ReceivedAck(&wire.AckFrame{
                AckRanges: []wire.AckRange{{Smallest: 0, Largest: lastPN}},
-       }, protocol.Encryption1RTT, time.Now())
+       }, protocol.Encryption1RTT, monotime.Now())
        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.ProtocolViolation})
        require.ErrorContains(t, err, fmt.Sprintf("received an ACK for skipped packet number: %d (1-RTT)", skippedPN))
 }
@@ -227,20 +228,20 @@ func testSentPacketHandlerRTTs(t *testing.T, encLevel protocol.EncryptionLevel,
                utils.DefaultLogger,
        )
 
-       sendPacket := func(ti time.Time) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time) protocol.PacketNumber {
                pn := sph.PopPacketNumber(encLevel)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, encLevel, protocol.ECNNon, 1200, false, false)
                return pn
        }
 
-       ackPacket := func(pn protocol.PacketNumber, ti time.Time, d time.Duration) {
+       ackPacket := func(pn protocol.PacketNumber, ti monotime.Time, d time.Duration) {
                t.Helper()
                _, err := sph.ReceivedAck(&wire.AckFrame{DelayTime: d, AckRanges: ackRanges(pn)}, encLevel, ti)
                require.NoError(t, err)
        }
 
        var packets []protocol.PacketNumber
-       now := time.Now()
+       now := monotime.Now()
        // send some packets and receive ACKs with 0 ack delay
        for i := 0; i < 5; i++ {
                packets = append(packets, sendPacket(now))
@@ -317,49 +318,49 @@ func testSentPacketHandlerAmplificationLimitServer(t *testing.T, addressValidate
        )
 
        if addressValidated {
-               require.Equal(t, SendAny, sph.SendMode(time.Now()))
+               require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
                return
        }
 
        // no data received yet, so we can't send any packet yet
-       require.Equal(t, SendNone, sph.SendMode(time.Now()))
+       require.Equal(t, SendNone, sph.SendMode(monotime.Now()))
        require.Zero(t, sph.GetLossDetectionTimeout())
 
        // Receive 1000 bytes from the client.
        // As long as we haven't sent out 3x the amount of bytes received, we can send out new packets,
        // even if we go above the 3x limit by sending the last packet.
-       sph.ReceivedBytes(1000, time.Now())
+       sph.ReceivedBytes(1000, monotime.Now())
        for i := 0; i < 4; i++ {
-               require.Equal(t, SendAny, sph.SendMode(time.Now()))
+               require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
                pn := sph.PopPacketNumber(protocol.EncryptionInitial)
-               sph.SentPacket(time.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 999, false, false)
+               sph.SentPacket(monotime.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 999, false, false)
                if i != 3 {
                        require.NotZero(t, sph.GetLossDetectionTimeout())
                }
        }
-       require.Equal(t, SendNone, sph.SendMode(time.Now()))
+       require.Equal(t, SendNone, sph.SendMode(monotime.Now()))
        // no need to set a loss detection timer, as we're blocked by the amplification limit
        require.Zero(t, sph.GetLossDetectionTimeout())
 
        // receiving more data allows us to send out more packets
-       sph.ReceivedBytes(1000, time.Now())
+       sph.ReceivedBytes(1000, monotime.Now())
        require.NotZero(t, sph.GetLossDetectionTimeout())
        for i := 0; i < 3; i++ {
-               require.Equal(t, SendAny, sph.SendMode(time.Now()))
+               require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
                pn := sph.PopPacketNumber(protocol.EncryptionInitial)
-               sph.SentPacket(time.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 1000, false, false)
+               sph.SentPacket(monotime.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 1000, false, false)
        }
-       require.Equal(t, SendNone, sph.SendMode(time.Now()))
+       require.Equal(t, SendNone, sph.SendMode(monotime.Now()))
        require.Zero(t, sph.GetLossDetectionTimeout())
 
        // receiving an Initial packet doesn't validate the client's address
-       sph.ReceivedPacket(protocol.EncryptionInitial, time.Now())
-       require.Equal(t, SendNone, sph.SendMode(time.Now()))
+       sph.ReceivedPacket(protocol.EncryptionInitial, monotime.Now())
+       require.Equal(t, SendNone, sph.SendMode(monotime.Now()))
        require.Zero(t, sph.GetLossDetectionTimeout())
 
        // receiving a Handshake packet validates the client's address
-       sph.ReceivedPacket(protocol.EncryptionHandshake, time.Now())
-       require.Equal(t, SendAny, sph.SendMode(time.Now()))
+       sph.ReceivedPacket(protocol.EncryptionHandshake, monotime.Now())
+       require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
        require.NotZero(t, sph.GetLossDetectionTimeout())
 }
 
@@ -386,43 +387,43 @@ func testSentPacketHandlerAmplificationLimitClient(t *testing.T, dropHandshake b
                utils.DefaultLogger,
        )
 
-       require.Equal(t, SendAny, sph.SendMode(time.Now()))
+       require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
        pn := sph.PopPacketNumber(protocol.EncryptionInitial)
-       sph.SentPacket(time.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 999, false, false)
+       sph.SentPacket(monotime.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionInitial, protocol.ECNNon, 999, false, false)
        // it's not surprising that the loss detection timer is set, as this packet might be lost...
        require.NotZero(t, sph.GetLossDetectionTimeout())
        // ... but it's still set after receiving an ACK for this packet,
        // since we might need to unblock the server's amplification limit
-       _, err := sph.ReceivedAck(&wire.AckFrame{AckRanges: ackRanges(pn)}, protocol.EncryptionInitial, time.Now())
+       _, err := sph.ReceivedAck(&wire.AckFrame{AckRanges: ackRanges(pn)}, protocol.EncryptionInitial, monotime.Now())
        require.NoError(t, err)
        require.NotZero(t, sph.GetLossDetectionTimeout())
-       require.Equal(t, SendAny, sph.SendMode(time.Now()))
+       require.Equal(t, SendAny, sph.SendMode(monotime.Now()))
 
        // when the timer expires, we should send a PTO packet
-       sph.OnLossDetectionTimeout(time.Now())
-       require.Equal(t, SendPTOInitial, sph.SendMode(time.Now()))
+       sph.OnLossDetectionTimeout(monotime.Now())
+       require.Equal(t, SendPTOInitial, sph.SendMode(monotime.Now()))
        require.NotZero(t, sph.GetLossDetectionTimeout())
 
        if dropHandshake {
                // dropping the handshake packet number space completes the handshake,
                // even if no ACK for a handshake packet was received
-               sph.DropPackets(protocol.EncryptionHandshake, time.Now())
+               sph.DropPackets(protocol.EncryptionHandshake, monotime.Now())
                require.Zero(t, sph.GetLossDetectionTimeout())
                return
        }
 
        // once the Initial packet number space is dropped, we need to send a Handshake PTO packet,
        // even if we haven't sent any packet in the Handshake packet number space yet
-       sph.DropPackets(protocol.EncryptionInitial, time.Now())
+       sph.DropPackets(protocol.EncryptionInitial, monotime.Now())
        require.NotZero(t, sph.GetLossDetectionTimeout())
-       sph.OnLossDetectionTimeout(time.Now())
-       require.Equal(t, SendPTOHandshake, sph.SendMode(time.Now()))
+       sph.OnLossDetectionTimeout(monotime.Now())
+       require.Equal(t, SendPTOHandshake, sph.SendMode(monotime.Now()))
 
        // receiving an ACK for a handshake packet shows that the server completed address validation
        pn = sph.PopPacketNumber(protocol.EncryptionHandshake)
-       sph.SentPacket(time.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionHandshake, protocol.ECNNon, 999, false, false)
+       sph.SentPacket(monotime.Now(), pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, protocol.EncryptionHandshake, protocol.ECNNon, 999, false, false)
        require.NotZero(t, sph.GetLossDetectionTimeout())
-       _, err = sph.ReceivedAck(&wire.AckFrame{AckRanges: ackRanges(pn)}, protocol.EncryptionHandshake, time.Now())
+       _, err = sph.ReceivedAck(&wire.AckFrame{AckRanges: ackRanges(pn)}, protocol.EncryptionHandshake, monotime.Now())
        require.NoError(t, err)
        require.Zero(t, sph.GetLossDetectionTimeout())
 }
@@ -442,14 +443,14 @@ func TestSentPacketHandlerDelayBasedLossDetection(t *testing.T) {
        )
 
        var packets packetTracker
-       sendPacket := func(ti time.Time, isPathMTUProbePacket bool) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, isPathMTUProbePacket bool) protocol.PacketNumber {
                pn := sph.PopPacketNumber(protocol.EncryptionInitial)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn)}, protocol.EncryptionInitial, protocol.ECNNon, 1000, isPathMTUProbePacket, false)
                return pn
        }
 
        const rtt = time.Second
-       now := time.Now()
+       now := monotime.Now()
        t1 := now.Add(-rtt)
        t2 := now.Add(-10 * time.Millisecond)
        // Send 3 packets
@@ -495,7 +496,7 @@ func TestSentPacketHandlerPacketBasedLossDetection(t *testing.T) {
        )
 
        var packets packetTracker
-       now := time.Now()
+       now := monotime.Now()
        var pns []protocol.PacketNumber
        for range 5 {
                pn := sph.PopPacketNumber(protocol.EncryptionInitial)
@@ -561,11 +562,11 @@ func testSentPacketHandlerPTO(t *testing.T, encLevel protocol.EncryptionLevel, p
 
        // in the application-data packet number space, the PTO is only set
        if encLevel == protocol.Encryption1RTT {
-               sph.DropPackets(protocol.EncryptionInitial, time.Now())
-               sph.DropPackets(protocol.EncryptionHandshake, time.Now())
+               sph.DropPackets(protocol.EncryptionInitial, monotime.Now())
+               sph.DropPackets(protocol.EncryptionHandshake, monotime.Now())
        }
 
-       sendPacket := func(ti time.Time, ackEliciting bool) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, ackEliciting bool) protocol.PacketNumber {
                pn := sph.PopPacketNumber(encLevel)
                if ackEliciting {
                        tr.EXPECT().SetLossTimer(logging.TimerTypePTO, encLevel, gomock.Any())
@@ -576,8 +577,8 @@ func testSentPacketHandlerPTO(t *testing.T, encLevel protocol.EncryptionLevel, p
                return pn
        }
 
-       now := time.Now()
-       sendTimes := []time.Time{
+       now := monotime.Now()
+       sendTimes := []monotime.Time{
                now,
                now.Add(100 * time.Millisecond),
                now.Add(200 * time.Millisecond),
@@ -699,15 +700,15 @@ func TestSentPacketHandlerPacketNumberSpacesPTO(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       sendPacket := func(ti time.Time, encLevel protocol.EncryptionLevel) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, encLevel protocol.EncryptionLevel) protocol.PacketNumber {
                pn := sph.PopPacketNumber(encLevel)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{{Frame: &wire.PingFrame{}}}, encLevel, protocol.ECNNon, 1000, false, false)
                return pn
        }
 
        var initialPNs, handshakePNs [4]protocol.PacketNumber
-       var initialTimes, handshakeTimes [4]time.Time
-       now := time.Now()
+       var initialTimes, handshakeTimes [4]monotime.Time
+       now := monotime.Now()
        initialPNs[0] = sendPacket(now, protocol.EncryptionInitial)
        initialTimes[0] = now
        now = now.Add(100 * time.Millisecond)
@@ -791,7 +792,7 @@ func TestSentPacketHandler0RTT(t *testing.T) {
        )
 
        var appDataPackets packetTracker
-       sendPacket := func(ti time.Time, encLevel protocol.EncryptionLevel) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, encLevel protocol.EncryptionLevel) protocol.PacketNumber {
                pn := sph.PopPacketNumber(encLevel)
                var frames []Frame
                if encLevel == protocol.Encryption0RTT || encLevel == protocol.Encryption1RTT {
@@ -803,7 +804,7 @@ func TestSentPacketHandler0RTT(t *testing.T) {
                return pn
        }
 
-       now := time.Now()
+       now := monotime.Now()
        sendPacket(now, protocol.Encryption0RTT)
        sendPacket(now.Add(100*time.Millisecond), protocol.EncryptionHandshake)
        sendPacket(now.Add(200*time.Millisecond), protocol.Encryption0RTT)
@@ -844,10 +845,10 @@ func TestSentPacketHandlerCongestion(t *testing.T) {
        var packets packetTracker
        // Send the first 5 packets: not congestion-limited, not pacing-limited.
        // The 2nd packet is a Path MTU Probe packet.
-       now := time.Now()
+       now := monotime.Now()
        var bytesInFlight protocol.ByteCount
        var pns []protocol.PacketNumber
-       var sendTimes []time.Time
+       var sendTimes []monotime.Time
        for i := range 5 {
                gomock.InOrder(
                        cong.EXPECT().CanSend(bytesInFlight).Return(true),
@@ -940,7 +941,7 @@ func testSentPacketHandlerRetry(t *testing.T, rtt, expectedRTT time.Duration) {
                utils.DefaultLogger,
        )
 
-       start := time.Now()
+       start := monotime.Now()
        now := start
        var initialPNs, appDataPNs []protocol.PacketNumber
        // send 2 initial and 2 0-RTT packets
@@ -992,7 +993,7 @@ func TestSentPacketHandlerRetryAfterPTO(t *testing.T) {
        )
 
        var packets packetTracker
-       start := time.Now()
+       start := monotime.Now()
        now := start
        pn1 := sph.PopPacketNumber(protocol.EncryptionInitial)
        sph.SentPacket(now, pn1, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn1)}, protocol.EncryptionInitial, protocol.ECNNon, 1000, false, false)
@@ -1038,12 +1039,12 @@ func TestSentPacketHandlerECN(t *testing.T) {
        sph.congestion = cong
 
        // ECN marks on non-1-RTT packets are ignored
-       sph.SentPacket(time.Now(), sph.PopPacketNumber(protocol.EncryptionInitial), protocol.InvalidPacketNumber, nil, nil, protocol.EncryptionInitial, protocol.ECT1, 1200, false, false)
-       sph.SentPacket(time.Now(), sph.PopPacketNumber(protocol.EncryptionHandshake), protocol.InvalidPacketNumber, nil, nil, protocol.EncryptionHandshake, protocol.ECT0, 1200, false, false)
-       sph.SentPacket(time.Now(), sph.PopPacketNumber(protocol.Encryption0RTT), protocol.InvalidPacketNumber, nil, nil, protocol.Encryption0RTT, protocol.ECNCE, 1200, false, false)
+       sph.SentPacket(monotime.Now(), sph.PopPacketNumber(protocol.EncryptionInitial), protocol.InvalidPacketNumber, nil, nil, protocol.EncryptionInitial, protocol.ECT1, 1200, false, false)
+       sph.SentPacket(monotime.Now(), sph.PopPacketNumber(protocol.EncryptionHandshake), protocol.InvalidPacketNumber, nil, nil, protocol.EncryptionHandshake, protocol.ECT0, 1200, false, false)
+       sph.SentPacket(monotime.Now(), sph.PopPacketNumber(protocol.Encryption0RTT), protocol.InvalidPacketNumber, nil, nil, protocol.Encryption0RTT, protocol.ECNCE, 1200, false, false)
 
        var packets packetTracker
-       sendPacket := func(ti time.Time, ecn protocol.ECN) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, ecn protocol.ECN) protocol.PacketNumber {
                pn := sph.PopPacketNumber(protocol.Encryption1RTT)
                ecnHandler.EXPECT().SentPacket(pn, ecn)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn)}, protocol.Encryption1RTT, ecn, 1200, false, false)
@@ -1051,7 +1052,7 @@ func TestSentPacketHandlerECN(t *testing.T) {
        }
 
        pns := make([]protocol.PacketNumber, 4)
-       now := time.Now()
+       now := monotime.Now()
        pns[0] = sendPacket(now, protocol.ECT1)
        now = now.Add(time.Second)
        pns[1] = sendPacket(now, protocol.ECT0)
@@ -1137,18 +1138,18 @@ func TestSentPacketHandlerPathProbe(t *testing.T) {
                nil,
                utils.DefaultLogger,
        )
-       sph.DropPackets(protocol.EncryptionInitial, time.Now())
-       sph.DropPackets(protocol.EncryptionHandshake, time.Now())
+       sph.DropPackets(protocol.EncryptionInitial, monotime.Now())
+       sph.DropPackets(protocol.EncryptionHandshake, monotime.Now())
 
        var packets packetTracker
-       sendPacket := func(ti time.Time, isPathProbe bool) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, isPathProbe bool) protocol.PacketNumber {
                pn := sph.PopPacketNumber(protocol.Encryption1RTT)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn)}, protocol.Encryption1RTT, protocol.ECNNon, 1200, false, isPathProbe)
                return pn
        }
 
        // send 5 packets: 2 non-probe packets, 1 probe packet, 2 non-probe packets
-       now := time.Now()
+       now := monotime.Now()
        var pns [5]protocol.PacketNumber
        pns[0] = sendPacket(now, false)
        now = now.Add(rtt)
@@ -1216,17 +1217,17 @@ func TestSentPacketHandlerPathProbeAckAndLoss(t *testing.T) {
                nil,
                utils.DefaultLogger,
        )
-       sph.DropPackets(protocol.EncryptionInitial, time.Now())
-       sph.DropPackets(protocol.EncryptionHandshake, time.Now())
+       sph.DropPackets(protocol.EncryptionInitial, monotime.Now())
+       sph.DropPackets(protocol.EncryptionHandshake, monotime.Now())
 
        var packets packetTracker
-       sendPacket := func(ti time.Time, isPathProbe bool) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, isPathProbe bool) protocol.PacketNumber {
                pn := sph.PopPacketNumber(protocol.Encryption1RTT)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn)}, protocol.Encryption1RTT, protocol.ECNNon, 1200, false, isPathProbe)
                return pn
        }
 
-       now := time.Now()
+       now := monotime.Now()
        pn1 := sendPacket(now, true)
        t1 := now
        now = now.Add(100 * time.Millisecond)
@@ -1291,17 +1292,17 @@ func testSentPacketHandlerRandomized(t *testing.T, seed uint64) {
                nil,
                utils.DefaultLogger,
        )
-       sph.DropPackets(protocol.EncryptionInitial, time.Now())
-       sph.DropPackets(protocol.EncryptionHandshake, time.Now())
+       sph.DropPackets(protocol.EncryptionInitial, monotime.Now())
+       sph.DropPackets(protocol.EncryptionHandshake, monotime.Now())
 
        var packets packetTracker
-       sendPacket := func(ti time.Time, isPathProbe bool) protocol.PacketNumber {
+       sendPacket := func(ti monotime.Time, isPathProbe bool) protocol.PacketNumber {
                pn := sph.PopPacketNumber(protocol.Encryption1RTT)
                sph.SentPacket(ti, pn, protocol.InvalidPacketNumber, nil, []Frame{packets.NewPingFrame(pn)}, protocol.Encryption1RTT, protocol.ECNNon, 1200, false, isPathProbe)
                return pn
        }
 
-       now := time.Now()
+       now := monotime.Now()
        start := now
        var pns []protocol.PacketNumber
        for range 4 {
@@ -1370,7 +1371,7 @@ func benchmarkSendAndAcknowledge(b *testing.B, ackEvery, inFlight int) {
                nil,
                utils.DefaultLogger,
        )
-       now := time.Now()
+       now := monotime.Now()
        sph.DropPackets(protocol.EncryptionInitial, now)
        sph.DropPackets(protocol.EncryptionHandshake, now)
 
index 4be59cca3989e304b960a4030492aad2af5305b4..15e259f929d55a413af7ebb1cba43dda262a8b73 100644 (file)
@@ -3,8 +3,8 @@ package ackhandler
 import (
        "slices"
        "testing"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 
        "github.com/stretchr/testify/require"
@@ -29,7 +29,7 @@ func TestSentPacketHistoryPacketTracking(t *testing.T) {
 
 func testSentPacketHistoryPacketTracking(t *testing.T, firstPacketAckEliciting bool) {
        hist := newSentPacketHistory(true)
-       now := time.Now()
+       now := monotime.Now()
 
        var firstPacketNumber []protocol.PacketNumber
        require.False(t, hist.HasOutstandingPackets())
index 405fae70f95c82ee5f89ec67b8f9ce964a5c0776..8315026f6cdace00d4183eb28e4be77ed12ab090 100644 (file)
@@ -1,10 +1,12 @@
 package congestion
 
-import "time"
+import (
+       "github.com/quic-go/quic-go/internal/monotime"
+)
 
 // A Clock returns the current time
 type Clock interface {
-       Now() time.Time
+       Now() monotime.Time
 }
 
 // DefaultClock implements the Clock interface using the Go stdlib clock.
@@ -13,6 +15,6 @@ type DefaultClock struct{}
 var _ Clock = DefaultClock{}
 
 // Now gets the current time
-func (DefaultClock) Now() time.Time {
-       return time.Now()
+func (DefaultClock) Now() monotime.Time {
+       return monotime.Now()
 }
index b35d40d410cb6efe9caa879c7eab2889eff15fbf..40655de61ecf1de6ed97f09606b319305530e058 100644 (file)
@@ -4,6 +4,7 @@ import (
        "math"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 )
 
@@ -42,7 +43,7 @@ type Cubic struct {
        numConnections int
 
        // Time when this cycle started, after last loss event.
-       epoch time.Time
+       epoch monotime.Time
 
        // Max congestion window used just before last loss event.
        // Note: to improve fairness to other streams an additional back off is
@@ -77,7 +78,7 @@ func NewCubic(clock Clock) *Cubic {
 
 // Reset is called after a timeout to reset the cubic state
 func (c *Cubic) Reset() {
-       c.epoch = time.Time{}
+       c.epoch = 0
        c.lastMaxCongestionWindow = 0
        c.ackedBytesCount = 0
        c.estimatedTCPcongestionWindow = 0
@@ -121,7 +122,7 @@ func (c *Cubic) OnApplicationLimited() {
        // in such a period. This reset effectively freezes congestion window growth
        // through application-limited periods and allows Cubic growth to continue
        // when the entire window is being used.
-       c.epoch = time.Time{}
+       c.epoch = 0
 }
 
 // CongestionWindowAfterPacketLoss computes a new congestion window to use after
@@ -135,7 +136,7 @@ func (c *Cubic) CongestionWindowAfterPacketLoss(currentCongestionWindow protocol
        } else {
                c.lastMaxCongestionWindow = currentCongestionWindow
        }
-       c.epoch = time.Time{} // Reset time.
+       c.epoch = 0 // Reset time.
        return protocol.ByteCount(float32(currentCongestionWindow) * c.beta())
 }
 
@@ -147,7 +148,7 @@ func (c *Cubic) CongestionWindowAfterAck(
        ackedBytes protocol.ByteCount,
        currentCongestionWindow protocol.ByteCount,
        delayMin time.Duration,
-       eventTime time.Time,
+       eventTime monotime.Time,
 ) protocol.ByteCount {
        c.ackedBytesCount += ackedBytes
 
index faac12d7806f521a4e282ed98c95d74b2380b3b1..1ae10390ae4d28620b17e3319d4ca1319d63efc8 100644 (file)
@@ -2,8 +2,8 @@ package congestion
 
 import (
        "fmt"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/logging"
@@ -121,11 +121,11 @@ func newCubicSender(
 }
 
 // TimeUntilSend returns when the next packet should be sent.
-func (c *cubicSender) TimeUntilSend(_ protocol.ByteCount) time.Time {
+func (c *cubicSender) TimeUntilSend(_ protocol.ByteCount) monotime.Time {
        return c.pacer.TimeUntilSend()
 }
 
-func (c *cubicSender) HasPacingBudget(now time.Time) bool {
+func (c *cubicSender) HasPacingBudget(now monotime.Time) bool {
        return c.pacer.Budget(now) >= c.maxDatagramSize
 }
 
@@ -138,7 +138,7 @@ func (c *cubicSender) minCongestionWindow() protocol.ByteCount {
 }
 
 func (c *cubicSender) OnPacketSent(
-       sentTime time.Time,
+       sentTime monotime.Time,
        _ protocol.ByteCount,
        packetNumber protocol.PacketNumber,
        bytes protocol.ByteCount,
@@ -181,7 +181,7 @@ func (c *cubicSender) OnPacketAcked(
        ackedPacketNumber protocol.PacketNumber,
        ackedBytes protocol.ByteCount,
        priorInFlight protocol.ByteCount,
-       eventTime time.Time,
+       eventTime monotime.Time,
 ) {
        c.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber)
        if c.InRecovery() {
@@ -226,7 +226,7 @@ func (c *cubicSender) maybeIncreaseCwnd(
        _ protocol.PacketNumber,
        ackedBytes protocol.ByteCount,
        priorInFlight protocol.ByteCount,
-       eventTime time.Time,
+       eventTime monotime.Time,
 ) {
        // Do not increase the congestion window unless the sender is close to using
        // the current window.
@@ -254,7 +254,10 @@ func (c *cubicSender) maybeIncreaseCwnd(
                        c.numAckedPackets = 0
                }
        } else {
-               c.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))
+               c.congestionWindow = min(
+                       c.maxCongestionWindow(),
+                       c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime),
+               )
        }
 }
 
index dded2d25ad7c43e1d71ab0f2479cbc01b43ef82a..ff5dd01414afebb601ec5e953c2f21821dd33965 100644 (file)
@@ -5,6 +5,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
 
@@ -16,14 +17,14 @@ const (
        defaultWindowTCP               = protocol.ByteCount(initialCongestionWindowPackets) * maxDatagramSize
 )
 
-type mockClock time.Time
+type mockClock monotime.Time
 
-func (c *mockClock) Now() time.Time {
-       return time.Time(*c)
+func (c *mockClock) Now() monotime.Time {
+       return monotime.Time(*c)
 }
 
 func (c *mockClock) Advance(d time.Duration) {
-       *c = mockClock(time.Time(*c).Add(d))
+       *c = mockClock(monotime.Time(*c).Add(d))
 }
 
 const MaxCongestionWindow = 200 * maxDatagramSize
@@ -38,7 +39,7 @@ type testCubicSender struct {
 }
 
 func newTestCubicSender(cubic bool) *testCubicSender {
-       clock := mockClock{}
+       var clock mockClock
        rttStats := utils.RTTStats{}
        return &testCubicSender{
                clock:        &clock,
@@ -132,7 +133,7 @@ func TestCubicSenderPacing(t *testing.T) {
        // Check that we can't send immediately due to pacing
        delay := sender.sender.TimeUntilSend(sender.bytesInFlight)
        require.NotZero(t, delay)
-       require.Less(t, delay.Sub(time.Time(*sender.clock)), time.Hour)
+       require.Less(t, delay.Sub(monotime.Time(*sender.clock)), time.Hour)
 }
 
 func TestCubicSenderApplicationLimitedSlowStart(t *testing.T) {
@@ -489,7 +490,7 @@ func TestCubicSenderResetAfterConnectionMigration(t *testing.T) {
 }
 
 func TestCubicSenderSlowStartsUpToMaximumCongestionWindow(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        rttStats := utils.RTTStats{}
        const initialMaxCongestionWindow = protocol.MaxCongestionWindowPackets * initialMaxDatagramSize
        sender := newCubicSender(
@@ -516,7 +517,7 @@ func TestCubicSenderMaximumPacketSizeReduction(t *testing.T) {
 }
 
 func TestCubicSenderSlowStartsPacketSizeIncrease(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        rttStats := utils.RTTStats{}
        const initialMaxCongestionWindow = protocol.MaxCongestionWindowPackets * initialMaxDatagramSize
        sender := newCubicSender(
@@ -541,7 +542,7 @@ func TestCubicSenderSlowStartsPacketSizeIncrease(t *testing.T) {
 
 func TestCubicSenderLimitCwndIncreaseInCongestionAvoidance(t *testing.T) {
        // Enable Cubic.
-       clock := mockClock{}
+       var clock mockClock
        rttStats := utils.RTTStats{}
        sender := newCubicSender(
                &clock,
index 181c94a114398e68c279a66c402d2bda0a4c336c..a46a720690555223148ae3351533c03457560f71 100644 (file)
@@ -28,7 +28,7 @@ func cubicConvexCwnd(initialCwnd protocol.ByteCount, rtt, elapsedTime time.Durat
 }
 
 func TestCubicAboveOriginWithTighterBounds(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        cubic := NewCubic(&clock)
        cubic.SetNumConnections(int(numConnections))
 
@@ -79,7 +79,7 @@ func TestCubicAboveOriginWithTighterBounds(t *testing.T) {
 }
 
 func TestCubicAboveOriginWithFineGrainedCubing(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        cubic := NewCubic(&clock)
        cubic.SetNumConnections(int(numConnections))
 
@@ -106,7 +106,7 @@ func TestCubicAboveOriginWithFineGrainedCubing(t *testing.T) {
 }
 
 func TestCubicHandlesPerAckUpdates(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        cubic := NewCubic(&clock)
        cubic.SetNumConnections(int(numConnections))
 
@@ -140,7 +140,7 @@ func TestCubicHandlesPerAckUpdates(t *testing.T) {
 }
 
 func TestCubicHandlesLossEvents(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        cubic := NewCubic(&clock)
        cubic.SetNumConnections(int(numConnections))
 
@@ -179,7 +179,7 @@ func TestCubicHandlesLossEvents(t *testing.T) {
 }
 
 func TestCubicBelowOrigin(t *testing.T) {
-       clock := mockClock{}
+       var clock mockClock
        cubic := NewCubic(&clock)
        cubic.SetNumConnections(int(numConnections))
 
index 881f453b69aa6f7e5b2bc2441c114a303be3d88d..996907c6110519d646d4a2f1b565075633dae5f8 100644 (file)
@@ -1,19 +1,18 @@
 package congestion
 
 import (
-       "time"
-
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 )
 
 // A SendAlgorithm performs congestion control
 type SendAlgorithm interface {
-       TimeUntilSend(bytesInFlight protocol.ByteCount) time.Time
-       HasPacingBudget(now time.Time) bool
-       OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool)
+       TimeUntilSend(bytesInFlight protocol.ByteCount) monotime.Time
+       HasPacingBudget(now monotime.Time) bool
+       OnPacketSent(sentTime monotime.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool)
        CanSend(bytesInFlight protocol.ByteCount) bool
        MaybeExitSlowStart()
-       OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime time.Time)
+       OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime monotime.Time)
        OnCongestionEvent(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount)
        OnRetransmissionTimeout(packetsRetransmitted bool)
        SetMaxDatagramSize(protocol.ByteCount)
index 34d3d1d096a8ea72ea7e34199d526fcc2fa1b968..92757eedac1236dfd4f71ab49003db79bb07109b 100644 (file)
@@ -3,6 +3,7 @@ package congestion
 import (
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 )
 
@@ -12,7 +13,7 @@ const maxBurstSizePackets = 10
 type pacer struct {
        budgetAtLastSent  protocol.ByteCount
        maxDatagramSize   protocol.ByteCount
-       lastSentTime      time.Time
+       lastSentTime      monotime.Time
        adjustedBandwidth func() uint64 // in bytes/s
 }
 
@@ -33,7 +34,7 @@ func newPacer(getBandwidth func() Bandwidth) *pacer {
        return p
 }
 
-func (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) {
+func (p *pacer) SentPacket(sendTime monotime.Time, size protocol.ByteCount) {
        budget := p.Budget(sendTime)
        if size >= budget {
                p.budgetAtLastSent = 0
@@ -43,7 +44,7 @@ func (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) {
        p.lastSentTime = sendTime
 }
 
-func (p *pacer) Budget(now time.Time) protocol.ByteCount {
+func (p *pacer) Budget(now monotime.Time) protocol.ByteCount {
        if p.lastSentTime.IsZero() {
                return p.maxBurstSize()
        }
@@ -62,10 +63,10 @@ func (p *pacer) maxBurstSize() protocol.ByteCount {
 }
 
 // TimeUntilSend returns when the next packet should be sent.
-// It returns the zero value of time.Time if a packet can be sent immediately.
-func (p *pacer) TimeUntilSend() time.Time {
+// It returns zero if a packet can be sent immediately.
+func (p *pacer) TimeUntilSend() monotime.Time {
        if p.budgetAtLastSent >= p.maxDatagramSize {
-               return time.Time{}
+               return 0
        }
        diff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent)
        bw := p.adjustedBandwidth()
index a79c1d7de80193a459cfdea723b95e18b72ed403..ca4135481e92997ac51106272cdcbe57a5c42ad4 100644 (file)
@@ -6,13 +6,14 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/stretchr/testify/require"
 )
 
 func TestPacerPacing(t *testing.T) {
        bandwidth := 50 * initialMaxDatagramSize // 50 full-size packets per second
        p := newPacer(func() Bandwidth { return Bandwidth(bandwidth) * BytesPerSecond * 4 / 5 })
-       now := time.Now()
+       now := monotime.Now()
        require.Zero(t, p.TimeUntilSend())
        budget := p.Budget(now)
        require.Equal(t, maxBurstSizePackets*initialMaxDatagramSize, budget)
@@ -68,7 +69,7 @@ func TestPacerUpdatePacketSize(t *testing.T) {
        p := newPacer(func() Bandwidth { return Bandwidth(bandwidth) * BytesPerSecond * 4 / 5 })
 
        // consume the initial budget by sending packets
-       now := time.Now()
+       now := monotime.Now()
        for p.Budget(now) > 0 {
                p.SentPacket(now, initialMaxDatagramSize)
        }
@@ -88,7 +89,7 @@ func TestPacerFastPacing(t *testing.T) {
        p := newPacer(func() Bandwidth { return Bandwidth(bandwidth) * BytesPerSecond * 4 / 5 })
 
        // consume the initial budget by sending packets
-       now := time.Now()
+       now := monotime.Now()
        for p.Budget(now) > 0 {
                p.SentPacket(now, initialMaxDatagramSize)
        }
@@ -110,7 +111,7 @@ func TestPacerFastPacing(t *testing.T) {
 
 func TestPacerNoOverflows(t *testing.T) {
        p := newPacer(func() Bandwidth { return infBandwidth })
-       now := time.Now()
+       now := monotime.Now()
        p.SentPacket(now, initialMaxDatagramSize)
        for range 100000 {
                require.NotZero(t, p.Budget(now.Add(time.Duration(rand.Int64N(math.MaxInt64)))))
index 950e5f72209fc13ba4fd750a6f1deb108348fdba..04a9f98eec2a88d7caf46af06e1f710fb3ac4bfc 100644 (file)
@@ -4,6 +4,7 @@ import (
        "sync"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
 )
@@ -25,7 +26,7 @@ type baseFlowController struct {
 
        allowWindowIncrease func(size protocol.ByteCount) bool
 
-       epochStartTime   time.Time
+       epochStartTime   monotime.Time
        epochStartOffset protocol.ByteCount
        rttStats         *utils.RTTStats
 
@@ -77,7 +78,7 @@ func (c *baseFlowController) hasWindowUpdate() bool {
 
 // getWindowUpdate updates the receive window, if necessary
 // it returns the new offset
-func (c *baseFlowController) getWindowUpdate(now time.Time) protocol.ByteCount {
+func (c *baseFlowController) getWindowUpdate(now monotime.Time) protocol.ByteCount {
        if !c.hasWindowUpdate() {
                return 0
        }
@@ -89,7 +90,7 @@ func (c *baseFlowController) getWindowUpdate(now time.Time) protocol.ByteCount {
 
 // maybeAdjustWindowSize increases the receiveWindowSize if we're sending updates too often.
 // For details about auto-tuning, see https://docs.google.com/document/d/1SExkMmGiz8VYzV3s9E35JQlJ73vhzCekKkDi85F1qCE/edit?usp=sharing.
-func (c *baseFlowController) maybeAdjustWindowSize(now time.Time) {
+func (c *baseFlowController) maybeAdjustWindowSize(now monotime.Time) {
        bytesReadInEpoch := c.bytesRead - c.epochStartOffset
        // don't do anything if less than half the window has been consumed
        if bytesReadInEpoch <= c.receiveWindowSize/2 {
@@ -111,7 +112,7 @@ func (c *baseFlowController) maybeAdjustWindowSize(now time.Time) {
        c.startNewAutoTuningEpoch(now)
 }
 
-func (c *baseFlowController) startNewAutoTuningEpoch(now time.Time) {
+func (c *baseFlowController) startNewAutoTuningEpoch(now monotime.Time) {
        c.epochStartTime = now
        c.epochStartOffset = c.bytesRead
 }
index c550e75a9a0462f9c9679fb73839c5e134dbb276..0c74dcc90ab0897364a77bfda10134f2f81e831b 100644 (file)
@@ -3,8 +3,8 @@ package flowcontrol
 import (
        "errors"
        "fmt"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -38,7 +38,7 @@ func NewConnectionFlowController(
 }
 
 // IncrementHighestReceived adds an increment to the highestReceived value
-func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount, now time.Time) error {
+func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount, now monotime.Time) error {
        c.mutex.Lock()
        defer c.mutex.Unlock()
 
@@ -65,7 +65,7 @@ func (c *connectionFlowController) AddBytesRead(n protocol.ByteCount) (hasWindow
        return c.hasWindowUpdate()
 }
 
-func (c *connectionFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount {
+func (c *connectionFlowController) GetWindowUpdate(now monotime.Time) protocol.ByteCount {
        c.mutex.Lock()
        defer c.mutex.Unlock()
 
@@ -79,7 +79,7 @@ func (c *connectionFlowController) GetWindowUpdate(now time.Time) protocol.ByteC
 
 // EnsureMinimumWindowSize sets a minimum window size
 // it should make sure that the connection-level window is increased when a stream-level window grows
-func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount, now time.Time) {
+func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount, now monotime.Time) {
        c.mutex.Lock()
        defer c.mutex.Unlock()
 
index 74b4a5f7704e7da2c1501b6586d3afe3e7d35363..c8e564afbb08c0cb1503b02b6a6b498218237440 100644 (file)
@@ -4,6 +4,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -20,9 +21,9 @@ func TestConnectionFlowControlWindowUpdate(t *testing.T) {
                utils.DefaultLogger,
        )
        require.False(t, fc.AddBytesRead(1))
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
        require.True(t, fc.AddBytesRead(99))
-       require.Equal(t, protocol.ByteCount(200), fc.GetWindowUpdate(time.Now()))
+       require.Equal(t, protocol.ByteCount(200), fc.GetWindowUpdate(monotime.Now()))
 }
 
 func TestConnectionWindowAutoTuningNotAllowed(t *testing.T) {
@@ -42,7 +43,7 @@ func TestConnectionWindowAutoTuningNotAllowed(t *testing.T) {
                rttStats,
                utils.DefaultLogger,
        )
-       now := time.Now()
+       now := monotime.Now()
        require.NoError(t, fc.IncrementHighestReceived(100, now))
        fc.AddBytesRead(90)
        require.Equal(t, protocol.InvalidByteCount, callbackCalledWith)
@@ -52,9 +53,9 @@ func TestConnectionWindowAutoTuningNotAllowed(t *testing.T) {
 
 func TestConnectionFlowControlViolation(t *testing.T) {
        fc := NewConnectionFlowController(100, 100, nil, &utils.RTTStats{}, utils.DefaultLogger)
-       require.NoError(t, fc.IncrementHighestReceived(40, time.Now()))
-       require.NoError(t, fc.IncrementHighestReceived(60, time.Now()))
-       err := fc.IncrementHighestReceived(1, time.Now())
+       require.NoError(t, fc.IncrementHighestReceived(40, monotime.Now()))
+       require.NoError(t, fc.IncrementHighestReceived(60, monotime.Now()))
+       err := fc.IncrementHighestReceived(1, monotime.Now())
        var terr *qerr.TransportError
        require.ErrorAs(t, err, &terr)
        require.Equal(t, qerr.FlowControlError, terr.ErrorCode)
index 23cf30c58f846b0352f084c8c6784b78dd73605a..e95c65d99b0db7a825b854abed3e8d4af55dc523 100644 (file)
@@ -1,8 +1,7 @@
 package flowcontrol
 
 import (
-       "time"
-
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
 )
 
@@ -12,7 +11,7 @@ type flowController interface {
        UpdateSendWindow(protocol.ByteCount) (updated bool)
        AddBytesSent(protocol.ByteCount)
        // for receiving
-       GetWindowUpdate(time.Time) protocol.ByteCount // returns 0 if no update is necessary
+       GetWindowUpdate(monotime.Time) protocol.ByteCount // returns 0 if no update is necessary
 }
 
 // A StreamFlowController is a flow controller for a QUIC stream.
@@ -22,7 +21,7 @@ type StreamFlowController interface {
        // UpdateHighestReceived is called when a new highest offset is received
        // final has to be to true if this is the final offset of the stream,
        // as contained in a STREAM frame with FIN bit, and the RESET_STREAM frame
-       UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error
+       UpdateHighestReceived(offset protocol.ByteCount, final bool, now monotime.Time) error
        // Abandon is called when reading from the stream is aborted early,
        // and there won't be any further calls to AddBytesRead.
        Abandon()
@@ -41,7 +40,7 @@ type connectionFlowControllerI interface {
        ConnectionFlowController
        // The following two methods are not supposed to be called from outside this packet, but are needed internally
        // for sending
-       EnsureMinimumWindowSize(protocol.ByteCount, time.Time)
+       EnsureMinimumWindowSize(protocol.ByteCount, monotime.Time)
        // for receiving
-       IncrementHighestReceived(protocol.ByteCount, time.Time) error
+       IncrementHighestReceived(protocol.ByteCount, monotime.Time) error
 }
index 968e9a5b5fd90c44cf01396a2c0e3426e47468d3..ccbfe9cd48f6bb5a46faf50aff45af364d62e16e 100644 (file)
@@ -2,8 +2,8 @@ package flowcontrol
 
 import (
        "fmt"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -46,7 +46,7 @@ func NewStreamFlowController(
 }
 
 // UpdateHighestReceived updates the highestReceived value, if the offset is higher.
-func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error {
+func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now monotime.Time) error {
        // If the final offset for this stream is already known, check for consistency.
        if c.receivedFinalOffset {
                // If we receive another final offset, check that it's the same.
@@ -135,7 +135,7 @@ func (c *streamFlowController) shouldQueueWindowUpdate() bool {
        return !c.receivedFinalOffset && c.hasWindowUpdate()
 }
 
-func (c *streamFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount {
+func (c *streamFlowController) GetWindowUpdate(now monotime.Time) protocol.ByteCount {
        // If we already received the final offset for this stream, the peer won't need any additional flow control credit.
        if c.receivedFinalOffset {
                return 0
index 92d5726697cceee0a4fc198d9adeab5be4c579b1..7fc58682c35853432873b78c24783867c6db4508 100644 (file)
@@ -4,6 +4,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -28,15 +29,15 @@ func TestStreamFlowControlReceiving(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       require.NoError(t, fc.UpdateHighestReceived(50, false, time.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(50, false, monotime.Now()))
        // duplicates are fine
-       require.NoError(t, fc.UpdateHighestReceived(50, false, time.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(50, false, monotime.Now()))
        // reordering is fine
-       require.NoError(t, fc.UpdateHighestReceived(40, false, time.Now()))
-       require.NoError(t, fc.UpdateHighestReceived(60, false, time.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(40, false, monotime.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(60, false, monotime.Now()))
 
        // exceeding the limit is not fine
-       err := fc.UpdateHighestReceived(101, false, time.Now())
+       err := fc.UpdateHighestReceived(101, false, monotime.Now())
        var terr *qerr.TransportError
        require.ErrorAs(t, err, &terr)
        require.Equal(t, qerr.FlowControlError, terr.ErrorCode)
@@ -64,15 +65,15 @@ func TestStreamFlowControllerFinalOffset(t *testing.T) {
 
        t.Run("duplicate final offset", func(t *testing.T) {
                fc := newFC()
-               require.NoError(t, fc.UpdateHighestReceived(50, true, time.Now()))
+               require.NoError(t, fc.UpdateHighestReceived(50, true, monotime.Now()))
                // it is valid to receive the same final offset multiple times
-               require.NoError(t, fc.UpdateHighestReceived(50, true, time.Now()))
+               require.NoError(t, fc.UpdateHighestReceived(50, true, monotime.Now()))
        })
 
        t.Run("inconsistent final offset", func(t *testing.T) {
                fc := newFC()
-               require.NoError(t, fc.UpdateHighestReceived(50, true, time.Now()))
-               err := fc.UpdateHighestReceived(51, true, time.Now())
+               require.NoError(t, fc.UpdateHighestReceived(50, true, monotime.Now()))
+               err := fc.UpdateHighestReceived(51, true, monotime.Now())
                require.Error(t, err)
                var terr *qerr.TransportError
                require.ErrorAs(t, err, &terr)
@@ -82,9 +83,9 @@ func TestStreamFlowControllerFinalOffset(t *testing.T) {
 
        t.Run("non-final offset past final offset", func(t *testing.T) {
                fc := newFC()
-               require.NoError(t, fc.UpdateHighestReceived(50, true, time.Now()))
+               require.NoError(t, fc.UpdateHighestReceived(50, true, monotime.Now()))
                // No matter the ordering, it's never ok to receive an offset past the final offset.
-               err := fc.UpdateHighestReceived(60, false, time.Now())
+               err := fc.UpdateHighestReceived(60, false, monotime.Now())
                var terr *qerr.TransportError
                require.ErrorAs(t, err, &terr)
                require.Equal(t, qerr.FinalSizeError, terr.ErrorCode)
@@ -93,9 +94,9 @@ func TestStreamFlowControllerFinalOffset(t *testing.T) {
 
        t.Run("final offset smaller than previous offset", func(t *testing.T) {
                fc := newFC()
-               require.NoError(t, fc.UpdateHighestReceived(50, false, time.Now()))
+               require.NoError(t, fc.UpdateHighestReceived(50, false, monotime.Now()))
                // If we received offset already, it's invalid to receive a smaller final offset.
-               err := fc.UpdateHighestReceived(40, true, time.Now())
+               err := fc.UpdateHighestReceived(40, true, monotime.Now())
                var terr *qerr.TransportError
                require.ErrorAs(t, err, &terr)
                require.Equal(t, qerr.FinalSizeError, terr.ErrorCode)
@@ -122,14 +123,14 @@ func TestStreamAbandoning(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       require.NoError(t, fc.UpdateHighestReceived(50, true, time.Now()))
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
-       require.Zero(t, connFC.GetWindowUpdate(time.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(50, true, monotime.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
+       require.Zero(t, connFC.GetWindowUpdate(monotime.Now()))
 
        // Abandon the stream.
        // This marks all bytes as having been consumed.
        fc.Abandon()
-       require.Equal(t, protocol.ByteCount(150), connFC.GetWindowUpdate(time.Now()))
+       require.Equal(t, protocol.ByteCount(150), connFC.GetWindowUpdate(monotime.Now()))
 }
 
 func TestStreamSendWindow(t *testing.T) {
@@ -191,28 +192,28 @@ func TestStreamWindowUpdate(t *testing.T) {
                &utils.RTTStats{},
                utils.DefaultLogger,
        )
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
        hasStreamWindowUpdate, _ := fc.AddBytesRead(24)
        require.False(t, hasStreamWindowUpdate)
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
        // the window is updated when it's 25% filled
        hasStreamWindowUpdate, _ = fc.AddBytesRead(1)
        require.True(t, hasStreamWindowUpdate)
-       require.Equal(t, protocol.ByteCount(125), fc.GetWindowUpdate(time.Now()))
+       require.Equal(t, protocol.ByteCount(125), fc.GetWindowUpdate(monotime.Now()))
 
        hasStreamWindowUpdate, _ = fc.AddBytesRead(24)
        require.False(t, hasStreamWindowUpdate)
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
        // the window is updated when it's 25% filled
        hasStreamWindowUpdate, _ = fc.AddBytesRead(1)
        require.True(t, hasStreamWindowUpdate)
-       require.Equal(t, protocol.ByteCount(150), fc.GetWindowUpdate(time.Now()))
+       require.Equal(t, protocol.ByteCount(150), fc.GetWindowUpdate(monotime.Now()))
 
        // Receive the final offset.
        // We don't need to send any more flow control updates.
-       require.NoError(t, fc.UpdateHighestReceived(100, true, time.Now()))
+       require.NoError(t, fc.UpdateHighestReceived(100, true, monotime.Now()))
        fc.AddBytesRead(50)
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
 }
 
 func TestStreamConnectionWindowUpdate(t *testing.T) {
@@ -235,9 +236,9 @@ func TestStreamConnectionWindowUpdate(t *testing.T) {
 
        hasStreamWindowUpdate, hasConnWindowUpdate := fc.AddBytesRead(50)
        require.False(t, hasStreamWindowUpdate)
-       require.Zero(t, fc.GetWindowUpdate(time.Now()))
+       require.Zero(t, fc.GetWindowUpdate(monotime.Now()))
        require.True(t, hasConnWindowUpdate)
-       require.NotZero(t, connFC.GetWindowUpdate(time.Now()))
+       require.NotZero(t, connFC.GetWindowUpdate(monotime.Now()))
 }
 
 func TestStreamWindowAutoTuning(t *testing.T) {
@@ -263,7 +264,7 @@ func TestStreamWindowAutoTuning(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       now := time.Now()
+       now := monotime.Now()
        require.NoError(t, fc.UpdateHighestReceived(100, false, now))
 
        // data consumption is too slow, window size is not increased
index c3a59fcd05280edd3a57322a2c973be4f98cb142..d9227339f180e841423a1bf6d35e277b7443d29d 100644 (file)
@@ -5,8 +5,8 @@ import (
        "crypto/tls"
        "errors"
        "io"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 )
@@ -38,7 +38,7 @@ type LongHeaderOpener interface {
 type ShortHeaderOpener interface {
        headerDecryptor
        DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber
-       Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error)
+       Open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error)
 }
 
 // LongHeaderSealer seals a long header packet
index 415f85de85de0fd89d552566cb1a47061096817a..ef92ab1c4eb678ad9b69235038a3a1c843cd550a 100644 (file)
@@ -7,8 +7,8 @@ import (
        "encoding/binary"
        "fmt"
        "sync/atomic"
-       "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -42,7 +42,7 @@ type updatableAEAD struct {
        invalidPacketCount uint64
 
        // Time when the keys should be dropped. Keys are dropped on the next call to Open().
-       prevRcvAEADExpiry time.Time
+       prevRcvAEADExpiry monotime.Time
        prevRcvAEAD       cipher.AEAD
 
        firstRcvdWithCurrentKey protocol.PacketNumber
@@ -97,7 +97,7 @@ func (a *updatableAEAD) rollKeys() {
                if a.tracer != nil && a.tracer.DroppedKey != nil {
                        a.tracer.DroppedKey(a.keyPhase - 1)
                }
-               a.prevRcvAEADExpiry = time.Time{}
+               a.prevRcvAEADExpiry = 0
        }
 
        a.keyPhase++
@@ -115,7 +115,7 @@ func (a *updatableAEAD) rollKeys() {
        a.nextSendAEAD = createAEAD(a.suite, a.nextSendTrafficSecret, a.version)
 }
 
-func (a *updatableAEAD) startKeyDropTimer(now time.Time) {
+func (a *updatableAEAD) startKeyDropTimer(now monotime.Time) {
        d := 3 * a.rttStats.PTO(true)
        a.logger.Debugf("Starting key drop timer to drop key phase %d (in %s)", a.keyPhase-1, d)
        a.prevRcvAEADExpiry = now.Add(d)
@@ -171,7 +171,7 @@ func (a *updatableAEAD) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNL
        return protocol.DecodePacketNumber(wirePNLen, a.highestRcvdPN, wirePN)
 }
 
-func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {
+func (a *updatableAEAD) Open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {
        dec, err := a.open(dst, src, rcvTime, pn, kp, ad)
        if err == ErrDecryptionFailed {
                a.invalidPacketCount++
@@ -185,11 +185,11 @@ func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.Pac
        return dec, err
 }
 
-func (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {
+func (a *updatableAEAD) open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {
        if a.prevRcvAEAD != nil && !a.prevRcvAEADExpiry.IsZero() && rcvTime.After(a.prevRcvAEADExpiry) {
                a.prevRcvAEAD = nil
                a.logger.Debugf("Dropping key phase %d", a.keyPhase-1)
-               a.prevRcvAEADExpiry = time.Time{}
+               a.prevRcvAEADExpiry = 0
                if a.tracer != nil && a.tracer.DroppedKey != nil {
                        a.tracer.DroppedKey(a.keyPhase - 1)
                }
index 38b70efedb88d70adc2f1395d95155e9092c55ee..8140294e48a95c54fa68ae9c61c463b3e9c4b75a 100644 (file)
@@ -9,6 +9,7 @@ import (
        "time"
 
        mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -141,14 +142,14 @@ func TestUpdatableAEADEncryptDecryptMessage(t *testing.T) {
 
                                encrypted := server.Seal(nil, msg, 0x1337, ad)
 
-                               opened, err := client.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseZero, ad)
+                               opened, err := client.Open(nil, encrypted, monotime.Now(), 0x1337, protocol.KeyPhaseZero, ad)
                                require.NoError(t, err)
                                require.Equal(t, msg, opened)
 
-                               _, err = client.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseZero, []byte("wrong ad"))
+                               _, err = client.Open(nil, encrypted, monotime.Now(), 0x1337, protocol.KeyPhaseZero, []byte("wrong ad"))
                                require.Equal(t, ErrDecryptionFailed, err)
 
-                               _, err = client.Open(nil, encrypted, time.Now(), 0x42, protocol.KeyPhaseZero, ad)
+                               _, err = client.Open(nil, encrypted, monotime.Now(), 0x42, protocol.KeyPhaseZero, ad)
                                require.Equal(t, ErrDecryptionFailed, err)
                        })
                }
@@ -166,11 +167,11 @@ func TestUpdatableAEADPacketNumbers(t *testing.T) {
        require.Equal(t, protocol.PacketNumber(0x1337), server.FirstPacketNumber()) // make sure we save the first packet number
 
        // check that decoding the packet number works as expected
-       _, err := client.Open(nil, encrypted[:len(encrypted)-1], time.Now(), 0x1337, protocol.KeyPhaseZero, ad)
+       _, err := client.Open(nil, encrypted[:len(encrypted)-1], monotime.Now(), 0x1337, protocol.KeyPhaseZero, ad)
        require.Error(t, err)
        require.Equal(t, protocol.PacketNumber(0x38), client.DecodePacketNumber(0x38, protocol.PacketNumberLen1))
 
-       _, err = client.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseZero, ad)
+       _, err = client.Open(nil, encrypted, monotime.Now(), 0x1337, protocol.KeyPhaseZero, ad)
        require.NoError(t, err)
        require.Equal(t, protocol.PacketNumber(0x1338), client.DecodePacketNumber(0x38, protocol.PacketNumberLen1))
 }
@@ -179,10 +180,10 @@ func TestAEADLimitReached(t *testing.T) {
        client, _, _ := setupEndpoints(t, &utils.RTTStats{})
        client.invalidPacketLimit = 10
        for i := 0; i < 9; i++ {
-               _, err := client.Open(nil, []byte("foobar"), time.Now(), protocol.PacketNumber(i), protocol.KeyPhaseZero, []byte("ad"))
+               _, err := client.Open(nil, []byte("foobar"), monotime.Now(), protocol.PacketNumber(i), protocol.KeyPhaseZero, []byte("ad"))
                require.Equal(t, ErrDecryptionFailed, err)
        }
-       _, err := client.Open(nil, []byte("foobar"), time.Now(), 10, protocol.KeyPhaseZero, []byte("ad"))
+       _, err := client.Open(nil, []byte("foobar"), monotime.Now(), 10, protocol.KeyPhaseZero, []byte("ad"))
        require.Error(t, err)
        var transportErr *qerr.TransportError
        require.ErrorAs(t, err, &transportErr)
@@ -192,7 +193,7 @@ func TestAEADLimitReached(t *testing.T) {
 func TestKeyUpdates(t *testing.T) {
        client, server, _ := setupEndpoints(t, &utils.RTTStats{})
 
-       now := time.Now()
+       now := monotime.Now()
        require.Equal(t, protocol.KeyPhaseZero, server.KeyPhase())
        encrypted0 := server.Seal(nil, []byte(msg), 0x1337, []byte(ad))
        server.rollKeys()
@@ -226,7 +227,7 @@ func TestKeyUpdates(t *testing.T) {
 //     server.SetReadKey(cs, trafficSecret1)
 //     server.SetWriteKey(cs, trafficSecret2)
 
-//     now := time.Now()
+//     now := monotime.Now()
 //     encrypted0 := client.Seal(nil, []byte(msg), 0x42, ad)
 //     decrypted, err := server.Open(nil, encrypted0, now, 0x42, protocol.KeyPhaseZero, ad)
 //     require.NoError(t, err)
@@ -247,7 +248,7 @@ func TestKeyUpdates(t *testing.T) {
 func TestReorderedPacketAfterKeyUpdate(t *testing.T) {
        client, server, serverTracer := setupEndpoints(t, &utils.RTTStats{})
 
-       now := time.Now()
+       now := monotime.Now()
        encrypted01 := client.Seal(nil, []byte(msg), 0x42, []byte(ad))
        encrypted02 := client.Seal(nil, []byte(msg), 0x43, []byte(ad))
        _, err := server.Open(nil, encrypted01, now, 0x42, protocol.KeyPhaseZero, []byte(ad))
@@ -273,7 +274,7 @@ func TestDropsKeys3PTOsAfterKeyUpdate(t *testing.T) {
        var rttStats utils.RTTStats
        client, server, serverTracer := setupEndpoints(t, &rttStats)
 
-       now := time.Now()
+       now := monotime.Now()
        rttStats.UpdateRTT(10*time.Millisecond, 0)
        pto := rttStats.PTO(true)
        encrypted01 := client.Seal(nil, []byte(msg), 0x42, []byte(ad))
@@ -302,12 +303,12 @@ func TestAllowsFirstKeyUpdateImmediately(t *testing.T) {
        encrypted := client.Seal(nil, []byte(msg), 0x1337, []byte(ad))
 
        // if decryption failed, we don't expect a key phase update
-       _, err := server.Open(nil, encrypted[:len(encrypted)-1], time.Now(), 0x1337, protocol.KeyPhaseOne, []byte(ad))
+       _, err := server.Open(nil, encrypted[:len(encrypted)-1], monotime.Now(), 0x1337, protocol.KeyPhaseOne, []byte(ad))
        require.Equal(t, ErrDecryptionFailed, err)
 
        // the key phase is updated on first successful decryption
        serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), true)
-       _, err = server.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseOne, []byte(ad))
+       _, err = server.Open(nil, encrypted, monotime.Now(), 0x1337, protocol.KeyPhaseOne, []byte(ad))
        require.NoError(t, err)
 }
 
@@ -317,12 +318,12 @@ func TestRejectFrequentKeyUpdates(t *testing.T) {
        server.rollKeys()
        client.rollKeys()
        encrypted0 := client.Seal(nil, []byte(msg), 0x42, []byte(ad))
-       _, err := server.Open(nil, encrypted0, time.Now(), 0x42, protocol.KeyPhaseOne, []byte(ad))
+       _, err := server.Open(nil, encrypted0, monotime.Now(), 0x42, protocol.KeyPhaseOne, []byte(ad))
        require.NoError(t, err)
 
        client.rollKeys()
        encrypted1 := client.Seal(nil, []byte(msg), 0x42, []byte(ad))
-       _, err = server.Open(nil, encrypted1, time.Now(), 0x42, protocol.KeyPhaseZero, []byte(ad))
+       _, err = server.Open(nil, encrypted1, monotime.Now(), 0x42, protocol.KeyPhaseZero, []byte(ad))
        require.Equal(t, &qerr.TransportError{
                ErrorCode:    qerr.KeyUpdateError,
                ErrorMessage: "keys updated too quickly",
@@ -369,7 +370,7 @@ func TestInitiateKeyUpdateAfterSendingMaxPackets(t *testing.T) {
        // receive an ACK for a packet sent in key phase 1
        client.rollKeys()
        b := client.Seal(nil, []byte("foobar"), 1, []byte("ad"))
-       _, err := server.Open(nil, b, time.Now(), 1, protocol.KeyPhaseOne, []byte("ad"))
+       _, err := server.Open(nil, b, monotime.Now(), 1, protocol.KeyPhaseOne, []byte("ad"))
        require.NoError(t, err)
        require.NoError(t, server.SetLargestAcked(firstKeyUpdateInterval))
 
@@ -430,7 +431,7 @@ func TestKeyUpdateAfterOpeningMaxPackets(t *testing.T) {
        for i := 0; i < firstKeyUpdateInterval; i++ {
                require.Equal(t, protocol.KeyPhaseZero, server.KeyPhase())
                encrypted := client.Seal(nil, msg, pn, ad)
-               _, err := server.Open(nil, encrypted, time.Now(), pn, protocol.KeyPhaseZero, ad)
+               _, err := server.Open(nil, encrypted, monotime.Now(), pn, protocol.KeyPhaseZero, ad)
                require.NoError(t, err)
                pn++
        }
@@ -444,7 +445,7 @@ func TestKeyUpdateAfterOpeningMaxPackets(t *testing.T) {
        for i := 0; i < keyUpdateInterval; i++ {
                require.Equal(t, protocol.KeyPhaseOne, server.KeyPhase())
                encrypted := client.Seal(nil, msg, pn, ad)
-               _, err := server.Open(nil, encrypted, time.Now(), pn, protocol.KeyPhaseOne, ad)
+               _, err := server.Open(nil, encrypted, monotime.Now(), pn, protocol.KeyPhaseOne, ad)
                require.NoError(t, err)
                pn++
        }
@@ -468,7 +469,7 @@ func TestKeyUpdateKeyPhaseSkipping(t *testing.T) {
        client, server, serverTracer := setupEndpoints(t, &rttStats)
        server.SetHandshakeConfirmed()
 
-       now := time.Now()
+       now := monotime.Now()
        data1 := client.Seal(nil, []byte(msg), 1, []byte(ad))
        _, err := server.Open(nil, data1, now, 1, protocol.KeyPhaseZero, []byte(ad))
        require.NoError(t, err)
@@ -502,7 +503,7 @@ func TestFastKeyUpdatesByPeer(t *testing.T) {
                pn++
        }
        b := client.Seal(nil, []byte("foobar"), 1, []byte("ad"))
-       _, err := server.Open(nil, b, time.Now(), 1, protocol.KeyPhaseZero, []byte("ad"))
+       _, err := server.Open(nil, b, monotime.Now(), 1, protocol.KeyPhaseZero, []byte("ad"))
        require.NoError(t, err)
        require.NoError(t, server.SetLargestAcked(0))
        serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), false)
@@ -513,7 +514,7 @@ func TestFastKeyUpdatesByPeer(t *testing.T) {
        server.Seal(nil, []byte(msg), pn, []byte(ad))
        client.rollKeys()
        dataKeyPhaseOne := client.Seal(nil, []byte(msg), 2, []byte(ad))
-       now := time.Now()
+       now := monotime.Now()
        _, err = server.Open(nil, dataKeyPhaseOne, now, 2, protocol.KeyPhaseOne, []byte(ad))
        require.NoError(t, err)
        require.NoError(t, server.SetLargestAcked(pn))
@@ -547,7 +548,7 @@ func TestFastKeyUpdateByUs(t *testing.T) {
                server.Seal(nil, []byte(msg), pn, []byte(ad))
        }
        b := client.Seal(nil, []byte("foobar"), 1, []byte("ad"))
-       _, err := server.Open(nil, b, time.Now(), 1, protocol.KeyPhaseZero, []byte("ad"))
+       _, err := server.Open(nil, b, monotime.Now(), 1, protocol.KeyPhaseZero, []byte("ad"))
        require.NoError(t, err)
        require.NoError(t, server.SetLargestAcked(0))
        serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), false)
@@ -561,7 +562,7 @@ func TestFastKeyUpdateByUs(t *testing.T) {
        }
        client.rollKeys()
        b = client.Seal(nil, []byte("foobar"), 2, []byte("ad"))
-       now := time.Now()
+       now := monotime.Now()
        _, err = server.Open(nil, b, now, 2, protocol.KeyPhaseOne, []byte("ad"))
        require.NoError(t, err)
        require.NoError(t, server.SetLargestAcked(keyUpdateInterval))
@@ -621,7 +622,7 @@ func BenchmarkPacketDecryption(b *testing.B) {
        src = client.Seal(src[:0], src[:l], 1337, ad)
 
        for b.Loop() {
-               if _, err := server.Open(dst[:0], src, time.Time{}, 1337, protocol.KeyPhaseZero, ad); err != nil {
+               if _, err := server.Open(dst[:0], src, 0, 1337, protocol.KeyPhaseZero, ad); err != nil {
                        b.Fatalf("opening failed: %v", err)
                }
        }
index a65f85774740a23823a9d99421b89b7570adfc4a..f03f673c626e6858686193449bc1a13ac805ff72 100644 (file)
@@ -11,8 +11,8 @@ package mockackhandler
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        wire "github.com/quic-go/quic-go/internal/wire"
        gomock "go.uber.org/mock/gomock"
@@ -79,7 +79,7 @@ func (c *MockReceivedPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.E
 }
 
 // GetAckFrame mocks base method.
-func (m *MockReceivedPacketHandler) GetAckFrame(arg0 protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame {
+func (m *MockReceivedPacketHandler) GetAckFrame(arg0 protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetAckFrame", arg0, now, onlyIfQueued)
        ret0, _ := ret[0].(*wire.AckFrame)
@@ -105,22 +105,22 @@ func (c *MockReceivedPacketHandlerGetAckFrameCall) Return(arg0 *wire.AckFrame) *
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockReceivedPacketHandlerGetAckFrameCall) Do(f func(protocol.EncryptionLevel, time.Time, bool) *wire.AckFrame) *MockReceivedPacketHandlerGetAckFrameCall {
+func (c *MockReceivedPacketHandlerGetAckFrameCall) Do(f func(protocol.EncryptionLevel, monotime.Time, bool) *wire.AckFrame) *MockReceivedPacketHandlerGetAckFrameCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockReceivedPacketHandlerGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, time.Time, bool) *wire.AckFrame) *MockReceivedPacketHandlerGetAckFrameCall {
+func (c *MockReceivedPacketHandlerGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, monotime.Time, bool) *wire.AckFrame) *MockReceivedPacketHandlerGetAckFrameCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // GetAlarmTimeout mocks base method.
-func (m *MockReceivedPacketHandler) GetAlarmTimeout() time.Time {
+func (m *MockReceivedPacketHandler) GetAlarmTimeout() monotime.Time {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetAlarmTimeout")
-       ret0, _ := ret[0].(time.Time)
+       ret0, _ := ret[0].(monotime.Time)
        return ret0
 }
 
@@ -137,19 +137,19 @@ type MockReceivedPacketHandlerGetAlarmTimeoutCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) Return(arg0 time.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
+func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) Return(arg0 monotime.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
        c.Call = c.Call.Return(arg0)
        return c
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) Do(f func() time.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
+func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) Do(f func() monotime.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) DoAndReturn(f func() time.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
+func (c *MockReceivedPacketHandlerGetAlarmTimeoutCall) DoAndReturn(f func() monotime.Time) *MockReceivedPacketHandlerGetAlarmTimeoutCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -193,7 +193,7 @@ func (c *MockReceivedPacketHandlerIsPotentiallyDuplicateCall) DoAndReturn(f func
 }
 
 // ReceivedPacket mocks base method.
-func (m *MockReceivedPacketHandler) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error {
+func (m *MockReceivedPacketHandler) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime monotime.Time, ackEliciting bool) error {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "ReceivedPacket", pn, ecn, encLevel, rcvTime, ackEliciting)
        ret0, _ := ret[0].(error)
@@ -219,13 +219,13 @@ func (c *MockReceivedPacketHandlerReceivedPacketCall) Return(arg0 error) *MockRe
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockReceivedPacketHandlerReceivedPacketCall) Do(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, time.Time, bool) error) *MockReceivedPacketHandlerReceivedPacketCall {
+func (c *MockReceivedPacketHandlerReceivedPacketCall) Do(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, monotime.Time, bool) error) *MockReceivedPacketHandlerReceivedPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockReceivedPacketHandlerReceivedPacketCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, time.Time, bool) error) *MockReceivedPacketHandlerReceivedPacketCall {
+func (c *MockReceivedPacketHandlerReceivedPacketCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ECN, protocol.EncryptionLevel, monotime.Time, bool) error) *MockReceivedPacketHandlerReceivedPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 61939c9d4c69674a9f96b77f1c507e37632f24c0..e48feddf0f3d581b43e1567e1ea66052ad48eb58 100644 (file)
@@ -11,9 +11,9 @@ package mockackhandler
 
 import (
        reflect "reflect"
-       time "time"
 
        ackhandler "github.com/quic-go/quic-go/internal/ackhandler"
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        wire "github.com/quic-go/quic-go/internal/wire"
        gomock "go.uber.org/mock/gomock"
@@ -44,7 +44,7 @@ func (m *MockSentPacketHandler) EXPECT() *MockSentPacketHandlerMockRecorder {
 }
 
 // DropPackets mocks base method.
-func (m *MockSentPacketHandler) DropPackets(arg0 protocol.EncryptionLevel, rcvTime time.Time) {
+func (m *MockSentPacketHandler) DropPackets(arg0 protocol.EncryptionLevel, rcvTime monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "DropPackets", arg0, rcvTime)
 }
@@ -68,13 +68,13 @@ func (c *MockSentPacketHandlerDropPacketsCall) Return() *MockSentPacketHandlerDr
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerDropPacketsCall) Do(f func(protocol.EncryptionLevel, time.Time)) *MockSentPacketHandlerDropPacketsCall {
+func (c *MockSentPacketHandlerDropPacketsCall) Do(f func(protocol.EncryptionLevel, monotime.Time)) *MockSentPacketHandlerDropPacketsCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.EncryptionLevel, time.Time)) *MockSentPacketHandlerDropPacketsCall {
+func (c *MockSentPacketHandlerDropPacketsCall) DoAndReturn(f func(protocol.EncryptionLevel, monotime.Time)) *MockSentPacketHandlerDropPacketsCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -118,10 +118,10 @@ func (c *MockSentPacketHandlerECNModeCall) DoAndReturn(f func(bool) protocol.ECN
 }
 
 // GetLossDetectionTimeout mocks base method.
-func (m *MockSentPacketHandler) GetLossDetectionTimeout() time.Time {
+func (m *MockSentPacketHandler) GetLossDetectionTimeout() monotime.Time {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetLossDetectionTimeout")
-       ret0, _ := ret[0].(time.Time)
+       ret0, _ := ret[0].(monotime.Time)
        return ret0
 }
 
@@ -138,25 +138,25 @@ type MockSentPacketHandlerGetLossDetectionTimeoutCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) Return(arg0 time.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
+func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) Return(arg0 monotime.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
        c.Call = c.Call.Return(arg0)
        return c
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) Do(f func() time.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
+func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) Do(f func() monotime.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) DoAndReturn(f func() time.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
+func (c *MockSentPacketHandlerGetLossDetectionTimeoutCall) DoAndReturn(f func() monotime.Time) *MockSentPacketHandlerGetLossDetectionTimeoutCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // MigratedPath mocks base method.
-func (m *MockSentPacketHandler) MigratedPath(now time.Time, initialMaxPacketSize protocol.ByteCount) {
+func (m *MockSentPacketHandler) MigratedPath(now monotime.Time, initialMaxPacketSize protocol.ByteCount) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "MigratedPath", now, initialMaxPacketSize)
 }
@@ -180,19 +180,19 @@ func (c *MockSentPacketHandlerMigratedPathCall) Return() *MockSentPacketHandlerM
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerMigratedPathCall) Do(f func(time.Time, protocol.ByteCount)) *MockSentPacketHandlerMigratedPathCall {
+func (c *MockSentPacketHandlerMigratedPathCall) Do(f func(monotime.Time, protocol.ByteCount)) *MockSentPacketHandlerMigratedPathCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerMigratedPathCall) DoAndReturn(f func(time.Time, protocol.ByteCount)) *MockSentPacketHandlerMigratedPathCall {
+func (c *MockSentPacketHandlerMigratedPathCall) DoAndReturn(f func(monotime.Time, protocol.ByteCount)) *MockSentPacketHandlerMigratedPathCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // OnLossDetectionTimeout mocks base method.
-func (m *MockSentPacketHandler) OnLossDetectionTimeout(now time.Time) error {
+func (m *MockSentPacketHandler) OnLossDetectionTimeout(now monotime.Time) error {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "OnLossDetectionTimeout", now)
        ret0, _ := ret[0].(error)
@@ -218,13 +218,13 @@ func (c *MockSentPacketHandlerOnLossDetectionTimeoutCall) Return(arg0 error) *Mo
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerOnLossDetectionTimeoutCall) Do(f func(time.Time) error) *MockSentPacketHandlerOnLossDetectionTimeoutCall {
+func (c *MockSentPacketHandlerOnLossDetectionTimeoutCall) Do(f func(monotime.Time) error) *MockSentPacketHandlerOnLossDetectionTimeoutCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerOnLossDetectionTimeoutCall) DoAndReturn(f func(time.Time) error) *MockSentPacketHandlerOnLossDetectionTimeoutCall {
+func (c *MockSentPacketHandlerOnLossDetectionTimeoutCall) DoAndReturn(f func(monotime.Time) error) *MockSentPacketHandlerOnLossDetectionTimeoutCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -345,7 +345,7 @@ func (c *MockSentPacketHandlerQueueProbePacketCall) DoAndReturn(f func(protocol.
 }
 
 // ReceivedAck mocks base method.
-func (m *MockSentPacketHandler) ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool, error) {
+func (m *MockSentPacketHandler) ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) (bool, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "ReceivedAck", f, encLevel, rcvTime)
        ret0, _ := ret[0].(bool)
@@ -372,19 +372,19 @@ func (c *MockSentPacketHandlerReceivedAckCall) Return(arg0 bool, arg1 error) *Mo
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerReceivedAckCall) Do(f func(*wire.AckFrame, protocol.EncryptionLevel, time.Time) (bool, error)) *MockSentPacketHandlerReceivedAckCall {
+func (c *MockSentPacketHandlerReceivedAckCall) Do(f func(*wire.AckFrame, protocol.EncryptionLevel, monotime.Time) (bool, error)) *MockSentPacketHandlerReceivedAckCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerReceivedAckCall) DoAndReturn(f func(*wire.AckFrame, protocol.EncryptionLevel, time.Time) (bool, error)) *MockSentPacketHandlerReceivedAckCall {
+func (c *MockSentPacketHandlerReceivedAckCall) DoAndReturn(f func(*wire.AckFrame, protocol.EncryptionLevel, monotime.Time) (bool, error)) *MockSentPacketHandlerReceivedAckCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // ReceivedBytes mocks base method.
-func (m *MockSentPacketHandler) ReceivedBytes(arg0 protocol.ByteCount, rcvTime time.Time) {
+func (m *MockSentPacketHandler) ReceivedBytes(arg0 protocol.ByteCount, rcvTime monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "ReceivedBytes", arg0, rcvTime)
 }
@@ -408,19 +408,19 @@ func (c *MockSentPacketHandlerReceivedBytesCall) Return() *MockSentPacketHandler
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerReceivedBytesCall) Do(f func(protocol.ByteCount, time.Time)) *MockSentPacketHandlerReceivedBytesCall {
+func (c *MockSentPacketHandlerReceivedBytesCall) Do(f func(protocol.ByteCount, monotime.Time)) *MockSentPacketHandlerReceivedBytesCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerReceivedBytesCall) DoAndReturn(f func(protocol.ByteCount, time.Time)) *MockSentPacketHandlerReceivedBytesCall {
+func (c *MockSentPacketHandlerReceivedBytesCall) DoAndReturn(f func(protocol.ByteCount, monotime.Time)) *MockSentPacketHandlerReceivedBytesCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // ResetForRetry mocks base method.
-func (m *MockSentPacketHandler) ResetForRetry(rcvTime time.Time) {
+func (m *MockSentPacketHandler) ResetForRetry(rcvTime monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "ResetForRetry", rcvTime)
 }
@@ -444,19 +444,19 @@ func (c *MockSentPacketHandlerResetForRetryCall) Return() *MockSentPacketHandler
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerResetForRetryCall) Do(f func(time.Time)) *MockSentPacketHandlerResetForRetryCall {
+func (c *MockSentPacketHandlerResetForRetryCall) Do(f func(monotime.Time)) *MockSentPacketHandlerResetForRetryCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerResetForRetryCall) DoAndReturn(f func(time.Time)) *MockSentPacketHandlerResetForRetryCall {
+func (c *MockSentPacketHandlerResetForRetryCall) DoAndReturn(f func(monotime.Time)) *MockSentPacketHandlerResetForRetryCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // SendMode mocks base method.
-func (m *MockSentPacketHandler) SendMode(now time.Time) ackhandler.SendMode {
+func (m *MockSentPacketHandler) SendMode(now monotime.Time) ackhandler.SendMode {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "SendMode", now)
        ret0, _ := ret[0].(ackhandler.SendMode)
@@ -482,19 +482,19 @@ func (c *MockSentPacketHandlerSendModeCall) Return(arg0 ackhandler.SendMode) *Mo
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerSendModeCall) Do(f func(time.Time) ackhandler.SendMode) *MockSentPacketHandlerSendModeCall {
+func (c *MockSentPacketHandlerSendModeCall) Do(f func(monotime.Time) ackhandler.SendMode) *MockSentPacketHandlerSendModeCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerSendModeCall) DoAndReturn(f func(time.Time) ackhandler.SendMode) *MockSentPacketHandlerSendModeCall {
+func (c *MockSentPacketHandlerSendModeCall) DoAndReturn(f func(monotime.Time) ackhandler.SendMode) *MockSentPacketHandlerSendModeCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // SentPacket mocks base method.
-func (m *MockSentPacketHandler) SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []ackhandler.StreamFrame, frames []ackhandler.Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool) {
+func (m *MockSentPacketHandler) SentPacket(t monotime.Time, pn, largestAcked protocol.PacketNumber, streamFrames []ackhandler.StreamFrame, frames []ackhandler.Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "SentPacket", t, pn, largestAcked, streamFrames, frames, encLevel, ecn, size, isPathMTUProbePacket, isPathProbePacket)
 }
@@ -518,13 +518,13 @@ func (c *MockSentPacketHandlerSentPacketCall) Return() *MockSentPacketHandlerSen
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerSentPacketCall) Do(f func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool, bool)) *MockSentPacketHandlerSentPacketCall {
+func (c *MockSentPacketHandlerSentPacketCall) Do(f func(monotime.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool, bool)) *MockSentPacketHandlerSentPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerSentPacketCall) DoAndReturn(f func(time.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool, bool)) *MockSentPacketHandlerSentPacketCall {
+func (c *MockSentPacketHandlerSentPacketCall) DoAndReturn(f func(monotime.Time, protocol.PacketNumber, protocol.PacketNumber, []ackhandler.StreamFrame, []ackhandler.Frame, protocol.EncryptionLevel, protocol.ECN, protocol.ByteCount, bool, bool)) *MockSentPacketHandlerSentPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -566,10 +566,10 @@ func (c *MockSentPacketHandlerSetMaxDatagramSizeCall) DoAndReturn(f func(protoco
 }
 
 // TimeUntilSend mocks base method.
-func (m *MockSentPacketHandler) TimeUntilSend() time.Time {
+func (m *MockSentPacketHandler) TimeUntilSend() monotime.Time {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "TimeUntilSend")
-       ret0, _ := ret[0].(time.Time)
+       ret0, _ := ret[0].(monotime.Time)
        return ret0
 }
 
@@ -586,19 +586,19 @@ type MockSentPacketHandlerTimeUntilSendCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockSentPacketHandlerTimeUntilSendCall) Return(arg0 time.Time) *MockSentPacketHandlerTimeUntilSendCall {
+func (c *MockSentPacketHandlerTimeUntilSendCall) Return(arg0 monotime.Time) *MockSentPacketHandlerTimeUntilSendCall {
        c.Call = c.Call.Return(arg0)
        return c
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSentPacketHandlerTimeUntilSendCall) Do(f func() time.Time) *MockSentPacketHandlerTimeUntilSendCall {
+func (c *MockSentPacketHandlerTimeUntilSendCall) Do(f func() monotime.Time) *MockSentPacketHandlerTimeUntilSendCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSentPacketHandlerTimeUntilSendCall) DoAndReturn(f func() time.Time) *MockSentPacketHandlerTimeUntilSendCall {
+func (c *MockSentPacketHandlerTimeUntilSendCall) DoAndReturn(f func() monotime.Time) *MockSentPacketHandlerTimeUntilSendCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 372d0824f517b166826a43605396579a17c920f4..51355d11f82a8abd1741c39280b8493f4f1cc5c8 100644 (file)
@@ -11,8 +11,8 @@ package mocks
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -118,7 +118,7 @@ func (c *MockSendAlgorithmWithDebugInfosGetCongestionWindowCall) DoAndReturn(f f
 }
 
 // HasPacingBudget mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(now time.Time) bool {
+func (m *MockSendAlgorithmWithDebugInfos) HasPacingBudget(now monotime.Time) bool {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "HasPacingBudget", now)
        ret0, _ := ret[0].(bool)
@@ -144,13 +144,13 @@ func (c *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall) Return(arg0 bool) *
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall) Do(f func(time.Time) bool) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
+func (c *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall) Do(f func(monotime.Time) bool) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall) DoAndReturn(f func(time.Time) bool) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
+func (c *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall) DoAndReturn(f func(monotime.Time) bool) *MockSendAlgorithmWithDebugInfosHasPacingBudgetCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -304,7 +304,7 @@ func (c *MockSendAlgorithmWithDebugInfosOnCongestionEventCall) DoAndReturn(f fun
 }
 
 // OnPacketAcked mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(number protocol.PacketNumber, ackedBytes, priorInFlight protocol.ByteCount, eventTime time.Time) {
+func (m *MockSendAlgorithmWithDebugInfos) OnPacketAcked(number protocol.PacketNumber, ackedBytes, priorInFlight protocol.ByteCount, eventTime monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "OnPacketAcked", number, ackedBytes, priorInFlight, eventTime)
 }
@@ -328,19 +328,19 @@ func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) Return() *MockSendAlg
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) Do(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, time.Time)) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
+func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) Do(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, monotime.Time)) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, time.Time)) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
+func (c *MockSendAlgorithmWithDebugInfosOnPacketAckedCall) DoAndReturn(f func(protocol.PacketNumber, protocol.ByteCount, protocol.ByteCount, monotime.Time)) *MockSendAlgorithmWithDebugInfosOnPacketAckedCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // OnPacketSent mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) {
+func (m *MockSendAlgorithmWithDebugInfos) OnPacketSent(sentTime monotime.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "OnPacketSent", sentTime, bytesInFlight, packetNumber, bytes, isRetransmittable)
 }
@@ -364,13 +364,13 @@ func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) Return() *MockSendAlgo
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) Do(f func(time.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
+func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) Do(f func(monotime.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) DoAndReturn(f func(time.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
+func (c *MockSendAlgorithmWithDebugInfosOnPacketSentCall) DoAndReturn(f func(monotime.Time, protocol.ByteCount, protocol.PacketNumber, protocol.ByteCount, bool)) *MockSendAlgorithmWithDebugInfosOnPacketSentCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -448,10 +448,10 @@ func (c *MockSendAlgorithmWithDebugInfosSetMaxDatagramSizeCall) DoAndReturn(f fu
 }
 
 // TimeUntilSend mocks base method.
-func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(bytesInFlight protocol.ByteCount) time.Time {
+func (m *MockSendAlgorithmWithDebugInfos) TimeUntilSend(bytesInFlight protocol.ByteCount) monotime.Time {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "TimeUntilSend", bytesInFlight)
-       ret0, _ := ret[0].(time.Time)
+       ret0, _ := ret[0].(monotime.Time)
        return ret0
 }
 
@@ -468,19 +468,19 @@ type MockSendAlgorithmWithDebugInfosTimeUntilSendCall struct {
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) Return(arg0 time.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
+func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) Return(arg0 monotime.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
        c.Call = c.Call.Return(arg0)
        return c
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) Do(f func(protocol.ByteCount) time.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
+func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) Do(f func(protocol.ByteCount) monotime.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) DoAndReturn(f func(protocol.ByteCount) time.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
+func (c *MockSendAlgorithmWithDebugInfosTimeUntilSendCall) DoAndReturn(f func(protocol.ByteCount) monotime.Time) *MockSendAlgorithmWithDebugInfosTimeUntilSendCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index be4ef3b64dfde9b56cfc072d4c6419f292039c96..de5cfe6604e542d29cf7cb1087ad628daea96430 100644 (file)
@@ -11,8 +11,8 @@ package mocks
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -116,7 +116,7 @@ func (c *MockShortHeaderOpenerDecryptHeaderCall) DoAndReturn(f func([]byte, *byt
 }
 
 // Open mocks base method.
-func (m *MockShortHeaderOpener) Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error) {
+func (m *MockShortHeaderOpener) Open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "Open", dst, src, rcvTime, pn, kp, associatedData)
        ret0, _ := ret[0].([]byte)
@@ -143,13 +143,13 @@ func (c *MockShortHeaderOpenerOpenCall) Return(arg0 []byte, arg1 error) *MockSho
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockShortHeaderOpenerOpenCall) Do(f func([]byte, []byte, time.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *MockShortHeaderOpenerOpenCall {
+func (c *MockShortHeaderOpenerOpenCall) Do(f func([]byte, []byte, monotime.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *MockShortHeaderOpenerOpenCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockShortHeaderOpenerOpenCall) DoAndReturn(f func([]byte, []byte, time.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *MockShortHeaderOpenerOpenCall {
+func (c *MockShortHeaderOpenerOpenCall) DoAndReturn(f func([]byte, []byte, monotime.Time, protocol.PacketNumber, protocol.KeyPhaseBit, []byte) ([]byte, error)) *MockShortHeaderOpenerOpenCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 38216131e7ab10066e5c7d132ad67f65d03163c2..13f4e693a1dfbed92368311c7f8ebe383b21bc7b 100644 (file)
@@ -11,8 +11,8 @@ package mocks
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -153,7 +153,7 @@ func (c *MockStreamFlowControllerAddBytesSentCall) DoAndReturn(f func(protocol.B
 }
 
 // GetWindowUpdate mocks base method.
-func (m *MockStreamFlowController) GetWindowUpdate(arg0 time.Time) protocol.ByteCount {
+func (m *MockStreamFlowController) GetWindowUpdate(arg0 monotime.Time) protocol.ByteCount {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetWindowUpdate", arg0)
        ret0, _ := ret[0].(protocol.ByteCount)
@@ -179,13 +179,13 @@ func (c *MockStreamFlowControllerGetWindowUpdateCall) Return(arg0 protocol.ByteC
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockStreamFlowControllerGetWindowUpdateCall) Do(f func(time.Time) protocol.ByteCount) *MockStreamFlowControllerGetWindowUpdateCall {
+func (c *MockStreamFlowControllerGetWindowUpdateCall) Do(f func(monotime.Time) protocol.ByteCount) *MockStreamFlowControllerGetWindowUpdateCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockStreamFlowControllerGetWindowUpdateCall) DoAndReturn(f func(time.Time) protocol.ByteCount) *MockStreamFlowControllerGetWindowUpdateCall {
+func (c *MockStreamFlowControllerGetWindowUpdateCall) DoAndReturn(f func(monotime.Time) protocol.ByteCount) *MockStreamFlowControllerGetWindowUpdateCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -267,7 +267,7 @@ func (c *MockStreamFlowControllerSendWindowSizeCall) DoAndReturn(f func() protoc
 }
 
 // UpdateHighestReceived mocks base method.
-func (m *MockStreamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error {
+func (m *MockStreamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now monotime.Time) error {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "UpdateHighestReceived", offset, final, now)
        ret0, _ := ret[0].(error)
@@ -293,13 +293,13 @@ func (c *MockStreamFlowControllerUpdateHighestReceivedCall) Return(arg0 error) *
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockStreamFlowControllerUpdateHighestReceivedCall) Do(f func(protocol.ByteCount, bool, time.Time) error) *MockStreamFlowControllerUpdateHighestReceivedCall {
+func (c *MockStreamFlowControllerUpdateHighestReceivedCall) Do(f func(protocol.ByteCount, bool, monotime.Time) error) *MockStreamFlowControllerUpdateHighestReceivedCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockStreamFlowControllerUpdateHighestReceivedCall) DoAndReturn(f func(protocol.ByteCount, bool, time.Time) error) *MockStreamFlowControllerUpdateHighestReceivedCall {
+func (c *MockStreamFlowControllerUpdateHighestReceivedCall) DoAndReturn(f func(protocol.ByteCount, bool, monotime.Time) error) *MockStreamFlowControllerUpdateHighestReceivedCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
diff --git a/internal/monotime/time.go b/internal/monotime/time.go
new file mode 100644 (file)
index 0000000..eda61dc
--- /dev/null
@@ -0,0 +1,90 @@
+// Package monotime provides a monotonic time representation that is useful for
+// measuring elapsed time.
+// It is designed as a memory optimized drop-in replacement for time.Time, with
+// a monotime.Time consuming just 8 bytes instead of 24 bytes.
+package monotime
+
+import (
+       "time"
+)
+
+// The absolute value doesn't matter, but it should be in the past,
+// so that every timestamp obtained with Now() is non-zero,
+// even on systems with low timer resolutions (e.g. Windows).
+var start = time.Now().Add(-time.Hour)
+
+// A Time represents an instant in monotonic time.
+// Times can be compared using the comparison operators, but the specific
+// value is implementation-dependent and should not be relied upon.
+// The zero value of Time doesn't have any specific meaning.
+type Time int64
+
+// Now returns the current monotonic time.
+func Now() Time {
+       return Time(time.Since(start).Nanoseconds())
+}
+
+// Sub returns the duration t-t2. 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 (t Time) Sub(t2 Time) time.Duration {
+       return time.Duration(t - t2)
+}
+
+// Add returns the time t+d.
+func (t Time) Add(d time.Duration) Time {
+       return Time(int64(t) + d.Nanoseconds())
+}
+
+// After reports whether the time instant t is after t2.
+func (t Time) After(t2 Time) bool {
+       return t > t2
+}
+
+// Before reports whether the time instant t is before t2.
+func (t Time) Before(t2 Time) bool {
+       return t < t2
+}
+
+// IsZero reports whether t represents the zero time instant.
+func (t Time) IsZero() bool {
+       return t == 0
+}
+
+// Equal reports whether t and t2 represent the same time instant.
+func (t Time) Equal(t2 Time) bool {
+       return t == t2
+}
+
+// ToTime converts the monotonic time to a time.Time value.
+// The returned time.Time will have the same instant as the monotonic time,
+// but may be subject to clock adjustments.
+func (t Time) ToTime() time.Time {
+       if t.IsZero() {
+               return time.Time{}
+       }
+       return start.Add(time.Duration(t))
+}
+
+// Since returns the time elapsed since t. It is shorthand for Now().Sub(t).
+func Since(t Time) time.Duration {
+       return Now().Sub(t)
+}
+
+// Until returns the duration until t.
+// It is shorthand for t.Sub(Now()).
+// If t is in the past, the returned duration will be negative.
+func Until(t Time) time.Duration {
+       return time.Duration(t - Now())
+}
+
+// FromTime converts a time.Time to a monotonic Time.
+// The conversion is relative to the package's start time and may lose
+// precision if the time.Time is far from the start time.
+func FromTime(t time.Time) Time {
+       if t.IsZero() {
+               return 0
+       }
+       return Time(t.Sub(start).Nanoseconds())
+}
diff --git a/internal/monotime/time_test.go b/internal/monotime/time_test.go
new file mode 100644 (file)
index 0000000..d51bb93
--- /dev/null
@@ -0,0 +1,79 @@
+package monotime
+
+import (
+       "testing"
+       "time"
+
+       "github.com/quic-go/quic-go/internal/synctest"
+
+       "github.com/stretchr/testify/require"
+)
+
+func TestTimeRelations(t *testing.T) {
+       t1 := Now()
+       require.Equal(t, t1, t1)
+       require.False(t, t1.IsZero())
+
+       t2 := t1.Add(time.Second)
+
+       require.False(t, t1.Equal(t2))
+       require.False(t, t2.Equal(t1))
+
+       require.True(t, t2.After(t1))
+       require.False(t, t1.After(t2))
+       require.False(t, t2.Before(t1))
+
+       require.Equal(t, t2.Sub(t1), time.Second)
+       require.Equal(t, t1.Sub(t2), -time.Second)
+}
+
+func TestSince(t *testing.T) {
+       synctest.Test(t, func(t *testing.T) {
+               t1 := Now()
+               time.Sleep(time.Second)
+               require.Equal(t, Since(t1), time.Second)
+               require.Equal(t, Now().Sub(t1), time.Second)
+               time.Sleep(time.Minute)
+               require.Equal(t, Since(t1), time.Minute+time.Second)
+               require.Equal(t, Now().Sub(t1), time.Minute+time.Second)
+       })
+}
+
+func TestUntil(t *testing.T) {
+       synctest.Test(t, func(t *testing.T) {
+               t1 := Now().Add(time.Minute)
+               require.Equal(t, Until(t1), time.Minute)
+               require.Equal(t, t1.Sub(Now()), time.Minute)
+               time.Sleep(15 * time.Second)
+               require.Equal(t, Until(t1), 45*time.Second)
+               require.Equal(t, t1.Sub(Now()), 45*time.Second)
+       })
+}
+
+func TestConversions(t *testing.T) {
+       t1 := Now()
+       t1Time := t1.ToTime()
+       require.Equal(t, FromTime(t1Time), t1)
+       require.Zero(t, t1Time.Sub(t1.ToTime()))
+
+       var zeroTime time.Time
+       require.Zero(t, FromTime(zeroTime))
+       require.Zero(t, FromTime(zeroTime))
+
+       var zero Time
+       require.True(t, zero.ToTime().IsZero())
+}
+
+func BenchmarkNow(b *testing.B) {
+       b.Run("Now", func(b *testing.B) {
+               for b.Loop() {
+                       _ = Now()
+               }
+       })
+
+       b.Run("time.Now", func(b *testing.B) {
+               for b.Loop() {
+                       _ = time.Now()
+               }
+       })
+}
index 361106c8a95bfc2bb86c4cd3559a5a0ddd10e1a6..333e8850fa62380085ab6203d4f20ea708a4ff3f 100644 (file)
@@ -3,13 +3,15 @@ package utils
 import (
        "math"
        "time"
+
+       "github.com/quic-go/quic-go/internal/monotime"
 )
 
 // A Timer wrapper that behaves correctly when resetting
 type Timer struct {
        t        *time.Timer
        read     bool
-       deadline time.Time
+       deadline monotime.Time
 }
 
 // NewTimer creates a new timer that is not set
@@ -23,7 +25,7 @@ func (t *Timer) Chan() <-chan time.Time {
 }
 
 // Reset the timer, no matter whether the value was read or not
-func (t *Timer) Reset(deadline time.Time) {
+func (t *Timer) Reset(deadline monotime.Time) {
        if deadline.Equal(t.deadline) && !t.read {
                // No need to reset the timer
                return
@@ -35,7 +37,7 @@ func (t *Timer) Reset(deadline time.Time) {
                <-t.t.C
        }
        if !deadline.IsZero() {
-               t.t.Reset(time.Until(deadline))
+               t.t.Reset(monotime.Until(deadline))
        }
 
        t.read = false
@@ -47,7 +49,7 @@ func (t *Timer) SetRead() {
        t.read = true
 }
 
-func (t *Timer) Deadline() time.Time {
+func (t *Timer) Deadline() monotime.Time {
        return t.deadline
 }
 
index 1a17cab15db948052727a9b992cb812286e7399e..daaaad843c9577467654eac63526d16a38cd1f2d 100644 (file)
@@ -4,6 +4,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/synctest"
 
        "github.com/stretchr/testify/require"
@@ -19,13 +20,13 @@ func TestTimerResets(t *testing.T) {
                default:
                }
 
-               start := time.Now()
+               start := monotime.Now()
 
                // timer fires immediately for a deadline in the past
-               timer.Reset(time.Now().Add(-time.Second))
+               timer.Reset(monotime.Now().Add(-time.Second))
                select {
                case <-timer.Chan():
-                       require.Zero(t, time.Since(start))
+                       require.Zero(t, monotime.Since(start))
                        timer.SetRead()
                case <-time.After(time.Hour): // this can be replaced with a default once we drop support for Go 1.24
                        t.Fatal("timer should have fired")
@@ -34,11 +35,11 @@ func TestTimerResets(t *testing.T) {
                // timer reset without getting read
                for range 10 {
                        time.Sleep(time.Second)
-                       timer.Reset(time.Now().Add(time.Hour))
+                       timer.Reset(monotime.Now().Add(time.Hour))
                }
                select {
                case <-timer.Chan():
-                       require.Equal(t, time.Since(start), time.Hour+10*time.Second)
+                       require.Equal(t, monotime.Since(start), time.Hour+10*time.Second)
                        timer.SetRead()
                case <-time.After(2 * time.Hour):
                        t.Fatal("timer should have fired")
@@ -46,12 +47,12 @@ func TestTimerResets(t *testing.T) {
 
                const d = 10 * time.Minute
                for i := range 10 {
-                       start := time.Now()
-                       timer.Reset(time.Now().Add(d))
+                       start := monotime.Now()
+                       timer.Reset(monotime.Now().Add(d))
                        if i%2 == 0 {
                                select {
                                case <-timer.Chan():
-                                       require.Equal(t, time.Since(start), d)
+                                       require.Equal(t, monotime.Since(start), d)
                                case <-time.After(2 * d):
                                        t.Fatal("timer should have fired")
                                }
@@ -72,7 +73,7 @@ func TestTimerResets(t *testing.T) {
 func TestTimerClearDeadline(t *testing.T) {
        synctest.Test(t, func(t *testing.T) {
                timer := NewTimer()
-               timer.Reset(time.Time{})
+               timer.Reset(0)
 
                // we don't expect the timer to be set for a zero deadline
                select {
@@ -85,7 +86,7 @@ func TestTimerClearDeadline(t *testing.T) {
 
 func TestTimerSameDeadline(t *testing.T) {
        t.Run("timer read in between", func(t *testing.T) {
-               deadline := time.Now().Add(-time.Millisecond)
+               deadline := monotime.Now().Add(-time.Millisecond)
                timer := NewTimer()
                timer.Reset(deadline)
 
@@ -106,7 +107,7 @@ func TestTimerSameDeadline(t *testing.T) {
        })
 
        t.Run("timer not read in between", func(t *testing.T) {
-               deadline := time.Now().Add(-time.Millisecond)
+               deadline := monotime.Now().Add(-time.Millisecond)
                timer := NewTimer()
                timer.Reset(deadline)
 
@@ -127,7 +128,7 @@ func TestTimerSameDeadline(t *testing.T) {
 func TestTimerStop(t *testing.T) {
        synctest.Test(t, func(t *testing.T) {
                timer := NewTimer()
-               timer.Reset(time.Now().Add(time.Second))
+               timer.Reset(monotime.Now().Add(time.Second))
                timer.Stop()
 
                select {
index c22f845307f444062ee26ba35f064e02cea62d3b..f2a06d8a98605c9ac45adacbb8db9591a77797b0 100644 (file)
@@ -11,8 +11,8 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        wire "github.com/quic-go/quic-go/internal/wire"
        gomock "go.uber.org/mock/gomock"
@@ -43,7 +43,7 @@ func (m *MockAckFrameSource) EXPECT() *MockAckFrameSourceMockRecorder {
 }
 
 // GetAckFrame mocks base method.
-func (m *MockAckFrameSource) GetAckFrame(arg0 protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame {
+func (m *MockAckFrameSource) GetAckFrame(arg0 protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetAckFrame", arg0, now, onlyIfQueued)
        ret0, _ := ret[0].(*wire.AckFrame)
@@ -69,13 +69,13 @@ func (c *MockAckFrameSourceGetAckFrameCall) Return(arg0 *wire.AckFrame) *MockAck
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockAckFrameSourceGetAckFrameCall) Do(f func(protocol.EncryptionLevel, time.Time, bool) *wire.AckFrame) *MockAckFrameSourceGetAckFrameCall {
+func (c *MockAckFrameSourceGetAckFrameCall) Do(f func(protocol.EncryptionLevel, monotime.Time, bool) *wire.AckFrame) *MockAckFrameSourceGetAckFrameCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockAckFrameSourceGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, time.Time, bool) *wire.AckFrame) *MockAckFrameSourceGetAckFrameCall {
+func (c *MockAckFrameSourceGetAckFrameCall) DoAndReturn(f func(protocol.EncryptionLevel, monotime.Time, bool) *wire.AckFrame) *MockAckFrameSourceGetAckFrameCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 46c7464b45c9915f5a8ed75dfe0ce70de6293828..1829ff88e70abfbebb2b0b0e792c2c652137ffc1 100644 (file)
@@ -11,9 +11,9 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
        ackhandler "github.com/quic-go/quic-go/internal/ackhandler"
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -43,7 +43,7 @@ func (m *MockFrameSource) EXPECT() *MockFrameSourceMockRecorder {
 }
 
 // Append mocks base method.
-func (m *MockFrameSource) Append(arg0 []ackhandler.Frame, arg1 []ackhandler.StreamFrame, arg2 protocol.ByteCount, arg3 time.Time, arg4 protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
+func (m *MockFrameSource) Append(arg0 []ackhandler.Frame, arg1 []ackhandler.StreamFrame, arg2 protocol.ByteCount, arg3 monotime.Time, arg4 protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "Append", arg0, arg1, arg2, arg3, arg4)
        ret0, _ := ret[0].([]ackhandler.Frame)
@@ -71,13 +71,13 @@ func (c *MockFrameSourceAppendCall) Return(arg0 []ackhandler.Frame, arg1 []ackha
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockFrameSourceAppendCall) Do(f func([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, time.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)) *MockFrameSourceAppendCall {
+func (c *MockFrameSourceAppendCall) Do(f func([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, monotime.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)) *MockFrameSourceAppendCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockFrameSourceAppendCall) DoAndReturn(f func([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, time.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)) *MockFrameSourceAppendCall {
+func (c *MockFrameSourceAppendCall) DoAndReturn(f func([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, monotime.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)) *MockFrameSourceAppendCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 472e6f3e142084086f083e7b4f9c51eee872716c..92332f127f5f150122b8c7f61108b7d742c8087a 100644 (file)
@@ -11,9 +11,9 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
        ackhandler "github.com/quic-go/quic-go/internal/ackhandler"
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        gomock "go.uber.org/mock/gomock"
 )
@@ -81,7 +81,7 @@ func (c *MockMTUDiscovererCurrentSizeCall) DoAndReturn(f func() protocol.ByteCou
 }
 
 // GetPing mocks base method.
-func (m *MockMTUDiscoverer) GetPing(now time.Time) (ackhandler.Frame, protocol.ByteCount) {
+func (m *MockMTUDiscoverer) GetPing(now monotime.Time) (ackhandler.Frame, protocol.ByteCount) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "GetPing", now)
        ret0, _ := ret[0].(ackhandler.Frame)
@@ -108,19 +108,19 @@ func (c *MockMTUDiscovererGetPingCall) Return(ping ackhandler.Frame, datagramSiz
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockMTUDiscovererGetPingCall) Do(f func(time.Time) (ackhandler.Frame, protocol.ByteCount)) *MockMTUDiscovererGetPingCall {
+func (c *MockMTUDiscovererGetPingCall) Do(f func(monotime.Time) (ackhandler.Frame, protocol.ByteCount)) *MockMTUDiscovererGetPingCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockMTUDiscovererGetPingCall) DoAndReturn(f func(time.Time) (ackhandler.Frame, protocol.ByteCount)) *MockMTUDiscovererGetPingCall {
+func (c *MockMTUDiscovererGetPingCall) DoAndReturn(f func(monotime.Time) (ackhandler.Frame, protocol.ByteCount)) *MockMTUDiscovererGetPingCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // Reset mocks base method.
-func (m *MockMTUDiscoverer) Reset(now time.Time, start, max protocol.ByteCount) {
+func (m *MockMTUDiscoverer) Reset(now monotime.Time, start, max protocol.ByteCount) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "Reset", now, start, max)
 }
@@ -144,19 +144,19 @@ func (c *MockMTUDiscovererResetCall) Return() *MockMTUDiscovererResetCall {
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockMTUDiscovererResetCall) Do(f func(time.Time, protocol.ByteCount, protocol.ByteCount)) *MockMTUDiscovererResetCall {
+func (c *MockMTUDiscovererResetCall) Do(f func(monotime.Time, protocol.ByteCount, protocol.ByteCount)) *MockMTUDiscovererResetCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockMTUDiscovererResetCall) DoAndReturn(f func(time.Time, protocol.ByteCount, protocol.ByteCount)) *MockMTUDiscovererResetCall {
+func (c *MockMTUDiscovererResetCall) DoAndReturn(f func(monotime.Time, protocol.ByteCount, protocol.ByteCount)) *MockMTUDiscovererResetCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // ShouldSendProbe mocks base method.
-func (m *MockMTUDiscoverer) ShouldSendProbe(now time.Time) bool {
+func (m *MockMTUDiscoverer) ShouldSendProbe(now monotime.Time) bool {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "ShouldSendProbe", now)
        ret0, _ := ret[0].(bool)
@@ -182,19 +182,19 @@ func (c *MockMTUDiscovererShouldSendProbeCall) Return(arg0 bool) *MockMTUDiscove
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockMTUDiscovererShouldSendProbeCall) Do(f func(time.Time) bool) *MockMTUDiscovererShouldSendProbeCall {
+func (c *MockMTUDiscovererShouldSendProbeCall) Do(f func(monotime.Time) bool) *MockMTUDiscovererShouldSendProbeCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockMTUDiscovererShouldSendProbeCall) DoAndReturn(f func(time.Time) bool) *MockMTUDiscovererShouldSendProbeCall {
+func (c *MockMTUDiscovererShouldSendProbeCall) DoAndReturn(f func(monotime.Time) bool) *MockMTUDiscovererShouldSendProbeCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // Start mocks base method.
-func (m *MockMTUDiscoverer) Start(now time.Time) {
+func (m *MockMTUDiscoverer) Start(now monotime.Time) {
        m.ctrl.T.Helper()
        m.ctrl.Call(m, "Start", now)
 }
@@ -218,13 +218,13 @@ func (c *MockMTUDiscovererStartCall) Return() *MockMTUDiscovererStartCall {
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockMTUDiscovererStartCall) Do(f func(time.Time)) *MockMTUDiscovererStartCall {
+func (c *MockMTUDiscovererStartCall) Do(f func(monotime.Time)) *MockMTUDiscovererStartCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockMTUDiscovererStartCall) DoAndReturn(f func(time.Time)) *MockMTUDiscovererStartCall {
+func (c *MockMTUDiscovererStartCall) DoAndReturn(f func(monotime.Time)) *MockMTUDiscovererStartCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 106f11d4fdc69cd0035701a51152d195d250f202..416f6b0dd38424bd5769886a7de079deeb1391e2 100644 (file)
@@ -11,9 +11,9 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
        ackhandler "github.com/quic-go/quic-go/internal/ackhandler"
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        qerr "github.com/quic-go/quic-go/internal/qerr"
        gomock "go.uber.org/mock/gomock"
@@ -44,7 +44,7 @@ func (m *MockPacker) EXPECT() *MockPackerMockRecorder {
 }
 
 // AppendPacket mocks base method.
-func (m *MockPacker) AppendPacket(arg0 *packetBuffer, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) {
+func (m *MockPacker) AppendPacket(arg0 *packetBuffer, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "AppendPacket", arg0, maxPacketSize, now, v)
        ret0, _ := ret[0].(shortHeaderPacket)
@@ -71,19 +71,19 @@ func (c *MockPackerAppendPacketCall) Return(arg0 shortHeaderPacket, arg1 error)
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockPackerAppendPacketCall) Do(f func(*packetBuffer, protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, error)) *MockPackerAppendPacketCall {
+func (c *MockPackerAppendPacketCall) Do(f func(*packetBuffer, protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, error)) *MockPackerAppendPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockPackerAppendPacketCall) DoAndReturn(f func(*packetBuffer, protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, error)) *MockPackerAppendPacketCall {
+func (c *MockPackerAppendPacketCall) DoAndReturn(f func(*packetBuffer, protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, error)) *MockPackerAppendPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
 
 // PackAckOnlyPacket mocks base method.
-func (m *MockPacker) PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+func (m *MockPacker) PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "PackAckOnlyPacket", maxPacketSize, now, v)
        ret0, _ := ret[0].(shortHeaderPacket)
@@ -111,13 +111,13 @@ func (c *MockPackerPackAckOnlyPacketCall) Return(arg0 shortHeaderPacket, arg1 *p
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockPackerPackAckOnlyPacketCall) Do(f func(protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error)) *MockPackerPackAckOnlyPacketCall {
+func (c *MockPackerPackAckOnlyPacketCall) Do(f func(protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error)) *MockPackerPackAckOnlyPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockPackerPackAckOnlyPacketCall) DoAndReturn(f func(protocol.ByteCount, time.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error)) *MockPackerPackAckOnlyPacketCall {
+func (c *MockPackerPackAckOnlyPacketCall) DoAndReturn(f func(protocol.ByteCount, monotime.Time, protocol.Version) (shortHeaderPacket, *packetBuffer, error)) *MockPackerPackAckOnlyPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -162,7 +162,7 @@ func (c *MockPackerPackApplicationCloseCall) DoAndReturn(f func(*qerr.Applicatio
 }
 
 // PackCoalescedPacket mocks base method.
-func (m *MockPacker) PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) {
+func (m *MockPacker) PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*coalescedPacket, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "PackCoalescedPacket", onlyAck, maxPacketSize, now, v)
        ret0, _ := ret[0].(*coalescedPacket)
@@ -189,13 +189,13 @@ func (c *MockPackerPackCoalescedPacketCall) Return(arg0 *coalescedPacket, arg1 e
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockPackerPackCoalescedPacketCall) Do(f func(bool, protocol.ByteCount, time.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackCoalescedPacketCall {
+func (c *MockPackerPackCoalescedPacketCall) Do(f func(bool, protocol.ByteCount, monotime.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackCoalescedPacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockPackerPackCoalescedPacketCall) DoAndReturn(f func(bool, protocol.ByteCount, time.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackCoalescedPacketCall {
+func (c *MockPackerPackCoalescedPacketCall) DoAndReturn(f func(bool, protocol.ByteCount, monotime.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackCoalescedPacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
@@ -280,7 +280,7 @@ func (c *MockPackerPackMTUProbePacketCall) DoAndReturn(f func(ackhandler.Frame,
 }
 
 // PackPTOProbePacket mocks base method.
-func (m *MockPacker) PackPTOProbePacket(arg0 protocol.EncryptionLevel, arg1 protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error) {
+func (m *MockPacker) PackPTOProbePacket(arg0 protocol.EncryptionLevel, arg1 protocol.ByteCount, addPingIfEmpty bool, now monotime.Time, v protocol.Version) (*coalescedPacket, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "PackPTOProbePacket", arg0, arg1, addPingIfEmpty, now, v)
        ret0, _ := ret[0].(*coalescedPacket)
@@ -307,13 +307,13 @@ func (c *MockPackerPackPTOProbePacketCall) Return(arg0 *coalescedPacket, arg1 er
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockPackerPackPTOProbePacketCall) Do(f func(protocol.EncryptionLevel, protocol.ByteCount, bool, time.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackPTOProbePacketCall {
+func (c *MockPackerPackPTOProbePacketCall) Do(f func(protocol.EncryptionLevel, protocol.ByteCount, bool, monotime.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackPTOProbePacketCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockPackerPackPTOProbePacketCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.ByteCount, bool, time.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackPTOProbePacketCall {
+func (c *MockPackerPackPTOProbePacketCall) DoAndReturn(f func(protocol.EncryptionLevel, protocol.ByteCount, bool, monotime.Time, protocol.Version) (*coalescedPacket, error)) *MockPackerPackPTOProbePacketCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 6882ab554db90f8d655725536bf808dd6de00c35..6f635018bcb7694d444d4c90ce6b86ce09fe9cf4 100644 (file)
@@ -11,9 +11,9 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
        ackhandler "github.com/quic-go/quic-go/internal/ackhandler"
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        gomock "go.uber.org/mock/gomock"
 )
 
@@ -42,7 +42,7 @@ func (m *MockStreamControlFrameGetter) EXPECT() *MockStreamControlFrameGetterMoc
 }
 
 // getControlFrame mocks base method.
-func (m *MockStreamControlFrameGetter) getControlFrame(arg0 time.Time) (ackhandler.Frame, bool, bool) {
+func (m *MockStreamControlFrameGetter) getControlFrame(arg0 monotime.Time) (ackhandler.Frame, bool, bool) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "getControlFrame", arg0)
        ret0, _ := ret[0].(ackhandler.Frame)
@@ -70,13 +70,13 @@ func (c *MockStreamControlFrameGettergetControlFrameCall) Return(arg0 ackhandler
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockStreamControlFrameGettergetControlFrameCall) Do(f func(time.Time) (ackhandler.Frame, bool, bool)) *MockStreamControlFrameGettergetControlFrameCall {
+func (c *MockStreamControlFrameGettergetControlFrameCall) Do(f func(monotime.Time) (ackhandler.Frame, bool, bool)) *MockStreamControlFrameGettergetControlFrameCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockStreamControlFrameGettergetControlFrameCall) DoAndReturn(f func(time.Time) (ackhandler.Frame, bool, bool)) *MockStreamControlFrameGettergetControlFrameCall {
+func (c *MockStreamControlFrameGettergetControlFrameCall) DoAndReturn(f func(monotime.Time) (ackhandler.Frame, bool, bool)) *MockStreamControlFrameGettergetControlFrameCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index b2f64dbb8e03c2236874258031a72dcee630971d..54ed4d3de77b72eed003ed3ffbd2cdf73eec6797 100644 (file)
@@ -11,8 +11,8 @@ package quic
 
 import (
        reflect "reflect"
-       time "time"
 
+       monotime "github.com/quic-go/quic-go/internal/monotime"
        protocol "github.com/quic-go/quic-go/internal/protocol"
        wire "github.com/quic-go/quic-go/internal/wire"
        gomock "go.uber.org/mock/gomock"
@@ -82,7 +82,7 @@ func (c *MockUnpackerUnpackLongHeaderCall) DoAndReturn(f func(*wire.Header, []by
 }
 
 // UnpackShortHeader mocks base method.
-func (m *MockUnpacker) UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+func (m *MockUnpacker) UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
        m.ctrl.T.Helper()
        ret := m.ctrl.Call(m, "UnpackShortHeader", rcvTime, data)
        ret0, _ := ret[0].(protocol.PacketNumber)
@@ -112,13 +112,13 @@ func (c *MockUnpackerUnpackShortHeaderCall) Return(arg0 protocol.PacketNumber, a
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *MockUnpackerUnpackShortHeaderCall) Do(f func(time.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *MockUnpackerUnpackShortHeaderCall {
+func (c *MockUnpackerUnpackShortHeaderCall) Do(f func(monotime.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *MockUnpackerUnpackShortHeaderCall {
        c.Call = c.Call.Do(f)
        return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *MockUnpackerUnpackShortHeaderCall) DoAndReturn(f func(time.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *MockUnpackerUnpackShortHeaderCall {
+func (c *MockUnpackerUnpackShortHeaderCall) DoAndReturn(f func(monotime.Time, []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)) *MockUnpackerUnpackShortHeaderCall {
        c.Call = c.Call.DoAndReturn(f)
        return c
 }
index 096eba1466325cd53a7a048bb1e6768e88c6c2c1..244cfe17cffbd3edeef81390386e222af44b9686 100644 (file)
@@ -1,9 +1,8 @@
 package quic
 
 import (
-       "time"
-
        "github.com/quic-go/quic-go/internal/ackhandler"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -13,11 +12,11 @@ import (
 type mtuDiscoverer interface {
        // Start starts the MTU discovery process.
        // It's unnecessary to call ShouldSendProbe before that.
-       Start(now time.Time)
-       ShouldSendProbe(now time.Time) bool
+       Start(now monotime.Time)
+       ShouldSendProbe(now monotime.Time) bool
        CurrentSize() protocol.ByteCount
-       GetPing(now time.Time) (ping ackhandler.Frame, datagramSize protocol.ByteCount)
-       Reset(now time.Time, start, max protocol.ByteCount)
+       GetPing(now monotime.Time) (ping ackhandler.Frame, datagramSize protocol.ByteCount)
+       Reset(now monotime.Time, start, max protocol.ByteCount)
 }
 
 const (
@@ -88,7 +87,7 @@ const (
 // MTU discovery concludes once the interval min and max has been narrowed down to maxMTUDiff.
 
 type mtuFinder struct {
-       lastProbeTime time.Time
+       lastProbeTime monotime.Time
 
        rttStats *utils.RTTStats
 
@@ -147,11 +146,11 @@ func (f *mtuFinder) max() protocol.ByteCount {
        return f.lost[len(f.lost)-1]
 }
 
-func (f *mtuFinder) Start(now time.Time) {
+func (f *mtuFinder) Start(now monotime.Time) {
        f.lastProbeTime = now // makes sure the first probe packet is not sent immediately
 }
 
-func (f *mtuFinder) ShouldSendProbe(now time.Time) bool {
+func (f *mtuFinder) ShouldSendProbe(now monotime.Time) bool {
        if f.lastProbeTime.IsZero() {
                return false
        }
@@ -161,7 +160,7 @@ func (f *mtuFinder) ShouldSendProbe(now time.Time) bool {
        return !now.Before(f.lastProbeTime.Add(mtuProbeDelay * f.rttStats.SmoothedRTT()))
 }
 
-func (f *mtuFinder) GetPing(now time.Time) (ackhandler.Frame, protocol.ByteCount) {
+func (f *mtuFinder) GetPing(now monotime.Time) (ackhandler.Frame, protocol.ByteCount) {
        var size protocol.ByteCount
        if f.lastProbeWasLost {
                size = (f.min + f.lost[0]) / 2
@@ -180,7 +179,7 @@ func (f *mtuFinder) CurrentSize() protocol.ByteCount {
        return f.min
 }
 
-func (f *mtuFinder) Reset(now time.Time, start, max protocol.ByteCount) {
+func (f *mtuFinder) Reset(now monotime.Time, start, max protocol.ByteCount) {
        f.generation++
        f.lastProbeTime = now
        f.lastProbeWasLost = false
index 733d0517ed78e83ef32c8e0b12f89eacff158c4b..4e89fd1a36764627e50c7b763290b46a80362797 100644 (file)
@@ -6,6 +6,7 @@ import (
        "testing"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/logging"
@@ -19,7 +20,7 @@ func TestMTUDiscovererTiming(t *testing.T) {
        rttStats.UpdateRTT(rtt, 0)
        d := newMTUDiscoverer(&rttStats, 1000, 2000, nil)
 
-       now := time.Now()
+       now := monotime.Now()
        require.False(t, d.ShouldSendProbe(now))
        d.Start(now)
        require.False(t, d.ShouldSendProbe(now))
@@ -39,7 +40,7 @@ func TestMTUDiscovererTiming(t *testing.T) {
 func TestMTUDiscovererAckAndLoss(t *testing.T) {
        d := newMTUDiscoverer(&utils.RTTStats{}, 1000, 2000, nil)
        // we use an RTT of 0 here, so we don't have to advance the timer on every step
-       now := time.Now()
+       now := monotime.Now()
        ping, size := d.GetPing(now)
        require.Equal(t, protocol.ByteCount(1500), size)
        // the MTU is reduced if the frame is lost
@@ -100,7 +101,7 @@ func testMTUDiscovererMTUDiscovery(t *testing.T) {
                        },
                },
        )
-       now := time.Now()
+       now := monotime.Now()
        d.Start(now)
        realMTU := protocol.ByteCount(rand.IntN(int(maxMTU-startMTU))) + startMTU
        t.Logf("MTU: %d, max: %d", realMTU, maxMTU)
@@ -158,8 +159,8 @@ func testMTUDiscovererWithRandomLoss(t *testing.T) {
                        },
                },
        )
-       d.Start(time.Now())
-       now := time.Now()
+       d.Start(monotime.Now())
+       now := monotime.Now()
        realMTU := protocol.ByteCount(rand.IntN(int(maxMTU-startMTU))) + startMTU
        t.Logf("MTU: %d, max: %d", realMTU, maxMTU)
        now = now.Add(mtuProbeDelay * rtt)
@@ -215,7 +216,7 @@ func testMTUDiscovererReset(t *testing.T, ackLastProbe bool) {
        rttStats := &utils.RTTStats{}
        rttStats.SetInitialRTT(rtt)
 
-       now := time.Now()
+       now := monotime.Now()
        d := newMTUDiscoverer(rttStats, startMTU, maxMTU, nil)
        d.Start(now)
 
index 992285340c7069f21e2ceb946b35584d802826f3..e3933da6bb2e8091aa7bbd7f6dd021acf75fe61d 100644 (file)
@@ -6,10 +6,10 @@ import (
        "errors"
        "fmt"
        "math/rand/v2"
-       "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/handshake"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -18,10 +18,10 @@ import (
 var errNothingToPack = errors.New("nothing to pack")
 
 type packer interface {
-       PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error)
-       PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error)
-       AppendPacket(_ *packetBuffer, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error)
-       PackPTOProbePacket(_ protocol.EncryptionLevel, _ protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error)
+       PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*coalescedPacket, error)
+       PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error)
+       AppendPacket(_ *packetBuffer, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, error)
+       PackPTOProbePacket(_ protocol.EncryptionLevel, _ protocol.ByteCount, addPingIfEmpty bool, now monotime.Time, v protocol.Version) (*coalescedPacket, error)
        PackConnectionClose(*qerr.TransportError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error)
        PackApplicationClose(*qerr.ApplicationError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error)
        PackPathProbePacket(protocol.ConnectionID, []ackhandler.Frame, protocol.Version) (shortHeaderPacket, *packetBuffer, error)
@@ -108,11 +108,11 @@ type sealingManager interface {
 
 type frameSource interface {
        HasData() bool
-       Append([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, time.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)
+       Append([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, monotime.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)
 }
 
 type ackFrameSource interface {
-       GetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame
+       GetAckFrame(_ protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame
 }
 
 type packetPacker struct {
@@ -330,7 +330,7 @@ func (p *packetPacker) initialPaddingLen(frames []ackhandler.Frame, currentSize,
 // PackCoalescedPacket packs a new packet.
 // It packs an Initial / Handshake if there is data to send in these packet number spaces.
 // It should only be called before the handshake is confirmed.
-func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) {
+func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*coalescedPacket, error) {
        var (
                initialHdr, handshakeHdr, zeroRTTHdr                            *wire.ExtendedHeader
                initialPayload, handshakePayload, zeroRTTPayload, oneRTTPayload payload
@@ -460,7 +460,7 @@ func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCo
 
 // PackAckOnlyPacket packs a packet containing only an ACK in the application data packet number space.
 // It should be called after the handshake is confirmed.
-func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
+func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {
        buf := getPacketBuffer()
        packet, err := p.appendPacket(buf, true, maxSize, now, v)
        return packet, buf, err
@@ -468,7 +468,7 @@ func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now time.Ti
 
 // AppendPacket packs a packet in the application data packet number space.
 // It should be called after the handshake is confirmed.
-func (p *packetPacker) AppendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) {
+func (p *packetPacker) AppendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, error) {
        return p.appendPacket(buf, false, maxSize, now, v)
 }
 
@@ -476,7 +476,7 @@ func (p *packetPacker) appendPacket(
        buf *packetBuffer,
        onlyAck bool,
        maxPacketSize protocol.ByteCount,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) (shortHeaderPacket, error) {
        sealer, err := p.cryptoSetup.Get1RTTSealer()
@@ -498,7 +498,7 @@ func (p *packetPacker) appendPacket(
 func (p *packetPacker) maybeGetCryptoPacket(
        maxPacketSize protocol.ByteCount,
        encLevel protocol.EncryptionLevel,
-       now time.Time,
+       now monotime.Time,
        addPingIfEmpty bool,
        onlyAck, ackAllowed bool,
        v protocol.Version,
@@ -578,7 +578,7 @@ func (p *packetPacker) maybeGetCryptoPacket(
        return hdr, pl
 }
 
-func (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*wire.ExtendedHeader, payload) {
+func (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*wire.ExtendedHeader, payload) {
        if p.perspective != protocol.PerspectiveClient {
                return nil, payload{}
        }
@@ -592,7 +592,7 @@ func (p *packetPacker) maybeGetShortHeaderPacket(
        sealer handshake.ShortHeaderSealer,
        hdrLen, maxPacketSize protocol.ByteCount,
        onlyAck, ackAllowed bool,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) payload {
        maxPayloadSize := maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead())
@@ -602,7 +602,7 @@ func (p *packetPacker) maybeGetShortHeaderPacket(
 func (p *packetPacker) maybeGetAppDataPacket(
        maxPayloadSize protocol.ByteCount,
        onlyAck, ackAllowed bool,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) payload {
        pl := p.composeNextPacket(maxPayloadSize, onlyAck, ackAllowed, now, v)
@@ -630,7 +630,7 @@ func (p *packetPacker) maybeGetAppDataPacket(
 func (p *packetPacker) composeNextPacket(
        maxPayloadSize protocol.ByteCount,
        onlyAck, ackAllowed bool,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) payload {
        if onlyAck {
@@ -716,7 +716,7 @@ func (p *packetPacker) PackPTOProbePacket(
        encLevel protocol.EncryptionLevel,
        maxPacketSize protocol.ByteCount,
        addPingIfEmpty bool,
-       now time.Time,
+       now monotime.Time,
        v protocol.Version,
 ) (*coalescedPacket, error) {
        if encLevel == protocol.Encryption1RTT {
@@ -769,7 +769,7 @@ func (p *packetPacker) PackPTOProbePacket(
        return packet, nil
 }
 
-func (p *packetPacker) packPTOProbePacket1RTT(maxPacketSize protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error) {
+func (p *packetPacker) packPTOProbePacket1RTT(maxPacketSize protocol.ByteCount, addPingIfEmpty bool, now monotime.Time, v protocol.Version) (*coalescedPacket, error) {
        s, err := p.cryptoSetup.Get1RTTSealer()
        if err != nil {
                return nil, err
index 423e506ee41ff35f89e4c378cd1ac2b04da93dec..6ffd6601ffd080868ef1ebb9f4ee874eec4b9c24 100644 (file)
@@ -5,12 +5,12 @@ import (
        "crypto/rand"
        "errors"
        "testing"
-       "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/handshake"
        "github.com/quic-go/quic-go/internal/mocks"
        mockackhandler "github.com/quic-go/quic-go/internal/mocks/ackhandler"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -108,7 +108,7 @@ func parseShortHeaderPacket(t *testing.T, data []byte, connIDLen int) {
 
 func expectAppendFrames(framer *MockFrameSource, controlFrames []ackhandler.Frame, streamFrames []ackhandler.StreamFrame) {
        framer.EXPECT().Append(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(cf []ackhandler.Frame, sf []ackhandler.StreamFrame, _ protocol.ByteCount, _ time.Time, v protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
+               func(cf []ackhandler.Frame, sf []ackhandler.StreamFrame, _ protocol.ByteCount, _ monotime.Time, v protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
                        var length protocol.ByteCount
                        for _, f := range controlFrames {
                                length += f.Frame.Length(v)
@@ -130,7 +130,7 @@ func TestPackLongHeaders(t *testing.T) {
        token := make([]byte, 20)
        rand.Read(token)
        tp.packer.SetToken(token)
-       now := time.Now()
+       now := monotime.Now()
 
        tp.pnManager.EXPECT().PeekPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24), protocol.PacketNumberLen3)
        tp.pnManager.EXPECT().PopPacketNumber(protocol.EncryptionInitial).Return(protocol.PacketNumber(0x24))
@@ -184,7 +184,7 @@ func TestPackCoalescedAckOnlyPacketNothingToSend(t *testing.T) {
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial, gomock.Any(), true)
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake, gomock.Any(), true)
        tp.ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, gomock.Any(), true)
-       p, err := tp.packer.PackCoalescedPacket(true, 1234, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(true, 1234, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Nil(t, p)
 }
@@ -203,7 +203,7 @@ func testPackInitialAckOnlyPacket(t *testing.T, pers protocol.Perspective) {
        tp.sealingManager.EXPECT().GetInitialSealer().Return(newMockShortHeaderSealer(mockCtrl), nil)
        ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial, gomock.Any(), true).Return(ack)
-       p, err := tp.packer.PackCoalescedPacket(true, maxPacketSize, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(true, maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p)
        require.Len(t, p.longHdrPackets, 1)
@@ -232,7 +232,7 @@ func TestPack1RTTAckOnlyPacket(t *testing.T) {
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(newMockShortHeaderSealer(mockCtrl), nil)
        ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 10}}}
        tp.ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, gomock.Any(), true).Return(ack)
-       p, buffer, err := tp.packer.PackAckOnlyPacket(maxPacketSize, time.Now(), protocol.Version1)
+       p, buffer, err := tp.packer.PackAckOnlyPacket(maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Equal(t, ack, p.Ack)
        require.Empty(t, p.Frames)
@@ -253,11 +253,11 @@ func TestPack0RTTPacket(t *testing.T) {
        tp.framer.EXPECT().HasData().Return(true)
        // TODO: check sizes
        tp.framer.EXPECT().Append(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
-               func(fs []ackhandler.Frame, sf []ackhandler.StreamFrame, _ protocol.ByteCount, _ time.Time, _ protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
+               func(fs []ackhandler.Frame, sf []ackhandler.StreamFrame, _ protocol.ByteCount, _ monotime.Time, _ protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
                        return append(fs, cf), sf, cf.Frame.Length(protocol.Version1)
                },
        )
-       p, err := tp.packer.PackCoalescedPacket(false, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(false, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p)
        require.Len(t, p.longHdrPackets, 1)
@@ -277,7 +277,7 @@ func TestPack0RTTPacketNoACK(t *testing.T) {
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial, gomock.Any(), true)
        // no further calls to get an ACK frame
-       p, err := tp.packer.PackCoalescedPacket(true, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(true, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Nil(t, p)
 }
@@ -300,7 +300,7 @@ func TestPackCoalescedAppData(t *testing.T) {
        tp.handshakeStream.Write([]byte("handshake"))
        expectAppendFrames(tp.framer, nil, []ackhandler.StreamFrame{{Frame: &wire.StreamFrame{Data: []byte("foobar")}}})
 
-       p, err := tp.packer.PackCoalescedPacket(false, maxPacketSize, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(false, maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Less(t, p.buffer.Len(), protocol.ByteCount(100))
        require.Len(t, p.longHdrPackets, 1)
@@ -460,7 +460,7 @@ func TestPack1RTTPacketNothingToSend(t *testing.T) {
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(newMockShortHeaderSealer(mockCtrl), nil)
        tp.ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, gomock.Any(), true)
        tp.framer.EXPECT().HasData()
-       _, err := tp.packer.AppendPacket(getPacketBuffer(), protocol.MaxByteCount, time.Now(), protocol.Version1)
+       _, err := tp.packer.AppendPacket(getPacketBuffer(), protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.ErrorIs(t, err, errNothingToPack)
 }
 
@@ -486,7 +486,7 @@ func TestPack1RTTPacketWithData(t *testing.T) {
        )
        buffer := getPacketBuffer()
        buffer.Data = append(buffer.Data, []byte("foobar")...)
-       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        b, err := f.Append(nil, protocol.Version1)
        require.NoError(t, err)
@@ -519,7 +519,7 @@ func TestPack1RTTPacketWithACK(t *testing.T) {
        tp.framer.EXPECT().HasData()
        tp.ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, gomock.Any(), true).Return(ack)
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(newMockShortHeaderSealer(mockCtrl), nil)
-       p, err := tp.packer.AppendPacket(getPacketBuffer(), protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(getPacketBuffer(), protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Equal(t, ack, p.Ack)
 }
@@ -539,7 +539,7 @@ func TestPackPathChallengeAndPathResponse(t *testing.T) {
        }
        expectAppendFrames(tp.framer, frames, nil)
        buffer := getPacketBuffer()
-       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Len(t, p.Frames, 3)
        var sawPathChallenge, sawPathResponse bool
@@ -576,7 +576,7 @@ func TestPackDatagramFrames(t *testing.T) {
        })
        tp.framer.EXPECT().HasData()
        buffer := getPacketBuffer()
-       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Len(t, p.Frames, 1)
        require.IsType(t, &wire.DatagramFrame{}, p.Frames[0].Frame)
@@ -598,7 +598,7 @@ func TestPackLargeDatagramFrame(t *testing.T) {
        tp.datagramQueue.Add(f)
        tp.framer.EXPECT().HasData()
        buffer := getPacketBuffer()
-       p, err := tp.packer.AppendPacket(buffer, maxPacketSize, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(buffer, maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p.Ack)
        require.Empty(t, p.Frames)
@@ -613,7 +613,7 @@ func TestPackLargeDatagramFrame(t *testing.T) {
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(newMockShortHeaderSealer(mockCtrl), nil)
        tp.framer.EXPECT().HasData()
        buffer = getPacketBuffer()
-       p, err = tp.packer.AppendPacket(buffer, newMaxPacketSize, time.Now(), protocol.Version1)
+       p, err = tp.packer.AppendPacket(buffer, newMaxPacketSize, monotime.Now(), protocol.Version1)
        require.ErrorIs(t, err, errNothingToPack)
        require.Nil(t, tp.datagramQueue.Peek()) // make sure the frame is gone
 }
@@ -630,7 +630,7 @@ func TestPackRetransmissions(t *testing.T) {
        tp.sealingManager.EXPECT().GetHandshakeSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
        tp.sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionInitial, gomock.Any(), false)
-       p, err := tp.packer.PackCoalescedPacket(false, 1000, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackCoalescedPacket(false, 1000, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Len(t, p.longHdrPackets, 1)
        require.Equal(t, protocol.EncryptionInitial, p.longHdrPackets[0].EncryptionLevel())
@@ -650,7 +650,7 @@ func packMaxNumNonAckElicitingAcks(t *testing.T, tp *testPacketPacker, mockCtrl
                        &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}},
                )
                expectAppendFrames(tp.framer, nil, nil)
-               p, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, time.Now(), protocol.Version1)
+               p, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, monotime.Now(), protocol.Version1)
                require.NoError(t, err)
                require.NotNil(t, p.Ack)
                require.Empty(t, p.Frames)
@@ -671,7 +671,7 @@ func TestPackEvery20thPacketAckEliciting(t *testing.T) {
        tp.ackFramer.EXPECT().GetAckFrame(protocol.Encryption1RTT, gomock.Any(), false)
        tp.framer.EXPECT().HasData().Return(true)
        expectAppendFrames(tp.framer, nil, nil)
-       _, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, time.Now(), protocol.Version1)
+       _, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, monotime.Now(), protocol.Version1)
        require.ErrorIs(t, err, errNothingToPack)
 
        // Now we have an ACK to send. We should bundle a PING to make the packet ack-eliciting.
@@ -683,7 +683,7 @@ func TestPackEvery20thPacketAckEliciting(t *testing.T) {
                &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}},
        )
        expectAppendFrames(tp.framer, nil, nil)
-       p, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, time.Now(), protocol.Version1)
+       p, err := tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Len(t, p.Frames, 1)
        require.Equal(t, &wire.PingFrame{}, p.Frames[0].Frame)
@@ -698,7 +698,7 @@ func TestPackEvery20thPacketAckEliciting(t *testing.T) {
                &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}},
        )
        expectAppendFrames(tp.framer, nil, nil)
-       p, err = tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, time.Now(), protocol.Version1)
+       p, err = tp.packer.AppendPacket(getPacketBuffer(), maxPacketSize, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p.Ack)
        require.Empty(t, p.Frames)
@@ -717,7 +717,7 @@ func TestPackLongHeaderPadToAtLeast4Bytes(t *testing.T) {
        tp.retransmissionQueue.addHandshake(&wire.PingFrame{})
        tp.ackFramer.EXPECT().GetAckFrame(protocol.EncryptionHandshake, gomock.Any(), false)
 
-       packet, err := tp.packer.PackCoalescedPacket(false, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       packet, err := tp.packer.PackCoalescedPacket(false, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, packet)
        require.Len(t, packet.longHdrPackets, 1)
@@ -763,7 +763,7 @@ func TestPackShortHeaderPadToAtLeast4Bytes(t *testing.T) {
        expectAppendFrames(tp.framer, nil, []ackhandler.StreamFrame{{Frame: f}})
 
        buffer := getPacketBuffer()
-       _, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, time.Now(), protocol.Version1)
+       _, err := tp.packer.AppendPacket(buffer, protocol.MaxByteCount, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        // cut off the tag that the mock sealer added
        buffer.Data = buffer.Data[:buffer.Len()-protocol.ByteCount(sealer.Overhead())]
@@ -829,7 +829,7 @@ func testPackProbePacket(t *testing.T, encLevel protocol.EncryptionLevel, perspe
        tp.pnManager.EXPECT().PeekPacketNumber(encLevel).Return(protocol.PacketNumber(0x42), protocol.PacketNumberLen2)
        tp.pnManager.EXPECT().PopPacketNumber(encLevel).Return(protocol.PacketNumber(0x42))
 
-       p, err := tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, false, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, false, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p)
        require.Len(t, p.longHdrPackets, 1)
@@ -863,14 +863,14 @@ func TestPack1RTTProbePacket(t *testing.T) {
        tp.pnManager.EXPECT().PopPacketNumber(protocol.Encryption1RTT).Return(protocol.PacketNumber(0x42))
        tp.framer.EXPECT().HasData().Return(true)
        tp.framer.EXPECT().Append(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), protocol.Version1).DoAndReturn(
-               func(cf []ackhandler.Frame, sf []ackhandler.StreamFrame, size protocol.ByteCount, _ time.Time, v protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
+               func(cf []ackhandler.Frame, sf []ackhandler.StreamFrame, size protocol.ByteCount, _ monotime.Time, v protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {
                        f, split := (&wire.StreamFrame{Data: make([]byte, 2*maxPacketSize)}).MaybeSplitOffFrame(size, v)
                        require.True(t, split)
                        return cf, append(sf, ackhandler.StreamFrame{Frame: f}), f.Length(v)
                },
        )
 
-       p, err := tp.packer.PackPTOProbePacket(protocol.Encryption1RTT, maxPacketSize, false, time.Now(), protocol.Version1)
+       p, err := tp.packer.PackPTOProbePacket(protocol.Encryption1RTT, maxPacketSize, false, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, p)
        require.True(t, p.IsOnlyShortHeaderPacket())
@@ -912,13 +912,13 @@ func testPackPTOProbePacketNothingToPack(t *testing.T, encLevel protocol.Encrypt
        tp.ackFramer.EXPECT().GetAckFrame(encLevel, gomock.Any(), true).Times(2)
 
        // don't force a PING to be sent
-       packet, err := tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, false, time.Now(), protocol.Version1)
+       packet, err := tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, false, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.Nil(t, packet)
 
        // now force a PING to be sent
        tp.pnManager.EXPECT().PopPacketNumber(encLevel).Return(protocol.PacketNumber(0x42))
-       packet, err = tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, true, time.Now(), protocol.Version1)
+       packet, err = tp.packer.PackPTOProbePacket(encLevel, maxPacketSize, true, monotime.Now(), protocol.Version1)
        require.NoError(t, err)
        require.NotNil(t, packet)
        var frames []ackhandler.Frame
index 2f607fbd8cc4c4ec15430043ce454061012db4a0..0729636e2a3283825bb7525c2dd785eee29ee375 100644 (file)
@@ -2,9 +2,9 @@ package quic
 
 import (
        "fmt"
-       "time"
 
        "github.com/quic-go/quic-go/internal/handshake"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -106,7 +106,7 @@ func (u *packetUnpacker) UnpackLongHeader(hdr *wire.Header, data []byte) (*unpac
        }, nil
 }
 
-func (u *packetUnpacker) UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+func (u *packetUnpacker) UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
        opener, err := u.cs.Get1RTTOpener()
        if err != nil {
                return 0, 0, 0, nil, err
@@ -144,7 +144,7 @@ func (u *packetUnpacker) unpackLongHeaderPacket(opener handshake.LongHeaderOpene
        return extHdr, decrypted, nil
 }
 
-func (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
+func (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {
        l, pn, pnLen, kp, parseErr := u.unpackShortHeader(opener, data)
        // If the reserved bits are set incorrectly, we still need to continue unpacking.
        // This avoids a timing side-channel, which otherwise might allow an attacker
index 75f0db876406df70efad50ba75a70d7b852f2f60..4fc234f1318aaf056069a94cb99323521f2780eb 100644 (file)
@@ -3,10 +3,10 @@ package quic
 import (
        "crypto/rand"
        "testing"
-       "time"
 
        "github.com/quic-go/quic-go/internal/handshake"
        "github.com/quic-go/quic-go/internal/mocks"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -211,7 +211,7 @@ func testUnpackShortHeaderPacket(t *testing.T, incorrectReservedBits bool, decry
        opener.EXPECT().Open(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(
                decryptResult.decrypted, decryptResult.err,
        )
-       pn, pnLen, kp, data, err := unpacker.UnpackShortHeader(time.Now(), append(hdrRaw, payload...))
+       pn, pnLen, kp, data, err := unpacker.UnpackShortHeader(monotime.Now(), append(hdrRaw, payload...))
        if expectedErr != nil {
                require.ErrorIs(t, err, expectedErr)
                return
@@ -282,7 +282,7 @@ func TestUnpackHeaderSampleShortHeader(t *testing.T) {
 
        t.Run("too short", func(t *testing.T) {
                cs.EXPECT().Get1RTTOpener().Return(mocks.NewMockShortHeaderOpener(mockCtrl), nil)
-               _, _, _, _, err = unpacker.UnpackShortHeader(time.Now(), data[:len(data)-1])
+               _, _, _, _, err = unpacker.UnpackShortHeader(monotime.Now(), data[:len(data)-1])
                require.IsType(t, &headerParseError{}, err)
                require.ErrorContains(t, err, "packet too small, expected at least 20 bytes after the header, got 19")
        })
@@ -293,7 +293,7 @@ func TestUnpackHeaderSampleShortHeader(t *testing.T) {
                opener.EXPECT().DecryptHeader(data[len(data)-16:], gomock.Any(), gomock.Any())
                opener.EXPECT().DecodePacketNumber(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(1337))
                opener.EXPECT().Open(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]byte("decrypted"), nil)
-               _, _, _, _, err = unpacker.UnpackShortHeader(time.Now(), data)
+               _, _, _, _, err = unpacker.UnpackShortHeader(monotime.Now(), data)
                require.NoError(t, err)
        })
 }
index 34096654b181f44a0a43cc7e2fc589b19ad4e4ae..dd188ea1488eb8f5b9a384e1e17bf4a2384d0d7a 100644 (file)
@@ -7,6 +7,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -30,7 +31,7 @@ const pathTimeout = 5 * time.Second
 type path struct {
        id             pathID
        addr           net.Addr
-       lastPacketTime time.Time
+       lastPacketTime monotime.Time
        pathChallenge  [8]byte
        validated      bool
        rcvdNonProbing bool
@@ -64,7 +65,7 @@ func newPathManager(
 // May return nil.
 func (pm *pathManager) HandlePacket(
        remoteAddr net.Addr,
-       t time.Time,
+       t monotime.Time,
        pathChallenge *wire.PathChallengeFrame, // may be nil if the packet didn't contain a PATH_CHALLENGE
        isNonProbing bool,
 ) (_ protocol.ConnectionID, _ []ackhandler.Frame, shouldSwitch bool) {
index 6109318a7fdc52b9baa30831edb9408968f6d610..ca84df1bbb14df1576fe70dccb08a188da3b8ff8 100644 (file)
@@ -7,6 +7,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/ackhandler"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -29,7 +30,7 @@ func TestPathManagerIntentionalMigration(t *testing.T) {
                func(id pathID) { retiredConnIDs = append(retiredConnIDs, connIDs[id]) },
                utils.DefaultLogger,
        )
-       now := time.Now()
+       now := monotime.Now()
        connID, frames, shouldSwitch := pm.HandlePacket(
                &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 1000},
                now,
@@ -132,7 +133,7 @@ func TestPathManagerMultipleProbes(t *testing.T) {
                func(id pathID) {},
                utils.DefaultLogger,
        )
-       now := time.Now()
+       now := monotime.Now()
        // first receive a packet without a PATH_CHALLENGE
        connID, frames, shouldSwitch := pm.HandlePacket(
                &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 1000},
@@ -187,7 +188,7 @@ func TestPathManagerNATRebinding(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       now := time.Now()
+       now := monotime.Now()
        connID, frames, shouldSwitch := pm.HandlePacket(&net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 1000}, now, nil, true)
        require.Equal(t, connIDs[0], connID)
        require.Len(t, frames, 1)
@@ -219,7 +220,7 @@ func TestPathManagerLimits(t *testing.T) {
                utils.DefaultLogger,
        )
 
-       now := time.Now()
+       now := monotime.Now()
        firstPathTime := now
        var firstPathConnID protocol.ConnectionID
        require.Greater(t, pathTimeout, maxPaths*time.Second)
index 61f4cdf4244c44777fc346668b4949354861ca8d..76d2967dc91f049d84c5e4c5bdba5be2d3a1af5c 100644 (file)
@@ -8,6 +8,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -47,7 +48,7 @@ type ReceiveStream struct {
 
        readChan chan struct{}
        readOnce chan struct{} // cap: 1, to protect against concurrent use of Read
-       deadline time.Time
+       deadline monotime.Time
 
        flowController flowcontrol.StreamFlowController
 }
@@ -161,7 +162,7 @@ func (s *ReceiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW
 
                        deadline := s.deadline
                        if !deadline.IsZero() {
-                               if !time.Now().Before(deadline) {
+                               if !monotime.Now().Before(deadline) {
                                        return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline
                                }
                                if deadlineTimer == nil {
@@ -283,7 +284,7 @@ func (s *ReceiveStream) cancelReadImpl(errorCode qerr.StreamErrorCode) (queuedNe
        return true
 }
 
-func (s *ReceiveStream) handleStreamFrame(frame *wire.StreamFrame, now time.Time) error {
+func (s *ReceiveStream) handleStreamFrame(frame *wire.StreamFrame, now monotime.Time) error {
        s.mutex.Lock()
        err := s.handleStreamFrameImpl(frame, now)
        completed := s.isNewlyCompleted()
@@ -296,7 +297,7 @@ func (s *ReceiveStream) handleStreamFrame(frame *wire.StreamFrame, now time.Time
        return err
 }
 
-func (s *ReceiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now time.Time) error {
+func (s *ReceiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now monotime.Time) error {
        maxOffset := frame.Offset + frame.DataLen()
        if err := s.flowController.UpdateHighestReceived(maxOffset, frame.Fin, now); err != nil {
                return err
@@ -314,7 +315,7 @@ func (s *ReceiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now time.
        return nil
 }
 
-func (s *ReceiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now time.Time) error {
+func (s *ReceiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now monotime.Time) error {
        s.mutex.Lock()
        err := s.handleResetStreamFrameImpl(frame, now)
        completed := s.isNewlyCompleted()
@@ -326,7 +327,7 @@ func (s *ReceiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now
        return err
 }
 
-func (s *ReceiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, now time.Time) error {
+func (s *ReceiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, now monotime.Time) error {
        if s.closeForShutdownErr != nil {
                return nil
        }
@@ -358,7 +359,7 @@ func (s *ReceiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame,
        return nil
 }
 
-func (s *ReceiveStream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) {
+func (s *ReceiveStream) getControlFrame(now monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) {
        s.mutex.Lock()
        defer s.mutex.Unlock()
 
@@ -386,7 +387,7 @@ func (s *ReceiveStream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok,
 // A zero value for t means Read will not time out.
 func (s *ReceiveStream) SetReadDeadline(t time.Time) error {
        s.mutex.Lock()
-       s.deadline = t
+       s.deadline = monotime.FromTime(t)
        s.mutex.Unlock()
        s.signalRead()
        return nil
index 9a8238f49d18740773ac254a8a7436c42270e7b2..cce71aa7b47e049f9730c6592a64c347eabb7349 100644 (file)
@@ -10,6 +10,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/mocks"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/synctest"
        "github.com/quic-go/quic-go/internal/wire"
@@ -45,7 +46,7 @@ func TestReceiveStreamReadData(t *testing.T) {
        str := newReceiveStream(42, nil, mockFC)
 
        // read an entire frame
-       now := time.Now()
+       now := monotime.Now()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(4), false, now)
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(4))
        require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte{0xde, 0xad, 0xbe, 0xef}}, now))
@@ -108,17 +109,17 @@ func TestReceiveStreamBlockRead(t *testing.T) {
                mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(2), false, gomock.Any())
                mockFC.EXPECT().AddBytesRead(protocol.ByteCount(2))
                errChan := make(chan error, 1)
-               now := time.Now()
+               now := monotime.Now()
                go func() {
                        frame := &wire.StreamFrame{Data: []byte{0xde, 0xad}}
                        time.Sleep(time.Hour)
-                       errChan <- str.handleStreamFrame(frame, time.Now())
+                       errChan <- str.handleStreamFrame(frame, monotime.Now())
                }()
 
                n, err := (&readerWithTimeout{Reader: str, Timeout: 2 * time.Hour}).Read(make([]byte, 2))
                require.NoError(t, err)
                require.Equal(t, 2, n)
-               require.Equal(t, now.Add(time.Hour), time.Now())
+               require.Equal(t, now.Add(time.Hour), monotime.Now())
                require.NoError(t, <-errChan)
        })
 }
@@ -129,7 +130,7 @@ func TestReceiveStreamReadOverlappingData(t *testing.T) {
        str := newReceiveStream(42, nil, mockFC)
 
        // receive the same frame multiple times
-       now := time.Now()
+       now := monotime.Now()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(4), false, now).Times(3)
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(4))
        for range 3 {
@@ -174,7 +175,7 @@ func testReceiveStreamFlowControlUpdates(t *testing.T, hasStreamWindowUpdate, ha
        mockSender := NewMockStreamSender(mockCtrl)
        str := newReceiveStream(streamID, mockSender, mockFC)
 
-       now := time.Now()
+       now := monotime.Now()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(4), false, now)
        require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte{0xde, 0xad, 0xbe, 0xef}}, now))
 
@@ -212,7 +213,7 @@ func TestReceiveStreamDeadlineInThePast(t *testing.T) {
 
        // no data is read when the deadline is in the past
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any()).AnyTimes()
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
        require.NoError(t, str.SetReadDeadline(time.Now().Add(-time.Second)))
        b := make([]byte, 6)
        n, err := (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(b)
@@ -278,7 +279,7 @@ func TestReceiveStreamDeadlineExtension(t *testing.T) {
                mockFC := mocks.NewMockStreamFlowController(mockCtrl)
                str := newReceiveStream(42, nil, mockFC)
 
-               start := time.Now()
+               start := monotime.Now()
                deadline := 5 * time.Second
                require.NoError(t, str.SetReadDeadline(time.Now().Add(deadline)))
                errChan := make(chan error, 1)
@@ -297,7 +298,7 @@ func TestReceiveStreamDeadlineExtension(t *testing.T) {
                select {
                case err := <-errChan:
                        require.ErrorIs(t, err, os.ErrDeadlineExceeded)
-                       require.Equal(t, start.Add(deadline*3/2), time.Now())
+                       require.Equal(t, start.Add(deadline*3/2), monotime.Now())
                case <-time.After(deadline + time.Nanosecond):
                        t.Fatal("timeout")
                }
@@ -310,7 +311,7 @@ func TestReceiveStreamEOFWithData(t *testing.T) {
        mockSender := NewMockStreamSender(mockCtrl)
        str := newReceiveStream(42, mockSender, mockFC)
 
-       now := time.Now()
+       now := monotime.Now()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(4), true, now)
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(2), false, now)
        require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Offset: 2, Data: []byte{0xbe, 0xef}, Fin: true}, now))
@@ -336,7 +337,7 @@ func TestReceiveStreamImmediateFINs(t *testing.T) {
        str := newReceiveStream(42, mockSender, mockFC)
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(0), true, gomock.Any())
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(0))
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Fin: true}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Fin: true}, monotime.Now()))
        mockSender.EXPECT().onStreamCompleted(protocol.StreamID(42))
        n, err := (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(make([]byte, 4))
        require.Zero(t, n)
@@ -382,7 +383,7 @@ func TestReceiveStreamCloseForShutdown(t *testing.T) {
                require.ErrorIs(t, err, assert.AnError)
 
                // receiving a RESET_STREAM frame after closeForShutdown does nothing
-               require.NoError(t, str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1234, FinalSize: 42}, time.Now()))
+               require.NoError(t, str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1234, FinalSize: 42}, monotime.Now()))
                n, err = strWithTimeout.Read([]byte{0})
                require.Zero(t, n)
                require.ErrorIs(t, err, assert.AnError)
@@ -414,7 +415,7 @@ func TestReceiveStreamCancellation(t *testing.T) {
 
                str.CancelRead(1234)
                // this queues a STOP_SENDING frame
-               f, ok, hasMore := str.getControlFrame(time.Now())
+               f, ok, hasMore := str.getControlFrame(monotime.Now())
                require.True(t, ok)
                require.Equal(t, &wire.StopSendingFrame{StreamID: 42, ErrorCode: 1234}, f.Frame)
                require.False(t, hasMore)
@@ -453,14 +454,14 @@ func TestReceiveStreamCancellation(t *testing.T) {
                mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), true, gomock.Any()).Times(2)
                mockSender.EXPECT().onStreamCompleted(protocol.StreamID(42))
                // receive two of them, to make sure onStreamCompleted is not called twice
-               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, time.Now()))
-               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, time.Now()))
+               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, monotime.Now()))
+               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, monotime.Now()))
                require.True(t, mockCtrl.Satisfied())
 
                // receiving a RESET_STREAM frame after CancelRead has no effect
                mockFC.EXPECT().Abandon()
                mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true, gomock.Any())
-               require.NoError(t, str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 4321, FinalSize: 42}, time.Now()))
+               require.NoError(t, str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 4321, FinalSize: 42}, monotime.Now()))
                n, err = strWithTimeout.Read([]byte{0})
                require.Zero(t, n)
                require.ErrorIs(t, err, &StreamError{StreamID: 42, ErrorCode: 1234, Remote: false})
@@ -484,7 +485,7 @@ func testReceiveStreamCancelReadAfterFIN(t *testing.T, finRead bool) {
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), true, gomock.Any())
        mockSender.EXPECT().onStreamCompleted(protocol.StreamID(42))
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, monotime.Now()))
        if finRead {
                mockFC.EXPECT().AddBytesRead(protocol.ByteCount(6))
                n, err := str.Read(make([]byte, 10))
@@ -498,7 +499,7 @@ func testReceiveStreamCancelReadAfterFIN(t *testing.T, finRead bool) {
                mockSender.EXPECT().onHasStreamControlFrame(str.StreamID(), str)
        }
        str.CancelRead(1337)
-       f, ok, hasMore := str.getControlFrame(time.Now())
+       f, ok, hasMore := str.getControlFrame(monotime.Now())
        // if the EOF was already read, no STOP_SENDING frame is queued
        if finRead {
                require.False(t, ok)
@@ -542,7 +543,7 @@ func TestReceiveStreamReset(t *testing.T) {
                )
                require.NoError(t, str.handleResetStreamFrame(
                        &wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1234, FinalSize: 42},
-                       time.Now(),
+                       monotime.Now(),
                ))
 
                synctest.Wait()
@@ -562,7 +563,7 @@ func TestReceiveStreamReset(t *testing.T) {
                mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(42), true, gomock.Any())
                require.NoError(t, str.handleResetStreamFrame(
                        &wire.ResetStreamFrame{StreamID: 42, ErrorCode: 4321, FinalSize: 42},
-                       time.Now(),
+                       monotime.Now(),
                ))
                n, err := str.Read([]byte{0})
                require.Zero(t, n)
@@ -587,7 +588,7 @@ func TestReceiveStreamResetAfterFINRead(t *testing.T) {
        mockSender.EXPECT().onStreamCompleted(protocol.StreamID(42))
        require.NoError(t, str.handleStreamFrame(
                &wire.StreamFrame{StreamID: 42, Data: []byte("foobar"), Fin: true},
-               time.Now(),
+               monotime.Now(),
        ))
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(6))
        n, err := str.Read(make([]byte, 6))
@@ -602,7 +603,7 @@ func TestReceiveStreamResetAfterFINRead(t *testing.T) {
        mockFC.EXPECT().Abandon()
        require.NoError(t, str.handleResetStreamFrame(
                &wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1234, FinalSize: 6},
-               time.Now(),
+               monotime.Now(),
        ))
        // now read the error
        n, err = str.Read([]byte{0})
@@ -644,7 +645,7 @@ func TestReceiveStreamConcurrentReads(t *testing.T) {
                                errChan <- err
                        }()
                }
-               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, time.Now()))
+               require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar"), Fin: true}, monotime.Now()))
                synctest.Wait()
 
                for range num {
@@ -667,7 +668,7 @@ func TestReceiveStreamResetStreamAtBeforeReadOffset(t *testing.T) {
        str := newReceiveStream(42, mockSender, mockFC)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any())
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(3))
        b := make([]byte, 3)
        n, err := str.Read(b)
@@ -677,7 +678,7 @@ func TestReceiveStreamResetStreamAtBeforeReadOffset(t *testing.T) {
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
        mockFC.EXPECT().Abandon()
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 3}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 3}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // Read returns the error
@@ -694,7 +695,7 @@ func TestReceiveStreamResetStreamAtAfterReadOffset(t *testing.T) {
        str := newReceiveStream(42, mockSender, mockFC)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any())
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(2))
        b := make([]byte, 2)
        n, err := str.Read(b)
@@ -703,7 +704,7 @@ func TestReceiveStreamResetStreamAtAfterReadOffset(t *testing.T) {
        require.Equal(t, []byte("fo"), b)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 6}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 6}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // Read returns the error
@@ -732,7 +733,7 @@ func TestReceiveStreamMultipleResetStreamAt(t *testing.T) {
        str := newReceiveStream(42, mockSender, mockFC)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any())
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
 
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(3))
        b := make([]byte, 3)
@@ -743,18 +744,18 @@ func TestReceiveStreamMultipleResetStreamAt(t *testing.T) {
        require.True(t, mockCtrl.Satisfied())
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 6}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 6}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // receiving a reordered RESET_STREAM_AT frame has no effect
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 8}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 8}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // receiving a RESET_STREAM_AT frame with a smaller reliable size is valid
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
        mockFC.EXPECT().Abandon()
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 3}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 3}, monotime.Now())
 
        // Read returns the error
        mockSender.EXPECT().onStreamCompleted(protocol.StreamID(42))
@@ -770,7 +771,7 @@ func TestReceiveStreamResetStreamAtAfterResetStream(t *testing.T) {
        str := newReceiveStream(42, mockSender, mockFC)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any())
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
 
        mockFC.EXPECT().AddBytesRead(protocol.ByteCount(3))
        b := make([]byte, 3)
@@ -782,13 +783,13 @@ func TestReceiveStreamResetStreamAtAfterResetStream(t *testing.T) {
 
        mockFC.EXPECT().Abandon()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // receiving a reordered RESET_STREAM_AT frame has no effect
        mockFC.EXPECT().Abandon()
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(10), true, gomock.Any())
-       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 8}, time.Now())
+       str.handleResetStreamFrame(&wire.ResetStreamFrame{StreamID: 42, ErrorCode: 1337, FinalSize: 10, ReliableSize: 8}, monotime.Now())
        require.True(t, mockCtrl.Satisfied())
 
        // Read returns the error
index 81f084c527910fce1edd77ca08924d17d0792215..889e01816468b7615fd563ea0653ddd9f989e11e 100644 (file)
@@ -8,6 +8,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
        "github.com/quic-go/quic-go/internal/wire"
@@ -52,7 +53,7 @@ type SendStream struct {
 
        writeChan chan struct{}
        writeOnce chan struct{}
-       deadline  time.Time
+       deadline  monotime.Time
 
        flowController flowcontrol.StreamFlowController
 }
@@ -118,7 +119,7 @@ func (s *SendStream) write(p []byte) (bool /* is newly completed */, int, error)
        if s.finishedWriting {
                return false, 0, fmt.Errorf("write on closed stream %d", s.streamID)
        }
-       if !s.deadline.IsZero() && !time.Now().Before(s.deadline) {
+       if !s.deadline.IsZero() && !monotime.Now().Before(s.deadline) {
                return false, 0, errDeadline
        }
        if len(p) == 0 {
@@ -134,7 +135,7 @@ func (s *SendStream) write(p []byte) (bool /* is newly completed */, int, error)
        )
        for {
                var copied bool
-               var deadline time.Time
+               var deadline monotime.Time
                // As soon as dataForWriting becomes smaller than a certain size x, we copy all the data to a STREAM frame (s.nextFrame),
                // which can then be popped the next time we assemble a packet.
                // This allows us to return Write() when all data but x bytes have been sent out.
@@ -161,7 +162,7 @@ func (s *SendStream) write(p []byte) (bool /* is newly completed */, int, error)
                        bytesWritten = len(p) - len(s.dataForWriting)
                        deadline = s.deadline
                        if !deadline.IsZero() {
-                               if !time.Now().Before(deadline) {
+                               if !monotime.Now().Before(deadline) {
                                        s.dataForWriting = nil
                                        return false, bytesWritten, errDeadline
                                }
@@ -590,7 +591,7 @@ func (s *SendStream) handleStopSendingFrame(f *wire.StopSendingFrame) {
        s.sender.onHasStreamControlFrame(s.streamID, s)
 }
 
-func (s *SendStream) getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool) {
+func (s *SendStream) getControlFrame(monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) {
        s.mutex.Lock()
        defer s.mutex.Unlock()
 
@@ -629,7 +630,7 @@ func (s *SendStream) Context() context.Context {
 // A zero value for t means Write will not time out.
 func (s *SendStream) SetWriteDeadline(t time.Time) error {
        s.mutex.Lock()
-       s.deadline = t
+       s.deadline = monotime.FromTime(t)
        s.mutex.Unlock()
        s.signalWrite()
        return nil
index b27da0893f545b11a27ca9455d876d46e99ffab1..206a3149028c4dcc1d2dac14fb0a0d179ca731a5 100644 (file)
@@ -17,6 +17,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/mocks"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/synctest"
        "github.com/quic-go/quic-go/internal/wire"
@@ -511,7 +512,7 @@ func TestSendStreamFlowControlBlocked(t *testing.T) {
        require.Nil(t, blocked)
        require.True(t, hasMore)
 
-       _, ok, hasMore := str.getControlFrame(time.Now())
+       _, ok, hasMore := str.getControlFrame(monotime.Now())
        require.False(t, ok)
        require.False(t, hasMore)
 }
@@ -546,7 +547,7 @@ func TestSendStreamCloseForShutdown(t *testing.T) {
 
                // STOP_SENDING frames are ignored
                str.handleStopSendingFrame(&wire.StopSendingFrame{StreamID: streamID, ErrorCode: 1337})
-               _, ok, hasMore := str.getControlFrame(time.Now())
+               _, ok, hasMore := str.getControlFrame(monotime.Now())
                require.False(t, ok)
                require.False(t, hasMore)
 
@@ -630,7 +631,7 @@ func TestSendStreamCancellation(t *testing.T) {
                str.CancelWrite(1234)
                require.True(t, mockCtrl.Satisfied())
 
-               cf, ok, hasMore := str.getControlFrame(time.Now())
+               cf, ok, hasMore := str.getControlFrame(monotime.Now())
                require.True(t, ok)
                // only the "foo" was sent out, so the final size is 3
                require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 3, ErrorCode: 1234}, cf.Frame)
@@ -646,7 +647,7 @@ func TestSendStreamCancellation(t *testing.T) {
 
                // duplicate calls to CancelWrite don't do anything
                str.CancelWrite(1234)
-               _, ok, _ = str.getControlFrame(time.Now())
+               _, ok, _ = str.getControlFrame(monotime.Now())
                require.False(t, ok)
 
                synctest.Wait()
@@ -708,7 +709,7 @@ func TestSendStreamCancellationAfterClose(t *testing.T) {
        require.Nil(t, frame.Frame)
        require.False(t, hasMore)
 
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 0, ErrorCode: 1337}, cf.Frame)
        require.False(t, hasMore)
@@ -753,7 +754,7 @@ func testSendStreamCancellationStreamRetransmission(t *testing.T, remote bool) {
        } else {
                str.CancelWrite(1337)
        }
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.IsType(t, &wire.ResetStreamFrame{}, cf.Frame)
        require.False(t, hasMore)
@@ -788,7 +789,7 @@ func TestSendStreamCancellationResetStreamRetransmission(t *testing.T) {
        mockSender.EXPECT().onHasStreamControlFrame(streamID, str)
        str.CancelWrite(1337)
 
-       f1, ok, hasMore := str.getControlFrame(time.Now())
+       f1, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 0, ErrorCode: 1337}, f1.Frame)
        require.False(t, hasMore)
@@ -798,7 +799,7 @@ func TestSendStreamCancellationResetStreamRetransmission(t *testing.T) {
        mockSender.EXPECT().onHasStreamControlFrame(streamID, str)
        f1.Handler.OnLost(f1.Frame)
        // get the retransmission
-       f2, ok, hasMore := str.getControlFrame(time.Now())
+       f2, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 0, ErrorCode: 1337}, f2.Frame)
        require.False(t, hasMore)
@@ -840,7 +841,7 @@ func testSendStreamStopSendingAfterWrite(t *testing.T, completeBy string) {
        mockSender.EXPECT().onHasStreamControlFrame(streamID, str)
        str.handleStopSendingFrame(&wire.StopSendingFrame{StreamID: streamID, ErrorCode: 1337})
 
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 6, ErrorCode: 1337}, cf.Frame)
        require.False(t, hasMore)
@@ -866,7 +867,7 @@ func testSendStreamStopSendingAfterWrite(t *testing.T, completeBy string) {
        require.ErrorIs(t, err, &StreamError{StreamID: streamID, ErrorCode: 1337, Remote: true})
        frame, _, _ = str.popStreamFrame(protocol.MaxByteCount, protocol.Version1)
        require.Nil(t, frame.Frame)
-       _, ok, _ = str.getControlFrame(time.Now())
+       _, ok, _ = str.getControlFrame(monotime.Now())
        require.False(t, ok)
 }
 
@@ -905,14 +906,14 @@ func TestSendStreamStopSendingDuringWrite(t *testing.T) {
                        t.Fatal("write should have returned")
                }
 
-               cf, ok, hasMore := str.getControlFrame(time.Now())
+               cf, ok, hasMore := str.getControlFrame(monotime.Now())
                require.True(t, ok)
                require.Equal(t, &wire.ResetStreamFrame{StreamID: streamID, FinalSize: 6, ErrorCode: 1337}, cf.Frame)
                require.False(t, hasMore)
 
                // receiving another STOP_SENDING frame has no effect
                str.handleStopSendingFrame(&wire.StopSendingFrame{StreamID: streamID, ErrorCode: 1234})
-               _, ok, hasMore = str.getControlFrame(time.Now())
+               _, ok, hasMore = str.getControlFrame(monotime.Now())
                require.False(t, ok)
                require.False(t, hasMore)
 
@@ -932,7 +933,7 @@ func TestSendStreamStopSendingDuringWrite(t *testing.T) {
                _, err = (&writerWithTimeout{Writer: str, Timeout: time.Second}).Write([]byte("foobar"))
                // error code and remote flag are unchanged
                require.ErrorIs(t, err, &StreamError{StreamID: streamID, ErrorCode: 1337, Remote: true})
-               _, ok, _ = str.getControlFrame(time.Now())
+               _, ok, _ = str.getControlFrame(monotime.Now())
                require.False(t, ok)
 
                // Close has no effect
@@ -1182,7 +1183,7 @@ func TestSendStreamResetStreamAtCancelBeforeSend(t *testing.T) {
 
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.CancelWrite(1337)
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: 1337, FinalSize: 6, ErrorCode: 1337, ReliableSize: 6}, cf.Frame)
        require.False(t, hasMore)
@@ -1248,7 +1249,7 @@ func TestSendStreamResetStreamAtCancelAfterSend(t *testing.T) {
 
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.CancelWrite(42)
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: 1337, FinalSize: 9, ErrorCode: 42, ReliableSize: 6}, cf.Frame)
        require.False(t, hasMore)
@@ -1350,7 +1351,7 @@ func TestSendStreamResetStreamAtRetransmissions(t *testing.T) {
        // but f3 and the data in the buffer should not.
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.CancelWrite(42)
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: 1337, FinalSize: 22, ErrorCode: 42, ReliableSize: 10}, cf.Frame)
        require.False(t, hasMore)
@@ -1409,7 +1410,7 @@ func TestSendStreamResetStreamAtStopSendingBeforeCancelation(t *testing.T) {
 
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.handleStopSendingFrame(&wire.StopSendingFrame{StreamID: 1337, ErrorCode: 42})
-       cf, ok, hasMore := str.getControlFrame(time.Now())
+       cf, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        // Since the peer reset the stream, the resulting RESET_STREAM frame has a reliable size of 0
        require.Equal(t, &wire.ResetStreamFrame{StreamID: 1337, FinalSize: 9, ErrorCode: 42, ReliableSize: 0}, cf.Frame)
@@ -1456,7 +1457,7 @@ func testSendStreamResetStreamAtStopSendingAfterCancelation(t *testing.T, loseRe
        // Canceling the stream results in a RESET_STREAM_AT frame.
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.CancelWrite(42)
-       cf1, ok, hasMore := str.getControlFrame(time.Now())
+       cf1, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, &wire.ResetStreamFrame{StreamID: 1337, FinalSize: 9, ErrorCode: 42, ReliableSize: 6}, cf1.Frame)
        require.False(t, hasMore)
@@ -1465,7 +1466,7 @@ func testSendStreamResetStreamAtStopSendingAfterCancelation(t *testing.T, loseRe
        // effectively reducing the reliable size to 0.
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        str.handleStopSendingFrame(&wire.StopSendingFrame{StreamID: 1337, ErrorCode: 1234})
-       cf2, ok, hasMore := str.getControlFrame(time.Now())
+       cf2, ok, hasMore := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        // Since the peer reset the stream, the resulting RESET_STREAM frame has a reliable size of 0.
        // The error code is still the one used for the CancelWrite call.
@@ -1481,13 +1482,13 @@ func testSendStreamResetStreamAtStopSendingAfterCancelation(t *testing.T, loseRe
                // the RESET_STREAM frame still needs to be transmitted reliably
                cf1.Handler.OnAcked(cf1.Frame)
        }
-       _, ok, _ = str.getControlFrame(time.Now())
+       _, ok, _ = str.getControlFrame(monotime.Now())
        require.False(t, ok)
 
        // but when the RESET_STREAM frame is lost, it needs to be retransmitted
        mockSender.EXPECT().onHasStreamControlFrame(protocol.StreamID(1337), str)
        cf2.Handler.OnLost(cf2.Frame)
-       cf3, ok, _ := str.getControlFrame(time.Now())
+       cf3, ok, _ := str.getControlFrame(monotime.Now())
        require.True(t, ok)
        require.Equal(t, cf2, cf3)
 
@@ -1555,7 +1556,7 @@ func TestSendStreamResetStreamAtRandomized(t *testing.T) {
                        t.Fatal("stream should have completed")
                }
                var dequeuedFrame bool
-               cf, ok, _ := str.getControlFrame(time.Now())
+               cf, ok, _ := str.getControlFrame(monotime.Now())
                if ok {
                        dequeuedFrame = true
                        frameQueue = append(frameQueue, cf)
index 13234df2838de263103389bdec335af5c84f1d2d..142de36ab028527109256c1a593beef30a32f7d5 100644 (file)
--- a/server.go
+++ b/server.go
@@ -10,6 +10,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/handshake"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -34,7 +35,7 @@ type packetHandler interface {
 
 type zeroRTTQueue struct {
        packets    []receivedPacket
-       expiration time.Time
+       expiration monotime.Time
 }
 
 type rejectedPacket struct {
@@ -62,7 +63,7 @@ type baseServer struct {
 
        receivedPackets chan receivedPacket
 
-       nextZeroRTTCleanup time.Time
+       nextZeroRTTCleanup monotime.Time
        zeroRTTQueues      map[protocol.ConnectionID]*zeroRTTQueue // only initialized if acceptEarlyConns == true
 
        connContext func(context.Context, *ClientInfo) (context.Context, error)
@@ -538,10 +539,10 @@ func (s *baseServer) handle0RTTPacket(p receivedPacket) bool {
        return true
 }
 
-func (s *baseServer) cleanupZeroRTTQueues(now time.Time) {
+func (s *baseServer) cleanupZeroRTTQueues(now monotime.Time) {
        // Iterate over all queues to find those that are expired.
        // This is ok since we're placing a pretty low limit on the number of queues.
-       var nextCleanup time.Time
+       var nextCleanup monotime.Time
        for connID, q := range s.zeroRTTQueues {
                if q.expiration.After(now) {
                        if nextCleanup.IsZero() || nextCleanup.After(q.expiration) {
index 6de609d71694eac8ec8bf635354dac0bd82354e3..deacf71bc04a528b80e50663e5301709e54c5add 100644 (file)
@@ -12,6 +12,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/handshake"
        mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/utils"
@@ -1170,7 +1171,7 @@ func TestServer0RTTQueueing(t *testing.T) {
                tracer:      tracer,
        })
 
-       firstRcvTime := time.Now()
+       firstRcvTime := monotime.Now()
        otherRcvTime := firstRcvTime.Add(protocol.Max0RTTQueueingDuration / 2)
        var sizes []protocol.ByteCount
        for i := range protocol.Max0RTTQueues {
index 64bcc838caad8220233dd445cf12086f88d8e197..7b5b8d09cf1f76ccee99c89fda9e74d5163d3195 100644 (file)
--- a/stream.go
+++ b/stream.go
@@ -9,6 +9,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/ackhandler"
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 )
@@ -147,11 +148,11 @@ func (s *Stream) Close() error {
        return s.sendStr.Close()
 }
 
-func (s *Stream) handleResetStreamFrame(frame *wire.ResetStreamFrame, rcvTime time.Time) error {
+func (s *Stream) handleResetStreamFrame(frame *wire.ResetStreamFrame, rcvTime monotime.Time) error {
        return s.receiveStr.handleResetStreamFrame(frame, rcvTime)
 }
 
-func (s *Stream) handleStreamFrame(frame *wire.StreamFrame, rcvTime time.Time) error {
+func (s *Stream) handleStreamFrame(frame *wire.StreamFrame, rcvTime monotime.Time) error {
        return s.receiveStr.handleStreamFrame(frame, rcvTime)
 }
 
@@ -171,7 +172,7 @@ func (s *Stream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version)
        return s.sendStr.popStreamFrame(maxBytes, v)
 }
 
-func (s *Stream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) {
+func (s *Stream) getControlFrame(now monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) {
        f, ok, _ := s.sendStr.getControlFrame(now)
        if ok {
                return f, true, true
index d4ee0a44bfb1820406b8d9d36460d8573017d4d8..e0a1bcb4214f47ab0b78cce3ee54e96bd55a1415 100644 (file)
@@ -8,6 +8,7 @@ import (
        "time"
 
        "github.com/quic-go/quic-go/internal/mocks"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/wire"
 
@@ -29,7 +30,7 @@ func TestStreamDeadlines(t *testing.T) {
        require.Zero(t, n)
 
        mockFC.EXPECT().UpdateHighestReceived(protocol.ByteCount(6), false, gomock.Any()).AnyTimes()
-       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, time.Now()))
+       require.NoError(t, str.handleStreamFrame(&wire.StreamFrame{Data: []byte("foobar")}, monotime.Now()))
        n, err = (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(make([]byte, 6))
        require.ErrorIs(t, err, os.ErrDeadlineExceeded)
        require.Zero(t, n)
@@ -49,7 +50,7 @@ func TestStreamCompletion(t *testing.T) {
                        StreamID: str.StreamID(),
                        Data:     []byte("foobar"),
                        Fin:      true,
-               }, time.Now()))
+               }, monotime.Now()))
                _, err := (&readerWithTimeout{Reader: str, Timeout: time.Second}).Read(make([]byte, 6))
                require.ErrorIs(t, err, io.EOF)
                require.True(t, mockCtrl.Satisfied())
index 14be5ad0bd10a162b57dafbb9fb28d8f464078a6..92023ac2646d567744e240e11ec870aef77a95c4 100644 (file)
@@ -4,9 +4,9 @@ import (
        "context"
        "fmt"
        "sync"
-       "time"
 
        "github.com/quic-go/quic-go/internal/flowcontrol"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -251,8 +251,8 @@ func (m *streamsMap) HandleStopSendingFrame(f *wire.StopSendingFrame) error {
 }
 
 type receiveStreamFrameHandler interface {
-       handleResetStreamFrame(*wire.ResetStreamFrame, time.Time) error
-       handleStreamFrame(*wire.StreamFrame, time.Time) error
+       handleResetStreamFrame(*wire.ResetStreamFrame, monotime.Time) error
+       handleStreamFrame(*wire.StreamFrame, monotime.Time) error
 }
 
 func (m *streamsMap) getReceiveStream(id protocol.StreamID) (receiveStreamFrameHandler, error) {
@@ -295,7 +295,7 @@ func (m *streamsMap) HandleStreamDataBlockedFrame(f *wire.StreamDataBlockedFrame
        return nil // we don't need to do anything in response to a STREAM_DATA_BLOCKED frame
 }
 
-func (m *streamsMap) HandleResetStreamFrame(f *wire.ResetStreamFrame, rcvTime time.Time) error {
+func (m *streamsMap) HandleResetStreamFrame(f *wire.ResetStreamFrame, rcvTime monotime.Time) error {
        str, err := m.getReceiveStream(f.StreamID)
        if err != nil {
                return err
@@ -306,7 +306,7 @@ func (m *streamsMap) HandleResetStreamFrame(f *wire.ResetStreamFrame, rcvTime ti
        return str.handleResetStreamFrame(f, rcvTime)
 }
 
-func (m *streamsMap) HandleStreamFrame(f *wire.StreamFrame, rcvTime time.Time) error {
+func (m *streamsMap) HandleStreamFrame(f *wire.StreamFrame, rcvTime monotime.Time) error {
        str, err := m.getReceiveStream(f.StreamID)
        if err != nil {
                return err
index ebb11a8da45d8fa3611f7dc4b09ca5152c8519c0..260cc3d6a0410e772dd85c847871f7c412856c1f 100644 (file)
@@ -8,6 +8,7 @@ import (
 
        "github.com/quic-go/quic-go/internal/flowcontrol"
        "github.com/quic-go/quic-go/internal/mocks"
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/qerr"
        "github.com/quic-go/quic-go/internal/wire"
@@ -79,8 +80,8 @@ func testStreamsMapCreatingStreams(t *testing.T,
        assert.Equal(t, ustr2.StreamID(), firstOutgoingUniStream+4)
 
        // accepting streams is triggered by receiving a frame referencing this stream
-       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingBidiStream}, time.Now()))
-       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingUniStream}, time.Now()))
+       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingBidiStream}, monotime.Now()))
+       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingUniStream}, monotime.Now()))
 
        ctx, cancel := context.WithTimeout(context.Background(), time.Second)
        defer cancel()
@@ -156,7 +157,7 @@ func testStreamsMapDeletingStreams(t *testing.T,
 
        require.Empty(t, frameQueue)
        // deleting incoming bidirectional streams
-       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingBidiStream}, time.Now()))
+       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingBidiStream}, monotime.Now()))
        require.NoError(t, m.DeleteStream(firstIncomingBidiStream))
        err = m.DeleteStream(firstIncomingBidiStream + 400)
        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.StreamStateError})
@@ -176,7 +177,7 @@ func testStreamsMapDeletingStreams(t *testing.T,
        frameQueue = frameQueue[:0]
 
        // deleting incoming unidirectional streams
-       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingUniStream}, time.Now()))
+       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: firstIncomingUniStream}, monotime.Now()))
        require.NoError(t, m.DeleteStream(firstIncomingUniStream))
        err = m.DeleteStream(firstIncomingUniStream + 400)
        require.ErrorIs(t, err, &qerr.TransportError{ErrorCode: qerr.StreamStateError})
@@ -273,7 +274,7 @@ func TestStreamsMapHandleReceiveStreamFrames(t *testing.T) {
                                testStreamsMapHandleReceiveStreamFrames(t,
                                        pers,
                                        func(m *streamsMap, id protocol.StreamID) error {
-                                               return m.HandleStreamFrame(&wire.StreamFrame{StreamID: id}, time.Now())
+                                               return m.HandleStreamFrame(&wire.StreamFrame{StreamID: id}, monotime.Now())
                                        },
                                )
                        })
@@ -291,7 +292,7 @@ func TestStreamsMapHandleReceiveStreamFrames(t *testing.T) {
                                testStreamsMapHandleReceiveStreamFrames(t,
                                        pers,
                                        func(m *streamsMap, id protocol.StreamID) error {
-                                               return m.HandleResetStreamFrame(&wire.ResetStreamFrame{StreamID: id}, time.Now())
+                                               return m.HandleResetStreamFrame(&wire.ResetStreamFrame{StreamID: id}, monotime.Now())
                                        },
                                )
                        })
@@ -592,7 +593,7 @@ func TestStreamsMap0RTTRejection(t *testing.T) {
        require.ErrorIs(t, err, Err0RTTRejected)
 
        // make sure that we can still get new streams, as the server might be sending us data
-       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: 3}, time.Now()))
+       require.NoError(t, m.HandleStreamFrame(&wire.StreamFrame{StreamID: 3}, monotime.Now()))
 
        // now switch to using the new streams map
        m.UseResetMaps()
index 6e768dcf2c4e32e6eddbb761fb1f002606b31323..ce35de883571c0b7ba87c5c3123223235512e97f 100644 (file)
@@ -10,6 +10,7 @@ import (
        "syscall"
        "time"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
 )
@@ -123,7 +124,7 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) {
        }
        return receivedPacket{
                remoteAddr: addr,
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
                data:       buffer.Data[:n],
                buffer:     buffer,
        }, nil
index e853470877d75d273995814d0df26834e319407c..0aa69cda4326a27d937bdb490bbd40f54abeb3f6 100644 (file)
@@ -12,13 +12,13 @@ import (
        "strconv"
        "sync"
        "syscall"
-       "time"
        "unsafe"
 
        "golang.org/x/net/ipv4"
        "golang.org/x/net/ipv6"
        "golang.org/x/sys/unix"
 
+       "github.com/quic-go/quic-go/internal/monotime"
        "github.com/quic-go/quic-go/internal/protocol"
        "github.com/quic-go/quic-go/internal/utils"
 )
@@ -185,7 +185,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) {
        data := msg.OOB[:msg.NN]
        p := receivedPacket{
                remoteAddr: msg.Addr,
-               rcvTime:    time.Now(),
+               rcvTime:    monotime.Now(),
                data:       msg.Buffers[0][:msg.N],
                buffer:     buffer,
        }
index afdb14a27535e276d8a5965eee4860aebe4c7e6b..d7d973b4df2d9e5ea1cc0365ee4863509c28e754 100644 (file)
@@ -69,7 +69,7 @@ func TestReadECNFlagsIPv4(t *testing.T) {
 
        select {
        case p := <-packetChan:
-               require.WithinDuration(t, time.Now(), p.rcvTime, scaleDuration(20*time.Millisecond))
+               require.WithinDuration(t, time.Now(), p.rcvTime.ToTime(), scaleDuration(20*time.Millisecond))
                require.Equal(t, []byte("foobar"), p.data)
                require.Equal(t, sentFrom, p.remoteAddr)
                require.Equal(t, protocol.ECT0, p.ecn)
@@ -91,7 +91,7 @@ func TestReadECNFlagsIPv6(t *testing.T) {
 
        select {
        case p := <-packetChan:
-               require.WithinDuration(t, time.Now(), p.rcvTime, scaleDuration(20*time.Millisecond))
+               require.WithinDuration(t, time.Now(), p.rcvTime.ToTime(), scaleDuration(20*time.Millisecond))
                require.Equal(t, []byte("foobar"), p.data)
                require.Equal(t, sentFrom, p.remoteAddr)
                require.Equal(t, protocol.ECNCE, p.ecn)
@@ -192,7 +192,7 @@ func TestSysConnPacketInfoIPv4(t *testing.T) {
 
        select {
        case p := <-packetChan:
-               require.WithinDuration(t, time.Now(), p.rcvTime, scaleDuration(50*time.Millisecond))
+               require.WithinDuration(t, time.Now(), p.rcvTime.ToTime(), scaleDuration(50*time.Millisecond))
                require.Equal(t, []byte("foobar"), p.data)
                require.Equal(t, conn.LocalAddr(), p.remoteAddr)
                require.True(t, p.info.addr.IsValid())
@@ -215,7 +215,7 @@ func TestSysConnPacketInfoIPv6(t *testing.T) {
 
        select {
        case p := <-packetChan:
-               require.WithinDuration(t, time.Now(), p.rcvTime, scaleDuration(20*time.Millisecond))
+               require.WithinDuration(t, time.Now(), p.rcvTime.ToTime(), scaleDuration(20*time.Millisecond))
                require.Equal(t, []byte("foobar"), p.data)
                require.Equal(t, conn.LocalAddr(), p.remoteAddr)
                require.NotNil(t, p.info)
index d465c51b008372d9e371fe304fae4381662009d9..a75d34f993d6d2dec60c221d5d703e0bcf20d453 100644 (file)
@@ -27,6 +27,6 @@ func TestBasicConn(t *testing.T) {
        p, err := conn.ReadPacket()
        require.NoError(t, err)
        require.Equal(t, []byte("foobar"), p.data)
-       require.WithinDuration(t, time.Now(), p.rcvTime, scaleDuration(100*time.Millisecond))
+       require.WithinDuration(t, time.Now(), p.rcvTime.ToTime(), scaleDuration(100*time.Millisecond))
        require.Equal(t, addr, p.remoteAddr)
 }