root/src/noit_listener.c

Revision 7212f9de44a1f04707e822e3337100a80f707cb3, 3.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

oh my, it compiles and runs

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <unistd.h>
9 #include <errno.h>
10 #include <sys/time.h>
11 #include <sys/socket.h>
12 #include <sys/ioctl.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15
16 #include "eventer/eventer.h"
17 #include "utils/noit_log.h"
18 #include "noit_listener.h"
19
20 static int
21 noit_listener_acceptor(eventer_t e, int mask,
22                        void *closure, struct timeval *tv) {
23   int conn, newmask = EVENTER_READ;
24   socklen_t salen;
25   listener_closure_t listener_closure = (listener_closure_t)closure;
26   union {
27     struct sockaddr_in addr4;
28     struct sockaddr_in6 addr6;
29   } s;
30
31   if(mask & EVENTER_EXCEPTION) {
32     eventer_remove_fd(e->fd);
33     close(e->fd);
34     return 0;
35   }
36
37   conn = e->opset->accept(e->fd, (struct sockaddr *)&s, &salen, &newmask, e);
38   if(conn >= 0) {
39     socklen_t on = 1;
40     eventer_t newe;
41     if(ioctl(conn, FIONBIO, &on)) {
42       close(conn);
43       goto accept_bail;
44     }
45     newe = eventer_alloc();
46     newe->fd = conn;
47     newe->mask = EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION;
48     newe->callback = listener_closure->dispatch_callback;
49     newe->closure = listener_closure->dispatch_closure;
50     eventer_add(newe);
51   }
52  accept_bail:
53   return newmask | EVENTER_EXCEPTION;
54 }
55
56 int
57 noit_listener(char *host, unsigned short port, int type,
58               int backlog, eventer_func_t handler, void *closure) {
59   int rv, fd;
60   int8_t family;
61   socklen_t on;
62   long reuse;
63   listener_closure_t listener_closure;
64   eventer_t event;
65   union {
66     struct in_addr addr4;
67     struct in6_addr addr6;
68   } a;
69   union {
70     struct sockaddr_in addr4;
71     struct sockaddr_in6 addr6;
72   } s;
73
74   family = AF_INET;
75   rv = inet_pton(family, host, &a);
76   if(rv != 1) {
77     family = AF_INET6;
78     rv = inet_pton(family, host, &a);
79     if(rv != 1) {
80       noit_log(noit_stderr, NULL, "Cannot translate '%s' to IP\n", host);
81       return -1;
82     }
83   }
84
85   fd = socket(family, type, 0);
86   if(fd < 0) return -1;
87
88   on = 1;
89   if(ioctl(fd, FIONBIO, &on)) {
90     close(fd);
91     return -1;
92   }
93
94   reuse = 1;
95   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
96                  (void*)&reuse, sizeof(reuse)) != 0) {
97
98     close(fd);
99     return -1;
100   }
101
102   memset(&s, 0, sizeof(s));
103   s.addr6.sin6_family = family;
104   s.addr6.sin6_port = htons(port);
105   memcpy(&s.addr6.sin6_addr, &a, sizeof(a));
106   if(bind(fd, (struct sockaddr *)&s,
107           (family == AF_INET) ?  sizeof(s.addr4) : sizeof(s.addr6)) < 0) {
108     noit_log(noit_stderr, NULL, "bind failed: %s\b", strerror(errno));
109     close(fd);
110     return -1;
111   }
112
113   if(type == SOCK_STREAM) {
114     if(listen(fd, backlog) < 0) {
115       close(fd);
116       return -1;
117     }
118   }
119
120   listener_closure = calloc(1, sizeof(*listener_closure));
121   listener_closure->family = family;
122   listener_closure->port = htons(port);
123   listener_closure->dispatch_callback = handler;
124   listener_closure->dispatch_closure = closure;
125
126   event = eventer_alloc();
127   event->fd = fd;
128   event->mask = EVENTER_READ | EVENTER_EXCEPTION;
129   event->callback = noit_listener_acceptor;
130   event->closure = listener_closure;
131
132   eventer_add(event);
133   return 0;
134 }
Note: See TracBrowser for help on using the browser.