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