general cleanups

This commit is contained in:
cozis
2023-10-29 22:38:14 +01:00
parent 5f3f7dc66d
commit 733597b6aa
16 changed files with 1525 additions and 917 deletions
+3
View File
@@ -4,3 +4,6 @@
[submodule "3p/tinycthread"] [submodule "3p/tinycthread"]
path = 3p/tinycthread path = 3p/tinycthread
url = https://github.com/tinycthread/tinycthread.git url = https://github.com/tinycthread/tinycthread.git
[submodule "3p/packetdrill"]
path = 3p/packetdrill
url = https://github.com/google/packetdrill.git
+1
Submodule 3p/packetdrill added at 8595c94c9c
+5 -46
View File
@@ -3,58 +3,17 @@
int main(void) int main(void)
{ {
microtcp_errcode_t errcode;
microtcp_t *mtcp = microtcp_create("10.0.0.5", "10.0.0.4", NULL, NULL); microtcp_t *mtcp = microtcp_create("10.0.0.5", "10.0.0.4", NULL, NULL);
if (mtcp == NULL) {
fprintf(stderr, "Error: Failed to instanciate microtcp stack\n");
return -1;
}
uint16_t port = 8081; uint16_t port = 8081;
microtcp_socket_t *server = microtcp_open(mtcp, port, &errcode); microtcp_socket_t *server = microtcp_open(mtcp, port, NULL);
if (errcode) {
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode));
microtcp_destroy(mtcp);
return -1;
}
assert(server);
fprintf(stderr, "Listening on port %d\n", port);
while (1) { while (1) {
fprintf(stderr, "About to accept\n"); microtcp_socket_t *client = microtcp_accept(server, false, NULL);
microtcp_socket_t *client = microtcp_accept(server, false, &errcode);
if (errcode) {
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode));
break;
}
fprintf(stderr, "Accepted a connection\n");
char buffer[1024]; char buffer[1024];
size_t num = microtcp_recv(client, buffer, sizeof(buffer), false, &errcode); size_t num = microtcp_recv(client, buffer, sizeof(buffer), false, NULL);
if (errcode) { microtcp_send(client, "echo: ", 6, false, NULL);
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode)); microtcp_send(client, buffer, num, false, NULL);
goto handled;
}
fprintf(stderr, "(%d bytes received)\n", (int) num);
size_t sent1 = microtcp_send(client, "echo: ", 6, false, &errcode);
if (errcode) {
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode));
goto handled;
}
fprintf(stderr, "(%d bytes sent 1)\n", (int) sent1);
size_t sent2 = microtcp_send(client, buffer, num, false, &errcode);
if (errcode) {
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode));
goto handled;
}
fprintf(stderr, "(%d bytes sent 2)\n", (int) sent2);
handled:
microtcp_close(client); microtcp_close(client);
} }
+25
View File
@@ -0,0 +1,25 @@
int main(void)
{
microtcp_t *mtcp = microtcp_create(..);
uint16_t port = 8080;
microtcp_socket_t *socket = microtcp_open(mtcp, port, 0);
microtcp_mux_t *mux = microtcp_mux_create(mtcp);
for (int i = 0; i < 3; i++) {
microtcp_socket_t *accepted = microtcp_accept(socket, 0, 0);
microtcp_mux_register(mux, accepted, MICROTCP_MUX_RECV | MICROTCP_MUX_SEND);
}
for (microtcp_muxevent_t event; microtcp_mux_wait(mux, &event)) {
if (event.events & MICROTCP_MUX_RECV) {
// Il socket "event.socket" ha dei dati da leggere
} else {
// Il socket "event.socket" ha spazio per inviare
}
}
microtcp_destroy(mtcp);
}
+4 -7
View File
@@ -48,13 +48,13 @@ MEMDBG=valgrind
LIBDIR = 3p/lib LIBDIR = 3p/lib
INCDIR = 3p/include INCDIR = 3p/include
CFLAGS = $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra CFLAGS = $(CUSTOM_CFLAGS) $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra
LFLAGS = -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR) LFLAGS = $(CUSTOM_LFLAGS) -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR)
ifeq ($(MEMDBG),drmemory) ifeq ($(MEMDBG),drmemory)
CFLAGS += -gdwarf-2 CFLAGS += -gdwarf-2
else else
CFLAGS += -g CFLAGS += -g3
endif endif
.PHONY: all clean .PHONY: all clean
@@ -154,7 +154,4 @@ report: build/test
gcov -b build/test-tcp_timer.c gcov -b build/test-tcp_timer.c
clean: clean:
rm build/*.gcda build/*.gcno rm -fr build 3p/libtuntap/build 3p/lib/* 3p/include/*
rm -fr build
rm -fr 3p/libtuntap/build
rm -f 3p/lib/* 3p/include/*
+1 -11
View File
@@ -690,17 +690,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",
((uint8_t*) &packet2->sender_protocol_address)[0],
((uint8_t*) &packet2->sender_protocol_address)[1],
((uint8_t*) &packet2->sender_protocol_address)[2],
((uint8_t*) &packet2->sender_protocol_address)[3],
((uint8_t*) &packet2->target_protocol_address)[0],
((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, 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);
+6
View File
@@ -26,4 +26,10 @@ typedef struct {
#define COUNT(X) ((int) (sizeof(X) / sizeof((X)[0]))) #define COUNT(X) ((int) (sizeof(X) / sizeof((X)[0])))
#define SLICE(X) ((slice_t) {.ptr=&(X), .len=sizeof(X)}) #define SLICE(X) ((slice_t) {.ptr=&(X), .len=sizeof(X)})
#define UNPACK_IP(IP) \
((IP) >> 0 & 0xff), \
((IP) >> 8 & 0xff), \
((IP) >> 16 & 0xff), \
((IP) >> 24 & 0xff)
#endif /* MICROTCP_DEFS_H */ #endif /* MICROTCP_DEFS_H */
+3 -1
View File
@@ -89,7 +89,9 @@ void icmp_process_packet(icmp_state_t *state, ip_address_t ip, const void *src,
} }
if (state->output_ptr == NULL || state->output_len < len) { if (state->output_ptr == NULL || state->output_len < len) {
ICMP_DEBUG_LOG("Ignoring ECHO REQUEST because the output buffer is too small for an ECHO REPLY (have %d, need %d)", (int) state->output_len, (int) len); ICMP_DEBUG_LOG("Ignoring ECHO REQUEST because the output buffer "
"is too small for an ECHO REPLY (have %d, need %d)",
(int) state->output_len, (int) len);
return; return;
} }
+1 -1
View File
@@ -22,7 +22,7 @@ typedef struct {
uint32_t src_ip; uint32_t src_ip;
uint32_t dst_ip; uint32_t dst_ip;
char payload[]; char payload[];
} ip_packet_t; } __attribute__((packed)) ip_packet_t;
static_assert(sizeof(ip_packet_t) == 20); static_assert(sizeof(ip_packet_t) == 20);
typedef enum { typedef enum {
+48 -25
View File
@@ -70,7 +70,7 @@ struct buffer_t {
buffer_t *prev; buffer_t *prev;
buffer_t *next; buffer_t *next;
size_t used; size_t used;
char data[1518]; char data[1218];
}; };
typedef enum { typedef enum {
@@ -143,6 +143,7 @@ const char *microtcp_strerror(microtcp_errcode_t errcode)
case MICROTCP_ERRCODE_CANTBLOCK: return "Can't execute a blocking call for this function"; case MICROTCP_ERRCODE_CANTBLOCK: return "Can't execute a blocking call for this function";
case MICROTCP_ERRCODE_WOULDBLOCK: return "Can't executa e non-blocking call for this function"; case MICROTCP_ERRCODE_WOULDBLOCK: return "Can't executa e non-blocking call for this function";
case MICROTCP_ERRCODE_NOTCONNECTION: return "Invalid operation on a non-connection socket"; case MICROTCP_ERRCODE_NOTCONNECTION: return "Invalid operation on a non-connection socket";
case MICROTCP_ERRCODE_PEERCLOSED: return "Peer closed the connection";
} }
return "???"; return "???";
} }
@@ -374,6 +375,7 @@ process_packet(microtcp_t *mtcp, const void *packet, size_t len)
const ethernet_frame_t *frame = packet; const ethernet_frame_t *frame = packet;
switch (net_to_cpu_u16(frame->proto)) { switch (net_to_cpu_u16(frame->proto)) {
case ETHERNET_PROTOCOL_ARP: case ETHERNET_PROTOCOL_ARP:
arp_process_packet(&mtcp->arp_state, frame+1, len - sizeof(ethernet_frame_t)); arp_process_packet(&mtcp->arp_state, frame+1, len - sizeof(ethernet_frame_t));
break; break;
@@ -644,6 +646,7 @@ static microtcp_socket_t*
pop_socket_struct_from_free_list(microtcp_t *mtcp) pop_socket_struct_from_free_list(microtcp_t *mtcp)
{ {
microtcp_socket_t *socket = mtcp->free_socket_list; microtcp_socket_t *socket = mtcp->free_socket_list;
if (socket)
mtcp->free_socket_list = socket->next; mtcp->free_socket_list = socket->next;
return socket; return socket;
} }
@@ -689,18 +692,24 @@ static void
signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int events); signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int events);
#endif #endif
static void ready_to_accept(void *data) static void listener_event_callback(void *data, tcp_listenevent_t event)
{ {
microtcp_socket_t *socket = data; microtcp_socket_t *socket = data;
(void) socket; (void) socket;
#ifdef MICROTCP_BACKGROUND_THREAD #ifdef MICROTCP_BACKGROUND_THREAD
cnd_signal(&socket->something_to_accept); switch (event) {
case TCP_LISTENEVENT_ACCEPT: cnd_signal(&socket->something_to_accept); break;
}
#endif #endif
#ifdef MICROTCP_USING_MUX #ifdef MICROTCP_USING_MUX
MICROTCP_DEBUG_LOG("Signaling ACCEPT to muxes"); int flags = 0;
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_ACCEPT); switch (event) {
case TCP_LISTENEVENT_ACCEPT: flags = MICROTCP_MUX_ACCEPT; MICROTCP_DEBUG_LOG("Signaling ACCEPT to muxes"); break;
}
if (flags)
signal_events_to_muxes_associated_to_socket(socket, flags);
#endif #endif
} }
@@ -717,7 +726,7 @@ microtcp_socket_t *microtcp_open(microtcp_t *mtcp, uint16_t port,
goto unlock_and_exit; // Socket limit reached goto unlock_and_exit; // Socket limit reached
} }
tcp_listener_t *listener = tcp_listener_create(&mtcp->tcp_state, port, false, socket, ready_to_accept); tcp_listener_t *listener = tcp_listener_create(&mtcp->tcp_state, port, false, socket, listener_event_callback);
if (listener == NULL) { if (listener == NULL) {
// FIXME: This error code should be more specific, // FIXME: This error code should be more specific,
// but the TCP module isn't stable yet // but the TCP module isn't stable yet
@@ -786,6 +795,8 @@ void microtcp_close(microtcp_socket_t *socket)
break; break;
case SOCKET_CONNECTION: case SOCKET_CONNECTION:
if (socket->connection) // Only need to close the connection
// if the peer didn't already.
tcp_connection_destroy(socket->connection); tcp_connection_destroy(socket->connection);
break; break;
} }
@@ -796,33 +807,34 @@ void microtcp_close(microtcp_socket_t *socket)
UNLOCK_WHEN_THREADED(mtcp); UNLOCK_WHEN_THREADED(mtcp);
} }
static void ready_to_recv(void *data) static void conn_event_callback(void *data, tcp_connevent_t event)
{ {
microtcp_socket_t *socket = data; microtcp_socket_t *socket = data;
(void) socket; (void) socket;
#ifdef MICROTCP_BACKGROUND_THREAD #ifdef MICROTCP_BACKGROUND_THREAD
cnd_signal(&socket->something_to_recv); switch (event) {
#endif
#ifdef MICROTCP_USING_MUX case TCP_CONNEVENT_RECV: MICROTCP_DEBUG_LOG("Signal RECV"); cnd_signal(&socket->something_to_recv); break;
MICROTCP_DEBUG_LOG("Signaling RECV to muxes"); case TCP_CONNEVENT_SEND: MICROTCP_DEBUG_LOG("Signal SEND"); cnd_signal(&socket->something_to_send); break;
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_RECV);
#endif case TCP_CONNEVENT_RESET:
case TCP_CONNEVENT_CLOSE:
socket->connection = NULL;
break;
} }
static void ready_to_send(void *data)
{
microtcp_socket_t *socket = data;
(void) socket;
#ifdef MICROTCP_BACKGROUND_THREAD
cnd_signal(&socket->something_to_send);
#endif #endif
#ifdef MICROTCP_USING_MUX #ifdef MICROTCP_USING_MUX
MICROTCP_DEBUG_LOG("Signaling SEND to muxes"); // TODO: Maybe signal closing and reset events to muxes?
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_SEND); int flags;
switch (event) {
case TCP_CONNEVENT_RECV: flags = MICROTCP_MUX_RECV; MICROTCP_DEBUG_LOG("Signaling RECV to muxes"); break;
case TCP_CONNEVENT_SEND: flags = MICROTCP_MUX_SEND; MICROTCP_DEBUG_LOG("Signaling SEND to muxes"); break;
default: flags = 0; break;
}
if (flags)
signal_events_to_muxes_associated_to_socket(socket, flags);
#endif #endif
} }
@@ -847,7 +859,7 @@ microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket,
goto unlock_and_exit; // Socket limit reached goto unlock_and_exit; // Socket limit reached
} }
tcp_connection_t *connection = tcp_listener_accept(socket->listener, socket2, ready_to_recv, ready_to_send); tcp_connection_t *connection = tcp_listener_accept(socket->listener, socket2, conn_event_callback);
#ifdef MICROTCP_BACKGROUND_THREAD #ifdef MICROTCP_BACKGROUND_THREAD
while (!connection && !no_block) { while (!connection && !no_block) {
@@ -856,7 +868,7 @@ microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket,
push_unlinked_socket_into_free_list(mtcp, socket2); push_unlinked_socket_into_free_list(mtcp, socket2);
goto unlock_and_exit; goto unlock_and_exit;
} }
connection = tcp_listener_accept(socket->listener, socket2, ready_to_recv, ready_to_send); connection = tcp_listener_accept(socket->listener, socket2, conn_event_callback);
} }
#else #else
if (!connection) { if (!connection) {
@@ -916,6 +928,12 @@ size_t microtcp_recv(microtcp_socket_t *socket,
return 0; return 0;
} }
if (socket->connection == NULL) {
if (errcode)
*errcode = MICROTCP_ERRCODE_PEERCLOSED;
return 0;
}
size_t num; size_t num;
microtcp_t *mtcp = socket->mtcp; microtcp_t *mtcp = socket->mtcp;
microtcp_errcode_t errcode2 = MICROTCP_ERRCODE_NONE; microtcp_errcode_t errcode2 = MICROTCP_ERRCODE_NONE;
@@ -962,6 +980,11 @@ size_t microtcp_send(microtcp_socket_t *socket,
return 0; return 0;
} }
if (socket->connection == NULL) {
if (errcode)
*errcode = MICROTCP_ERRCODE_PEERCLOSED;
return 0;
}
size_t num; size_t num;
microtcp_t *mtcp = socket->mtcp; microtcp_t *mtcp = socket->mtcp;
+3
View File
@@ -32,6 +32,9 @@ typedef enum {
// Returned by microtcp_accept, microtcp_recv and microtcp_send // Returned by microtcp_accept, microtcp_recv and microtcp_send
MICROTCP_ERRCODE_WOULDBLOCK, MICROTCP_ERRCODE_WOULDBLOCK,
// Returned by microtcp_recv, microtcp_send
MICROTCP_ERRCODE_PEERCLOSED,
} microtcp_errcode_t; } microtcp_errcode_t;
typedef struct { typedef struct {
+1283 -727
View File
File diff suppressed because it is too large Load Diff
+73 -26
View File
@@ -12,8 +12,8 @@
#define TCP_MAX_TIMEOUTS 1024 #define TCP_MAX_TIMEOUTS 1024
#define TCP_MAX_LISTENERS 32 #define TCP_MAX_LISTENERS 32
#define TCP_MAX_SOCKETS 1024 #define TCP_MAX_SOCKETS 1024
#define TCP_INPUT_BUFFER_SIZE 1024 #define TCP_IBUFFER_SIZE 1024
#define TCP_OUTPUT_BUFFER_SIZE 1024 #define TCP_OBUFFER_SIZE 1024
typedef struct tcp_state_t tcp_state_t; // Predeclare for cyclic references typedef struct tcp_state_t tcp_state_t; // Predeclare for cyclic references
@@ -36,12 +36,29 @@ typedef struct {
uint16_t checksum; uint16_t checksum;
uint16_t urgent_pointer; uint16_t urgent_pointer;
char payload[]; char payload[];
} tcp_segment_t; } __attribute__((packed)) tcp_segment_t;
static_assert(sizeof(tcp_segment_t) == 20); static_assert(sizeof(tcp_segment_t) == 20);
typedef struct tcp_connection_t tcp_connection_t; typedef struct tcp_connection_t tcp_connection_t;
typedef struct tcp_listener_t tcp_listener_t; typedef struct tcp_listener_t tcp_listener_t;
// After receiving a reset or close event, no
// methods shall be called on the connection
// object, not even to close it.
typedef enum {
TCP_CONNEVENT_CLOSE,
TCP_CONNEVENT_RESET,
TCP_CONNEVENT_RECV,
TCP_CONNEVENT_SEND,
} tcp_connevent_t;
typedef enum {
TCP_LISTENEVENT_ACCEPT,
} tcp_listenevent_t;
typedef void (*tcp_conneventcb_t)(void *data, tcp_connevent_t);
typedef void (*tcp_listeneventcb_t)(void *data, tcp_listenevent_t);
struct tcp_listener_t { struct tcp_listener_t {
tcp_state_t *state; tcp_state_t *state;
tcp_listener_t *prev; tcp_listener_t *prev;
@@ -53,20 +70,35 @@ struct tcp_listener_t {
// its still holding. // its still holding.
// In this state the listener can be reopened by setting the "closed" // In this state the listener can be reopened by setting the "closed"
// flag to true (and keeping the old connections intact). // flag to true (and keeping the old connections intact).
// Port the listener is listening onto
uint16_t port; uint16_t port;
tcp_connection_t *accepted_list;
tcp_connection_t *non_established_list; // Number of connection
tcp_connection_t *non_accepted_queue_head; int count;
tcp_connection_t *non_accepted_queue_tail;
void (*callback_ready_to_accept)(void*); // List of established and accepted connections
void *callback_data; tcp_connection_t *accepted;
// List of connections which aren't in an established
// state yet.
tcp_connection_t *noestab;
// Queue of connections ready to be accepted
// (established but not accepted)
tcp_connection_t *qhead;
tcp_connection_t *qtail;
tcp_listeneventcb_t cb_event;
void *cb_data;
}; };
typedef enum { typedef enum {
TCP_STATE_CLOSED = 0, TCP_STATE_CLOSED = 0,
TCP_STATE_LISTEN,
TCP_STATE_SYN_SENT, TCP_STATE_SYN_SENT,
TCP_STATE_SYN_RCVD, TCP_STATE_SYN_RCVD,
TCP_STATE_ESTAB, TCP_STATE_ESTABLISHED,
TCP_STATE_FIN_WAIT_1, TCP_STATE_FIN_WAIT_1,
TCP_STATE_FIN_WAIT_2, TCP_STATE_FIN_WAIT_2,
TCP_STATE_CLOSE_WAIT, TCP_STATE_CLOSE_WAIT,
@@ -76,27 +108,29 @@ typedef enum {
} tcp_connstate_t; } tcp_connstate_t;
struct tcp_connection_t { struct tcp_connection_t {
tcp_listener_t *listener; // Listener that accepted this connection tcp_listener_t *listener; // Listener that accepted this connection
tcp_connection_t *next; tcp_connection_t *next;
tcp_connection_t *prev; tcp_connection_t *prev;
void *callback_data; tcp_conneventcb_t cb_event;
void (*callback_ready_to_recv)(void*); void *cb_data;
void (*callback_ready_to_send)(void*);
tcp_connstate_t state; tcp_connstate_t state;
ip_address_t peer_ip; // Network byte order ip_address_t peer_ip; // Network byte order
uint16_t peer_port; // CPU byte order uint16_t peer_port; // CPU byte order
uint64_t estimated_rtt; // From RFC 6298, Section 2
uint64_t estimated_dev; // To compute the current RTO, a TCP sender maintains two state
// variables, SRTT (smoothed round-trip time) and RTTVAR (round-trip
bool calculating_rtt; // time variation). In addition, we assume a clock granularity of G
uint32_t rtt_calc_seq; // seconds.
uint64_t rtt_calc_time; float srtt;
float rttvar;
tcp_timer_t *retr_timer; tcp_timer_t *retr_timer;
tcp_timer_t *wait_timer;
// Send Sequence Space // Send Sequence Space
// //
@@ -149,10 +183,24 @@ struct tcp_connection_t {
// It's the sequence number of the last // It's the sequence number of the last
// byte sent and acknowledged by the peer. // byte sent and acknowledged by the peer.
bool in_buffer_syn; uint32_t snd_wl1; // SND.WL1 from RFC 9293
bool in_buffer_fin; // segment sequence number used for last
char in_buffer[TCP_INPUT_BUFFER_SIZE]; // window update.
char out_buffer[TCP_OUTPUT_BUFFER_SIZE];
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;
bool waiting_ack_for_syn;
bool waiting_ack_for_fin;
size_t oused;
char idata[TCP_IBUFFER_SIZE];
char odata[TCP_OBUFFER_SIZE];
}; };
typedef struct { typedef struct {
@@ -180,10 +228,9 @@ void tcp_init(tcp_state_t *tcp_state, ip_address_t ip, tcp_callback
void tcp_free(tcp_state_t *tcp_state); void tcp_free(tcp_state_t *tcp_state);
void tcp_ms_passed(tcp_state_t *state, size_t ms); void tcp_ms_passed(tcp_state_t *state, size_t ms);
void tcp_process_segment(tcp_state_t *state, ip_address_t sender, tcp_segment_t *segment, size_t len); void tcp_process_segment(tcp_state_t *state, ip_address_t sender, tcp_segment_t *segment, size_t len);
tcp_listener_t *tcp_listener_create(tcp_state_t *state, uint16_t port, bool reuse, void *data, void (*callback)(void*)); tcp_listener_t *tcp_listener_create(tcp_state_t *state, uint16_t port, bool reuse, void *cb_data, tcp_listeneventcb_t func);
void tcp_listener_destroy(tcp_listener_t *listener); void tcp_listener_destroy(tcp_listener_t *listener);
tcp_connection_t *tcp_listener_accept(tcp_listener_t *listener, void *callback_data, void (*callback_ready_to_recv)(void*), void (*callback_ready_to_send)(void*)); tcp_connection_t *tcp_listener_accept(tcp_listener_t *listener, void *cb_data, tcp_conneventcb_t func);
void tcp_connection_destroy(tcp_connection_t *connection); void tcp_connection_destroy(tcp_connection_t *connection);
void tcp_connection_finish(tcp_connection_t *connection);
size_t tcp_connection_recv(tcp_connection_t *connection, void *dst, size_t len); size_t tcp_connection_recv(tcp_connection_t *connection, void *dst, size_t len);
size_t tcp_connection_send(tcp_connection_t *connection, const void *src, size_t len); size_t tcp_connection_send(tcp_connection_t *connection, const void *src, size_t len);
+4 -2
View File
@@ -61,6 +61,8 @@ tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t ms,
// first item of the free list. // first item of the free list.
timer->set = set; timer->set = set;
timer->set_time = set->current_time_ms;
timer->trg_time = ms;
timer->deadline = set->current_time_ms + ms; timer->deadline = set->current_time_ms + ms;
timer->data = data; timer->data = data;
timer->callback = callback; timer->callback = callback;
@@ -125,7 +127,7 @@ void tcp_timerset_step(tcp_timerset_t *set, size_t ms)
// Scan through all of the timeouts that just triggered // Scan through all of the timeouts that just triggered
tcp_timer_t *timeout = set->used_list; tcp_timer_t *timeout = set->used_list;
while (timeout) { do {
if (timeout->deadline > set->current_time_ms) if (timeout->deadline > set->current_time_ms)
// This timeout didn't trigger, so the last // This timeout didn't trigger, so the last
@@ -137,7 +139,7 @@ void tcp_timerset_step(tcp_timerset_t *set, size_t ms)
timedout_tail = timeout; timedout_tail = timeout;
timeout = timeout->next; timeout = timeout->next;
} } while (timeout);
// Now put the list of timed out timeouts back // Now put the list of timed out timeouts back
// into the free list // into the free list
+2
View File
@@ -14,6 +14,8 @@ struct tcp_timer_t {
tcp_timerset_t *set; tcp_timerset_t *set;
tcp_timer_t *prev; tcp_timer_t *prev;
tcp_timer_t *next; tcp_timer_t *next;
uint64_t set_time;
uint64_t trg_time;
uint64_t deadline; uint64_t deadline;
void (*callback)(void *data); void (*callback)(void *data);
void *data; void *data;
+9 -17
View File
@@ -17,15 +17,14 @@ static bool is_hex_digit(char c)
static int int_from_hex_digit(char c) static int int_from_hex_digit(char c)
{ {
assert(is_hex_digit(c)); assert(is_hex_digit(c));
if (c >= 'A' || c <= 'F') if (c >= 'A' && c <= 'F')
return c - 'A' + 10; return c - 'A' + 10;
if (c >= 'a' || c <= 'f') if (c >= 'a' && c <= 'f')
return c - 'a' + 10; return c - 'a' + 10;
return c - '0'; return c - '0';
} }
bool parse_mac(const char *src, size_t len, bool parse_mac(const char *src, size_t len, mac_address_t *mac)
mac_address_t *mac)
{ {
if (src == NULL || len != 17 if (src == NULL || len != 17
|| !is_hex_digit(src[0]) || !is_hex_digit(src[0])
@@ -49,20 +48,13 @@ bool parse_mac(const char *src, size_t len,
static const char max_char_map[] = "0123456789ABCDEF"; static const char max_char_map[] = "0123456789ABCDEF";
if (mac) { if (mac)
mac->data[0] = max_char_map[int_from_hex_digit(src[ 0])] << 4 for (int i = 0; i < 6; i++) {
| max_char_map[int_from_hex_digit(src[ 1])]; int u = int_from_hex_digit(src[i * 3 + 0]);
mac->data[1] = max_char_map[int_from_hex_digit(src[ 3])] << 4 int v = int_from_hex_digit(src[i * 3 + 1]);
| max_char_map[int_from_hex_digit(src[ 4])]; mac->data[i] = (max_char_map[u] << 4) | max_char_map[v];
mac->data[2] = max_char_map[int_from_hex_digit(src[ 6])] << 4
| max_char_map[int_from_hex_digit(src[ 7])];
mac->data[3] = max_char_map[int_from_hex_digit(src[ 9])] << 4
| max_char_map[int_from_hex_digit(src[10])];
mac->data[4] = max_char_map[int_from_hex_digit(src[12])] << 4
| max_char_map[int_from_hex_digit(src[13])];
mac->data[5] = max_char_map[int_from_hex_digit(src[15])] << 4
| max_char_map[int_from_hex_digit(src[16])];
} }
return true; return true;
} }