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