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