Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIN is sent before earlier data #3100

Open
stevenengler opened this issue Aug 9, 2023 · 1 comment
Open

FIN is sent before earlier data #3100

stevenengler opened this issue Aug 9, 2023 · 1 comment
Labels
Type: Bug Error or flaw producing unexpected results

Comments

@stevenengler
Copy link
Contributor

stevenengler commented Aug 9, 2023

If an application does a large write and then a shutdown(SHUT_WR), the FIN packet seems to be sent before the data (and even before acknowledging the peer's SYN). For example with the client:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('server', 8080))
s.send(b'1'*1000)
s.shutdown(socket.SHUT_WR)
assert b'' == s.recv(1)
s.close()

Shadow gives the pcap:

1691601064_grim

We can see that the 1000 bytes are sent after the FIN packet, which leads to bugs.

@robgjansen This might be related to the tgen stream issue, where we can close the socket while there is still data in the send buffer, and it seems like the FIN might be sent out-of-order.

Server code

import asyncio
import socket
import sys

async def handle_client(client, addr):
    loop = asyncio.get_event_loop()

    while True:
        buf = await loop.sock_recv(client, 1024)
        if len(buf) == 0:
            break

    print("Connection closed:", addr)
    client.close()

async def run_server(port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', port))
    server.listen(100)
    server.setblocking(False)

    loop = asyncio.get_event_loop()

    while True:
        client, addr = await loop.sock_accept(server)
        print("New connection:", addr)
        loop.create_task(handle_client(client, addr))

asyncio.run(run_server(int(sys.argv[1])))

@stevenengler stevenengler added the Type: Bug Error or flaw producing unexpected results label Aug 9, 2023
@stevenengler
Copy link
Contributor Author

Also worth noting that the sequence numbers seem to be ordered correctly (the data has SEQ=2 and the FIN has SEQ=3), even though they're sent out-of-order.

I'm not sure exactly what's happening within shadow's TCP code. It seems like the server is dropping the FIN, receiving the data, and then the client is never retransmitting the FIN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Error or flaw producing unexpected results
Projects
None yet
Development

No branches or pull requests

1 participant