Skip to content

Commit

Permalink
fix bug not registering remote MAC on SYN
Browse files Browse the repository at this point in the history
  • Loading branch information
soypat committed Nov 19, 2023
1 parent af8ab03 commit 6a1bb58
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
3 changes: 2 additions & 1 deletion stack/socket_tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func (t *TCPSocket) handleRecv(response []byte, pkt *TCPPacket) (n int, err erro
}
if segIncoming.Flags.HasAny(seqs.FlagSYN) && t.remote == (netip.AddrPort{}) {
// We have a client that wants to connect to us.
t.remoteMAC = pkt.Eth.Source
t.remote = netip.AddrPortFrom(netip.AddrFrom4(pkt.IP.Source), pkt.TCP.SourcePort)
}
pkt.InvertSrcDest()
Expand Down Expand Up @@ -214,7 +215,7 @@ func (t *TCPSocket) handleUser(response []byte, pkt *TCPPacket) (n int, err erro
}

func (t *TCPSocket) setSrcDest(pkt *TCPPacket) {
pkt.Eth.Source = t.stack.mac
pkt.Eth.Source = t.stack.MACAs6()
pkt.IP.Source = t.stack.IP.As4()
pkt.TCP.SourcePort = t.localPort

Expand Down
21 changes: 14 additions & 7 deletions stack/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestStackSendReceive_simplex(t *testing.T) {
}
got := socketReadAllString(server)
if got != data {
t.Errorf("got %q want %q", got, data)
t.Errorf("server: got %q want %q", got, data)
}
}

Expand All @@ -81,17 +81,15 @@ func TestStackSendReceive_duplex(t *testing.T) {
clientstr := socketReadAllString(client)
serverstr := socketReadAllString(server)
if clientstr != data {
t.Errorf("got %q want %q", clientstr, data)
t.Errorf("client: got %q want %q", clientstr, data)
}
if serverstr != data {
t.Errorf("got %q want %q", serverstr, data)
t.Errorf("server: got %q want %q", serverstr, data)
}
}

func isDroppedPacket(err error) bool {
return err != nil && (errors.Is(err, stack.ErrDroppedPacket) || strings.HasPrefix(err.Error(), "drop"))
}

// exchangeStacks exchanges packets between stacks until no more data is being sent or maxExchanges is reached.
// By convention client (initiator) is the first stack and server (listener) is the second when dealing with pairs.
func exchangeStacks(t *testing.T, maxExchanges int, stacks ...*stack.PortStack) (ex, bytesSent int) {
t.Helper()
sprintErr := func(err error) (s string) {
Expand All @@ -108,6 +106,7 @@ func exchangeStacks(t *testing.T, maxExchanges int, stacks ...*stack.PortStack)
for ; ex <= maxExchanges; ex++ {
sentInTx := 0
for isend := 0; isend < len(stacks); isend++ {
// This first for loop generates packets "in-flight" contained in `pipes` data structure.
pipeN[isend], err = stacks[isend].HandleEth(pipes[isend][:])
if err != nil && !isDroppedPacket(err) {
t.Errorf("ex[%d] send[%d]: %s", ex, isend, sprintErr(err))
Expand All @@ -131,11 +130,15 @@ func exchangeStacks(t *testing.T, maxExchanges int, stacks ...*stack.PortStack)
break // No more data being sent.
}
for isend := 0; isend < len(stacks); isend++ {
// We deliver each in-flight packet to all stacks, except the one that sent it.
payload := getPayload(isend)
if len(payload) == 0 {
continue
}
for irecv := 0; irecv < len(stacks); irecv++ {
if irecv == isend {
continue // Don't deliver to self.
}
err = stacks[irecv].RecvEth(payload)
if err != nil && !isDroppedPacket(err) {
t.Errorf("ex[%d] recv[%d]: %s", ex, irecv, sprintErr(err))
Expand All @@ -150,6 +153,10 @@ func exchangeStacks(t *testing.T, maxExchanges int, stacks ...*stack.PortStack)
return ex, bytesSent
}

func isDroppedPacket(err error) bool {
return err != nil && (errors.Is(err, stack.ErrDroppedPacket) || strings.HasPrefix(err.Error(), "drop"))
}

func createTCPClientServerPair(t *testing.T) (client, server *stack.TCPSocket) {
t.Helper()
const (
Expand Down

0 comments on commit 6a1bb58

Please sign in to comment.