Remove [AP]F_* comment from netcslisten.
[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     if(confgetint("net", "mode") == 0)
596         return(netcslistenlocal(type, name, namelen, func, data));
597     errno = EOPNOTSUPP;
598     return(NULL);
599 }
600
601 struct socket *netcstcplisten(int port, int local, void (*func)(struct socket *, struct socket *, void *), void *data)
602 {
603     struct sockaddr_in addr;
604 #ifdef HAVE_IPV6
605     struct sockaddr_in6 addr6;
606 #endif
607     struct socket *(*csfunc)(int, struct sockaddr *, socklen_t, void (*)(struct socket *, struct socket *, void *), void *);
608     struct socket *ret;
609     
610     if(local)
611         csfunc = netcslistenlocal;
612     else
613         csfunc = netcslisten;
614 #ifdef HAVE_IPV6
615     memset(&addr6, 0, sizeof(addr6));
616     addr6.sin6_family = AF_INET6;
617     addr6.sin6_port = htons(port);
618     addr6.sin6_addr = in6addr_any;
619     if((ret = csfunc(SOCK_STREAM, (struct sockaddr *)&addr6, sizeof(addr6), func, data)) != NULL)
620         return(ret);
621     if((ret == NULL) && (errno != EAFNOSUPPORT))
622         return(NULL);
623 #endif
624     memset(&addr, 0, sizeof(addr));
625     addr.sin_family = AF_INET;
626     addr.sin_port = htons(port);
627     return(csfunc(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), func, data));
628 }
629
630 struct socket *netcsdgram(struct sockaddr *name, socklen_t namelen)
631 {
632     struct socket *sk;
633     int mode;
634     
635     mode = confgetint("net", "mode");
636     if((mode == 0) || (mode == 1))
637     {
638         if((sk = mksock(name->sa_family, SOCK_DGRAM)) == NULL)
639             return(NULL);
640         if(bind(sk->fd, name, namelen) < 0)
641         {
642             putsock(sk);
643             return(NULL);
644         }
645         sk->state = SOCK_EST;
646         return(sk);
647     }
648     errno = EOPNOTSUPP;
649     return(NULL);
650 }
651
652 struct socket *netdupsock(struct socket *sk)
653 {
654     struct socket *newsk;
655     
656     newsk = newsock(sk->type);
657     if((newsk->fd = dup(sk->fd)) < 0)
658     {
659         flog(LOG_WARNING, "could not dup() socket: %s", strerror(errno));
660         putsock(newsk);
661         return(NULL);
662     }
663     newsk->state = sk->state;
664     newsk->ignread = sk->ignread;
665     if(sk->remote != NULL)
666         memcpy(newsk->remote = smalloc(sk->remotelen), sk->remote, newsk->remotelen = sk->remotelen);
667     return(newsk);
668 }
669
670 void netdgramconn(struct socket *sk, struct sockaddr *addr, socklen_t addrlen)
671 {
672     if(sk->remote != NULL)
673         free(sk->remote);
674     memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
675     sk->ignread = 1;
676 }
677
678 struct socket *netcsconn(struct sockaddr *addr, socklen_t addrlen, void (*func)(struct socket *, int, void *), void *data)
679 {
680     struct socket *sk;
681     int mode;
682     
683     mode = confgetint("net", "mode");
684     if((mode == 0) || (mode == 1))
685     {
686         if((sk = mksock(addr->sa_family, SOCK_STREAM)) == NULL)
687             return(NULL);
688         memcpy(sk->remote = smalloc(addrlen), addr, sk->remotelen = addrlen);
689         if(!connect(sk->fd, addr, addrlen))
690         {
691             sk->state = SOCK_EST;
692             func(sk, 0, data);
693             return(sk);
694         }
695         if(errno == EINPROGRESS)
696         {
697             sk->state = SOCK_SYN;
698             sk->conncb = func;
699             sk->data = data;
700             return(sk);
701         }
702         putsock(sk);
703         return(NULL);
704     }
705     errno = EOPNOTSUPP;
706     return(NULL);
707 }
708
709 int pollsocks(int timeout)
710 {
711     int i, num, ret, retlen;
712     int newfd;
713     struct pollfd *pfds;
714     struct socket *sk, *next, *newsk;
715     struct sockaddr_storage ss;
716     socklen_t sslen;
717     
718     pfds = smalloc(sizeof(*pfds) * (num = numsocks));
719     for(i = 0, sk = sockets; i < num; sk = sk->next)
720     {
721         if(sk->state == SOCK_STL)
722         {
723             num--;
724             continue;
725         }
726         pfds[i].fd = sk->fd;
727         pfds[i].events = 0;
728         if(!sk->ignread)
729             pfds[i].events |= POLLIN;
730         if((sk->state == SOCK_SYN) || (sockqueuesize(sk) > 0))
731             pfds[i].events |= POLLOUT;
732         pfds[i].revents = 0;
733         i++;
734     }
735     ret = poll(pfds, num, timeout);
736     if(ret < 0)
737     {
738         if(errno != EINTR)
739         {
740             flog(LOG_CRIT, "pollsocks: poll errored out: %s", strerror(errno));
741             /* To avoid CPU hogging in case it's bad, which it
742              * probably is. */
743             sleep(1);
744         }
745         free(pfds);
746         return(1);
747     }
748     for(sk = sockets; sk != NULL; sk = next)
749     {
750         next = sk->next;
751         for(i = 0; i < num; i++)
752         {
753             if(pfds[i].fd == sk->fd)
754                 break;
755         }
756         if(i == num)
757             continue;
758         switch(sk->state)
759         {
760         case SOCK_LST:
761             if(pfds[i].revents & POLLIN)
762             {
763                 sslen = sizeof(ss);
764                 if((newfd = accept(sk->fd, (struct sockaddr *)&ss, &sslen)) < 0)
765                 {
766                     if(sk->errcb != NULL)
767                         sk->errcb(sk, errno, sk->data);
768                 }
769                 newsk = newsock(sk->type);
770                 newsk->fd = newfd;
771                 newsk->family = sk->family;
772                 newsk->state = SOCK_EST;
773                 memcpy(newsk->remote = smalloc(sslen), &ss, sslen);
774                 newsk->remotelen = sslen;
775                 putsock(newsk);
776                 if(sk->acceptcb != NULL)
777                     sk->acceptcb(sk, newsk, sk->data);
778             }
779             if(pfds[i].revents & POLLERR)
780             {
781                 retlen = sizeof(ret);
782                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
783                 if(sk->errcb != NULL)
784                     sk->errcb(sk, ret, sk->data);
785                 continue;
786             }
787             break;
788         case SOCK_SYN:
789             if(pfds[i].revents & POLLERR)
790             {
791                 retlen = sizeof(ret);
792                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
793                 if(sk->conncb != NULL)
794                     sk->conncb(sk, ret, sk->data);
795                 closesock(sk);
796                 continue;
797             }
798             if(pfds[i].revents & (POLLIN | POLLOUT))
799             {
800                 sk->state = SOCK_EST;
801                 if(sk->conncb != NULL)
802                     sk->conncb(sk, 0, sk->data);
803             }
804             break;
805         case SOCK_EST:
806             if(pfds[i].revents & POLLERR)
807             {
808                 retlen = sizeof(ret);
809                 getsockopt(sk->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
810                 if(sk->errcb != NULL)
811                     sk->errcb(sk, ret, sk->data);
812                 closesock(sk);
813                 continue;
814             }
815             if(pfds[i].revents & POLLIN)
816                 sockrecv(sk);
817             if(pfds[i].revents & POLLOUT)
818             {
819                 if(sockqueuesize(sk) > 0)
820                     sockflush(sk);
821             }
822             break;
823         }
824         if(pfds[i].revents & POLLNVAL)
825         {
826             flog(LOG_CRIT, "BUG: stale socket struct on fd %i", sk->fd);
827             sk->state = SOCK_STL;
828             unlinksock(sk);
829             continue;
830         }
831         if(pfds[i].revents & POLLHUP)
832         {
833             if(sk->errcb != NULL)
834                 sk->errcb(sk, 0, sk->data);
835             closesock(sk);
836             unlinksock(sk);
837             continue;
838         }
839     }
840     free(pfds);
841     for(sk = sockets; sk != NULL; sk = next)
842     {
843         next = sk->next;
844         if(sk->refcount == 1 && (sockqueuesize(sk) == 0))
845         {
846             unlinksock(sk);
847             continue;
848         }
849         if(sk->close && (sockqueuesize(sk) == 0))
850             closesock(sk);
851         if(sk->state == SOCK_STL)
852         {
853             unlinksock(sk);
854             continue;
855         }
856     }
857     return(1);
858 }
859
860 int socksettos(struct socket *sk, int tos)
861 {
862     int buf;
863     
864     if(sk->family == AF_INET)
865     {
866         switch(tos)
867         {
868         case 0:
869             buf = 0;
870             break;
871         case SOCK_TOS_MINCOST:
872             buf = 0x02;
873             break;
874         case SOCK_TOS_MAXREL:
875             buf = 0x04;
876             break;
877         case SOCK_TOS_MAXTP:
878             buf = 0x08;
879             break;
880         case SOCK_TOS_MINDELAY:
881             buf = 0x10;
882             break;
883         default:
884             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
885             return(-1);
886         }
887         if(setsockopt(sk->fd, SOL_IP, IP_TOS, &buf, sizeof(buf)) < 0)
888         {
889             flog(LOG_WARNING, "could not set sock TOS to %i: %s", tos, strerror(errno));
890             return(-1);
891         }
892         return(0);
893     }
894     if(sk->family == AF_INET6)
895     {
896         switch(tos)
897         {
898         case 0:
899             buf = 0;
900         case SOCK_TOS_MINCOST:
901             buf = confgetint("net", "diffserv-mincost");
902             break;
903         case SOCK_TOS_MAXREL:
904             buf = confgetint("net", "diffserv-maxrel");
905             break;
906         case SOCK_TOS_MAXTP:
907             buf = confgetint("net", "diffserv-maxtp");
908             break;
909         case SOCK_TOS_MINDELAY:
910             buf = confgetint("net", "diffserv-mindelay");
911             break;
912         default:
913             flog(LOG_WARNING, "attempted to set unknown TOS value %i to IPv4 sock", tos);
914             return(-1);
915         }
916         /*
917           On Linux, the API IPv6 flow label management doesn't seem to
918           be entirely complete, so I guess this will have to wait.
919           
920         if(setsockopt(...) < 0)
921         {
922             flog(LOG_WARNING, "could not set sock traffic class to %i: %s", tos, strerror(errno));
923             return(-1);
924         }
925         */
926         return(0);
927     }
928     flog(LOG_WARNING, "could not set TOS on sock of family %i", sk->family);
929     return(1);
930 }
931
932 struct resolvedata
933 {
934     int fd;
935     void (*callback)(struct sockaddr *addr, int addrlen, void *data);
936     void *data;
937     struct sockaddr_storage addr;
938     int addrlen;
939 };
940
941 static void resolvecb(pid_t pid, int status, struct resolvedata *data)
942 {
943     static char buf[80];
944     int ret;
945     struct sockaddr_in *ipv4;
946     
947     if(!status)
948     {
949         if((ret = read(data->fd, buf, sizeof(buf))) != 4)
950         {
951             errno = ENONET;
952             data->callback(NULL, 0, data->data);
953         } else {
954             ipv4 = (struct sockaddr_in *)&data->addr;
955             memcpy(&ipv4->sin_addr, buf, 4);
956             data->callback((struct sockaddr *)ipv4, sizeof(*ipv4), data->data);
957         }
958     } else {
959         errno = ENONET;
960         data->callback(NULL, 0, data->data);
961     }
962     close(data->fd);
963     free(data);
964 }
965
966 int netresolve(char *addr, void (*callback)(struct sockaddr *addr, int addrlen, void *data), void *data)
967 {
968     int i;
969     char *p;
970     int port;
971     int pfd[2];
972     pid_t child;
973     struct resolvedata *rdata;
974     struct sockaddr_in ipv4;
975     struct hostent *he;
976     sigset_t sigset;
977     
978     /* IPv4 */
979     port = -1;
980     if((p = strchr(addr, ':')) != NULL)
981     {
982         *p = 0;
983         port = atoi(p + 1);
984     }
985     ipv4.sin_family = AF_INET;
986     ipv4.sin_port = htons(port);
987     if(inet_aton(addr, &ipv4.sin_addr))
988     {
989         callback((struct sockaddr *)&ipv4, sizeof(ipv4), data);
990     } else {
991         sigemptyset(&sigset);
992         sigaddset(&sigset, SIGCHLD);
993         sigprocmask(SIG_BLOCK, &sigset, NULL);
994         if((pipe(pfd) < 0) || ((child = fork()) < 0))
995         {
996             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
997             return(-1);
998         }
999         if(child == 0)
1000         {
1001             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1002             for(i = 3; i < FD_SETSIZE; i++)
1003             {
1004                 if(i != pfd[1])
1005                     close(i);
1006             }
1007             signal(SIGALRM, SIG_DFL);
1008             alarm(30);
1009             if((he = gethostbyname(addr)) == NULL)
1010                 exit(1);
1011             write(pfd[1], he->h_addr_list[0], 4);
1012             exit(0);
1013         } else {
1014             close(pfd[1]);
1015             fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK);
1016             rdata = smalloc(sizeof(*rdata));
1017             rdata->fd = pfd[0];
1018             rdata->callback = callback;
1019             rdata->data = data;
1020             memcpy(&rdata->addr, &ipv4, rdata->addrlen = sizeof(ipv4));
1021             childcallback(child, (void (*)(pid_t, int, void *))resolvecb, rdata);
1022             sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1023             return(1);
1024         }
1025     }
1026     return(0);
1027 }
1028
1029 int sockgetlocalname(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1030 {
1031     socklen_t len;
1032     struct sockaddr_storage name;
1033     
1034     *namebuf = NULL;
1035     if((sk->state == SOCK_STL) || (sk->fd < 0))
1036         return(-1);
1037     len = sizeof(name);
1038     if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1039     {
1040         flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetlocalname");
1041         return(-1);
1042     }
1043     *namebuf = memcpy(smalloc(len), &name, len);
1044     *lenbuf = len;
1045     return(0);
1046 }
1047
1048 int sockgetremotename(struct socket *sk, struct sockaddr **namebuf, socklen_t *lenbuf)
1049 {
1050     socklen_t len;
1051     struct sockaddr_storage name;
1052     struct sockaddr_in *ipv4;
1053     struct sockaddr *pname;
1054     socklen_t pnamelen;
1055     
1056     switch(confgetint("net", "mode"))
1057     {
1058     case 0:
1059         *namebuf = NULL;
1060         if((sk->state == SOCK_STL) || (sk->fd < 0))
1061             return(-1);
1062         len = sizeof(name);
1063         if(getsockname(sk->fd, (struct sockaddr *)&name, &len) < 0)
1064         {
1065             flog(LOG_ERR, "BUG: alive socket with dead fd in sockgetremotename");
1066             return(-1);
1067         }
1068         if(name.ss_family == AF_INET)
1069         {
1070             ipv4 = (struct sockaddr_in *)&name;
1071             if(getpublicaddr(AF_INET, &pname, &pnamelen) < 0)
1072             {
1073                 flog(LOG_WARNING, "could not determine public IP address - strange things may happen");
1074                 return(-1);
1075             }
1076             ipv4->sin_addr.s_addr = ((struct sockaddr_in *)pname)->sin_addr.s_addr;
1077             free(pname);
1078         }
1079         *namebuf = memcpy(smalloc(len), &name, len);
1080         *lenbuf = len;
1081         return(0);
1082     case 1:
1083         errno = EOPNOTSUPP;
1084         return(-1);
1085     default:
1086         flog(LOG_CRIT, "unknown net mode %i active", confgetint("net", "mode"));
1087         errno = EOPNOTSUPP;
1088         return(-1);
1089     }
1090 }
1091
1092 int addreq(struct sockaddr *x, struct sockaddr *y)
1093 {
1094     struct sockaddr_un *u1, *u2;
1095     struct sockaddr_in *n1, *n2;
1096 #ifdef HAVE_IPV6
1097     struct sockaddr_in6 *s1, *s2;
1098 #endif
1099     
1100     if(x->sa_family != y->sa_family)
1101         return(0);
1102     switch(x->sa_family) {
1103     case AF_UNIX:
1104         u1 = (struct sockaddr_un *)x; u2 = (struct sockaddr_un *)y;
1105         if(strncmp(u1->sun_path, u2->sun_path, sizeof(u1->sun_path)))
1106             return(0);
1107         break;
1108     case AF_INET:
1109         n1 = (struct sockaddr_in *)x; n2 = (struct sockaddr_in *)y;
1110         if(n1->sin_port != n2->sin_port)
1111             return(0);
1112         if(n1->sin_addr.s_addr != n2->sin_addr.s_addr)
1113             return(0);
1114         break;
1115     case AF_INET6:
1116         s1 = (struct sockaddr_in6 *)x; s2 = (struct sockaddr_in6 *)y;
1117         if(s1->sin6_port != s2->sin6_port)
1118             return(0);
1119         if(memcmp(s1->sin6_addr.s6_addr, s2->sin6_addr.s6_addr, sizeof(s1->sin6_addr.s6_addr)))
1120             return(0);
1121         break;
1122     }
1123     return(1);
1124 }
1125
1126 char *formataddress(struct sockaddr *arg, socklen_t arglen)
1127 {
1128     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1129                                * lowercase letters to 1, so I do this
1130                                * instead. */
1131     struct sockaddr_in *ipv4;
1132 #ifdef HAVE_IPV6
1133     struct sockaddr_in6 *ipv6;
1134 #endif
1135     static char *ret = NULL;
1136     char buf[1024];
1137     
1138     if(ret != NULL)
1139         free(ret);
1140     ret = NULL;
1141     switch(arg->sa_family)
1142     {
1143     case AF_UNIX:
1144         UNIX = (struct sockaddr_un *)arg;
1145         ret = sprintf2("%s", UNIX->sun_path);
1146         break;
1147     case AF_INET:
1148         ipv4 = (struct sockaddr_in *)arg;
1149         if(inet_ntop(AF_INET, &ipv4->sin_addr, buf, sizeof(buf)) == NULL)
1150             return(NULL);
1151         ret = sprintf2("%s:%i", buf, (int)ntohs(ipv4->sin_port));
1152         break;
1153 #ifdef HAVE_IPV6
1154     case AF_INET6:
1155         ipv6 = (struct sockaddr_in6 *)arg;
1156         if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL)
1157             return(NULL);
1158         ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port));
1159         break;
1160 #endif
1161     default:
1162         errno = EPFNOSUPPORT;
1163         break;
1164     }
1165     return(ret);
1166 }
1167
1168 #if 0
1169
1170 /* 
1171  * It was very nice to use this, but it seems
1172  * to mess things up, so I guess it has to go... :-(
1173  */
1174
1175 static int formataddress(FILE *stream, const struct printf_info *info, const void *const *args)
1176 {
1177     struct sockaddr *arg;
1178     socklen_t arglen;
1179     struct sockaddr_un *UNIX; /* Some wise guy has #defined unix with
1180                                * lowercase letters to 1, so I do this
1181                                * instead. */
1182     struct sockaddr_in *ipv4;
1183     int ret;
1184     
1185     arg = *(struct sockaddr **)(args[0]);
1186     arglen = *(socklen_t *)(args[1]);
1187     switch(arg->sa_family)
1188     {
1189     case AF_UNIX:
1190         UNIX = (struct sockaddr_un *)arg;
1191         ret = fprintf(stream, "%s", UNIX->sun_path);
1192         break;
1193     case AF_INET:
1194         ipv4 = (struct sockaddr_in *)arg;
1195         ret = fprintf(stream, "%s:%i", inet_ntoa(ipv4->sin_addr), (int)ntohs(ipv4->sin_port));
1196         break;
1197     default:
1198         ret = -1;
1199         errno = EPFNOSUPPORT;
1200         break;
1201     }
1202     return(ret);
1203 }
1204
1205 static int formataddress_arginfo(const struct printf_info *info, size_t n, int *argtypes)
1206 {
1207     if(n > 0)
1208         argtypes[0] = PA_POINTER;
1209     if(n > 1)
1210         argtypes[1] = PA_INT; /* Sources tell me that socklen_t _must_
1211                                * be an int, so I guess this should be
1212                                * safe. */
1213     return(2);
1214 }
1215 #endif
1216
1217 static int init(int hup)
1218 {
1219     if(!hup)
1220     {
1221         /*
1222         if(register_printf_function('N', formataddress, formataddress_arginfo))
1223         {
1224             flog(LOG_CRIT, "could not register printf handler %%N: %s", strerror(errno));
1225             return(1);
1226         }
1227         */
1228     }
1229     return(0);
1230 }
1231
1232 static void terminate(void)
1233 {
1234     while(sockets != NULL)
1235         unlinksock(sockets);
1236 }
1237
1238 static struct module me =
1239 {
1240     .name = "net",
1241     .conf =
1242     {
1243         .vars = myvars
1244     },
1245     .init = init,
1246     .terminate = terminate
1247 };
1248
1249 MODULE(me)