Added socket debugging support.
[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/select.h>
32 #include <arpa/inet.h>
33 #include <netinet/in.h>
34 #include <netdb.h>
35 #include <sys/signal.h>
36 #include <sys/stat.h>       /* For rebindunix() */
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     /** The network mode to use. Currently supported values are 0 for
53      * active mode and 1 for passive mode. In the future, SOCKS5 proxy
54      * support may be added. */
55     {CONF_VAR_INT, "mode", {.num = 0}},
56     /** Set the SO_REUSEADDR socket option on listening sockets, so
57      * that dead TCP connections waiting for timeout are ignored. */
58     {CONF_VAR_BOOL, "reuseaddr", {.num = 0}},
59     /** Overrides the IPv4 address reported to other clients in active
60      * mode. Useful for servers behind NAT routers. If both this and
61      * net.publicif are unspecified the address of the hub connection
62      * is used. */
63     {CONF_VAR_IPV4, "visibleipv4", {.ipv4 = {0}}},
64     /** Specifies an interface name from which to fetch the IPv4
65      * address reported to other clients in active mode. If both this
66      * and net.visibleipv4 are unspecified the address of the hub
67      * connection is used. */
68     {CONF_VAR_STRING, "publicif", {.str = L""}},
69     /* Diffserv should be supported on IPv4, too, but I don't know the
70      * API to do that. */
71     /** The Diffserv value to use on IPv6 connections when the
72      * minimize cost TOS value is used (see the TOS VALUES
73      * section). */
74     {CONF_VAR_INT, "diffserv-mincost", {.num = 0}},
75     /** The Diffserv value to use on IPv6 connections when the
76      * maximize reliability TOS value is used (see the TOS VALUES
77      * section). */
78     {CONF_VAR_INT, "diffserv-maxrel", {.num = 0}},
79     /** The Diffserv value to use on IPv6 connections when the
80      * maximize throughput TOS value is used (see the TOS VALUES
81      * section). */
82     {CONF_VAR_INT, "diffserv-maxtp", {.num = 0}},
83     /** The Diffserv value to use on IPv6 connections when the
84      * minimize delay TOS value is used (see the TOS VALUES
85      * section). */
86     {CONF_VAR_INT, "diffserv-mindelay", {.num = 0}},
87     {CONF_VAR_END}
88 };
89
90 #define UFD_SOCK 0
91 #define UFD_PIPE 1
92 #define UFD_LISTEN 2
93
94 struct scons {
95     struct scons *n, *p;
96     struct socket *s;
97 };
98
99 struct ufd {
100     struct ufd *next, *prev;
101     int fd;
102     int type;
103     int ignread;
104     struct socket *sk;
105     union {
106         struct {
107             int family;
108             int type;
109             struct sockaddr *remote;
110             socklen_t remotelen;
111             struct {
112                 uid_t uid;
113                 gid_t gid;
114             } ucred;
115         } s;
116         struct {
117             struct lport *lp;
118             int family;
119         } l;
120     } d;
121 };
122
123 static int getlocalname(int fd, struct sockaddr **namebuf, socklen_t *lenbuf);
124
125 static struct ufd *ufds = NULL;
126 static struct scons *rbatch, *wbatch, *cbatch;
127 int numsocks = 0;
128
129 /* XXX: Get autoconf for all this... */
130 int getpublicaddr(int af, struct sockaddr **addr, socklen_t *lenbuf)
131 {
132     struct sockaddr_in *ipv4;
133     struct configvar *var;
134     void *bufend;
135     int sock;
136     struct ifconf conf;
137     struct ifreq *ifr, req;
138     char *pif;
139     
140     if(af == AF_INET)
141     {
142         var = confgetvar("net", "visibleipv4");
143         if(var->val.ipv4.s_addr != 0)
144         {
145             ipv4 = smalloc(sizeof(*ipv4));
146             ipv4->sin_family = AF_INET;
147             ipv4->sin_addr.s_addr = var->val.ipv4.s_addr;
148             *addr = (struct sockaddr *)ipv4;
149             *lenbuf = sizeof(*ipv4);
150             return(0);
151         }
152         if((pif = icswcstombs(confgetstr("net", "publicif"), NULL, NULL)) == NULL)
153         {
154             flog(LOG_ERR, "could not convert net.publicif into local charset: %s", strerror(errno));
155             return(-1);
156         }
157         if(!strcmp(pif, ""))
158             return(1);
159         if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
160             return(-1);
161         conf.ifc_buf = smalloc(conf.ifc_len = 65536);
162         if(ioctl(sock, SIOCGIFCONF, &conf) < 0)
163         {
164             free(conf.ifc_buf);
165             close(sock);
166             return(-1);
167         }
168         bufend = ((char *)conf.ifc_buf) + conf.ifc_len;
169         ipv4 = NULL;
170         for(ifr = conf.ifc_ifcu.ifcu_req; (void *)ifr < bufend; ifr++)
171         {
172             if(strcmp(ifr->ifr_name, pif))
173                 continue;
174             memset(&req, 0, sizeof(req));
175             memcpy(req.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
176             if(ioctl(sock, SIOCGIFFLAGS, &req) < 0)
177                 break;
178             if(!(req.ifr_flags & IFF_UP))
179             {
180                 flog(LOG_WARNING, "public interface is down");
181                 break;
182             }
183             if(ifr->ifr_addr.sa_family != AF_INET)
184             {
185                 flog(LOG_WARNING, "address of the public interface is not AF_INET");
186                 break;
187             }
188             ipv4 = smalloc(sizeof(*ipv4));
189             memcpy(ipv4, &ifr->ifr_addr, sizeof(ifr->ifr_addr));
190             break;
191         }
192         free(conf.ifc_buf);
193         close(sock);
194         if(ipv4 != NULL)
195         {
196             *addr = (struct sockaddr *)ipv4;
197             *lenbuf = sizeof(*ipv4);
198             return(0);
199         }
200         errno = ENETDOWN;
201         return(-1);
202     }
203     return(1);
204 }
205
206 static struct socket *newsock1(int dgram)
207 {
208     struct socket *new;
209     
210     new = memset(smalloc(sizeof(*new)), 0, sizeof(*new));
211     new->refcount = 1;
212     new->state = -1;
213     new->dgram = dgram;
214     new->maxbuf = 65536;
215     numsocks++;
216     return(new);
217 }
218
219 static struct socket *sockpair(int dgram)
220 {
221     struct socket *s1, *s2;
222     
223     s1 = newsock1(dgram);
224     s2 = newsock1(dgram);
225     s1->back = s2;
226     s2->back = s1;
227     putsock(s2);
228     return(s1);
229 }
230
231 static void sksetstate(struct socket *sk, int state)
232 {
233     sk->state = state;
234     sk->back->state = state;
235 }
236
237 struct socket *netsockpipe(void)
238 {
239     struct socket *sk;
240     
241     sk = sockpair(0);
242     sksetstate(sk, SOCK_EST);
243     return(sk);
244 }
245
246 static void closeufd(struct ufd *ufd)
247 {
248     if(ufd->fd != -1)
249         close(ufd->fd);
250     ufd->fd = -1;
251 }
252
253 static void freeufd(struct ufd *ufd)
254 {
255     if(ufd->next != NULL)
256         ufd->next->prev = ufd->prev;
257     if(ufd->prev != NULL)
258         ufd->prev->next = ufd->next;
259     if(ufd == ufds)
260         ufds = ufd->next;
261     closeufd(ufd);
262     if(ufd->sk != NULL)
263         putsock(ufd->sk);
264     if(ufd->type == UFD_SOCK) {
265         if(ufd->d.s.remote != NULL)
266             free(ufd->d.s.remote);
267     }
268     free(ufd);
269 }
270
271 static struct ufd *mkufd(int fd, int type, struct socket *sk)
272 {
273     struct ufd *ufd;
274     
275     ufd = memset(smalloc(sizeof(*ufd)), 0, sizeof(*ufd));
276     ufd->fd = fd;
277     ufd->type = type;
278     if(sk != NULL) {
279         getsock(ufd->sk = sk);
280         sk->ufd = ufd;
281     }
282     if(type == UFD_SOCK) {
283         ufd->d.s.ucred.uid = -1;
284         ufd->d.s.ucred.gid = -1;
285     }
286     ufd->next = ufds;
287     if(ufds)
288         ufds->prev = ufd;
289     ufds = ufd;
290     return(ufd);
291 }
292
293 static struct ufd *dupufd(struct ufd *ufd)
294 {
295     struct ufd *nufd;
296     struct socket *nsk;
297     
298     if(ufd->sk != NULL)
299         nsk = sockpair(ufd->sk->dgram);
300     else
301         nsk = NULL;
302     nufd = mkufd(ufd->fd, ufd->type, nsk);
303     if(nsk != NULL)
304         putsock(nsk);
305     if((nufd->fd = dup(ufd->fd)) < 0)
306     {
307         flog(LOG_WARNING, "could not dup() fd: %s", strerror(errno));
308         freeufd(nufd);
309         return(NULL);
310     }
311     sksetstate(nsk, SOCK_EST);
312     if(ufd->type == UFD_SOCK) {
313         nufd->d.s.family = ufd->d.s.family;
314         nufd->d.s.type = ufd->d.s.type;
315         nufd->d.s.ucred.uid = ufd->d.s.ucred.uid;
316         nufd->d.s.ucred.gid = ufd->d.s.ucred.gid;
317         if(ufd->d.s.remote != NULL)
318             nufd->d.s.remote = memcpy(smalloc(ufd->d.s.remotelen), ufd->d.s.remote, nufd->d.s.remotelen = ufd->d.s.remotelen);
319     } else if(ufd->type == UFD_LISTEN) {
320         nufd->d.l.family = ufd->d.l.family;
321     }
322     return(nufd);
323 }
324
325 static struct socket *mksock(int domain, int type)
326 {
327     int fd;
328     struct socket *sk;
329     struct ufd *ufd;
330     
331     if((fd = socket(domain, type, 0)) < 0)
332     {
333         flog(LOG_CRIT, "could not create socket: %s", strerror(errno));
334         return(NULL);
335     }
336     sk = sockpair(type == SOCK_DGRAM);
337     ufd = mkufd(fd, UFD_SOCK, sk);
338     ufd->d.s.family = domain;
339     ufd->d.s.type = type;
340     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
341     return(sk);
342 }
343
344 struct socket *wrapsock(int fd)
345 {
346     struct socket *sk;
347     struct ufd *ufd;
348     
349     sk = sockpair(0);
350     ufd = mkufd(fd, UFD_PIPE, sk->back);
351     sksetstate(sk, SOCK_EST);
352     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
353     return(sk);
354 }
355
356 void getsock(struct socket *sk)
357 {
358     sk->refcount++;
359 }
360
361 static void sockdebug(int level, struct socket *sk, char *format, ...)
362 {
363     va_list args;
364     
365     if((sk->dbgnm == NULL) || (level < sk->dbglvl))
366         return;
367     va_start(args, format);
368     vfprintf(stderr, format, args);
369     va_end(args);
370 }
371
372 void socksetdebug(struct socket *sk, int level, char *nm, ...)
373 {
374     va_list args;
375     char *tb;
376     
377     va_start(args, nm);
378     tb = vsprintf2(nm, args);
379     va_end(args);
380     sk->dbgnm = sprintf2("%s (f)", tb);
381     sk->back->dbgnm = sprintf2("%s (b)", tb);
382     free(tb);
383     sk->dbglvl = level;
384     sk->back->dbglvl = level;
385 }
386
387 static void freesock(struct socket *sk)
388 {
389     struct dgrambuf *buf;
390     
391     sockdebug(1, sk, "freeing socket");
392     if(sk->dgram) {
393         while((buf = sk->buf.d.f) != NULL) {
394             sk->buf.d.f = buf->next;
395             freedgbuf(buf);
396         }
397     } else {
398         if(sk->buf.s.buf != NULL)
399             free(sk->buf.s.buf);
400     }
401     if(sk->dbgnm != NULL)
402         free(sk->dbgnm);
403     free(sk);
404     numsocks--;
405 }
406
407 void putsock(struct socket *sk)
408 {
409     struct socket *back;
410     
411     if(--(sk->refcount) < 0) {
412         flog(LOG_CRIT, "BUG: socket refcount < 0");
413         abort();
414     }
415     if((sk->refcount == 0) && (sk->back->refcount == 0)) {
416         back = sk->back;
417         freesock(sk);
418         freesock(back);
419     }
420 }
421
422 void quitsock(struct socket *sk)
423 {
424     sk->readcb = NULL;
425     sk->writecb = NULL;
426     sk->errcb = NULL;
427     putsock(sk);
428 }
429
430 static void linksock(struct scons **list, struct socket *sk)
431 {
432     struct scons *sc;
433     
434     for(sc = *list; sc != NULL; sc = sc->n) {
435         if(sc->s == sk)
436             return;
437     }
438     sc = smalloc(sizeof(*sc));
439     getsock(sc->s = sk);
440     sc->n = *list;
441     sc->p = NULL;
442     if(*list)
443         (*list)->p = sc;
444     *list = sc;
445 }
446
447 void sockpushdata(struct socket *sk, void *buf, size_t size)
448 {
449     if(size == 0)
450         return;
451     if(sk->dgram) {
452         /* XXX */
453     } else {
454         sizebuf(&sk->buf.s.buf, &sk->buf.s.bufsize, sk->buf.s.datasize + size, 1, 1);
455         memmove(sk->buf.s.buf + size, sk->buf.s.buf, sk->buf.s.datasize);
456         memcpy(sk->buf.s.buf, buf, size);
457         sk->buf.s.datasize += size;
458         linksock(&rbatch, sk);
459     }
460 }
461
462 /* Read as the preterite of `read' */
463 void sockread(struct socket *sk)
464 {
465     if((sockgetdatalen(sk) == 0) && (sk->eos == 1))
466         linksock(&rbatch, sk);
467     linksock(&wbatch, sk->back);
468 }
469
470 void freedgbuf(struct dgrambuf *dg)
471 {
472     if(dg->data != NULL)
473         free(dg->data);
474     if(dg->addr != NULL)
475         free(dg->addr);
476     free(dg);
477 }
478
479 struct dgrambuf *sockgetdgbuf(struct socket *sk)
480 {
481     struct dgrambuf *dbuf;
482     
483     if((dbuf = sk->buf.d.f) == NULL)
484         return(NULL);
485     sk->buf.d.f = dbuf->next;
486     if(dbuf->next == NULL)
487         sk->buf.d.l = NULL;
488     dbuf->next = NULL;
489     sockread(sk);
490     return(dbuf);
491 }
492
493 void *sockgetinbuf(struct socket *sk, size_t *size)
494 {
495     void *buf;
496     struct dgrambuf *dbuf;
497     
498     if(sk->dgram) {
499         dbuf = sockgetdgbuf(sk);
500         buf = dbuf->data;
501         *size = dbuf->size;
502         free(dbuf->addr);
503         free(dbuf);
504     } else {
505         if((sk->buf.s.buf == NULL) || (sk->buf.s.datasize == 0))
506         {
507             *size = 0;
508             sockdebug(2, sk, "read 0 bytes", *size);
509             return(NULL);
510         }
511         buf = sk->buf.s.buf;
512         *size = sk->buf.s.datasize;
513         sk->buf.s.buf = NULL;
514         sk->buf.s.bufsize = sk->buf.s.datasize = 0;
515         sockread(sk);
516     }
517     sockdebug(2, sk, "read %ji bytes", *size);
518     return(buf);
519 }
520
521 void sockqueue(struct socket *sk, void *data, size_t size)
522 {
523     struct dgrambuf *new;
524     struct sockaddr *remote;
525     socklen_t remotelen;
526     
527     sockdebug(2, sk, "queued %ji bytes", size);
528     if(size == 0)
529         return;
530     if(sk->state == SOCK_STL)
531         return;
532     if(sk->dgram) {
533         if(sockpeeraddr(sk, &remote, &remotelen))
534             return;
535         new = smalloc(sizeof(*new));
536         new->next = NULL;
537         memcpy(new->data = smalloc(size), data, new->size = size);
538         new->addr = remote;
539         new->addrlen = remotelen;
540         if(sk->back->buf.d.l == NULL)
541         {
542             sk->back->buf.d.l = sk->back->buf.d.f = new;
543         } else {
544             sk->back->buf.d.l->next = new;
545             sk->back->buf.d.l = new;
546         }
547     } else {
548         sizebuf(&(sk->back->buf.s.buf), &(sk->back->buf.s.bufsize), sk->back->buf.s.datasize + size, 1, 1);
549         memcpy(sk->back->buf.s.buf + sk->back->buf.s.datasize, data, size);
550         sk->back->buf.s.datasize += size;
551     }
552     linksock(&rbatch, sk->back);
553 }
554
555 void sockqueuedg(struct socket *sk, struct dgrambuf *dg)
556 {
557     if(sk->state == SOCK_STL) {
558         freedgbuf(dg);
559         return;
560     }
561     if(!sk->dgram) {
562         flog(LOG_ERR, "BUG: sockqueuedg called on non-dgram socket");
563         freedgbuf(dg);
564         return;
565     }
566     dg->next = NULL;
567     if(sk->back->buf.d.l == NULL)
568     {
569         sk->back->buf.d.l = sk->back->buf.d.f = dg;
570     } else {
571         sk->back->buf.d.l->next = dg;
572         sk->back->buf.d.l = dg;
573     }
574     linksock(&rbatch, sk->back);
575 }
576
577 void sockerror(struct socket *sk, int en)
578 {
579     sksetstate(sk, SOCK_STL);
580     if(sk->back->errcb != NULL)
581         sk->back->errcb(sk->back, en, sk->back->data);
582 }
583
584 static void recvcmsg(struct ufd *ufd, struct msghdr *msg)
585 {
586     struct cmsghdr *cmsg;
587     
588     for(cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
589     {
590 #if UNIX_AUTH_STYLE == 1
591         if((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_CREDENTIALS))
592         {
593             struct ucred *cred;
594             if(ufd->d.s.ucred.uid == -1)
595             {
596                 cred = (struct ucred *)CMSG_DATA(cmsg);
597                 ufd->d.s.ucred.uid = cred->uid;
598                 ufd->d.s.ucred.gid = cred->gid;
599             }
600         }
601 #endif
602     }
603 }
604
605 static int ufddgram(struct ufd *ufd)
606 {
607     int dgram;
608
609     if(ufd->type == UFD_SOCK) {
610         dgram = ufd->d.s.type == SOCK_DGRAM;
611     } else if(ufd->type == UFD_PIPE) {
612         dgram = 0;
613     } else {
614         flog(LOG_ERR, "BUG: calling ufddgram on ufd of bad type %i", ufd->type);
615         return(-1);
616     }
617     if(ufd->sk == NULL) {
618         flog(LOG_ERR, "BUG: calling ufddgram on socketless ufd (type %i)", ufd->type);
619         return(-1);
620     }
621     if(dgram != ufd->sk->dgram) {
622         flog(LOG_ERR, "BUG: ufd/socket dgram value mismatch");
623         return(-1);
624     }
625     return(dgram);
626 }
627
628 static void sockrecv(struct ufd *ufd)
629 {
630     int ret, inq;
631     int dgram;
632     struct dgrambuf *dbuf;
633     struct msghdr msg;
634     char cbuf[65536];
635     struct iovec bufvec;
636     void *buf;
637     
638     memset(&msg, 0, sizeof(msg));
639     msg.msg_iov = &bufvec;
640     msg.msg_iovlen = 1;
641     msg.msg_control = cbuf;
642     msg.msg_controllen = sizeof(cbuf);
643     if((dgram = ufddgram(ufd)) < 0)
644         return;
645     if(dgram) {
646 #if defined(HAVE_LINUX_SOCKIOS_H) && defined(SIOCINQ)
647         if(ioctl(ufd->fd, SIOCINQ, &inq))
648         {
649             /* I don't really know what could go wrong here, so let's
650              * assume it's transient. */
651             flog(LOG_WARNING, "SIOCINQ return %s on socket %i", strerror(errno), ufd->fd);
652             return;
653         }
654 #else
655         inq = 65536;
656 #endif
657         dbuf = smalloc(sizeof(*dbuf));
658         dbuf->data = smalloc(inq);
659         dbuf->addr = smalloc(dbuf->addrlen = sizeof(struct sockaddr_storage));
660         msg.msg_name = dbuf->addr;
661         msg.msg_namelen = dbuf->addrlen;
662         bufvec.iov_base = dbuf->data;
663         bufvec.iov_len = inq;
664         ret = recvmsg(ufd->fd, &msg, 0);
665         dbuf->addrlen = msg.msg_namelen;
666         if(ret < 0)
667         {
668             freedgbuf(dbuf);
669             if((errno == EINTR) || (errno == EAGAIN))
670                 return;
671             closeufd(ufd);
672             sockerror(ufd->sk, errno);
673             return;
674         }
675         if(msg.msg_flags & MSG_CTRUNC)
676             flog(LOG_DEBUG, "ancillary data was truncated");
677         else
678             recvcmsg(ufd, &msg);
679         /* On UDP/IPv[46], ret == 0 doesn't mean EOF (since UDP can't
680          * have EOF), but rather an empty packet. I don't know if any
681          * other potential DGRAM protocols might have an EOF
682          * condition, so let's play safe. */
683         if(ret == 0)
684         {
685             freedgbuf(dbuf);
686             if((ufd->type != UFD_SOCK) || !((ufd->d.s.family == AF_INET) || (ufd->d.s.family == AF_INET6)))
687             {
688                 closesock(ufd->sk);
689                 closeufd(ufd);
690             }
691             return;
692         }
693         dbuf->addr = srealloc(dbuf->addr, dbuf->addrlen);
694         dbuf->data = srealloc(dbuf->data, dbuf->size = ret);
695         dbuf->next = NULL;
696         sockqueuedg(ufd->sk, dbuf);
697     } else {
698 #if defined(HAVE_LINUX_SOCKIOS_H) && defined(SIOCINQ)
699         /* SIOCINQ is Linux-specific AFAIK, but I really have no idea
700          * how to read the inqueue size on other OSs */
701         if(ufd->type == UFD_SOCK) {
702             if(ioctl(ufd->fd, SIOCINQ, &inq))
703             {
704                 /* I don't really know what could go wrong here, so let's
705                  * assume it's transient. */
706                 flog(LOG_WARNING, "SIOCINQ return %s on socket %i, falling back to 2048 bytes", strerror(errno), ufd->fd);
707                 inq = 2048;
708             }
709         } else {
710             /* There are perils when trying to use SIOCINQ on files >2GiB... */
711             inq = 65536;
712         }
713 #else
714         inq = 2048;
715 #endif
716         if(inq > 65536)
717             inq = 65536;
718         /* This part could be optimized by telling the kernel to read
719          * directly into ufd->sk->back->buf, but that would be uglier
720          * by not using the socket function interface. */
721         buf = smalloc(inq);
722         if(ufd->type == UFD_SOCK)
723         {
724             bufvec.iov_base = buf;
725             bufvec.iov_len = inq;
726             ret = recvmsg(ufd->fd, &msg, 0);
727         } else {
728             ret = read(ufd->fd, buf, inq);
729             msg.msg_controllen = 0;
730             msg.msg_flags = 0;
731         }
732         if(ret < 0)
733         {
734             free(buf);
735             if((errno == EINTR) || (errno == EAGAIN))
736                 return;
737             closeufd(ufd);
738             sockerror(ufd->sk, errno);
739             return;
740         }
741         if(msg.msg_flags & MSG_CTRUNC)
742             flog(LOG_DEBUG, "ancillary data was truncated");
743         else
744             recvcmsg(ufd, &msg);
745         if(ret == 0)
746         {
747             free(buf);
748             closeufd(ufd);
749             closesock(ufd->sk);
750             return;
751         }
752         sockqueue(ufd->sk, buf, ret);
753         free(buf);
754     }
755 }
756
757 static int sockflush(struct ufd *ufd)
758 {
759     int ret;
760     struct dgrambuf *dbuf;
761     int dgram;
762     
763     if((dgram = ufddgram(ufd)) < 0) {
764         errno = EBADFD;
765         return(-1);
766     }
767     if(dgram) {
768         dbuf = sockgetdgbuf(ufd->sk);
769         sendto(ufd->fd, dbuf->data, dbuf->size, MSG_DONTWAIT | MSG_NOSIGNAL, dbuf->addr, dbuf->addrlen);
770         freedgbuf(dbuf);
771     } else {
772         if(ufd->type == UFD_SOCK)
773             ret = send(ufd->fd, ufd->sk->buf.s.buf, ufd->sk->buf.s.datasize, MSG_DONTWAIT | MSG_NOSIGNAL);
774         else
775             ret = write(ufd->fd, ufd->sk->buf.s.buf, ufd->sk->buf.s.datasize);
776         if(ret < 0)
777             return(-1);
778         if(ret > 0) {
779             memmove(ufd->sk->buf.s.buf, ((char *)ufd->sk->buf.s.buf) + ret, ufd->sk->buf.s.datasize -= ret);
780             sockread(ufd->sk);
781         }
782     }
783     return(0);
784 }
785
786 void closesock(struct socket *sk)
787 {
788     sockdebug(1, sk, "closed");
789     sksetstate(sk, SOCK_STL);
790     if(sk->back->eos == 0)
791         sk->back->eos = 1;
792     linksock(&rbatch, sk->back);
793 }
794
795 size_t sockgetdatalen(struct socket *sk)
796 {
797     struct dgrambuf *b;
798     size_t ret;
799     
800     if(sk->dgram) {
801         ret = 0;
802         for(b = sk->buf.d.f; b != NULL; b = b->next)
803             ret += b->size;
804     } else {
805         ret = sk->buf.s.datasize;
806     }
807     return(ret);
808 }
809
810 /* size_t sockqueuesize(struct socket *sk) */
811 /* { */
812 /*     return(sockgetdatalen(sk->back)); */
813 /* } */
814
815 size_t socktqueuesize(struct socket *sk)
816 {
817     size_t ret;
818     
819     ret = 0;
820     while(1) {
821         ret += sockgetdatalen(sk->back);
822         if((sk = sk->back->pnext) == NULL)
823             return(ret);
824     }
825 }
826
827 ssize_t sockqueueleft(struct socket *sk)
828 {
829     return(sk->back->maxbuf - sockgetdatalen(sk->back));
830 }
831
832 /*
833  * Seriously, I don't know if it's naughty or not to remove
834  * pre-existing Unix sockets.
835  */
836 static int rebindunix(struct ufd *ufd, struct sockaddr *name, socklen_t namelen)
837 {
838     struct sockaddr_un *un;
839     struct stat sb;
840     
841     if((ufd->d.l.family != AF_UNIX) || (name->sa_family != PF_UNIX))
842         return(-1);
843     un = (struct sockaddr_un *)name;
844     if(stat(un->sun_path, &sb))
845         return(-1);
846     if(!S_ISSOCK(sb.st_mode))
847         return(-1);
848     if(unlink(un->sun_path))
849         return(-1);
850     if(bind(ufd->fd, name, namelen) < 0)
851         return(-1);
852     return(0);
853 }
854
855 void closelport(struct lport *lp)
856 {
857     struct ufd *ufd;
858     struct sockaddr_un *un;
859     
860     ufd = lp->ufd;
861     if((ufd->d.l.family == AF_UNIX) && !getlocalname(ufd->fd, (struct sockaddr **)(void *)&un, NULL) && (un->sun_family == PF_UNIX) && strchr(un->sun_path, '/')) {
862         if(unlink(un->sun_path))
863             flog(LOG_WARNING, "could not unlink Unix socket %s: %s", un->sun_path, strerror(errno));
864     }
865     freeufd(lp->ufd);
866 }
867
868 /*
869  * The difference between netcslisten() and netcslistenlocal() is that
870  * netcslistenlocal() always listens on the local host, instead of
871  * following proxy/passive mode directions. It is suitable for eg. the
872  * UI channel, while the file sharing networks should, naturally, use
873  * netcslisten() instead.
874 */
875
876 struct lport *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct lport *, struct socket *, void *), void *data)
877 {
878     struct lport *lp;
879     struct ufd *ufd;
880     int fd;
881     int intbuf;
882     
883     /* I don't know if this is actually correct (it probably isn't),
884      * but since, at on least Linux systems, PF_* are specifically
885      * #define'd to their AF_* counterparts, it allows for a severely
886      * smoother implementation. If it breaks something on your
887      * platform, please tell me so.
888      */
889     if((fd = socket(name->sa_family, type, 0)) < 0)
890         return(NULL);
891     if(confgetint("net", "reuseaddr")) {
892         intbuf = 1;
893         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &intbuf, sizeof(intbuf));
894     }
895     ufd = mkufd(fd, UFD_LISTEN, NULL);
896     ufd->d.l.family = name->sa_family;
897     lp = memset(smalloc(sizeof(*lp)), 0, sizeof(*lp));
898     lp->ufd = ufd;
899     ufd->d.l.lp = lp;
900     if((bind(fd, name, namelen) < 0) && ((errno != EADDRINUSE) || (rebindunix(ufd, name, namelen) < 0))) {
901         freeufd(ufd);
902         return(NULL);
903     }
904     if(listen(fd, 16) < 0)
905     {
906         freeufd(ufd);
907         return(NULL);
908     }
909     lp->acceptcb = func;
910     lp->data = data;
911     return(lp);
912 }
913
914 struct lport *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct lport *, struct socket *, void *), void *data)
915 {
916     if(confgetint("net", "mode") == 1)
917     {
918         errno = EOPNOTSUPP;
919         return(NULL);
920     }
921     if(confgetint("net", "mode") == 0)
922         return(netcslistenlocal(type, name, namelen, func, data));
923     errno = EOPNOTSUPP;
924     return(NULL);
925 }
926
927 struct lport *netcstcplisten(int port, int local, void (*func)(struct lport *, struct socket *, void *), void *data)
928 {
929     struct sockaddr_in addr;
930 #ifdef HAVE_IPV6
931     struct sockaddr_in6 addr6;
932 #endif
933     struct lport *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct lport *, struct socket *, void *), void *);
934     struct lport *ret;
935     
936     if(local)
937         csfunc = netcslistenlocal;
938     else
939         csfunc = netcslisten;
940 #ifdef HAVE_IPV6
941     memset(&addr6, 0, sizeof(addr6));
942     addr6.sin6_family = AF_INET6;
943     addr6.sin6_port = htons(port);
944     addr6.sin6_addr = in6addr_any;
945     if((ret = csfunc(SOCK_STREAM, (struct sockaddr *)&addr6, sizeof(addr6), func, data)) != NULL)
946         return(ret);
947     if((ret == NULL) && (errno != EAFNOSUPPORT))
948         return(NULL);
949 #endif
950     memset(&addr, 0, sizeof(addr));
951     addr.sin_family = AF_INET;
952     addr.sin_port = htons(port);
953     return(csfunc(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), func, data));
954 }
955
956 struct socket *netcsdgram(struct sockaddr *name, socklen_t namelen)
957 {
958     struct socket *sk;
959     int mode;
960     
961     mode = confgetint("net", "mode");
962     if((mode == 0) || (mode == 1))
963     {
964         if((sk = mksock(name->sa_family, SOCK_DGRAM)) == NULL)
965             return(NULL);
966         if(bind(sk->ufd->fd, name, namelen) < 0)
967         {
968             putsock(sk);
969             return(NULL);
970         }
971         sksetstate(sk, SOCK_EST);
972         return(sk->back);
973     }
974     errno = EOPNOTSUPP;
975     return(NULL);
976 }
977
978 struct socket *netdgramconn(struct socket *sk, struct sockaddr *addr, socklen_t addrlen)
979 {
980     struct ufd *nufd;
981     
982     nufd = dupufd(sk->back->ufd);
983     getsock(sk = nufd->sk->back);
984     memcpy(nufd->d.s.remote = smalloc(addrlen), addr, nufd->d.s.remotelen = addrlen);
985     nufd->ignread = 1;
986     return(sk);
987 }
988
989 struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data)
990 {
991     struct socket *sk;
992     int mode;
993     
994     mode = confgetint("net", "mode");
995     if((mode == 0) || (mode == 1))
996     {
997         if((sk = mksock(addr->sa_family, SOCK_STREAM)) == NULL)
998             return(NULL);
999         memcpy(sk->ufd->d.s.remote = smalloc(addrlen), addr, sk->ufd->d.s.remotelen = addrlen);
1000         sk->back->conncb = func;
1001         sk->back->data = data;
1002         if(!connect(sk->ufd->fd, addr, addrlen))
1003         {
1004             sksetstate(sk, SOCK_EST);
1005             linksock(&cbatch, sk->back);
1006             return(sk->back);
1007         }
1008         if(errno == EINPROGRESS)
1009         {
1010             sksetstate(sk, SOCK_SYN);
1011             return(sk->back);
1012         }
1013         putsock(sk);
1014         return(NULL);
1015     }
1016     errno = EOPNOTSUPP;
1017     return(NULL);
1018 }
1019
1020 static void acceptunix(struct ufd *ufd)
1021 {
1022     int buf;
1023     
1024     buf = 1;
1025 #if UNIX_AUTH_STYLE == 1
1026     if(setsockopt(ufd->fd, SOL_SOCKET, SO_PASSCRED, &buf, sizeof(buf)) < 0)
1027         flog(LOG_WARNING, "could not enable SO_PASSCRED on Unix socket %i: %s", ufd->fd, strerror(errno));
1028 #elif UNIX_AUTH_STYLE == 2
1029     if(getpeereid(ufd->fd, &ufd->d.s.ucred.uid, &ufd->d.s.ucred.gid) < 0)
1030     {
1031         flog(LOG_WARNING, "could not get peer creds on Unix socket %i: %s", ufd->fd, strerror(errno));
1032         ufd->d.s.ucred.uid = -1;
1033         ufd->d.s.ucred.gid = -1;
1034     }
1035 #endif
1036 }
1037
1038 static void runbatches(void)
1039 {
1040     struct scons *sc, *nsc;
1041
1042     for(sc = cbatch, cbatch = NULL; sc; sc = nsc) {
1043         nsc = sc->n;
1044         if(sc->s->conncb != NULL)
1045             sc->s->conncb(sc->s, 0, sc->s->data);
1046         putsock(sc->s);
1047         free(sc);
1048     }
1049     for(sc = rbatch, rbatch = NULL; sc; sc = nsc) {
1050         nsc = sc->n;
1051         if(sc->s->readcb != NULL)
1052             sc->s->readcb(sc->s, sc->s->data);
1053         if((sockgetdatalen(sc->s) == 0) && (sc->s->eos == 1)) {
1054             if(sc->s->errcb != NULL)
1055                 sc->s->errcb(sc->s, 0, sc->s->data);
1056             sc->s->eos = 2;
1057         }
1058         putsock(sc->s);
1059         free(sc);
1060     }
1061     for(sc = wbatch, wbatch = NULL; sc; sc = nsc) {
1062         nsc = sc->n;
1063         if(sc->s->writecb != NULL)
1064             sc->s->writecb(sc->s, sc->s->data);
1065         putsock(sc->s);
1066         free(sc);
1067     }
1068 }
1069
1070 static void cleansocks(void)
1071 {
1072     struct ufd *ufd, *next;
1073     
1074     for(ufd = ufds; ufd != NULL; ufd = next) {
1075         next = ufd->next;
1076         if(ufd->sk && ((ufd->fd < 0) || (sockgetdatalen(ufd->sk) == 0))) {
1077             if(ufd->sk->eos == 1) {
1078                 ufd->sk->eos = 2;
1079                 closeufd(ufd);
1080                 closesock(ufd->sk);
1081             }
1082             if((ufd->sk->refcount == 1) && (ufd->sk->back->refcount == 0)) {
1083                 freeufd(ufd);
1084                 continue;
1085             }
1086         }
1087     }
1088 }
1089
1090 int pollsocks(int timeout)
1091 {
1092     int ret;
1093     socklen_t retlen;
1094     int newfd, maxfd;
1095     fd_set rfds, wfds, efds;
1096     struct ufd *ufd, *nufd;
1097     struct socket *nsk;
1098     struct sockaddr_storage ss;
1099     socklen_t sslen;
1100     struct timeval tv;
1101     
1102     cleansocks();
1103     FD_ZERO(&rfds);
1104     FD_ZERO(&wfds);
1105     FD_ZERO(&efds);
1106     for(maxfd = 0, ufd = ufds; ufd != NULL; ufd = ufd->next) {
1107         if(ufd->fd < 0)
1108             continue;
1109         if(!ufd->ignread && ((ufd->sk == NULL) || (sockqueueleft(ufd->sk) > 0)))
1110             FD_SET(ufd->fd, &rfds);
1111         if(ufd->sk != NULL) {
1112             if(sockgetdatalen(ufd->sk) > 0)
1113                 FD_SET(ufd->fd, &wfds);
1114             else if(ufd->sk->state == SOCK_SYN)
1115                 FD_SET(ufd->fd, &wfds);
1116         }
1117         FD_SET(ufd->fd, &efds);
1118         if(ufd->fd > maxfd)
1119             maxfd = ufd->fd;
1120     }
1121     if(rbatch || wbatch || cbatch)
1122         timeout = 0;
1123     tv.tv_sec = timeout / 1000;
1124     tv.tv_usec = (timeout % 1000) * 1000;
1125     ret = select(maxfd + 1, &rfds, &wfds, &efds, (timeout < 0)?NULL:&tv);
1126     if(ret < 0) {
1127         if(errno != EINTR) {
1128             flog(LOG_CRIT, "pollsocks: select errored out: %s", strerror(errno));
1129             /* To avoid CPU hogging in case it's bad, which it
1130              * probably is. */
1131             sleep(1);
1132         }
1133         return(1);
1134     }
1135     for(ufd = ufds; ufd != NULL; ufd = ufd->next) {
1136         if(ufd->sk < 0)
1137             continue;
1138         if(ufd->type == UFD_LISTEN) {
1139             if(FD_ISSET(ufd->fd, &rfds)) {
1140                 sslen = sizeof(ss);
1141                 if((newfd = accept(ufd->fd, (struct sockaddr *)&ss, &sslen)) < 0) {
1142                     if(ufd->d.l.lp->errcb != NULL)
1143                         ufd->d.l.lp->errcb(ufd->d.l.lp, errno, ufd->d.l.lp->data);
1144                 }
1145                 nsk = sockpair(0);
1146                 nufd = mkufd(newfd, UFD_SOCK, nsk);
1147                 nufd->d.s.family = ufd->d.l.family;
1148                 sksetstate(nsk, SOCK_EST);
1149                 memcpy(nufd->d.s.remote = smalloc(sslen), &ss, sslen);
1150                 nufd->d.s.remotelen = sslen;
1151                 if(ss.ss_family == PF_UNIX)
1152                     acceptunix(nufd);
1153                 if(ufd->d.l.lp->acceptcb != NULL)
1154                     ufd->d.l.lp->acceptcb(ufd->d.l.lp, nsk->back, ufd->d.l.lp->data);
1155                 putsock(nsk);
1156             }
1157             if(FD_ISSET(ufd->fd, &efds)) {
1158                 retlen = sizeof(ret);
1159                 getsockopt(ufd->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
1160                 if(ufd->d.l.lp->errcb != NULL)
1161                     ufd->d.l.lp->errcb(ufd->d.l.lp, ret, ufd->d.l.lp->data);
1162                 continue;
1163             }
1164         } else {
1165             if(ufd->sk->state == SOCK_SYN) {
1166                 if(FD_ISSET(ufd->fd, &efds)) {
1167                     retlen = sizeof(ret);
1168                     getsockopt(ufd->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
1169                     if(ufd->sk->back->conncb != NULL)
1170                         ufd->sk->back->conncb(ufd->sk->back, ret, ufd->sk->back->data);
1171                     closeufd(ufd);
1172                     continue;
1173                 }
1174                 if(FD_ISSET(ufd->fd, &rfds) || FD_ISSET(ufd->fd, &wfds)) {
1175                     sksetstate(ufd->sk, SOCK_EST);
1176                     linksock(&cbatch, ufd->sk->back);
1177                 }
1178             } else if(ufd->sk->state == SOCK_EST) {
1179                 if(FD_ISSET(ufd->fd, &efds)) {
1180                     retlen = sizeof(ret);
1181                     getsockopt(ufd->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
1182                     sockerror(ufd->sk, ret);
1183                     closeufd(ufd);
1184                     continue;
1185                 }
1186                 if(FD_ISSET(ufd->fd, &rfds))
1187                     sockrecv(ufd);
1188                 if(ufd->fd == -1)
1189                     continue;
1190                 if(FD_ISSET(ufd->fd, &wfds)) {
1191                     if(sockflush(ufd)) {
1192                         sockerror(ufd->sk, errno);
1193                         closeufd(ufd);
1194                         continue;
1195                     }
1196                 }
1197             }
1198         }
1199     }
1200     runbatches();
1201     cleansocks();
1202     return(1);
1203 }
1204
1205 static struct ufd *getskufd(struct socket *sk)
1206 {
1207     while(1) {
1208         if(sk->back->ufd != NULL)
1209             return(sk->back->ufd);
1210         if((sk = sk->back->pnext) == NULL)
1211             break;
1212     }
1213     return(NULL);
1214 }
1215
1216 int socksettos(struct socket *sk, int tos)
1217 {
1218     int buf;
1219     struct ufd *ufd;
1220     
1221     ufd = getskufd(sk);
1222     if(ufd->type != UFD_SOCK) {
1223         errno = EOPNOTSUPP;
1224         return(-1);
1225     }
1226     if(ufd->d.s.family == AF_UNIX)
1227         return(0); /* Unix sockets are always perfect. :) */
1228     if(ufd->d.s.family == AF_INET)
1229     {
1230         switch(tos)
1231         {
1232         case 0:
1233             buf = 0;
1234             break;
1235         case SOCK_TOS_MINCOST:
1236             buf = 0x02;
1237             break;
1238         case SOCK_TOS_MAXREL:
1239             buf = 0x04;
1240             break;
1241         case SOCK_TOS_MAXTP:
1242             buf = 0x08;
1243             break;
1244         case SOCK_TOS_MINDELAY:
1245             buf = 0x10;
1246             break;
1247         default:
1248             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
1249             return(-1);
1250         }
1251         if(setsockopt(ufd->fd, IPPROTO_IP, IP_TOS, &buf, sizeof(buf)) < 0)
1252         {
1253             flog(LOG_WARNING, "could not set sock TOS to %i: %s", tos, strerror(errno));
1254             return(-1);
1255         }
1256         return(0);
1257     }
1258     if(ufd->d.s.family == AF_INET6)
1259     {
1260         switch(tos)
1261         {
1262         case 0:
1263             buf = 0;
1264         case SOCK_TOS_MINCOST:
1265             buf = confgetint("net", "diffserv-mincost");
1266             break;
1267         case SOCK_TOS_MAXREL:
1268             buf = confgetint("net", "diffserv-maxrel");
1269             break;
1270         case SOCK_TOS_MAXTP:
1271             buf = confgetint("net", "diffserv-maxtp");
1272             break;
1273         case SOCK_TOS_MINDELAY:
1274             buf = confgetint("net", "diffserv-mindelay");
1275             break;
1276         default:
1277             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
1278             return(-1);
1279         }
1280         /*
1281           On Linux, the API IPv6 flow label management doesn't seem to
1282           be entirely complete, so I guess this will have to wait.
1283           
1284         if(setsockopt(...) < 0)
1285         {
1286             flog(LOG_WARNING, "could not set sock traffic class to %i: %s", tos, strerror(errno));
1287             return(-1);
1288         }
1289         */
1290         return(0);
1291     }
1292     flog(LOG_WARNING, "could not set TOS on sock of family %i", ufd->d.s.family);
1293     return(1);
1294 }
1295
1296 struct resolvedata
1297 {
1298     int fd;
1299     void (*callback)(struct sockaddr *addr, int addrlen, void *data);
1300     void *data;
1301     struct sockaddr_storage addr;
1302     int addrlen;
1303 };
1304
1305 static void resolvecb(pid_t pid, int status, struct resolvedata *data)
1306 {
1307     static char buf[80];
1308     int ret;
1309     struct sockaddr_in *ipv4;
1310     
1311     if(!status)
1312     {
1313         if((ret = read(data->fd, buf, sizeof(buf))) != 4)
1314         {
1315             errno = ENOENT;
1316             data->callback(NULL, 0, data->data);
1317         } else {
1318             ipv4 = (struct sockaddr_in *)&data->addr;
1319             memcpy(&ipv4->sin_addr, buf, 4);
1320             data->callback((struct sockaddr *)ipv4, sizeof(*ipv4), data->data);
1321         }
1322     } else {
1323         errno = ENOENT;
1324         data->callback(NULL, 0, data->data);
1325     }
1326     close(data->fd);
1327     free(data);
1328 }
1329
1330 int netresolve(char *addr, void (*callback)(struct sockaddr *addr, int addrlen, void *data), void *data)
1331 {
1332     int i;
1333     char *p;
1334     int port;
1335     int pfd[2];
1336     pid_t child;
1337     struct resolvedata *rdata;
1338     struct sockaddr_in ipv4;
1339     struct hostent *he;
1340     sigset_t sigset;
1341     
1342     /* IPv4 */
1343     port = -1;
1344     if((p = strchr(addr, ':')) != NULL)
1345     {
1346         *p = 0;
1347         port = atoi(p + 1);
1348     }
1349     ipv4.sin_family = AF_INET;
1350     ipv4.sin_port = htons(port);
1351     if(inet_aton(addr, &ipv4.sin_addr))
1352     {
1353         callback((struct sockaddr *)&ipv4, sizeof(ipv4), data);
1354     } else {
1355         sigemptyset(&sigset);
1356         sigaddset(&sigset, SIGCHLD);
1357         sigprocmask(SIG_BLOCK, &sigset, NULL);
1358         if((pipe(pfd) < 0) || ((child = fork()) < 0))
1359         {
1360             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1361             return(-1);
1362         }
1363         if(child == 0)
1364         {
1365             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1366             for(i = 3; i < FD_SETSIZE; i++)
1367             {
1368                 if(i != pfd[1])
1369                     close(i);
1370             }
1371             signal(SIGALRM, SIG_DFL);
1372             alarm(30);
1373             if((he = gethostbyname(addr)) == NULL)
1374                 exit(1);
1375             write(pfd[1], he->h_addr_list[0], 4);
1376             exit(0);
1377         } else {
1378             close(pfd[1]);
1379             fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK);
1380             rdata = smalloc(sizeof(*rdata));
1381             rdata->fd = pfd[0];
1382             rdata->callback = callback;
1383             rdata->data = data;
1384             memcpy(&rdata->addr, &ipv4, rdata->addrlen = sizeof(ipv4));
1385             childcallback(child, (void (*)(pid_t, int, void *))resolvecb, rdata);
1386             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1387             return(1);
1388         }
1389     }
1390     return(0);
1391 }
1392
1393 static int getlocalname(int fd, struct sockaddr **namebuf, socklen_t *lenbuf)
1394 {
1395     socklen_t len;
1396     struct sockaddr_storage name;
1397     
1398     *namebuf = NULL;
1399     if(fd < 0)
1400         return(-1);
1401     len = sizeof(name);
1402     if(getsockname(fd, (struct sockaddr *)&name, &len) < 0)
1403     {
1404         flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetlocalname (%s)", strerror(errno));
1405         return(-1);
1406     }
1407     *namebuf = memcpy(smalloc(len), &name, len);
1408     if(lenbuf != NULL)
1409         *lenbuf = len;
1410     return(0);
1411 }
1412
1413 int lstgetlocalname(struct lport *lp, struct sockaddr **namebuf, socklen_t *lenbuf)
1414 {
1415     struct ufd *ufd;
1416
1417     ufd = lp->ufd;
1418     return(getlocalname(ufd->fd, namebuf, lenbuf));
1419 }
1420
1421 int sockgetlocalname(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1422 {
1423     struct ufd *ufd;
1424
1425     ufd = getskufd(sk);
1426     if(ufd->type != UFD_SOCK) {
1427         errno = EOPNOTSUPP;
1428         return(-1);
1429     }
1430     return(getlocalname(ufd->fd, namebuf, lenbuf));
1431 }
1432
1433 static void sethostaddr(struct sockaddr *dst, struct sockaddr *src)
1434 {
1435     if(dst->sa_family != src->sa_family)
1436     {
1437         flog(LOG_ERR, "BUG: non-matching socket families in sethostaddr (%i -> %i)", src->sa_family, dst->sa_family);
1438         return;
1439     }
1440     switch(src->sa_family)
1441     {
1442     case AF_INET:
1443         ((struct sockaddr_in *)dst)->sin_addr = ((struct sockaddr_in *)src)->sin_addr;
1444         break;
1445     case AF_INET6:
1446         ((struct sockaddr_in6 *)dst)->sin6_addr = ((struct sockaddr_in6 *)src)->sin6_addr;
1447         break;
1448     default:
1449         flog(LOG_WARNING, "sethostaddr unimplemented for family %i", src->sa_family);
1450         break;
1451     }
1452 }
1453
1454 static int makepublic(struct sockaddr *addr)
1455 {
1456     int ret;
1457     socklen_t plen;
1458     struct sockaddr *pname;
1459     
1460     if((ret = getpublicaddr(addr->sa_family, &pname, &plen)) < 0)
1461     {
1462         flog(LOG_ERR, "could not get public address: %s", strerror(errno));
1463         return(-1);
1464     }
1465     if(ret)
1466         return(0);
1467     sethostaddr(addr, pname);
1468     free(pname);
1469     return(0);
1470 }
1471
1472 static int getremotename(int fd, struct sockaddr **namebuf, socklen_t *lenbuf)
1473 {
1474     socklen_t len;
1475     struct sockaddr *name;
1476
1477     switch(confgetint("net", "mode")) {
1478     case 0:
1479         *namebuf = NULL;
1480         if(!getlocalname(fd, &name, &len)) {
1481             *namebuf = name;
1482             *lenbuf = len;
1483             makepublic(name);
1484             return(0);
1485         }
1486         flog(LOG_ERR, "could not get remotely accessible name by any means");
1487         return(-1);
1488     case 1:
1489         errno = EOPNOTSUPP;
1490         return(-1);
1491     default:
1492         flog(LOG_CRIT, "unknown net mode %i active", confgetint("net", "mode"));
1493         errno = EOPNOTSUPP;
1494         return(-1);
1495     }
1496 }
1497
1498 int sockgetremotename(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1499 {
1500     struct ufd *ufd;
1501     
1502     ufd = getskufd(sk);
1503     if(ufd->type != UFD_SOCK) {
1504         errno = EOPNOTSUPP;
1505         return(-1);
1506     }
1507     if(ufd->fd < 0) {
1508         errno = EBADF;
1509         return(-1);
1510     }
1511     return(getremotename(ufd->fd, namebuf, lenbuf));
1512 }
1513
1514 int lstgetremotename(struct lport *lp, struct sockaddr **namebuf, socklen_t *lenbuf)
1515 {
1516     struct ufd *ufd;
1517     
1518     ufd = lp->ufd;
1519     return(getremotename(ufd->fd, namebuf, lenbuf));
1520 }
1521
1522 int sockgetremotename2(struct socket *sk, struct socket *sk2, struct sockaddr **namebuf, socklen_t *lenbuf)
1523 {
1524     struct sockaddr *name1, *name2;
1525     socklen_t len1, len2;
1526     struct ufd *ufd1, *ufd2;
1527     
1528     ufd1 = getskufd(sk);
1529     ufd2 = getskufd(sk2);
1530     if((ufd1->type != UFD_SOCK) || (ufd2->type != UFD_SOCK)) {
1531         errno = EOPNOTSUPP;
1532         return(-1);
1533     }
1534     if(ufd1->d.s.family != ufd2->d.s.family)
1535     {
1536         flog(LOG_ERR, "using sockgetremotename2 with sockets of differing family: %i %i", ufd1->d.s.family, ufd2->d.s.family);
1537         return(-1);
1538     }
1539     if(getremotename(ufd1->fd, &name1, &len1))
1540         return(-1);
1541     if(getremotename(ufd2->fd, &name2, &len2)) {
1542         free(name1);
1543         return(-1);
1544     }
1545     sethostaddr(name1, name2);
1546     free(name2);
1547     *namebuf = name1;
1548     *lenbuf = len1;
1549     return(0);
1550 }
1551
1552 int lstgetremotename2(struct lport *lp, struct socket *sk2, struct sockaddr **namebuf, socklen_t *lenbuf)
1553 {
1554     struct sockaddr *name1, *name2;
1555     socklen_t len1, len2;
1556     struct ufd *ufd1, *ufd2;
1557     
1558     ufd1 = lp->ufd;
1559     ufd2 = getskufd(sk2);
1560     if(ufd2->type != UFD_SOCK) {
1561         errno = EOPNOTSUPP;
1562         return(-1);
1563     }
1564     if(ufd1->d.l.family != ufd2->d.s.family)
1565     {
1566         flog(LOG_ERR, "using lstgetremotename2 with sockets of differing family: %i %i", ufd1->d.l.family, ufd2->d.s.family);
1567         return(-1);
1568     }
1569     if(getremotename(ufd1->fd, &name1, &len1))
1570         return(-1);
1571     if(getremotename(ufd2->fd, &name2, &len2)) {
1572         free(name1);
1573         return(-1);
1574     }
1575     sethostaddr(name1, name2);
1576     free(name2);
1577     *namebuf = name1;
1578     *lenbuf = len1;
1579     return(0);
1580 }
1581
1582 int getucred(struct socket *sk, uid_t *uid, gid_t *gid)
1583 {
1584     struct ufd *ufd;
1585     
1586     ufd = getskufd(sk);
1587     if(ufd->type != UFD_SOCK) {
1588         errno = EOPNOTSUPP;
1589         return(-1);
1590     }
1591     if(ufd->d.s.family != AF_UNIX) {
1592         errno = EOPNOTSUPP;
1593         return(-1);
1594     }
1595     *uid = ufd->d.s.ucred.uid;
1596     *gid = ufd->d.s.ucred.gid;
1597     return(0);
1598 }
1599
1600 /* void sockblock(struct socket *sk, int block) */
1601 /* { */
1602 /*     struct ufd *ufd; */
1603     
1604 /*     ufd = getskufd(sk); */
1605 /*     ufd->ignread = block; */
1606 /* } */
1607
1608 int sockfamily(struct socket *sk)
1609 {
1610     struct ufd *ufd;
1611     
1612     ufd = getskufd(sk);
1613     if(ufd->type != UFD_SOCK) {
1614         errno = EOPNOTSUPP;
1615         return(-1);
1616     }
1617     return(ufd->d.s.family);
1618 }
1619
1620 int sockpeeraddr(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1621 {
1622     struct ufd *ufd;
1623     
1624     ufd = getskufd(sk);
1625     if(ufd->type != UFD_SOCK) {
1626         errno = EOPNOTSUPP;
1627         return(-1);
1628     }
1629     if(ufd->d.s.remote == NULL)
1630         return(-1);
1631     *namebuf = memcpy(smalloc(ufd->d.s.remotelen), ufd->d.s.remote, ufd->d.s.remotelen);
1632     if(lenbuf != NULL)
1633         *lenbuf = ufd->d.s.remotelen;
1634     return(0);
1635 }
1636
1637 char *formatsockpeer(struct socket *sk)
1638 {
1639     struct sockaddr *name;
1640     socklen_t nlen;
1641     char *ret;
1642     
1643     if(sockpeeraddr(sk, &name, &nlen))
1644         return(NULL);
1645     ret = formataddress(name, nlen);
1646     free(name);
1647     return(ret);
1648 }
1649
1650 int addreq(struct sockaddr *x, struct sockaddr *y)
1651 {
1652     struct sockaddr_un *u1, *u2;
1653     struct sockaddr_in *n1, *n2;
1654 #ifdef HAVE_IPV6
1655     struct sockaddr_in6 *s1, *s2;
1656 #endif
1657     
1658     if(x->sa_family != y->sa_family)
1659         return(0);
1660     switch(x->sa_family) {
1661     case AF_UNIX:
1662         u1 = (struct sockaddr_un *)x; u2 = (struct sockaddr_un *)y;
1663         if(strncmp(u1->sun_path, u2->sun_path, sizeof(u1->sun_path)))
1664             return(0);
1665         break;
1666     case AF_INET:
1667         n1 = (struct sockaddr_in *)x; n2 = (struct sockaddr_in *)y;
1668         if(n1->sin_port != n2->sin_port)
1669             return(0);
1670         if(n1->sin_addr.s_addr != n2->sin_addr.s_addr)
1671             return(0);
1672         break;
1673 #ifdef HAVE_IPV6
1674     case AF_INET6:
1675         s1 = (struct sockaddr_in6 *)x; s2 = (struct sockaddr_in6 *)y;
1676         if(s1->sin6_port != s2->sin6_port)
1677             return(0);
1678         if(memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr)))
1679             return(0);
1680         break;
1681 #endif
1682     }
1683     return(1);
1684 }
1685
1686 char *formataddress(struct sockaddr *arg, socklen_t arglen)
1687 {
1688     struct sockaddr_in *ipv4;
1689 #ifdef HAVE_IPV6
1690     struct sockaddr_in6 *ipv6;
1691 #endif
1692     static char *ret = NULL;
1693     char buf[1024];
1694     
1695     if(ret != NULL)
1696         free(ret);
1697     ret = NULL;
1698     switch(arg->sa_family)
1699     {
1700     case AF_UNIX:
1701         ret = sstrdup("Unix socket");
1702         break;
1703     case AF_INET:
1704         ipv4 = (struct sockaddr_in *)arg;
1705         if(inet_ntop(AF_INET, &ipv4->sin_addr, buf, sizeof(buf)) == NULL)
1706             return(NULL);
1707         ret = sprintf2("%s:%i", buf, (int)ntohs(ipv4->sin_port));
1708         break;
1709 #ifdef HAVE_IPV6
1710     case AF_INET6:
1711         ipv6 = (struct sockaddr_in6 *)arg;
1712         if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL)
1713             return(NULL);
1714         ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port));
1715         break;
1716 #endif
1717     default:
1718         errno = EPFNOSUPPORT;
1719         break;
1720     }
1721     return(ret);
1722 }
1723
1724 #if 0
1725
1726 /* 
1727  * It was very nice to use this, but it seems
1728  * to mess things up, so I guess it has to go... :-(
1729  */
1730
1731 static int formataddress(FILE *stream, const struct printf_info *info, const void *const *args)
1732 {
1733     struct sockaddr *arg;
1734     socklen_t arglen;
1735     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1736                                * lowercase letters to 1, so I do this
1737                                * instead. */
1738     struct sockaddr_in *ipv4;
1739     int ret;
1740     
1741     arg = *(struct sockaddr **)(args[0]);
1742     arglen = *(socklen_t *)(args[1]);
1743     switch(arg->sa_family)
1744     {
1745     case AF_UNIX:
1746         UNIX = (struct sockaddr_un *)arg;
1747         ret = fprintf(stream, "%s", UNIX->sun_path);
1748         break;
1749     case AF_INET:
1750         ipv4 = (struct sockaddr_in *)arg;
1751         ret = fprintf(stream, "%s:%i", inet_ntoa(ipv4->sin_addr), (int)ntohs(ipv4->sin_port));
1752         break;
1753     default:
1754         ret = -1;
1755         errno = EPFNOSUPPORT;
1756         break;
1757     }
1758     return(ret);
1759 }
1760
1761 static int formataddress_arginfo(const struct printf_info *info, size_t n, int *argtypes)
1762 {
1763     if(n > 0)
1764         argtypes[0] = PA_POINTER;
1765     if(n > 1)
1766         argtypes[1] = PA_INT; /* Sources tell me that socklen_t _must_
1767                                * be an int, so I guess this should be
1768                                * safe. */
1769     return(2);
1770 }
1771 #endif
1772
1773 static int init(int hup)
1774 {
1775     if(!hup)
1776     {
1777         /*
1778         if(register_printf_function('N', formataddress, formataddress_arginfo))
1779         {
1780             flog(LOG_CRIT, "could not register printf handler %%N: %s", strerror(errno));
1781             return(1);
1782         }
1783         */
1784     }
1785     return(0);
1786 }
1787
1788 static void terminate(void)
1789 {
1790     /*
1791     while(ufds != NULL)
1792         freeufd(ufds);
1793     */
1794 }
1795
1796 static struct module me =
1797 {
1798     .name = "net",
1799     .conf =
1800     {
1801         .vars = myvars
1802     },
1803     .init = init,
1804     .terminate = terminate
1805 };
1806
1807 MODULE(me)