general cleanups
This commit is contained in:
@@ -4,3 +4,6 @@
|
||||
[submodule "3p/tinycthread"]
|
||||
path = 3p/tinycthread
|
||||
url = https://github.com/tinycthread/tinycthread.git
|
||||
[submodule "3p/packetdrill"]
|
||||
path = 3p/packetdrill
|
||||
url = https://github.com/google/packetdrill.git
|
||||
|
||||
Submodule
+1
Submodule 3p/packetdrill added at 8595c94c9c
+5
-46
@@ -3,58 +3,17 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
microtcp_errcode_t errcode;
|
||||
|
||||
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;
|
||||
microtcp_socket_t *server = microtcp_open(mtcp, port, &errcode);
|
||||
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);
|
||||
microtcp_socket_t *server = microtcp_open(mtcp, port, NULL);
|
||||
|
||||
while (1) {
|
||||
fprintf(stderr, "About to accept\n");
|
||||
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");
|
||||
|
||||
microtcp_socket_t *client = microtcp_accept(server, false, NULL);
|
||||
char buffer[1024];
|
||||
size_t num = microtcp_recv(client, buffer, sizeof(buffer), false, &errcode);
|
||||
if (errcode) {
|
||||
fprintf(stderr, "Error: %s\n", microtcp_strerror(errcode));
|
||||
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:
|
||||
size_t num = microtcp_recv(client, buffer, sizeof(buffer), false, NULL);
|
||||
microtcp_send(client, "echo: ", 6, false, NULL);
|
||||
microtcp_send(client, buffer, num, false, NULL);
|
||||
microtcp_close(client);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -48,13 +48,13 @@ MEMDBG=valgrind
|
||||
LIBDIR = 3p/lib
|
||||
INCDIR = 3p/include
|
||||
|
||||
CFLAGS = $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra
|
||||
LFLAGS = -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR)
|
||||
CFLAGS = $(CUSTOM_CFLAGS) $(CFLAGS_PLATFORM) -I$(INCDIR) -Ibuild/ -Wall -Wextra
|
||||
LFLAGS = $(CUSTOM_LFLAGS) -ltuntap $(LFLAGS_PLATFORM) -L$(LIBDIR)
|
||||
|
||||
ifeq ($(MEMDBG),drmemory)
|
||||
CFLAGS += -gdwarf-2
|
||||
else
|
||||
CFLAGS += -g
|
||||
CFLAGS += -g3
|
||||
endif
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -154,7 +154,4 @@ report: build/test
|
||||
gcov -b build/test-tcp_timer.c
|
||||
|
||||
clean:
|
||||
rm build/*.gcda build/*.gcno
|
||||
rm -fr build
|
||||
rm -fr 3p/libtuntap/build
|
||||
rm -f 3p/lib/* 3p/include/*
|
||||
rm -fr build 3p/libtuntap/build 3p/lib/* 3p/include/*
|
||||
@@ -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);
|
||||
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,
|
||||
packet2->sender_protocol_address, state->cache_timeout);
|
||||
|
||||
|
||||
@@ -26,4 +26,10 @@ typedef struct {
|
||||
#define COUNT(X) ((int) (sizeof(X) / sizeof((X)[0])))
|
||||
#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 */
|
||||
+3
-1
@@ -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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ typedef struct {
|
||||
uint32_t src_ip;
|
||||
uint32_t dst_ip;
|
||||
char payload[];
|
||||
} ip_packet_t;
|
||||
} __attribute__((packed)) ip_packet_t;
|
||||
static_assert(sizeof(ip_packet_t) == 20);
|
||||
|
||||
typedef enum {
|
||||
|
||||
+48
-25
@@ -70,7 +70,7 @@ struct buffer_t {
|
||||
buffer_t *prev;
|
||||
buffer_t *next;
|
||||
size_t used;
|
||||
char data[1518];
|
||||
char data[1218];
|
||||
};
|
||||
|
||||
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_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_PEERCLOSED: return "Peer closed the connection";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
@@ -374,6 +375,7 @@ process_packet(microtcp_t *mtcp, const void *packet, size_t len)
|
||||
const ethernet_frame_t *frame = packet;
|
||||
|
||||
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;
|
||||
@@ -644,6 +646,7 @@ static microtcp_socket_t*
|
||||
pop_socket_struct_from_free_list(microtcp_t *mtcp)
|
||||
{
|
||||
microtcp_socket_t *socket = mtcp->free_socket_list;
|
||||
if (socket)
|
||||
mtcp->free_socket_list = socket->next;
|
||||
return socket;
|
||||
}
|
||||
@@ -689,18 +692,24 @@ static void
|
||||
signal_events_to_muxes_associated_to_socket(microtcp_socket_t *socket, int events);
|
||||
#endif
|
||||
|
||||
static void ready_to_accept(void *data)
|
||||
static void listener_event_callback(void *data, tcp_listenevent_t event)
|
||||
{
|
||||
microtcp_socket_t *socket = data;
|
||||
(void) socket;
|
||||
|
||||
#ifdef MICROTCP_BACKGROUND_THREAD
|
||||
cnd_signal(&socket->something_to_accept);
|
||||
switch (event) {
|
||||
case TCP_LISTENEVENT_ACCEPT: cnd_signal(&socket->something_to_accept); break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MICROTCP_USING_MUX
|
||||
MICROTCP_DEBUG_LOG("Signaling ACCEPT to muxes");
|
||||
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_ACCEPT);
|
||||
int flags = 0;
|
||||
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
|
||||
}
|
||||
|
||||
@@ -717,7 +726,7 @@ microtcp_socket_t *microtcp_open(microtcp_t *mtcp, uint16_t port,
|
||||
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) {
|
||||
// FIXME: This error code should be more specific,
|
||||
// but the TCP module isn't stable yet
|
||||
@@ -786,6 +795,8 @@ void microtcp_close(microtcp_socket_t *socket)
|
||||
break;
|
||||
|
||||
case SOCKET_CONNECTION:
|
||||
if (socket->connection) // Only need to close the connection
|
||||
// if the peer didn't already.
|
||||
tcp_connection_destroy(socket->connection);
|
||||
break;
|
||||
}
|
||||
@@ -796,33 +807,34 @@ void microtcp_close(microtcp_socket_t *socket)
|
||||
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;
|
||||
(void) socket;
|
||||
|
||||
#ifdef MICROTCP_BACKGROUND_THREAD
|
||||
cnd_signal(&socket->something_to_recv);
|
||||
#endif
|
||||
switch (event) {
|
||||
|
||||
#ifdef MICROTCP_USING_MUX
|
||||
MICROTCP_DEBUG_LOG("Signaling RECV to muxes");
|
||||
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_RECV);
|
||||
#endif
|
||||
case TCP_CONNEVENT_RECV: MICROTCP_DEBUG_LOG("Signal RECV"); cnd_signal(&socket->something_to_recv); break;
|
||||
case TCP_CONNEVENT_SEND: MICROTCP_DEBUG_LOG("Signal SEND"); cnd_signal(&socket->something_to_send); break;
|
||||
|
||||
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
|
||||
|
||||
#ifdef MICROTCP_USING_MUX
|
||||
MICROTCP_DEBUG_LOG("Signaling SEND to muxes");
|
||||
signal_events_to_muxes_associated_to_socket(socket, MICROTCP_MUX_SEND);
|
||||
// TODO: Maybe signal closing and reset events to muxes?
|
||||
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
|
||||
}
|
||||
|
||||
@@ -847,7 +859,7 @@ microtcp_socket_t *microtcp_accept(microtcp_socket_t *socket,
|
||||
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
|
||||
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);
|
||||
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
|
||||
if (!connection) {
|
||||
@@ -916,6 +928,12 @@ size_t microtcp_recv(microtcp_socket_t *socket,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (socket->connection == NULL) {
|
||||
if (errcode)
|
||||
*errcode = MICROTCP_ERRCODE_PEERCLOSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num;
|
||||
microtcp_t *mtcp = socket->mtcp;
|
||||
microtcp_errcode_t errcode2 = MICROTCP_ERRCODE_NONE;
|
||||
@@ -962,6 +980,11 @@ size_t microtcp_send(microtcp_socket_t *socket,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (socket->connection == NULL) {
|
||||
if (errcode)
|
||||
*errcode = MICROTCP_ERRCODE_PEERCLOSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t num;
|
||||
microtcp_t *mtcp = socket->mtcp;
|
||||
|
||||
@@ -32,6 +32,9 @@ typedef enum {
|
||||
// Returned by microtcp_accept, microtcp_recv and microtcp_send
|
||||
MICROTCP_ERRCODE_WOULDBLOCK,
|
||||
|
||||
// Returned by microtcp_recv, microtcp_send
|
||||
MICROTCP_ERRCODE_PEERCLOSED,
|
||||
|
||||
} microtcp_errcode_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#define TCP_MAX_TIMEOUTS 1024
|
||||
#define TCP_MAX_LISTENERS 32
|
||||
#define TCP_MAX_SOCKETS 1024
|
||||
#define TCP_INPUT_BUFFER_SIZE 1024
|
||||
#define TCP_OUTPUT_BUFFER_SIZE 1024
|
||||
#define TCP_IBUFFER_SIZE 1024
|
||||
#define TCP_OBUFFER_SIZE 1024
|
||||
|
||||
typedef struct tcp_state_t tcp_state_t; // Predeclare for cyclic references
|
||||
|
||||
@@ -36,12 +36,29 @@ typedef struct {
|
||||
uint16_t checksum;
|
||||
uint16_t urgent_pointer;
|
||||
char payload[];
|
||||
} tcp_segment_t;
|
||||
} __attribute__((packed)) tcp_segment_t;
|
||||
static_assert(sizeof(tcp_segment_t) == 20);
|
||||
|
||||
typedef struct tcp_connection_t tcp_connection_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 {
|
||||
tcp_state_t *state;
|
||||
tcp_listener_t *prev;
|
||||
@@ -53,20 +70,35 @@ struct tcp_listener_t {
|
||||
// its still holding.
|
||||
// In this state the listener can be reopened by setting the "closed"
|
||||
// flag to true (and keeping the old connections intact).
|
||||
|
||||
// Port the listener is listening onto
|
||||
uint16_t port;
|
||||
tcp_connection_t *accepted_list;
|
||||
tcp_connection_t *non_established_list;
|
||||
tcp_connection_t *non_accepted_queue_head;
|
||||
tcp_connection_t *non_accepted_queue_tail;
|
||||
void (*callback_ready_to_accept)(void*);
|
||||
void *callback_data;
|
||||
|
||||
// Number of connection
|
||||
int count;
|
||||
|
||||
// List of established and accepted connections
|
||||
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 {
|
||||
TCP_STATE_CLOSED = 0,
|
||||
TCP_STATE_LISTEN,
|
||||
TCP_STATE_SYN_SENT,
|
||||
TCP_STATE_SYN_RCVD,
|
||||
TCP_STATE_ESTAB,
|
||||
TCP_STATE_ESTABLISHED,
|
||||
TCP_STATE_FIN_WAIT_1,
|
||||
TCP_STATE_FIN_WAIT_2,
|
||||
TCP_STATE_CLOSE_WAIT,
|
||||
@@ -76,27 +108,29 @@ typedef enum {
|
||||
} tcp_connstate_t;
|
||||
|
||||
struct tcp_connection_t {
|
||||
|
||||
tcp_listener_t *listener; // Listener that accepted this connection
|
||||
tcp_connection_t *next;
|
||||
tcp_connection_t *prev;
|
||||
|
||||
void *callback_data;
|
||||
void (*callback_ready_to_recv)(void*);
|
||||
void (*callback_ready_to_send)(void*);
|
||||
tcp_conneventcb_t cb_event;
|
||||
void *cb_data;
|
||||
|
||||
tcp_connstate_t state;
|
||||
|
||||
ip_address_t peer_ip; // Network byte order
|
||||
uint16_t peer_port; // CPU byte order
|
||||
|
||||
uint64_t estimated_rtt;
|
||||
uint64_t estimated_dev;
|
||||
|
||||
bool calculating_rtt;
|
||||
uint32_t rtt_calc_seq;
|
||||
uint64_t rtt_calc_time;
|
||||
// From RFC 6298, Section 2
|
||||
// To compute the current RTO, a TCP sender maintains two state
|
||||
// variables, SRTT (smoothed round-trip time) and RTTVAR (round-trip
|
||||
// time variation). In addition, we assume a clock granularity of G
|
||||
// seconds.
|
||||
float srtt;
|
||||
float rttvar;
|
||||
|
||||
tcp_timer_t *retr_timer;
|
||||
tcp_timer_t *wait_timer;
|
||||
|
||||
// Send Sequence Space
|
||||
//
|
||||
@@ -149,10 +183,24 @@ struct tcp_connection_t {
|
||||
// It's the sequence number of the last
|
||||
// byte sent and acknowledged by the peer.
|
||||
|
||||
bool in_buffer_syn;
|
||||
bool in_buffer_fin;
|
||||
char in_buffer[TCP_INPUT_BUFFER_SIZE];
|
||||
char out_buffer[TCP_OUTPUT_BUFFER_SIZE];
|
||||
uint32_t snd_wl1; // SND.WL1 from RFC 9293
|
||||
// segment sequence number used for last
|
||||
// window update.
|
||||
|
||||
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 {
|
||||
@@ -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_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);
|
||||
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);
|
||||
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_finish(tcp_connection_t *connection);
|
||||
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);
|
||||
|
||||
+4
-2
@@ -61,6 +61,8 @@ tcp_timer_t *tcp_timer_create(tcp_timerset_t *set, size_t ms,
|
||||
// first item of the free list.
|
||||
|
||||
timer->set = set;
|
||||
timer->set_time = set->current_time_ms;
|
||||
timer->trg_time = ms;
|
||||
timer->deadline = set->current_time_ms + ms;
|
||||
timer->data = data;
|
||||
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
|
||||
tcp_timer_t *timeout = set->used_list;
|
||||
while (timeout) {
|
||||
do {
|
||||
|
||||
if (timeout->deadline > set->current_time_ms)
|
||||
// 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;
|
||||
timeout = timeout->next;
|
||||
}
|
||||
} while (timeout);
|
||||
|
||||
// Now put the list of timed out timeouts back
|
||||
// into the free list
|
||||
|
||||
@@ -14,6 +14,8 @@ struct tcp_timer_t {
|
||||
tcp_timerset_t *set;
|
||||
tcp_timer_t *prev;
|
||||
tcp_timer_t *next;
|
||||
uint64_t set_time;
|
||||
uint64_t trg_time;
|
||||
uint64_t deadline;
|
||||
void (*callback)(void *data);
|
||||
void *data;
|
||||
|
||||
+9
-17
@@ -17,15 +17,14 @@ static bool is_hex_digit(char c)
|
||||
static int int_from_hex_digit(char c)
|
||||
{
|
||||
assert(is_hex_digit(c));
|
||||
if (c >= 'A' || c <= 'F')
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' || c <= 'f')
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
bool parse_mac(const char *src, size_t len,
|
||||
mac_address_t *mac)
|
||||
bool parse_mac(const char *src, size_t len, mac_address_t *mac)
|
||||
{
|
||||
if (src == NULL || len != 17
|
||||
|| !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";
|
||||
|
||||
if (mac) {
|
||||
mac->data[0] = max_char_map[int_from_hex_digit(src[ 0])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 1])];
|
||||
mac->data[1] = max_char_map[int_from_hex_digit(src[ 3])] << 4
|
||||
| max_char_map[int_from_hex_digit(src[ 4])];
|
||||
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])];
|
||||
if (mac)
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int u = int_from_hex_digit(src[i * 3 + 0]);
|
||||
int v = int_from_hex_digit(src[i * 3 + 1]);
|
||||
mac->data[i] = (max_char_map[u] << 4) | max_char_map[v];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user