diff --git a/src/microtcp.c b/src/microtcp.c index 2d55e13..e623843 100644 --- a/src/microtcp.c +++ b/src/microtcp.c @@ -5,6 +5,7 @@ #include #include #include + #include "ip.h" #include "arp.h" #include "tcp.h" @@ -111,6 +112,17 @@ struct microtcp_t { microtcp_socket_t socket_pool[MICROTCP_MAX_SOCKETS]; }; +typedef enum { + ETHERNET_PROTOCOL_ARP = 0x0806, + ETHERNET_PROTOCOL_IP = 0x0800, +} ethernet_protocol_t; + +typedef struct { + mac_address_t dst; + mac_address_t src; + uint16_t proto; +} __attribute__((packed)) ethernet_frame_t; + microtcp_errcode_t microtcp_get_error(microtcp_t *mtcp) { return mtcp->errcode; @@ -147,17 +159,6 @@ const char *microtcp_strerror(microtcp_errcode_t errcode) return "???"; } -typedef enum { - ETHERNET_PROTOCOL_ARP = 0x0806, - ETHERNET_PROTOCOL_IP = 0x0800, -} ethernet_protocol_t; - -typedef struct { - mac_address_t dst; - mac_address_t src; - uint16_t proto; -} __attribute__((packed)) ethernet_frame_t; - static void send_arp_packet(void *data, mac_address_t dst) { microtcp_t *mtcp = data; @@ -326,13 +327,8 @@ process_packet(microtcp_t *mtcp, const void *packet, size_t len) switch (net_to_cpu_u16(frame->proto)) { - case ETHERNET_PROTOCOL_ARP: - arp_process_packet(&mtcp->arp_state, frame+1, len - sizeof(ethernet_frame_t)); - break; - - case ETHERNET_PROTOCOL_IP: - ip_process_packet(&mtcp->ip_state, frame+1, len - sizeof(ethernet_frame_t)); - break; + case ETHERNET_PROTOCOL_ARP: arp_process_packet(&mtcp->arp_state, frame+1, len - sizeof(ethernet_frame_t)); break; + case ETHERNET_PROTOCOL_IP : ip_process_packet(&mtcp->ip_state, frame+1, len - sizeof(ethernet_frame_t)); break; default: // Unsupported ethertype @@ -745,7 +741,7 @@ static void conn_event_callback(void *data, tcp_connevent_t event) { microtcp_socket_t *socket = data; - int flags; + int flags = 0; switch (event) { case TCP_CONNEVENT_RECV: @@ -760,10 +756,14 @@ static void conn_event_callback(void *data, tcp_connevent_t event) flags = MICROTCP_MUX_SEND; break; - case TCP_CONNEVENT_RESET: - case TCP_CONNEVENT_CLOSE: + case TCP_CONNEVENT_RESET: + MICROTCP_DEBUG_LOG("Signal RESET"); + socket->conn = NULL; + break; + + case TCP_CONNEVENT_CLOSE: + MICROTCP_DEBUG_LOG("Signal CLOSE"); socket->conn = NULL; - flags = 0; // TODO: Maybe signal closing and reset events to muxes? break; } if (flags) @@ -1234,7 +1234,7 @@ bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev) while (!mux_poll(mux, ev)) { MICROTCP_DEBUG_LOG("Multiplexer waiting for an event"); if (cnd_wait(&mux->queue_not_empty, &mux->mtcp->lock) != thrd_success) - abort(); + abort(); // FIXME: Shouldn't just abort like this MICROTCP_DEBUG_LOG("Multiplexer woke up for an event"); } mtx_unlock(&mux->mtcp->lock); diff --git a/src/tcp.c b/src/tcp.c index c6378b0..d537b14 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -97,7 +97,6 @@ connection_create(tcp_listener_t *listener, ip_address_t ip, uint16_t port, uint c->snd_nxt = seq; c->snd_wl1 = seq; c->snd_wl2 = ack; - c->last_acked = 0; c->oused = 0; c->waiting_ack_for_syn = false; c->waiting_ack_for_fin = false; @@ -292,9 +291,6 @@ static void transmit_rst(tcp_connection_t *c, bool ack) .payload = SLICE_EMPTY, }; transmit_basic(tcp, config); - - if (flags & TCP_FLAG_ACK) - c->last_acked = c->rcv_nxt; } #ifdef TCP_DEBUG @@ -330,14 +326,6 @@ static void transmit_(tcp_connection_t *c, uint8_t flags, bool no_payload tcp_listener_t *listener = c->listener; tcp_state_t *tcp = listener->state; - if (flags == TCP_FLAG_ACK && no_payload) { - // The peer is requesting a segment just containing an ACK - // If there are no additional bytes to ACK, ignore the - // transmission request. - if (c->last_acked == c->rcv_nxt) - return; - } - bool ack = flags & TCP_FLAG_ACK; size_t waiting_to_be_sent = c->oused - (c->snd_nxt - c->snd_una); @@ -412,9 +400,6 @@ static void transmit_(tcp_connection_t *c, uint8_t flags, bool no_payload c->waiting_ack_for_syn = true; } - if (flags & TCP_FLAG_ACK) - c->last_acked = c->rcv_nxt; - // Restart the retransmission timer if necessary if (c->snd_una < c->snd_nxt) { @@ -436,6 +421,7 @@ static void transmit_(tcp_connection_t *c, uint8_t flags, bool no_payload static void retransmit(tcp_connection_t *c) { + TCP_DEBUG_LOG("Retransmitting"); tcp_listener_t *listener = c->listener; tcp_state_t *tcp = listener->state; @@ -1211,7 +1197,7 @@ void tcp_process_segment(tcp_state_t *tcp, ip_address_t sender, // and that SND.WL2 records the acknowledgment number of the last // segment used to update SND.WND. The check here prevents using // old segments to update the window. - + TCP_DEBUG_LOG("ack=%lld, UNA=%lld, NXT=%lld", ack, c->snd_una, c->snd_nxt); if (ack > c->snd_nxt) { // Peer acked something not sent yet transmit(c, TCP_FLAG_ACK, true); @@ -1275,8 +1261,9 @@ void tcp_process_segment(tcp_state_t *tcp, ip_address_t sender, // In addition to the processing for the ESTABLISHED state, if the // ACK acknowledges our FIN, then enter the TIME-WAIT state; // otherwise, ignore the segment. - + TCP_DEBUG_LOG("ACK with seq=%lld, ack=%lld reached here (NXT=%lld)", seq, ack, c->snd_nxt); if (ack == c->snd_nxt) { + TCP_DEBUG_LOG("And here"); // Everything was ACKed, so if a FIN was sent that was ACKed too. transition_to_time_wait(c); } @@ -1350,8 +1337,8 @@ void tcp_process_segment(tcp_state_t *tcp, ip_address_t sender, { size_t num = move_data_into_input_buffer(c, payload); if (num > 0) { - if (c->cb_event) c->cb_event(c->cb_data, TCP_CONNEVENT_RECV); transmit(c, TCP_FLAG_ACK, false); + if (c->cb_event) c->cb_event(c->cb_data, TCP_CONNEVENT_RECV); } } break; diff --git a/src/tcp.h b/src/tcp.h index e41ab7a..6aea7e9 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -187,9 +187,7 @@ struct tcp_connection_t { uint32_t snd_wl2; // SND.WL2 from RFC 9293 // segment acknowledgment number used for // last window update. - - uint32_t last_acked; // Last sequence number of the peer that was ACKed - + // If true, the next segment which will empty the // output buffer will contain a FIN. bool send_fin_when_fully_flushed;