Fix callbacks, added some design doc

This commit is contained in:
Daniele Lacamera 2024-11-03 16:26:14 +01:00
parent f11153b3c6
commit 574abdca7b
3 changed files with 126 additions and 22 deletions

2
.gitignore vendored
View file

@ -2,5 +2,5 @@
*.a
*.pcap
build/*
test/unit/unit-core
test/unit/unit
tags

107
core.md Normal file
View file

@ -0,0 +1,107 @@
# FemtoTCP
## Stack architecture
- No dynamic allocation (pre-allocated sockets and buffers)
- Four-steps main loop function
- Callback-based socket interface (allows implementing blocking BSD calls)
## Data structures
* Two types of circular buffers (fixed size):
- "fifo" : contains entire frames, including a descriptor.
- "queue" : contains pure data, indexed by byte. Used for TCP receive buffer
only.
* One binary heap for timers
### FemtoTCP fifo
```
+---------------------------------------------------------------------------------------------------------------------------+
| +-----+---+----+-----+------------------+-----+---+----+-----+------------------+ |
| | De | E | IP | TCP | Payload | De | E | IP | TCP | Payload | |
| | sc | T | | | | sc | T | | | | |
|* FREE SPACE * | ri | H | | | | ri | H | | | | * FREE SPACE* |
| | pt | | | | | pt | | | | | |
| | or | | | | | or | | | | | |
| +-----+---+----+-----+------------------+-----+---+----+-----+------------------+ |
+---------------------------------------------------------------------------------------------------------------------------+
^ ^
| |
| |
| |
|Tail Head|
```
### FemtoTCP queue
```
+--------------+--------------------------------------------+---------------------------------------------------------------+
| |*------------------------------------------*| |
| || || |
| || || |
|* FREE SPACE *|| DATA PAYLOAD || * FREE SPACE * |
| || || |
| || || |
| |*------------------------------------------*| |
+--------------+--------------------------------------------+---------------------------------------------------------------+
^ ^
| |
| |
| |
|Tail Head|
```
## Sockets
### TCP socket
```
+-------------+
|Main loop TX |
+-------------+
^
+----------------------------------+ |
| | +------+
| TCP Socket | |
| | |
| | |
| | |
| +-----------------------+
| +---------------+ | |
>DATA OUT==>>|socket send() |-->| TX buffer (fifo) |
| +---------------+ | |
| +-----------------------+
| |
| |
| |
| +-----------------------+
| +-------------+ | |
<DATA IN<<====|socket recv()|<---| RX buffer (queue) |
| +-------------+ | |
| +-----------------------+
+----------------------------------+ ^
|
|
|
+--------------+
| tcp_recv() |
+--------------+
```

View file

@ -56,8 +56,9 @@ static void socket_cb(int fd, uint16_t event, void *arg)
ft_close((struct ipstack *)arg, client_fd);
printf("Server: I closed the connection.\n");
closed = 1;
exit_ok = 1;
}
if (tot_sent < tot_recv) {
if ((!closed) && (tot_sent < tot_recv)) {
snd_ret = ft_sendto((struct ipstack *)arg, client_fd, buf + tot_sent, tot_recv - tot_sent, 0, NULL, 0);
if (snd_ret != -11) {
if (snd_ret < 0) {
@ -90,30 +91,12 @@ static void socket_cb(int fd, uint16_t event, void *arg)
static int test_echoserver(struct ipstack *s, int active_close)
{
int ret;
struct ipstack_sockaddr_in local_sock = {
.sin_family = AF_INET,
.sin_port = ee16(8), /* Echo */
.sin_addr.s_addr = 0
};
exit_ok = 0;
exit_count = 0;
listen_fd = -1;
client_fd = -1;
tot_sent = 0;
server_closing = active_close;
closed = 0;
listen_fd = ft_socket(s, AF_INET, IPSTACK_SOCK_STREAM, 0);
printf("socket: %04x\n", listen_fd);
ipstack_register_callback(s, listen_fd, socket_cb, s);
ret = ft_bind(s, listen_fd, (struct ipstack_sockaddr *)&local_sock, sizeof(local_sock));
printf("bind: %d\n", ret);
ret = ft_listen(s, listen_fd, 1);
printf("listen: %d\n", ret);
while(1) {
uint32_t ms_next;
struct timeval tv;
@ -126,7 +109,6 @@ static int test_echoserver(struct ipstack *s, int active_close)
else break;
}
}
ft_close(s, listen_fd);
return 0;
}
@ -172,6 +154,9 @@ void *pt_echoclient(void *arg)
}
if (ret == 0) {
printf("test client read: server has closed the connection.\n");
if (server_closing)
return (void *)0;
else
return (void *)-1;
}
total_r += ret;
@ -201,6 +186,11 @@ int main(int argc, char **argv)
struct in_addr linux_ip;
ip4 ip = 0, nm = 0, gw = 0;
uint32_t srv_ip;
struct ipstack_sockaddr_in local_sock = {
.sin_family = AF_INET,
.sin_port = ee16(8), /* Echo */
.sin_addr.s_addr = 0
};
int ret, test_ret = 0;
(void)argc;
@ -243,9 +233,16 @@ int main(int argc, char **argv)
inet_pton(AF_INET, FEMTOTCP_IP, &srv_ip);
#endif
listen_fd = ft_socket(s, AF_INET, IPSTACK_SOCK_STREAM, 0);
printf("socket: %04x\n", listen_fd);
ipstack_register_callback(s, listen_fd, socket_cb, s);
pthread_create(&pt, NULL, pt_echoclient, &srv_ip);
printf("Starting test: echo server close-wait\n");
ret = ft_bind(s, listen_fd, (struct ipstack_sockaddr *)&local_sock, sizeof(local_sock));
printf("bind: %d\n", ret);
ret = ft_listen(s, listen_fd, 1);
printf("listen: %d\n", ret);
ret = test_echoserver(s, 0);
pthread_join(pt, (void **)&test_ret);
printf("Test echo server close-wait: %d\n", ret);