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