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