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 a server API. #39

Merged
merged 9 commits into from
Oct 24, 2024
Merged

Add a server API. #39

merged 9 commits into from
Oct 24, 2024

Conversation

hlef
Copy link
Collaborator

@hlef hlef commented Oct 9, 2024

This PR implements a server API, and showcases it with a toy HTTP server.

This has been tested in normal conditions, through various edge-cases (retransmitted SYNs, incomplete TCP create three-way handshake, client-side termination and server-side termination), as well as through various network stack resets. I also tested it for memory leaks.

@hlef hlef requested a review from davidchisnall October 9, 2024 05:22
@hlef hlef force-pushed the hlefeuvre/server-api-v3 branch from 1df9fa4 to 8d5de2c Compare October 9, 2024 05:38
@hlef
Copy link
Collaborator Author

hlef commented Oct 9, 2024

For testing, I found hping3 particularly useful:

  • hping3 -c 1 -S -p 80 $ip for sending a single SYN (incomplete three-way handshake)
  • hping3 -c 1 -S -p 80 $ip -s 9999 for sending a single SYN that reuses the same client port 9999 (simulate SYN retransmissions)
  • hping3 -c 1 -1 $ip for sending a ping of the death (see patch here)

I simply used curl to grab the webpage this server serves: curl $ip.

It is worth noting that this server does not properly close the TCP connection with the client, and so curl has to be forcefully terminated (e.g., with CTRL-C). This is due to a pre-existing bug which I documented in #40 .

Also, the server seems to indicate a memory leak when a network stack reset occurs. I suspect that this is also a pre-existing problem which should be investigated separately.

examples/05.HTTP_SERVER/http_server.cc Outdated Show resolved Hide resolved
examples/05.HTTP_SERVER/xmake.lua Outdated Show resolved Hide resolved
include/NetAPI.h Outdated Show resolved Hide resolved
include/NetAPI.h Outdated Show resolved Hide resolved
include/NetAPI.h Show resolved Hide resolved
lib/tcpip/network_wrapper.cc Show resolved Hide resolved
lib/tcpip/network_wrapper.cc Outdated Show resolved Hide resolved
lib/tcpip/network_wrapper.cc Show resolved Hide resolved
lib/tcpip/network_wrapper.cc Show resolved Hide resolved
lib/tcpip/network_wrapper.cc Show resolved Hide resolved
examples/05.HTTP_SERVER/http_server.cc Outdated Show resolved Hide resolved
examples/05.HTTP_SERVER/http_server.cc Outdated Show resolved Hide resolved
include/NetAPI.h Show resolved Hide resolved
lib/firewall/firewall.cc Show resolved Hide resolved
@davidchisnall
Copy link
Contributor

Just checking, but I think TLS is out of scope for this? Connecting up the server bits of BearSSL is future work?

@hlef
Copy link
Collaborator Author

hlef commented Oct 11, 2024

Just checking, but I think TLS is out of scope for this? Connecting up the server bits of BearSSL is future work?

Right, I would consider this future work. Hopefully that makes sense?

The maximum number of TCP connections is set in an indirect way through
`ipconfigTCP_WIN_SEG_COUNT` (see documentation in `FreeRTOSIPConfig.h`).

However we need to use it at other places in the code base. Factor it
out of `ipconfigTCP_WIN_SEG_COUNT` into a separate constant.

Signed-off-by: Hugo Lefeuvre <[email protected]>
@davidchisnall davidchisnall force-pushed the hlefeuvre/server-api-v3 branch from 8d5de2c to bf13210 Compare October 14, 2024 09:18
@davidchisnall
Copy link
Contributor

(Rebasing to pick up CI fixes)

@davidchisnall
Copy link
Contributor

Now the CI failures are new, not ones that were present prior to this PR.

@hlef
Copy link
Collaborator Author

hlef commented Oct 18, 2024

Now the CI failures are new, not ones that were present prior to this PR.

Thanks for rebasing! I'll fix that as well.

@hlef hlef force-pushed the hlefeuvre/server-api-v3 branch 3 times, most recently from 4d4dbee to e8610c3 Compare October 19, 2024 00:52
hlef added 2 commits October 21, 2024 14:21
A server port is a local TCP port which is listened to by an
application.

Any new TCP connection to a local server port (detected through an
incoming SYN) causes the creation of a firewall entry.

There is no equivalent concept for UDP, as we do not currently have any
use-case for a UDP server that cannot be handled with custom rules (NTP,
DNS, DHCP, QUIC).

This commit also fixes the documentation of other firewall APIs which do
not specify which compartment they should be called from.

Signed-off-by: Hugo Lefeuvre <[email protected]>
…reset.

The reset process flushes all firewall tables, so no need to close the
firewall holes again when calling `network_socket_close` on a socket
from an older instance of the stack.

Signed-off-by: Hugo Lefeuvre <[email protected]>
@hlef hlef force-pushed the hlefeuvre/server-api-v3 branch 3 times, most recently from 509b0d1 to 29e0b55 Compare October 22, 2024 03:54
hlef added 6 commits October 22, 2024 11:26
The new server API allows application-level code to create listening TCP
sockets bound to given server ports, and accept connections on a
listening socket.

The permission to open a given server port is encoded in bind
capabilities: capabilities sealed with a NetAPI-owned key that permit
the opening of a TCP server port on either IPv4 or IPv6, and enforce a
limit on the maximum number of concurrent TCP connections that may be
opened on the server port.

Important implementation point here: we use socket callbacks to handle
the situation where a three-way TCP handshake initiated by a peer on a
listening socket fails. In this case the firewall hole will be closed by
the socket disconnection callback and not by a call to
`FreeRTOS_closesocket`. See comment in `network_wrapper.cc` for more
details. This behavior can easily be tested by sending a lone TCP SYN,
e.g., through:

   hping3 -c 1 -S -p $port $ip

Signed-off-by: Hugo Lefeuvre <[email protected]>
The NetAPI currently uses null as common error value for pointer types.

This is problematic as it does not cover "compartment-wide" types of
failure, such as `-ECOMPARTMENTFAIL` or `-ENOTENOUGHSTACK`.

Address this by documenting error values for pointer types as untagged
values instead of null.

This does not require changes in the NetAPI implementation, as null is
itself untagged.

Examples do not currently check error values so do not need updating
either. (Note: maybe they should to give an example of proper use of
the API...)

Signed-off-by: Hugo Lefeuvre <[email protected]>
This commit updates the auditing policy of the network stack to include
the new firewall APIs and the new bind capabilities.

This commit also fixes some pre-existing issues:
- checks were missing from some previous changes (`ethernet_link_is_up`,
  `firewall_mac_address_get`, among others)
- the SNTP-related rules always fail if SNTP is not compiled in

Signed-off-by: Hugo Lefeuvre <[email protected]>
`network_socket_send` and `tls_connection_send` return a signed value,
so the current code is incorrect.

Signed-off-by: Hugo Lefeuvre <[email protected]>
The compartments will be compiled anyways as dependencies.

Signed-off-by: Hugo Lefeuvre <[email protected]>
@hlef hlef force-pushed the hlefeuvre/server-api-v3 branch from 29e0b55 to ed0f11f Compare October 22, 2024 18:27
@hlef
Copy link
Collaborator Author

hlef commented Oct 23, 2024

@davidchisnall @nwf All comments addressed! I re-tested with the new changes. I also ensured that the rego audit changes pass as expected (and needed a few fixes to pre-existing issues for that).

@hlef hlef requested review from nwf and davidchisnall October 23, 2024 17:28
@hlef hlef merged commit 473249a into main Oct 24, 2024
2 checks passed
@hlef hlef deleted the hlefeuvre/server-api-v3 branch October 24, 2024 17:27
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.

3 participants