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