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