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