mirror of
https://github.com/soypat/lneto.git
synced 2026-09-10 00:29:34 +00:00
Implement basic retransmit queue reset method (#52)
* implement basic retransmit queue reset method * tcp: rto reset on new ack; accept ack after retransmit bugfix
This commit is contained in:
+21
@@ -28,6 +28,7 @@ type Conn struct {
|
||||
mu sync.Mutex
|
||||
h Handler
|
||||
remoteAddr []byte
|
||||
nanoTime func() int64 // monotonic clock source; set by Configure.
|
||||
|
||||
rdead time.Time
|
||||
wdead time.Time
|
||||
@@ -55,6 +56,10 @@ type ConnConfig struct {
|
||||
TxBuf []byte
|
||||
TxPacketQueueSize int
|
||||
Logger *slog.Logger
|
||||
// NanoTime returns the current monotonic time in nanoseconds.
|
||||
// Used for retransmission timing (RFC 6298).
|
||||
// If nil, defaults to a function that calls time.Now().UnixNano().
|
||||
NanoTime func() int64
|
||||
}
|
||||
|
||||
func (conn *Conn) Configure(config ConnConfig) (err error) {
|
||||
@@ -65,9 +70,19 @@ func (conn *Conn) Configure(config ConnConfig) (err error) {
|
||||
return err
|
||||
}
|
||||
conn.logger.log = config.Logger
|
||||
conn.nanoTime = config.NanoTime // nil is fine; conn.now() falls back to time.Now().
|
||||
return nil
|
||||
}
|
||||
|
||||
// now returns the current monotonic time in nanoseconds.
|
||||
// Uses the configured NanoTime function or falls back to time.Now().UnixNano().
|
||||
func (conn *Conn) now() int64 {
|
||||
if conn.nanoTime != nil {
|
||||
return conn.nanoTime()
|
||||
}
|
||||
return time.Now().UnixNano()
|
||||
}
|
||||
|
||||
// LocalPort returns the local port on which the socket is listening or connected to.
|
||||
func (conn *Conn) LocalPort() uint16 {
|
||||
conn.mu.Lock()
|
||||
@@ -339,6 +354,7 @@ func (conn *Conn) Demux(buf []byte, off int) (err error) {
|
||||
return lneto.ErrMismatch
|
||||
}
|
||||
conn.trace("tcpconn.Recv", slog.Uint64("lport", uint64(conn.h.LocalPort())), slog.Uint64("rport", uint64(conn.h.remotePort)))
|
||||
conn.h.SetNow(uint32(conn.now() / 1e6)) // ns → ms for accurate ACK timestamps.
|
||||
err = conn.h.Recv(buf[off:])
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -366,6 +382,11 @@ func (conn *Conn) Encapsulate(carrierData []byte, offsetToIP, offsetToFrame int)
|
||||
} else if len(raddr) != len(conn.remoteAddr) {
|
||||
return 0, lneto.ErrMismatchLen
|
||||
}
|
||||
conn.h.SetNow(uint32(conn.now() / 1e6)) // ns → ms.
|
||||
// RFC 6298 §5.1: check RTO before sending new data.
|
||||
if conn.h.ShouldRetransmit() {
|
||||
conn.h.triggerRetransmit()
|
||||
}
|
||||
n, err = conn.h.Send(carrierData[offsetToFrame:])
|
||||
if err != nil || n == 0 {
|
||||
return 0, err
|
||||
|
||||
Reference in New Issue
Block a user