2 utcp.c -- Userspace TCP
3 Copyright (C) 2014-2017 Guus Sliepen <guus@tinc-vpn.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "utcp_priv.h"
38 #if defined(CLOCK_MONOTONIC_RAW) && defined(__x86_64__)
39 #define UTCP_CLOCK CLOCK_MONOTONIC_RAW
41 #define UTCP_CLOCK CLOCK_MONOTONIC
45 static void timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *r) {
46 r->tv_sec = a->tv_sec - b->tv_sec;
47 r->tv_nsec = a->tv_nsec - b->tv_nsec;
50 r->tv_sec--, r->tv_nsec += NSEC_PER_SEC;
54 static int32_t timespec_diff_usec(const struct timespec *a, const struct timespec *b) {
55 return (a->tv_sec - b->tv_sec) * 1000000 + (a->tv_nsec - b->tv_nsec) / 1000;
58 static bool timespec_lt(const struct timespec *a, const struct timespec *b) {
59 if(a->tv_sec == b->tv_sec) {
60 return a->tv_nsec < b->tv_nsec;
62 return a->tv_sec < b->tv_sec;
66 static void timespec_clear(struct timespec *a) {
71 static bool timespec_isset(const struct timespec *a) {
75 static long CLOCK_GRANULARITY; // usec
77 static inline size_t min(size_t a, size_t b) {
81 static inline size_t max(size_t a, size_t b) {
88 #ifndef UTCP_DEBUG_DATALEN
89 #define UTCP_DEBUG_DATALEN 20
92 static void debug(struct utcp_connection *c, const char *format, ...) {
97 clock_gettime(CLOCK_REALTIME, &tv);
98 len = snprintf(buf, sizeof(buf), "%ld.%06lu %u:%u ", (long)tv.tv_sec, tv.tv_nsec / 1000, c ? c->src : 0, c ? c->dst : 0);
100 va_start(ap, format);
101 len += vsnprintf(buf + len, sizeof(buf) - len, format, ap);
104 if(len > 0 && (size_t)len < sizeof(buf)) {
105 fwrite(buf, len, 1, stderr);
109 static void print_packet(struct utcp_connection *c, const char *dir, const void *pkt, size_t len) {
112 if(len < sizeof(hdr)) {
113 debug(c, "%s: short packet (%lu bytes)\n", dir, (unsigned long)len);
117 memcpy(&hdr, pkt, sizeof(hdr));
121 if(len > sizeof(hdr)) {
122 datalen = min(len - sizeof(hdr), UTCP_DEBUG_DATALEN);
128 const uint8_t *data = (uint8_t *)pkt + sizeof(hdr);
129 char str[datalen * 2 + 1];
132 for(uint32_t i = 0; i < datalen; i++) {
133 *p++ = "0123456789ABCDEF"[data[i] >> 4];
134 *p++ = "0123456789ABCDEF"[data[i] & 15];
139 debug(c, "%s: len %lu src %u dst %u seq %u ack %u wnd %u aux %x ctl %s%s%s%s%s data %s\n",
140 dir, (unsigned long)len, hdr.src, hdr.dst, hdr.seq, hdr.ack, hdr.wnd, hdr.aux,
141 hdr.ctl & SYN ? "SYN" : "",
142 hdr.ctl & RST ? "RST" : "",
143 hdr.ctl & FIN ? "FIN" : "",
144 hdr.ctl & ACK ? "ACK" : "",
145 hdr.ctl & MF ? "MF" : "",
150 static void debug_cwnd(struct utcp_connection *c) {
151 debug(c, "snd.cwnd %u snd.ssthresh %u\n", c->snd.cwnd, ~c->snd.ssthresh ? c->snd.ssthresh : 0);
154 #define debug(...) do {} while(0)
155 #define print_packet(...) do {} while(0)
156 #define debug_cwnd(...) do {} while(0)
159 static void set_state(struct utcp_connection *c, enum state state) {
162 if(state == ESTABLISHED) {
163 timespec_clear(&c->conn_timeout);
166 debug(c, "state %s\n", strstate[state]);
169 static bool fin_wanted(struct utcp_connection *c, uint32_t seq) {
170 if(seq != c->snd.last) {
185 static int32_t seqdiff(uint32_t a, uint32_t b) {
189 // Connections are stored in a sorted list.
190 // This gives O(log(N)) lookup time, O(N log(N)) insertion time and O(N) deletion time.
192 static int compare(const void *va, const void *vb) {
195 const struct utcp_connection *a = *(struct utcp_connection **)va;
196 const struct utcp_connection *b = *(struct utcp_connection **)vb;
200 int c = (int)a->src - (int)b->src;
206 c = (int)a->dst - (int)b->dst;
210 static struct utcp_connection *find_connection(const struct utcp *utcp, uint16_t src, uint16_t dst) {
211 if(!utcp->nconnections) {
215 struct utcp_connection key = {
219 struct utcp_connection **match = bsearch(&keyp, utcp->connections, utcp->nconnections, sizeof(*utcp->connections), compare);
220 return match ? *match : NULL;
223 static void free_connection(struct utcp_connection *c) {
224 struct utcp *utcp = c->utcp;
225 struct utcp_connection **cp = bsearch(&c, utcp->connections, utcp->nconnections, sizeof(*utcp->connections), compare);
229 int i = cp - utcp->connections;
230 memmove(cp, cp + 1, (utcp->nconnections - i - 1) * sizeof(*cp));
231 utcp->nconnections--;
236 static struct utcp_connection *allocate_connection(struct utcp *utcp, uint16_t src, uint16_t dst) {
237 // Check whether this combination of src and dst is free
240 if(find_connection(utcp, src, dst)) {
244 } else { // If src == 0, generate a random port number with the high bit set
245 if(utcp->nconnections >= 32767) {
250 src = rand() | 0x8000;
252 while(find_connection(utcp, src, dst)) {
257 // Allocate memory for the new connection
259 if(utcp->nconnections >= utcp->nallocated) {
260 if(!utcp->nallocated) {
261 utcp->nallocated = 4;
263 utcp->nallocated *= 2;
266 struct utcp_connection **new_array = realloc(utcp->connections, utcp->nallocated * sizeof(*utcp->connections));
272 utcp->connections = new_array;
275 struct utcp_connection *c = calloc(1, sizeof(*c));
281 // Fill in the details
290 c->snd.una = c->snd.iss;
291 c->snd.nxt = c->snd.iss + 1;
292 c->snd.last = c->snd.nxt;
293 c->snd.cwnd = (utcp->mss > 2190 ? 2 : utcp->mss > 1095 ? 3 : 4) * utcp->mss;
294 c->snd.ssthresh = ~0;
301 // Add it to the sorted list of connections
303 utcp->connections[utcp->nconnections++] = c;
304 qsort(utcp->connections, utcp->nconnections, sizeof(*utcp->connections), compare);
309 static inline uint32_t absdiff(uint32_t a, uint32_t b) {
317 // Update RTT variables. See RFC 6298.
318 static void update_rtt(struct utcp_connection *c, uint32_t rtt) {
320 debug(c, "invalid rtt\n");
328 c->rttvar = (c->rttvar * 3 + absdiff(c->srtt, rtt)) / 4;
329 c->srtt = (c->srtt * 7 + rtt) / 8;
332 c->rto = c->srtt + max(4 * c->rttvar, CLOCK_GRANULARITY);
334 if(c->rto > MAX_RTO) {
338 debug(c, "rtt %u srtt %u rttvar %u rto %u\n", rtt, c->srtt, c->rttvar, c->rto);
341 static void start_retransmit_timer(struct utcp_connection *c) {
342 clock_gettime(UTCP_CLOCK, &c->rtrx_timeout);
344 uint32_t rto = c->rto;
346 while(rto > USEC_PER_SEC) {
347 c->rtrx_timeout.tv_sec++;
351 c->rtrx_timeout.tv_nsec += rto * 1000;
353 if(c->rtrx_timeout.tv_nsec >= NSEC_PER_SEC) {
354 c->rtrx_timeout.tv_nsec -= NSEC_PER_SEC;
355 c->rtrx_timeout.tv_sec++;
358 debug(c, "rtrx_timeout %ld.%06lu\n", c->rtrx_timeout.tv_sec, c->rtrx_timeout.tv_nsec);
361 static void stop_retransmit_timer(struct utcp_connection *c) {
362 timespec_clear(&c->rtrx_timeout);
363 debug(c, "rtrx_timeout cleared\n");
366 struct utcp_connection *utcp_connect_ex(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv, uint32_t flags) {
367 struct utcp_connection *c = allocate_connection(utcp, 0, dst);
373 assert(flags == 0); // UDP only
384 pkt.hdr.src = c->src;
385 pkt.hdr.dst = c->dst;
386 pkt.hdr.seq = c->snd.iss;
388 pkt.hdr.wnd = c->utcp->mtu;
390 pkt.hdr.aux = 0x0101;
394 pkt.init[3] = flags & 0x7;
396 set_state(c, SYN_SENT);
398 print_packet(c, "send", &pkt, sizeof(pkt));
399 utcp->send(utcp, &pkt, sizeof(pkt));
401 clock_gettime(UTCP_CLOCK, &c->conn_timeout);
402 c->conn_timeout.tv_sec += utcp->timeout;
404 start_retransmit_timer(c);
409 void utcp_accept(struct utcp_connection *c, utcp_recv_t recv, void *priv) {
410 if(c->reapable || c->state != SYN_RECEIVED) {
411 debug(c, "accept() called on invalid connection in state %s\n", c, strstate[c->state]);
415 debug(c, "accepted %p %p\n", c, recv, priv);
418 set_state(c, ESTABLISHED);
421 static void ack(struct utcp_connection *c, const void *data, size_t len) {
425 } *pkt = c->utcp->pkt;
427 pkt->hdr.src = c->src;
428 pkt->hdr.dst = c->dst;
429 pkt->hdr.ack = c->rcv.nxt;
434 uint32_t seglen = len;
435 pkt->hdr.seq = c->snd.nxt;
437 c->snd.nxt += seglen;
439 if(fin_wanted(c, c->snd.nxt)) {
444 assert(len <= c->utcp->mtu);
445 memcpy(pkt->data, data, len);
447 assert(!data && !len);
450 if(!c->rtt_start.tv_sec) {
451 // Start RTT measurement
452 clock_gettime(UTCP_CLOCK, &c->rtt_start);
453 c->rtt_seq = pkt->hdr.seq + seglen;
454 debug(c, "starting RTT measurement, expecting ack %u\n", c->rtt_seq);
457 print_packet(c, "send", pkt, sizeof(pkt->hdr) + seglen);
458 c->utcp->send(c->utcp, pkt, sizeof(pkt->hdr) + seglen);
461 ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) {
463 debug(c, "send() called on closed connection\n");
471 debug(c, "send() called on unconnected connection\n");
486 debug(c, "send() called on closed connection\n");
491 // Exit early if we have nothing to send.
502 if(len > MAX_UNRELIABLE_SIZE || len > c->utcp->mtu) {
513 // Don't send anything yet if the connection has not fully established yet
515 if(c->state == SYN_SENT || c->state == SYN_RECEIVED) {
521 c->snd.una = c->snd.nxt = c->snd.last;
526 static void swap_ports(struct hdr *hdr) {
527 uint16_t tmp = hdr->src;
532 static void retransmit(struct utcp_connection *c) {
533 if(c->state == CLOSED || c->snd.last == c->snd.una) {
534 debug(c, "retransmit() called but nothing to retransmit!\n");
535 stop_retransmit_timer(c);
539 struct utcp *utcp = c->utcp;
544 } *pkt = c->utcp->pkt;
546 pkt->hdr.src = c->src;
547 pkt->hdr.dst = c->dst;
548 pkt->hdr.wnd = c->utcp->mtu;
553 // Send our SYN again
554 pkt->hdr.seq = c->snd.iss;
557 pkt->hdr.aux = 0x0101;
561 pkt->data[3] = c->flags & 0x7;
562 print_packet(c, "rtrx", pkt, sizeof(pkt->hdr) + 4);
563 utcp->send(utcp, pkt, sizeof(pkt->hdr) + 4);
568 pkt->hdr.seq = c->snd.nxt;
569 pkt->hdr.ack = c->rcv.nxt;
570 pkt->hdr.ctl = SYN | ACK;
571 print_packet(c, "rtrx", pkt, sizeof(pkt->hdr));
572 utcp->send(utcp, pkt, sizeof(pkt->hdr));
582 // Send unacked data again.
583 pkt->hdr.seq = c->snd.una;
584 pkt->hdr.ack = c->rcv.nxt;
586 uint32_t len = min(seqdiff(c->snd.last, c->snd.una), utcp->mss);
588 if(fin_wanted(c, c->snd.una + len)) {
597 print_packet(c, "rtrx", pkt, sizeof(pkt->hdr) + len);
598 utcp->send(utcp, pkt, sizeof(pkt->hdr) + len);
605 // We shouldn't need to retransmit anything in this state.
609 stop_retransmit_timer(c);
613 start_retransmit_timer(c);
616 if(c->rto > MAX_RTO) {
620 c->rtt_start.tv_sec = 0; // invalidate RTT timer
621 c->dupack = 0; // cancel any ongoing fast recovery
627 static void handle_unreliable(struct utcp_connection *c, const struct hdr *hdr, const void *data, size_t len) {
628 // Fast path for unfragmented packets
629 if(!hdr->wnd && !(hdr->ctl & MF)) {
631 c->recv(c, data, len);
634 c->rcv.nxt = hdr->seq + len;
639 static void handle_incoming_data(struct utcp_connection *c, const struct hdr *hdr, const void *data, size_t len) {
640 handle_unreliable(c, hdr, data, len);
643 ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
644 const uint8_t *ptr = data;
660 // Drop packets smaller than the header
664 if(len < sizeof(hdr)) {
665 print_packet(NULL, "recv", data, len);
670 // Make a copy from the potentially unaligned data to a struct hdr
672 memcpy(&hdr, ptr, sizeof(hdr));
674 // Try to match the packet to an existing connection
676 struct utcp_connection *c = find_connection(utcp, hdr.dst, hdr.src);
677 print_packet(c, "recv", data, len);
679 // Process the header
684 // Drop packets with an unknown CTL flag
686 if(hdr.ctl & ~(SYN | ACK | RST | FIN | MF)) {
687 print_packet(NULL, "recv", data, len);
692 // Check for auxiliary headers
694 const uint8_t *init = NULL;
696 uint16_t aux = hdr.aux;
699 size_t auxlen = 4 * (aux >> 8) & 0xf;
700 uint8_t auxtype = aux & 0xff;
709 if(!(hdr.ctl & SYN) || auxlen != 4) {
734 memcpy(&aux, ptr, 2);
739 // Is it for a new connection?
742 // Ignore RST packets
748 // Is it a SYN packet and are we LISTENing?
750 if(hdr.ctl & SYN && !(hdr.ctl & ACK) && utcp->accept) {
751 // If we don't want to accept it, send a RST back
752 if((utcp->listen && !utcp->listen(utcp, hdr.dst))) {
757 // Try to allocate memory, otherwise send a RST back
758 c = allocate_connection(utcp, hdr.dst, hdr.src);
765 // Parse auxilliary information
772 c->flags = init[3] & 0x7;
778 // Return SYN+ACK, go to SYN_RECEIVED state
779 c->snd.wnd = hdr.wnd;
780 c->rcv.irs = hdr.seq;
781 c->rcv.nxt = c->rcv.irs + 1;
782 set_state(c, SYN_RECEIVED);
789 pkt.hdr.src = c->src;
790 pkt.hdr.dst = c->dst;
791 pkt.hdr.ack = c->rcv.irs + 1;
792 pkt.hdr.seq = c->snd.iss;
793 pkt.hdr.wnd = c->utcp->mtu;
794 pkt.hdr.ctl = SYN | ACK;
797 pkt.hdr.aux = 0x0101;
801 pkt.data[3] = c->flags & 0x7;
802 print_packet(c, "send", &pkt, sizeof(hdr) + 4);
803 utcp->send(utcp, &pkt, sizeof(hdr) + 4);
806 print_packet(c, "send", &pkt, sizeof(hdr));
807 utcp->send(utcp, &pkt, sizeof(hdr));
810 start_retransmit_timer(c);
812 // No, we don't want your packets, send a RST back
820 debug(c, "state %s\n", strstate[c->state]);
822 // In case this is for a CLOSED connection, ignore the packet.
823 // TODO: make it so incoming packets can never match a CLOSED connection.
825 if(c->state == CLOSED) {
826 debug(c, "got packet for closed connection\n");
830 // It is for an existing connection.
832 // 1. Drop invalid packets.
834 // 1a. Drop packets that should not happen in our current state.
856 int32_t rcv_offset = seqdiff(hdr.seq, c->rcv.nxt);
859 debug(c, "packet out of order, offset %u bytes", rcv_offset);
864 c->snd.wnd = hdr.wnd; // TODO: move below
866 // 1c. Drop packets with an invalid ACK.
867 // ackno should not roll back, and it should also not be bigger than what we ever could have sent
868 // (= snd.una + c->sndbuf.used).
870 if(hdr.ack != c->snd.last && c->state >= ESTABLISHED) {
871 hdr.ack = c->snd.una;
874 // 2. Handle RST packets
879 if(!(hdr.ctl & ACK)) {
883 // The peer has refused our connection.
884 set_state(c, CLOSED);
885 errno = ECONNREFUSED;
898 // We haven't told the application about this connection yet. Silently delete.
910 // The peer has aborted our connection.
911 set_state(c, CLOSED);
927 // As far as the application is concerned, the connection has already been closed.
928 // If it has called utcp_close() already, we can immediately free this connection.
934 // Otherwise, immediately move to the CLOSED state.
935 set_state(c, CLOSED);
948 if(!(hdr.ctl & ACK)) {
953 // 3. Advance snd.una
955 if(seqdiff(hdr.ack, c->snd.last) > 0 || seqdiff(hdr.ack, c->snd.una) < 0) {
956 debug(c, "packet ack seqno out of range, %u <= %u < %u\n", c->snd.una, hdr.ack, c->snd.una + c->sndbuf.used);
960 advanced = seqdiff(hdr.ack, c->snd.una);
964 if(c->rtt_start.tv_sec) {
965 if(c->rtt_seq == hdr.ack) {
967 clock_gettime(UTCP_CLOCK, &now);
968 int32_t diff = timespec_diff_usec(&now, &c->rtt_start);
970 c->rtt_start.tv_sec = 0;
971 } else if(c->rtt_seq < hdr.ack) {
972 debug(c, "cancelling RTT measurement: %u < %u\n", c->rtt_seq, hdr.ack);
973 c->rtt_start.tv_sec = 0;
977 int32_t data_acked = advanced;
985 // TODO: handle FIN as well.
990 assert(data_acked >= 0);
993 int32_t bufused = seqdiff(c->snd.last, c->snd.una);
994 assert(data_acked <= bufused);
997 // Also advance snd.nxt if possible
998 if(seqdiff(c->snd.nxt, hdr.ack) < 0) {
999 c->snd.nxt = hdr.ack;
1002 c->snd.una = hdr.ack;
1005 if(c->dupack >= 3) {
1006 debug(c, "fast recovery ended\n");
1007 c->snd.cwnd = c->snd.ssthresh;
1013 // Increase the congestion window according to RFC 5681
1014 if(c->snd.cwnd < c->snd.ssthresh) {
1015 c->snd.cwnd += min(advanced, utcp->mss); // eq. 2
1017 c->snd.cwnd += max(1, (utcp->mss * utcp->mss) / c->snd.cwnd); // eq. 3
1020 if(c->snd.cwnd > c->utcp->mtu) {
1021 c->snd.cwnd = c->utcp->mtu;
1026 // Check if we have sent a FIN that is now ACKed.
1029 if(c->snd.una == c->snd.last) {
1030 set_state(c, FIN_WAIT_2);
1036 if(c->snd.una == c->snd.last) {
1037 clock_gettime(UTCP_CLOCK, &c->conn_timeout);
1038 c->conn_timeout.tv_sec += utcp->timeout;
1039 set_state(c, TIME_WAIT);
1052 if(c->snd.una == c->snd.last) {
1053 stop_retransmit_timer(c);
1054 timespec_clear(&c->conn_timeout);
1059 // 5. Process SYN stuff
1065 // This is a SYNACK. It should always have ACKed the SYN.
1070 c->rcv.irs = hdr.seq;
1071 c->rcv.nxt = hdr.seq + 1;
1075 set_state(c, FIN_WAIT_1);
1077 set_state(c, ESTABLISHED);
1083 // This is a retransmit of a SYN, send back the SYNACK.
1093 // This could be a retransmission. Ignore the SYN flag, but send an ACK back.
1104 // 6. Process new data
1106 if(c->state == SYN_RECEIVED) {
1107 // This is the ACK after the SYNACK. It should always have ACKed the SYNACK.
1112 // Are we still LISTENing?
1114 utcp->accept(c, c->src);
1117 if(c->state != ESTABLISHED) {
1118 set_state(c, CLOSED);
1128 // This should never happen.
1140 // We already closed the connection and are not interested in more data.
1150 // Ehm no, We should never receive more data after a FIN.
1160 handle_incoming_data(c, &hdr, ptr, len);
1163 // 7. Process FIN stuff
1169 // This should never happen.
1176 set_state(c, CLOSE_WAIT);
1180 set_state(c, CLOSING);
1184 clock_gettime(UTCP_CLOCK, &c->conn_timeout);
1185 c->conn_timeout.tv_sec += utcp->timeout;
1186 set_state(c, TIME_WAIT);
1193 // Ehm, no. We should never receive a second FIN.
1203 // FIN counts as one sequence number
1207 // Inform the application that the peer closed its end of the connection.
1210 c->recv(c, NULL, 0);
1214 // Now we send something back if:
1215 // - we received data, so we have to send back an ACK
1216 // -> sendatleastone = true
1217 // - or we got an ack, so we should maybe send a bit more data
1218 // -> sendatleastone = false
1220 if(hdr.ctl & SYN || hdr.ctl & FIN) {
1235 hdr.ack = hdr.seq + len;
1237 hdr.ctl = RST | ACK;
1240 print_packet(c, "send", &hdr, sizeof(hdr));
1241 utcp->send(utcp, &hdr, sizeof(hdr));
1246 int utcp_shutdown(struct utcp_connection *c, int dir) {
1247 debug(c, "shutdown %d at %u\n", dir, c ? c->snd.last : 0);
1255 debug(c, "shutdown() called on closed connection\n");
1260 if(!(dir == UTCP_SHUT_RD || dir == UTCP_SHUT_WR || dir == UTCP_SHUT_RDWR)) {
1265 // TCP does not have a provision for stopping incoming packets.
1266 // The best we can do is to just ignore them.
1267 if(dir == UTCP_SHUT_RD || dir == UTCP_SHUT_RDWR) {
1271 // The rest of the code deals with shutting down writes.
1272 if(dir == UTCP_SHUT_RD) {
1276 // Only process shutting down writes once.
1294 set_state(c, FIN_WAIT_1);
1302 set_state(c, CLOSING);
1315 if(!timespec_isset(&c->rtrx_timeout)) {
1316 start_retransmit_timer(c);
1322 static bool reset_connection(struct utcp_connection *c) {
1329 debug(c, "abort() called on closed connection\n");
1343 set_state(c, CLOSED);
1351 set_state(c, CLOSED);
1361 hdr.seq = c->snd.nxt;
1362 hdr.ack = c->rcv.nxt;
1367 print_packet(c, "send", &hdr, sizeof(hdr));
1368 c->utcp->send(c->utcp, &hdr, sizeof(hdr));
1372 static void set_reapable(struct utcp_connection *c) {
1377 // Resets all connections, but does not invalidate connection handles
1378 void utcp_reset_all_connections(struct utcp *utcp) {
1384 for(int i = 0; i < utcp->nconnections; i++) {
1385 struct utcp_connection *c = utcp->connections[i];
1387 if(c->reapable || c->state == CLOSED) {
1391 reset_connection(c);
1395 c->recv(c, NULL, 0);
1402 int utcp_close(struct utcp_connection *c) {
1403 if(utcp_shutdown(c, SHUT_RDWR) && errno != ENOTCONN) {
1411 int utcp_abort(struct utcp_connection *c) {
1412 if(!reset_connection(c)) {
1421 * One call to this function will loop through all connections,
1422 * checking if something needs to be resent or not.
1423 * The return value is the time to the next timeout in milliseconds,
1424 * or maybe a negative value if the timeout is infinite.
1426 struct timespec utcp_timeout(struct utcp *utcp) {
1427 struct timespec now;
1428 clock_gettime(UTCP_CLOCK, &now);
1429 struct timespec next = {now.tv_sec + 3600, now.tv_nsec};
1431 for(int i = 0; i < utcp->nconnections; i++) {
1432 struct utcp_connection *c = utcp->connections[i];
1438 // delete connections that have been utcp_close()d.
1439 if(c->state == CLOSED) {
1441 debug(c, "reaping\n");
1449 if(timespec_isset(&c->conn_timeout) && timespec_lt(&c->conn_timeout, &now)) {
1454 c->recv(c, NULL, 0);
1460 if(timespec_isset(&c->rtrx_timeout) && timespec_lt(&c->rtrx_timeout, &now)) {
1461 debug(c, "retransmitting after timeout\n");
1465 if(timespec_isset(&c->conn_timeout) && timespec_lt(&c->conn_timeout, &next)) {
1466 next = c->conn_timeout;
1469 if(timespec_isset(&c->rtrx_timeout) && timespec_lt(&c->rtrx_timeout, &next)) {
1470 next = c->rtrx_timeout;
1474 struct timespec diff;
1476 timespec_sub(&next, &now, &diff);
1481 bool utcp_is_active(struct utcp *utcp) {
1486 for(int i = 0; i < utcp->nconnections; i++)
1487 if(utcp->connections[i]->state != CLOSED && utcp->connections[i]->state != TIME_WAIT) {
1494 struct utcp *utcp_init(utcp_accept_t accept, utcp_listen_t listen, utcp_send_t send, void *priv) {
1500 struct utcp *utcp = calloc(1, sizeof(*utcp));
1506 utcp_set_mtu(utcp, DEFAULT_MTU);
1513 if(!CLOCK_GRANULARITY) {
1514 struct timespec res;
1515 clock_getres(UTCP_CLOCK, &res);
1516 CLOCK_GRANULARITY = res.tv_sec * USEC_PER_SEC + res.tv_nsec / 1000;
1519 utcp->accept = accept;
1520 utcp->listen = listen;
1523 utcp->timeout = DEFAULT_USER_TIMEOUT; // sec
1528 void utcp_exit(struct utcp *utcp) {
1533 for(int i = 0; i < utcp->nconnections; i++) {
1534 struct utcp_connection *c = utcp->connections[i];
1538 c->recv(c, NULL, 0);
1545 free(utcp->connections);
1550 uint16_t utcp_get_mtu(struct utcp *utcp) {
1551 return utcp ? utcp->mtu : 0;
1554 uint16_t utcp_get_mss(struct utcp *utcp) {
1555 return utcp ? utcp->mss : 0;
1558 void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) {
1563 if(mtu <= sizeof(struct hdr)) {
1567 if(mtu > utcp->mtu) {
1568 char *new = realloc(utcp->pkt, mtu + sizeof(struct hdr));
1578 utcp->mss = mtu - sizeof(struct hdr);
1581 void utcp_reset_timers(struct utcp *utcp) {
1586 struct timespec now, then;
1588 clock_gettime(UTCP_CLOCK, &now);
1592 then.tv_sec += utcp->timeout;
1594 for(int i = 0; i < utcp->nconnections; i++) {
1595 struct utcp_connection *c = utcp->connections[i];
1601 if(timespec_isset(&c->rtrx_timeout)) {
1602 c->rtrx_timeout = now;
1605 if(timespec_isset(&c->conn_timeout)) {
1606 c->conn_timeout = then;
1609 c->rtt_start.tv_sec = 0;
1611 if(c->rto > START_RTO) {
1617 int utcp_get_user_timeout(struct utcp *u) {
1618 return u ? u->timeout : 0;
1621 void utcp_set_user_timeout(struct utcp *u, int timeout) {
1623 u->timeout = timeout;
1627 bool utcp_get_nodelay(struct utcp_connection *c) {
1628 return c ? c->nodelay : false;
1631 void utcp_set_nodelay(struct utcp_connection *c, bool nodelay) {
1633 c->nodelay = nodelay;
1637 bool utcp_get_keepalive(struct utcp_connection *c) {
1638 return c ? c->keepalive : false;
1641 void utcp_set_keepalive(struct utcp_connection *c, bool keepalive) {
1643 c->keepalive = keepalive;
1647 void utcp_set_recv_cb(struct utcp_connection *c, utcp_recv_t recv) {
1653 void utcp_set_accept_cb(struct utcp *utcp, utcp_accept_t accept, utcp_listen_t listen) {
1655 utcp->accept = accept;
1656 utcp->listen = listen;
1660 void utcp_expect_data(struct utcp_connection *c, bool expect) {
1661 if(!c || c->reapable) {
1665 if(!(c->state == ESTABLISHED || c->state == FIN_WAIT_1 || c->state == FIN_WAIT_2)) {
1670 // If we expect data, start the connection timer.
1671 if(!timespec_isset(&c->conn_timeout)) {
1672 clock_gettime(UTCP_CLOCK, &c->conn_timeout);
1673 c->conn_timeout.tv_sec += c->utcp->timeout;
1676 // If we want to cancel expecting data, only clear the timer when there is no unACKed data.
1677 if(c->snd.una == c->snd.last) {
1678 timespec_clear(&c->conn_timeout);
1683 void utcp_set_flags(struct utcp_connection *c, uint32_t flags) {
1684 c->flags &= ~UTCP_CHANGEABLE_FLAGS;
1685 c->flags |= flags & UTCP_CHANGEABLE_FLAGS;
1688 void utcp_offline(struct utcp *utcp, bool offline) {
1689 struct timespec now;
1690 clock_gettime(UTCP_CLOCK, &now);
1692 for(int i = 0; i < utcp->nconnections; i++) {
1693 struct utcp_connection *c = utcp->connections[i];
1699 utcp_expect_data(c, offline);
1702 if(timespec_isset(&c->rtrx_timeout)) {
1703 c->rtrx_timeout = now;
1706 utcp->connections[i]->rtt_start.tv_sec = 0;
1708 if(c->rto > START_RTO) {
1715 void utcp_set_clock_granularity(long granularity) {
1716 CLOCK_GRANULARITY = granularity;