mirror of
https://github.com/soypat/lneto.git
synced 2026-09-11 09:09:30 +00:00
tcp: retransmit logic rollback (#61)
* tcp: remove retransmit logic entirely; add duplicate ack counting to ControlBlock * retransmit implemented in nice simple straightforward way * narrow down retransmission cases * remove old timing tests * add ControlBlock retransmit test * add failing handler test * reworking payload length semantic meaning in code * fix establish conn logic * clean up tests and add TCB dupack generation and test it * catch pending retransmit satisfy in test * add fuzz test for control block * bugfix: be more strict in what is considered dupack * add IncomingIsDupACK docs * limit queue of retransmits * protect retransmit overflow from incorrectly updating nxt
This commit is contained in:
-22
@@ -28,7 +28,6 @@ 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
|
||||
@@ -56,10 +55,6 @@ 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) {
|
||||
@@ -70,19 +65,9 @@ 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()
|
||||
@@ -354,7 +339,6 @@ 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
|
||||
@@ -382,12 +366,6 @@ 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()
|
||||
conn.h.dupACKs = 0 // RTO is a new loss event; reset dup-ACK counter.
|
||||
}
|
||||
n, err = conn.h.Send(carrierData[offsetToFrame:])
|
||||
if err != nil || n == 0 {
|
||||
return 0, err
|
||||
|
||||
Reference in New Issue
Block a user