Add more resilient TCP listening function.
[doldaconnect.git] / daemon / net.c
1 /*
2  *  Dolda Connect - Modular multiuser Direct Connect-style client
3  *  Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com)
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
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 /* XXX: Implement SOCKS proxyability */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <string.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <sys/poll.h>
32 #include <arpa/inet.h>
33 #include <netinet/in.h>
34 #include <netdb.h>
35 #include <sys/signal.h>
36 #include <printf.h>
37 #ifdef HAVE_LINUX_SOCKIOS_H
38 #include <linux/sockios.h>
39 #endif
40 #include <errno.h>
41 #include <net/if.h>
42
43 #include "conf.h"
44 #include "net.h"
45 #include "module.h"
46 #include "log.h"
47 #include "utils.h"
48 #include "sysevents.h"
49
50 static struct configvar myvars[] =
51 {
52     /* 0 = Direct mode, 1 = Passive mode, 2 = SOCKS proxy */
53     {CONF_VAR_INT, "mode", {.num = 0}},
54     {CONF_VAR_BOOL, "reuseaddr", {.num = 0}},
55     /* Only for direct mode */
56     {CONF_VAR_IPV4, "visibleipv4", {.ipv4 = {0}}},
57     {CONF_VAR_STRING, "publicif", {.str = L""}},
58     /* Diffserv should be supported on IPv4, too, but I don't know the
59      * API to do that. */
60     {CONF_VAR_INT, "diffserv-mincost", {.num = 0}},
61     {CONF_VAR_INT, "diffserv-maxrel", {.num = 0}},
62     {CONF_VAR_INT, "diffserv-maxtp", {.num = 0}},
63     {CONF_VAR_INT, "diffserv-mindelay", {.num = 0}},
64     {CONF_VAR_END}
65 };
66
67 static struct socket *sockets = NULL;
68 int numsocks = 0;
69
70 /* XXX: Get autoconf for all this... */
71 int getpublicaddr(int af, struct sockaddr **addr, socklen_t *lenbuf)
72 {
73     struct sockaddr_in *ipv4;
74     struct configvar *var;
75     void *bufend;
76     int sock;
77     struct ifconf conf;
78     struct ifreq *ifr, req;
79     char *pif;
80     
81     if(af == AF_INET)
82     {
83         var = confgetvar("net", "visibleipv4");
84         if(var->val.ipv4.s_addr != 0)
85         {
86             ipv4 = smalloc(sizeof(*ipv4));
87             ipv4->sin_family = AF_INET;
88             ipv4->sin_addr.s_addr = var->val.ipv4.s_addr;
89             *addr = (struct sockaddr *)ipv4;
90             *lenbuf = sizeof(*ipv4);
91             return(0);
92         }
93         if((pif = icswcstombs(confgetstr("net", "publicif"), NULL, NULL)) == NULL)
94         {
95             flog(LOG_ERR, "could not convert net.publicif into local charset: %s", strerror(errno));
96             return(-1);
97         }
98         if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
99             return(-1);
100         conf.ifc_buf = smalloc(conf.ifc_len = 65536);
101         if(ioctl(sock, SIOCGIFCONF, &conf) < 0)
102         {
103             free(conf.ifc_buf);
104             close(sock);
105             return(-1);
106         }
107         bufend = ((char *)conf.ifc_buf) + conf.ifc_len;
108         ipv4 = NULL;
109         for(ifr = conf.ifc_ifcu.ifcu_req; (void *)ifr < bufend; ifr++)
110         {
111             memset(&req, 0, sizeof(req));
112             memcpy(req.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
113             if(ioctl(sock, SIOCGIFFLAGS, &req) < 0)
114             {
115                 free(conf.ifc_buf);
116                 close(sock);
117                 return(-1);
118             }
119             if(!(req.ifr_flags & IFF_UP))
120                 continue;
121             if(ifr->ifr_addr.sa_family == AF_INET)
122             {
123                 if(ntohl(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr) == 0x7f000001)
124                     continue;
125                 if(ipv4 == NULL)
126                 {
127                     ipv4 = smalloc(sizeof(*ipv4));
128                     memcpy(ipv4, &ifr->ifr_addr, sizeof(ifr->ifr_addr));
129                 } else {
130                     free(ipv4);
131                     free(conf.ifc_buf);
132                     flog(LOG_WARNING, "could not locate an unambiguous interface for determining your public IP address - set net.publicif");
133                     errno = ENFILE; /* XXX: There's no appropriate one for this... */
134                     return(-1);
135                 }
136             }
137         }
138         free(conf.ifc_buf);
139         close(sock);
140         if(ipv4 != NULL)
141         {
142             *addr = (struct sockaddr *)ipv4;
143             *lenbuf = sizeof(*ipv4);
144             return(0);
145         }
146         errno = ENETDOWN;
147         return(-1);
148     }
149     errno = EPFNOSUPPORT;
150     return(-1);
151 }
152
153 static struct socket *newsock(int type)
154 {
155     struct socket *new;
156     
157     new = smalloc(sizeof(*new));
158     new->refcount = 2;
159     new->fd = -1;
160     new->isrealsocket = 1;
161     new->family = -1;
162     new->tos = 0;
163     new->type = type;
164     new->state = -1;
165     new->ignread = 0;
166     new->close = 0;
167     new->remote = NULL;
168     new->remotelen = 0;
169     switch(type)
170     {
171     case SOCK_STREAM:
172         new->outbuf.s.buf = NULL;
173         new->outbuf.s.bufsize = 0;
174         new->outbuf.s.datasize = 0;
175         new->inbuf.s.buf = NULL;
176         new->inbuf.s.bufsize = 0;
177         new->inbuf.s.datasize = 0;
178         break;
179     case SOCK_DGRAM:
180         new->outbuf.d.f = new->outbuf.d.l = NULL;
181         new->inbuf.d.f = new->inbuf.d.l = NULL;
182         break;
183     }
184     new->conncb = NULL;
185     new->errcb = NULL;
186     new->readcb = NULL;
187     new->writecb = NULL;
188     new->acceptcb = NULL;
189     new->next = sockets;
190     new->prev = NULL;
191     if(sockets != NULL)
192         sockets->prev = new;
193     sockets = new;
194     numsocks++;
195     return(new);
196 }
197
198 static struct socket *mksock(int domain, int type)
199 {
200     int fd;
201     struct socket *new;
202     
203     if((fd = socket(domain, type, 0)) < 0)
204     {
205         flog(LOG_CRIT, "could not create socket: %s", strerror(errno));
206         return(NULL);
207     }
208     new = newsock(type);
209     new->fd = fd;
210     new->family = domain;
211     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
212     return(new);
213 }
214
215 struct socket *wrapsock(int fd)
216 {
217     struct socket *new;
218     
219     new = newsock(SOCK_STREAM);
220     new->fd = fd;
221     new->state = SOCK_EST;
222     new->isrealsocket = 0;
223     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
224     return(new);
225 }
226
227 static void unlinksock(struct socket *sk)
228 {
229     if(sk->prev != NULL)
230         sk->prev->next = sk->next;
231     if(sk->next != NULL)
232         sk->next->prev = sk->prev;
233     if(sk == sockets)
234         sockets = sk->next;
235     putsock(sk);
236     numsocks--;
237 }
238
239 void getsock(struct socket *sk)
240 {
241     sk->refcount++;
242 }
243
244 void putsock(struct socket *sk)
245 {
246     struct dgrambuf *buf;
247     
248     if(--(sk->refcount) == 0)
249     {
250         switch(sk->type)
251         {
252         case SOCK_STREAM:
253             if(sk->outbuf.s.buf != NULL)
254                 free(sk->outbuf.s.buf);
255             if(sk->inbuf.s.buf != NULL)
256                 free(sk->inbuf.s.buf);
257             break;
258         case SOCK_DGRAM:
259             while((buf = sk->outbuf.d.f) != NULL)
260             {
261                 sk->outbuf.d.f = buf->next;
262                 free(buf->data);
263                 free(buf);
264             }
265             while((buf = sk->inbuf.d.f) != NULL)
266             {
267                 sk->inbuf.d.f = buf->next;
268                 free(buf->data);
269                 free(buf);
270             }
271             break;
272         }
273         if(sk->fd >= 0)
274             close(sk->fd);
275         if(sk->remote != NULL)
276             free(sk->remote);
277         free(sk);
278     }
279 }
280
281 void sockpushdata(struct socket *sk, void *buf, size_t size)
282 {
283     switch(sk->type)
284     {
285     case SOCK_STREAM:
286         sizebuf(&sk->inbuf.s.buf, &sk->inbuf.s.bufsize, sk->inbuf.s.datasize + size, 1, 1);
287         memmove(sk->inbuf.s.buf + size, sk->inbuf.s.buf, sk->inbuf.s.datasize);
288         memcpy(sk->inbuf.s.buf, buf, size);
289         sk->inbuf.s.datasize += size;
290         break;
291     case SOCK_DGRAM:
292         /* XXX */
293         break;
294     }
295     return;
296 }
297
298 void *sockgetinbuf(struct socket *sk, size_t *size)
299 {
300     void *buf;
301     struct dgrambuf *dbuf;
302     
303     switch(sk->type)
304     {
305     case SOCK_STREAM:
306         if((sk->inbuf.s.buf == NULL) || (sk->inbuf.s.datasize == 0))
307         {
308             *size = 0;
309             return(NULL);
310         }
311         buf = sk->inbuf.s.buf;
312         *size = sk->inbuf.s.datasize;
313         sk->inbuf.s.buf = NULL;
314         sk->inbuf.s.bufsize = sk->inbuf.s.datasize = 0;
315         return(buf);
316     case SOCK_DGRAM:
317         if((dbuf = sk->inbuf.d.f) == NULL)
318             return(NULL);
319         sk->inbuf.d.f = dbuf->next;
320         if(dbuf->next == NULL)
321             sk->inbuf.d.l = NULL;
322         buf = dbuf->data;
323         *size = dbuf->size;
324         free(dbuf->addr);
325         free(dbuf);
326         return(buf);
327     }
328     return(NULL);
329 }
330
331 static void sockrecv(struct socket *sk)
332 {
333     int ret, inq;
334     struct dgrambuf *dbuf;
335     
336     switch(sk->type)
337     {
338     case SOCK_STREAM:
339 #if defined(HAVE_LINUX_SOCKIOS_H) && defined(SIOCINQ)
340         /* SIOCINQ is Linux-specific AFAIK, but I really have no idea
341          * how to read the inqueue size on other OSs */
342         if(ioctl(sk->fd, SIOCINQ, &inq))
343         {
344             /* I don't really know what could go wrong here, so let's
345              * assume it's transient. */
346             flog(LOG_WARNING, "SIOCINQ return %s on socket %i, falling back to 2048 bytes", strerror(errno), sk->fd);
347             inq = 2048;
348         }
349 #else
350         inq = 2048;
351 #endif
352         if(inq > 65536)
353             inq = 65536;
354         sizebuf(&sk->inbuf.s.buf, &sk->inbuf.s.bufsize, sk->inbuf.s.datasize + inq, 1, 1);
355         ret = read(sk->fd, sk->inbuf.s.buf + sk->inbuf.s.datasize, inq);
356         if(ret < 0)
357         {
358             if((errno == EINTR) || (errno == EAGAIN))
359                 return;
360             if(sk->errcb != NULL)
361                 sk->errcb(sk, errno, sk->data);
362             closesock(sk);
363             return;
364         }
365         if(ret == 0)
366         {
367             if(sk->errcb != NULL)
368                 sk->errcb(sk, 0, sk->data);
369             closesock(sk);
370             return;
371         }
372         sk->inbuf.s.datasize += ret;
373         if(sk->readcb != NULL)
374             sk->readcb(sk, sk->data);
375         break;
376     case SOCK_DGRAM:
377         if(ioctl(sk->fd, SIOCINQ, &inq))
378         {
379             /* I don't really know what could go wrong here, so let's
380              * assume it's transient. */
381             flog(LOG_WARNING, "SIOCINQ return %s on socket %i", strerror(errno), sk->fd);
382             return;
383         }
384         dbuf = smalloc(sizeof(*dbuf));
385         dbuf->data = smalloc(inq);
386         dbuf->addr = smalloc(dbuf->addrlen = sizeof(struct sockaddr_storage));
387         ret = recvfrom(sk->fd, dbuf->data, inq, 0, dbuf->addr, &dbuf->addrlen);
388         if(ret < 0)
389         {
390             free(dbuf->addr);
391             free(dbuf->data);
392             free(dbuf);
393             if((errno == EINTR) || (errno == EAGAIN))
394                 return;
395             if(sk->errcb != NULL)
396                 sk->errcb(sk, errno, sk->data);
397             closesock(sk);
398             return;
399         }
400         /* On UDP/IPv[46], ret == 0 doesn't mean EOF (since UDP can't
401          * have EOF), but rather an empty packet. I don't know if any
402          * other potential DGRAM protocols might have an EOF
403          * condition, so let's play safe. */
404         if(ret == 0)
405         {
406             free(dbuf->addr);
407             free(dbuf->data);
408             free(dbuf);
409             if(!((sk->family == AF_INET) || (sk->family == AF_INET6)))
410             {
411                 if(sk->errcb != NULL)
412                     sk->errcb(sk, 0, sk->data);
413                 closesock(sk);
414             }
415             return;
416         }
417         dbuf->addr = srealloc(dbuf->addr, dbuf->addrlen);
418         dbuf->data = srealloc(dbuf->data, dbuf->size = ret);
419         dbuf->next = NULL;
420         if(sk->inbuf.d.l != NULL)
421             sk->inbuf.d.l->next = dbuf;
422         else
423             sk->inbuf.d.f = dbuf;
424         sk->inbuf.d.l = dbuf;
425         if(sk->readcb != NULL)
426             sk->readcb(sk, sk->data);
427         break;
428     }
429 }
430
431 static void sockflush(struct socket *sk)
432 {
433     int ret;
434     struct dgrambuf *dbuf;
435     
436     switch(sk->type)
437     {
438     case SOCK_STREAM:
439         if(sk->isrealsocket)
440             ret = send(sk->fd, sk->outbuf.s.buf, sk->outbuf.s.datasize, MSG_DONTWAIT | MSG_NOSIGNAL);
441         else
442             ret = write(sk->fd, sk->outbuf.s.buf, sk->outbuf.s.datasize);
443         if(ret < 0)
444         {
445             /* For now, assume transient error, since
446              * the socket is polled for errors */
447             break;
448         }
449         if(ret > 0)
450         {
451             memmove(sk->outbuf.s.buf, ((char *)sk->outbuf.s.buf) + ret, sk->outbuf.s.datasize -= ret);
452             if(sk->writecb != NULL)
453                 sk->writecb(sk, sk->data);
454         }
455         break;
456     case SOCK_DGRAM:
457         dbuf = sk->outbuf.d.f;
458         if((sk->outbuf.d.f = dbuf->next) == NULL)
459             sk->outbuf.d.l = NULL;
460         sendto(sk->fd, dbuf->data, dbuf->size, MSG_DONTWAIT | MSG_NOSIGNAL, dbuf->addr, dbuf->addrlen);
461         free(dbuf->data);
462         free(dbuf->addr);
463         free(dbuf);
464         if(sk->writecb != NULL)
465             sk->writecb(sk, sk->data);
466         break;
467     }
468 }
469
470 void closesock(struct socket *sk)
471 {
472     sk->state = SOCK_STL;
473     close(sk->fd);
474     sk->fd = -1;
475     sk->close = 0;
476 }
477
478 void sockqueue(struct socket *sk, void *data, size_t size)
479 {
480     struct dgrambuf *new;
481     
482     if(sk->state == SOCK_STL)
483         return;
484     switch(sk->type)
485     {
486     case SOCK_STREAM:
487         sizebuf(&(sk->outbuf.s.buf), &(sk->outbuf.s.bufsize), sk->outbuf.s.datasize + size, 1, 1);
488         memcpy(sk->outbuf.s.buf + sk->outbuf.s.datasize, data, size);
489         sk->outbuf.s.datasize += size;
490         break;
491     case SOCK_DGRAM:
492         if(sk->remote == NULL)
493             return;
494         new = smalloc(sizeof(*new));
495         new->next = NULL;
496         memcpy(new->data = smalloc(size), data, new->size = size);
497         memcpy(new->addr = smalloc(sk->remotelen), sk->remote, new->addrlen = sk->remotelen);
498         if(sk->outbuf.d.l == NULL)
499         {
500             sk->outbuf.d.l = sk->outbuf.d.f = new;
501         } else {
502             sk->outbuf.d.l->next = new;
503             sk->outbuf.d.l = new;
504         }
505         break;
506     }
507 }
508
509 size_t sockgetdatalen(struct socket *sk)
510 {
511     struct dgrambuf *b;
512     size_t ret;
513     
514     switch(sk->type)
515     {
516     case SOCK_STREAM:
517         ret = sk->inbuf.s.datasize;
518         break;
519     case SOCK_DGRAM:
520         ret = 0;
521         for(b = sk->inbuf.d.f; b != NULL; b = b->next)
522             ret += b->size;
523         break;
524     }
525     return(ret);
526 }
527
528 size_t sockqueuesize(struct socket *sk)
529 {
530     struct dgrambuf *b;
531     size_t ret;
532     
533     switch(sk->type)
534     {
535     case SOCK_STREAM:
536         ret = sk->outbuf.s.datasize;
537         break;
538     case SOCK_DGRAM:
539         ret = 0;
540         for(b = sk->outbuf.d.f; b != NULL; b = b->next)
541             ret += b->size;
542         break;
543     }
544     return(ret);
545 }
546
547 /*
548  * The difference between netcslisten() and netcslistenlocal() is that
549  * netcslistenlocal() always listens on the local host, instead of
550  * following proxy/passive mode directions. It is suitable for eg. the
551  * UI channel, while the file sharing networks should, naturally, use
552  * netcslisten() instead.
553 */
554
555 struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
556 {
557     struct socket *sk;
558     int intbuf;
559     
560     /* I don't know if this is actually correct (it probably isn't),
561      * but since, at on least Linux systems, PF_* are specifically
562      * #define'd to their AF_* counterparts, it allows for a severely
563      * smoother implementation. If it breaks something on your
564      * platform, please tell me so.
565      */
566     if((sk = mksock(name->sa_family, type)) == NULL)
567         return(NULL);
568     sk->state = SOCK_LST;
569     if(confgetint("net", "reuseaddr"))
570     {
571         intbuf = 1;
572         setsockopt(sk->fd, SOL_SOCKET, SO_REUSEADDR, &intbuf, sizeof(intbuf));
573     }
574     if(bind(sk->fd, name, namelen) < 0)
575     {
576         putsock(sk);
577         return(NULL);
578     }
579     if(listen(sk->fd, 16) < 0)
580     {
581         putsock(sk);
582         return(NULL);
583     }
584     sk->acceptcb = func;
585     sk->data = data;
586     return(sk);
587 }
588
589 struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
590 {
591     if(confgetint("net", "mode") == 1)
592     {
593         errno = EOPNOTSUPP;
594         return(NULL);
595     }
596     /* I don't know if this is actually correct (it probably isn't),
597      * but since, at on least Linux systems, PF_* are specifically
598      * #define'd to their AF_* counterparts, it allows for a severely
599      * smoother implementation. If it breaks something on your
600      * platform, please tell me so.
601      */
602     if(confgetint("net", "mode") == 0)
603         return(netcslistenlocal(type, name, namelen, func, data));
604     errno = EOPNOTSUPP;
605     return(NULL);
606 }
607
608 struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data)
609 {
610     struct sockaddr_in addr;
611 #ifdef HAVE_IPV6
612     struct sockaddr_in6 addr6;
613 #endif
614     struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct socket *, struct socket *, void *), void *);
615     struct socket *ret;
616     
617     if(local)
618         csfunc = netcslistenlocal;
619     else
620         csfunc = netcslisten;
621 #ifdef HAVE_IPV6
622     memset(&addr6, 0, sizeof(addr6));
623     addr6.sin6_family = AF_INET6;
624     addr6.sin6_port = htons(port);
625     addr6.sin6_addr = in6addr_any;
626     if((ret = csfunc(SOCK_STREAM, (struct sockaddr *)&addr6, sizeof(addr6), func, data)) != NULL)
627         return(ret);
628     if((ret == NULL) && (errno != EAFNOSUPPORT))
629         return(NULL);
630 #endif
631     memset(&addr, 0, sizeof(addr));
632     addr.sin_family = AF_INET;
633     addr.sin_port = htons(port);
634     return(csfunc(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), func, data));
635 }
636
637 struct socket *netcsdgram(struct sockaddr *name, socklen_t namelen)
638 {
639     struct socket *sk;
640     int mode;
641     
642     mode = confgetint("net", "mode");
643     if((mode == 0) || (mode == 1))
644     {
645         if((sk = mksock(name->sa_family, SOCK_DGRAM)) == NULL)
646             return(NULL);
647         if(bind(sk->fd, name, namelen) < 0)
648         {
649             putsock(sk);
650             return(NULL);
651         }
652         sk->state = SOCK_EST;
653         return(sk);
654     }
655     errno = EOPNOTSUPP;
656     return(NULL);
657 }
658
659 struct socket *netdupsock(struct socket *sk)
660 {
661     struct socket *newsk;
662     
663     newsk = newsock(sk->type);
664     if((newsk->fd = dup(sk->fd)) < 0)
665     {
666         flog(LOG_WARNING, "could not dup() socket: %s", strerror(errno));
667         putsock(newsk);
668         return(NULL);
669     }
670     newsk->state = sk->state;
671     newsk->ignread = sk->ignread;
672     if(sk->remote != NULL)
673         memcpy(newsk->remote = smalloc(sk->remotelen), sk->remote, newsk->remotelen = sk->remotelen);
674     return(newsk);
675 }
676
677 void netdgramconn(struct socket *sk, struct sockaddr *addr, socklen_t addrlen)
678 {
679     if(sk->remote != NULL)
680         free(sk->remote);
681     memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
682     sk->ignread = 1;
683 }
684
685 struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data)
686 {
687     struct socket *sk;
688     int mode;
689     
690     mode = confgetint("net", "mode");
691     if((mode == 0) || (mode == 1))
692     {
693         if((sk = mksock(addr->sa_family, SOCK_STREAM)) == NULL)
694             return(NULL);
695         memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
696         if(!connect(sk->fd, addr, addrlen))
697         {
698             sk->state = SOCK_EST;
699             func(sk, 0, data);
700             return(sk);
701         }
702         if(errno == EINPROGRESS)
703         {
704             sk->state = SOCK_SYN;
705             sk->conncb = func;
706             sk->data = data;
707             return(sk);
708         }
709         putsock(sk);
710         return(NULL);
711     }
712     errno = EOPNOTSUPP;
713     return(NULL);
714 }
715
716 int pollsocks(int timeout)
717 {
718     int i, num, ret, retlen;
719     int newfd;
720     struct pollfd *pfds;
721     struct socket *sk, *next, *newsk;
722     struct sockaddr_storage ss;
723     socklen_t sslen;
724     
725     pfds = smalloc(sizeof(*pfds) * (num = numsocks));
726     for(i = 0, sk = sockets; i < num; sk = sk->next)
727     {
728         if(sk->state == SOCK_STL)
729         {
730             num--;
731             continue;
732         }
733         pfds[i].fd = sk->fd;
734         pfds[i].events = 0;
735         if(!sk->ignread)
736             pfds[i].events |= POLLIN;
737         if((sk->state == SOCK_SYN) || (sockqueuesize(sk) > 0))
738             pfds[i].events |= POLLOUT;
739         pfds[i].revents = 0;
740         i++;
741     }
742     ret = poll(pfds, num, timeout);
743     if(ret < 0)
744     {
745         if(errno != EINTR)
746         {
747             flog(LOG_CRIT, "pollsocks: poll errored out: %s", strerror(errno));
748             /* To avoid CPU hogging in case it's bad, which it
749              * probably is. */
750             sleep(1);
751         }
752         free(pfds);
753         return(1);
754     }
755     for(sk = sockets; sk != NULL; sk = next)
756     {
757         next = sk->next;
758         for(i = 0; i < num; i++)
759         {
760             if(pfds[i].fd == sk->fd)
761                 break;
762         }
763         if(i == num)
764             continue;
765         switch(sk->state)
766         {
767         case SOCK_LST:
768             if(pfds[i].revents & POLLIN)
769             {
770                 sslen = sizeof(ss);
771                 if((newfd = accept(sk->fd, (struct sockaddr *)&ss, &sslen)) < 0)
772                 {
773                     if(sk->errcb != NULL)
774                         sk->errcb(sk, errno, sk->data);
775                 }
776                 newsk = newsock(sk->type);
777                 newsk->fd = newfd;
778                 newsk->family = sk->family;
779                 newsk->state = SOCK_EST;
780                 memcpy(newsk->remote = smalloc(sslen), &ss, sslen);
781                 newsk->remotelen = sslen;
782                 putsock(newsk);
783                 if(sk->acceptcb != NULL)
784                     sk->acceptcb(sk, newsk, sk->data);
785             }
786             if(pfds[i].revents & POLLERR)
787             {
788                 retlen = sizeof(ret);
789                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
790                 if(sk->errcb != NULL)
791                     sk->errcb(sk, ret, sk->data);
792                 continue;
793             }
794             break;
795         case SOCK_SYN:
796             if(pfds[i].revents & POLLERR)
797             {
798                 retlen = sizeof(ret);
799                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
800                 if(sk->conncb != NULL)
801                     sk->conncb(sk, ret, sk->data);
802                 closesock(sk);
803                 continue;
804             }
805             if(pfds[i].revents & (POLLIN | POLLOUT))
806             {
807                 sk->state = SOCK_EST;
808                 if(sk->conncb != NULL)
809                     sk->conncb(sk, 0, sk->data);
810             }
811             break;
812         case SOCK_EST:
813             if(pfds[i].revents & POLLERR)
814             {
815                 retlen = sizeof(ret);
816                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
817                 if(sk->errcb != NULL)
818                     sk->errcb(sk, ret, sk->data);
819                 closesock(sk);
820                 continue;
821             }
822             if(pfds[i].revents & POLLIN)
823                 sockrecv(sk);
824             if(pfds[i].revents & POLLOUT)
825             {
826                 if(sockqueuesize(sk) > 0)
827                     sockflush(sk);
828             }
829             break;
830         }
831         if(pfds[i].revents & POLLNVAL)
832         {
833             flog(LOG_CRIT, "BUG: stale socket struct on fd %i", sk->fd);
834             sk->state = SOCK_STL;
835             unlinksock(sk);
836             continue;
837         }
838         if(pfds[i].revents & POLLHUP)
839         {
840             if(sk->errcb != NULL)
841                 sk->errcb(sk, 0, sk->data);
842             closesock(sk);
843             unlinksock(sk);
844             continue;
845         }
846     }
847     free(pfds);
848     for(sk = sockets; sk != NULL; sk = next)
849     {
850         next = sk->next;
851         if(sk->refcount == 1 && (sockqueuesize(sk) == 0))
852         {
853             unlinksock(sk);
854             continue;
855         }
856         if(sk->close && (sockqueuesize(sk) == 0))
857             closesock(sk);
858         if(sk->state == SOCK_STL)
859         {
860             unlinksock(sk);
861             continue;
862         }
863     }
864     return(1);
865 }
866
867 int socksettos(struct socket *sk, int tos)
868 {
869     int buf;
870     
871     if(sk->family == AF_INET)
872     {
873         switch(tos)
874         {
875         case 0:
876             buf = 0;
877             break;
878         case SOCK_TOS_MINCOST:
879             buf = 0x02;
880             break;
881         case SOCK_TOS_MAXREL:
882             buf = 0x04;
883             break;
884         case SOCK_TOS_MAXTP:
885             buf = 0x08;
886             break;
887         case SOCK_TOS_MINDELAY:
888             buf = 0x10;
889             break;
890         default:
891             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
892             return(-1);
893         }
894         if(setsockopt(sk->fd, SOL_IP, IP_TOS, &buf, sizeof(buf)) < 0)
895         {
896             flog(LOG_WARNING, "could not set sock TOS to %i: %s", tos, strerror(errno));
897             return(-1);
898         }
899         return(0);
900     }
901     if(sk->family == AF_INET6)
902     {
903         switch(tos)
904         {
905         case 0:
906             buf = 0;
907         case SOCK_TOS_MINCOST:
908             buf = confgetint("net", "diffserv-mincost");
909             break;
910         case SOCK_TOS_MAXREL:
911             buf = confgetint("net", "diffserv-maxrel");
912             break;
913         case SOCK_TOS_MAXTP:
914             buf = confgetint("net", "diffserv-maxtp");
915             break;
916         case SOCK_TOS_MINDELAY:
917             buf = confgetint("net", "diffserv-mindelay");
918             break;
919         default:
920             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
921             return(-1);
922         }
923         /*
924           On Linux, the API IPv6 flow label management doesn't seem to
925           be entirely complete, so I guess this will have to wait.
926           
927         if(setsockopt(...) < 0)
928         {
929             flog(LOG_WARNING, "could not set sock traffic class to %i: %s", tos, strerror(errno));
930             return(-1);
931         }
932         */
933         return(0);
934     }
935     flog(LOG_WARNING, "could not set TOS on sock of family %i", sk->family);
936     return(1);
937 }
938
939 struct resolvedata
940 {
941     int fd;
942     void (*callback)(struct sockaddr *addr, int addrlen, void *data);
943     void *data;
944     struct sockaddr_storage addr;
945     int addrlen;
946 };
947
948 static void resolvecb(pid_t pid, int status, struct resolvedata *data)
949 {
950     static char buf[80];
951     int ret;
952     struct sockaddr_in *ipv4;
953     
954     if(!status)
955     {
956         if((ret = read(data->fd, buf, sizeof(buf))) != 4)
957         {
958             errno = ENONET;
959             data->callback(NULL, 0, data->data);
960         } else {
961             ipv4 = (struct sockaddr_in *)&data->addr;
962             memcpy(&ipv4->sin_addr, buf, 4);
963             data->callback((struct sockaddr *)ipv4, sizeof(*ipv4), data->data);
964         }
965     } else {
966         errno = ENONET;
967         data->callback(NULL, 0, data->data);
968     }
969     close(data->fd);
970     free(data);
971 }
972
973 int netresolve(char *addr, void (*callback)(struct sockaddr *addr, int addrlen, void *data), void *data)
974 {
975     int i;
976     char *p;
977     int port;
978     int pfd[2];
979     pid_t child;
980     struct resolvedata *rdata;
981     struct sockaddr_in ipv4;
982     struct hostent *he;
983     sigset_t sigset;
984     
985     /* IPv4 */
986     port = -1;
987     if((p = strchr(addr, ':')) != NULL)
988     {
989         *p = 0;
990         port = atoi(p + 1);
991     }
992     ipv4.sin_family = AF_INET;
993     ipv4.sin_port = htons(port);
994     if(inet_aton(addr, &ipv4.sin_addr))
995     {
996         callback((struct sockaddr *)&ipv4, sizeof(ipv4), data);
997     } else {
998         sigemptyset(&sigset);
999         sigaddset(&sigset, SIGCHLD);
1000         sigprocmask(SIG_BLOCK, &sigset, NULL);
1001         if((pipe(pfd) < 0) || ((child = fork()) < 0))
1002         {
1003             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1004             return(-1);
1005         }
1006         if(child == 0)
1007         {
1008             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1009             for(i = 3; i < FD_SETSIZE; i++)
1010             {
1011                 if(i != pfd[1])
1012                     close(i);
1013             }
1014             signal(SIGALRM, SIG_DFL);
1015             alarm(30);
1016             if((he = gethostbyname(addr)) == NULL)
1017                 exit(1);
1018             write(pfd[1], he->h_addr_list[0], 4);
1019             exit(0);
1020         } else {
1021             close(pfd[1]);
1022             fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK);
1023             rdata = smalloc(sizeof(*rdata));
1024             rdata->fd = pfd[0];
1025             rdata->callback = callback;
1026             rdata->data = data;
1027             memcpy(&rdata->addr, &ipv4, rdata->addrlen = sizeof(ipv4));
1028             childcallback(child, (void (*)(pid_t, int, void *))resolvecb, rdata);
1029             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1030             return(1);
1031         }
1032     }
1033     return(0);
1034 }
1035
1036 int sockgetlocalname(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1037 {
1038     socklen_t len;
1039     struct sockaddr_storage name;
1040     
1041     *namebuf = NULL;
1042     if((sk->state == SOCK_STL) || (sk->fd < 0))
1043         return(-1);
1044     len = sizeof(name);
1045     if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1046     {
1047         flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetlocalname");
1048         return(-1);
1049     }
1050     *namebuf = memcpy(smalloc(len), &name, len);
1051     *lenbuf = len;
1052     return(0);
1053 }
1054
1055 int sockgetremotename(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1056 {
1057     socklen_t len;
1058     struct sockaddr_storage name;
1059     struct sockaddr_in *ipv4;
1060     struct sockaddr *pname;
1061     socklen_t pnamelen;
1062     
1063     switch(confgetint("net", "mode"))
1064     {
1065     case 0:
1066         *namebuf = NULL;
1067         if((sk->state == SOCK_STL) || (sk->fd < 0))
1068             return(-1);
1069         len = sizeof(name);
1070         if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1071         {
1072             flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetremotename");
1073             return(-1);
1074         }
1075         if(name.ss_family == AF_INET)
1076         {
1077             ipv4 = (struct sockaddr_in *)&name;
1078             if(getpublicaddr(AF_INET, &pname, &pnamelen) < 0)
1079             {
1080                 flog(LOG_WARNING, "could not determine public IP address - strange things may happen");
1081                 return(-1);
1082             }
1083             ipv4->sin_addr.s_addr = ((struct sockaddr_in *)pname)->sin_addr.s_addr;
1084             free(pname);
1085         }
1086         *namebuf = memcpy(smalloc(len), &name, len);
1087         *lenbuf = len;
1088         return(0);
1089     case 1:
1090         errno = EOPNOTSUPP;
1091         return(-1);
1092     default:
1093         flog(LOG_CRIT, "unknown net mode %i active", confgetint("net", "mode"));
1094         errno = EOPNOTSUPP;
1095         return(-1);
1096     }
1097 }
1098
1099 int addreq(struct sockaddr *x, struct sockaddr *y)
1100 {
1101     struct sockaddr_un *u1, *u2;
1102     struct sockaddr_in *n1, *n2;
1103 #ifdef HAVE_IPV6
1104     struct sockaddr_in6 *s1, *s2;
1105 #endif
1106     
1107     if(x->sa_family != y->sa_family)
1108         return(0);
1109     switch(x->sa_family) {
1110     case AF_UNIX:
1111         u1 = (struct sockaddr_un *)x; u2 = (struct sockaddr_un *)y;
1112         if(strncmp(u1->sun_path, u2->sun_path, sizeof(u1->sun_path)))
1113             return(0);
1114         break;
1115     case AF_INET:
1116         n1 = (struct sockaddr_in *)x; n2 = (struct sockaddr_in *)y;
1117         if(n1->sin_port != n2->sin_port)
1118             return(0);
1119         if(n1->sin_addr.s_addr != n2->sin_addr.s_addr)
1120             return(0);
1121         break;
1122     case AF_INET6:
1123         s1 = (struct sockaddr_in6 *)x; s2 = (struct sockaddr_in6 *)y;
1124         if(s1->sin6_port != s2->sin6_port)
1125             return(0);
1126         if(memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr)))
1127             return(0);
1128         break;
1129     }
1130     return(1);
1131 }
1132
1133 char *formataddress(struct sockaddr *arg, socklen_t arglen)
1134 {
1135     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1136                                * lowercase letters to 1, so I do this
1137                                * instead. */
1138     struct sockaddr_in *ipv4;
1139 #ifdef HAVE_IPV6
1140     struct sockaddr_in6 *ipv6;
1141 #endif
1142     static char *ret = NULL;
1143     char buf[1024];
1144     
1145     if(ret != NULL)
1146         free(ret);
1147     ret = NULL;
1148     switch(arg->sa_family)
1149     {
1150     case AF_UNIX:
1151         UNIX = (struct sockaddr_un *)arg;
1152         ret = sprintf2("%s", UNIX->sun_path);
1153         break;
1154     case AF_INET:
1155         ipv4 = (struct sockaddr_in *)arg;
1156         if(inet_ntop(AF_INET, &ipv4->sin_addr, buf, sizeof(buf)) == NULL)
1157             return(NULL);
1158         ret = sprintf2("%s:%i", buf, (int)ntohs(ipv4->sin_port));
1159         break;
1160 #ifdef HAVE_IPV6
1161     case AF_INET6:
1162         ipv6 = (struct sockaddr_in6 *)arg;
1163         if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL)
1164             return(NULL);
1165         ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port));
1166         break;
1167 #endif
1168     default:
1169         errno = EPFNOSUPPORT;
1170         break;
1171     }
1172     return(ret);
1173 }
1174
1175 #if 0
1176
1177 /* 
1178  * It was very nice to use this, but it seems
1179  * to mess things up, so I guess it has to go... :-(
1180  */
1181
1182 static int formataddress(FILE *stream, const struct printf_info *info, const void *const *args)
1183 {
1184     struct sockaddr *arg;
1185     socklen_t arglen;
1186     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1187                                * lowercase letters to 1, so I do this
1188                                * instead. */
1189     struct sockaddr_in *ipv4;
1190     int ret;
1191     
1192     arg = *(struct sockaddr **)(args[0]);
1193     arglen = *(socklen_t *)(args[1]);
1194     switch(arg->sa_family)
1195     {
1196     case AF_UNIX:
1197         UNIX = (struct sockaddr_un *)arg;
1198         ret = fprintf(stream, "%s", UNIX->sun_path);
1199         break;
1200     case AF_INET:
1201         ipv4 = (struct sockaddr_in *)arg;
1202         ret = fprintf(stream, "%s:%i", inet_ntoa(ipv4->sin_addr), (int)ntohs(ipv4->sin_port));
1203         break;
1204     default:
1205         ret = -1;
1206         errno = EPFNOSUPPORT;
1207         break;
1208     }
1209     return(ret);
1210 }
1211
1212 static int formataddress_arginfo(const struct printf_info *info, size_t n, int *argtypes)
1213 {
1214     if(n > 0)
1215         argtypes[0] = PA_POINTER;
1216     if(n > 1)
1217         argtypes[1] = PA_INT; /* Sources tell me that socklen_t _must_
1218                                * be an int, so I guess this should be
1219                                * safe. */
1220     return(2);
1221 }
1222 #endif
1223
1224 static int init(int hup)
1225 {
1226     if(!hup)
1227     {
1228         /*
1229         if(register_printf_function('N', formataddress, formataddress_arginfo))
1230         {
1231             flog(LOG_CRIT, "could not register printf handler %%N: %s", strerror(errno));
1232             return(1);
1233         }
1234         */
1235     }
1236     return(0);
1237 }
1238
1239 static void terminate(void)
1240 {
1241     while(sockets != NULL)
1242         unlinksock(sockets);
1243 }
1244
1245 static struct module me =
1246 {
1247     .name = "net",
1248     .conf =
1249     {
1250         .vars = myvars
1251     },
1252     .init = init,
1253     .terminate = terminate
1254 };
1255
1256 MODULE(me)