aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c747
1 files changed, 361 insertions, 386 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 2fbd3abc..3b2ebab0 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -48,30 +48,28 @@
48 * already exists 48 * already exists
49 */ 49 */
50int 50int
51MHD_register_handler(struct MHD_Daemon * daemon, 51MHD_register_handler (struct MHD_Daemon *daemon,
52 const char * uri_prefix, 52 const char *uri_prefix,
53 MHD_AccessHandlerCallback dh, 53 MHD_AccessHandlerCallback dh, void *dh_cls)
54 void * dh_cls) { 54{
55 struct MHD_Access_Handler * ah; 55 struct MHD_Access_Handler *ah;
56 56
57 if ( (daemon == NULL) || 57 if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL))
58 (uri_prefix == NULL) || 58 return MHD_NO;
59 (dh == NULL) )
60 return MHD_NO;
61 ah = daemon->handlers; 59 ah = daemon->handlers;
62 while (ah != NULL) { 60 while (ah != NULL)
63 if (0 == strcmp(uri_prefix, 61 {
64 ah->uri_prefix)) 62 if (0 == strcmp (uri_prefix, ah->uri_prefix))
65 return MHD_NO; 63 return MHD_NO;
66 ah = ah->next; 64 ah = ah->next;
67 } 65 }
68 ah = malloc(sizeof(struct MHD_Access_Handler)); 66 ah = malloc (sizeof (struct MHD_Access_Handler));
69 ah->next = daemon->handlers; 67 ah->next = daemon->handlers;
70 ah->uri_prefix = strdup(uri_prefix); 68 ah->uri_prefix = strdup (uri_prefix);
71 ah->dh = dh; 69 ah->dh = dh;
72 ah->dh_cls = dh_cls; 70 ah->dh_cls = dh_cls;
73 daemon->handlers = ah; 71 daemon->handlers = ah;
74 return MHD_YES; 72 return MHD_YES;
75} 73}
76 74
77 75
@@ -84,34 +82,33 @@ MHD_register_handler(struct MHD_Daemon * daemon,
84 * is not known for this daemon 82 * is not known for this daemon
85 */ 83 */
86int 84int
87MHD_unregister_handler(struct MHD_Daemon * daemon, 85MHD_unregister_handler (struct MHD_Daemon *daemon,
88 const char * uri_prefix, 86 const char *uri_prefix,
89 MHD_AccessHandlerCallback dh, 87 MHD_AccessHandlerCallback dh, void *dh_cls)
90 void * dh_cls) { 88{
91 struct MHD_Access_Handler * prev; 89 struct MHD_Access_Handler *prev;
92 struct MHD_Access_Handler * pos; 90 struct MHD_Access_Handler *pos;
93 91
94 if ( (daemon == NULL) || 92 if ((daemon == NULL) || (uri_prefix == NULL) || (dh == NULL))
95 (uri_prefix == NULL) || 93 return MHD_NO;
96 (dh == NULL) )
97 return MHD_NO;
98 pos = daemon->handlers; 94 pos = daemon->handlers;
99 prev = NULL; 95 prev = NULL;
100 while (pos != NULL) { 96 while (pos != NULL)
101 if ( (dh == pos->dh) && 97 {
102 (dh_cls == pos->dh_cls) && 98 if ((dh == pos->dh) &&
103 (0 == strcmp(uri_prefix, 99 (dh_cls == pos->dh_cls) &&
104 pos->uri_prefix)) ) { 100 (0 == strcmp (uri_prefix, pos->uri_prefix)))
105 if (prev == NULL) 101 {
106 daemon->handlers = pos->next; 102 if (prev == NULL)
107 else 103 daemon->handlers = pos->next;
108 prev->next = pos->next; 104 else
109 free(pos); 105 prev->next = pos->next;
110 return MHD_YES; 106 free (pos);
107 return MHD_YES;
108 }
109 prev = pos;
110 pos = pos->next;
111 } 111 }
112 prev = pos;
113 pos = pos->next;
114 }
115 return MHD_NO; 112 return MHD_NO;
116} 113}
117 114
@@ -123,34 +120,32 @@ MHD_unregister_handler(struct MHD_Daemon * daemon,
123 * options for this call. 120 * options for this call.
124 */ 121 */
125int 122int
126MHD_get_fdset(struct MHD_Daemon * daemon, 123MHD_get_fdset (struct MHD_Daemon *daemon,
127 fd_set * read_fd_set, 124 fd_set * read_fd_set,
128 fd_set * write_fd_set, 125 fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
129 fd_set * except_fd_set, 126{
130 int * max_fd) { 127 struct MHD_Connection *pos;
131 struct MHD_Connection * pos; 128
132 129 if ((daemon == NULL) ||
133 if ( (daemon == NULL) || 130 (read_fd_set == NULL) ||
134 (read_fd_set == NULL) || 131 (write_fd_set == NULL) ||
135 (write_fd_set == NULL) || 132 (except_fd_set == NULL) ||
136 (except_fd_set == NULL) || 133 (max_fd == NULL) ||
137 (max_fd == NULL) || 134 ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0))
138 ( (daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0) ) 135 return MHD_NO;
139 return MHD_NO; 136 FD_SET (daemon->socket_fd, read_fd_set);
140 FD_SET(daemon->socket_fd, 137 if ((*max_fd) < daemon->socket_fd)
141 read_fd_set);
142 if ( (*max_fd) < daemon->socket_fd)
143 *max_fd = daemon->socket_fd; 138 *max_fd = daemon->socket_fd;
144 pos = daemon->connections; 139 pos = daemon->connections;
145 while (pos != NULL) { 140 while (pos != NULL)
146 if (MHD_YES != MHD_connection_get_fdset(pos, 141 {
147 read_fd_set, 142 if (MHD_YES != MHD_connection_get_fdset (pos,
148 write_fd_set, 143 read_fd_set,
149 except_fd_set, 144 write_fd_set,
150 max_fd)) 145 except_fd_set, max_fd))
151 return MHD_NO; 146 return MHD_NO;
152 pos = pos->next; 147 pos = pos->next;
153 } 148 }
154 return MHD_YES; 149 return MHD_YES;
155} 150}
156 151
@@ -160,8 +155,9 @@ MHD_get_fdset(struct MHD_Daemon * daemon,
160 * connection. 155 * connection.
161 */ 156 */
162static void * 157static void *
163MHD_handle_connection(void * data) { 158MHD_handle_connection (void *data)
164 struct MHD_Connection * con = data; 159{
160 struct MHD_Connection *con = data;
165 int num_ready; 161 int num_ready;
166 fd_set rs; 162 fd_set rs;
167 fd_set ws; 163 fd_set ws;
@@ -169,42 +165,35 @@ MHD_handle_connection(void * data) {
169 int max; 165 int max;
170 166
171 if (con == NULL) 167 if (con == NULL)
172 abort(); 168 abort ();
173 while ( (! con->daemon->shutdown) && 169 while ((!con->daemon->shutdown) && (con->socket_fd != -1))
174 (con->socket_fd != -1) ) { 170 {
175 FD_ZERO(&rs); 171 FD_ZERO (&rs);
176 FD_ZERO(&ws); 172 FD_ZERO (&ws);
177 FD_ZERO(&es); 173 FD_ZERO (&es);
178 max = 0; 174 max = 0;
179 MHD_connection_get_fdset(con, 175 MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
180 &rs, 176 num_ready = SELECT (max + 1, &rs, &ws, &es, NULL);
181 &ws, 177 if (num_ready <= 0)
182 &es, 178 {
183 &max); 179 if (errno == EINTR)
184 num_ready = SELECT(max + 1, 180 continue;
185 &rs, 181 break;
186 &ws, 182 }
187 &es, 183 if (((FD_ISSET (con->socket_fd, &rs)) &&
188 NULL); 184 (MHD_YES != MHD_connection_handle_read (con))) ||
189 if (num_ready <= 0) { 185 ((con->socket_fd != -1) &&
190 if (errno == EINTR) 186 (FD_ISSET (con->socket_fd, &ws)) &&
191 continue; 187 (MHD_YES != MHD_connection_handle_write (con))))
192 break; 188 break;
189 if ((con->headersReceived == 1) && (con->response == NULL))
190 MHD_call_connection_handler (con);
191 }
192 if (con->socket_fd != -1)
193 {
194 CLOSE (con->socket_fd);
195 con->socket_fd = -1;
193 } 196 }
194 if ( ( (FD_ISSET(con->socket_fd, &rs)) &&
195 (MHD_YES != MHD_connection_handle_read(con)) ) ||
196 ( (con->socket_fd != -1) &&
197 (FD_ISSET(con->socket_fd, &ws)) &&
198 (MHD_YES != MHD_connection_handle_write(con)) ) )
199 break;
200 if ( (con->headersReceived == 1) &&
201 (con->response == NULL) )
202 MHD_call_connection_handler(con);
203 }
204 if (con->socket_fd != -1) {
205 CLOSE(con->socket_fd);
206 con->socket_fd = -1;
207 }
208 return NULL; 197 return NULL;
209} 198}
210 199
@@ -215,77 +204,66 @@ MHD_handle_connection(void * data) {
215 * accept policy callback. 204 * accept policy callback.
216 */ 205 */
217static int 206static int
218MHD_accept_connection(struct MHD_Daemon * daemon) { 207MHD_accept_connection (struct MHD_Daemon *daemon)
219 struct MHD_Connection * connection; 208{
209 struct MHD_Connection *connection;
220 struct sockaddr_in6 addr6; 210 struct sockaddr_in6 addr6;
221 struct sockaddr * addr = (struct sockaddr*) &addr6; 211 struct sockaddr *addr = (struct sockaddr *) &addr6;
222 socklen_t addrlen; 212 socklen_t addrlen;
223 int s; 213 int s;
224 214
225 215
226 if (sizeof(struct sockaddr) > sizeof(struct sockaddr_in6)) 216 if (sizeof (struct sockaddr) > sizeof (struct sockaddr_in6))
227 abort(); /* fatal, serious error */ 217 abort (); /* fatal, serious error */
228 addrlen = sizeof(struct sockaddr_in6); 218 addrlen = sizeof (struct sockaddr_in6);
229 memset(addr, 219 memset (addr, 0, sizeof (struct sockaddr_in6));
230 0, 220 s = ACCEPT (daemon->socket_fd, addr, &addrlen);
231 sizeof(struct sockaddr_in6)); 221 if ((s < 0) || (addrlen <= 0))
232 s = ACCEPT(daemon->socket_fd, 222 {
233 addr, 223 MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno));
234 &addrlen); 224 if (s != -1)
235 if ( (s < 0) || 225 CLOSE (s); /* just in case */
236 (addrlen <= 0) ) { 226 return MHD_NO;
237 MHD_DLOG(daemon, 227 }
238 "Error accepting connection: %s\n", 228 if (daemon->max_connections == 0)
239 STRERROR(errno)); 229 {
240 if (s != -1) 230 /* above connection limit - reject */
241 CLOSE(s); /* just in case */ 231 CLOSE (s);
242 return MHD_NO; 232 return MHD_NO;
243 } 233 }
244 if (daemon->max_connections == 0) { 234 if ((daemon->apc != NULL) &&
245 /* above connection limit - reject */ 235 (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen)))
246 CLOSE(s); 236 {
247 return MHD_NO; 237 CLOSE (s);
248 } 238 return MHD_YES;
249 if ( (daemon->apc != NULL) && 239 }
250 (MHD_NO == daemon->apc(daemon->apc_cls, 240 connection = malloc (sizeof (struct MHD_Connection));
251 addr, 241 memset (connection, 0, sizeof (struct MHD_Connection));
252 addrlen)) ) {
253 CLOSE(s);
254 return MHD_YES;
255 }
256 connection = malloc(sizeof(struct MHD_Connection));
257 memset(connection,
258 0,
259 sizeof(struct MHD_Connection));
260 connection->pool = NULL; 242 connection->pool = NULL;
261 connection->addr = malloc(addrlen); 243 connection->addr = malloc (addrlen);
262 if (connection->addr == NULL) { 244 if (connection->addr == NULL)
263 CLOSE(s); 245 {
264 free(connection); 246 CLOSE (s);
265 return MHD_NO; 247 free (connection);
266 } 248 return MHD_NO;
267 memcpy(connection->addr, 249 }
268 addr, 250 memcpy (connection->addr, addr, addrlen);
269 addrlen);
270 connection->addr_len = addrlen; 251 connection->addr_len = addrlen;
271 connection->socket_fd = s; 252 connection->socket_fd = s;
272 connection->daemon = daemon; 253 connection->daemon = daemon;
273 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION) ) && 254 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
274 (0 != pthread_create(&connection->pid, 255 (0 != pthread_create (&connection->pid,
275 NULL, 256 NULL, &MHD_handle_connection, connection)))
276 &MHD_handle_connection, 257 {
277 connection)) ) { 258 MHD_DLOG (daemon, "Failed to create a thread: %s\n", STRERROR (errno));
278 MHD_DLOG(daemon, 259 CLOSE (s);
279 "Failed to create a thread: %s\n", 260 free (connection->addr);
280 STRERROR(errno)); 261 free (connection);
281 CLOSE(s); 262 return MHD_NO;
282 free(connection->addr); 263 }
283 free(connection);
284 return MHD_NO;
285 }
286 connection->next = daemon->connections; 264 connection->next = daemon->connections;
287 daemon->connections = connection; 265 daemon->connections = connection;
288 daemon->max_connections--; 266 daemon->max_connections--;
289 return MHD_YES; 267 return MHD_YES;
290} 268}
291 269
@@ -301,43 +279,46 @@ MHD_accept_connection(struct MHD_Daemon * daemon) {
301 * the upload data buffer is full). 279 * the upload data buffer is full).
302 */ 280 */
303static void 281static void
304MHD_cleanup_connections(struct MHD_Daemon * daemon) { 282MHD_cleanup_connections (struct MHD_Daemon *daemon)
305 struct MHD_Connection * pos; 283{
306 struct MHD_Connection * prev; 284 struct MHD_Connection *pos;
307 void * unused; 285 struct MHD_Connection *prev;
286 void *unused;
308 287
309 pos = daemon->connections; 288 pos = daemon->connections;
310 prev = NULL; 289 prev = NULL;
311 while (pos != NULL) { 290 while (pos != NULL)
312 if (pos->socket_fd == -1) { 291 {
313 if (prev == NULL) 292 if (pos->socket_fd == -1)
314 daemon->connections = pos->next; 293 {
315 else 294 if (prev == NULL)
316 prev->next = pos->next; 295 daemon->connections = pos->next;
317 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { 296 else
318 pthread_kill(pos->pid, SIGALRM); 297 prev->next = pos->next;
319 pthread_join(pos->pid, &unused); 298 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
320 } 299 {
321 if (pos->response != NULL) 300 pthread_kill (pos->pid, SIGALRM);
322 MHD_destroy_response(pos->response); 301 pthread_join (pos->pid, &unused);
323 MHD_pool_destroy(pos->pool); 302 }
324 free(pos->addr); 303 if (pos->response != NULL)
325 free(pos); 304 MHD_destroy_response (pos->response);
326 daemon->max_connections++; 305 MHD_pool_destroy (pos->pool);
327 if (prev == NULL) 306 free (pos->addr);
328 pos = daemon->connections; 307 free (pos);
329 else 308 daemon->max_connections++;
330 pos = prev->next; 309 if (prev == NULL)
331 continue; 310 pos = daemon->connections;
311 else
312 pos = prev->next;
313 continue;
314 }
315
316 if ((pos->headersReceived == 1) && (pos->response == NULL))
317 MHD_call_connection_handler (pos);
318
319 prev = pos;
320 pos = pos->next;
332 } 321 }
333
334 if ( (pos->headersReceived == 1) &&
335 (pos->response == NULL) )
336 MHD_call_connection_handler(pos);
337
338 prev = pos;
339 pos = pos->next;
340 }
341} 322}
342 323
343 324
@@ -348,9 +329,9 @@ MHD_cleanup_connections(struct MHD_Daemon * daemon) {
348 * @return MHD_NO on serious errors, MHD_YES on success 329 * @return MHD_NO on serious errors, MHD_YES on success
349 */ 330 */
350static int 331static int
351MHD_select(struct MHD_Daemon * daemon, 332MHD_select (struct MHD_Daemon *daemon, int may_block)
352 int may_block) { 333{
353 struct MHD_Connection * pos; 334 struct MHD_Connection *pos;
354 int num_ready; 335 int num_ready;
355 fd_set rs; 336 fd_set rs;
356 fd_set ws; 337 fd_set ws;
@@ -361,61 +342,58 @@ MHD_select(struct MHD_Daemon * daemon,
361 342
362 timeout.tv_sec = 0; 343 timeout.tv_sec = 0;
363 timeout.tv_usec = 0; 344 timeout.tv_usec = 0;
364 if(daemon == NULL) 345 if (daemon == NULL)
365 abort(); 346 abort ();
366 FD_ZERO(&rs); 347 FD_ZERO (&rs);
367 FD_ZERO(&ws); 348 FD_ZERO (&ws);
368 FD_ZERO(&es); 349 FD_ZERO (&es);
369 max = 0; 350 max = 0;
370 351
371 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { 352 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
372 /* single-threaded, go over everything */ 353 {
373 if (MHD_NO == MHD_get_fdset(daemon, 354 /* single-threaded, go over everything */
374 &rs, 355 if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
375 &ws, 356 return MHD_NO;
376 &es, 357 }
377 &max)) 358 else
359 {
360 /* accept only, have one thread per connection */
361 max = daemon->socket_fd;
362 FD_SET (daemon->socket_fd, &rs);
363 }
364 num_ready = SELECT (max + 1,
365 &rs, &ws, &es, may_block == MHD_NO ? &timeout : NULL);
366 if (num_ready < 0)
367 {
368 if (errno == EINTR)
369 return MHD_YES;
370 MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno));
378 return MHD_NO; 371 return MHD_NO;
379 } else { 372 }
380 /* accept only, have one thread per connection */
381 max = daemon->socket_fd;
382 FD_SET(daemon->socket_fd, &rs);
383 }
384 num_ready = SELECT(max + 1,
385 &rs,
386 &ws,
387 &es,
388 may_block == MHD_NO ? &timeout : NULL);
389 if (num_ready < 0) {
390 if (errno == EINTR)
391 return MHD_YES;
392 MHD_DLOG(daemon,
393 "Select failed: %s\n",
394 STRERROR(errno));
395 return MHD_NO;
396 }
397 ds = daemon->socket_fd; 373 ds = daemon->socket_fd;
398 if (ds == -1) 374 if (ds == -1)
399 return MHD_YES; 375 return MHD_YES;
400 if (FD_ISSET(ds, 376 if (FD_ISSET (ds, &rs))
401 &rs)) 377 MHD_accept_connection (daemon);
402 MHD_accept_connection(daemon); 378 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
403 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) { 379 {
404 /* do not have a thread per connection, process all connections now */ 380 /* do not have a thread per connection, process all connections now */
405 pos = daemon->connections; 381 pos = daemon->connections;
406 while (pos != NULL) { 382 while (pos != NULL)
407 ds = pos->socket_fd; 383 {
408 if (ds == -1) { 384 ds = pos->socket_fd;
409 pos = pos->next; 385 if (ds == -1)
410 continue; 386 {
411 } 387 pos = pos->next;
412 if (FD_ISSET(ds, &rs)) 388 continue;
413 MHD_connection_handle_read(pos); 389 }
414 if (FD_ISSET(ds, &ws)) 390 if (FD_ISSET (ds, &rs))
415 MHD_connection_handle_write(pos); 391 MHD_connection_handle_read (pos);
416 pos = pos->next; 392 if (FD_ISSET (ds, &ws))
393 MHD_connection_handle_write (pos);
394 pos = pos->next;
395 }
417 } 396 }
418 }
419 return MHD_YES; 397 return MHD_YES;
420} 398}
421 399
@@ -431,13 +409,14 @@ MHD_select(struct MHD_Daemon * daemon,
431 * options for this call. 409 * options for this call.
432 */ 410 */
433int 411int
434MHD_run(struct MHD_Daemon * daemon) { 412MHD_run (struct MHD_Daemon *daemon)
435 if ( (daemon->shutdown != 0) || 413{
436 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 414 if ((daemon->shutdown != 0) ||
437 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) 415 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
416 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
438 return MHD_NO; 417 return MHD_NO;
439 MHD_select(daemon, MHD_NO); 418 MHD_select (daemon, MHD_NO);
440 MHD_cleanup_connections(daemon); 419 MHD_cleanup_connections (daemon);
441 return MHD_YES; 420 return MHD_YES;
442} 421}
443 422
@@ -447,12 +426,14 @@ MHD_run(struct MHD_Daemon * daemon) {
447 * is explicitly shut down. 426 * is explicitly shut down.
448 */ 427 */
449static void * 428static void *
450MHD_select_thread(void * cls) { 429MHD_select_thread (void *cls)
451 struct MHD_Daemon * daemon = cls; 430{
452 while (daemon->shutdown == 0) { 431 struct MHD_Daemon *daemon = cls;
453 MHD_select(daemon, MHD_YES); 432 while (daemon->shutdown == 0)
454 MHD_cleanup_connections(daemon); 433 {
455 } 434 MHD_select (daemon, MHD_YES);
435 MHD_cleanup_connections (daemon);
436 }
456 return NULL; 437 return NULL;
457} 438}
458 439
@@ -469,88 +450,75 @@ MHD_select_thread(void * cls) {
469 * @return NULL on error, handle to daemon on success 450 * @return NULL on error, handle to daemon on success
470 */ 451 */
471struct MHD_Daemon * 452struct MHD_Daemon *
472MHD_start_daemon(unsigned int options, 453MHD_start_daemon (unsigned int options,
473 unsigned short port, 454 unsigned short port,
474 MHD_AcceptPolicyCallback apc, 455 MHD_AcceptPolicyCallback apc,
475 void * apc_cls, 456 void *apc_cls,
476 MHD_AccessHandlerCallback dh, 457 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
477 void * dh_cls, 458{
478 ...) {
479 const int on = 1; 459 const int on = 1;
480 struct MHD_Daemon * retVal; 460 struct MHD_Daemon *retVal;
481 int socket_fd; 461 int socket_fd;
482 struct sockaddr_in servaddr4; 462 struct sockaddr_in servaddr4;
483 struct sockaddr_in6 servaddr6; 463 struct sockaddr_in6 servaddr6;
484 const struct sockaddr * servaddr; 464 const struct sockaddr *servaddr;
485 socklen_t addrlen; 465 socklen_t addrlen;
486 va_list ap; 466 va_list ap;
487 enum MHD_OPTION opt; 467 enum MHD_OPTION opt;
488 468
489 if ((options & MHD_USE_SSL) != 0) 469 if ((options & MHD_USE_SSL) != 0)
490 return NULL; 470 return NULL;
491 if ( (port == 0) || 471 if ((port == 0) || (dh == NULL))
492 (dh == NULL) )
493 return NULL; 472 return NULL;
494 if ((options & MHD_USE_IPv6) != 0) 473 if ((options & MHD_USE_IPv6) != 0)
495 socket_fd = SOCKET(PF_INET6, SOCK_STREAM, 0); 474 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
496 else 475 else
497 socket_fd = SOCKET(PF_INET, SOCK_STREAM, 0); 476 socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
498 if (socket_fd < 0) { 477 if (socket_fd < 0)
499 if ((options & MHD_USE_DEBUG) != 0) 478 {
500 fprintf(stderr, 479 if ((options & MHD_USE_DEBUG) != 0)
501 "Call to socket failed: %s\n", 480 fprintf (stderr, "Call to socket failed: %s\n", STRERROR (errno));
502 STRERROR(errno)); 481 return NULL;
503 return NULL; 482 }
504 } 483 if ((SETSOCKOPT (socket_fd,
505 if ( (SETSOCKOPT(socket_fd, 484 SOL_SOCKET,
506 SOL_SOCKET, 485 SO_REUSEADDR,
507 SO_REUSEADDR, 486 &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0)
508 &on, 487 fprintf (stderr, "setsockopt failed: %s\n", STRERROR (errno));
509 sizeof(on)) < 0) && 488 if ((options & MHD_USE_IPv6) != 0)
510 (options & MHD_USE_DEBUG) != 0) 489 {
511 fprintf(stderr, 490 memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
512 "setsockopt failed: %s\n", 491 servaddr6.sin6_family = AF_INET6;
513 STRERROR(errno)); 492 servaddr6.sin6_port = htons (port);
514 if ((options & MHD_USE_IPv6) != 0) { 493 servaddr = (struct sockaddr *) &servaddr6;
515 memset(&servaddr6, 494 addrlen = sizeof (struct sockaddr_in6);
516 0, 495 }
517 sizeof(struct sockaddr_in6)); 496 else
518 servaddr6.sin6_family = AF_INET6; 497 {
519 servaddr6.sin6_port = htons(port); 498 memset (&servaddr4, 0, sizeof (struct sockaddr_in));
520 servaddr = (struct sockaddr*) &servaddr6; 499 servaddr4.sin_family = AF_INET;
521 addrlen = sizeof(struct sockaddr_in6); 500 servaddr4.sin_port = htons (port);
522 } else { 501 servaddr = (struct sockaddr *) &servaddr4;
523 memset(&servaddr4, 502 addrlen = sizeof (struct sockaddr_in);
524 0, 503 }
525 sizeof(struct sockaddr_in)); 504 if (BIND (socket_fd, servaddr, addrlen) < 0)
526 servaddr4.sin_family = AF_INET; 505 {
527 servaddr4.sin_port = htons(port); 506 if ((options & MHD_USE_DEBUG) != 0)
528 servaddr = (struct sockaddr*) &servaddr4; 507 fprintf (stderr,
529 addrlen = sizeof(struct sockaddr_in); 508 "Failed to bind to port %u: %s\n", port, STRERROR (errno));
530 } 509 CLOSE (socket_fd);
531 if (BIND(socket_fd, 510 return NULL;
532 servaddr, 511 }
533 addrlen) < 0) { 512 if (LISTEN (socket_fd, 20) < 0)
534 if ( (options & MHD_USE_DEBUG) != 0) 513 {
535 fprintf(stderr, 514 if ((options & MHD_USE_DEBUG) != 0)
536 "Failed to bind to port %u: %s\n", 515 fprintf (stderr,
537 port, 516 "Failed to listen for connections: %s\n", STRERROR (errno));
538 STRERROR(errno)); 517 CLOSE (socket_fd);
539 CLOSE(socket_fd); 518 return NULL;
540 return NULL; 519 }
541 } 520 retVal = malloc (sizeof (struct MHD_Daemon));
542 if (LISTEN(socket_fd, 20) < 0) { 521 memset (retVal, 0, sizeof (struct MHD_Daemon));
543 if ((options & MHD_USE_DEBUG) != 0)
544 fprintf(stderr,
545 "Failed to listen for connections: %s\n",
546 STRERROR(errno));
547 CLOSE(socket_fd);
548 return NULL;
549 }
550 retVal = malloc(sizeof(struct MHD_Daemon));
551 memset(retVal,
552 0,
553 sizeof(struct MHD_Daemon));
554 retVal->options = options; 522 retVal->options = options;
555 retVal->port = port; 523 retVal->port = port;
556 retVal->apc = apc; 524 retVal->apc = apc;
@@ -562,35 +530,34 @@ MHD_start_daemon(unsigned int options,
562 retVal->default_handler.next = NULL; 530 retVal->default_handler.next = NULL;
563 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; 531 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
564 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 532 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
565 va_start(ap, dh_cls); 533 va_start (ap, dh_cls);
566 while (MHD_OPTION_END != (opt = va_arg(ap, enum MHD_OPTION))) { 534 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
567 switch (opt) { 535 {
568 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 536 switch (opt)
569 retVal->pool_size = va_arg(ap, unsigned int); 537 {
570 break; 538 case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
571 case MHD_OPTION_CONNECTION_LIMIT: 539 retVal->pool_size = va_arg (ap, unsigned int);
572 retVal->max_connections = va_arg(ap, unsigned int); 540 break;
573 break; 541 case MHD_OPTION_CONNECTION_LIMIT:
574 default: 542 retVal->max_connections = va_arg (ap, unsigned int);
575 fprintf(stderr, 543 break;
576 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); 544 default:
577 abort(); 545 fprintf (stderr,
546 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n");
547 abort ();
548 }
549 }
550 va_end (ap);
551 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
552 (0 != (options & MHD_USE_SELECT_INTERNALLY))) &&
553 (0 != pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal)))
554 {
555 MHD_DLOG (retVal,
556 "Failed to create listen thread: %s\n", STRERROR (errno));
557 free (retVal);
558 CLOSE (socket_fd);
559 return NULL;
578 } 560 }
579 }
580 va_end(ap);
581 if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
582 (0 != (options & MHD_USE_SELECT_INTERNALLY)) ) &&
583 (0 != pthread_create(&retVal->pid,
584 NULL,
585 &MHD_select_thread,
586 retVal)) ) {
587 MHD_DLOG(retVal,
588 "Failed to create listen thread: %s\n",
589 STRERROR(errno));
590 free(retVal);
591 CLOSE(socket_fd);
592 return NULL;
593 }
594 return retVal; 561 return retVal;
595} 562}
596 563
@@ -598,27 +565,31 @@ MHD_start_daemon(unsigned int options,
598 * Shutdown an http daemon. 565 * Shutdown an http daemon.
599 */ 566 */
600void 567void
601MHD_stop_daemon(struct MHD_Daemon * daemon) { 568MHD_stop_daemon (struct MHD_Daemon *daemon)
602 void * unused; 569{
570 void *unused;
603 571
604 if (daemon == NULL) 572 if (daemon == NULL)
605 return; 573 return;
606 daemon->shutdown = 1; 574 daemon->shutdown = 1;
607 CLOSE(daemon->socket_fd); 575 CLOSE (daemon->socket_fd);
608 daemon->socket_fd = -1; 576 daemon->socket_fd = -1;
609 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 577 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
610 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ) { 578 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
611 pthread_kill(daemon->pid, SIGALRM); 579 {
612 pthread_join(daemon->pid, &unused); 580 pthread_kill (daemon->pid, SIGALRM);
613 } 581 pthread_join (daemon->pid, &unused);
614 while (daemon->connections != NULL) { 582 }
615 if (-1 != daemon->connections->socket_fd) { 583 while (daemon->connections != NULL)
616 CLOSE(daemon->connections->socket_fd); 584 {
617 daemon->connections->socket_fd = -1; 585 if (-1 != daemon->connections->socket_fd)
586 {
587 CLOSE (daemon->connections->socket_fd);
588 daemon->connections->socket_fd = -1;
589 }
590 MHD_cleanup_connections (daemon);
618 } 591 }
619 MHD_cleanup_connections(daemon); 592 free (daemon);
620 }
621 free(daemon);
622} 593}
623 594
624#ifndef WINDOWS 595#ifndef WINDOWS
@@ -627,23 +598,27 @@ static struct sigaction sig;
627 598
628static struct sigaction old; 599static struct sigaction old;
629 600
630static void sigalrmHandler(int sig) { 601static void
602sigalrmHandler (int sig)
603{
631} 604}
632 605
633/** 606/**
634 * Initialize the signal handler for SIGALRM. 607 * Initialize the signal handler for SIGALRM.
635 */ 608 */
636void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init() { 609void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init ()
610{
637 /* make sure SIGALRM does not kill us */ 611 /* make sure SIGALRM does not kill us */
638 memset(&sig, 0, sizeof(struct sigaction)); 612 memset (&sig, 0, sizeof (struct sigaction));
639 memset(&old, 0, sizeof(struct sigaction)); 613 memset (&old, 0, sizeof (struct sigaction));
640 sig.sa_flags = SA_NODEFER; 614 sig.sa_flags = SA_NODEFER;
641 sig.sa_handler = &sigalrmHandler; 615 sig.sa_handler = &sigalrmHandler;
642 sigaction(SIGALRM, &sig, &old); 616 sigaction (SIGALRM, &sig, &old);
643} 617}
644 618
645void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini() { 619void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini ()
646 sigaction(SIGALRM, &old, &sig); 620{
621 sigaction (SIGALRM, &old, &sig);
647} 622}
648 623
649#endif 624#endif