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

Add network syscalls #512

Merged
merged 41 commits into from
Jul 29, 2023
Merged

Add network syscalls #512

merged 41 commits into from
Jul 29, 2023

Conversation

vinc
Copy link
Owner

@vinc vinc commented Jul 7, 2023

  • Add /dev/net/tcp device file to open a TCP socket handle
  • Add /dev/net/udp device file to open a UDP socket handle
  • Add poll syscall
  • Add connect syscall
  • Add listen syscall
  • Add accept syscall
  • Rewrite tcp command to use the network using syscalls only
  • Rewrite http command to use the network using syscalls only
  • Rewrite httpd command to use the network using syscalls only
  • Rewrite socket command to use the network using syscalls only
  • Rewrite host command to use the network using syscalls only
  • Rewrite dhcp command to use the network using syscalls only

@vinc
Copy link
Owner Author

vinc commented Jul 7, 2023

Syscalls used for a TCP Client:

- OPEN /dev/net/tcp -> handle
- CONNECT handle address port
- WRITE handle buffer -> bytes written
- READ handle buffer -> bytes read
- CLOSE handle

@vinc
Copy link
Owner Author

vinc commented Jul 8, 2023

We could introduce an equivalent of Unix IOCTL named CONTROL or MANAGE to replace CONNECT handle address port with MANAGE handle request response where request could be "connect 192.168.1.1 80" for example.

@vinc
Copy link
Owner Author

vinc commented Jul 10, 2023

We need a poll syscall to be able to wait on multiple handles without blocking.

For example:

let list = vec![(stdin, Event::Read), (socket, Event::Read)];
loop {
  if let Some((h, e)) = syscall::poll(&list) {
    // Read from stdin or socket, whichever is ready first
  }
}

@vinc
Copy link
Owner Author

vinc commented Jul 10, 2023

The updated socket command using poll allows us to have a chat interface with other computers.

The command socket -l 1234 and socket 192.168.1.100 1234 have the equivalent on Unix with nc and can be used to launch a basic chat server/client on port 1234.

What's missing is knowing when a socket connection is closed. We could add another IO::Close event to poll.

@vinc
Copy link
Owner Author

vinc commented Jul 10, 2023

Poll is not blocking for now, so we could poll only one file handle at a time instead of a list. The list is only useful to reduce the number of userspace/kernelspace boundary crossing. But if poll was blocking the we would cross it only once at the beginning. And in that case we need the list because we can't poll the file handles one by one.

@vinc
Copy link
Owner Author

vinc commented Jul 12, 2023

With a blocking poll the console and socket read don't need to be blocking.

@vinc
Copy link
Owner Author

vinc commented Jul 14, 2023

Sometime the TCP state after a connect change directly from syn-sent to close-wait without seemingly going through established but that's only because the transition is too fast. In that case we can check if there's something that can be read to know if an error occurred or not.

@vinc
Copy link
Owner Author

vinc commented Jul 14, 2023

There was some confusion with the syntax for the port number between tcp and socket on one side and http on the other side:

  • tcp <host> <port>
  • socket [<host>] <port>
  • http <host>[:<port>][ ]<path>

We can't change http because of the path so this commit changes the first two commands to remove the confusion.

  • tcp <host>:<port>
  • socket [<host>:]port
  • http <host>[:<port>][ ]<path>

We don't support IPv6 yet but we might want to use ! instead of : like Plan 9 does when this will be the case.

@vinc
Copy link
Owner Author

vinc commented Jul 14, 2023

Finally we also introduced a special case in read to return the socket state without blocking when the given buffer is 1 byte. This is a simple hack that we are also using for reading the console where 4 bytes is read_char and something else like 256 is read_line.

@vinc
Copy link
Owner Author

vinc commented Jul 28, 2023

There's two options for DHCPv4, either using the smoltcp crate's implementation of the protocol in the kernel by creating a special dhcp socket, or reimplementing the protocol in userspace using a pair of UDP sockets. The latter is the most interesting way to do it but this work could be done later in another PR.

The HTTP server will also have to be rewritten but this can be done in a separate PR too.

@vinc vinc marked this pull request as ready for review July 28, 2023 20:07
@vinc
Copy link
Owner Author

vinc commented Jul 29, 2023

The socket file size will now show the recommended buffer size:

> list /dev/net
1446 2023-07-29 12:09:21 tcp
1458 2023-07-29 12:09:21 udp

Size: MTU - Ethernet header - IP header - TCP/UDP header

@vinc
Copy link
Owner Author

vinc commented Jul 29, 2023

We can now delete a device file. This was needed to easily recreate the socket files and change their sizes without recreating the file system.

@vinc vinc merged commit b606c06 into trunk Jul 29, 2023
@vinc vinc deleted the feature/socket-syscalls branch July 29, 2023 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant