diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 816 |
1 files changed, 416 insertions, 400 deletions
diff --git a/src/util/server.c b/src/util/server.c index 63993ee37..f792e5a67 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -33,6 +33,12 @@ | |||
33 | #include "gnunet_disk_lib.h" | 33 | #include "gnunet_disk_lib.h" |
34 | #include "gnunet_protocols.h" | 34 | #include "gnunet_protocols.h" |
35 | 35 | ||
36 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | ||
37 | |||
38 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | ||
39 | |||
40 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | ||
41 | |||
36 | #define DEBUG_SERVER GNUNET_EXTRA_LOGGING | 42 | #define DEBUG_SERVER GNUNET_EXTRA_LOGGING |
37 | 43 | ||
38 | /** | 44 | /** |
@@ -258,7 +264,8 @@ struct GNUNET_SERVER_Client | |||
258 | * @param tc reason why we are running right now | 264 | * @param tc reason why we are running right now |
259 | */ | 265 | */ |
260 | static void | 266 | static void |
261 | process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 267 | process_listen_socket (void *cls, |
268 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
262 | { | 269 | { |
263 | struct GNUNET_SERVER_Handle *server = cls; | 270 | struct GNUNET_SERVER_Handle *server = cls; |
264 | struct GNUNET_CONNECTION_Handle *sock; | 271 | struct GNUNET_CONNECTION_Handle *sock; |
@@ -272,46 +279,47 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
272 | while (NULL != server->listen_sockets[i]) | 279 | while (NULL != server->listen_sockets[i]) |
273 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); | 280 | GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]); |
274 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 281 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
275 | { | 282 | { |
276 | /* ignore shutdown, someone else will take care of it! */ | 283 | /* ignore shutdown, someone else will take care of it! */ |
277 | server->listen_task = | 284 | server->listen_task = |
278 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 285 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
279 | GNUNET_SCHEDULER_NO_TASK, | 286 | GNUNET_SCHEDULER_NO_TASK, |
280 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 287 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
281 | &process_listen_socket, server); | 288 | &process_listen_socket, server); |
282 | GNUNET_NETWORK_fdset_destroy (r); | 289 | GNUNET_NETWORK_fdset_destroy (r); |
283 | return; | 290 | return; |
284 | } | 291 | } |
285 | i = 0; | 292 | i = 0; |
286 | while (NULL != server->listen_sockets[i]) | 293 | while (NULL != server->listen_sockets[i]) |
287 | { | ||
288 | if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i])) | ||
289 | { | 294 | { |
290 | sock = | 295 | if (GNUNET_NETWORK_fdset_isset |
291 | GNUNET_CONNECTION_create_from_accept (server->access, | 296 | (tc->read_ready, server->listen_sockets[i])) |
292 | server->access_cls, | 297 | { |
293 | server->listen_sockets[i]); | 298 | sock = |
294 | if (sock != NULL) | 299 | GNUNET_CONNECTION_create_from_accept (server->access, |
295 | { | 300 | server->access_cls, |
301 | server->listen_sockets[i]); | ||
302 | if (sock != NULL) | ||
303 | { | ||
296 | #if DEBUG_SERVER | 304 | #if DEBUG_SERVER |
297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 305 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
298 | "Server accepted incoming connection.\n"); | 306 | "Server accepted incoming connection.\n"); |
299 | #endif | 307 | #endif |
300 | client = GNUNET_SERVER_connect_socket (server, sock); | 308 | client = GNUNET_SERVER_connect_socket (server, sock); |
301 | GNUNET_CONNECTION_ignore_shutdown (sock, | 309 | GNUNET_CONNECTION_ignore_shutdown (sock, |
302 | server->clients_ignore_shutdown); | 310 | server->clients_ignore_shutdown); |
303 | /* decrement reference count, we don't keep "client" alive */ | 311 | /* decrement reference count, we don't keep "client" alive */ |
304 | GNUNET_SERVER_client_drop (client); | 312 | GNUNET_SERVER_client_drop (client); |
305 | } | 313 | } |
314 | } | ||
315 | i++; | ||
306 | } | 316 | } |
307 | i++; | ||
308 | } | ||
309 | /* listen for more! */ | 317 | /* listen for more! */ |
310 | server->listen_task = | 318 | server->listen_task = |
311 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 319 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
312 | GNUNET_SCHEDULER_NO_TASK, | 320 | GNUNET_SCHEDULER_NO_TASK, |
313 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 321 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
314 | &process_listen_socket, server); | 322 | &process_listen_socket, server); |
315 | GNUNET_NETWORK_fdset_destroy (r); | 323 | GNUNET_NETWORK_fdset_destroy (r); |
316 | } | 324 | } |
317 | 325 | ||
@@ -332,87 +340,87 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) | |||
332 | int eno; | 340 | int eno; |
333 | 341 | ||
334 | switch (serverAddr->sa_family) | 342 | switch (serverAddr->sa_family) |
335 | { | 343 | { |
336 | case AF_INET: | 344 | case AF_INET: |
337 | port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port); | 345 | port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port); |
338 | break; | 346 | break; |
339 | case AF_INET6: | 347 | case AF_INET6: |
340 | port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port); | 348 | port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port); |
341 | break; | 349 | break; |
342 | case AF_UNIX: | 350 | case AF_UNIX: |
343 | port = 0; | 351 | port = 0; |
344 | break; | 352 | break; |
345 | default: | 353 | default: |
346 | GNUNET_break (0); | 354 | GNUNET_break (0); |
347 | port = 0; | 355 | port = 0; |
348 | break; | 356 | break; |
349 | } | 357 | } |
350 | sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0); | 358 | sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0); |
351 | if (NULL == sock) | 359 | if (NULL == sock) |
352 | { | 360 | { |
353 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); | 361 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
354 | errno = 0; | 362 | errno = 0; |
355 | return NULL; | 363 | return NULL; |
356 | } | 364 | } |
357 | if (port != 0) | 365 | if (port != 0) |
358 | { | 366 | { |
359 | if (GNUNET_NETWORK_socket_setsockopt | 367 | if (GNUNET_NETWORK_socket_setsockopt |
360 | (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) | 368 | (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) |
361 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 369 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
362 | "setsockopt"); | 370 | "setsockopt"); |
363 | #ifdef IPV6_V6ONLY | 371 | #ifdef IPV6_V6ONLY |
364 | if ((serverAddr->sa_family == AF_INET6) && | 372 | if ((serverAddr->sa_family == AF_INET6) && |
365 | (GNUNET_NETWORK_socket_setsockopt | 373 | (GNUNET_NETWORK_socket_setsockopt |
366 | (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) | 374 | (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) |
367 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 375 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
368 | "setsockopt"); | 376 | "setsockopt"); |
369 | #endif | 377 | #endif |
370 | } | 378 | } |
371 | /* bind the socket */ | 379 | /* bind the socket */ |
372 | if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) | 380 | if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK) |
373 | { | ||
374 | eno = errno; | ||
375 | if (errno != EADDRINUSE) | ||
376 | { | 381 | { |
377 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may | 382 | eno = errno; |
378 | * fail if we already took the port on IPv6; if both IPv4 and | 383 | if (errno != EADDRINUSE) |
379 | * IPv6 binds fail, then our caller will log using the | 384 | { |
380 | * errno preserved in 'eno' */ | 385 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may |
381 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); | 386 | * fail if we already took the port on IPv6; if both IPv4 and |
382 | if (port != 0) | 387 | * IPv6 binds fail, then our caller will log using the |
383 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 388 | * errno preserved in 'eno' */ |
384 | _("`%s' failed for port %d (%s).\n"), "bind", port, | 389 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); |
385 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | 390 | if (port != 0) |
386 | eno = 0; | 391 | LOG (GNUNET_ERROR_TYPE_ERROR, |
392 | _("`%s' failed for port %d (%s).\n"), "bind", port, | ||
393 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
394 | eno = 0; | ||
395 | } | ||
396 | else | ||
397 | { | ||
398 | if (port != 0) | ||
399 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
400 | _("`%s' failed for port %d (%s): address already in use\n"), | ||
401 | "bind", port, | ||
402 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
403 | else if (serverAddr->sa_family == AF_UNIX) | ||
404 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
405 | _("`%s' failed for `%s': address already in use\n"), "bind", | ||
406 | ((const struct sockaddr_un *) serverAddr)->sun_path); | ||
407 | |||
408 | } | ||
409 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
410 | errno = eno; | ||
411 | return NULL; | ||
387 | } | 412 | } |
388 | else | 413 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) |
389 | { | 414 | { |
390 | if (port != 0) | 415 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); |
391 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 416 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
392 | _("`%s' failed for port %d (%s): address already in use\n"), | 417 | errno = 0; |
393 | "bind", port, | 418 | return NULL; |
394 | (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6"); | ||
395 | else if (serverAddr->sa_family == AF_UNIX) | ||
396 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
397 | _("`%s' failed for `%s': address already in use\n"), "bind", | ||
398 | ((const struct sockaddr_un *) serverAddr)->sun_path); | ||
399 | |||
400 | } | 419 | } |
401 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
402 | errno = eno; | ||
403 | return NULL; | ||
404 | } | ||
405 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | ||
406 | { | ||
407 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); | ||
408 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
409 | errno = 0; | ||
410 | return NULL; | ||
411 | } | ||
412 | #if DEBUG_SERVER | 420 | #if DEBUG_SERVER |
413 | if (port != 0) | 421 | if (port != 0) |
414 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 422 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
415 | "Server starts to listen on port %u.\n", port); | 423 | "Server starts to listen on port %u.\n", port); |
416 | #endif | 424 | #endif |
417 | return sock; | 425 | return sock; |
418 | } | 426 | } |
@@ -432,10 +440,10 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen) | |||
432 | */ | 440 | */ |
433 | struct GNUNET_SERVER_Handle * | 441 | struct GNUNET_SERVER_Handle * |
434 | GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | 442 | GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, |
435 | void *access_cls, | 443 | void *access_cls, |
436 | struct GNUNET_NETWORK_Handle **lsocks, | 444 | struct GNUNET_NETWORK_Handle **lsocks, |
437 | struct GNUNET_TIME_Relative idle_timeout, | 445 | struct GNUNET_TIME_Relative idle_timeout, |
438 | int require_found) | 446 | int require_found) |
439 | { | 447 | { |
440 | struct GNUNET_SERVER_Handle *ret; | 448 | struct GNUNET_SERVER_Handle *ret; |
441 | struct GNUNET_NETWORK_FDSet *r; | 449 | struct GNUNET_NETWORK_FDSet *r; |
@@ -448,18 +456,18 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | |||
448 | ret->access_cls = access_cls; | 456 | ret->access_cls = access_cls; |
449 | ret->require_found = require_found; | 457 | ret->require_found = require_found; |
450 | if (lsocks != NULL) | 458 | if (lsocks != NULL) |
451 | { | 459 | { |
452 | r = GNUNET_NETWORK_fdset_create (); | 460 | r = GNUNET_NETWORK_fdset_create (); |
453 | i = 0; | 461 | i = 0; |
454 | while (NULL != ret->listen_sockets[i]) | 462 | while (NULL != ret->listen_sockets[i]) |
455 | GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); | 463 | GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]); |
456 | ret->listen_task = | 464 | ret->listen_task = |
457 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, | 465 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, |
458 | GNUNET_SCHEDULER_NO_TASK, | 466 | GNUNET_SCHEDULER_NO_TASK, |
459 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | 467 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
460 | &process_listen_socket, ret); | 468 | &process_listen_socket, ret); |
461 | GNUNET_NETWORK_fdset_destroy (r); | 469 | GNUNET_NETWORK_fdset_destroy (r); |
462 | } | 470 | } |
463 | return ret; | 471 | return ret; |
464 | } | 472 | } |
465 | 473 | ||
@@ -479,10 +487,10 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, | |||
479 | */ | 487 | */ |
480 | struct GNUNET_SERVER_Handle * | 488 | struct GNUNET_SERVER_Handle * |
481 | GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, | 489 | GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, |
482 | struct sockaddr *const *serverAddr, | 490 | struct sockaddr *const *serverAddr, |
483 | const socklen_t * socklen, | 491 | const socklen_t * socklen, |
484 | struct GNUNET_TIME_Relative idle_timeout, | 492 | struct GNUNET_TIME_Relative idle_timeout, |
485 | int require_found) | 493 | int require_found) |
486 | { | 494 | { |
487 | struct GNUNET_NETWORK_Handle **lsocks; | 495 | struct GNUNET_NETWORK_Handle **lsocks; |
488 | unsigned int i; | 496 | unsigned int i; |
@@ -492,31 +500,32 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls, | |||
492 | while (serverAddr[i] != NULL) | 500 | while (serverAddr[i] != NULL) |
493 | i++; | 501 | i++; |
494 | if (i > 0) | 502 | if (i > 0) |
495 | { | ||
496 | lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); | ||
497 | i = 0; | ||
498 | j = 0; | ||
499 | while (serverAddr[i] != NULL) | ||
500 | { | 503 | { |
501 | lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]); | 504 | lsocks = |
502 | if (lsocks[j] != NULL) | 505 | GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1)); |
503 | j++; | 506 | i = 0; |
504 | i++; | 507 | j = 0; |
508 | while (serverAddr[i] != NULL) | ||
509 | { | ||
510 | lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]); | ||
511 | if (lsocks[j] != NULL) | ||
512 | j++; | ||
513 | i++; | ||
514 | } | ||
515 | if (j == 0) | ||
516 | { | ||
517 | if (errno != 0) | ||
518 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
519 | GNUNET_free (lsocks); | ||
520 | lsocks = NULL; | ||
521 | } | ||
505 | } | 522 | } |
506 | if (j == 0) | 523 | else |
507 | { | 524 | { |
508 | if (errno != 0) | ||
509 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
510 | GNUNET_free (lsocks); | ||
511 | lsocks = NULL; | 525 | lsocks = NULL; |
512 | } | 526 | } |
513 | } | ||
514 | else | ||
515 | { | ||
516 | lsocks = NULL; | ||
517 | } | ||
518 | return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks, | 527 | return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks, |
519 | idle_timeout, require_found); | 528 | idle_timeout, require_found); |
520 | } | 529 | } |
521 | 530 | ||
522 | 531 | ||
@@ -533,35 +542,35 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | |||
533 | unsigned int i; | 542 | unsigned int i; |
534 | 543 | ||
535 | #if DEBUG_SERVER | 544 | #if DEBUG_SERVER |
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); | 545 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); |
537 | #endif | 546 | #endif |
538 | if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) | 547 | if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) |
539 | { | 548 | { |
540 | GNUNET_SCHEDULER_cancel (s->listen_task); | 549 | GNUNET_SCHEDULER_cancel (s->listen_task); |
541 | s->listen_task = GNUNET_SCHEDULER_NO_TASK; | 550 | s->listen_task = GNUNET_SCHEDULER_NO_TASK; |
542 | } | 551 | } |
543 | if (s->listen_sockets != NULL) | 552 | if (s->listen_sockets != NULL) |
544 | { | 553 | { |
545 | i = 0; | 554 | i = 0; |
546 | while (s->listen_sockets[i] != NULL) | 555 | while (s->listen_sockets[i] != NULL) |
547 | GNUNET_break (GNUNET_OK == | 556 | GNUNET_break (GNUNET_OK == |
548 | GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); | 557 | GNUNET_NETWORK_socket_close (s->listen_sockets[i++])); |
549 | GNUNET_free (s->listen_sockets); | 558 | GNUNET_free (s->listen_sockets); |
550 | s->listen_sockets = NULL; | 559 | s->listen_sockets = NULL; |
551 | } | 560 | } |
552 | while (s->clients != NULL) | 561 | while (s->clients != NULL) |
553 | GNUNET_SERVER_client_disconnect (s->clients); | 562 | GNUNET_SERVER_client_disconnect (s->clients); |
554 | while (NULL != (hpos = s->handlers)) | 563 | while (NULL != (hpos = s->handlers)) |
555 | { | 564 | { |
556 | s->handlers = hpos->next; | 565 | s->handlers = hpos->next; |
557 | GNUNET_free (hpos); | 566 | GNUNET_free (hpos); |
558 | } | 567 | } |
559 | while (NULL != (npos = s->disconnect_notify_list)) | 568 | while (NULL != (npos = s->disconnect_notify_list)) |
560 | { | 569 | { |
561 | npos->callback (npos->callback_cls, NULL); | 570 | npos->callback (npos->callback_cls, NULL); |
562 | s->disconnect_notify_list = npos->next; | 571 | s->disconnect_notify_list = npos->next; |
563 | GNUNET_free (npos); | 572 | GNUNET_free (npos); |
564 | } | 573 | } |
565 | GNUNET_free (s); | 574 | GNUNET_free (s); |
566 | } | 575 | } |
567 | 576 | ||
@@ -581,7 +590,8 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | |||
581 | */ | 590 | */ |
582 | void | 591 | void |
583 | GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | 592 | GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, |
584 | const struct GNUNET_SERVER_MessageHandler *handlers) | 593 | const struct GNUNET_SERVER_MessageHandler |
594 | *handlers) | ||
585 | { | 595 | { |
586 | struct HandlerList *p; | 596 | struct HandlerList *p; |
587 | 597 | ||
@@ -599,21 +609,21 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | |||
599 | * @param tc scheduler context (unused) | 609 | * @param tc scheduler context (unused) |
600 | */ | 610 | */ |
601 | static void | 611 | static void |
602 | warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 612 | warn_no_receive_done (void *cls, |
613 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
603 | { | 614 | { |
604 | struct GNUNET_SERVER_Client *client = cls; | 615 | struct GNUNET_SERVER_Client *client = cls; |
605 | 616 | ||
606 | client->warn_task = | 617 | client->warn_task = |
607 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | 618 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
608 | &warn_no_receive_done, client); | 619 | &warn_no_receive_done, client); |
609 | if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 620 | if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) |
610 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 621 | LOG (GNUNET_ERROR_TYPE_WARNING, |
611 | _ | 622 | _ |
612 | ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"), | 623 | ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"), |
613 | (unsigned int) client->warn_type, | 624 | (unsigned int) client->warn_type, |
614 | (unsigned long long) | 625 | (unsigned long long) |
615 | GNUNET_TIME_absolute_get_duration | 626 | GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value); |
616 | (client->warn_start).rel_value); | ||
617 | } | 627 | } |
618 | 628 | ||
619 | 629 | ||
@@ -625,13 +635,14 @@ warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
625 | * @param client client for which to disable the warning | 635 | * @param client client for which to disable the warning |
626 | */ | 636 | */ |
627 | void | 637 | void |
628 | GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client) | 638 | GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client |
639 | *client) | ||
629 | { | 640 | { |
630 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) | 641 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) |
631 | { | 642 | { |
632 | GNUNET_SCHEDULER_cancel (client->warn_task); | 643 | GNUNET_SCHEDULER_cancel (client->warn_task); |
633 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 644 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
634 | } | 645 | } |
635 | } | 646 | } |
636 | 647 | ||
637 | 648 | ||
@@ -652,8 +663,8 @@ GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client) | |||
652 | */ | 663 | */ |
653 | int | 664 | int |
654 | GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | 665 | GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, |
655 | struct GNUNET_SERVER_Client *sender, | 666 | struct GNUNET_SERVER_Client *sender, |
656 | const struct GNUNET_MessageHeader *message) | 667 | const struct GNUNET_MessageHeader *message) |
657 | { | 668 | { |
658 | struct HandlerList *pos; | 669 | struct HandlerList *pos; |
659 | const struct GNUNET_SERVER_MessageHandler *mh; | 670 | const struct GNUNET_SERVER_MessageHandler *mh; |
@@ -666,56 +677,57 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | |||
666 | size = ntohs (message->size); | 677 | size = ntohs (message->size); |
667 | #if DEBUG_SERVER | 678 | #if DEBUG_SERVER |
668 | 679 | ||
669 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 680 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
670 | "Server schedules transmission of %u-byte message of type %u to client.\n", | 681 | "Server schedules transmission of %u-byte message of type %u to client.\n", |
671 | size, type); | 682 | size, type); |
672 | #endif | 683 | #endif |
673 | pos = server->handlers; | 684 | pos = server->handlers; |
674 | found = GNUNET_NO; | 685 | found = GNUNET_NO; |
675 | while (pos != NULL) | 686 | while (pos != NULL) |
676 | { | ||
677 | i = 0; | ||
678 | while (pos->handlers[i].callback != NULL) | ||
679 | { | 687 | { |
680 | mh = &pos->handlers[i]; | 688 | i = 0; |
681 | if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL)) | 689 | while (pos->handlers[i].callback != NULL) |
682 | { | 690 | { |
683 | if ((mh->expected_size != 0) && (mh->expected_size != size)) | 691 | mh = &pos->handlers[i]; |
684 | { | 692 | if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL)) |
693 | { | ||
694 | if ((mh->expected_size != 0) && (mh->expected_size != size)) | ||
695 | { | ||
685 | #if GNUNET8_NETWORK_IS_DEAD | 696 | #if GNUNET8_NETWORK_IS_DEAD |
686 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 697 | LOG (GNUNET_ERROR_TYPE_WARNING, |
687 | "Expected %u bytes for message of type %u, got %u\n", | 698 | "Expected %u bytes for message of type %u, got %u\n", |
688 | mh->expected_size, mh->type, size); | 699 | mh->expected_size, mh->type, size); |
689 | GNUNET_break_op (0); | 700 | GNUNET_break_op (0); |
690 | #endif | 701 | #endif |
691 | return GNUNET_SYSERR; | 702 | return GNUNET_SYSERR; |
692 | } | 703 | } |
693 | if (sender != NULL) | 704 | if (sender != NULL) |
694 | { | 705 | { |
695 | if (0 == sender->suspended) | 706 | if (0 == sender->suspended) |
696 | { | 707 | { |
697 | sender->warn_start = GNUNET_TIME_absolute_get (); | 708 | sender->warn_start = GNUNET_TIME_absolute_get (); |
698 | sender->warn_task = | 709 | sender->warn_task = |
699 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | 710 | GNUNET_SCHEDULER_add_delayed |
700 | &warn_no_receive_done, sender); | 711 | (GNUNET_TIME_UNIT_MINUTES, &warn_no_receive_done, |
701 | sender->warn_type = type; | 712 | sender); |
702 | } | 713 | sender->warn_type = type; |
703 | sender->suspended++; | 714 | } |
704 | } | 715 | sender->suspended++; |
705 | mh->callback (mh->callback_cls, sender, message); | 716 | } |
706 | found = GNUNET_YES; | 717 | mh->callback (mh->callback_cls, sender, message); |
707 | } | 718 | found = GNUNET_YES; |
708 | i++; | 719 | } |
720 | i++; | ||
721 | } | ||
722 | pos = pos->next; | ||
709 | } | 723 | } |
710 | pos = pos->next; | ||
711 | } | ||
712 | if (found == GNUNET_NO) | 724 | if (found == GNUNET_NO) |
713 | { | 725 | { |
714 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 726 | LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
715 | "Received message of unknown type %d\n", type); | 727 | "Received message of unknown type %d\n", type); |
716 | if (server->require_found == GNUNET_YES) | 728 | if (server->require_found == GNUNET_YES) |
717 | return GNUNET_SYSERR; | 729 | return GNUNET_SYSERR; |
718 | } | 730 | } |
719 | return GNUNET_OK; | 731 | return GNUNET_OK; |
720 | } | 732 | } |
721 | 733 | ||
@@ -732,7 +744,8 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | |||
732 | */ | 744 | */ |
733 | static void | 745 | static void |
734 | process_incoming (void *cls, const void *buf, size_t available, | 746 | process_incoming (void *cls, const void *buf, size_t available, |
735 | const struct sockaddr *addr, socklen_t addrlen, int errCode); | 747 | const struct sockaddr *addr, socklen_t addrlen, |
748 | int errCode); | ||
736 | 749 | ||
737 | 750 | ||
738 | /** | 751 | /** |
@@ -752,44 +765,44 @@ static void | |||
752 | process_mst (struct GNUNET_SERVER_Client *client, int ret) | 765 | process_mst (struct GNUNET_SERVER_Client *client, int ret) |
753 | { | 766 | { |
754 | while ((ret != GNUNET_SYSERR) && (client->server != NULL) && | 767 | while ((ret != GNUNET_SYSERR) && (client->server != NULL) && |
755 | (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) | 768 | (GNUNET_YES != client->shutdown_now) && (0 == client->suspended)) |
756 | { | ||
757 | if (ret == GNUNET_OK) | ||
758 | { | 769 | { |
759 | client->receive_pending = GNUNET_YES; | 770 | if (ret == GNUNET_OK) |
771 | { | ||
772 | client->receive_pending = GNUNET_YES; | ||
760 | #if DEBUG_SERVER | 773 | #if DEBUG_SERVER |
761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 774 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
762 | "Server re-enters receive loop, timeout: %llu.\n", | 775 | "Server re-enters receive loop, timeout: %llu.\n", |
763 | client->idle_timeout.rel_value); | 776 | client->idle_timeout.rel_value); |
764 | #endif | 777 | #endif |
765 | GNUNET_CONNECTION_receive (client->connection, | 778 | GNUNET_CONNECTION_receive (client->connection, |
766 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 779 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
767 | client->idle_timeout, &process_incoming, | 780 | client->idle_timeout, &process_incoming, |
768 | client); | 781 | client); |
769 | break; | 782 | break; |
770 | } | 783 | } |
771 | #if DEBUG_SERVER | 784 | #if DEBUG_SERVER |
772 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 785 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
773 | "Server processes additional messages instantly.\n"); | 786 | "Server processes additional messages instantly.\n"); |
774 | #endif | 787 | #endif |
775 | ret = | 788 | ret = |
776 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, | 789 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, |
777 | GNUNET_YES); | 790 | GNUNET_YES); |
778 | } | 791 | } |
779 | #if DEBUG_SERVER | 792 | #if DEBUG_SERVER |
780 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 793 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
781 | "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", | 794 | "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n", |
782 | ret, client->server, client->shutdown_now, client->suspended); | 795 | ret, client->server, client->shutdown_now, client->suspended); |
783 | #endif | 796 | #endif |
784 | 797 | ||
785 | if (ret == GNUNET_NO) | 798 | if (ret == GNUNET_NO) |
786 | { | 799 | { |
787 | #if DEBUG_SERVER | 800 | #if DEBUG_SERVER |
788 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 801 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
789 | "Server has more data pending but is suspended.\n"); | 802 | "Server has more data pending but is suspended.\n"); |
790 | #endif | 803 | #endif |
791 | client->receive_pending = GNUNET_SYSERR; /* data pending */ | 804 | client->receive_pending = GNUNET_SYSERR; /* data pending */ |
792 | } | 805 | } |
793 | if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now)) | 806 | if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now)) |
794 | GNUNET_SERVER_client_disconnect (client); | 807 | GNUNET_SERVER_client_disconnect (client); |
795 | GNUNET_SERVER_client_drop (client); | 808 | GNUNET_SERVER_client_drop (client); |
@@ -808,7 +821,7 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret) | |||
808 | */ | 821 | */ |
809 | static void | 822 | static void |
810 | process_incoming (void *cls, const void *buf, size_t available, | 823 | process_incoming (void *cls, const void *buf, size_t available, |
811 | const struct sockaddr *addr, socklen_t addrlen, int errCode) | 824 | const struct sockaddr *addr, socklen_t addrlen, int errCode) |
812 | { | 825 | { |
813 | struct GNUNET_SERVER_Client *client = cls; | 826 | struct GNUNET_SERVER_Client *client = cls; |
814 | struct GNUNET_SERVER_Handle *server = client->server; | 827 | struct GNUNET_SERVER_Handle *server = client->server; |
@@ -819,43 +832,44 @@ process_incoming (void *cls, const void *buf, size_t available, | |||
819 | GNUNET_assert (client->receive_pending == GNUNET_YES); | 832 | GNUNET_assert (client->receive_pending == GNUNET_YES); |
820 | client->receive_pending = GNUNET_NO; | 833 | client->receive_pending = GNUNET_NO; |
821 | now = GNUNET_TIME_absolute_get (); | 834 | now = GNUNET_TIME_absolute_get (); |
822 | end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); | 835 | end = |
836 | GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout); | ||
823 | 837 | ||
824 | if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && | 838 | if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) && |
825 | (client->shutdown_now != GNUNET_YES) && (server != NULL) && | 839 | (client->shutdown_now != GNUNET_YES) && (server != NULL) && |
826 | (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && | 840 | (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) && |
827 | (end.abs_value > now.abs_value)) | 841 | (end.abs_value > now.abs_value)) |
828 | { | 842 | { |
829 | /* wait longer, timeout changed (i.e. due to us sending) */ | 843 | /* wait longer, timeout changed (i.e. due to us sending) */ |
830 | #if DEBUG_SERVER | 844 | #if DEBUG_SERVER |
831 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 845 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
832 | "Receive time out, but no disconnect due to sending (%p)\n", | 846 | "Receive time out, but no disconnect due to sending (%p)\n", |
833 | GNUNET_a2s (addr, addrlen)); | 847 | GNUNET_a2s (addr, addrlen)); |
834 | #endif | 848 | #endif |
835 | client->receive_pending = GNUNET_YES; | 849 | client->receive_pending = GNUNET_YES; |
836 | GNUNET_CONNECTION_receive (client->connection, | 850 | GNUNET_CONNECTION_receive (client->connection, |
837 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 851 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
838 | GNUNET_TIME_absolute_get_remaining (end), | 852 | GNUNET_TIME_absolute_get_remaining (end), |
839 | &process_incoming, client); | 853 | &process_incoming, client); |
840 | return; | 854 | return; |
841 | } | 855 | } |
842 | if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) || | 856 | if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) |
843 | (client->shutdown_now == GNUNET_YES) || | 857 | || (client->shutdown_now == GNUNET_YES) |
844 | (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) | 858 | || (GNUNET_YES != GNUNET_CONNECTION_check (client->connection))) |
845 | { | 859 | { |
846 | /* other side closed connection, error connecting, etc. */ | 860 | /* other side closed connection, error connecting, etc. */ |
847 | GNUNET_SERVER_client_disconnect (client); | 861 | GNUNET_SERVER_client_disconnect (client); |
848 | return; | 862 | return; |
849 | } | 863 | } |
850 | #if DEBUG_SERVER | 864 | #if DEBUG_SERVER |
851 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", | 865 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n", |
852 | (unsigned int) available, GNUNET_a2s (addr, addrlen)); | 866 | (unsigned int) available, GNUNET_a2s (addr, addrlen)); |
853 | #endif | 867 | #endif |
854 | GNUNET_SERVER_client_keep (client); | 868 | GNUNET_SERVER_client_keep (client); |
855 | client->last_activity = now; | 869 | client->last_activity = now; |
856 | ret = | 870 | ret = |
857 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, | 871 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, |
858 | GNUNET_YES); | 872 | GNUNET_YES); |
859 | process_mst (client, ret); | 873 | process_mst (client, ret); |
860 | } | 874 | } |
861 | 875 | ||
@@ -876,25 +890,26 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
876 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | 890 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; |
877 | if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && | 891 | if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && |
878 | (GNUNET_NO == server->clients_ignore_shutdown)) | 892 | (GNUNET_NO == server->clients_ignore_shutdown)) |
879 | { | 893 | { |
880 | GNUNET_SERVER_client_disconnect (client); | 894 | GNUNET_SERVER_client_disconnect (client); |
881 | return; | 895 | return; |
882 | } | 896 | } |
883 | if (client->receive_pending == GNUNET_NO) | 897 | if (client->receive_pending == GNUNET_NO) |
884 | { | 898 | { |
885 | #if DEBUG_SERVER | 899 | #if DEBUG_SERVER |
886 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 900 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
887 | "Server begins to read again from client.\n"); | 901 | "Server begins to read again from client.\n"); |
888 | #endif | 902 | #endif |
889 | client->receive_pending = GNUNET_YES; | 903 | client->receive_pending = GNUNET_YES; |
890 | GNUNET_CONNECTION_receive (client->connection, | 904 | GNUNET_CONNECTION_receive (client->connection, |
891 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 905 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
892 | client->idle_timeout, &process_incoming, client); | 906 | client->idle_timeout, &process_incoming, |
893 | return; | 907 | client); |
894 | } | 908 | return; |
909 | } | ||
895 | #if DEBUG_SERVER | 910 | #if DEBUG_SERVER |
896 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 911 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
897 | "Server continues processing messages still in the buffer.\n"); | 912 | "Server continues processing messages still in the buffer.\n"); |
898 | #endif | 913 | #endif |
899 | GNUNET_SERVER_client_keep (client); | 914 | GNUNET_SERVER_client_keep (client); |
900 | client->receive_pending = GNUNET_NO; | 915 | client->receive_pending = GNUNET_NO; |
@@ -912,7 +927,7 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
912 | */ | 927 | */ |
913 | static void | 928 | static void |
914 | client_message_tokenizer_callback (void *cls, void *client, | 929 | client_message_tokenizer_callback (void *cls, void *client, |
915 | const struct GNUNET_MessageHeader *message) | 930 | const struct GNUNET_MessageHeader *message) |
916 | { | 931 | { |
917 | struct GNUNET_SERVER_Handle *server = cls; | 932 | struct GNUNET_SERVER_Handle *server = cls; |
918 | struct GNUNET_SERVER_Client *sender = client; | 933 | struct GNUNET_SERVER_Client *sender = client; |
@@ -920,9 +935,9 @@ client_message_tokenizer_callback (void *cls, void *client, | |||
920 | 935 | ||
921 | #if DEBUG_SERVER | 936 | #if DEBUG_SERVER |
922 | 937 | ||
923 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 938 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
924 | "Tokenizer gives server message of type %u from client\n", | 939 | "Tokenizer gives server message of type %u from client\n", |
925 | ntohs (message->type)); | 940 | ntohs (message->type)); |
926 | #endif | 941 | #endif |
927 | sender->in_process_client_buffer = GNUNET_YES; | 942 | sender->in_process_client_buffer = GNUNET_YES; |
928 | ret = GNUNET_SERVER_inject (server, sender, message); | 943 | ret = GNUNET_SERVER_inject (server, sender, message); |
@@ -946,14 +961,14 @@ client_message_tokenizer_callback (void *cls, void *client, | |||
946 | */ | 961 | */ |
947 | struct GNUNET_SERVER_Client * | 962 | struct GNUNET_SERVER_Client * |
948 | GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | 963 | GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, |
949 | struct GNUNET_CONNECTION_Handle *connection) | 964 | struct GNUNET_CONNECTION_Handle *connection) |
950 | { | 965 | { |
951 | struct GNUNET_SERVER_Client *client; | 966 | struct GNUNET_SERVER_Client *client; |
952 | 967 | ||
953 | client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); | 968 | client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); |
954 | client->connection = connection; | 969 | client->connection = connection; |
955 | client->mst = | 970 | client->mst = |
956 | GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); | 971 | GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); |
957 | client->reference_count = 1; | 972 | client->reference_count = 1; |
958 | client->server = server; | 973 | client->server = server; |
959 | client->last_activity = GNUNET_TIME_absolute_get (); | 974 | client->last_activity = GNUNET_TIME_absolute_get (); |
@@ -964,8 +979,8 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | |||
964 | client->callback = NULL; | 979 | client->callback = NULL; |
965 | client->callback_cls = NULL; | 980 | client->callback_cls = NULL; |
966 | GNUNET_CONNECTION_receive (client->connection, | 981 | GNUNET_CONNECTION_receive (client->connection, |
967 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 982 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
968 | client->idle_timeout, &process_incoming, client); | 983 | client->idle_timeout, &process_incoming, client); |
969 | return client; | 984 | return client; |
970 | } | 985 | } |
971 | 986 | ||
@@ -980,7 +995,7 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | |||
980 | */ | 995 | */ |
981 | void | 996 | void |
982 | GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, | 997 | GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, |
983 | struct GNUNET_TIME_Relative timeout) | 998 | struct GNUNET_TIME_Relative timeout) |
984 | { | 999 | { |
985 | client->idle_timeout = timeout; | 1000 | client->idle_timeout = timeout; |
986 | } | 1001 | } |
@@ -1028,7 +1043,7 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client) | |||
1028 | */ | 1043 | */ |
1029 | int | 1044 | int |
1030 | GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | 1045 | GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, |
1031 | void **addr, size_t * addrlen) | 1046 | void **addr, size_t * addrlen) |
1032 | { | 1047 | { |
1033 | return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen); | 1048 | return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen); |
1034 | } | 1049 | } |
@@ -1046,8 +1061,8 @@ GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client, | |||
1046 | */ | 1061 | */ |
1047 | void | 1062 | void |
1048 | GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | 1063 | GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, |
1049 | GNUNET_SERVER_DisconnectCallback callback, | 1064 | GNUNET_SERVER_DisconnectCallback callback, |
1050 | void *callback_cls) | 1065 | void *callback_cls) |
1051 | { | 1066 | { |
1052 | struct NotifyList *n; | 1067 | struct NotifyList *n; |
1053 | 1068 | ||
@@ -1068,8 +1083,8 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server, | |||
1068 | */ | 1083 | */ |
1069 | void | 1084 | void |
1070 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | 1085 | GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, |
1071 | GNUNET_SERVER_DisconnectCallback | 1086 | GNUNET_SERVER_DisconnectCallback |
1072 | callback, void *callback_cls) | 1087 | callback, void *callback_cls) |
1073 | { | 1088 | { |
1074 | struct NotifyList *pos; | 1089 | struct NotifyList *pos; |
1075 | struct NotifyList *prev; | 1090 | struct NotifyList *prev; |
@@ -1077,17 +1092,17 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server, | |||
1077 | prev = NULL; | 1092 | prev = NULL; |
1078 | pos = server->disconnect_notify_list; | 1093 | pos = server->disconnect_notify_list; |
1079 | while (pos != NULL) | 1094 | while (pos != NULL) |
1080 | { | 1095 | { |
1081 | if ((pos->callback == callback) && (pos->callback_cls == callback_cls)) | 1096 | if ((pos->callback == callback) && (pos->callback_cls == callback_cls)) |
1082 | break; | 1097 | break; |
1083 | prev = pos; | 1098 | prev = pos; |
1084 | pos = pos->next; | 1099 | pos = pos->next; |
1085 | } | 1100 | } |
1086 | if (pos == NULL) | 1101 | if (pos == NULL) |
1087 | { | 1102 | { |
1088 | GNUNET_break (0); | 1103 | GNUNET_break (0); |
1089 | return; | 1104 | return; |
1090 | } | 1105 | } |
1091 | if (prev == NULL) | 1106 | if (prev == NULL) |
1092 | server->disconnect_notify_list = pos->next; | 1107 | server->disconnect_notify_list = pos->next; |
1093 | else | 1108 | else |
@@ -1114,76 +1129,76 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1114 | unsigned int rc; | 1129 | unsigned int rc; |
1115 | 1130 | ||
1116 | #if DEBUG_SERVER | 1131 | #if DEBUG_SERVER |
1117 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1132 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1118 | "Client is being disconnected from the server.\n"); | 1133 | "Client is being disconnected from the server.\n"); |
1119 | #endif | 1134 | #endif |
1120 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | 1135 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) |
1121 | { | ||
1122 | GNUNET_SCHEDULER_cancel (client->restart_task); | ||
1123 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | ||
1124 | } | ||
1125 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | ||
1126 | { | ||
1127 | GNUNET_SCHEDULER_cancel (client->warn_task); | ||
1128 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | ||
1129 | } | ||
1130 | if (GNUNET_YES == client->receive_pending) | ||
1131 | { | ||
1132 | GNUNET_CONNECTION_receive_cancel (client->connection); | ||
1133 | client->receive_pending = GNUNET_NO; | ||
1134 | } | ||
1135 | |||
1136 | rc = client->reference_count; | ||
1137 | if (client->server != NULL) | ||
1138 | { | ||
1139 | server = client->server; | ||
1140 | client->server = NULL; | ||
1141 | client->shutdown_now = GNUNET_YES; | ||
1142 | prev = NULL; | ||
1143 | pos = server->clients; | ||
1144 | while ((pos != NULL) && (pos != client)) | ||
1145 | { | ||
1146 | prev = pos; | ||
1147 | pos = pos->next; | ||
1148 | } | ||
1149 | GNUNET_assert (pos != NULL); | ||
1150 | if (prev == NULL) | ||
1151 | server->clients = pos->next; | ||
1152 | else | ||
1153 | prev->next = pos->next; | ||
1154 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | ||
1155 | { | 1136 | { |
1156 | GNUNET_SCHEDULER_cancel (client->restart_task); | 1137 | GNUNET_SCHEDULER_cancel (client->restart_task); |
1157 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | 1138 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; |
1158 | } | 1139 | } |
1159 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | 1140 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) |
1160 | { | 1141 | { |
1161 | GNUNET_SCHEDULER_cancel (client->warn_task); | 1142 | GNUNET_SCHEDULER_cancel (client->warn_task); |
1162 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 1143 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
1163 | } | 1144 | } |
1164 | n = server->disconnect_notify_list; | 1145 | if (GNUNET_YES == client->receive_pending) |
1165 | while (n != NULL) | ||
1166 | { | 1146 | { |
1167 | n->callback (n->callback_cls, client); | 1147 | GNUNET_CONNECTION_receive_cancel (client->connection); |
1168 | n = n->next; | 1148 | client->receive_pending = GNUNET_NO; |
1149 | } | ||
1150 | |||
1151 | rc = client->reference_count; | ||
1152 | if (client->server != NULL) | ||
1153 | { | ||
1154 | server = client->server; | ||
1155 | client->server = NULL; | ||
1156 | client->shutdown_now = GNUNET_YES; | ||
1157 | prev = NULL; | ||
1158 | pos = server->clients; | ||
1159 | while ((pos != NULL) && (pos != client)) | ||
1160 | { | ||
1161 | prev = pos; | ||
1162 | pos = pos->next; | ||
1163 | } | ||
1164 | GNUNET_assert (pos != NULL); | ||
1165 | if (prev == NULL) | ||
1166 | server->clients = pos->next; | ||
1167 | else | ||
1168 | prev->next = pos->next; | ||
1169 | if (client->restart_task != GNUNET_SCHEDULER_NO_TASK) | ||
1170 | { | ||
1171 | GNUNET_SCHEDULER_cancel (client->restart_task); | ||
1172 | client->restart_task = GNUNET_SCHEDULER_NO_TASK; | ||
1173 | } | ||
1174 | if (client->warn_task != GNUNET_SCHEDULER_NO_TASK) | ||
1175 | { | ||
1176 | GNUNET_SCHEDULER_cancel (client->warn_task); | ||
1177 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | ||
1178 | } | ||
1179 | n = server->disconnect_notify_list; | ||
1180 | while (n != NULL) | ||
1181 | { | ||
1182 | n->callback (n->callback_cls, client); | ||
1183 | n = n->next; | ||
1184 | } | ||
1169 | } | 1185 | } |
1170 | } | ||
1171 | if (rc > 0) | 1186 | if (rc > 0) |
1172 | { | 1187 | { |
1173 | #if DEBUG_SERVER | 1188 | #if DEBUG_SERVER |
1174 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1189 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1175 | "RC still positive, not destroying everything.\n"); | 1190 | "RC still positive, not destroying everything.\n"); |
1176 | #endif | 1191 | #endif |
1177 | return; | 1192 | return; |
1178 | } | 1193 | } |
1179 | if (client->in_process_client_buffer == GNUNET_YES) | 1194 | if (client->in_process_client_buffer == GNUNET_YES) |
1180 | { | 1195 | { |
1181 | #if DEBUG_SERVER | 1196 | #if DEBUG_SERVER |
1182 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1197 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1183 | "Still processing inputs, not destroying everything.\n"); | 1198 | "Still processing inputs, not destroying everything.\n"); |
1184 | #endif | 1199 | #endif |
1185 | return; | 1200 | return; |
1186 | } | 1201 | } |
1187 | 1202 | ||
1188 | if (client->persist == GNUNET_YES) | 1203 | if (client->persist == GNUNET_YES) |
1189 | GNUNET_CONNECTION_persist_ (client->connection); | 1204 | GNUNET_CONNECTION_persist_ (client->connection); |
@@ -1247,17 +1262,17 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf) | |||
1247 | */ | 1262 | */ |
1248 | struct GNUNET_CONNECTION_TransmitHandle * | 1263 | struct GNUNET_CONNECTION_TransmitHandle * |
1249 | GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, | 1264 | GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client, |
1250 | size_t size, | 1265 | size_t size, |
1251 | struct GNUNET_TIME_Relative timeout, | 1266 | struct GNUNET_TIME_Relative timeout, |
1252 | GNUNET_CONNECTION_TransmitReadyNotify | 1267 | GNUNET_CONNECTION_TransmitReadyNotify |
1253 | callback, void *callback_cls) | 1268 | callback, void *callback_cls) |
1254 | { | 1269 | { |
1255 | client->callback_cls = callback_cls; | 1270 | client->callback_cls = callback_cls; |
1256 | client->callback = callback; | 1271 | client->callback = callback; |
1257 | return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, | 1272 | return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, |
1258 | timeout, | 1273 | timeout, |
1259 | &transmit_ready_callback_wrapper, | 1274 | &transmit_ready_callback_wrapper, |
1260 | client); | 1275 | client); |
1261 | } | 1276 | } |
1262 | 1277 | ||
1263 | 1278 | ||
@@ -1294,46 +1309,47 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success) | |||
1294 | GNUNET_assert (client->suspended > 0); | 1309 | GNUNET_assert (client->suspended > 0); |
1295 | client->suspended--; | 1310 | client->suspended--; |
1296 | if (success != GNUNET_OK) | 1311 | if (success != GNUNET_OK) |
1297 | { | 1312 | { |
1298 | #if DEBUG_SERVER | 1313 | #if DEBUG_SERVER |
1299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1314 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1300 | "GNUNET_SERVER_receive_done called with failure indication\n"); | 1315 | "GNUNET_SERVER_receive_done called with failure indication\n"); |
1301 | #endif | 1316 | #endif |
1302 | GNUNET_SERVER_client_disconnect (client); | 1317 | GNUNET_SERVER_client_disconnect (client); |
1303 | return; | 1318 | return; |
1304 | } | 1319 | } |
1305 | if (client->suspended > 0) | 1320 | if (client->suspended > 0) |
1306 | { | 1321 | { |
1307 | #if DEBUG_SERVER | 1322 | #if DEBUG_SERVER |
1308 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1323 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1309 | "GNUNET_SERVER_receive_done called, but more clients pending\n"); | 1324 | "GNUNET_SERVER_receive_done called, but more clients pending\n"); |
1310 | #endif | 1325 | #endif |
1311 | return; | 1326 | return; |
1312 | } | 1327 | } |
1313 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) | 1328 | if (GNUNET_SCHEDULER_NO_TASK != client->warn_task) |
1314 | { | 1329 | { |
1315 | GNUNET_SCHEDULER_cancel (client->warn_task); | 1330 | GNUNET_SCHEDULER_cancel (client->warn_task); |
1316 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; | 1331 | client->warn_task = GNUNET_SCHEDULER_NO_TASK; |
1317 | } | 1332 | } |
1318 | if (client->in_process_client_buffer == GNUNET_YES) | 1333 | if (client->in_process_client_buffer == GNUNET_YES) |
1319 | { | 1334 | { |
1320 | #if DEBUG_SERVER | 1335 | #if DEBUG_SERVER |
1321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1336 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1322 | "GNUNET_SERVER_receive_done called while still in processing loop\n"); | 1337 | "GNUNET_SERVER_receive_done called while still in processing loop\n"); |
1323 | #endif | 1338 | #endif |
1324 | return; | 1339 | return; |
1325 | } | 1340 | } |
1326 | if (client->server == NULL) | 1341 | if (client->server == NULL) |
1327 | { | 1342 | { |
1328 | GNUNET_SERVER_client_disconnect (client); | 1343 | GNUNET_SERVER_client_disconnect (client); |
1329 | return; | 1344 | return; |
1330 | } | 1345 | } |
1331 | #if DEBUG_SERVER | 1346 | #if DEBUG_SERVER |
1332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1347 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1333 | "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); | 1348 | "GNUNET_SERVER_receive_done causes restart in reading from the socket\n"); |
1334 | #endif | 1349 | #endif |
1335 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); | 1350 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task); |
1336 | client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client); | 1351 | client->restart_task = |
1352 | GNUNET_SCHEDULER_add_now (&restart_processing, client); | ||
1337 | } | 1353 | } |
1338 | 1354 | ||
1339 | 1355 | ||