}
bool do_pre_accept(struct utcp *utcp, uint16_t port) {
+ (void)utcp;
fprintf(stderr, "pre-accept\n");
if(port != 7)
return false;
}
void do_accept(struct utcp_connection *c, uint16_t port) {
+ (void)port;
fprintf(stderr, "accept\n");
utcp_accept(c, do_recv, NULL);
}
}
int main(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+
srand(time(NULL));
a = utcp_init(do_accept, do_pre_accept, do_send, NULL);
va_end(ap);
}
#else
-#define debug(...)
+#define debug(...) do {} while(0)
#endif
ssize_t do_recv(struct utcp_connection *c, const void *data, size_t len) {
+ (void)c;
if(!data || !len) {
if(errno) {
debug("Error: %s\n", strerror(errno));
}
void do_accept(struct utcp_connection *nc, uint16_t port) {
+ (void)port;
utcp_accept(nc, do_recv, NULL);
c = nc;
utcp_set_accept_cb(c->utcp, NULL, NULL);
/*
utcp.c -- Userspace TCP
- Copyright (C) 2014 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2014-2017 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
debug("\n");
}
#else
-#define debug(...)
-#define print_packet(...)
+#define debug(...) do {} while(0)
+#define print_packet(...) do {} while(0)
#endif
static void set_state(struct utcp_connection *c, enum state state) {
return c->flags & UTCP_RELIABLE;
}
-static inline void list_connections(struct utcp *utcp) {
- debug("%p has %d connections:\n", utcp, utcp->nconnections);
- for(int i = 0; i < utcp->nconnections; i++)
- debug(" %u -> %u state %s\n", utcp->connections[i]->src, utcp->connections[i]->dst, strstate[utcp->connections[i]->state]);
-}
-
static int32_t seqdiff(uint32_t a, uint32_t b) {
return a - b;
}
return c;
}
+static inline uint32_t absdiff(uint32_t a, uint32_t b) {
+ if(a > b)
+ return a - b;
+ else
+ return b - a;
+}
+
// Update RTT variables. See RFC 6298.
static void update_rtt(struct utcp_connection *c, uint32_t rtt) {
if(!rtt) {
utcp->rttvar = rtt / 2;
utcp->rto = rtt + max(2 * rtt, CLOCK_GRANULARITY);
} else {
- utcp->rttvar = (utcp->rttvar * 3 + abs(utcp->srtt - rtt)) / 4;
+ utcp->rttvar = (utcp->rttvar * 3 + absdiff(utcp->srtt, rtt)) / 4;
utcp->srtt = (utcp->srtt * 7 + rtt) / 8;
utcp->rto = utcp->srtt + max(utcp->rttvar, CLOCK_GRANULARITY);
}
debug("out of order packet, offset %u\n", offset);
// Packet loss or reordering occured. Store the data in the buffer.
ssize_t rxd = buffer_put_at(&c->rcvbuf, offset, data, len);
- if(rxd < len)
+ if(rxd < 0 || (size_t)rxd < len)
abort();
// Make note of where we put it.
if(c->recv) {
ssize_t rxd = c->recv(c, data, len);
- if(rxd != len) {
+ if(rxd < 0 || (size_t)rxd != len) {
// TODO: handle the application not accepting all data.
abort();
}
// cut already accepted front overlapping
if(rcv_offset < 0) {
- acceptable = len > -rcv_offset;
+ acceptable = len > (size_t)-rcv_offset;
if(acceptable) {
data -= rcv_offset;
len += rcv_offset;