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