Skip to content

Commit

Permalink
need to fix broken Send/Recv test
Browse files Browse the repository at this point in the history
  • Loading branch information
soypat committed Nov 18, 2023
1 parent f198ea9 commit e59351f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions control.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ func (seg *Segment) Last() Value {
}

// PendingSegment calculates a suitable next segment to send from a payload length.
// It does not modify the ControlBlock state.
func (tcb *ControlBlock) PendingSegment(payloadLen int) (_ Segment, ok bool) {
if (payloadLen == 0 && tcb.pending == 0) || (payloadLen > 0 && tcb.state != StateEstablished) {
return Segment{}, false // No pending segment.
Expand Down
23 changes: 22 additions & 1 deletion stack/socket_tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/soypat/seqs"
)

const defaultSocketSize = 2048

type tcp struct {
stack *PortStack
scb seqs.ControlBlock
Expand All @@ -30,7 +32,7 @@ func (t *tcp) State() seqs.State {
func (t *tcp) Send(b []byte) error {
if t.tx.buf == nil {
t.tx = ring{
buf: make([]byte, max(2048, len(b))),
buf: make([]byte, max(defaultSocketSize, len(b))),
}
}
_, err := t.tx.Write(b)
Expand All @@ -40,6 +42,11 @@ func (t *tcp) Send(b []byte) error {
return nil
}

func (t *tcp) Recv(b []byte) (int, error) {
n, err := t.rx.Read(b)
return n, err
}

// DialTCP opens an active TCP connection to the given remote address.
func DialTCP(stack *PortStack, localPort uint16, remoteMAC [6]byte, remote netip.AddrPort, iss seqs.Value, window seqs.Size) (*tcp, error) {
t := tcp{
Expand Down Expand Up @@ -110,6 +117,20 @@ func (t *tcp) handleRecv(response []byte, pkt *TCPPacket) (n int, err error) {
// if segIncoming.SEQ != t.scb.RecvNext() {
// return 0, ErrDroppedPacket // SCB does not admit out-of-order packets.
// }
if segIncoming.Flags.HasAny(seqs.FlagPSH) {
if len(payload) != int(segIncoming.DATALEN) {
return 0, errors.New("segment data length does not match payload length")
}
if t.rx.buf == nil {
t.rx = ring{
buf: make([]byte, defaultSocketSize),
}
}
_, err = t.rx.Write(payload)
if err != nil {
return 0, err
}
}
err = t.scb.Recv(segIncoming)
if err != nil {
return 0, err
Expand Down
18 changes: 18 additions & 0 deletions stack/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,24 @@ func TestStackSendReceive(t *testing.T) {
t.Fatal("not established")
}

// Send data from client to server.
const data = "hello world"
err = clientTCP.Send([]byte(data))
if err != nil {
t.Fatal(err)
}
txStacks(t, 1, Client, Server)
if clientTCP.State() != seqs.StateEstablished || serverTCP.State() != seqs.StateEstablished {
t.Fatal("not established")
}
var buf [len(data)]byte
n, err := serverTCP.Recv(buf[:])
if err != nil {
t.Fatal(err)
}
if string(buf[:n]) != data {
t.Error("got", string(buf[:n]), "want", data)
}
}

func isDroppedPacket(err error) bool {
Expand Down

0 comments on commit e59351f

Please sign in to comment.