diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-27 14:23:36 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-27 14:23:36 +0000 |
commit | 61e6913970371e15edec7a72f0eab5d8d4dd2c84 (patch) | |
tree | 28192c0f97f285577f09c4974b19043a1bc8b279 /src/transport/plugin_transport_http_client.c | |
parent | 07d9ba845fc86d810c029ee474b37c14bf1a68ee (diff) | |
download | gnunet-61e6913970371e15edec7a72f0eab5d8d4dd2c84.tar.gz gnunet-61e6913970371e15edec7a72f0eab5d8d4dd2c84.zip |
more code
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 324 |
1 files changed, 189 insertions, 135 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 1f0c4dab7..fc954498c 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -144,6 +144,10 @@ struct Session | |||
144 | */ | 144 | */ |
145 | int client_put_paused; | 145 | int client_put_paused; |
146 | 146 | ||
147 | /** | ||
148 | * Was session given to transport service? | ||
149 | */ | ||
150 | int session_passed; | ||
147 | 151 | ||
148 | /** | 152 | /** |
149 | * Client send handle | 153 | * Client send handle |
@@ -355,8 +359,9 @@ http_client_plugin_send (void *cls, | |||
355 | } | 359 | } |
356 | 360 | ||
357 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, | 361 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, |
358 | "Sending message with %u to peer `%s' with session %p\n", | 362 | "Session %p/connection %p: Sending message with %u to peer `%s' with \n", |
359 | msgbuf_size, GNUNET_i2s (&session->target), session); | 363 | session, session->client_put, |
364 | msgbuf_size, GNUNET_i2s (&session->target)); | ||
360 | 365 | ||
361 | /* create new message and schedule */ | 366 | /* create new message and schedule */ |
362 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); | 367 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); |
@@ -372,7 +377,8 @@ http_client_plugin_send (void *cls, | |||
372 | if (session->client_put_paused == GNUNET_YES) | 377 | if (session->client_put_paused == GNUNET_YES) |
373 | { | 378 | { |
374 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, | 379 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, |
375 | "Session %p was suspended, unpausing\n", session->client_put); | 380 | "Session %p/connection %p: unpausing connection\n", |
381 | session, session->client_put); | ||
376 | session->client_put_paused = GNUNET_NO; | 382 | session->client_put_paused = GNUNET_NO; |
377 | curl_easy_pause (session->client_put, CURLPAUSE_CONT); | 383 | curl_easy_pause (session->client_put, CURLPAUSE_CONT); |
378 | } | 384 | } |
@@ -383,6 +389,136 @@ http_client_plugin_send (void *cls, | |||
383 | } | 389 | } |
384 | 390 | ||
385 | 391 | ||
392 | void | ||
393 | client_delete_session (struct Session *s) | ||
394 | { | ||
395 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
396 | struct HTTP_Message *pos = s->msg_head; | ||
397 | struct HTTP_Message *next = NULL; | ||
398 | |||
399 | client_stop_session_timeout (s); | ||
400 | |||
401 | GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); | ||
402 | |||
403 | while (NULL != (pos = next)) | ||
404 | { | ||
405 | next = pos->next; | ||
406 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, pos); | ||
407 | if (pos->transmit_cont != NULL) | ||
408 | pos->transmit_cont (pos->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
409 | GNUNET_free (pos); | ||
410 | } | ||
411 | |||
412 | if (s->msg_tk != NULL) | ||
413 | { | ||
414 | GNUNET_SERVER_mst_destroy (s->msg_tk); | ||
415 | s->msg_tk = NULL; | ||
416 | } | ||
417 | GNUNET_free (s->addr); | ||
418 | GNUNET_free (s); | ||
419 | } | ||
420 | |||
421 | |||
422 | |||
423 | /** | ||
424 | * Disconnect a session | ||
425 | * | ||
426 | * @param s session | ||
427 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
428 | */ | ||
429 | static int | ||
430 | client_disconnect (struct Session *s) | ||
431 | { | ||
432 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
433 | struct HTTP_Message *msg; | ||
434 | struct HTTP_Message *t; | ||
435 | int res = GNUNET_OK; | ||
436 | CURLMcode mret; | ||
437 | |||
438 | if (GNUNET_YES != client_exist_session(plugin, s)) | ||
439 | { | ||
440 | GNUNET_break (0); | ||
441 | return GNUNET_SYSERR; | ||
442 | } | ||
443 | |||
444 | if (s->client_put != NULL) | ||
445 | { | ||
446 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
447 | "Session %p/connection %p: disconnecting PUT connectionto peer `%s'\n", | ||
448 | s, s->client_put, GNUNET_i2s (&s->target)); | ||
449 | |||
450 | /* remove curl handle from multi handle */ | ||
451 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_put); | ||
452 | if (mret != CURLM_OK) | ||
453 | { | ||
454 | /* clean up easy handle, handle is now invalid and free'd */ | ||
455 | res = GNUNET_SYSERR; | ||
456 | GNUNET_break (0); | ||
457 | } | ||
458 | curl_easy_cleanup (s->client_put); | ||
459 | s->client_put = NULL; | ||
460 | } | ||
461 | |||
462 | |||
463 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
464 | { | ||
465 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
466 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
467 | } | ||
468 | |||
469 | if (s->client_get != NULL) | ||
470 | { | ||
471 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
472 | "Session %p/connection %p: disconnecting GET connection to peer `%s'\n", | ||
473 | s, s->client_get, GNUNET_i2s (&s->target)); | ||
474 | |||
475 | /* remove curl handle from multi handle */ | ||
476 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); | ||
477 | if (mret != CURLM_OK) | ||
478 | { | ||
479 | /* clean up easy handle, handle is now invalid and free'd */ | ||
480 | res = GNUNET_SYSERR; | ||
481 | GNUNET_break (0); | ||
482 | } | ||
483 | curl_easy_cleanup (s->client_get); | ||
484 | s->client_get = NULL; | ||
485 | } | ||
486 | |||
487 | msg = s->msg_head; | ||
488 | while (msg != NULL) | ||
489 | { | ||
490 | t = msg->next; | ||
491 | if (NULL != msg->transmit_cont) | ||
492 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
493 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
494 | GNUNET_free (msg); | ||
495 | msg = t; | ||
496 | } | ||
497 | |||
498 | GNUNET_assert (plugin->cur_connections >= 2); | ||
499 | plugin->cur_connections -= 2; | ||
500 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
501 | "# HTTP client sessions", | ||
502 | plugin->cur_connections, | ||
503 | GNUNET_NO); | ||
504 | |||
505 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
506 | "Session %p: notifying transport about ending session\n",s); | ||
507 | |||
508 | plugin->env->session_end (plugin->env->cls, &s->target, s); | ||
509 | client_delete_session (s); | ||
510 | |||
511 | /* Re-schedule since handles have changed */ | ||
512 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
513 | { | ||
514 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
515 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
516 | } | ||
517 | client_schedule (plugin, GNUNET_YES); | ||
518 | |||
519 | return res; | ||
520 | } | ||
521 | |||
386 | 522 | ||
387 | /** | 523 | /** |
388 | * Function that can be used to force the plugin to disconnect | 524 | * Function that can be used to force the plugin to disconnect |
@@ -395,9 +531,27 @@ http_client_plugin_send (void *cls, | |||
395 | static void | 531 | static void |
396 | http_client_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 532 | http_client_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) |
397 | { | 533 | { |
398 | // struct Plugin *plugin = cls; | 534 | struct HTTP_Client_Plugin *plugin = cls; |
399 | // FIXME | 535 | struct Session *next = NULL; |
400 | GNUNET_break (0); | 536 | struct Session *pos = NULL; |
537 | |||
538 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
539 | "Transport tells me to disconnect `%s'\n", | ||
540 | GNUNET_i2s (target)); | ||
541 | |||
542 | next = plugin->head; | ||
543 | while (NULL != (pos = next)) | ||
544 | { | ||
545 | next = pos->next; | ||
546 | if (0 == memcmp (target, &pos->target, sizeof (struct GNUNET_PeerIdentity))) | ||
547 | { | ||
548 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
549 | "Disconnecting session %p to `%pos'\n", | ||
550 | pos, GNUNET_i2s (target)); | ||
551 | GNUNET_assert (GNUNET_OK == client_disconnect (pos)); | ||
552 | } | ||
553 | } | ||
554 | |||
401 | } | 555 | } |
402 | 556 | ||
403 | static struct Session * | 557 | static struct Session * |
@@ -440,7 +594,8 @@ client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) | |||
440 | if (NULL == msg) | 594 | if (NULL == msg) |
441 | { | 595 | { |
442 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 596 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
443 | "Nothing to for session %p send! Suspending PUT handle!\n", s); | 597 | "Session %p/connection %p: nothing to send, suspending\n", |
598 | s, s->client_put); | ||
444 | s->client_put_paused = GNUNET_YES; | 599 | s->client_put_paused = GNUNET_YES; |
445 | return CURL_READFUNC_PAUSE; | 600 | return CURL_READFUNC_PAUSE; |
446 | } | 601 | } |
@@ -454,8 +609,8 @@ client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) | |||
454 | if (msg->pos == msg->size) | 609 | if (msg->pos == msg->size) |
455 | { | 610 | { |
456 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 611 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
457 | "Session %p message with %u bytes sent, removing message from queue\n", | 612 | "Session %p/connection %p: sent message with %u bytes sent, removing message from queue\n", |
458 | s, msg->size, msg->pos); | 613 | s, s->client_put, msg->size, msg->pos); |
459 | /* Calling transmit continuation */ | 614 | /* Calling transmit continuation */ |
460 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | 615 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); |
461 | if (NULL != msg->transmit_cont) | 616 | if (NULL != msg->transmit_cont) |
@@ -481,7 +636,7 @@ client_wake_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
481 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 636 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
482 | return; | 637 | return; |
483 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | 638 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, |
484 | "Client: %p Waking up receive handle\n", s->client_get); | 639 | "Session %p/connection %p: Waking up GET handle\n", s, s->client_get); |
485 | if (s->client_get != NULL) | 640 | if (s->client_get != NULL) |
486 | curl_easy_pause (s->client_get, CURLPAUSE_CONT); | 641 | curl_easy_pause (s->client_get, CURLPAUSE_CONT); |
487 | } | 642 | } |
@@ -658,98 +813,6 @@ client_schedule (struct HTTP_Client_Plugin *plugin, int now) | |||
658 | 813 | ||
659 | 814 | ||
660 | 815 | ||
661 | static int | ||
662 | client_disconnect (struct Session *s) | ||
663 | { | ||
664 | |||
665 | int res = GNUNET_OK; | ||
666 | CURLMcode mret; | ||
667 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
668 | struct HTTP_Message *msg; | ||
669 | struct HTTP_Message *t; | ||
670 | |||
671 | if (GNUNET_YES != client_exist_session (plugin, s)) | ||
672 | { | ||
673 | GNUNET_break (0); | ||
674 | return GNUNET_SYSERR; | ||
675 | } | ||
676 | |||
677 | if (s->client_put != NULL) | ||
678 | { | ||
679 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
680 | "Disconnecting PUT session %p to peer `%s'\n", | ||
681 | s, GNUNET_i2s (&s->target)); | ||
682 | |||
683 | /* remove curl handle from multi handle */ | ||
684 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_put); | ||
685 | if (mret != CURLM_OK) | ||
686 | { | ||
687 | /* clean up easy handle, handle is now invalid and free'd */ | ||
688 | res = GNUNET_SYSERR; | ||
689 | GNUNET_break (0); | ||
690 | } | ||
691 | curl_easy_cleanup (s->client_put); | ||
692 | s->client_put = NULL; | ||
693 | } | ||
694 | |||
695 | |||
696 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
697 | { | ||
698 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
699 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
700 | } | ||
701 | |||
702 | if (s->client_get != NULL) | ||
703 | { | ||
704 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
705 | "Disconnecting GET session %p to peer `%s'\n", | ||
706 | s, GNUNET_i2s (&s->target)); | ||
707 | |||
708 | /* remove curl handle from multi handle */ | ||
709 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); | ||
710 | if (mret != CURLM_OK) | ||
711 | { | ||
712 | /* clean up easy handle, handle is now invalid and free'd */ | ||
713 | res = GNUNET_SYSERR; | ||
714 | GNUNET_break (0); | ||
715 | } | ||
716 | curl_easy_cleanup (s->client_get); | ||
717 | s->client_get = NULL; | ||
718 | } | ||
719 | |||
720 | msg = s->msg_head; | ||
721 | while (msg != NULL) | ||
722 | { | ||
723 | t = msg->next; | ||
724 | if (NULL != msg->transmit_cont) | ||
725 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
726 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
727 | GNUNET_free (msg); | ||
728 | msg = t; | ||
729 | } | ||
730 | |||
731 | plugin->cur_connections -= 2; | ||
732 | plugin->env->session_end (plugin->env->cls, &s->target, s); | ||
733 | |||
734 | GNUNET_assert (plugin->cur_connections >= 0); | ||
735 | plugin->cur_connections --; | ||
736 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
737 | "# HTTP client connections", | ||
738 | plugin->cur_connections, | ||
739 | GNUNET_NO); | ||
740 | |||
741 | /* Re-schedule since handles have changed */ | ||
742 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
743 | { | ||
744 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
745 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
746 | } | ||
747 | client_schedule (plugin, GNUNET_YES); | ||
748 | |||
749 | return res; | ||
750 | } | ||
751 | |||
752 | |||
753 | /** | 816 | /** |
754 | * Task performing curl operations | 817 | * Task performing curl operations |
755 | * | 818 | * |
@@ -807,10 +870,8 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
807 | if (msg->msg == CURLMSG_DONE) | 870 | if (msg->msg == CURLMSG_DONE) |
808 | { | 871 | { |
809 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 872 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
810 | "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", | 873 | "Session %p/connection %p: connection to `%s' ended with reason %i: `%s'\n", |
811 | msg->easy_handle, GNUNET_i2s (&s->target), | 874 | s, msg->easy_handle, GNUNET_i2s (&s->target), |
812 | http_common_plugin_address_to_string (NULL, s->addr, | ||
813 | s->addrlen), | ||
814 | msg->data.result, | 875 | msg->data.result, |
815 | curl_easy_strerror (msg->data.result)); | 876 | curl_easy_strerror (msg->data.result)); |
816 | 877 | ||
@@ -931,6 +992,10 @@ client_connect (struct Session *s) | |||
931 | return GNUNET_SYSERR; | 992 | return GNUNET_SYSERR; |
932 | } | 993 | } |
933 | 994 | ||
995 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
996 | "Session %p: connected with connections GET %p and PUT %p\n", | ||
997 | s, s->client_get, s->client_put); | ||
998 | |||
934 | /* Perform connect */ | 999 | /* Perform connect */ |
935 | plugin->cur_connections += 2; | 1000 | plugin->cur_connections += 2; |
936 | GNUNET_STATISTICS_set (plugin->env->stats, | 1001 | GNUNET_STATISTICS_set (plugin->env->stats, |
@@ -948,35 +1013,6 @@ client_connect (struct Session *s) | |||
948 | return res; | 1013 | return res; |
949 | } | 1014 | } |
950 | 1015 | ||
951 | void | ||
952 | client_delete_session (struct Session *s) | ||
953 | { | ||
954 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
955 | struct HTTP_Message *pos = s->msg_head; | ||
956 | struct HTTP_Message *next = NULL; | ||
957 | |||
958 | client_stop_session_timeout (s); | ||
959 | |||
960 | GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); | ||
961 | |||
962 | while (NULL != (pos = next)) | ||
963 | { | ||
964 | next = pos->next; | ||
965 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, pos); | ||
966 | if (pos->transmit_cont != NULL) | ||
967 | pos->transmit_cont (pos->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
968 | GNUNET_free (pos); | ||
969 | } | ||
970 | |||
971 | if (s->msg_tk != NULL) | ||
972 | { | ||
973 | GNUNET_SERVER_mst_destroy (s->msg_tk); | ||
974 | s->msg_tk = NULL; | ||
975 | } | ||
976 | GNUNET_free (s->addr); | ||
977 | GNUNET_free (s); | ||
978 | } | ||
979 | |||
980 | 1016 | ||
981 | /** | 1017 | /** |
982 | * Creates a new outbound session the transport service will use to send data to the | 1018 | * Creates a new outbound session the transport service will use to send data to the |
@@ -1156,6 +1192,20 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
1156 | { | 1192 | { |
1157 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 1193 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
1158 | struct HTTP_Client_Plugin *plugin = api->cls; | 1194 | struct HTTP_Client_Plugin *plugin = api->cls; |
1195 | struct Session *pos; | ||
1196 | struct Session *next; | ||
1197 | |||
1198 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1199 | _("Shutting down plugin `%s'\n"), | ||
1200 | plugin->name); | ||
1201 | |||
1202 | next = plugin->head; | ||
1203 | while (NULL != (pos = next)) | ||
1204 | { | ||
1205 | next = pos->next; | ||
1206 | GNUNET_CONTAINER_DLL_remove( plugin->head, plugin->tail, pos); | ||
1207 | client_disconnect (pos); | ||
1208 | } | ||
1159 | 1209 | ||
1160 | if (NULL == api->cls) | 1210 | if (NULL == api->cls) |
1161 | { | 1211 | { |
@@ -1170,6 +1220,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
1170 | } | 1220 | } |
1171 | curl_global_cleanup (); | 1221 | curl_global_cleanup (); |
1172 | 1222 | ||
1223 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1224 | _("Shutdown for plugin `%s' complete\n"), | ||
1225 | plugin->name); | ||
1226 | |||
1173 | GNUNET_free (plugin); | 1227 | GNUNET_free (plugin); |
1174 | GNUNET_free (api); | 1228 | GNUNET_free (api); |
1175 | return NULL; | 1229 | return NULL; |