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