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