From ad65c260355cddd5f08432bb853cbda43abd1b2d Mon Sep 17 00:00:00 2001 From: cozis Date: Sat, 20 May 2023 02:14:47 +0200 Subject: [PATCH] resolved some bug in the MUX --- examples/microhttp/xhttp.c | 52 ++++++++++++++++++++++++++++++++------ makefile | 2 +- src/microtcp.c | 16 ++++++------ src/tcp.c | 7 ++++- src/tcp.h | 2 +- 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/examples/microhttp/xhttp.c b/examples/microhttp/xhttp.c index 1d87623..3f53f57 100644 --- a/examples/microhttp/xhttp.c +++ b/examples/microhttp/xhttp.c @@ -509,19 +509,19 @@ static void req_deinit(xh_request *req) req->headers.count = 0; } -static void accept_connection(context_t *ctx) +static conn_t *accept_connection(context_t *ctx) { microtcp_errcode_t errcode; microtcp_socket_t *accepted_sock = microtcp_accept(ctx->sock, true, &errcode); if(accepted_sock == NULL) - return; // Failed to accept. + return NULL; // Failed to accept. if(ctx->freelist == NULL) { // Connection limit reached. microtcp_close(accepted_sock); - return; + return NULL; } conn_t *conn = ctx->freelist; @@ -534,17 +534,18 @@ static void accept_connection(context_t *ctx) conn->sock = accepted_sock; req_init(&conn->request); - if(microtcp_mux_register(ctx->mux, accepted_sock, MICROTCP_MUX_RECV|MICROTCP_MUX_SEND, conn)) + if(!microtcp_mux_register(ctx->mux, accepted_sock, MICROTCP_MUX_RECV|MICROTCP_MUX_SEND, conn)) { microtcp_close(accepted_sock); conn->sock = NULL; conn->next = ctx->freelist; ctx->freelist = conn; - return; + return NULL; } ctx->connum += 1; + return conn; } static void close_connection(context_t *ctx, conn_t *conn) @@ -960,6 +961,9 @@ static bool upload(conn_t *conn) break; // ERROR! +#ifdef DEBUG + fprintf(stderr, "XHTTP :: microtcp_send failed (%s)\n", microtcp_strerror(errcode)); +#endif return 0; } @@ -1251,7 +1255,7 @@ static void when_data_is_ready_to_be_read(context_t *ctx, conn_t *conn) microtcp_errcode_t errcode; size_t n = microtcp_recv(conn->sock, b->data + b->used, b->size - b->used, true, &errcode); - + if(n == 0) { // Peer disconnected or an error occurred @@ -1260,6 +1264,9 @@ static void when_data_is_ready_to_be_read(context_t *ctx, conn_t *conn) break; // Done downloading. if (errcode != MICROTCP_ERRCODE_NONE) { +#ifdef DEBUG + fprintf(stderr, "XHTTP :: %s\n", microtcp_strerror(errcode)); +#endif // An error occurred. close_connection(ctx, conn); return; @@ -1466,11 +1473,40 @@ const char *xhttp(unsigned short port, xh_callback callback, if (!microtcp_mux_wait(context.mux, &ev)) continue; +#ifdef DEBUG + const char *event_bitset_string; + switch (ev.events) { + case 0: event_bitset_string = ""; break; + case MICROTCP_MUX_RECV: event_bitset_string = "RECV"; break; + case MICROTCP_MUX_SEND: event_bitset_string = "SEND"; break; + case MICROTCP_MUX_ACCEPT: event_bitset_string = "ACCEPT"; break; + case MICROTCP_MUX_RECV | MICROTCP_MUX_SEND: event_bitset_string = "RECV|SEND"; break; + case MICROTCP_MUX_RECV | MICROTCP_MUX_ACCEPT: event_bitset_string = "RECV|ACCEPT"; break; + case MICROTCP_MUX_SEND | MICROTCP_MUX_ACCEPT: event_bitset_string = "SEND|ACCEPT"; break; + case MICROTCP_MUX_RECV | MICROTCP_MUX_SEND | MICROTCP_MUX_ACCEPT: event_bitset_string = "RECV|SEND|ACCEPT"; break; + default: event_bitset_string = "???"; + } + fprintf(stderr, "XHTTP :: Event %s\n", event_bitset_string); +#endif + if(ev.userp == NULL) { +#ifdef DEBUG + fprintf(stderr, "XHTTP :: New connection\n"); +#endif // New connection. - accept_connection(&context); - continue; + conn_t *newly_accepted = accept_connection(&context); + if (!newly_accepted) + continue; // For some reason, although a MICROTCP_MUX_ACCEPT + // was received by the MUX, accepting failed. + // Wait for the next event. + + // A connection was accepted. Since it may already + // contain data to be read or space to write we continue + // by building a fake event ourselves + ev.userp = newly_accepted; + ev.events = MICROTCP_MUX_RECV | MICROTCP_MUX_SEND; + ev.socket = newly_accepted->sock; } conn_t *conn = ev.userp; diff --git a/makefile b/makefile index 75cf810..12782ac 100644 --- a/makefile +++ b/makefile @@ -48,7 +48,7 @@ MEMDBG=valgrind LIBDIR = 3p/lib INCDIR = 3p/include -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 +CFLAGS = $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra -DDEBUG=1 -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) diff --git a/src/microtcp.c b/src/microtcp.c index 09fb84a..d7d915e 100644 --- a/src/microtcp.c +++ b/src/microtcp.c @@ -810,6 +810,7 @@ static void ready_to_accept(void *data) #endif #ifdef MICROTCP_USING_MUX + MICROTCP_DEBUG_LOG("Signaling ACCEPT to muxes"); signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_ACCEPT); #endif } @@ -903,6 +904,7 @@ static void ready_to_recv(void *data) #endif #ifdef MICROTCP_USING_MUX + MICROTCP_DEBUG_LOG("Signaling RECV to muxes"); signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_RECV); #endif } @@ -917,6 +919,7 @@ static void ready_to_send(void *data) #endif #ifdef MICROTCP_USING_MUX + MICROTCP_DEBUG_LOG("Signaling SEND to muxes"); signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_SEND); #endif } @@ -978,14 +981,12 @@ microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket, if (cnd_init(&socket2->something_to_recv) != thrd_success) { errcode2 = MICROTCP_ERRCODE_BADCONDVAR; push_unlinked_socket_into_free_list(mtcp, socket2); - tcp_connection_destroy(connection); goto unlock_and_exit; } if (cnd_init(&socket2->something_to_send) != thrd_success) { errcode2 = MICROTCP_ERRCODE_BADCONDVAR; cnd_destroy(&socket2->something_to_recv); push_unlinked_socket_into_free_list(mtcp, socket2); - tcp_connection_destroy(connection); goto unlock_and_exit; } #endif @@ -1029,15 +1030,13 @@ size_t microtcp_recv(microtcp_socket_t *socket, } num = tcp_connection_recv(socket->connection, dst, len); } -#else +#endif if (num == 0) { if (no_block) errcode2 = MICROTCP_ERRCODE_WOULDBLOCK; else errcode2 = MICROTCP_ERRCODE_CANTBLOCK; - goto unlock_and_exit; } -#endif } unlock_and_exit: UNLOCK_WHEN_THREADED(mtcp); @@ -1075,15 +1074,13 @@ size_t microtcp_send(microtcp_socket_t *socket, } num = tcp_connection_send(socket->connection, src, len); } -#else +#endif if (num == 0) { if (no_block) errcode2 = MICROTCP_ERRCODE_WOULDBLOCK; else errcode2 = MICROTCP_ERRCODE_CANTBLOCK; - goto unlock_and_exit; } -#endif } unlock_and_exit: UNLOCK_WHEN_THREADED(mtcp); @@ -1393,6 +1390,9 @@ signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int event // interested in. int newly_triggered_events = events & entry->events_of_interest; + if (!newly_triggered_events) + MICROTCP_DEBUG_LOG("MUX not interested in these events"); + // 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 diff --git a/src/tcp.c b/src/tcp.c index 2f673a0..18efc94 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -238,6 +238,8 @@ static void handle_received_data(tcp_connection_t *connection, emit_segment(connection, true, false, SIZE_MAX); + TCP_DEBUG_LOG("Received %d bytes", considered); + // Data is ready to be received by the parent application if (connection->callback_ready_to_recv) connection->callback_ready_to_recv(connection->callback_data); @@ -340,6 +342,9 @@ void tcp_process_segment(tcp_state_t *state, ip_address_t sender, tcp_connection_t *connection = find_connection_associated_to_listener(listener, sender, reordered_src_port); if (!connection) { + + TCP_DEBUG_LOG("Connection request from port %d", reordered_src_port); + // Something sent to an open listener. // We expect it to be a request to connect, @@ -606,7 +611,7 @@ tcp_connection_t *tcp_listener_accept(tcp_listener_t *listener, void *callback_d connection->callback_data = callback_data; connection->callback_ready_to_recv = callback_ready_to_recv; connection->callback_ready_to_send = callback_ready_to_send; - + return connection; } diff --git a/src/tcp.h b/src/tcp.h index 86dd649..25fd645 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -107,7 +107,7 @@ struct tcp_connection_t { // byte sent and acknowledged by the peer. char out_buffer[TCP_OUTPUT_BUFFER_SIZE]; - char in_buffer[TCP_INPUT_BUFFER_SIZE]; + char in_buffer[TCP_INPUT_BUFFER_SIZE]; }; typedef struct {