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 { if err != nil {
return err return err
} }
const tcpDebugTimeout = 60 * time.Minute
target := netip.AddrPortFrom(addrs[0], 80) 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 { if err != nil {
return fmt.Errorf("TCP failed: %w", err) return fmt.Errorf("TCP failed: %w", err)
} }
+4
View File
@@ -17,6 +17,7 @@ import (
var ( var (
errDeadlineExceeded = os.ErrDeadlineExceeded errDeadlineExceeded = os.ErrDeadlineExceeded
errNoRemoteAddr = errors.New("tcp: no remote address established") errNoRemoteAddr = errors.New("tcp: no remote address established")
errInvalidIP = errors.New("tcp: invalid IP")
errMismatchedIPVersion = errors.New("mismatched IP version") 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. // 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. // 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 { 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) err := conn.h.OpenActive(localPort, remote.Port(), iss)
if err != nil { if err != nil {
return err 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") return errors.New("zero port on open call")
} }
h.reset(localPort, remotePort, iss) h.reset(localPort, remotePort, iss)
h.scb.SetRecvWindow(Size(h.bufRx.Size()))
return nil return nil
} }
@@ -234,7 +235,7 @@ func (h *Handler) Send(b []byte) (int, error) {
var segment Segment var segment Segment
if h.AwaitingSynSend() { if h.AwaitingSynSend() {
// Handling init syn segment. // 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))) h.optcodec.PutOption16(b[sizeHeaderTCP:], OptMaxSegmentSize, uint16(len(b)))
offset++ offset++
} else { } else {
@@ -266,7 +267,7 @@ func (h *Handler) Send(b []byte) (int, error) {
} }
tfrm.SetSourcePort(h.localPort) tfrm.SetSourcePort(h.localPort)
tfrm.SetDestinationPort(h.remotePort) tfrm.SetDestinationPort(h.remotePort)
tfrm.SetSegment(segment, offset) // No TCP options. tfrm.SetSegment(segment, offset)
tfrm.SetUrgentPtr(0) tfrm.SetUrgentPtr(0)
return int(offset)*4 + int(segment.DATALEN), nil return int(offset)*4 + int(segment.DATALEN), nil
} }
+3 -1
View File
@@ -32,6 +32,7 @@ type ringTx struct {
// seq Value // seq Value
// always empty ring. // always empty ring.
emptyRing ringidx emptyRing ringidx
iss Value
} }
// ringidx represents packet data inside RingTx // 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 // Reset resets the RingTx's internal state to use buf as the main ring buffer and creates or reuses
// the packet ring buffer. // 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. buf = buf[:len(buf):len(buf)] // safely omit capacity section.
if maxqueuedPackets <= 0 { if maxqueuedPackets <= 0 {
return errors.New("queued packets <=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 { for i := range rtx.packets {
rtx.packets[i].markRcvd() rtx.packets[i].markRcvd()
} }
rtx.iss = iss
return nil return nil
} }