From f11153b3c675ed59f906afa6460019a32c4f59ac Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sun, 3 Nov 2024 09:47:29 +0100 Subject: [PATCH] Fix CLOSED event, fix linux test callback --- src/femtotcp.c | 29 +++++++++++--------- test/test-linux.c | 67 +++++++++++++++++++++++------------------------ 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/femtotcp.c b/src/femtotcp.c index 40fcf8a..df194ae 100644 --- a/src/femtotcp.c +++ b/src/femtotcp.c @@ -4,7 +4,7 @@ * Copyright: 2024 Danielinux * */ - + #include #include #include "femtotcp.h" @@ -87,7 +87,7 @@ struct fifo { /* TCP TX is a circular buffer and contains an array of full packets */ /* TCP RX only contains application data */ -/* FIFO functions +/* FIFO functions * head: next empty slot * tail: oldest populated slot * @@ -143,7 +143,7 @@ static struct pkt_desc *fifo_peek(struct fifo *f) f->tail = 0; f->h_wrap = 0; } - if (f->tail == f->head) + if (f->tail == f->head) return NULL; while (f->tail % 4) f->tail++; @@ -527,7 +527,7 @@ struct timers_binheap { uint32_t size; }; -struct ipstack +struct ipstack { struct ll ll_dev; struct ipconf ipconf; @@ -668,7 +668,7 @@ static void udp_try_recv(struct ipstack *s, struct ipstack_udp_datagram *udp, ui { for (int i = 0; i < MAX_UDPSOCKETS; i++) { struct tsocket *t = &s->udpsockets[i]; - if (t->src_port == ee16(udp->dst_port) && t->dst_port == ee16(udp->src_port) && + if (t->src_port == ee16(udp->dst_port) && t->dst_port == ee16(udp->src_port) && (((t->local_ip == 0) && DHCP_IS_RUNNING(s)) || (t->local_ip == ee32(udp->ip.dst) && t->remote_ip != s->ipconf.ip)) ) { @@ -1020,7 +1020,7 @@ static void tcp_ack(struct tsocket *t, struct ipstack_tcp_seg *tcp) desc = fifo_next(&t->sock.tcp.txbuf, desc); } } -} +} /* Preselect socket, parse options, manage handshakes, pass to application */ static void tcp_input(struct ipstack *S, struct ipstack_tcp_seg *tcp, uint32_t frame_len) @@ -1051,13 +1051,15 @@ static void tcp_input(struct ipstack *S, struct ipstack_tcp_seg *tcp, uint32_t f t->sock.tcp.state = TCP_CLOSE_WAIT; t->sock.tcp.ack = ee32(tcp->seq) + 1; tcp_send_ack(t); + t->events |= CB_EVENT_CLOSED; } else if (t->sock.tcp.state == TCP_FIN_WAIT_1) { t->sock.tcp.state = TCP_CLOSING; t->sock.tcp.ack = ee32(tcp->seq) + 1; tcp_send_ack(t); + t->events |= CB_EVENT_CLOSED; } - } + } /* Check if SYN */ if (tcp->flags & 0x02) { @@ -1102,12 +1104,12 @@ static void tcp_input(struct ipstack *S, struct ipstack_tcp_seg *tcp, uint32_t f /* FIN */ if (t->sock.tcp.state == TCP_ESTABLISHED) { t->sock.tcp.state = TCP_CLOSE_WAIT; - t->events |= CB_EVENT_CLOSED; t->events &= ~CB_EVENT_READABLE; } else if (t->sock.tcp.state == TCP_FIN_WAIT_1) { t->sock.tcp.state = TCP_CLOSING; } t->sock.tcp.ack = ee32(tcp->seq) + 1; + t->events |= CB_EVENT_CLOSED; tcp_send_ack(t); } if (tcp->flags & 0x10) { @@ -1280,7 +1282,7 @@ int ft_accept(struct ipstack *s, int sockfd, struct ipstack_sockaddr *addr, sock int ft_sendto(struct ipstack *s, int sockfd, const void *buf, size_t len, int flags, const struct ipstack_sockaddr *dest_addr, socklen_t addrlen) { - uint8_t frame[LINK_MTU]; + uint8_t frame[LINK_MTU]; struct tsocket *ts; struct ipstack_tcp_seg *tcp = (struct ipstack_tcp_seg *)frame; struct ipstack_udp_datagram *udp = (struct ipstack_udp_datagram *)frame; @@ -1780,7 +1782,7 @@ int dhcp_client_init(struct ipstack *s) if (s->dhcp_udp_sd > 0) { ft_close(s, s->dhcp_udp_sd); } - + s->dhcp_udp_sd = ft_socket(s, AF_INET, IPSTACK_SOCK_DGRAM, IPPROTO_UDP); if (s->dhcp_udp_sd < 0) { s->dhcp_state = DHCP_OFF; @@ -1898,7 +1900,7 @@ void ipstack_init_static(struct ipstack **s) /* ipstack_poll: poll the network stack for incoming packets * This function should be called in a loop to process incoming packets. * It will call the poll function of the device driver and process the - * received packets. + * received packets. * * This function also handles timers for all supported protocols. * @@ -1971,6 +1973,7 @@ int ipstack_poll(struct ipstack *s, uint64_t now) ts->callback(i | MARK_TCP_SOCKET, ts->events, ts->callback_arg); ts->events = 0; } + } for (i = 0; i < MAX_UDPSOCKETS; i++) { struct tsocket *ts = &s->udpsockets[i]; @@ -2011,7 +2014,7 @@ int ipstack_poll(struct ipstack *s, uint64_t now) struct ipstack_timer tmr = {}; len = desc->len - ETH_HEADER_LEN; tcp = (struct ipstack_tcp_seg *)(ts->txmem + desc->pos + sizeof(*desc)); - if ((ts->sock.tcp.ack == ts->sock.tcp.last_ack) && + if ((ts->sock.tcp.ack == ts->sock.tcp.last_ack) && (len == IP_HEADER_LEN + (uint32_t)(tcp->hlen >> 2)) && (tcp->flags == 0x10)) { desc->flags |= PKT_FLAG_SENT; @@ -2059,7 +2062,7 @@ int ipstack_poll(struct ipstack *s, uint64_t now) /* Send ARP request */ arp_request(s, nexthop); break; - } + } if (IS_IP_BCAST(nexthop)) memset(t->nexthop_mac, 0xFF, 6); #endif len = desc->len - ETH_HEADER_LEN; diff --git a/test/test-linux.c b/test/test-linux.c index 0d2967c..418224e 100644 --- a/test/test-linux.c +++ b/test/test-linux.c @@ -26,31 +26,28 @@ static int closed = 0; static void socket_cb(int fd, uint16_t event, void *arg) { int ret = 0; - printf("Called socket_cb, events: %04x\n", event); + printf("Called socket_cb, events: %04x fd %d\n", event, fd & (~0x1000)); - if ((fd == listen_fd) && (event & CB_EVENT_READABLE)) { + if ((fd == listen_fd) && (event & CB_EVENT_READABLE) && (client_fd == -1)) { client_fd = ft_accept((struct ipstack *)arg, listen_fd, NULL, NULL); if (client_fd > 0) { printf("accept: %04x\n", client_fd); } } else if ((fd == client_fd) && (event & CB_EVENT_READABLE )) { ret = ft_recvfrom((struct ipstack *)arg, client_fd, buf, sizeof(buf), 0, NULL, NULL); - if (ret == -11) - return; /* Call again */ - if (ret < 0) { - printf("Recv error: %d\n", ret); - ft_close((struct ipstack *)arg, client_fd); - return; - } else if (ret == 0) { - printf("Client side closed the connection.\n"); - ft_close((struct ipstack *)arg, client_fd); - client_fd = -1; - printf("Server: Exiting.\n"); - exit_ok = 1; - return; - } else if (ret > 0) { - printf("recv: %d, echoing back\n", ret); - tot_recv += ret; + if (ret != -11) { + if (ret < 0) { + printf("Recv error: %d\n", ret); + ft_close((struct ipstack *)arg, client_fd); + } else if (ret == 0) { + printf("Client side closed the connection.\n"); + ft_close((struct ipstack *)arg, client_fd); + printf("Server: Exiting.\n"); + exit_ok = 1; + } else if (ret > 0) { + printf("recv: %d, echoing back\n", ret); + tot_recv += ret; + } } } if ((event & CB_EVENT_WRITABLE) || ((ret > 0) && !closed)) { @@ -60,24 +57,26 @@ static void socket_cb(int fd, uint16_t event, void *arg) printf("Server: I closed the connection.\n"); closed = 1; } - if (tot_sent >= tot_recv) - return; - snd_ret = ft_sendto((struct ipstack *)arg, client_fd, buf + tot_sent, tot_recv - tot_sent, 0, NULL, 0); - if (snd_ret == -11) - return; /* Call again */ - if (snd_ret < 0) { - printf("Send error: %d\n", snd_ret); - ft_close((struct ipstack *)arg, client_fd); - return; - } - - tot_sent += snd_ret; - printf("sent %d bytes\n", snd_ret); - if (tot_recv == tot_sent) { - tot_sent = 0; - tot_recv = 0; + if (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) { + printf("Send error: %d\n", snd_ret); + ft_close((struct ipstack *)arg, client_fd); + } else { + tot_sent += snd_ret; + printf("sent %d bytes\n", snd_ret); + if (tot_recv == tot_sent) { + tot_sent = 0; + tot_recv = 0; + } + } + } } } + if (event & CB_EVENT_CLOSED) { + printf("Closing %d, client fd: %d\n", fd, client_fd); + } if ((fd == client_fd) && (event & CB_EVENT_CLOSED)) { printf("Client side closed the connection (EVENT_CLOSED)\n"); ft_close((struct ipstack *)arg, client_fd);