Skip to content

TcpConnection writes become stuck #6

Open
@gbl08ma

Description

@gbl08ma

Steps to reproduce:

  1. Set up a v86 VM that boots the linux4.iso available at https://i.copy.sh/linux4.iso (note: you might need to copy link and paste in a new window to not run into a 403 Forbidden 😕)
  2. Create a stack with a TAP interface and attach it to the v86 VM, more or less like this:
const networkStack = await createStack();

const tapInterface = await networkStack.createTapInterface({
  mac: '02:00:00:01:00:01',
  ip: 192.168.255.1/24',
});

const vmNic = createV86NetworkStream(emulator);
tapInterface.readable.pipeTo(vmNic.writable);
vmNic.readable.pipeTo(tapInterface.writable);
  1. Create a TCP listener that queues lots of stuff to be written as soon as a client connects, more or less like this:
const listener = await lan.listenTcp(5000);
const handler = async () => {
	for await (const connection of listener) {
		const readable = new ReadableStream({
			start: (controller) => {
				const a = async () => {
					for (let j = 0; j < 10; j++) {
						const b = new TextEncoder().encode('12345678\nabcdefgh\n'.repeat(2000) + "END\n");
						controller.enqueue(b);
					}
				};
				a();
			}
		});

		// could also use await readable.pipeTo(connection.writable) - it also wouldn't work as intended
		const reader = readable.getReader();
		const writer = connection.writable.getWriter();
		while (true) {
			const { done, value } = await reader.read();
			if (done) break;
			await writer.write(value);
		}
	}
};
handler();
  1. Boot the VM and assign it an IP within the subnet, with ifconfig eth0 up arp 192.168.255.2. You may ping 192.168.255.1 to confirm it's connected.
  2. Connect to the listener with e.g. telnet 192.168.255.1 5000

Expectation: the full stream available from the ReadableStream gets printed, ending with END.

What I observe: after one or two calls to writer.write (depends on how much is being written/read at a time from the reader-writer combo), the promise returned by writer.write(value) never resolves and the data transfer becomes stuck, despite the VM guest still having the socket open and trying to receive data.
I observe the same behavior with Windows guests inside the VM, and also when using the stream() provided by a File from a file input.

If you have trouble reproducing just let me know, I can try to set up a full minimal example that's ready to run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions