diff --git a/makefile b/makefile index e755e92..75cf810 100644 --- a/makefile +++ b/makefile @@ -48,7 +48,7 @@ MEMDBG=valgrind LIBDIR = 3p/lib INCDIR = 3p/include -CFLAGS = $(CFLAGS_PLATFORM) -I$(INCDIR) -Iinclude/ -Wall -Wextra -DARP_DEBUG -DMICROTCP_DEBUG -DIP_DEBUG -DICMP_DEBUG -DTCP_DEBUG -DMICROTCP_BACKGROUND_THREAD -DMICROTCP_USING_TAP -DMICROTCP_USING_MUX +CFLAGS = $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra -DARP_DEBUG -DMICROTCP_DEBUG -DIP_DEBUG -DICMP_DEBUG -DTCP_DEBUG -DMICROTCP_BACKGROUND_THREAD -DMICROTCP_USING_TAP -DMICROTCP_USING_MUX LFLAGS = -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR) ifeq ($(MEMDBG),drmemory) @@ -91,11 +91,11 @@ build/echo_tcp: examples/echo_tcp.c $(LIBDIR)/libtuntap.a 3p/include/tuntap.h 3p mkdir -p $(@D) gcc build/microtcp.c examples/echo_tcp.c -o $@ $(CFLAGS) $(LFLAGS) -build/microtcp.h: include/microtcp.h +build/microtcp.h: src/microtcp.h mkdir -p $(@D) [ ! -e $@ ] || rm $@ echo "#define MICROTCP_AMALGAMATION" >> $@ - cat include/microtcp.h >> $@ + cat src/microtcp.h >> $@ build/microtcp.c: 3p/include/tinycthread.h 3p/src/tinycthread.c $(wildcard src/*.c src/*.h) mkdir -p $(@D) diff --git a/src/arp.c b/src/arp.c index fae8ac5..20fb26b 100644 --- a/src/arp.c +++ b/src/arp.c @@ -697,7 +697,7 @@ arp_process_result_t arp_process_packet(arp_state_t *state, const void *packet, ARP_DEBUG_LOG("Invalid hardware or protocol address size %d or %d (expected %d and %d)", packet2->hardware_len, packet2->protocol_len, 6, 4); return ARP_PROCESS_RESULT_INVALID; } - +/* ARP_DEBUG_LOG("ARP from %d.%d.%d.%d to %d.%d.%d.%d", ((uint8_t*) &packet2->sender_protocol_address)[0], ((uint8_t*) &packet2->sender_protocol_address)[1], @@ -707,7 +707,7 @@ arp_process_result_t arp_process_packet(arp_state_t *state, const void *packet, ((uint8_t*) &packet2->target_protocol_address)[1], ((uint8_t*) &packet2->target_protocol_address)[2], ((uint8_t*) &packet2->target_protocol_address)[3]); - +*/ bool merge = arp_translation_table_update(&state->table, packet2->sender_hardware_address, packet2->sender_protocol_address, state->cache_timeout); @@ -740,7 +740,7 @@ arp_process_result_t arp_process_packet(arp_state_t *state, const void *packet, state->send(state->send_data, packet2->sender_hardware_address); } } else { - ARP_DEBUG_LOG("Request not for me"); + //ARP_DEBUG_LOG("Request not for me"); } return ARP_PROCESS_RESULT_OK; diff --git a/src/ip.c b/src/ip.c index 6b63f08..d4306a0 100644 --- a/src/ip.c +++ b/src/ip.c @@ -252,7 +252,7 @@ void ip_process_packet(ip_state_t *ip_state, const void *packet, size_t len) IP_DEBUG_LOG("Dropping IP packet with invalid checksum"); return; } - +/* IP_DEBUG_LOG("Received packet for %d.%d.%d.%d (I'm %d.%d.%d.%d)", ((uint8_t*) &packet2->dst_ip)[0], ((uint8_t*) &packet2->dst_ip)[1], @@ -262,9 +262,9 @@ void ip_process_packet(ip_state_t *ip_state, const void *packet, size_t len) ((uint8_t*) &ip_state->ip)[1], ((uint8_t*) &ip_state->ip)[2], ((uint8_t*) &ip_state->ip)[3]); - +*/ if (packet2->dst_ip != ip_state->ip) { - IP_DEBUG_LOG("Packet not for me"); +// IP_DEBUG_LOG("Packet not for me"); return; } diff --git a/src/microtcp.c b/src/microtcp.c index c2358da..09fb84a 100644 --- a/src/microtcp.c +++ b/src/microtcp.c @@ -1132,6 +1132,8 @@ microtcp_mux_t *microtcp_mux_create(microtcp_t *mtcp) return mux; } +static bool mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev); + void microtcp_mux_destroy(microtcp_mux_t *mux) { // Unregister all idle sockets @@ -1144,7 +1146,7 @@ void microtcp_mux_destroy(microtcp_mux_t *mux) // Consume all previously reported events // to make sure that when unregistering // the entries are actually removed - while (microtcp_mux_poll(mux, NULL)); + while (mux_poll(mux, NULL)); // Unreagister all sockets that have events while (mux->ready_queue_head) { @@ -1181,6 +1183,8 @@ move_mux_entry_to_free_list(mux_entry_t *entry) microtcp_mux_t *mux = entry->mux; // If the entry is in a list, unlink it + if (mux->ready_queue_tail == entry) + mux->ready_queue_tail = entry->mux_next; if (entry->mux_prev) *entry->mux_prev = entry->mux_next; if (entry->sock_prev) @@ -1197,6 +1201,8 @@ move_mux_entry_to_free_list(mux_entry_t *entry) static void move_mux_entry_to_idle_list(mux_entry_t *entry) { + microtcp_mux_t *mux = entry->mux; + // To be moved to the idle list the entry // must be associated to a socket so it // must be in a socket mux list, therefore @@ -1205,11 +1211,12 @@ move_mux_entry_to_idle_list(mux_entry_t *entry) // Make sure the entry is unlinked relative // to the lists in the mux + if (mux->ready_queue_tail == entry) + mux->ready_queue_tail = entry->mux_next; if (entry->mux_prev) *entry->mux_prev = entry->mux_next; // Now actually insert it into the idle list - microtcp_mux_t *mux = entry->mux; entry->mux_prev = &mux->idle_list; entry->mux_next = mux->idle_list; if (mux->idle_list) @@ -1286,15 +1293,17 @@ bool microtcp_mux_register(microtcp_mux_t *mux, microtcp_socket_t *sock, int eve // Push it into the idle list of the mux entry->mux_prev = &mux->idle_list; - entry->mux_next = mux->idle_list; + entry->mux_next = mux->idle_list; if (mux->idle_list) mux->idle_list->mux_prev = &entry->mux_next; + mux->idle_list = entry; // Push it into the socket mux list entry->sock_prev = &sock->mux_list; - entry->sock_next = sock->mux_list; + entry->sock_next = sock->mux_list; if (sock->mux_list) sock->mux_list->sock_prev = &entry->sock_next; + sock->mux_list = entry; // Initialize the entry entry->sock = sock; @@ -1312,17 +1321,14 @@ bool microtcp_mux_register(microtcp_mux_t *mux, microtcp_socket_t *sock, int eve return true; } -bool microtcp_mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev) +static bool mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev) { - LOCK_WHEN_THREADED(mux->mtcp); + + if (!mux->ready_queue_head) + return false; // No events occurred // Get the tail of the queue (without popping it) - mux_entry_t *entry = mux->ready_queue_tail; - - if (!entry) { - UNLOCK_WHEN_THREADED(mux->mtcp); - return false; // No events occurred - } + mux_entry_t *entry = mux->ready_queue_head; // If this socket was in the ready queue // it must have triggered events @@ -1347,7 +1353,6 @@ bool microtcp_mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev) // we put the entry into the idle list move_mux_entry_to_idle_list(entry); - UNLOCK_WHEN_THREADED(mux->mtcp); return true; } @@ -1355,13 +1360,16 @@ bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev) { #ifdef MICROTCP_BACKGROUND_THREAD LOCK_WHEN_THREADED(mux->mtcp); - while (!microtcp_mux_poll(mux, 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(); + MICROTCP_DEBUG_LOG("Multiplexer woke up for an event"); + } UNLOCK_WHEN_THREADED(mux->mtcp); return true; #else - return microtcp_mux_poll(mux, ev); + return mux_poll(mux, ev); #endif } @@ -1372,45 +1380,58 @@ signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int event assert(events); // If no events need to be signaled then // this function has no reason to be called. + + MICROTCP_DEBUG_LOG("Socket about to signal to multiplexers"); mux_entry_t *entry = socket->mux_list; while (entry) { microtcp_mux_t *mux = entry->mux; - bool first_event_of_socket = (entry->triggered_events == 0); - entry->triggered_events |= events & entry->events_of_interest; + // Mask the bitmask of triggered events [events] with + // the bitmask of events that this multiplexer is + // interested in. + int newly_triggered_events = events & entry->events_of_interest; - if (first_event_of_socket) { + // If there are no previously triggered events by this + // socket and the socket just generated some events the + // mux is interested in, then we need to move the socket-mux + // structure from the idle list to the ready queue of the mux. + bool first_event_of_socket_in_mux = (entry->triggered_events == 0) && newly_triggered_events; + entry->triggered_events |= newly_triggered_events; + if (first_event_of_socket_in_mux) { + + // Is this the first socket structure of the muxes + // ready queue? If it is, we'll need to wake it up bool queue_was_empty = (mux->ready_queue_head == NULL); - // No entries were already triggered so - // it's necessary to move the entry from - // the mux's idle list to ready queue - - // Unlink it from the idle queue + // Unlink it from the idle list *entry->mux_prev = entry->mux_next; if (entry->mux_next) entry->mux_next->mux_prev = entry->mux_prev; // Add it to the queue - entry->mux_prev = &mux->ready_queue_head; - entry->mux_next = mux->ready_queue_head; - if (mux->ready_queue_head) - mux->ready_queue_head->mux_prev = &entry->mux_next; - else - mux->ready_queue_tail = entry; - mux->ready_queue_head = entry; + if (mux->ready_queue_tail) + entry->mux_prev = &mux->ready_queue_tail->mux_next; + else { + entry->mux_prev = &mux->ready_queue_head; + mux->ready_queue_head = entry; + } + entry->mux_next = NULL; + mux->ready_queue_tail = entry; #ifdef MICROTCP_BACKGROUND_THREAD + MICROTCP_DEBUG_LOG("Signaling event to multiplexer"); if (queue_was_empty) cnd_signal(&mux->queue_not_empty); + MICROTCP_DEBUG_LOG("Signaled event to multiplexer"); #else (void) queue_was_empty; #endif } entry = entry->sock_next; } + MICROTCP_DEBUG_LOG("Socket signaled to multiplexers"); } #endif \ No newline at end of file diff --git a/include/microtcp.h b/src/microtcp.h similarity index 94% rename from include/microtcp.h rename to src/microtcp.h index 9846ae8..e52daff 100644 --- a/include/microtcp.h +++ b/src/microtcp.h @@ -1,80 +1,79 @@ - -#include -#include -#include -#include - -typedef struct microtcp_t microtcp_t; -typedef struct microtcp_socket_t microtcp_socket_t; - -#define MICROTCP_MAX_BUFFERS 8 -#define MICROTCP_MAX_SOCKETS 32 -#define MICROTCP_MAX_MUX_ENTRIES 32 - -typedef enum { - - MICROTCP_ERRCODE_NONE = 0, - - // Returned by microtcp_open and microtcp_accept - MICROTCP_ERRCODE_SOCKETLIMIT, - - // Returned by microtcp_open - MICROTCP_ERRCODE_TCPERROR, - MICROTCP_ERRCODE_BADCONDVAR, - - // Returned by microtcp_accept - MICROTCP_ERRCODE_NOTLISTENER, - MICROTCP_ERRCODE_CANTBLOCK, - - // Returned by microtcp_recv and microtcp_send - MICROTCP_ERRCODE_NOTCONNECTION, - - // Returned by microtcp_accept, microtcp_recv and microtcp_send - MICROTCP_ERRCODE_WOULDBLOCK, - -} microtcp_errcode_t; - -typedef struct { - void *data; - void (*free)(void *data); - int (*send)(void *data, const void *src, size_t len); - int (*recv)(void *data, void *dst, size_t len); -} microtcp_callbacks_t; - -#ifdef MICROTCP_USING_TAP -bool microtcp_callbacks_create_for_tap(const char *ip, const char *mac, microtcp_callbacks_t *callbacks); -microtcp_t *microtcp_create(const char *tap_ip, const char *stack_ip, const char *tap_mac, const char *stack_mac); -#endif - -microtcp_t *microtcp_create_using_callbacks(const char *ip, const char *mac, microtcp_callbacks_t callbacks); -void microtcp_destroy(microtcp_t *mtcp); -const char *microtcp_strerror(microtcp_errcode_t errcode); -microtcp_socket_t *microtcp_open(microtcp_t *mtcp, uint16_t port, microtcp_errcode_t *errcode); -microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket, bool no_block, microtcp_errcode_t *errcode); -void microtcp_close(microtcp_socket_t *socket); -size_t microtcp_send(microtcp_socket_t *socket, const void *src, size_t len, bool no_block, microtcp_errcode_t *errcode); -size_t microtcp_recv(microtcp_socket_t *socket, void *dst, size_t len, bool no_block, microtcp_errcode_t *errcode); -void microtcp_step(microtcp_t *mtcp); -void microtcp_process_packet(microtcp_t *mtcp, const void *packet, size_t len); - -#ifdef MICROTCP_USING_MUX -typedef enum { - MICROTCP_MUX_ACCEPT = 1, - MICROTCP_MUX_RECV = 2, - MICROTCP_MUX_SEND = 4, -} microtcp_muxeventid_t; - -typedef struct { - void *userp; - int events; - microtcp_socket_t *socket; -} microtcp_muxevent_t; - -typedef struct microtcp_mux_t microtcp_mux_t; -microtcp_mux_t *microtcp_mux_create(microtcp_t *mtcp); -void microtcp_mux_destroy(microtcp_mux_t *mux); -bool microtcp_mux_register(microtcp_mux_t *mux, microtcp_socket_t *sock, int events, void *userp); -bool microtcp_mux_unregister(microtcp_mux_t *mux, microtcp_socket_t *sock, int events); -bool microtcp_mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev); -bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev); + +#include +#include +#include +#include + +typedef struct microtcp_t microtcp_t; +typedef struct microtcp_socket_t microtcp_socket_t; + +#define MICROTCP_MAX_BUFFERS 8 +#define MICROTCP_MAX_SOCKETS 32 +#define MICROTCP_MAX_MUX_ENTRIES 32 + +typedef enum { + + MICROTCP_ERRCODE_NONE = 0, + + // Returned by microtcp_open and microtcp_accept + MICROTCP_ERRCODE_SOCKETLIMIT, + + // Returned by microtcp_open + MICROTCP_ERRCODE_TCPERROR, + MICROTCP_ERRCODE_BADCONDVAR, + + // Returned by microtcp_accept + MICROTCP_ERRCODE_NOTLISTENER, + MICROTCP_ERRCODE_CANTBLOCK, + + // Returned by microtcp_recv and microtcp_send + MICROTCP_ERRCODE_NOTCONNECTION, + + // Returned by microtcp_accept, microtcp_recv and microtcp_send + MICROTCP_ERRCODE_WOULDBLOCK, + +} microtcp_errcode_t; + +typedef struct { + void *data; + void (*free)(void *data); + int (*send)(void *data, const void *src, size_t len); + int (*recv)(void *data, void *dst, size_t len); +} microtcp_callbacks_t; + +#ifdef MICROTCP_USING_TAP +bool microtcp_callbacks_create_for_tap(const char *ip, const char *mac, microtcp_callbacks_t *callbacks); +microtcp_t *microtcp_create(const char *tap_ip, const char *stack_ip, const char *tap_mac, const char *stack_mac); +#endif + +microtcp_t *microtcp_create_using_callbacks(const char *ip, const char *mac, microtcp_callbacks_t callbacks); +void microtcp_destroy(microtcp_t *mtcp); +const char *microtcp_strerror(microtcp_errcode_t errcode); +microtcp_socket_t *microtcp_open(microtcp_t *mtcp, uint16_t port, microtcp_errcode_t *errcode); +microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket, bool no_block, microtcp_errcode_t *errcode); +void microtcp_close(microtcp_socket_t *socket); +size_t microtcp_send(microtcp_socket_t *socket, const void *src, size_t len, bool no_block, microtcp_errcode_t *errcode); +size_t microtcp_recv(microtcp_socket_t *socket, void *dst, size_t len, bool no_block, microtcp_errcode_t *errcode); +void microtcp_step(microtcp_t *mtcp); +void microtcp_process_packet(microtcp_t *mtcp, const void *packet, size_t len); + +#ifdef MICROTCP_USING_MUX +typedef enum { + MICROTCP_MUX_ACCEPT = 1, + MICROTCP_MUX_RECV = 2, + MICROTCP_MUX_SEND = 4, +} microtcp_muxeventid_t; + +typedef struct { + void *userp; + int events; + microtcp_socket_t *socket; +} microtcp_muxevent_t; + +typedef struct microtcp_mux_t microtcp_mux_t; +microtcp_mux_t *microtcp_mux_create(microtcp_t *mtcp); +void microtcp_mux_destroy(microtcp_mux_t *mux); +bool microtcp_mux_register(microtcp_mux_t *mux, microtcp_socket_t *sock, int events, void *userp); +bool microtcp_mux_unregister(microtcp_mux_t *mux, microtcp_socket_t *sock, int events); +bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev); #endif \ No newline at end of file diff --git a/src/tcp.c b/src/tcp.c index d31107a..2f673a0 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -311,7 +311,7 @@ move_from_non_established_list_to_non_accepted_queue(tcp_connection_t *connectio void tcp_process_segment(tcp_state_t *state, ip_address_t sender, tcp_segment_t *segment, size_t len) { - TCP_DEBUG_LOG("Received TCP segment"); +// TCP_DEBUG_LOG("Received TCP segment"); assert(len >= sizeof(tcp_segment_t)); size_t data_offset = SEGMENT_OFFSET(segment) * sizeof(uint32_t); // Length (in bytes) of the TCP header, @@ -320,6 +320,8 @@ void tcp_process_segment(tcp_state_t *state, ip_address_t sender, size_t options_len = data_offset - sizeof(tcp_segment_t); // The number of bytes of the options is // the size of the whole header minus the // size of the header without options. + (void) options_len; + size_t payload_size = len - data_offset; void *payload_addr = (uint8_t*) segment + data_offset; // The segment->payload doesn't refer to the // first byte of the payload but to the first