aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_client.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-08-27 14:23:36 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-08-27 14:23:36 +0000
commit61e6913970371e15edec7a72f0eab5d8d4dd2c84 (patch)
tree28192c0f97f285577f09c4974b19043a1bc8b279 /src/transport/plugin_transport_http_client.c
parent07d9ba845fc86d810c029ee474b37c14bf1a68ee (diff)
downloadgnunet-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.c324
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
392void
393client_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 */
429static int
430client_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,
395static void 531static void
396http_client_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 532http_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
403static struct Session * 557static 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
661static int
662client_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
951void
952client_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;