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