Remove printf.h, since it is no longer used.
[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/poll.h>
32 #include <arpa/inet.h>
33 #include <netinet/in.h>
34 #include <netdb.h>
35 #include <sys/signal.h>
36 #ifdef HAVE_LINUX_SOCKIOS_H
37 #include <linux/sockios.h>
38 #endif
39 #include <errno.h>
40 #include <net/if.h>
41
42 #include "conf.h"
43 #include "net.h"
44 #include "module.h"
45 #include "log.h"
46 #include "utils.h"
47 #include "sysevents.h"
48
49 static struct configvar myvars[] =
50 {
51     /* 0 = Direct mode, 1 = Passive mode, 2 = SOCKS proxy */
52     {CONF_VAR_INT, "mode", {.num = 0}},
53     {CONF_VAR_BOOL, "reuseaddr", {.num = 0}},
54     /* Only for direct mode */
55     {CONF_VAR_IPV4, "visibleipv4", {.ipv4 = {0}}},
56     {CONF_VAR_STRING, "publicif", {.str = L""}},
57     /* Diffserv should be supported on IPv4, too, but I don't know the
58      * API to do that. */
59     {CONF_VAR_INT, "diffserv-mincost", {.num = 0}},
60     {CONF_VAR_INT, "diffserv-maxrel", {.num = 0}},
61     {CONF_VAR_INT, "diffserv-maxtp", {.num = 0}},
62     {CONF_VAR_INT, "diffserv-mindelay", {.num = 0}},
63     {CONF_VAR_END}
64 };
65
66 static struct socket *sockets = NULL;
67 int numsocks = 0;
68
69 /* XXX: Get autoconf for all this... */
70 int getpublicaddr(int af, struct sockaddr **addr, socklen_t *lenbuf)
71 {
72     struct sockaddr_in *ipv4;
73     struct configvar *var;
74     void *bufend;
75     int sock;
76     struct ifconf conf;
77     struct ifreq *ifr, req;
78     char *pif;
79     
80     if(af == AF_INET)
81     {
82         var = confgetvar("net", "visibleipv4");
83         if(var->val.ipv4.s_addr != 0)
84         {
85             ipv4 = smalloc(sizeof(*ipv4));
86             ipv4->sin_family = AF_INET;
87             ipv4->sin_addr.s_addr = var->val.ipv4.s_addr;
88             *addr = (struct sockaddr *)ipv4;
89             *lenbuf = sizeof(*ipv4);
90             return(0);
91         }
92         if((pif = icswcstombs(confgetstr("net", "publicif"), NULL, NULL)) == NULL)
93         {
94             flog(LOG_ERR, "could not convert net.publicif into local charset: %s", strerror(errno));
95             return(-1);
96         }
97         if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
98             return(-1);
99         conf.ifc_buf = smalloc(conf.ifc_len = 65536);
100         if(ioctl(sock, SIOCGIFCONF, &conf) < 0)
101         {
102             free(conf.ifc_buf);
103             close(sock);
104             return(-1);
105         }
106         bufend = ((char *)conf.ifc_buf) + conf.ifc_len;
107         ipv4 = NULL;
108         for(ifr = conf.ifc_ifcu.ifcu_req; (void *)ifr < bufend; ifr++)
109         {
110             memset(&req, 0, sizeof(req));
111             memcpy(req.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
112             if(ioctl(sock, SIOCGIFFLAGS, &req) < 0)
113             {
114                 free(conf.ifc_buf);
115                 close(sock);
116                 return(-1);
117             }
118             if(!(req.ifr_flags & IFF_UP))
119                 continue;
120             if(ifr->ifr_addr.sa_family == AF_INET)
121             {
122                 if(ntohl(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr) == 0x7f000001)
123                     continue;
124                 if(ipv4 == NULL)
125                 {
126                     ipv4 = smalloc(sizeof(*ipv4));
127                     memcpy(ipv4, &ifr->ifr_addr, sizeof(ifr->ifr_addr));
128                 } else {
129                     free(ipv4);
130                     free(conf.ifc_buf);
131                     flog(LOG_WARNING, "could not locate an unambiguous interface for determining your public IP address - set net.publicif");
132                     errno = ENFILE; /* XXX: There's no appropriate one for this... */
133                     return(-1);
134                 }
135             }
136         }
137         free(conf.ifc_buf);
138         close(sock);
139         if(ipv4 != NULL)
140         {
141             *addr = (struct sockaddr *)ipv4;
142             *lenbuf = sizeof(*ipv4);
143             return(0);
144         }
145         errno = ENETDOWN;
146         return(-1);
147     }
148     errno = EPFNOSUPPORT;
149     return(-1);
150 }
151
152 static struct socket *newsock(int type)
153 {
154     struct socket *new;
155     
156     new = smalloc(sizeof(*new));
157     new->refcount = 2;
158     new->fd = -1;
159     new->isrealsocket = 1;
160     new->family = -1;
161     new->tos = 0;
162     new->type = type;
163     new->state = -1;
164     new->ignread = 0;
165     new->close = 0;
166     new->remote = NULL;
167     new->remotelen = 0;
168     switch(type)
169     {
170     case SOCK_STREAM:
171         new->outbuf.s.buf = NULL;
172         new->outbuf.s.bufsize = 0;
173         new->outbuf.s.datasize = 0;
174         new->inbuf.s.buf = NULL;
175         new->inbuf.s.bufsize = 0;
176         new->inbuf.s.datasize = 0;
177         break;
178     case SOCK_DGRAM:
179         new->outbuf.d.f = new->outbuf.d.l = NULL;
180         new->inbuf.d.f = new->inbuf.d.l = NULL;
181         break;
182     }
183     new->conncb = NULL;
184     new->errcb = NULL;
185     new->readcb = NULL;
186     new->writecb = NULL;
187     new->acceptcb = NULL;
188     new->next = sockets;
189     new->prev = NULL;
190     if(sockets != NULL)
191         sockets->prev = new;
192     sockets = new;
193     numsocks++;
194     return(new);
195 }
196
197 static struct socket *mksock(int domain, int type)
198 {
199     int fd;
200     struct socket *new;
201     
202     if((fd = socket(domain, type, 0)) < 0)
203     {
204         flog(LOG_CRIT, "could not create socket: %s", strerror(errno));
205         return(NULL);
206     }
207     new = newsock(type);
208     new->fd = fd;
209     new->family = domain;
210     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
211     return(new);
212 }
213
214 struct socket *wrapsock(int fd)
215 {
216     struct socket *new;
217     
218     new = newsock(SOCK_STREAM);
219     new->fd = fd;
220     new->state = SOCK_EST;
221     new->isrealsocket = 0;
222     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
223     return(new);
224 }
225
226 static void unlinksock(struct socket *sk)
227 {
228     if(sk->prev != NULL)
229         sk->prev->next = sk->next;
230     if(sk->next != NULL)
231         sk->next->prev = sk->prev;
232     if(sk == sockets)
233         sockets = sk->next;
234     putsock(sk);
235     numsocks--;
236 }
237
238 void getsock(struct socket *sk)
239 {
240     sk->refcount++;
241 }
242
243 void putsock(struct socket *sk)
244 {
245     struct dgrambuf *buf;
246     
247     if(--(sk->refcount) == 0)
248     {
249         switch(sk->type)
250         {
251         case SOCK_STREAM:
252             if(sk->outbuf.s.buf != NULL)
253                 free(sk->outbuf.s.buf);
254             if(sk->inbuf.s.buf != NULL)
255                 free(sk->inbuf.s.buf);
256             break;
257         case SOCK_DGRAM:
258             while((buf = sk->outbuf.d.f) != NULL)
259             {
260                 sk->outbuf.d.f = buf->next;
261                 free(buf->data);
262                 free(buf);
263             }
264             while((buf = sk->inbuf.d.f) != NULL)
265             {
266                 sk->inbuf.d.f = buf->next;
267                 free(buf->data);
268                 free(buf);
269             }
270             break;
271         }
272         if(sk->fd >= 0)
273             close(sk->fd);
274         if(sk->remote != NULL)
275             free(sk->remote);
276         free(sk);
277     }
278 }
279
280 void sockpushdata(struct socket *sk, void *buf, size_t size)
281 {
282     switch(sk->type)
283     {
284     case SOCK_STREAM:
285         sizebuf(&sk->inbuf.s.buf, &sk->inbuf.s.bufsize, sk->inbuf.s.datasize + size, 1, 1);
286         memmove(sk->inbuf.s.buf + size, sk->inbuf.s.buf, sk->inbuf.s.datasize);
287         memcpy(sk->inbuf.s.buf, buf, size);
288         sk->inbuf.s.datasize += size;
289         break;
290     case SOCK_DGRAM:
291         /* XXX */
292         break;
293     }
294     return;
295 }
296
297 void *sockgetinbuf(struct socket *sk, size_t *size)
298 {
299     void *buf;
300     struct dgrambuf *dbuf;
301     
302     switch(sk->type)
303     {
304     case SOCK_STREAM:
305         if((sk->inbuf.s.buf == NULL) || (sk->inbuf.s.datasize == 0))
306         {
307             *size = 0;
308             return(NULL);
309         }
310         buf = sk->inbuf.s.buf;
311         *size = sk->inbuf.s.datasize;
312         sk->inbuf.s.buf = NULL;
313         sk->inbuf.s.bufsize = sk->inbuf.s.datasize = 0;
314         return(buf);
315     case SOCK_DGRAM:
316         if((dbuf = sk->inbuf.d.f) == NULL)
317             return(NULL);
318         sk->inbuf.d.f = dbuf->next;
319         if(dbuf->next == NULL)
320             sk->inbuf.d.l = NULL;
321         buf = dbuf->data;
322         *size = dbuf->size;
323         free(dbuf->addr);
324         free(dbuf);
325         return(buf);
326     }
327     return(NULL);
328 }
329
330 static void sockrecv(struct socket *sk)
331 {
332     int ret, inq;
333     struct dgrambuf *dbuf;
334     
335     switch(sk->type)
336     {
337     case SOCK_STREAM:
338 #if defined(HAVE_LINUX_SOCKIOS_H) && defined(SIOCINQ)
339         /* SIOCINQ is Linux-specific AFAIK, but I really have no idea
340          * how to read the inqueue size on other OSs */
341         if(ioctl(sk->fd, SIOCINQ, &inq))
342         {
343             /* I don't really know what could go wrong here, so let's
344              * assume it's transient. */
345             flog(LOG_WARNING, "SIOCINQ return %s on socket %i, falling back to 2048 bytes", strerror(errno), sk->fd);
346             inq = 2048;
347         }
348 #else
349         inq = 2048;
350 #endif
351         if(inq > 65536)
352             inq = 65536;
353         sizebuf(&sk->inbuf.s.buf, &sk->inbuf.s.bufsize, sk->inbuf.s.datasize + inq, 1, 1);
354         ret = read(sk->fd, sk->inbuf.s.buf + sk->inbuf.s.datasize, inq);
355         if(ret < 0)
356         {
357             if((errno == EINTR) || (errno == EAGAIN))
358                 return;
359             if(sk->errcb != NULL)
360                 sk->errcb(sk, errno, sk->data);
361             closesock(sk);
362             return;
363         }
364         if(ret == 0)
365         {
366             if(sk->errcb != NULL)
367                 sk->errcb(sk, 0, sk->data);
368             closesock(sk);
369             return;
370         }
371         sk->inbuf.s.datasize += ret;
372         if(sk->readcb != NULL)
373             sk->readcb(sk, sk->data);
374         break;
375     case SOCK_DGRAM:
376         if(ioctl(sk->fd, SIOCINQ, &inq))
377         {
378             /* I don't really know what could go wrong here, so let's
379              * assume it's transient. */
380             flog(LOG_WARNING, "SIOCINQ return %s on socket %i", strerror(errno), sk->fd);
381             return;
382         }
383         dbuf = smalloc(sizeof(*dbuf));
384         dbuf->data = smalloc(inq);
385         dbuf->addr = smalloc(dbuf->addrlen = sizeof(struct sockaddr_storage));
386         ret = recvfrom(sk->fd, dbuf->data, inq, 0, dbuf->addr, &dbuf->addrlen);
387         if(ret < 0)
388         {
389             free(dbuf->addr);
390             free(dbuf->data);
391             free(dbuf);
392             if((errno == EINTR) || (errno == EAGAIN))
393                 return;
394             if(sk->errcb != NULL)
395                 sk->errcb(sk, errno, sk->data);
396             closesock(sk);
397             return;
398         }
399         /* On UDP/IPv[46], ret == 0 doesn't mean EOF (since UDP can't
400          * have EOF), but rather an empty packet. I don't know if any
401          * other potential DGRAM protocols might have an EOF
402          * condition, so let's play safe. */
403         if(ret == 0)
404         {
405             free(dbuf->addr);
406             free(dbuf->data);
407             free(dbuf);
408             if(!((sk->family == AF_INET) || (sk->family == AF_INET6)))
409             {
410                 if(sk->errcb != NULL)
411                     sk->errcb(sk, 0, sk->data);
412                 closesock(sk);
413             }
414             return;
415         }
416         dbuf->addr = srealloc(dbuf->addr, dbuf->addrlen);
417         dbuf->data = srealloc(dbuf->data, dbuf->size = ret);
418         dbuf->next = NULL;
419         if(sk->inbuf.d.l != NULL)
420             sk->inbuf.d.l->next = dbuf;
421         else
422             sk->inbuf.d.f = dbuf;
423         sk->inbuf.d.l = dbuf;
424         if(sk->readcb != NULL)
425             sk->readcb(sk, sk->data);
426         break;
427     }
428 }
429
430 static void sockflush(struct socket *sk)
431 {
432     int ret;
433     struct dgrambuf *dbuf;
434     
435     switch(sk->type)
436     {
437     case SOCK_STREAM:
438         if(sk->isrealsocket)
439             ret = send(sk->fd, sk->outbuf.s.buf, sk->outbuf.s.datasize, MSG_DONTWAIT | MSG_NOSIGNAL);
440         else
441             ret = write(sk->fd, sk->outbuf.s.buf, sk->outbuf.s.datasize);
442         if(ret < 0)
443         {
444             /* For now, assume transient error, since
445              * the socket is polled for errors */
446             break;
447         }
448         if(ret > 0)
449         {
450             memmove(sk->outbuf.s.buf, ((char *)sk->outbuf.s.buf) + ret, sk->outbuf.s.datasize -= ret);
451             if(sk->writecb != NULL)
452                 sk->writecb(sk, sk->data);
453         }
454         break;
455     case SOCK_DGRAM:
456         dbuf = sk->outbuf.d.f;
457         if((sk->outbuf.d.f = dbuf->next) == NULL)
458             sk->outbuf.d.l = NULL;
459         sendto(sk->fd, dbuf->data, dbuf->size, MSG_DONTWAIT | MSG_NOSIGNAL, dbuf->addr, dbuf->addrlen);
460         free(dbuf->data);
461         free(dbuf->addr);
462         free(dbuf);
463         if(sk->writecb != NULL)
464             sk->writecb(sk, sk->data);
465         break;
466     }
467 }
468
469 void closesock(struct socket *sk)
470 {
471     sk->state = SOCK_STL;
472     close(sk->fd);
473     sk->fd = -1;
474     sk->close = 0;
475 }
476
477 void sockqueue(struct socket *sk, void *data, size_t size)
478 {
479     struct dgrambuf *new;
480     
481     if(sk->state == SOCK_STL)
482         return;
483     switch(sk->type)
484     {
485     case SOCK_STREAM:
486         sizebuf(&(sk->outbuf.s.buf), &(sk->outbuf.s.bufsize), sk->outbuf.s.datasize + size, 1, 1);
487         memcpy(sk->outbuf.s.buf + sk->outbuf.s.datasize, data, size);
488         sk->outbuf.s.datasize += size;
489         break;
490     case SOCK_DGRAM:
491         if(sk->remote == NULL)
492             return;
493         new = smalloc(sizeof(*new));
494         new->next = NULL;
495         memcpy(new->data = smalloc(size), data, new->size = size);
496         memcpy(new->addr = smalloc(sk->remotelen), sk->remote, new->addrlen = sk->remotelen);
497         if(sk->outbuf.d.l == NULL)
498         {
499             sk->outbuf.d.l = sk->outbuf.d.f = new;
500         } else {
501             sk->outbuf.d.l->next = new;
502             sk->outbuf.d.l = new;
503         }
504         break;
505     }
506 }
507
508 size_t sockgetdatalen(struct socket *sk)
509 {
510     struct dgrambuf *b;
511     size_t ret;
512     
513     switch(sk->type)
514     {
515     case SOCK_STREAM:
516         ret = sk->inbuf.s.datasize;
517         break;
518     case SOCK_DGRAM:
519         ret = 0;
520         for(b = sk->inbuf.d.f; b != NULL; b = b->next)
521             ret += b->size;
522         break;
523     }
524     return(ret);
525 }
526
527 size_t sockqueuesize(struct socket *sk)
528 {
529     struct dgrambuf *b;
530     size_t ret;
531     
532     switch(sk->type)
533     {
534     case SOCK_STREAM:
535         ret = sk->outbuf.s.datasize;
536         break;
537     case SOCK_DGRAM:
538         ret = 0;
539         for(b = sk->outbuf.d.f; b != NULL; b = b->next)
540             ret += b->size;
541         break;
542     }
543     return(ret);
544 }
545
546 /*
547  * The difference between netcslisten() and netcslistenlocal() is that
548  * netcslistenlocal() always listens on the local host, instead of
549  * following proxy/passive mode directions. It is suitable for eg. the
550  * UI channel, while the file sharing networks should, naturally, use
551  * netcslisten() instead.
552 */
553
554 struct socket *netcslistenlocal(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
555 {
556     struct socket *sk;
557     int intbuf;
558     
559     /* I don't know if this is actually correct (it probably isn't),
560      * but since, at on least Linux systems, PF_* are specifically
561      * #define'd to their AF_* counterparts, it allows for a severely
562      * smoother implementation. If it breaks something on your
563      * platform, please tell me so.
564      */
565     if((sk = mksock(name->sa_family, type)) == NULL)
566         return(NULL);
567     sk->state = SOCK_LST;
568     if(confgetint("net", "reuseaddr"))
569     {
570         intbuf = 1;
571         setsockopt(sk->fd, SOL_SOCKET, SO_REUSEADDR, &intbuf, sizeof(intbuf));
572     }
573     if(bind(sk->fd, name, namelen) < 0)
574     {
575         putsock(sk);
576         return(NULL);
577     }
578     if(listen(sk->fd, 16) < 0)
579     {
580         putsock(sk);
581         return(NULL);
582     }
583     sk->acceptcb = func;
584     sk->data = data;
585     return(sk);
586 }
587
588 struct socket *netcslisten(int type, struct sockaddr *name, socklen_t namelen, void (*func)(struct socket *, struct socket *, void *), void *data)
589 {
590     if(confgetint("net", "mode") == 1)
591     {
592         errno = EOPNOTSUPP;
593         return(NULL);
594     }
595     /* I don't know if this is actually correct (it probably isn't),
596      * but since, at on least Linux systems, PF_* are specifically
597      * #define'd to their AF_* counterparts, it allows for a severely
598      * smoother implementation. If it breaks something on your
599      * platform, please tell me so.
600      */
601     if(confgetint("net", "mode") == 0)
602         return(netcslistenlocal(type, name, namelen, func, data));
603     errno = EOPNOTSUPP;
604     return(NULL);
605 }
606
607 struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data)
608 {
609     struct sockaddr_in addr;
610 #ifdef HAVE_IPV6
611     struct sockaddr_in6 addr6;
612 #endif
613     struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct socket *, struct socket *, void *), void *);
614     struct socket *ret;
615     
616     if(local)
617         csfunc = netcslistenlocal;
618     else
619         csfunc = netcslisten;
620 #ifdef HAVE_IPV6
621     memset(&addr6, 0, sizeof(addr6));
622     addr6.sin6_family = AF_INET6;
623     addr6.sin6_port = htons(port);
624     addr6.sin6_addr = in6addr_any;
625     if((ret = csfunc(SOCK_STREAM, (struct sockaddr *)&addr6, sizeof(addr6), func, data)) != NULL)
626         return(ret);
627     if((ret == NULL) && (errno != EAFNOSUPPORT))
628         return(NULL);
629 #endif
630     memset(&addr, 0, sizeof(addr));
631     addr.sin_family = AF_INET;
632     addr.sin_port = htons(port);
633     return(csfunc(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), func, data));
634 }
635
636 struct socket *netcsdgram(struct sockaddr *name, socklen_t namelen)
637 {
638     struct socket *sk;
639     int mode;
640     
641     mode = confgetint("net", "mode");
642     if((mode == 0) || (mode == 1))
643     {
644         if((sk = mksock(name->sa_family, SOCK_DGRAM)) == NULL)
645             return(NULL);
646         if(bind(sk->fd, name, namelen) < 0)
647         {
648             putsock(sk);
649             return(NULL);
650         }
651         sk->state = SOCK_EST;
652         return(sk);
653     }
654     errno = EOPNOTSUPP;
655     return(NULL);
656 }
657
658 struct socket *netdupsock(struct socket *sk)
659 {
660     struct socket *newsk;
661     
662     newsk = newsock(sk->type);
663     if((newsk->fd = dup(sk->fd)) < 0)
664     {
665         flog(LOG_WARNING, "could not dup() socket: %s", strerror(errno));
666         putsock(newsk);
667         return(NULL);
668     }
669     newsk->state = sk->state;
670     newsk->ignread = sk->ignread;
671     if(sk->remote != NULL)
672         memcpy(newsk->remote = smalloc(sk->remotelen), sk->remote, newsk->remotelen = sk->remotelen);
673     return(newsk);
674 }
675
676 void netdgramconn(struct socket *sk, struct sockaddr *addr, socklen_t addrlen)
677 {
678     if(sk->remote != NULL)
679         free(sk->remote);
680     memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
681     sk->ignread = 1;
682 }
683
684 struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data)
685 {
686     struct socket *sk;
687     int mode;
688     
689     mode = confgetint("net", "mode");
690     if((mode == 0) || (mode == 1))
691     {
692         if((sk = mksock(addr->sa_family, SOCK_STREAM)) == NULL)
693             return(NULL);
694         memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
695         if(!connect(sk->fd, addr, addrlen))
696         {
697             sk->state = SOCK_EST;
698             func(sk, 0, data);
699             return(sk);
700         }
701         if(errno == EINPROGRESS)
702         {
703             sk->state = SOCK_SYN;
704             sk->conncb = func;
705             sk->data = data;
706             return(sk);
707         }
708         putsock(sk);
709         return(NULL);
710     }
711     errno = EOPNOTSUPP;
712     return(NULL);
713 }
714
715 int pollsocks(int timeout)
716 {
717     int i, num, ret, retlen;
718     int newfd;
719     struct pollfd *pfds;
720     struct socket *sk, *next, *newsk;
721     struct sockaddr_storage ss;
722     socklen_t sslen;
723     
724     pfds = smalloc(sizeof(*pfds) * (num = numsocks));
725     for(i = 0, sk = sockets; i < num; sk = sk->next)
726     {
727         if(sk->state == SOCK_STL)
728         {
729             num--;
730             continue;
731         }
732         pfds[i].fd = sk->fd;
733         pfds[i].events = 0;
734         if(!sk->ignread)
735             pfds[i].events |= POLLIN;
736         if((sk->state == SOCK_SYN) || (sockqueuesize(sk) > 0))
737             pfds[i].events |= POLLOUT;
738         pfds[i].revents = 0;
739         i++;
740     }
741     ret = poll(pfds, num, timeout);
742     if(ret < 0)
743     {
744         if(errno != EINTR)
745         {
746             flog(LOG_CRIT, "pollsocks: poll errored out: %s", strerror(errno));
747             /* To avoid CPU hogging in case it's bad, which it
748              * probably is. */
749             sleep(1);
750         }
751         free(pfds);
752         return(1);
753     }
754     for(sk = sockets; sk != NULL; sk = next)
755     {
756         next = sk->next;
757         for(i = 0; i < num; i++)
758         {
759             if(pfds[i].fd == sk->fd)
760                 break;
761         }
762         if(i == num)
763             continue;
764         switch(sk->state)
765         {
766         case SOCK_LST:
767             if(pfds[i].revents & POLLIN)
768             {
769                 sslen = sizeof(ss);
770                 if((newfd = accept(sk->fd, (struct sockaddr *)&ss, &sslen)) < 0)
771                 {
772                     if(sk->errcb != NULL)
773                         sk->errcb(sk, errno, sk->data);
774                 }
775                 newsk = newsock(sk->type);
776                 newsk->fd = newfd;
777                 newsk->family = sk->family;
778                 newsk->state = SOCK_EST;
779                 memcpy(newsk->remote = smalloc(sslen), &ss, sslen);
780                 newsk->remotelen = sslen;
781                 putsock(newsk);
782                 if(sk->acceptcb != NULL)
783                     sk->acceptcb(sk, newsk, sk->data);
784             }
785             if(pfds[i].revents & POLLERR)
786             {
787                 retlen = sizeof(ret);
788                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
789                 if(sk->errcb != NULL)
790                     sk->errcb(sk, ret, sk->data);
791                 continue;
792             }
793             break;
794         case SOCK_SYN:
795             if(pfds[i].revents & POLLERR)
796             {
797                 retlen = sizeof(ret);
798                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
799                 if(sk->conncb != NULL)
800                     sk->conncb(sk, ret, sk->data);
801                 closesock(sk);
802                 continue;
803             }
804             if(pfds[i].revents & (POLLIN | POLLOUT))
805             {
806                 sk->state = SOCK_EST;
807                 if(sk->conncb != NULL)
808                     sk->conncb(sk, 0, sk->data);
809             }
810             break;
811         case SOCK_EST:
812             if(pfds[i].revents & POLLERR)
813             {
814                 retlen = sizeof(ret);
815                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
816                 if(sk->errcb != NULL)
817                     sk->errcb(sk, ret, sk->data);
818                 closesock(sk);
819                 continue;
820             }
821             if(pfds[i].revents & POLLIN)
822                 sockrecv(sk);
823             if(pfds[i].revents & POLLOUT)
824             {
825                 if(sockqueuesize(sk) > 0)
826                     sockflush(sk);
827             }
828             break;
829         }
830         if(pfds[i].revents & POLLNVAL)
831         {
832             flog(LOG_CRIT, "BUG: stale socket struct on fd %i", sk->fd);
833             sk->state = SOCK_STL;
834             unlinksock(sk);
835             continue;
836         }
837         if(pfds[i].revents & POLLHUP)
838         {
839             if(sk->errcb != NULL)
840                 sk->errcb(sk, 0, sk->data);
841             closesock(sk);
842             unlinksock(sk);
843             continue;
844         }
845     }
846     free(pfds);
847     for(sk = sockets; sk != NULL; sk = next)
848     {
849         next = sk->next;
850         if(sk->refcount == 1 && (sockqueuesize(sk) == 0))
851         {
852             unlinksock(sk);
853             continue;
854         }
855         if(sk->close && (sockqueuesize(sk) == 0))
856             closesock(sk);
857         if(sk->state == SOCK_STL)
858         {
859             unlinksock(sk);
860             continue;
861         }
862     }
863     return(1);
864 }
865
866 int socksettos(struct socket *sk, int tos)
867 {
868     int buf;
869     
870     if(sk->family == AF_INET)
871     {
872         switch(tos)
873         {
874         case 0:
875             buf = 0;
876             break;
877         case SOCK_TOS_MINCOST:
878             buf = 0x02;
879             break;
880         case SOCK_TOS_MAXREL:
881             buf = 0x04;
882             break;
883         case SOCK_TOS_MAXTP:
884             buf = 0x08;
885             break;
886         case SOCK_TOS_MINDELAY:
887             buf = 0x10;
888             break;
889         default:
890             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
891             return(-1);
892         }
893         if(setsockopt(sk->fd, SOL_IP, IP_TOS, &buf, sizeof(buf)) < 0)
894         {
895             flog(LOG_WARNING, "could not set sock TOS to %i: %s", tos, strerror(errno));
896             return(-1);
897         }
898         return(0);
899     }
900     if(sk->family == AF_INET6)
901     {
902         switch(tos)
903         {
904         case 0:
905             buf = 0;
906         case SOCK_TOS_MINCOST:
907             buf = confgetint("net", "diffserv-mincost");
908             break;
909         case SOCK_TOS_MAXREL:
910             buf = confgetint("net", "diffserv-maxrel");
911             break;
912         case SOCK_TOS_MAXTP:
913             buf = confgetint("net", "diffserv-maxtp");
914             break;
915         case SOCK_TOS_MINDELAY:
916             buf = confgetint("net", "diffserv-mindelay");
917             break;
918         default:
919             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
920             return(-1);
921         }
922         /*
923           On Linux, the API IPv6 flow label management doesn't seem to
924           be entirely complete, so I guess this will have to wait.
925           
926         if(setsockopt(...) < 0)
927         {
928             flog(LOG_WARNING, "could not set sock traffic class to %i: %s", tos, strerror(errno));
929             return(-1);
930         }
931         */
932         return(0);
933     }
934     flog(LOG_WARNING, "could not set TOS on sock of family %i", sk->family);
935     return(1);
936 }
937
938 struct resolvedata
939 {
940     int fd;
941     void (*callback)(struct sockaddr *addr, int addrlen, void *data);
942     void *data;
943     struct sockaddr_storage addr;
944     int addrlen;
945 };
946
947 static void resolvecb(pid_t pid, int status, struct resolvedata *data)
948 {
949     static char buf[80];
950     int ret;
951     struct sockaddr_in *ipv4;
952     
953     if(!status)
954     {
955         if((ret = read(data->fd, buf, sizeof(buf))) != 4)
956         {
957             errno = ENONET;
958             data->callback(NULL, 0, data->data);
959         } else {
960             ipv4 = (struct sockaddr_in *)&data->addr;
961             memcpy(&ipv4->sin_addr, buf, 4);
962             data->callback((struct sockaddr *)ipv4, sizeof(*ipv4), data->data);
963         }
964     } else {
965         errno = ENONET;
966         data->callback(NULL, 0, data->data);
967     }
968     close(data->fd);
969     free(data);
970 }
971
972 int netresolve(char *addr, void (*callback)(struct sockaddr *addr, int addrlen, void *data), void *data)
973 {
974     int i;
975     char *p;
976     int port;
977     int pfd[2];
978     pid_t child;
979     struct resolvedata *rdata;
980     struct sockaddr_in ipv4;
981     struct hostent *he;
982     sigset_t sigset;
983     
984     /* IPv4 */
985     port = -1;
986     if((p = strchr(addr, ':')) != NULL)
987     {
988         *p = 0;
989         port = atoi(p + 1);
990     }
991     ipv4.sin_family = AF_INET;
992     ipv4.sin_port = htons(port);
993     if(inet_aton(addr, &ipv4.sin_addr))
994     {
995         callback((struct sockaddr *)&ipv4, sizeof(ipv4), data);
996     } else {
997         sigemptyset(&sigset);
998         sigaddset(&sigset, SIGCHLD);
999         sigprocmask(SIG_BLOCK, &sigset, NULL);
1000         if((pipe(pfd) < 0) || ((child = fork()) < 0))
1001         {
1002             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1003             return(-1);
1004         }
1005         if(child == 0)
1006         {
1007             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1008             for(i = 3; i < FD_SETSIZE; i++)
1009             {
1010                 if(i != pfd[1])
1011                     close(i);
1012             }
1013             signal(SIGALRM, SIG_DFL);
1014             alarm(30);
1015             if((he = gethostbyname(addr)) == NULL)
1016                 exit(1);
1017             write(pfd[1], he->h_addr_list[0], 4);
1018             exit(0);
1019         } else {
1020             close(pfd[1]);
1021             fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK);
1022             rdata = smalloc(sizeof(*rdata));
1023             rdata->fd = pfd[0];
1024             rdata->callback = callback;
1025             rdata->data = data;
1026             memcpy(&rdata->addr, &ipv4, rdata->addrlen = sizeof(ipv4));
1027             childcallback(child, (void (*)(pid_t, int, void *))resolvecb, rdata);
1028             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1029             return(1);
1030         }
1031     }
1032     return(0);
1033 }
1034
1035 int sockgetlocalname(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1036 {
1037     socklen_t len;
1038     struct sockaddr_storage name;
1039     
1040     *namebuf = NULL;
1041     if((sk->state == SOCK_STL) || (sk->fd < 0))
1042         return(-1);
1043     len = sizeof(name);
1044     if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1045     {
1046         flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetlocalname");
1047         return(-1);
1048     }
1049     *namebuf = memcpy(smalloc(len), &name, len);
1050     *lenbuf = len;
1051     return(0);
1052 }
1053
1054 int sockgetremotename(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1055 {
1056     socklen_t len;
1057     struct sockaddr_storage name;
1058     struct sockaddr_in *ipv4;
1059     struct sockaddr *pname;
1060     socklen_t pnamelen;
1061     
1062     switch(confgetint("net", "mode"))
1063     {
1064     case 0:
1065         *namebuf = NULL;
1066         if((sk->state == SOCK_STL) || (sk->fd < 0))
1067             return(-1);
1068         len = sizeof(name);
1069         if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1070         {
1071             flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetremotename");
1072             return(-1);
1073         }
1074         if(name.ss_family == AF_INET)
1075         {
1076             ipv4 = (struct sockaddr_in *)&name;
1077             if(getpublicaddr(AF_INET, &pname, &pnamelen) < 0)
1078             {
1079                 flog(LOG_WARNING, "could not determine public IP address - strange things may happen");
1080                 return(-1);
1081             }
1082             ipv4->sin_addr.s_addr = ((struct sockaddr_in *)pname)->sin_addr.s_addr;
1083             free(pname);
1084         }
1085         *namebuf = memcpy(smalloc(len), &name, len);
1086         *lenbuf = len;
1087         return(0);
1088     case 1:
1089         errno = EOPNOTSUPP;
1090         return(-1);
1091     default:
1092         flog(LOG_CRIT, "unknown net mode %i active", confgetint("net", "mode"));
1093         errno = EOPNOTSUPP;
1094         return(-1);
1095     }
1096 }
1097
1098 int addreq(struct sockaddr *x, struct sockaddr *y)
1099 {
1100     struct sockaddr_un *u1, *u2;
1101     struct sockaddr_in *n1, *n2;
1102 #ifdef HAVE_IPV6
1103     struct sockaddr_in6 *s1, *s2;
1104 #endif
1105     
1106     if(x->sa_family != y->sa_family)
1107         return(0);
1108     switch(x->sa_family) {
1109     case AF_UNIX:
1110         u1 = (struct sockaddr_un *)x; u2 = (struct sockaddr_un *)y;
1111         if(strncmp(u1->sun_path, u2->sun_path, sizeof(u1->sun_path)))
1112             return(0);
1113         break;
1114     case AF_INET:
1115         n1 = (struct sockaddr_in *)x; n2 = (struct sockaddr_in *)y;
1116         if(n1->sin_port != n2->sin_port)
1117             return(0);
1118         if(n1->sin_addr.s_addr != n2->sin_addr.s_addr)
1119             return(0);
1120         break;
1121     case AF_INET6:
1122         s1 = (struct sockaddr_in6 *)x; s2 = (struct sockaddr_in6 *)y;
1123         if(s1->sin6_port != s2->sin6_port)
1124             return(0);
1125         if(memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr)))
1126             return(0);
1127         break;
1128     }
1129     return(1);
1130 }
1131
1132 char *formataddress(struct sockaddr *arg, socklen_t arglen)
1133 {
1134     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1135                                * lowercase letters to 1, so I do this
1136                                * instead. */
1137     struct sockaddr_in *ipv4;
1138 #ifdef HAVE_IPV6
1139     struct sockaddr_in6 *ipv6;
1140 #endif
1141     static char *ret = NULL;
1142     char buf[1024];
1143     
1144     if(ret != NULL)
1145         free(ret);
1146     ret = NULL;
1147     switch(arg->sa_family)
1148     {
1149     case AF_UNIX:
1150         UNIX = (struct sockaddr_un *)arg;
1151         ret = sprintf2("%s", UNIX->sun_path);
1152         break;
1153     case AF_INET:
1154         ipv4 = (struct sockaddr_in *)arg;
1155         if(inet_ntop(AF_INET, &ipv4->sin_addr, buf, sizeof(buf)) == NULL)
1156             return(NULL);
1157         ret = sprintf2("%s:%i", buf, (int)ntohs(ipv4->sin_port));
1158         break;
1159 #ifdef HAVE_IPV6
1160     case AF_INET6:
1161         ipv6 = (struct sockaddr_in6 *)arg;
1162         if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL)
1163             return(NULL);
1164         ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port));
1165         break;
1166 #endif
1167     default:
1168         errno = EPFNOSUPPORT;
1169         break;
1170     }
1171     return(ret);
1172 }
1173
1174 #if 0
1175
1176 /* 
1177  * It was very nice to use this, but it seems
1178  * to mess things up, so I guess it has to go... :-(
1179  */
1180
1181 static int formataddress(FILE *stream, const struct printf_info *info, const void *const *args)
1182 {
1183     struct sockaddr *arg;
1184     socklen_t arglen;
1185     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1186                                * lowercase letters to 1, so I do this
1187                                * instead. */
1188     struct sockaddr_in *ipv4;
1189     int ret;
1190     
1191     arg = *(struct sockaddr **)(args[0]);
1192     arglen = *(socklen_t *)(args[1]);
1193     switch(arg->sa_family)
1194     {
1195     case AF_UNIX:
1196         UNIX = (struct sockaddr_un *)arg;
1197         ret = fprintf(stream, "%s", UNIX->sun_path);
1198         break;
1199     case AF_INET:
1200         ipv4 = (struct sockaddr_in *)arg;
1201         ret = fprintf(stream, "%s:%i", inet_ntoa(ipv4->sin_addr), (int)ntohs(ipv4->sin_port));
1202         break;
1203     default:
1204         ret = -1;
1205         errno = EPFNOSUPPORT;
1206         break;
1207     }
1208     return(ret);
1209 }
1210
1211 static int formataddress_arginfo(const struct printf_info *info, size_t n, int *argtypes)
1212 {
1213     if(n > 0)
1214         argtypes[0] = PA_POINTER;
1215     if(n > 1)
1216         argtypes[1] = PA_INT; /* Sources tell me that socklen_t _must_
1217                                * be an int, so I guess this should be
1218                                * safe. */
1219     return(2);
1220 }
1221 #endif
1222
1223 static int init(int hup)
1224 {
1225     if(!hup)
1226     {
1227         /*
1228         if(register_printf_function('N', formataddress, formataddress_arginfo))
1229         {
1230             flog(LOG_CRIT, "could not register printf handler %%N: %s", strerror(errno));
1231             return(1);
1232         }
1233         */
1234     }
1235     return(0);
1236 }
1237
1238 static void terminate(void)
1239 {
1240     while(sockets != NULL)
1241         unlinksock(sockets);
1242 }
1243
1244 static struct module me =
1245 {
1246     .name = "net",
1247     .conf =
1248     {
1249         .vars = myvars
1250     },
1251     .init = init,
1252     .terminate = terminate
1253 };
1254
1255 MODULE(me)