moved include/microtcp.h to src/microtcp.h and fixed some mux bugs
This commit is contained in:
@@ -48,7 +48,7 @@ MEMDBG=valgrind
|
|||||||
LIBDIR = 3p/lib
|
LIBDIR = 3p/lib
|
||||||
INCDIR = 3p/include
|
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)
|
LFLAGS = -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR)
|
||||||
|
|
||||||
ifeq ($(MEMDBG),drmemory)
|
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)
|
mkdir -p $(@D)
|
||||||
gcc build/microtcp.c examples/echo_tcp.c -o $@ $(CFLAGS) $(LFLAGS)
|
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)
|
mkdir -p $(@D)
|
||||||
[ ! -e $@ ] || rm $@
|
[ ! -e $@ ] || rm $@
|
||||||
echo "#define MICROTCP_AMALGAMATION" >> $@
|
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)
|
build/microtcp.c: 3p/include/tinycthread.h 3p/src/tinycthread.c $(wildcard src/*.c src/*.h)
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
|
|||||||
@@ -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);
|
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;
|
return ARP_PROCESS_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
ARP_DEBUG_LOG("ARP from %d.%d.%d.%d to %d.%d.%d.%d",
|
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)[0],
|
||||||
((uint8_t*) &packet2->sender_protocol_address)[1],
|
((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)[1],
|
||||||
((uint8_t*) &packet2->target_protocol_address)[2],
|
((uint8_t*) &packet2->target_protocol_address)[2],
|
||||||
((uint8_t*) &packet2->target_protocol_address)[3]);
|
((uint8_t*) &packet2->target_protocol_address)[3]);
|
||||||
|
*/
|
||||||
bool merge = arp_translation_table_update(&state->table, packet2->sender_hardware_address,
|
bool merge = arp_translation_table_update(&state->table, packet2->sender_hardware_address,
|
||||||
packet2->sender_protocol_address, state->cache_timeout);
|
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);
|
state->send(state->send_data, packet2->sender_hardware_address);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ARP_DEBUG_LOG("Request not for me");
|
//ARP_DEBUG_LOG("Request not for me");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ARP_PROCESS_RESULT_OK;
|
return ARP_PROCESS_RESULT_OK;
|
||||||
|
|||||||
@@ -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");
|
IP_DEBUG_LOG("Dropping IP packet with invalid checksum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
IP_DEBUG_LOG("Received packet for %d.%d.%d.%d (I'm %d.%d.%d.%d)",
|
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)[0],
|
||||||
((uint8_t*) &packet2->dst_ip)[1],
|
((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)[1],
|
||||||
((uint8_t*) &ip_state->ip)[2],
|
((uint8_t*) &ip_state->ip)[2],
|
||||||
((uint8_t*) &ip_state->ip)[3]);
|
((uint8_t*) &ip_state->ip)[3]);
|
||||||
|
*/
|
||||||
if (packet2->dst_ip != ip_state->ip) {
|
if (packet2->dst_ip != ip_state->ip) {
|
||||||
IP_DEBUG_LOG("Packet not for me");
|
// IP_DEBUG_LOG("Packet not for me");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+51
-30
@@ -1132,6 +1132,8 @@ microtcp_mux_t *microtcp_mux_create(microtcp_t *mtcp)
|
|||||||
return mux;
|
return mux;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mux_poll(microtcp_mux_t *mux, microtcp_muxevent_t *ev);
|
||||||
|
|
||||||
void microtcp_mux_destroy(microtcp_mux_t *mux)
|
void microtcp_mux_destroy(microtcp_mux_t *mux)
|
||||||
{
|
{
|
||||||
// Unregister all idle sockets
|
// Unregister all idle sockets
|
||||||
@@ -1144,7 +1146,7 @@ void microtcp_mux_destroy(microtcp_mux_t *mux)
|
|||||||
// Consume all previously reported events
|
// Consume all previously reported events
|
||||||
// to make sure that when unregistering
|
// to make sure that when unregistering
|
||||||
// the entries are actually removed
|
// the entries are actually removed
|
||||||
while (microtcp_mux_poll(mux, NULL));
|
while (mux_poll(mux, NULL));
|
||||||
|
|
||||||
// Unreagister all sockets that have events
|
// Unreagister all sockets that have events
|
||||||
while (mux->ready_queue_head) {
|
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;
|
microtcp_mux_t *mux = entry->mux;
|
||||||
|
|
||||||
// If the entry is in a list, unlink it
|
// 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)
|
if (entry->mux_prev)
|
||||||
*entry->mux_prev = entry->mux_next;
|
*entry->mux_prev = entry->mux_next;
|
||||||
if (entry->sock_prev)
|
if (entry->sock_prev)
|
||||||
@@ -1197,6 +1201,8 @@ move_mux_entry_to_free_list(mux_entry_t *entry)
|
|||||||
static void
|
static void
|
||||||
move_mux_entry_to_idle_list(mux_entry_t *entry)
|
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
|
// To be moved to the idle list the entry
|
||||||
// must be associated to a socket so it
|
// must be associated to a socket so it
|
||||||
// must be in a socket mux list, therefore
|
// 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
|
// Make sure the entry is unlinked relative
|
||||||
// to the lists in the mux
|
// to the lists in the mux
|
||||||
|
if (mux->ready_queue_tail == entry)
|
||||||
|
mux->ready_queue_tail = entry->mux_next;
|
||||||
if (entry->mux_prev)
|
if (entry->mux_prev)
|
||||||
*entry->mux_prev = entry->mux_next;
|
*entry->mux_prev = entry->mux_next;
|
||||||
|
|
||||||
// Now actually insert it into the idle list
|
// Now actually insert it into the idle list
|
||||||
microtcp_mux_t *mux = entry->mux;
|
|
||||||
entry->mux_prev = &mux->idle_list;
|
entry->mux_prev = &mux->idle_list;
|
||||||
entry->mux_next = mux->idle_list;
|
entry->mux_next = mux->idle_list;
|
||||||
if (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
|
// Push it into the idle list of the mux
|
||||||
entry->mux_prev = &mux->idle_list;
|
entry->mux_prev = &mux->idle_list;
|
||||||
entry->mux_next = mux->idle_list;
|
entry->mux_next = mux->idle_list;
|
||||||
if (mux->idle_list)
|
if (mux->idle_list)
|
||||||
mux->idle_list->mux_prev = &entry->mux_next;
|
mux->idle_list->mux_prev = &entry->mux_next;
|
||||||
|
mux->idle_list = entry;
|
||||||
|
|
||||||
// Push it into the socket mux list
|
// Push it into the socket mux list
|
||||||
entry->sock_prev = &sock->mux_list;
|
entry->sock_prev = &sock->mux_list;
|
||||||
entry->sock_next = sock->mux_list;
|
entry->sock_next = sock->mux_list;
|
||||||
if (sock->mux_list)
|
if (sock->mux_list)
|
||||||
sock->mux_list->sock_prev = &entry->sock_next;
|
sock->mux_list->sock_prev = &entry->sock_next;
|
||||||
|
sock->mux_list = entry;
|
||||||
|
|
||||||
// Initialize the entry
|
// Initialize the entry
|
||||||
entry->sock = sock;
|
entry->sock = sock;
|
||||||
@@ -1312,17 +1321,14 @@ bool microtcp_mux_register(microtcp_mux_t *mux, microtcp_socket_t *sock, int eve
|
|||||||
return true;
|
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)
|
// Get the tail of the queue (without popping it)
|
||||||
mux_entry_t *entry = mux->ready_queue_tail;
|
mux_entry_t *entry = mux->ready_queue_head;
|
||||||
|
|
||||||
if (!entry) {
|
|
||||||
UNLOCK_WHEN_THREADED(mux->mtcp);
|
|
||||||
return false; // No events occurred
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this socket was in the ready queue
|
// If this socket was in the ready queue
|
||||||
// it must have triggered events
|
// 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
|
// we put the entry into the idle list
|
||||||
move_mux_entry_to_idle_list(entry);
|
move_mux_entry_to_idle_list(entry);
|
||||||
|
|
||||||
UNLOCK_WHEN_THREADED(mux->mtcp);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1355,13 +1360,16 @@ bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev)
|
|||||||
{
|
{
|
||||||
#ifdef MICROTCP_BACKGROUND_THREAD
|
#ifdef MICROTCP_BACKGROUND_THREAD
|
||||||
LOCK_WHEN_THREADED(mux->mtcp);
|
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)
|
if (cnd_wait(&mux->queue_not_empty, &mux->mtcp->lock) != thrd_success)
|
||||||
abort();
|
abort();
|
||||||
|
MICROTCP_DEBUG_LOG("Multiplexer woke up for an event");
|
||||||
|
}
|
||||||
UNLOCK_WHEN_THREADED(mux->mtcp);
|
UNLOCK_WHEN_THREADED(mux->mtcp);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return microtcp_mux_poll(mux, ev);
|
return mux_poll(mux, ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1373,44 +1381,57 @@ signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int event
|
|||||||
assert(events); // If no events need to be signaled then
|
assert(events); // If no events need to be signaled then
|
||||||
// this function has no reason to be called.
|
// this function has no reason to be called.
|
||||||
|
|
||||||
|
MICROTCP_DEBUG_LOG("Socket about to signal to multiplexers");
|
||||||
|
|
||||||
mux_entry_t *entry = socket->mux_list;
|
mux_entry_t *entry = socket->mux_list;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
|
|
||||||
microtcp_mux_t *mux = entry->mux;
|
microtcp_mux_t *mux = entry->mux;
|
||||||
|
|
||||||
bool first_event_of_socket = (entry->triggered_events == 0);
|
// Mask the bitmask of triggered events [events] with
|
||||||
entry->triggered_events |= events & entry->events_of_interest;
|
// 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);
|
bool queue_was_empty = (mux->ready_queue_head == NULL);
|
||||||
|
|
||||||
// No entries were already triggered so
|
// Unlink it from the idle list
|
||||||
// it's necessary to move the entry from
|
|
||||||
// the mux's idle list to ready queue
|
|
||||||
|
|
||||||
// Unlink it from the idle queue
|
|
||||||
*entry->mux_prev = entry->mux_next;
|
*entry->mux_prev = entry->mux_next;
|
||||||
if (entry->mux_next)
|
if (entry->mux_next)
|
||||||
entry->mux_next->mux_prev = entry->mux_prev;
|
entry->mux_next->mux_prev = entry->mux_prev;
|
||||||
|
|
||||||
// Add it to the queue
|
// Add it to the queue
|
||||||
entry->mux_prev = &mux->ready_queue_head;
|
if (mux->ready_queue_tail)
|
||||||
entry->mux_next = mux->ready_queue_head;
|
entry->mux_prev = &mux->ready_queue_tail->mux_next;
|
||||||
if (mux->ready_queue_head)
|
else {
|
||||||
mux->ready_queue_head->mux_prev = &entry->mux_next;
|
entry->mux_prev = &mux->ready_queue_head;
|
||||||
else
|
mux->ready_queue_head = entry;
|
||||||
mux->ready_queue_tail = entry;
|
}
|
||||||
mux->ready_queue_head = entry;
|
entry->mux_next = NULL;
|
||||||
|
mux->ready_queue_tail = entry;
|
||||||
|
|
||||||
#ifdef MICROTCP_BACKGROUND_THREAD
|
#ifdef MICROTCP_BACKGROUND_THREAD
|
||||||
|
MICROTCP_DEBUG_LOG("Signaling event to multiplexer");
|
||||||
if (queue_was_empty)
|
if (queue_was_empty)
|
||||||
cnd_signal(&mux->queue_not_empty);
|
cnd_signal(&mux->queue_not_empty);
|
||||||
|
MICROTCP_DEBUG_LOG("Signaled event to multiplexer");
|
||||||
#else
|
#else
|
||||||
(void) queue_was_empty;
|
(void) queue_was_empty;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
entry = entry->sock_next;
|
entry = entry->sock_next;
|
||||||
}
|
}
|
||||||
|
MICROTCP_DEBUG_LOG("Socket signaled to multiplexers");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -75,6 +75,5 @@ microtcp_mux_t *microtcp_mux_create(microtcp_t *mtcp);
|
|||||||
void microtcp_mux_destroy(microtcp_mux_t *mux);
|
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_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_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);
|
bool microtcp_mux_wait(microtcp_mux_t *mux, microtcp_muxevent_t *ev);
|
||||||
#endif
|
#endif
|
||||||
@@ -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,
|
void tcp_process_segment(tcp_state_t *state, ip_address_t sender,
|
||||||
tcp_segment_t *segment, size_t len)
|
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));
|
assert(len >= sizeof(tcp_segment_t));
|
||||||
size_t data_offset = SEGMENT_OFFSET(segment) * sizeof(uint32_t); // Length (in bytes) of the TCP header,
|
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
|
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
|
// the size of the whole header minus the
|
||||||
// size of the header without options.
|
// size of the header without options.
|
||||||
|
(void) options_len;
|
||||||
|
|
||||||
size_t payload_size = len - data_offset;
|
size_t payload_size = len - data_offset;
|
||||||
void *payload_addr = (uint8_t*) segment + data_offset; // The segment->payload doesn't refer to the
|
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
|
// first byte of the payload but to the first
|
||||||
|
|||||||
Reference in New Issue
Block a user