]> git.meshlink.io Git - utcp/blob - utcp.c
Fix memory and resource leaks.
[utcp] / utcp.c
1 /*
2     utcp.c -- Userspace TCP
3     Copyright (C) 2014 Guus Sliepen <guus@tinc-vpn.org>
4
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.
9
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.
14
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.
18 */
19
20 #define _GNU_SOURCE
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <sys/time.h>
30 #include <sys/socket.h>
31
32 #include "utcp_priv.h"
33
34 #ifdef UTCP_DEBUG
35 #include <stdarg.h>
36
37 static void debug(const char *format, ...) {
38         va_list ap;
39         va_start(ap, format);
40         vfprintf(stderr, format, ap);
41         va_end(ap);
42 }
43
44 static void print_packet(struct utcp *utcp, const char *dir, const void *pkt, size_t len) {
45         struct hdr hdr;
46         if(len < sizeof hdr) {
47                 debug("%p %s: short packet (%zu bytes)\n", utcp, dir, len);
48                 return;
49         }
50
51         memcpy(&hdr, pkt, sizeof hdr);
52         fprintf (stderr, "%p %s: src=%u dst=%u seq=%u ack=%u wnd=%u ctl=", utcp, dir, hdr.src, hdr.dst, hdr.seq, hdr.ack, hdr.wnd);
53         if(hdr.ctl & SYN)
54                 debug("SYN");
55         if(hdr.ctl & RST)
56                 debug("RST");
57         if(hdr.ctl & FIN)
58                 debug("FIN");
59         if(hdr.ctl & ACK)
60                 debug("ACK");
61
62         if(len > sizeof hdr) {
63                 debug(" data=");
64                 for(int i = sizeof hdr; i < len; i++) {
65                         const char *data = pkt;
66                         debug("%c", data[i] >= 32 ? data[i] : '.');
67                 }
68         }
69
70         debug("\n");
71 }
72 #else
73 #define debug(...)
74 #define print_packet(...)
75 #endif
76
77 static void set_state(struct utcp_connection *c, enum state state) {
78         c->state = state;
79         if(state == ESTABLISHED)
80                 timerclear(&c->conn_timeout);
81         debug("%p new state: %s\n", c->utcp, strstate[state]);
82 }
83
84 static inline void list_connections(struct utcp *utcp) {
85         debug("%p has %d connections:\n", utcp, utcp->nconnections);
86         for(int i = 0; i < utcp->nconnections; i++)
87                 debug("  %u -> %u state %s\n", utcp->connections[i]->src, utcp->connections[i]->dst, strstate[utcp->connections[i]->state]);
88 }
89
90 static int32_t seqdiff(uint32_t a, uint32_t b) {
91         return a - b;
92 }
93
94 // Connections are stored in a sorted list.
95 // This gives O(log(N)) lookup time, O(N log(N)) insertion time and O(N) deletion time.
96
97 static int compare(const void *va, const void *vb) {
98         const struct utcp_connection *a = *(struct utcp_connection **)va;
99         const struct utcp_connection *b = *(struct utcp_connection **)vb;
100         if(!a->src || !b->src)
101                 abort();
102         int c = (int)a->src - (int)b->src;
103         if(c)
104                 return c;
105         c = (int)a->dst - (int)b->dst;
106         return c;
107 }
108
109 static struct utcp_connection *find_connection(const struct utcp *utcp, uint16_t src, uint16_t dst) {
110         if(!utcp->nconnections)
111                 return NULL;
112         struct utcp_connection key = {
113                 .src = src,
114                 .dst = dst,
115         }, *keyp = &key;
116         struct utcp_connection **match = bsearch(&keyp, utcp->connections, utcp->nconnections, sizeof *utcp->connections, compare);
117         return match ? *match : NULL;
118 }
119
120 static void free_connection(struct utcp_connection *c) {
121         struct utcp *utcp = c->utcp;
122         struct utcp_connection **cp = bsearch(&c, utcp->connections, utcp->nconnections, sizeof *utcp->connections, compare);
123         if(!cp)
124                 abort();
125
126         int i = cp - utcp->connections;
127         memmove(cp + i, cp + i + 1, (utcp->nconnections - i - 1) * sizeof *cp);
128         utcp->nconnections--;
129
130         free(c->sndbuf);
131         free(c);
132 }
133
134 static struct utcp_connection *allocate_connection(struct utcp *utcp, uint16_t src, uint16_t dst) {
135         // Check whether this combination of src and dst is free
136
137         if(src) {
138                 if(find_connection(utcp, src, dst)) {
139                         errno = EADDRINUSE;
140                         return NULL;
141                 }
142         } else { // If src == 0, generate a random port number with the high bit set
143                 if(utcp->nconnections >= 32767) {
144                         errno = ENOMEM;
145                         return NULL;
146                 }
147                 src = rand() | 0x8000;
148                 while(find_connection(utcp, src, dst))
149                         src++;
150         }
151
152         // Allocate memory for the new connection
153
154         if(utcp->nconnections >= utcp->nallocated) {
155                 if(!utcp->nallocated)
156                         utcp->nallocated = 4;
157                 else
158                         utcp->nallocated *= 2;
159                 struct utcp_connection **new_array = realloc(utcp->connections, utcp->nallocated * sizeof *utcp->connections);
160                 if(!new_array)
161                         return NULL;
162                 utcp->connections = new_array;
163         }
164
165         struct utcp_connection *c = calloc(1, sizeof *c);
166         if(!c)
167                 return NULL;
168
169         c->sndbufsize = DEFAULT_SNDBUFSIZE;
170         c->maxsndbufsize = DEFAULT_MAXSNDBUFSIZE;
171         c->sndbuf = malloc(c->sndbufsize);
172         if(!c->sndbuf) {
173                 free(c);
174                 return NULL;
175         }
176
177         // Fill in the details
178
179         c->src = src;
180         c->dst = dst;
181         c->snd.iss = rand();
182         c->snd.una = c->snd.iss;
183         c->snd.nxt = c->snd.iss + 1;
184         c->rcv.wnd = utcp->mtu;
185         c->snd.last = c->snd.nxt;
186         c->snd.cwnd = utcp->mtu;
187         c->utcp = utcp;
188
189         // Add it to the sorted list of connections
190
191         utcp->connections[utcp->nconnections++] = c;
192         qsort(utcp->connections, utcp->nconnections, sizeof *utcp->connections, compare);
193
194         return c;
195 }
196
197 struct utcp_connection *utcp_connect(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv) {
198         struct utcp_connection *c = allocate_connection(utcp, 0, dst);
199         if(!c)
200                 return NULL;
201
202         c->recv = recv;
203
204         struct hdr hdr;
205
206         hdr.src = c->src;
207         hdr.dst = c->dst;
208         hdr.seq = c->snd.iss;
209         hdr.ack = 0;
210         hdr.wnd = c->rcv.wnd;
211         hdr.ctl = SYN;
212         hdr.aux = 0;
213
214         set_state(c, SYN_SENT);
215
216         print_packet(utcp, "send", &hdr, sizeof hdr);
217         utcp->send(utcp, &hdr, sizeof hdr);
218
219         gettimeofday(&c->conn_timeout, NULL);
220         c->conn_timeout.tv_sec += utcp->timeout;
221
222         return c;
223 }
224
225 void utcp_accept(struct utcp_connection *c, utcp_recv_t recv, void *priv) {
226         if(c->reapable || c->state != SYN_RECEIVED) {
227                 debug("Error: accept() called on invalid connection %p in state %s\n", c, strstate[c->state]);
228                 return;
229         }
230
231         debug("%p accepted, %p %p\n", c, recv, priv);
232         c->recv = recv;
233         c->priv = priv;
234         set_state(c, ESTABLISHED);
235 }
236
237 static void ack(struct utcp_connection *c, bool sendatleastone) {
238         int32_t left = seqdiff(c->snd.last, c->snd.nxt);
239         int32_t cwndleft = c->snd.cwnd - seqdiff(c->snd.nxt, c->snd.una);
240         char *data = c->sndbuf + seqdiff(c->snd.nxt, c->snd.una);
241
242         fprintf(stderr, "ack, left=%d, cwndleft=%d, sendatleastone=%d\n", left, cwndleft, sendatleastone);
243         if(left < 0)
244                 abort();
245
246         if(cwndleft <= 0)
247                 cwndleft = 0;
248
249         if(cwndleft < left)
250                 left = cwndleft;
251
252         if(!left && !sendatleastone)
253                 return;
254
255         struct {
256                 struct hdr hdr;
257                 char data[c->utcp->mtu];
258         } pkt;
259
260         pkt.hdr.src = c->src;
261         pkt.hdr.dst = c->dst;
262         pkt.hdr.ack = c->rcv.nxt;
263         pkt.hdr.wnd = c->snd.wnd;
264         pkt.hdr.ctl = ACK;
265         pkt.hdr.aux = 0;
266
267         do {
268                 uint32_t seglen = left > c->utcp->mtu ? c->utcp->mtu : left;
269                 pkt.hdr.seq = c->snd.nxt;
270
271                 memcpy(pkt.data, data, seglen);
272
273                 c->snd.nxt += seglen;
274                 data += seglen;
275                 left -= seglen;
276
277                 if(c->state != ESTABLISHED && !left && seglen) {
278                         switch(c->state) {
279                         case FIN_WAIT_1:
280                         case CLOSING:
281                                 seglen--;
282                                 pkt.hdr.ctl |= FIN;
283                                 break;
284                         default:
285                                 break;
286                         }
287                 }
288
289                 print_packet(c->utcp, "send", &pkt, sizeof pkt.hdr + seglen);
290                 c->utcp->send(c->utcp, &pkt, sizeof pkt.hdr + seglen);
291         } while(left);
292 }
293
294 ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) {
295         if(c->reapable) {
296                 debug("Error: send() called on closed connection %p\n", c);
297                 errno = EBADF;
298                 return -1;
299         }
300
301         switch(c->state) {
302         case CLOSED:
303         case LISTEN:
304         case SYN_SENT:
305         case SYN_RECEIVED:
306                 debug("Error: send() called on unconnected connection %p\n", c);
307                 errno = ENOTCONN;
308                 return -1;
309         case ESTABLISHED:
310         case CLOSE_WAIT:
311                 break;
312         case FIN_WAIT_1:
313         case FIN_WAIT_2:
314         case CLOSING:
315         case LAST_ACK:
316         case TIME_WAIT:
317                 debug("Error: send() called on closing connection %p\n", c);
318                 errno = EPIPE;
319                 return -1;
320         }
321
322         // Add data to send buffer
323
324         if(!len)
325                 return 0;
326
327         if(!data) {
328                 errno = EFAULT;
329                 return -1;
330         }
331
332         uint32_t bufused = seqdiff(c->snd.nxt, c->snd.una);
333
334         /* Check our send buffer.
335          * - If it's big enough, just put the data in there.
336          * - If not, decide whether to enlarge if possible.
337          * - Cap len so it doesn't overflow our buffer.
338          */
339
340         if(len > c->sndbufsize - bufused && c->sndbufsize < c->maxsndbufsize) {
341                 uint32_t newbufsize;
342                 if(c->sndbufsize > c->maxsndbufsize / 2)
343                         newbufsize = c->maxsndbufsize;
344                 else
345                         newbufsize = c->sndbufsize * 2;
346                 if(bufused + len > newbufsize) {
347                         if(bufused + len > c->maxsndbufsize)
348                                 newbufsize = c->maxsndbufsize;
349                         else
350                                 newbufsize = bufused + len;
351                 }
352                 char *newbuf = realloc(c->sndbuf, newbufsize);
353                 if(newbuf) {
354                         c->sndbuf = newbuf;
355                         c->sndbufsize = newbufsize;
356                 }
357         }
358
359         if(len > c->sndbufsize - bufused)
360                 len = c->sndbufsize - bufused;
361
362         if(!len) {
363                 errno == EWOULDBLOCK;
364                 return 0;
365         }
366
367         memcpy(c->sndbuf + bufused, data, len);
368         c->snd.last += len;
369
370         ack(c, false);
371         return len;
372 }
373
374 static void swap_ports(struct hdr *hdr) {
375         uint16_t tmp = hdr->src;
376         hdr->src = hdr->dst;
377         hdr->dst = tmp;
378 }
379
380 int utcp_recv(struct utcp *utcp, const void *data, size_t len) {
381         if(!utcp) {
382                 errno = EFAULT;
383                 return -1;
384         }
385
386         if(!len)
387                 return 0;
388
389         if(!data) {
390                 errno = EFAULT;
391                 return -1;
392         }
393
394         print_packet(utcp, "recv", data, len);
395
396         // Drop packets smaller than the header
397
398         struct hdr hdr;
399         if(len < sizeof hdr) {
400                 errno = EBADMSG;
401                 return -1;
402         }
403
404         // Make a copy from the potentially unaligned data to a struct hdr
405
406         memcpy(&hdr, data, sizeof hdr);
407         data += sizeof hdr;
408         len -= sizeof hdr;
409
410         // Drop packets with an unknown CTL flag
411
412         if(hdr.ctl & ~(SYN | ACK | RST | FIN)) {
413                 errno = EBADMSG;
414                 return -1;
415         }
416
417         // Try to match the packet to an existing connection
418
419         struct utcp_connection *c = find_connection(utcp, hdr.dst, hdr.src);
420
421         // Is it for a new connection?
422
423         if(!c) {
424                 // Ignore RST packets
425
426                 if(hdr.ctl & RST)
427                         return 0;
428
429                 // Is it a SYN packet and are we LISTENing?
430
431                 if(hdr.ctl & SYN && !(hdr.ctl & ACK) && utcp->accept) {
432                         // If we don't want to accept it, send a RST back
433                         if((utcp->pre_accept && !utcp->pre_accept(utcp, hdr.dst))) {
434                                 len = 1;
435                                 goto reset;
436                         }
437
438                         // Try to allocate memory, otherwise send a RST back
439                         c = allocate_connection(utcp, hdr.dst, hdr.src);
440                         if(!c) {
441                                 len = 1;
442                                 goto reset;
443                         }
444
445                         // Return SYN+ACK, go to SYN_RECEIVED state
446                         c->snd.wnd = hdr.wnd;
447                         c->rcv.irs = hdr.seq;
448                         c->rcv.nxt = c->rcv.irs + 1;
449                         set_state(c, SYN_RECEIVED);
450
451                         hdr.dst = c->dst;
452                         hdr.src = c->src;
453                         hdr.ack = c->rcv.irs + 1;
454                         hdr.seq = c->snd.iss;
455                         hdr.ctl = SYN | ACK;
456                         print_packet(c->utcp, "send", &hdr, sizeof hdr);
457                         utcp->send(utcp, &hdr, sizeof hdr);
458                 } else {
459                         // No, we don't want your packets, send a RST back
460                         len = 1;
461                         goto reset;
462                 }
463
464                 return 0;
465         }
466
467         debug("%p state %s\n", c->utcp, strstate[c->state]);
468
469         // In case this is for a CLOSED connection, ignore the packet.
470         // TODO: make it so incoming packets can never match a CLOSED connection.
471
472         if(c->state == CLOSED)
473                 return 0;
474
475         // It is for an existing connection.
476
477         // 1. Drop invalid packets.
478
479         // 1a. Drop packets that should not happen in our current state.
480
481         switch(c->state) {
482         case SYN_SENT:
483         case SYN_RECEIVED:
484         case ESTABLISHED:
485         case FIN_WAIT_1:
486         case FIN_WAIT_2:
487         case CLOSE_WAIT:
488         case CLOSING:
489         case LAST_ACK:
490         case TIME_WAIT:
491                 break;
492         default:
493                 abort();
494         }
495
496         // 1b. Drop packets with a sequence number not in our receive window.
497
498         bool acceptable;
499
500         if(c->state == SYN_SENT)
501                 acceptable = true;
502
503         // TODO: handle packets overlapping c->rcv.nxt.
504 #if 0
505         // Only use this when accepting out-of-order packets.
506         else if(len == 0)
507                 if(c->rcv.wnd == 0)
508                         acceptable = hdr.seq == c->rcv.nxt;
509                 else
510                         acceptable = (seqdiff(hdr.seq, c->rcv.nxt) >= 0 && seqdiff(hdr.seq, c->rcv.nxt + c->rcv.wnd) < 0);
511         else
512                 if(c->rcv.wnd == 0)
513                         // We don't accept data when the receive window is zero.
514                         acceptable = false;
515                 else
516                         // Both start and end of packet must be within the receive window
517                         acceptable = (seqdiff(hdr.seq, c->rcv.nxt) >= 0 && seqdiff(hdr.seq, c->rcv.nxt + c->rcv.wnd) < 0)
518                                 || (seqdiff(hdr.seq + len + 1, c->rcv.nxt) >= 0 && seqdiff(hdr.seq + len - 1, c->rcv.nxt + c->rcv.wnd) < 0);
519 #else
520         if(c->state != SYN_SENT)
521                 acceptable = hdr.seq == c->rcv.nxt;
522 #endif
523
524         if(!acceptable) {
525                 debug("Packet not acceptable, %u  <= %u + %zu < %u\n", c->rcv.nxt, hdr.seq, len, c->rcv.nxt + c->rcv.wnd);
526                 // Ignore unacceptable RST packets.
527                 if(hdr.ctl & RST)
528                         return 0;
529                 // Otherwise, send an ACK back in the hope things improve.
530                 goto ack;
531         }
532
533         c->snd.wnd = hdr.wnd; // TODO: move below
534
535         // 1c. Drop packets with an invalid ACK.
536         // ackno should not roll back, and it should also not be bigger than snd.nxt.
537
538         if(hdr.ctl & ACK && (seqdiff(hdr.ack, c->snd.nxt) > 0 || seqdiff(hdr.ack, c->snd.una) < 0)) {
539                 debug("Packet ack seqno out of range, %u %u %u\n", hdr.ack, c->snd.una, c->snd.nxt);
540                 // Ignore unacceptable RST packets.
541                 if(hdr.ctl & RST)
542                         return 0;
543                 goto reset;
544         }
545
546         // 2. Handle RST packets
547
548         if(hdr.ctl & RST) {
549                 switch(c->state) {
550                 case SYN_SENT:
551                         if(!(hdr.ctl & ACK))
552                                 return 0;
553                         // The peer has refused our connection.
554                         set_state(c, CLOSED);
555                         errno = ECONNREFUSED;
556                         if(c->recv)
557                                 c->recv(c, NULL, 0);
558                         return 0;
559                 case SYN_RECEIVED:
560                         if(hdr.ctl & ACK)
561                                 return 0;
562                         // We haven't told the application about this connection yet. Silently delete.
563                         free_connection(c);
564                         return 0;
565                 case ESTABLISHED:
566                 case FIN_WAIT_1:
567                 case FIN_WAIT_2:
568                 case CLOSE_WAIT:
569                         if(hdr.ctl & ACK)
570                                 return 0;
571                         // The peer has aborted our connection.
572                         set_state(c, CLOSED);
573                         errno = ECONNRESET;
574                         if(c->recv)
575                                 c->recv(c, NULL, 0);
576                         return 0;
577                 case CLOSING:
578                 case LAST_ACK:
579                 case TIME_WAIT:
580                         if(hdr.ctl & ACK)
581                                 return 0;
582                         // As far as the application is concerned, the connection has already been closed.
583                         // If it has called utcp_close() already, we can immediately free this connection.
584                         if(c->reapable) {
585                                 free_connection(c);
586                                 return 0;
587                         }
588                         // Otherwise, immediately move to the CLOSED state.
589                         set_state(c, CLOSED);
590                         return 0;
591                 default:
592                         abort();
593                 }
594         }
595
596         // 3. Advance snd.una
597
598         uint32_t advanced = seqdiff(hdr.ack, c->snd.una);
599         c->snd.una = hdr.ack;
600
601         if(advanced) {
602                 debug("%p advanced %u\n", utcp, advanced);
603                 // Make room in the send buffer.
604                 // TODO: try to avoid memmoving too much. Circular buffer?
605                 uint32_t left = seqdiff(c->snd.nxt, hdr.ack);
606                 if(left)
607                         memmove(c->sndbuf, c->sndbuf + advanced, left);
608                 c->dupack = 0;
609                 c->snd.cwnd += utcp->mtu;
610                 if(c->snd.cwnd > c->maxsndbufsize)
611                         c->snd.cwnd = c->maxsndbufsize;
612                 debug("%p increasing cwnd to %u\n", utcp, c->snd.cwnd);
613
614                 // Check if we have sent a FIN that is now ACKed.
615                 switch(c->state) {
616                 case FIN_WAIT_1:
617                         if(c->snd.una == c->snd.last)
618                                 set_state(c, FIN_WAIT_2);
619                         break;
620                 case CLOSING:
621                         if(c->snd.una == c->snd.last) {
622                                 gettimeofday(&c->conn_timeout, NULL);
623                                 c->conn_timeout.tv_sec += 60;
624                                 set_state(c, TIME_WAIT);
625                         }
626                         break;
627                 default:
628                         break;
629                 }
630         } else {
631                 if(!len) {
632                         c->dupack++;
633                         if(c->dupack >= 3) {
634                                 debug("Triplicate ACK\n");
635                                 abort();
636                         }
637                 }
638         }
639
640         // 4. Update timers
641
642         if(advanced) {
643                 timerclear(&c->conn_timeout); // It should be set anew in utcp_timeout() if c->snd.una != c->snd.nxt.
644                 if(c->snd.una == c->snd.nxt)
645                         timerclear(&c->rtrx_timeout);
646         }
647
648         // 5. Process SYN stuff
649
650         if(hdr.ctl & SYN) {
651                 switch(c->state) {
652                 case SYN_SENT:
653                         // This is a SYNACK. It should always have ACKed the SYN.
654                         if(!advanced)
655                                 goto reset;
656                         c->rcv.irs = hdr.seq;
657                         c->rcv.nxt = hdr.seq;
658                         set_state(c, ESTABLISHED);
659                         // TODO: notify application of this somehow.
660                         break;
661                 case SYN_RECEIVED:
662                 case ESTABLISHED:
663                 case FIN_WAIT_1:
664                 case FIN_WAIT_2:
665                 case CLOSE_WAIT:
666                 case CLOSING:
667                 case LAST_ACK:
668                 case TIME_WAIT:
669                         // Ehm, no. We should never receive a second SYN.
670                         goto reset;
671                 default:
672                         abort();
673                 }
674
675                 // SYN counts as one sequence number
676                 c->rcv.nxt++;
677         }
678
679         // 6. Process new data
680
681         if(c->state == SYN_RECEIVED) {
682                 // This is the ACK after the SYNACK. It should always have ACKed the SYNACK.
683                 if(!advanced)
684                         goto reset;
685
686                 // Are we still LISTENing?
687                 if(utcp->accept)
688                         utcp->accept(c, c->src);
689
690                 if(c->state != ESTABLISHED) {
691                         set_state(c, CLOSED);
692                         c->reapable = true;
693                         goto reset;
694                 }
695         }
696
697         if(len) {
698                 switch(c->state) {
699                 case SYN_SENT:
700                 case SYN_RECEIVED:
701                         // This should never happen.
702                         abort();
703                 case ESTABLISHED:
704                 case FIN_WAIT_1:
705                 case FIN_WAIT_2:
706                         break;
707                 case CLOSE_WAIT:
708                 case CLOSING:
709                 case LAST_ACK:
710                 case TIME_WAIT:
711                         // Ehm no, We should never receive more data after a FIN.
712                         goto reset;
713                 default:
714                         abort();
715                 }
716
717                 int rxd;
718
719                 if(c->recv) {
720                         rxd = c->recv(c, data, len);
721                         if(rxd < 0)
722                                 rxd = 0;
723                         else if(rxd > len)
724                                 rxd = len; // Bad application, bad!
725                 } else {
726                         rxd = len;
727                 }
728
729                 c->rcv.nxt += len;
730         }
731
732         // 7. Process FIN stuff
733
734         if(hdr.ctl & FIN) {
735                 switch(c->state) {
736                 case SYN_SENT:
737                 case SYN_RECEIVED:
738                         // This should never happen.
739                         abort();
740                 case ESTABLISHED:
741                         set_state(c, CLOSE_WAIT);
742                         break;
743                 case FIN_WAIT_1:
744                         set_state(c, CLOSING);
745                         break;
746                 case FIN_WAIT_2:
747                         gettimeofday(&c->conn_timeout, NULL);
748                         c->conn_timeout.tv_sec += 60;
749                         set_state(c, TIME_WAIT);
750                         break;
751                 case CLOSE_WAIT:
752                 case CLOSING:
753                 case LAST_ACK:
754                 case TIME_WAIT:
755                         // Ehm, no. We should never receive a second FIN.
756                         goto reset;
757                 default:
758                         abort();
759                 }
760
761                 // FIN counts as one sequence number
762                 c->rcv.nxt++;
763                 len++;
764
765                 // Inform the application that the peer closed the connection.
766                 if(c->recv) {
767                         errno = 0;
768                         c->recv(c, NULL, 0);
769                 }
770         }
771
772         if(!len && !advanced)
773                 return 0;
774
775         if(!len && !(hdr.ctl & SYN) && !(hdr.ctl & FIN))
776                 return 0;
777
778 ack:
779         ack(c, true);
780         return 0;
781
782 reset:
783         swap_ports(&hdr);
784         hdr.wnd = 0;
785         if(hdr.ctl & ACK) {
786                 hdr.seq = hdr.ack;
787                 hdr.ctl = RST;
788         } else {
789                 hdr.ack = hdr.seq + len;
790                 hdr.seq = 0;
791                 hdr.ctl = RST | ACK;
792         }
793         print_packet(utcp, "send", &hdr, sizeof hdr);
794         utcp->send(utcp, &hdr, sizeof hdr);
795         return 0;
796
797 }
798
799 int utcp_shutdown(struct utcp_connection *c, int dir) {
800         debug("%p shutdown %d\n", c->utcp, dir);
801         if(!c) {
802                 errno = EFAULT;
803                 return -1;
804         }
805
806         if(c->reapable) {
807                 debug("Error: shutdown() called on closed connection %p\n", c);
808                 errno = EBADF;
809                 return -1;
810         }
811
812         // TODO: handle dir
813
814         switch(c->state) {
815         case CLOSED:
816                 return 0;
817         case LISTEN:
818         case SYN_SENT:
819                 set_state(c, CLOSED);
820                 return 0;
821
822         case SYN_RECEIVED:
823         case ESTABLISHED:
824                 set_state(c, FIN_WAIT_1);
825                 break;
826         case FIN_WAIT_1:
827         case FIN_WAIT_2:
828                 return 0;
829         case CLOSE_WAIT:
830                 set_state(c, CLOSING);
831                 break;
832
833         case CLOSING:
834         case LAST_ACK:
835         case TIME_WAIT:
836                 return 0;
837         }
838
839         c->snd.last++;
840
841         ack(c, false);
842         return 0;
843 }
844
845 int utcp_close(struct utcp_connection *c) {
846         if(utcp_shutdown(c, SHUT_RDWR))
847                 return -1;
848         c->reapable = true;
849         return 0;
850 }
851
852 int utcp_abort(struct utcp_connection *c) {
853         if(!c) {
854                 errno = EFAULT;
855                 return -1;
856         }
857
858         if(c->reapable) {
859                 debug("Error: abort() called on closed connection %p\n", c);
860                 errno = EBADF;
861                 return -1;
862         }
863
864         c->reapable = true;
865
866         switch(c->state) {
867         case CLOSED:
868                 return 0;
869         case LISTEN:
870         case SYN_SENT:
871         case CLOSING:
872         case LAST_ACK:
873         case TIME_WAIT:
874                 set_state(c, CLOSED);
875                 return 0;
876
877         case SYN_RECEIVED:
878         case ESTABLISHED:
879         case FIN_WAIT_1:
880         case FIN_WAIT_2:
881         case CLOSE_WAIT:
882                 set_state(c, CLOSED);
883                 break;
884         }
885
886         // Send RST
887
888         struct hdr hdr;
889
890         hdr.src = c->src;
891         hdr.dst = c->dst;
892         hdr.seq = c->snd.nxt;
893         hdr.ack = 0;
894         hdr.wnd = 0;
895         hdr.ctl = RST;
896
897         print_packet(c->utcp, "send", &hdr, sizeof hdr);
898         c->utcp->send(c->utcp, &hdr, sizeof hdr);
899         return 0;
900 }
901
902 static void retransmit(struct utcp_connection *c) {
903         if(c->state == CLOSED || c->snd.nxt == c->snd.una)
904                 return;
905
906         struct utcp *utcp = c->utcp;
907
908         struct {
909                 struct hdr hdr;
910                 char data[c->utcp->mtu];
911         } pkt;
912
913         pkt.hdr.src = c->src;
914         pkt.hdr.dst = c->dst;
915
916         switch(c->state) {
917                 case LISTEN:
918                         // TODO: this should not happen
919                         break;
920
921                 case SYN_SENT:
922                         pkt.hdr.seq = c->snd.iss;
923                         pkt.hdr.ack = 0;
924                         pkt.hdr.wnd = c->rcv.wnd;
925                         pkt.hdr.ctl = SYN;
926                         print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr);
927                         utcp->send(utcp, &pkt, sizeof pkt.hdr);
928                         break;
929
930                 case SYN_RECEIVED:
931                         pkt.hdr.seq = c->snd.nxt;
932                         pkt.hdr.ack = c->rcv.nxt;
933                         pkt.hdr.ctl = SYN | ACK;
934                         print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr);
935                         utcp->send(utcp, &pkt, sizeof pkt.hdr);
936                         break;
937
938                 case ESTABLISHED:
939                 case FIN_WAIT_1:
940                         pkt.hdr.seq = c->snd.una;
941                         pkt.hdr.ack = c->rcv.nxt;
942                         pkt.hdr.ctl = ACK;
943                         uint32_t len = seqdiff(c->snd.nxt, c->snd.una);
944                         if(c->state == FIN_WAIT_1)
945                                 len--;
946                         if(len > utcp->mtu)
947                                 len = utcp->mtu;
948                         else {
949                                 if(c->state == FIN_WAIT_1)
950                                         pkt.hdr.ctl |= FIN;
951                         }
952                         memcpy(pkt.data, c->sndbuf, len);
953                         print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr + len);
954                         utcp->send(utcp, &pkt, sizeof pkt.hdr + len);
955                         break;
956
957                 default:
958                         // TODO: implement
959                         abort();
960         }
961 }
962
963 /* Handle timeouts.
964  * One call to this function will loop through all connections,
965  * checking if something needs to be resent or not.
966  * The return value is the time to the next timeout in milliseconds,
967  * or maybe a negative value if the timeout is infinite.
968  */
969 int utcp_timeout(struct utcp *utcp) {
970         struct timeval now;
971         gettimeofday(&now, NULL);
972         struct timeval next = {now.tv_sec + 3600, now.tv_usec};
973
974         for(int i = 0; i < utcp->nconnections; i++) {
975                 struct utcp_connection *c = utcp->connections[i];
976                 if(!c)
977                         continue;
978
979                 if(c->state == CLOSED) {
980                         if(c->reapable) {
981                                 debug("Reaping %p\n", c);
982                                 free_connection(c);
983                                 i--;
984                         }
985                         continue;
986                 }
987
988                 if(timerisset(&c->conn_timeout) && timercmp(&c->conn_timeout, &now, <)) {
989                         errno = ETIMEDOUT;
990                         c->state = CLOSED;
991                         if(c->recv)
992                                 c->recv(c, NULL, 0);
993                         continue;
994                 }
995
996                 if(timerisset(&c->rtrx_timeout) && timercmp(&c->rtrx_timeout, &now, <)) {
997                         retransmit(c);
998                 }
999
1000                 if(timerisset(&c->conn_timeout) && timercmp(&c->conn_timeout, &next, <))
1001                         next = c->conn_timeout;
1002
1003                 if(c->snd.nxt != c->snd.una) {
1004                         c->rtrx_timeout = now;
1005                         c->rtrx_timeout.tv_sec++;
1006                 } else {
1007                         timerclear(&c->rtrx_timeout);
1008                 }
1009
1010                 if(timerisset(&c->rtrx_timeout) && timercmp(&c->rtrx_timeout, &next, <))
1011                         next = c->rtrx_timeout;
1012         }
1013
1014         struct timeval diff;
1015         timersub(&next, &now, &diff);
1016         if(diff.tv_sec < 0)
1017                 return 0;
1018         return diff.tv_sec * 1000 + diff.tv_usec / 1000;
1019 }
1020
1021 struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_send_t send, void *priv) {
1022         struct utcp *utcp = calloc(1, sizeof *utcp);
1023         if(!utcp)
1024                 return NULL;
1025
1026         if(!send) {
1027                 errno = EFAULT;
1028                 return NULL;
1029         }
1030
1031         utcp->accept = accept;
1032         utcp->pre_accept = pre_accept;
1033         utcp->send = send;
1034         utcp->priv = priv;
1035         utcp->mtu = 1000;
1036         utcp->timeout = 60;
1037
1038         return utcp;
1039 }
1040
1041 void utcp_exit(struct utcp *utcp) {
1042         if(!utcp)
1043                 return;
1044         for(int i = 0; i < utcp->nconnections; i++) {
1045                 if(!utcp->connections[i]->reapable)
1046                         debug("Warning, freeing unclosed connection %p\n", utcp->connections[i]);
1047                 free(utcp->connections[i]->sndbuf);
1048                 free(utcp->connections[i]);
1049         }
1050         free(utcp->connections);
1051         free(utcp);
1052 }
1053
1054 uint16_t utcp_get_mtu(struct utcp *utcp) {
1055         return utcp->mtu;
1056 }
1057
1058 void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) {
1059         // TODO: handle overhead of the header
1060         utcp->mtu = mtu;
1061 }
1062
1063 int utcp_get_user_timeout(struct utcp *u) {
1064         return u->timeout;
1065 }
1066
1067 void utcp_set_user_timeout(struct utcp *u, int timeout) {
1068         u->timeout = timeout;
1069 }
1070
1071 size_t utcp_get_sndbuf(struct utcp_connection *c) {
1072         return c->maxsndbufsize;
1073 }
1074
1075 void utcp_set_sndbuf(struct utcp_connection *c, size_t size) {
1076         c->maxsndbufsize = size;
1077         if(c->maxsndbufsize != size)
1078                 c->maxsndbufsize = -1;
1079 }
1080
1081 bool utcp_get_nodelay(struct utcp_connection *c) {
1082         return c->nodelay;
1083 }
1084
1085 void utcp_set_nodelay(struct utcp_connection *c, bool nodelay) {
1086         c->nodelay = nodelay;
1087 }
1088
1089 bool utcp_get_keepalive(struct utcp_connection *c) {
1090         return c->keepalive;
1091 }
1092
1093 void utcp_set_keepalive(struct utcp_connection *c, bool keepalive) {
1094         c->keepalive = keepalive;
1095 }
1096
1097 size_t utcp_get_outq(struct utcp_connection *c) {
1098         return seqdiff(c->snd.nxt, c->snd.una);
1099 }