1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "../public/nsapi.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34 #include <sys/shm.h>
35 #include <sys/types.h>
36 #include <sys/ipc.h>
37 #include <sys/socket.h>
38 #include <sys/file.h>
39 #include <netinet/in.h>
40 #include <netdb.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <strings.h>
46 #include <stdbool.h>
47 #include <pthread.h>
48
49 #include <ucx/map.h>
50
51 #include "../util/atomic.h"
52 #include "httplistener.h"
53 #include "netsite.h"
54
55 #include "session.h"
56 #include "configmanager.h"
57 #include "log.h"
58
59 UcxMap *listener_map =
NULL;
60
61 int start_all_listener() {
62 ServerConfiguration *conf = cfgmgr_get_server_config();
63 UcxList *ls = conf->listeners;
64 while(ls) {
65 HttpListener *listener = ls->data;
66 http_listener_start(listener);
67 ls = ls->next;
68 }
69
70 return 0;
71 }
72
73 HttpListener* http_listener_create(ListenerConfig *conf) {
74 if(listener_map ==
NULL) {
75 listener_map = ucx_map_new(
16);
76 }
77
78 HttpListener *fl = ucx_map_sstr_get(listener_map, conf->name);
79 if(fl ==
NULL) {
80 return http_listener_new(conf);
81 }
82
83 HttpListener* newls = calloc(
1,
sizeof(HttpListener));
84 if(newls ==
NULL) {
85
86 }
87
88 newls->name = conf->name;
89 newls->cfg = conf->cfg;
90 newls->nacceptors = conf->nacceptors;
91 newls->default_vs.vs_name = conf->vs.ptr;
92 newls->port = fl->port;
93 newls->server_socket = fl->server_socket;
94 newls->running =
1;
95 newls->threadpool =
NULL;
96 newls->ref =
2;
97
98 newls->session_handler = fl->session_handler;
99
100
101 if(conf->threadpool.ptr !=
NULL) {
102 newls->threadpool = get_threadpool(conf->threadpool);
103 }
104 if(newls->threadpool ==
NULL) {
105 newls->threadpool = get_default_threadpool();
106 }
107
108
109 newls->acceptors = calloc(newls->nacceptors,
sizeof(
void*));
110 for (
int i=
0;i<newls->nacceptors;i++) {
111 newls->acceptors[i] = acceptor_new(newls);
112 }
113
114
115 fl->next = newls;
116
117
118 ucx_map_sstr_put(listener_map, newls->name, newls);
119
120 for (
int i=
0;i<newls->nacceptors;i++) {
121 acceptor_start(newls->acceptors[i]);
122 }
123
124
125
126 if(newls->port != conf->port) {
127
128 }
129
130 return newls;
131 }
132
133 HttpListener* http_listener_new(ListenerConfig *conf) {
134
135 if(listener_map ==
NULL) {
136 listener_map = ucx_map_new(
16);
137 }
138
139 HttpListener *fl = ucx_map_sstr_get(listener_map, conf->name);
140 if(fl !=
NULL) {
141 return fl;
142 }
143
144
145 HttpListener *listener = malloc(
sizeof(HttpListener));
146 listener->running =
0;
147 listener->cfg = conf->cfg;
148 listener->name = conf->name;
149 listener->default_vs.vs_name = conf->vs.ptr;
150 listener->threadpool =
NULL;
151 if(conf->threadpool.ptr !=
NULL) {
152 listener->threadpool = get_threadpool(conf->threadpool);
153 }
154 if(listener->threadpool ==
NULL) {
155 listener->threadpool = get_default_threadpool();
156 }
157 if(conf->blockingio) {
158 listener->session_handler = create_basic_session_handler();
159 }
else {
160 listener->session_handler = create_event_session_handler();
161 }
162 listener->nacceptors = conf->nacceptors;
163 listener->port = conf->port;
164 listener->ref =
1;
165 listener->next =
NULL;
166 listener->ssl =
NULL;
167
168 int error =
0;
169
170 if(conf->ssl) {
171 listener->ssl = malloc(
sizeof(HttpSSL));
172
173 SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
174 SSL_CTX_set_options(
175 ctx,
176 SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv3);
177 if(conf->disable_proto.ptr) {
178 ssize_t n =
0;
179 sstr_t *plist = sstrsplit(conf->disable_proto,
S(
","), &n);
180 if(plist) {
181 for(
int i=
0;i<n;i++) {
182 sstr_t proto = plist[i];
183 log_ereport(
184 LOG_VERBOSE,
185 "Listener %s: Disable protocol %s",
186 listener->name.ptr,
187 proto.ptr);
188 if(!sstrcasecmp(sstrtrim(proto),
S(
"SSLv2"))) {
189 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
190 }
else if(!sstrcasecmp(sstrtrim(proto),
S(
"SSLv3"))) {
191 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
192 }
else if(!sstrcasecmp(sstrtrim(proto),
S(
"TLSv1"))) {
193 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
194 }
else if(!sstrcasecmp(sstrtrim(proto),
S(
"TLSv1.1"))) {
195 #ifdef SSL_OP_NO_TLSv1_1
196 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
197 #else
198 log_ereport(
199 LOG_WARN,
200 "Listener: %s: TLSv1.1 already not supported",
201 listener->name.ptr);
202 #endif
203 }
else if(sstrcasecmp(sstrtrim(proto),
S(
"TLSv1.2"))) {
204 #ifdef SSL_OP_NO_TLSv1_2
205 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
206 #else
207 log_ereport(
208 LOG_WARN,
209 "Listener: %s: TLSv1.2 already not supported",
210 listener->name.ptr);
211 #endif
212 }
else if(sstrcasecmp(sstrtrim(proto),
S(
"TLSv1.3"))) {
213 #ifdef SSL_OP_NO_TLSv1_3
214 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
215 #else
216 log_ereport(
217 LOG_WARN,
218 "Listener: %s: TLSv1.3 already not supported",
219 listener->name.ptr);
220 #endif
221 }
else {
222 error =
1;
223 log_ereport(
224 LOG_MISCONFIG,
225 "Listener: %s: Unknown protocol %s",
226 listener->name.ptr,
227 proto.ptr);
228 }
229 free(proto.ptr);
230 }
231 free(plist);
232 }
233 }
234
235 if(error) {
236 return NULL;
237 }
238
239
240 sstr_t file;
241 int ret;
242 char errbuf[
512];
243
244 if(!conf->chainfile.ptr) {
245 file = sstrdup(conf->certfile);
246 ret = SSL_CTX_use_certificate_file(ctx, file.ptr,
SSL_FILETYPE_PEM);
247 free(file.ptr);
248 if(!ret) {
249 ERR_error_string(ERR_get_error(), errbuf);
250 log_ereport(
LOG_MISCONFIG,
"Cannot load ssl chain file: %s", errbuf);
251 return NULL;
252 }
253 }
else {
254 file = sstrdup(conf->chainfile);
255 ret = SSL_CTX_use_certificate_chain_file(ctx, file.ptr);
256 free(file.ptr);
257 if(!ret) {
258 ERR_error_string(ERR_get_error(), errbuf);
259 log_ereport(
LOG_MISCONFIG,
"Cannot load ssl cert file: %s", errbuf);
260 return NULL;
261 }
262 }
263
264 file = sstrdup(conf->privkeyfile);
265 ret = SSL_CTX_use_PrivateKey_file(ctx, file.ptr,
SSL_FILETYPE_PEM);
266 free(file.ptr);
267 if(!ret) {
268 ERR_error_string(ERR_get_error(), errbuf);
269 log_ereport(
LOG_MISCONFIG,
"Cannot load ssl key file: %s", errbuf);
270 return NULL;
271 }
272
273
274 listener->ssl->sslctx = ctx;
275 }
276
277
278 ucx_map_sstr_put(listener_map, listener->name, listener);
279
280 struct sockaddr_in servaddr;
281
282
283 memset(&servaddr,
0,
sizeof(servaddr));
284 servaddr.sin_family =
AF_INET;
285 servaddr.sin_addr.s_addr = htonl(
INADDR_ANY);
286 servaddr.sin_port = htons(conf->port);
287
288
289 if((listener->server_socket = socket(
AF_INET,
SOCK_STREAM,
0)) == -
1) {
290 perror(
"Error: http_listener_new: socket");
291 return NULL;
292 }
293
294 int o =
1;
295 setsockopt(
296 listener->server_socket,
297 SOL_SOCKET,
SO_REUSEADDR,
298 &o,
299 sizeof(
int));
300
301
302 if(bind(listener->server_socket, (
struct sockaddr*)&servaddr,
sizeof(servaddr))){
303 log_ereport(
LOG_FAILURE,
"http_listener_new: bind failed. Port: %d", conf->port);
304 return NULL;
305 }
306
307
308 listener->acceptors = calloc(listener->nacceptors,
sizeof(
void*));
309 for (
int i=
0;i<listener->nacceptors;i++) {
310 listener->acceptors[i] = acceptor_new(listener);
311 }
312
313 return listener;
314 }
315
316 int http_listener_start(HttpListener *listener) {
317 if(listener->running) {
318 return 0;
319 }
320 log_ereport(
LOG_INFORM,
"start listener on port %d", listener->port);
321
322 if (listen(listener->server_socket,
256) == -
1) {
323 log_ereport(
LOG_FAILURE,
"http_listener_start: listen failed");
324 return -
1;
325 }
326
327
328 for (
int i=
0;i<listener->nacceptors;i++) {
329 acceptor_start(listener->acceptors[i]);
330 }
331
332 return 0;
333 }
334
335 void http_listener_ref(HttpListener *listener) {
336 ws_atomic_inc32(&listener->ref);
337 }
338
339 void http_listener_unref(HttpListener *listener) {
340 uint32_t ref = ws_atomic_dec32(&listener->ref);
341 if(ref ==
0) {
342 free(listener->acceptors);
343
344
345 free(listener);
346 }
347 }
348
349
350
351 Acceptor* acceptor_new(HttpListener *listener) {
352 Acceptor *acceptor = malloc(
sizeof(Acceptor));
353 acceptor->listener = listener;
354 return acceptor;
355 }
356
357 void acceptor_start(Acceptor *a) {
358 if(pthread_create(
359 &a->tid,
360 NULL,
361 (
void*(*)(
void*))acceptor_thread,
362 a) !=
0)
363 {
364 perror(
"Error: acceptor_start: pthread_create");
365 }
366 }
367
368 void* acceptor_thread(Acceptor *acceptor) {
369 WS_ASSERT(acceptor);
370 WS_ASSERT(acceptor->listener);
371 WS_ASSERT(acceptor->listener->session_handler);
372 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection);
373
374 HttpListener *listener = acceptor->listener;
375
376 for (;;) {
377
378 struct sockaddr_in ca;
379 socklen_t length =
sizeof(ca);
380 int clientfd;
381
382
383 clientfd = accept(
384 listener->server_socket,
385 (
struct sockaddr*)&ca,
386 &length);
387 if (clientfd == -
1) {
388 perror(
"Error: acceptor_thread: accept");
389 continue;
390 }
391
392
393 HttpListener *ls = listener;
394 int acceptor_exit =
0;
395 while(ls->next) {
396 ls = ls->next;
397 acceptor_exit =
1;
398 }
399
400
401 Connection *conn = malloc(
sizeof(Connection));
402 conn->address = ca;
403 conn->fd = clientfd;
404 conn->listener = ls;
405 conn->ssl_accepted =
0;
406 if(ls->ssl) {
407
408
409 int flags;
410 if((flags = fcntl(conn->fd,
F_GETFL,
0)) == -
1) {
411 flags =
0;
412 }
413 if(fcntl(conn->fd,
F_SETFL, flags |
O_NONBLOCK)) {
414 perror(
"Error: acceptor_thread: fcntl");
415
416 }
417
418 SSL *ssl = SSL_new(ls->ssl->sslctx);
419 SSL_set_fd(ssl, clientfd);
420
421 conn->ssl = ssl;
422 conn->read = connection_ssl_read;
423 conn->write = connection_ssl_write;
424 conn->close = connection_ssl_close;
425 }
else {
426 conn->ssl =
NULL;
427 conn->read = connection_read;
428 conn->write = connection_write;
429 conn->close = connection_close;
430 }
431
432 if(conn) {
433 cfg_ref(ls->cfg);
434
435
436 ls->session_handler->enqueue_connection(
437 ls->session_handler,
438 conn);
439 }
440
441
442
443 if(acceptor_exit) {
444
445 break;
446 }
447 }
448
449 http_listener_unref(listener->next);
450 http_listener_unref(listener);
451
452 return NULL;
453 }
454