bugfix: use ISS on active TCP connection

This commit is contained in:
soypat
2025-08-16 18:26:50 -03:00
parent 9cf4e35d2e
commit 0f20090d78
4 changed files with 12 additions and 4 deletions
+2 -1
View File
@@ -203,8 +203,9 @@ func run() (err error) {
if err != nil {
return err
}
const tcpDebugTimeout = 60 * time.Minute
target := netip.AddrPortFrom(addrs[0], 80)
conn, err := rstack.DoDialTCP(uint16(softRand&0xefff)+1024, target, internetTimeout, internetRetries)
conn, err := rstack.DoDialTCP(uint16(softRand&0xefff)+1024, target, tcpDebugTimeout, internetRetries)
if err != nil {
return fmt.Errorf("TCP failed: %w", err)
}
+4
View File
@@ -17,6 +17,7 @@ import (
var (
errDeadlineExceeded = os.ErrDeadlineExceeded
errNoRemoteAddr = errors.New("tcp: no remote address established")
errInvalidIP = errors.New("tcp: invalid IP")
errMismatchedIPVersion = errors.New("mismatched IP version")
)
@@ -70,6 +71,9 @@ func (conn *Conn) BufferedInput() int { return conn.h.BufferedInput() }
// OpenActive opens a connection to a remote peer with a known IP address and port combination.
// iss is the initial send sequence number which is ideally a random number which is far away from the last sequence number used on a connection to the same host.
func (conn *Conn) OpenActive(localPort uint16, remote netip.AddrPort, iss Value) error {
if !remote.IsValid() {
return errInvalidIP
}
err := conn.h.OpenActive(localPort, remote.Port(), iss)
if err != nil {
return err
+3 -2
View File
@@ -92,6 +92,7 @@ func (h *Handler) OpenActive(localPort, remotePort uint16, iss Value) error {
return errors.New("zero port on open call")
}
h.reset(localPort, remotePort, iss)
h.scb.SetRecvWindow(Size(h.bufRx.Size()))
return nil
}
@@ -234,7 +235,7 @@ func (h *Handler) Send(b []byte) (int, error) {
var segment Segment
if h.AwaitingSynSend() {
// Handling init syn segment.
segment = ClientSynSegment(h.scb.ISS(), h.scb.RecvWindow())
segment = ClientSynSegment(h.bufTx.iss, Size(h.bufRx.Size()))
h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, uint16(len(b)))
offset++
} else {
@@ -266,7 +267,7 @@ func (h *Handler) Send(b []byte) (int, error) {
}
tfrm.SetSourcePort(h.localPort)
tfrm.SetDestinationPort(h.remotePort)
tfrm.SetSegment(segment, offset) // No TCP options.
tfrm.SetSegment(segment, offset)
tfrm.SetUrgentPtr(0)
return int(offset)*4 + int(segment.DATALEN), nil
}
+3 -1
View File
@@ -32,6 +32,7 @@ type ringTx struct {
// seq Value
// always empty ring.
emptyRing ringidx
iss Value
}
// ringidx represents packet data inside RingTx
@@ -49,7 +50,7 @@ type ringidx struct {
// Reset resets the RingTx's internal state to use buf as the main ring buffer and creates or reuses
// the packet ring buffer.
func (rtx *ringTx) Reset(buf []byte, maxqueuedPackets int, seq Value) error {
func (rtx *ringTx) Reset(buf []byte, maxqueuedPackets int, iss Value) error {
buf = buf[:len(buf):len(buf)] // safely omit capacity section.
if maxqueuedPackets <= 0 {
return errors.New("queued packets <=0")
@@ -66,6 +67,7 @@ func (rtx *ringTx) Reset(buf []byte, maxqueuedPackets int, seq Value) error {
for i := range rtx.packets {
rtx.packets[i].markRcvd()
}
rtx.iss = iss
return nil
}