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