root/src/noit_listener.c

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

more work -- this doesn't do much except add plumbing

  • 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 <sys/time.h>
10 #include <sys/socket.h>
11 #include <sys/ioctl.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14
15 #include "eventer/eventer.h"
16 #include "utils/noit_log.h"
17 #include "noit_listener.h"
18
19 static int
20 noit_listener_acceptor(eventer_t e, int mask,
21                        void *closure, struct timeval *tv) {
22   int conn, newmask = EVENTER_READ;
23   socklen_t salen;
24   listener_closure_t listener_closure = (listener_closure_t)closure;
25   union {
26     struct sockaddr_in addr4;
27     struct sockaddr_in6 addr6;
28   } s;
29
30   noit_log(noit_stderr, NULL, "Accepting\n");
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   listener_closure_t listener_closure;
63   eventer_t event;
64   union {
65     struct in_addr addr4;
66     struct in6_addr addr6;
67   } a;
68   union {
69     struct sockaddr_in addr4;
70     struct sockaddr_in6 addr6;
71   } s;
72
73   family = AF_INET;
74   rv = inet_pton(family, host, &a);
75   if(rv != 1) {
76     family = AF_INET6;
77     rv = inet_pton(family, host, &a);
78     if(rv != 1) {
79       noit_log(noit_stderr, NULL, "Cannot translate '%s' to IP\n", host);
80       return -1;
81     }
82   }
83
84   fd = socket(family, type, 0);
85   if(fd < 0) return -1;
86
87   on = 1;
88   if(ioctl(fd, FIONBIO, &on)) {
89     close(fd);
90     return -1;
91   }
92
93   memset(&s, 0, sizeof(s));
94   s.addr6.sin6_family = family;
95   s.addr6.sin6_port = htons(port);
96   memcpy(&s.addr6.sin6_addr, &a, sizeof(a));
97   if(bind(fd, (struct sockaddr *)&s,
98           (family == AF_INET) ?  sizeof(s.addr4) : sizeof(s.addr6)) < 0) {
99     close(fd);
100     return -1;
101   }
102
103   if(type == SOCK_STREAM) {
104     if(listen(fd, backlog) < 0) {
105       close(fd);
106       return -1;
107     }
108   }
109
110   listener_closure = calloc(1, sizeof(*listener_closure));
111   listener_closure->family = family;
112   listener_closure->port = htons(port);
113   listener_closure->dispatch_closure = closure;
114
115   event = eventer_alloc();
116   event->fd = fd;
117   event->mask = EVENTER_READ | EVENTER_EXCEPTION;
118   event->callback = noit_listener_acceptor;
119   event->closure = listener_closure;
120
121   eventer_add(event);
122   return 0;
123 }
Note: See TracBrowser for help on using the browser.