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