aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/datastore/plugin_datastore_mysql.c3
-rw-r--r--src/include/gauger.h6
-rw-r--r--src/transport/gnunet-service-transport.c80
-rw-r--r--src/transport/plugin_transport_http.c2851
4 files changed, 1558 insertions, 1382 deletions
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index baba03efb..ec263a035 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -339,9 +339,6 @@ prepared_statement_destroy (struct Plugin *plugin,
339static int 339static int
340iclose (struct Plugin *plugin) 340iclose (struct Plugin *plugin)
341{ 341{
342 struct GNUNET_MysqlStatementHandle *spos;
343
344 spos = plugin->shead;
345 while (NULL != plugin->shead) 342 while (NULL != plugin->shead)
346 prepared_statement_destroy (plugin, 343 prepared_statement_destroy (plugin,
347 plugin->shead); 344 plugin->shead);
diff --git a/src/include/gauger.h b/src/include/gauger.h
index b45b2b83f..b4737c259 100644
--- a/src/include/gauger.h
+++ b/src/include/gauger.h
@@ -23,6 +23,8 @@
23 char __gauger_s[32];\ 23 char __gauger_s[32];\
24 pid_t __gauger_p;\ 24 pid_t __gauger_p;\
25 if(!(__gauger_p=fork())){\ 25 if(!(__gauger_p=fork())){\
26 close (1); \
27 close (2); \
26 if(!fork()){\ 28 if(!fork()){\
27 sprintf(__gauger_s,"%Lf", (long double) (value));\ 29 sprintf(__gauger_s,"%Lf", (long double) (value));\
28 __gauger_v[0] = "gauger-cli.py";\ 30 __gauger_v[0] = "gauger-cli.py";\
@@ -36,7 +38,6 @@
36 __gauger_v[8] = category;\ 38 __gauger_v[8] = category;\
37 __gauger_v[9] = (char *)NULL;\ 39 __gauger_v[9] = (char *)NULL;\
38 execvp("gauger-cli.py",__gauger_v);\ 40 execvp("gauger-cli.py",__gauger_v);\
39 perror("gauger");\
40 _exit(1);\ 41 _exit(1);\
41 }else{\ 42 }else{\
42 _exit(0);\ 43 _exit(0);\
@@ -52,6 +53,8 @@
52 char __gauger_s[32];\ 53 char __gauger_s[32];\
53 pid_t __gauger_p;\ 54 pid_t __gauger_p;\
54 if(!(__gauger_p=fork())){\ 55 if(!(__gauger_p=fork())){\
56 close (1); \
57 close (2); \
55 if(!fork()){\ 58 if(!fork()){\
56 sprintf(__gauger_s,"%Lf", (long double) (value));\ 59 sprintf(__gauger_s,"%Lf", (long double) (value));\
57 __gauger_v[0] = "gauger-cli.py";\ 60 __gauger_v[0] = "gauger-cli.py";\
@@ -67,7 +70,6 @@
67 __gauger_v[10] = category;\ 70 __gauger_v[10] = category;\
68 __gauger_v[11] = (char *)NULL;\ 71 __gauger_v[11] = (char *)NULL;\
69 execvp("gauger-cli.py",__gauger_v);\ 72 execvp("gauger-cli.py",__gauger_v);\
70 perror("gauger");\
71 _exit(1);\ 73 _exit(1);\
72 }else{\ 74 }else{\
73 _exit(0);\ 75 _exit(0);\
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index f01c64bb4..9691f55eb 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -2792,50 +2792,44 @@ add_peer_address (struct NeighbourList *neighbour,
2792 } 2792 }
2793 2793
2794 ret->ressources = GNUNET_malloc(available_ressources * sizeof (struct ATS_ressource_entry)); 2794 ret->ressources = GNUNET_malloc(available_ressources * sizeof (struct ATS_ressource_entry));
2795 int plugin;
2796 for (c=0; c<available_ressources; c++) 2795 for (c=0; c<available_ressources; c++)
2797 { 2796 {
2798 struct ATS_ressource_entry *r = ret->ressources; 2797 struct ATS_ressource_entry *r = ret->ressources;
2799 r[c].index = c; 2798 r[c].index = c;
2800 r[c].atis_index = ressources[c].atis_index; 2799 r[c].atis_index = ressources[c].atis_index;
2801 if (0 == strcmp(neighbour->plugins->plugin->short_name,"unix")) 2800 if (0 == strcmp(neighbour->plugins->plugin->short_name,"unix"))
2802 { 2801 {
2803 r[c].c = ressources[c].c_unix; 2802 r[c].c = ressources[c].c_unix;
2804 plugin = 1; 2803 }
2805 } 2804 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"udp"))
2806 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"udp")) 2805 {
2807 { 2806 r[c].c = ressources[c].c_udp;
2808 r[c].c = ressources[c].c_udp; 2807 }
2809 plugin = 2; 2808 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"tcp"))
2810 } 2809 {
2811 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"tcp")) 2810 r[c].c = ressources[c].c_tcp;
2812 { 2811 }
2813 r[c].c = ressources[c].c_tcp; 2812 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"http"))
2814 plugin = 3; 2813 {
2815 } 2814 r[c].c = ressources[c].c_http;
2816 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"http")) 2815 }
2817 { 2816 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"https"))
2818 r[c].c = ressources[c].c_http; 2817 {
2819 plugin = 4; 2818 r[c].c = ressources[c].c_https;
2820 } 2819 }
2821 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"https")) 2820 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"wlan"))
2822 { 2821 {
2823 r[c].c = ressources[c].c_https; 2822 r[c].c = ressources[c].c_wlan;
2824 plugin = 5; 2823 }
2825 } 2824 else
2826 else if (0 == strcmp(neighbour->plugins->plugin->short_name,"wlan")) 2825 {
2827 { 2826 r[c].c = ressources[c].c_default;
2828 r[c].c = ressources[c].c_wlan; 2827 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2829 plugin = 6; 2828 "Assigning default cost to peer `%s' addr plugin `%s'! This should not happen!\n",
2830 } 2829 GNUNET_i2s(&neighbour->peer),
2831 else 2830 neighbour->plugins->plugin->short_name);
2832 { 2831 }
2833 plugin = -1; 2832 }
2834 r[c].c = ressources[c].c_default;
2835 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"Assigning default cost to peer `%s' addr plugin `%s'! This should not happen!",
2836 GNUNET_i2s(&neighbour->peer), neighbour->plugins->plugin->short_name);
2837 }
2838 }
2839 2833
2840 ret->quality = GNUNET_malloc (available_quality_metrics * sizeof (struct ATS_quality_entry)); 2834 ret->quality = GNUNET_malloc (available_quality_metrics * sizeof (struct ATS_quality_entry));
2841 ret->addrlen = addrlen; 2835 ret->addrlen = addrlen;
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
index b34972722..0c859cdbf 100644
--- a/src/transport/plugin_transport_http.c
+++ b/src/transport/plugin_transport_http.c
@@ -535,17 +535,13 @@ static int curl_schedule (struct Plugin *plugin);
535static void reset_inbound_quota_delay (void *cls, 535static void reset_inbound_quota_delay (void *cls,
536 const struct GNUNET_SCHEDULER_TaskContext *tc) 536 const struct GNUNET_SCHEDULER_TaskContext *tc)
537{ 537{
538 struct HTTP_PeerContext * pc; 538 struct HTTP_PeerContext * pc = cls;
539 539
540 GNUNET_assert(cls !=NULL); 540 GNUNET_assert(cls != NULL);
541 541 pc->reset_task = GNUNET_SCHEDULER_NO_TASK;
542 pc = (struct HTTP_PeerContext *) cls; 542 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
543 pc->reset_task = GNUNET_SCHEDULER_NO_TASK; 543 return;
544 544 pc->delay = GNUNET_TIME_relative_get_zero ();
545 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
546 return;
547
548 pc->delay = GNUNET_TIME_relative_get_zero ();
549} 545}
550 546
551 547
@@ -557,7 +553,10 @@ static void reset_inbound_quota_delay (void *cls,
557 * @param id session id 553 * @param id session id
558 * @return the created url 554 * @return the created url
559 */ 555 */
560static char * create_url(struct Plugin *plugin, const void * addr, size_t addrlen, size_t id) 556static char *
557create_url(struct Plugin *plugin,
558 const void * addr, size_t addrlen,
559 size_t id)
561{ 560{
562 char *url = NULL; 561 char *url = NULL;
563 char *addr_str = (char *) http_plugin_address_to_string(NULL, addr, addrlen); 562 char *addr_str = (char *) http_plugin_address_to_string(NULL, addr, addrlen);
@@ -570,15 +569,20 @@ static char * create_url(struct Plugin *plugin, const void * addr, size_t addrle
570 return url; 569 return url;
571} 570}
572 571
572
573/** 573/**
574 * Removes a message from the linked list of messages 574 * Removes a message from the linked list of messages
575 * @param ps session 575 * @param ps session
576 * @param msg message 576 * @param msg message
577 * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success 577 * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success
578 */ 578 */
579static int remove_http_message (struct Session * ps, struct HTTP_Message * msg) 579static int
580remove_http_message (struct Session * ps,
581 struct HTTP_Message * msg)
580{ 582{
581 GNUNET_CONTAINER_DLL_remove(ps->pending_msgs_head,ps->pending_msgs_tail,msg); 583 GNUNET_CONTAINER_DLL_remove(ps->pending_msgs_head,
584 ps->pending_msgs_tail,
585 msg);
582 GNUNET_free(msg); 586 GNUNET_free(msg);
583 return GNUNET_OK; 587 return GNUNET_OK;
584} 588}
@@ -590,7 +594,10 @@ static int remove_http_message (struct Session * ps, struct HTTP_Message * msg)
590 * @param value the peer context 594 * @param value the peer context
591 * @return GNUNET_YES on success 595 * @return GNUNET_YES on success
592 */ 596 */
593int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value) 597static int
598remove_peer_context_Iterator (void *cls,
599 const GNUNET_HashCode *key,
600 void *value)
594{ 601{
595 struct Plugin *plugin = cls; 602 struct Plugin *plugin = cls;
596 struct HTTP_PeerContext * pc = value; 603 struct HTTP_PeerContext * pc = value;
@@ -598,38 +605,40 @@ int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *v
598 struct Session * tmp = NULL; 605 struct Session * tmp = NULL;
599 struct HTTP_Message * msg = NULL; 606 struct HTTP_Message * msg = NULL;
600 struct HTTP_Message * msg_tmp = NULL; 607 struct HTTP_Message * msg_tmp = NULL;
608
601#if DEBUG_HTTP 609#if DEBUG_HTTP
602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Freeing context for peer `%s'\n",GNUNET_i2s(&pc->identity)); 610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
611 "Freeing context for peer `%s'\n",
612 GNUNET_i2s(&pc->identity));
603#endif 613#endif
604 GNUNET_CONTAINER_multihashmap_remove (plugin->peers, &pc->identity.hashPubKey, pc); 614 GNUNET_CONTAINER_multihashmap_remove (plugin->peers, &pc->identity.hashPubKey, pc);
605 while (ps!=NULL) 615 while (ps!=NULL)
606 {
607 plugin->env->session_end(plugin, &pc->identity, ps);
608 tmp = ps->next;
609
610 GNUNET_free_non_null (ps->addr);
611 GNUNET_free(ps->url);
612 if (ps->msgtok != NULL)
613 GNUNET_SERVER_mst_destroy (ps->msgtok);
614
615 msg = ps->pending_msgs_head;
616 while (msg!=NULL)
617 {
618 msg_tmp = msg->next;
619 GNUNET_free(msg);
620 msg = msg_tmp;
621 }
622 if (ps->direction==OUTBOUND)
623 { 616 {
624 if (ps->send_endpoint!=NULL) 617 plugin->env->session_end(plugin, &pc->identity, ps);
625 curl_easy_cleanup(ps->send_endpoint); 618 tmp = ps->next;
626 if (ps->recv_endpoint!=NULL) 619
627 curl_easy_cleanup(ps->recv_endpoint); 620 GNUNET_free_non_null (ps->addr);
621 GNUNET_free(ps->url);
622 if (ps->msgtok != NULL)
623 GNUNET_SERVER_mst_destroy (ps->msgtok);
624
625 msg = ps->pending_msgs_head;
626 while (msg!=NULL)
627 {
628 msg_tmp = msg->next;
629 GNUNET_free(msg);
630 msg = msg_tmp;
631 }
632 if (ps->direction==OUTBOUND)
633 {
634 if (ps->send_endpoint!=NULL)
635 curl_easy_cleanup(ps->send_endpoint);
636 if (ps->recv_endpoint!=NULL)
637 curl_easy_cleanup(ps->recv_endpoint);
638 }
639 GNUNET_free(ps);
640 ps=tmp;
628 } 641 }
629
630 GNUNET_free(ps);
631 ps=tmp;
632 }
633 GNUNET_free(pc); 642 GNUNET_free(pc);
634 GNUNET_STATISTICS_update (plugin->env->stats, 643 GNUNET_STATISTICS_update (plugin->env->stats,
635 gettext_noop ("# HTTP peers active"), 644 gettext_noop ("# HTTP peers active"),
@@ -647,59 +656,73 @@ int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *v
647 * @param call_msg_cont_result result to call message continuations with 656 * @param call_msg_cont_result result to call message continuations with
648 * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success 657 * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success
649 */ 658 */
650static int remove_session (struct HTTP_PeerContext * pc, struct Session * ps, int call_msg_cont, int call_msg_cont_result) 659static int
660remove_session (struct HTTP_PeerContext * pc,
661 struct Session * ps,
662 int call_msg_cont,
663 int call_msg_cont_result)
651{ 664{
652 struct HTTP_Message * msg; 665 struct HTTP_Message * msg;
653 struct Plugin * plugin = ps->peercontext->plugin; 666 struct Plugin * plugin = ps->peercontext->plugin;
654 667
655#if DEBUG_CONNECTIONS 668#if DEBUG_CONNECTIONS
656 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: removing %s session %X with id %u\n", ps, (ps->direction == INBOUND) ? "inbound" : "outbound", ps, ps->session_id); 669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
670 "Connection %X: removing %s session %X with id %u\n",
671 ps,
672 (ps->direction == INBOUND)
673 ? "inbound"
674 : "outbound",
675 ps, ps->session_id);
657#endif 676#endif
658 plugin->env->session_end(plugin, &pc->identity, ps); 677 plugin->env->session_end(plugin, &pc->identity, ps);
659
660 GNUNET_free_non_null (ps->addr); 678 GNUNET_free_non_null (ps->addr);
661 GNUNET_SERVER_mst_destroy (ps->msgtok); 679 GNUNET_SERVER_mst_destroy (ps->msgtok);
662 GNUNET_free(ps->url); 680 GNUNET_free(ps->url);
663
664 if (ps->direction==INBOUND) 681 if (ps->direction==INBOUND)
665 { 682 {
666 if (ps->recv_endpoint != NULL) 683 if (ps->recv_endpoint != NULL)
667 { 684 {
668 curl_easy_cleanup(ps->recv_endpoint); 685 curl_easy_cleanup(ps->recv_endpoint);
669 ps->recv_endpoint = NULL; 686 ps->recv_endpoint = NULL;
670 } 687 }
671 if (ps->send_endpoint != NULL) 688 if (ps->send_endpoint != NULL)
672 { 689 {
673 curl_easy_cleanup(ps->send_endpoint); 690 curl_easy_cleanup(ps->send_endpoint);
674 ps->send_endpoint = NULL; 691 ps->send_endpoint = NULL;
675 } 692 }
676 } 693 }
677 694
678 msg = ps->pending_msgs_head; 695 msg = ps->pending_msgs_head;
679 while (msg!=NULL) 696 while (msg!=NULL)
680 {
681 if ((call_msg_cont == GNUNET_YES) && (msg->transmit_cont!=NULL))
682 { 697 {
683 msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,call_msg_cont_result); 698 if ((call_msg_cont == GNUNET_YES) && (msg->transmit_cont!=NULL))
699 {
700 msg->transmit_cont (msg->transmit_cont_cls,
701 &pc->identity,
702 call_msg_cont_result);
703 }
704 GNUNET_CONTAINER_DLL_remove(ps->pending_msgs_head,
705 ps->pending_msgs_head,
706 msg);
707 GNUNET_free(msg);
708 msg = ps->pending_msgs_head;
684 } 709 }
685 GNUNET_CONTAINER_DLL_remove(ps->pending_msgs_head,ps->pending_msgs_head,msg); 710
686 GNUNET_free(msg);
687 msg = ps->pending_msgs_head;
688 }
689
690 GNUNET_CONTAINER_DLL_remove(pc->head,pc->tail,ps); 711 GNUNET_CONTAINER_DLL_remove(pc->head,pc->tail,ps);
691 GNUNET_free(ps); 712 GNUNET_free(ps);
692 ps = NULL; 713 ps = NULL;
693 714
694 /* no sessions left remove peer */ 715 /* no sessions left remove peer */
695 if (pc->head==NULL) 716 if (pc->head==NULL)
696 { 717 {
697#if DEBUG_HTTP 718#if DEBUG_HTTP
698 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No sessions left for peer `%s', removing context\n",GNUNET_i2s(&pc->identity)); 719 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
720 "No sessions left for peer `%s', removing context\n",
721 GNUNET_i2s(&pc->identity));
699#endif 722#endif
700 remove_peer_context_Iterator(plugin, &pc->identity.hashPubKey, pc); 723 remove_peer_context_Iterator(plugin, &pc->identity.hashPubKey, pc);
701 } 724 }
702 725
703 return GNUNET_OK; 726 return GNUNET_OK;
704} 727}
705 728
@@ -729,40 +752,52 @@ process_interfaces (void *cls,
729 752
730 GNUNET_assert(cls !=NULL); 753 GNUNET_assert(cls !=NULL);
731 af = addr->sa_family; 754 af = addr->sa_family;
732 if ((af == AF_INET) && (plugin->use_ipv4 == GNUNET_YES) && (plugin->bind6_address == NULL)) 755 if ( (af == AF_INET) &&
756 (plugin->use_ipv4 == GNUNET_YES) &&
757 (plugin->bind6_address == NULL) )
733 { 758 {
734 struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr; 759 struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr;
735 t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); 760 t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress));
736 /* Not skipping loopback addresses 761 /* Not skipping loopback addresses
737 if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr)) 762 if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr))
738 { 763 {
739 764
740 return GNUNET_OK; 765 return GNUNET_OK;
741 } 766 }
742 */ 767 */
743 t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 768 t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
744 t4->u_port = htons (plugin->port_inbound); 769 t4->u_port = htons (plugin->port_inbound);
745 if (plugin->bind4_address != NULL) 770 if (plugin->bind4_address != NULL)
746 { 771 {
747 if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) 772 if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr)))
748 { 773 {
749 GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4); 774 GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4);
750 plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); 775 plugin->env->notify_address(plugin->env->cls,
751 return GNUNET_OK; 776 PROTOCOL_PREFIX,
752 } 777 t4, sizeof (struct IPv4HttpAddress),
753 GNUNET_free (t4); 778 GNUNET_TIME_UNIT_FOREVER_REL);
754 return GNUNET_OK; 779 return GNUNET_OK;
755 } 780 }
781 GNUNET_free (t4);
782 return GNUNET_OK;
783 }
756 else 784 else
757 { 785 {
758 GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4); 786 GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head,
759 plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); 787 plugin->ipv4_addr_tail,
788 t4);
789 plugin->env->notify_address (plugin->env->cls,
790 PROTOCOL_PREFIX,
791 t4, sizeof (struct IPv4HttpAddress),
792 GNUNET_TIME_UNIT_FOREVER_REL);
760 return GNUNET_OK; 793 return GNUNET_OK;
761 } 794 }
762 } 795 }
763 else if ((af == AF_INET6) && (plugin->use_ipv6 == GNUNET_YES) && (plugin->bind4_address == NULL)) 796 else if ( (af == AF_INET6) &&
797 (plugin->use_ipv6 == GNUNET_YES) &&
798 (plugin->bind4_address == NULL) )
764 { 799 {
765 struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr; 800 struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr;
766 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) 801 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
767 { 802 {
768 return GNUNET_OK; 803 return GNUNET_OK;
@@ -770,26 +805,36 @@ process_interfaces (void *cls,
770 t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); 805 t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress));
771 GNUNET_assert(t6 != NULL); 806 GNUNET_assert(t6 != NULL);
772 if (plugin->bind6_address != NULL) 807 if (plugin->bind6_address != NULL)
773 { 808 {
774 if (0 == memcmp(&plugin->bind6_address->sin6_addr, &bnd_cmp6, sizeof (struct in6_addr))) 809 if (0 == memcmp(&plugin->bind6_address->sin6_addr,
775 { 810 &bnd_cmp6,
811 sizeof (struct in6_addr)))
812 {
776 memcpy (&t6->ipv6_addr, 813 memcpy (&t6->ipv6_addr,
777 &((struct sockaddr_in6 *) addr)->sin6_addr, 814 &((struct sockaddr_in6 *) addr)->sin6_addr,
778 sizeof (struct in6_addr)); 815 sizeof (struct in6_addr));
779 t6->u6_port = htons (plugin->port_inbound); 816 t6->u6_port = htons (plugin->port_inbound);
780 plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); 817 plugin->env->notify_address(plugin->env->cls,
781 GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6); 818 PROTOCOL_PREFIX, t6,
782 return GNUNET_OK; 819 sizeof (struct IPv6HttpAddress),
783 } 820 GNUNET_TIME_UNIT_FOREVER_REL);
784 GNUNET_free (t6); 821 GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,
785 return GNUNET_OK; 822 plugin->ipv6_addr_tail,
786 } 823 t6);
787 memcpy (&t6->ipv6_addr, 824 return GNUNET_OK;
788 &((struct sockaddr_in6 *) addr)->sin6_addr, 825 }
789 sizeof (struct in6_addr)); 826 GNUNET_free (t6);
790 t6->u6_port = htons (plugin->port_inbound); 827 return GNUNET_OK;
791 GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6); 828 }
792 plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); 829 memcpy (&t6->ipv6_addr,
830 &((struct sockaddr_in6 *) addr)->sin6_addr,
831 sizeof (struct in6_addr));
832 t6->u6_port = htons (plugin->port_inbound);
833 GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6);
834 plugin->env->notify_address(plugin->env->cls,
835 PROTOCOL_PREFIX,
836 t6, sizeof (struct IPv6HttpAddress),
837 GNUNET_TIME_UNIT_FOREVER_REL);
793 } 838 }
794 return GNUNET_OK; 839 return GNUNET_OK;
795} 840}
@@ -801,16 +846,25 @@ process_interfaces (void *cls,
801 * @param fmt format string 846 * @param fmt format string
802 * @param ap list of arguments 847 * @param ap list of arguments
803 */ 848 */
804void mhd_logger (void * arg, const char * fmt, va_list ap) 849static void
850mhd_logger (void * arg,
851 const char * fmt,
852 va_list ap)
805{ 853{
806 char text[1024]; 854 char text[1024];
807 vsnprintf(text, 1024, fmt, ap); 855
808 va_end(ap); 856 vsnprintf(text, sizeof(text), fmt, ap);
809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"MHD: %s \n", text); 857 va_end(ap);
858 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
859 "MHD: %s\n",
860 text);
810} 861}
811 862
812 863
813static void mhd_termination_cb (void *cls, struct MHD_Connection * connection, void **httpSessionCache) 864static void
865mhd_termination_cb (void *cls,
866 struct MHD_Connection * connection,
867 void **httpSessionCache)
814{ 868{
815 struct Session * ps = *httpSessionCache; 869 struct Session * ps = *httpSessionCache;
816 if (ps == NULL) 870 if (ps == NULL)
@@ -818,52 +872,59 @@ static void mhd_termination_cb (void *cls, struct MHD_Connection * connection, v
818 struct HTTP_PeerContext * pc = ps->peercontext; 872 struct HTTP_PeerContext * pc = ps->peercontext;
819 873
820 if (connection==ps->recv_endpoint) 874 if (connection==ps->recv_endpoint)
821 { 875 {
822#if DEBUG_CONNECTIONS 876#if DEBUG_CONNECTIONS
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound connection from peer `%s' was terminated\n", ps, GNUNET_i2s(&pc->identity)); 877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
878 "Connection %X: inbound connection from peer `%s' was terminated\n",
879 ps,
880 GNUNET_i2s(&pc->identity));
824#endif 881#endif
825 ps->recv_active = GNUNET_NO; 882 ps->recv_active = GNUNET_NO;
826 ps->recv_connected = GNUNET_NO; 883 ps->recv_connected = GNUNET_NO;
827 ps->recv_endpoint = NULL; 884 ps->recv_endpoint = NULL;
828 } 885 }
829 if (connection==ps->send_endpoint) 886 if (connection==ps->send_endpoint)
830 { 887 {
831 888 ps->send_active = GNUNET_NO;
832 ps->send_active = GNUNET_NO; 889 ps->send_connected = GNUNET_NO;
833 ps->send_connected = GNUNET_NO; 890 ps->send_endpoint = NULL;
834 ps->send_endpoint = NULL;
835#if DEBUG_CONNECTIONS 891#if DEBUG_CONNECTIONS
836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound connection from peer `%s' was terminated\n", ps, GNUNET_i2s(&pc->identity)); 892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
893 "Connection %X: outbound connection from peer `%s' was terminated\n",
894 ps,
895 GNUNET_i2s(&pc->identity));
837#endif 896#endif
838 } 897 }
839 898
840 /* if both connections disconnected, remove session */ 899 /* if both connections disconnected, remove session */
841 if ((ps->send_connected == GNUNET_NO) && (ps->recv_connected == GNUNET_NO)) 900 if ( (ps->send_connected == GNUNET_NO) &&
901 (ps->recv_connected == GNUNET_NO) )
842 { 902 {
843 GNUNET_STATISTICS_update (pc->plugin->env->stats, 903 GNUNET_STATISTICS_update (pc->plugin->env->stats,
844 gettext_noop ("# HTTP inbound sessions for peers active"), 904 gettext_noop ("# HTTP inbound sessions for peers active"),
845 -1, 905 -1,
846 GNUNET_NO); 906 GNUNET_NO);
847 remove_session(pc,ps,GNUNET_YES,GNUNET_SYSERR); 907 remove_session(pc,ps,GNUNET_YES,GNUNET_SYSERR);
848 } 908 }
849} 909}
850 910
911
851/** 912/**
852 * Callback called by MessageStreamTokenizer when a message has arrived 913 * Callback called by MessageStreamTokenizer when a message has arrived
853 * @param cls current session as closure 914 * @param cls current session as closure
854 * @param client clien 915 * @param client clien
855 * @param message the message to be forwarded to transport service 916 * @param message the message to be forwarded to transport service
856 */ 917 */
857 918static void
858static void mhd_write_mst_cb (void *cls, 919mhd_write_mst_cb (void *cls,
859 void *client, 920 void *client,
860 const struct GNUNET_MessageHeader *message) 921 const struct GNUNET_MessageHeader *message)
861{ 922{
923 struct Session *ps = cls;
924 struct HTTP_PeerContext *pc = ps->peercontext;
862 struct GNUNET_TIME_Relative delay; 925 struct GNUNET_TIME_Relative delay;
863 struct Session *ps = cls;
864 GNUNET_assert(ps != NULL);
865 926
866 struct HTTP_PeerContext *pc = ps->peercontext; 927 GNUNET_assert(ps != NULL);
867 GNUNET_assert(pc != NULL); 928 GNUNET_assert(pc != NULL);
868#if DEBUG_HTTP 929#if DEBUG_HTTP
869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 930 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -871,35 +932,39 @@ static void mhd_write_mst_cb (void *cls,
871 ps, 932 ps,
872 ntohs(message->type), 933 ntohs(message->type),
873 ntohs(message->size), 934 ntohs(message->size),
874 GNUNET_i2s(&(ps->peercontext)->identity),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); 935 GNUNET_i2s(&(ps->peercontext)->identity),
936 http_plugin_address_to_string(NULL,ps->addr,ps->addrlen));
875#endif 937#endif
876 struct GNUNET_TRANSPORT_ATS_Information distance[2]; 938 struct GNUNET_TRANSPORT_ATS_Information distance[2];
877 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 939 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
878 distance[0].value = htonl (1); 940 distance[0].value = htonl (1);
879 distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); 941 distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
880 distance[1].value = htonl (0); 942 distance[1].value = htonl (0);
881
882 delay = pc->plugin->env->receive (ps->peercontext->plugin->env->cls, 943 delay = pc->plugin->env->receive (ps->peercontext->plugin->env->cls,
883 &pc->identity, 944 &pc->identity,
884 message, 945 message,
885 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 946 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance,
886 2, 947 2,
887 ps, 948 ps,
888 NULL, 949 NULL,
889 0); 950 0);
890 pc->delay = delay; 951 pc->delay = delay;
891 if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK) 952 if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK)
892 GNUNET_SCHEDULER_cancel (pc->reset_task); 953 GNUNET_SCHEDULER_cancel (pc->reset_task);
893 954
894 if (delay.rel_value > 0) 955 if (delay.rel_value > 0)
895 { 956 {
896#if DEBUG_HTTP 957#if DEBUG_HTTP
897 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.rel_value); 958 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
959 "Connection %X: Inbound quota management: delay next read for %llu ms \n",
960 ps,
961 delay.rel_value);
898#endif 962#endif
899 pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc); 963 pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc);
900 } 964 }
901} 965}
902 966
967
903/** 968/**
904 * Check if incoming connection is accepted. 969 * Check if incoming connection is accepted.
905 * NOTE: Here every connection is accepted 970 * NOTE: Here every connection is accepted
@@ -910,7 +975,9 @@ static void mhd_write_mst_cb (void *cls,
910 * 975 *
911 */ 976 */
912static int 977static int
913mhd_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) 978mhd_accept_cb (void *cls,
979 const struct sockaddr *addr,
980 socklen_t addr_len)
914{ 981{
915#if 0 982#if 0
916 struct Plugin *plugin = cls; 983 struct Plugin *plugin = cls;
@@ -941,42 +1008,48 @@ mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
941 pc = ps->peercontext; 1008 pc = ps->peercontext;
942 msg = ps->pending_msgs_tail; 1009 msg = ps->pending_msgs_tail;
943 if (ps->send_force_disconnect==GNUNET_YES) 1010 if (ps->send_force_disconnect==GNUNET_YES)
944 { 1011 {
945#if DEBUG_CONNECTIONS 1012#if DEBUG_CONNECTIONS
946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound forced to disconnect\n",ps); 1013 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1014 "Connection %X: outbound forced to disconnect\n",
1015 ps);
947#endif 1016#endif
948 return -1; 1017 return -1;
949 }
950
951 if (msg!=NULL)
952 {
953 if ((msg->size-msg->pos) <= max)
954 {
955 memcpy(buf,&msg->buf[msg->pos],(msg->size-msg->pos));
956 bytes_read = msg->size-msg->pos;
957 msg->pos+=(msg->size-msg->pos);
958 } 1018 }
959 else 1019
960 { 1020 if (msg!=NULL)
961 memcpy(buf,&msg->buf[msg->pos],max);
962 msg->pos+=max;
963 bytes_read = max;
964 }
965
966 if (msg->pos==msg->size)
967 { 1021 {
968 if (NULL!=msg->transmit_cont) 1022 if ((msg->size-msg->pos) <= max)
969 msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,GNUNET_OK); 1023 {
970 ps->queue_length_cur -= msg->size; 1024 memcpy(buf,&msg->buf[msg->pos],(msg->size-msg->pos));
971 remove_http_message(ps,msg); 1025 bytes_read = msg->size-msg->pos;
1026 msg->pos+=(msg->size-msg->pos);
1027 }
1028 else
1029 {
1030 memcpy(buf,&msg->buf[msg->pos],max);
1031 msg->pos+=max;
1032 bytes_read = max;
1033 }
1034
1035 if (msg->pos==msg->size)
1036 {
1037 if (NULL!=msg->transmit_cont)
1038 msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1039 ps->queue_length_cur -= msg->size;
1040 remove_http_message(ps,msg);
1041 }
972 } 1042 }
973 }
974#if DEBUG_CONNECTIONS 1043#if DEBUG_CONNECTIONS
975 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: MHD has sent %u bytes\n", ps, bytes_read); 1044 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1045 "Connection %X: MHD has sent %u bytes\n",
1046 ps,
1047 bytes_read);
976#endif 1048#endif
977 return bytes_read; 1049 return bytes_read;
978} 1050}
979 1051
1052
980/** 1053/**
981 * Process GET or PUT request received via MHD. For 1054 * Process GET or PUT request received via MHD. For
982 * GET, queue response that will send back our pending 1055 * GET, queue response that will send back our pending
@@ -986,12 +1059,13 @@ mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
986 */ 1059 */
987static int 1060static int
988mhd_access_cb (void *cls, 1061mhd_access_cb (void *cls,
989 struct MHD_Connection *mhd_connection, 1062 struct MHD_Connection *mhd_connection,
990 const char *url, 1063 const char *url,
991 const char *method, 1064 const char *method,
992 const char *version, 1065 const char *version,
993 const char *upload_data, 1066 const char *upload_data,
994 size_t * upload_data_size, void **httpSessionCache) 1067 size_t * upload_data_size,
1068 void **httpSessionCache)
995{ 1069{
996 struct Plugin *plugin = cls; 1070 struct Plugin *plugin = cls;
997 struct MHD_Response *response; 1071 struct MHD_Response *response;
@@ -999,244 +1073,264 @@ mhd_access_cb (void *cls,
999 const struct sockaddr *client_addr; 1073 const struct sockaddr *client_addr;
1000 const struct sockaddr_in *addrin; 1074 const struct sockaddr_in *addrin;
1001 const struct sockaddr_in6 *addrin6; 1075 const struct sockaddr_in6 *addrin6;
1002
1003 char address[INET6_ADDRSTRLEN+14]; 1076 char address[INET6_ADDRSTRLEN+14];
1004 struct GNUNET_PeerIdentity pi_in; 1077 struct GNUNET_PeerIdentity pi_in;
1005 size_t id_num = 0; 1078 size_t id_num = 0;
1006
1007 struct IPv4HttpAddress ipv4addr; 1079 struct IPv4HttpAddress ipv4addr;
1008 struct IPv6HttpAddress ipv6addr; 1080 struct IPv6HttpAddress ipv6addr;
1009
1010 struct HTTP_PeerContext *pc = NULL; 1081 struct HTTP_PeerContext *pc = NULL;
1011 struct Session *ps = NULL; 1082 struct Session *ps = NULL;
1012 struct Session *ps_tmp = NULL; 1083 struct Session *ps_tmp = NULL;
1013
1014 int res = GNUNET_NO; 1084 int res = GNUNET_NO;
1015 int send_error_to_client;
1016 void * addr = NULL; 1085 void * addr = NULL;
1017 size_t addr_len = 0 ; 1086 size_t addr_len = 0 ;
1018 1087
1019 GNUNET_assert(cls !=NULL); 1088 GNUNET_assert(cls !=NULL);
1020 send_error_to_client = GNUNET_NO;
1021 1089
1022 if (NULL == *httpSessionCache) 1090 if (NULL == *httpSessionCache)
1023 {
1024 /* check url for peer identity , if invalid send HTTP 404*/
1025 size_t len = strlen(&url[1]);
1026 char * peer = GNUNET_malloc(104+1);
1027
1028 if ((len>104) && (url[104]==';'))
1029 { 1091 {
1030 char * id = GNUNET_malloc((len-104)+1); 1092 /* check url for peer identity , if invalid send HTTP 404*/
1031 strcpy(id,&url[105]); 1093 size_t len = strlen(&url[1]);
1032 memcpy(peer,&url[1],103); 1094 char * peer = GNUNET_malloc(104+1);
1033 peer[103] = '\0'; 1095
1096 if ( (len>104) && (url[104]==';'))
1097 {
1098 char * id = GNUNET_malloc((len-104)+1);
1099 strcpy(id,&url[105]);
1100 memcpy(peer,&url[1],103);
1101 peer[103] = '\0';
1034 id_num = strtoul ( id, NULL , 10); 1102 id_num = strtoul ( id, NULL , 10);
1035 GNUNET_free(id); 1103 GNUNET_free(id);
1036 } 1104 }
1037 res = GNUNET_CRYPTO_hash_from_string (peer, &(pi_in.hashPubKey)); 1105 res = GNUNET_CRYPTO_hash_from_string (peer, &(pi_in.hashPubKey));
1038 GNUNET_free(peer); 1106 GNUNET_free(peer);
1039 if ( GNUNET_SYSERR == res ) 1107 if ( GNUNET_SYSERR == res )
1040 { 1108 {
1041 response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); 1109 response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),
1042 res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); 1110 HTTP_ERROR_RESPONSE,
1043 MHD_destroy_response (response); 1111 MHD_NO, MHD_NO);
1112 res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response);
1113 MHD_destroy_response (response);
1044#if DEBUG_CONNECTIONS 1114#if DEBUG_CONNECTIONS
1045 if (res == MHD_YES) 1115 if (res == MHD_YES)
1046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Peer has no valid ident, sent HTTP 1.1/404\n"); 1116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1117 "Peer has no valid ident, sent HTTP 1.1/404\n");
1047 else 1118 else
1048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Peer has no valid ident, could not send error\n"); 1119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1120 "Peer has no valid ident, could not send error\n");
1049#endif 1121#endif
1050 return res; 1122 return res;
1123 }
1051 } 1124 }
1052 }
1053 else 1125 else
1054 {
1055 ps = *httpSessionCache;
1056 pc = ps->peercontext;
1057 }
1058
1059 if (NULL == *httpSessionCache)
1060 {
1061 /* get peer context */
1062 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &pi_in.hashPubKey);
1063 /* Peer unknown */
1064 if (pc==NULL)
1065 {
1066 pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext));
1067 pc->plugin = plugin;
1068 pc->session_id_counter=1;
1069 pc->last_session = NULL;
1070 memcpy(&pc->identity, &pi_in, sizeof(struct GNUNET_PeerIdentity));
1071 GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1072 GNUNET_STATISTICS_update (plugin->env->stats,
1073 gettext_noop ("# HTTP peers active"),
1074 1,
1075 GNUNET_NO);
1076 }
1077
1078 conn_info = MHD_get_connection_info(mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS );
1079 /* Incoming IPv4 connection */
1080 /* cast required for legacy MHD API < 0.9.6 */
1081 client_addr = (const struct sockaddr *) conn_info->client_addr;
1082 if ( AF_INET == client_addr->sa_family)
1083 { 1126 {
1084 addrin = (const struct sockaddr_in*) client_addr; 1127 ps = *httpSessionCache;
1085 inet_ntop(addrin->sin_family, &(addrin->sin_addr),address,INET_ADDRSTRLEN); 1128 pc = ps->peercontext;
1086 memcpy(&ipv4addr.ipv4_addr,&(addrin->sin_addr),sizeof(struct in_addr));
1087 ipv4addr.u_port = addrin->sin_port;
1088 addr = &ipv4addr;
1089 addr_len = sizeof(struct IPv4HttpAddress);
1090 } 1129 }
1091 /* Incoming IPv6 connection */ 1130
1092 if ( AF_INET6 == client_addr->sa_family) 1131 if (NULL == *httpSessionCache)
1093 { 1132 {
1094 addrin6 = (const struct sockaddr_in6 *) client_addr; 1133 /* get peer context */
1095 inet_ntop(addrin6->sin6_family, &(addrin6->sin6_addr),address,INET6_ADDRSTRLEN); 1134 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &pi_in.hashPubKey);
1096 memcpy(&ipv6addr.ipv6_addr,&(addrin6->sin6_addr),sizeof(struct in6_addr)); 1135 /* Peer unknown */
1097 ipv6addr.u6_port = addrin6->sin6_port; 1136 if (pc==NULL)
1098 addr = &ipv6addr; 1137 {
1099 addr_len = sizeof(struct IPv6HttpAddress); 1138 pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext));
1100 } 1139 pc->plugin = plugin;
1101 1140 pc->session_id_counter=1;
1102 GNUNET_assert (addr != NULL); 1141 pc->last_session = NULL;
1103 GNUNET_assert (addr_len != 0); 1142 memcpy(&pc->identity, &pi_in, sizeof(struct GNUNET_PeerIdentity));
1104 1143 GNUNET_CONTAINER_multihashmap_put(plugin->peers,
1105 ps = NULL; 1144 &pc->identity.hashPubKey,
1106 /* only inbound sessions here */ 1145 pc,
1146 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1147 GNUNET_STATISTICS_update (plugin->env->stats,
1148 gettext_noop ("# HTTP peers active"),
1149 1,
1150 GNUNET_NO);
1151 }
1107 1152
1108 ps_tmp = pc->head; 1153 conn_info = MHD_get_connection_info(mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS );
1109 while (ps_tmp!=NULL) 1154 /* Incoming IPv4 connection */
1110 { 1155 /* cast required for legacy MHD API < 0.9.6 */
1111 if ((ps_tmp->direction==INBOUND) && (ps_tmp->session_id == id_num) && (id_num!=0)) 1156 client_addr = (const struct sockaddr *) conn_info->client_addr;
1112 { 1157 if ( AF_INET == client_addr->sa_family)
1113 if ((ps_tmp->recv_force_disconnect!=GNUNET_YES) && (ps_tmp->send_force_disconnect!=GNUNET_YES)) 1158 {
1114 ps=ps_tmp; 1159 addrin = (const struct sockaddr_in*) client_addr;
1115 break; 1160 inet_ntop(addrin->sin_family, &(addrin->sin_addr),address,INET_ADDRSTRLEN);
1116 } 1161 memcpy(&ipv4addr.ipv4_addr,&(addrin->sin_addr),sizeof(struct in_addr));
1117 ps_tmp=ps_tmp->next; 1162 ipv4addr.u_port = addrin->sin_port;
1118 } 1163 addr = &ipv4addr;
1119 1164 addr_len = sizeof(struct IPv4HttpAddress);
1120 if (ps==NULL) 1165 }
1121 { 1166 /* Incoming IPv6 connection */
1122 ps = GNUNET_malloc(sizeof (struct Session)); 1167 if ( AF_INET6 == client_addr->sa_family)
1123 ps->addr = GNUNET_malloc(addr_len); 1168 {
1124 memcpy(ps->addr,addr,addr_len); 1169 addrin6 = (const struct sockaddr_in6 *) client_addr;
1125 ps->addrlen = addr_len; 1170 inet_ntop(addrin6->sin6_family, &(addrin6->sin6_addr),address,INET6_ADDRSTRLEN);
1126 ps->direction=INBOUND; 1171 memcpy(&ipv6addr.ipv6_addr,&(addrin6->sin6_addr),sizeof(struct in6_addr));
1127 ps->pending_msgs_head = NULL; 1172 ipv6addr.u6_port = addrin6->sin6_port;
1128 ps->pending_msgs_tail = NULL; 1173 addr = &ipv6addr;
1129 ps->send_connected=GNUNET_NO; 1174 addr_len = sizeof(struct IPv6HttpAddress);
1130 ps->send_active=GNUNET_NO; 1175 }
1131 ps->recv_connected=GNUNET_NO; 1176
1132 ps->recv_active=GNUNET_NO; 1177 GNUNET_assert (addr != NULL);
1133 ps->peercontext=pc; 1178 GNUNET_assert (addr_len != 0);
1134 ps->session_id =id_num; 1179
1180 ps = NULL;
1181 /* only inbound sessions here */
1182
1183 ps_tmp = pc->head;
1184 while (ps_tmp!=NULL)
1185 {
1186 if ((ps_tmp->direction==INBOUND) && (ps_tmp->session_id == id_num) && (id_num!=0))
1187 {
1188 if ((ps_tmp->recv_force_disconnect!=GNUNET_YES) && (ps_tmp->send_force_disconnect!=GNUNET_YES))
1189 ps=ps_tmp;
1190 break;
1191 }
1192 ps_tmp=ps_tmp->next;
1193 }
1194
1195 if (ps==NULL)
1196 {
1197 ps = GNUNET_malloc(sizeof (struct Session));
1198 ps->addr = GNUNET_malloc(addr_len);
1199 memcpy(ps->addr,addr,addr_len);
1200 ps->addrlen = addr_len;
1201 ps->direction=INBOUND;
1202 ps->pending_msgs_head = NULL;
1203 ps->pending_msgs_tail = NULL;
1204 ps->send_connected=GNUNET_NO;
1205 ps->send_active=GNUNET_NO;
1206 ps->recv_connected=GNUNET_NO;
1207 ps->recv_active=GNUNET_NO;
1208 ps->peercontext=pc;
1209 ps->session_id =id_num;
1135 ps->queue_length_cur = 0; 1210 ps->queue_length_cur = 0;
1136 ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE; 1211 ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE;
1137 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); 1212 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id);
1138 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); 1213 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps);
1139 GNUNET_STATISTICS_update (plugin->env->stats, 1214 GNUNET_STATISTICS_update (plugin->env->stats,
1140 gettext_noop ("# HTTP inbound sessions for peers active"), 1215 gettext_noop ("# HTTP inbound sessions for peers active"),
1141 1, 1216 1,
1142 GNUNET_NO); 1217 GNUNET_NO);
1143 } 1218 }
1144 1219
1145 *httpSessionCache = ps; 1220 *httpSessionCache = ps;
1146 if (ps->msgtok==NULL) 1221 if (ps->msgtok==NULL)
1147 ps->msgtok = GNUNET_SERVER_mst_create (&mhd_write_mst_cb, ps); 1222 ps->msgtok = GNUNET_SERVER_mst_create (&mhd_write_mst_cb, ps);
1148#if DEBUG_HTTP 1223#if DEBUG_HTTP
1149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: HTTP Daemon has new an incoming `%s' request from peer `%s' (`%s')\n", 1224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1150 ps, 1225 "Connection %X: HTTP Daemon has new an incoming `%s' request from peer `%s' (`%s')\n",
1151 method, 1226 ps,
1152 GNUNET_i2s(&pc->identity), 1227 method,
1153 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen)); 1228 GNUNET_i2s(&pc->identity),
1229 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen));
1154#endif 1230#endif
1155 } 1231 }
1156 1232
1157 /* Is it a PUT or a GET request */ 1233 /* Is it a PUT or a GET request */
1158 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) 1234 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method))
1159 {
1160 if (ps->recv_force_disconnect == GNUNET_YES)
1161 { 1235 {
1236 if (ps->recv_force_disconnect == GNUNET_YES)
1237 {
1162#if DEBUG_CONNECTIONS 1238#if DEBUG_CONNECTIONS
1163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound connection was forced to disconnect\n",ps); 1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "Connection %X: inbound connection was forced to disconnect\n",ps);
1164#endif 1241#endif
1165 ps->recv_active = GNUNET_NO; 1242 ps->recv_active = GNUNET_NO;
1166 return MHD_NO; 1243 return MHD_NO;
1167 } 1244 }
1168 if ((*upload_data_size == 0) && (ps->recv_active==GNUNET_NO)) 1245 if ((*upload_data_size == 0) && (ps->recv_active==GNUNET_NO))
1169 { 1246 {
1170 ps->recv_endpoint = mhd_connection; 1247 ps->recv_endpoint = mhd_connection;
1171 ps->recv_connected = GNUNET_YES; 1248 ps->recv_connected = GNUNET_YES;
1172 ps->recv_active = GNUNET_YES; 1249 ps->recv_active = GNUNET_YES;
1173 ps->recv_force_disconnect = GNUNET_NO; 1250 ps->recv_force_disconnect = GNUNET_NO;
1174#if DEBUG_CONNECTIONS 1251#if DEBUG_CONNECTIONS
1175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound PUT connection connected\n",ps); 1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1253 "Connection %X: inbound PUT connection connected\n",ps);
1176#endif 1254#endif
1177 return MHD_YES; 1255 return MHD_YES;
1178 } 1256 }
1179 1257
1180 /* Transmission of all data complete */ 1258 /* Transmission of all data complete */
1181 if ((*upload_data_size == 0) && (ps->recv_active == GNUNET_YES)) 1259 if ((*upload_data_size == 0) && (ps->recv_active == GNUNET_YES))
1182 { 1260 {
1183 response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); 1261 response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),
1184 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1262 HTTP_PUT_RESPONSE,
1263 MHD_NO, MHD_NO);
1264 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1185#if DEBUG_CONNECTIONS 1265#if DEBUG_CONNECTIONS
1186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Sent HTTP/1.1: 200 OK as PUT Response\n",ps); 1266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1267 "Connection %X: Sent HTTP/1.1: 200 OK as PUT Response\n",
1268 ps);
1187#endif 1269#endif
1188 MHD_destroy_response (response); 1270 MHD_destroy_response (response);
1189 ps->recv_active=GNUNET_NO; 1271 ps->recv_active=GNUNET_NO;
1190 return MHD_YES; 1272 return MHD_YES;
1191 } 1273 }
1192 1274
1193 /* Recieving data */ 1275 /* Recieving data */
1194 if ((*upload_data_size > 0) && (ps->recv_active == GNUNET_YES)) 1276 if ((*upload_data_size > 0) && (ps->recv_active == GNUNET_YES))
1195 { 1277 {
1196 if (pc->delay.rel_value == 0) 1278 if (pc->delay.rel_value == 0)
1197 { 1279 {
1198#if DEBUG_HTTP 1280#if DEBUG_HTTP
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: PUT with %u bytes forwarded to MST\n", ps, *upload_data_size); 1281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1200#endif 1282 "Connection %X: PUT with %u bytes forwarded to MST\n",
1201 res = GNUNET_SERVER_mst_receive(ps->msgtok, ps, upload_data, *upload_data_size, GNUNET_NO, GNUNET_NO); 1283 ps, *upload_data_size);
1202 (*upload_data_size) = 0; 1284#endif
1203 } 1285 res = GNUNET_SERVER_mst_receive(ps->msgtok, ps,
1204 else 1286 upload_data, *upload_data_size,
1205 { 1287 GNUNET_NO, GNUNET_NO);
1288 (*upload_data_size) = 0;
1289 }
1290 else
1291 {
1206#if DEBUG_HTTP 1292#if DEBUG_HTTP
1207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: no inbound bandwidth available! Next read was delayed for %llu ms\n", ps, ps->peercontext->delay.rel_value); 1293 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1294 "Connection %X: no inbound bandwidth available! Next read was delayed for %llu ms\n",
1295 ps,
1296 ps->peercontext->delay.rel_value);
1208#endif 1297#endif
1209 } 1298 }
1210 return MHD_YES; 1299 return MHD_YES;
1300 }
1301 else
1302 return MHD_NO;
1211 } 1303 }
1212 else
1213 return MHD_NO;
1214 }
1215 if ( 0 == strcmp (MHD_HTTP_METHOD_GET, method) ) 1304 if ( 0 == strcmp (MHD_HTTP_METHOD_GET, method) )
1216 {
1217 if (ps->send_force_disconnect == GNUNET_YES)
1218 { 1305 {
1306 if (ps->send_force_disconnect == GNUNET_YES)
1307 {
1219#if DEBUG_CONNECTIONS 1308#if DEBUG_CONNECTIONS
1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound connection was forced to disconnect\n",ps); 1309 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1310 "Connection %X: outbound connection was forced to disconnect\n",
1311 ps);
1221#endif 1312#endif
1222 ps->send_active = GNUNET_NO; 1313 ps->send_active = GNUNET_NO;
1223 return MHD_NO; 1314 return MHD_NO;
1224 } 1315 }
1225 ps->send_connected = GNUNET_YES; 1316 ps->send_connected = GNUNET_YES;
1226 ps->send_active = GNUNET_YES; 1317 ps->send_active = GNUNET_YES;
1227 ps->send_endpoint = mhd_connection; 1318 ps->send_endpoint = mhd_connection;
1228 ps->send_force_disconnect = GNUNET_NO; 1319 ps->send_force_disconnect = GNUNET_NO;
1229#if DEBUG_CONNECTIONS 1320#if DEBUG_CONNECTIONS
1230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound GET connection connected\n",ps); 1321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1322 "Connection %X: inbound GET connection connected\n",
1323 ps);
1231#endif 1324#endif
1232 response = MHD_create_response_from_callback(-1,32 * 1024, &mhd_send_callback, ps, NULL); 1325 response = MHD_create_response_from_callback(-1,32 * 1024, &mhd_send_callback, ps, NULL);
1233 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1326 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1234 MHD_destroy_response (response); 1327 MHD_destroy_response (response);
1235 return MHD_YES; 1328 return MHD_YES;
1236 } 1329 }
1237 return MHD_NO; 1330 return MHD_NO;
1238} 1331}
1239 1332
1333
1240/** 1334/**
1241 * Function that queries MHD's select sets and 1335 * Function that queries MHD's select sets and
1242 * starts the task waiting for them. 1336 * starts the task waiting for them.
@@ -1245,7 +1339,8 @@ mhd_access_cb (void *cls,
1245 * @return gnunet task identifier 1339 * @return gnunet task identifier
1246 */ 1340 */
1247static GNUNET_SCHEDULER_TaskIdentifier 1341static GNUNET_SCHEDULER_TaskIdentifier
1248http_server_daemon_prepare (struct Plugin *plugin , struct MHD_Daemon *daemon_handle) 1342http_server_daemon_prepare (struct Plugin *plugin,
1343 struct MHD_Daemon *daemon_handle)
1249{ 1344{
1250 GNUNET_SCHEDULER_TaskIdentifier ret; 1345 GNUNET_SCHEDULER_TaskIdentifier ret;
1251 fd_set rs; 1346 fd_set rs;
@@ -1282,65 +1377,72 @@ http_server_daemon_prepare (struct Plugin *plugin , struct MHD_Daemon *daemon_ha
1282 GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); 1377 GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
1283 GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); 1378 GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1);
1284 if (daemon_handle == plugin->http_server_daemon_v4) 1379 if (daemon_handle == plugin->http_server_daemon_v4)
1285 { 1380 {
1286 if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) 1381 if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK)
1287 { 1382 {
1288 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4); 1383 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4);
1289 plugin->http_server_daemon_v4 = GNUNET_SCHEDULER_NO_TASK; 1384 plugin->http_server_daemon_v4 = GNUNET_SCHEDULER_NO_TASK;
1290 } 1385 }
1291 1386
1292 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1387 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1293 GNUNET_SCHEDULER_NO_TASK, 1388 GNUNET_SCHEDULER_NO_TASK,
1294 tv, 1389 tv,
1295 wrs, 1390 wrs,
1296 wws, 1391 wws,
1297 &http_server_daemon_v4_run, 1392 &http_server_daemon_v4_run,
1298 plugin); 1393 plugin);
1299 } 1394 }
1300 if (daemon_handle == plugin->http_server_daemon_v6) 1395 if (daemon_handle == plugin->http_server_daemon_v6)
1301 { 1396 {
1302 if (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) 1397 if (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK)
1303 { 1398 {
1304 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6); 1399 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6);
1305 plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK; 1400 plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK;
1306 } 1401 }
1307 1402
1308 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1403 ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1309 GNUNET_SCHEDULER_NO_TASK, 1404 GNUNET_SCHEDULER_NO_TASK,
1310 tv, 1405 tv,
1311 wrs, 1406 wrs,
1312 wws, 1407 wws,
1313 &http_server_daemon_v6_run, 1408 &http_server_daemon_v6_run,
1314 plugin); 1409 plugin);
1315 } 1410 }
1316 GNUNET_NETWORK_fdset_destroy (wrs); 1411 GNUNET_NETWORK_fdset_destroy (wrs);
1317 GNUNET_NETWORK_fdset_destroy (wws); 1412 GNUNET_NETWORK_fdset_destroy (wws);
1318 GNUNET_NETWORK_fdset_destroy (wes); 1413 GNUNET_NETWORK_fdset_destroy (wes);
1319 return ret; 1414 return ret;
1320} 1415}
1321 1416
1417
1322/** 1418/**
1323 * Call MHD IPv4 to process pending requests and then go back 1419 * Call MHD IPv4 to process pending requests and then go back
1324 * and schedule the next run. 1420 * and schedule the next run.
1325 * @param cls plugin as closure 1421 * @param cls plugin as closure
1326 * @param tc task context 1422 * @param tc task context
1327 */ 1423 */
1328static void http_server_daemon_v4_run (void *cls, 1424static void
1329 const struct GNUNET_SCHEDULER_TaskContext *tc) 1425http_server_daemon_v4_run (void *cls,
1426 const struct GNUNET_SCHEDULER_TaskContext *tc)
1330{ 1427{
1331 struct Plugin *plugin = cls; 1428 struct Plugin *plugin = cls;
1332 1429
1333#if DEBUG_SCHEDULING 1430#if DEBUG_SCHEDULING
1334 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 1431 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
1335 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_READ_READY\n"); 1432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1433 "http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_READ_READY\n");
1336 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) 1434 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n"); 1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1436 "http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n");
1338 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) 1437 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n"); 1438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1439 "http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n");
1340 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP)) 1440 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP))
1341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_STARTUP\n"); 1441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1442 "http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_STARTUP\n");
1342 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 1443 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n"); 1444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1445 "http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n");
1344#endif 1446#endif
1345 1447
1346 GNUNET_assert(cls !=NULL); 1448 GNUNET_assert(cls !=NULL);
@@ -1360,22 +1462,28 @@ static void http_server_daemon_v4_run (void *cls,
1360 * @param cls plugin as closure 1462 * @param cls plugin as closure
1361 * @param tc task context 1463 * @param tc task context
1362 */ 1464 */
1363static void http_server_daemon_v6_run (void *cls, 1465static void
1364 const struct GNUNET_SCHEDULER_TaskContext *tc) 1466http_server_daemon_v6_run (void *cls,
1467 const struct GNUNET_SCHEDULER_TaskContext *tc)
1365{ 1468{
1366 struct Plugin *plugin = cls; 1469 struct Plugin *plugin = cls;
1367 1470
1368#if DEBUG_SCHEDULING 1471#if DEBUG_SCHEDULING
1369 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 1472 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
1370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_READ_READY\n"); 1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1474 "http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_READ_READY\n");
1371 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) 1475 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n"); 1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1477 "http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n");
1373 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) 1478 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n"); 1479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1480 "http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n");
1375 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP)) 1481 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP))
1376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_STARTUP\n"); 1482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1483 "http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_STARTUP\n");
1377 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 1484 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n"); 1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1486 "http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n");
1379#endif 1487#endif
1380 1488
1381 GNUNET_assert(cls !=NULL); 1489 GNUNET_assert(cls !=NULL);
@@ -1388,7 +1496,11 @@ static void http_server_daemon_v6_run (void *cls,
1388 plugin->http_server_task_v6 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v6); 1496 plugin->http_server_task_v6 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v6);
1389} 1497}
1390 1498
1391static size_t curl_get_header_cb( void *ptr, size_t size, size_t nmemb, void *stream) 1499
1500static size_t
1501curl_get_header_cb( void *ptr,
1502 size_t size, size_t nmemb,
1503 void *stream)
1392{ 1504{
1393 struct Session * ps = stream; 1505 struct Session * ps = stream;
1394 1506
@@ -1397,23 +1509,23 @@ static size_t curl_get_header_cb( void *ptr, size_t size, size_t nmemb, void *st
1397 /* Getting last http result code */ 1509 /* Getting last http result code */
1398 GNUNET_assert(NULL!=ps); 1510 GNUNET_assert(NULL!=ps);
1399 if (ps->recv_connected==GNUNET_NO) 1511 if (ps->recv_connected==GNUNET_NO)
1400 {
1401 res = curl_easy_getinfo(ps->recv_endpoint, CURLINFO_RESPONSE_CODE, &http_result);
1402 if (CURLE_OK == res)
1403 { 1512 {
1404 if (http_result == 200) 1513 res = curl_easy_getinfo(ps->recv_endpoint, CURLINFO_RESPONSE_CODE, &http_result);
1405 { 1514 if (CURLE_OK == res)
1406 ps->recv_connected = GNUNET_YES; 1515 {
1407 ps->recv_active = GNUNET_YES; 1516 if (http_result == 200)
1517 {
1518 ps->recv_connected = GNUNET_YES;
1519 ps->recv_active = GNUNET_YES;
1408#if DEBUG_CONNECTIONS 1520#if DEBUG_CONNECTIONS
1409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: connected to recieve data\n",ps); 1521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: connected to recieve data\n",ps);
1410#endif 1522#endif
1411 // Calling send_check_connections again since receive is established 1523 // Calling send_check_connections again since receive is established
1412 send_check_connections (ps->peercontext->plugin, ps); 1524 send_check_connections (ps->peercontext->plugin, ps);
1413 } 1525 }
1526 }
1414 } 1527 }
1415 } 1528
1416
1417#if DEBUG_CURL 1529#if DEBUG_CURL
1418 char * tmp; 1530 char * tmp;
1419 size_t len = size * nmemb; 1531 size_t len = size * nmemb;
@@ -1422,21 +1534,24 @@ static size_t curl_get_header_cb( void *ptr, size_t size, size_t nmemb, void *st
1422 tmp = GNUNET_malloc (len+1); 1534 tmp = GNUNET_malloc (len+1);
1423 1535
1424 if ((tmp != NULL) && (len > 0)) 1536 if ((tmp != NULL) && (len > 0))
1425 {
1426 memcpy(tmp,ptr,len);
1427 if (len>=2)
1428 { 1537 {
1429 if (tmp[len-2] == 13) 1538 memcpy(tmp,ptr,len);
1430 tmp[len-2]= '\0'; 1539 if (len>=2)
1540 {
1541 if (tmp[len-2] == 13)
1542 tmp[len-2]= '\0';
1543 }
1544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1545 "Connection %X: Header: %s\n",
1546 ps, tmp);
1431 } 1547 }
1432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Header: %s\n",ps,tmp);
1433 }
1434 GNUNET_free_non_null (tmp); 1548 GNUNET_free_non_null (tmp);
1435#endif 1549#endif
1436 1550
1437 return size * nmemb; 1551 return size * nmemb;
1438} 1552}
1439 1553
1554
1440/** 1555/**
1441 * Callback called by libcurl when new headers arrive 1556 * Callback called by libcurl when new headers arrive
1442 * Used to get HTTP result for curl operations 1557 * Used to get HTTP result for curl operations
@@ -1446,8 +1561,11 @@ static size_t curl_get_header_cb( void *ptr, size_t size, size_t nmemb, void *st
1446 * @param stream closure set by user 1561 * @param stream closure set by user
1447 * @return bytes read by function 1562 * @return bytes read by function
1448 */ 1563 */
1449 1564static size_t
1450static size_t curl_put_header_cb( void *ptr, size_t size, size_t nmemb, void *stream) 1565curl_put_header_cb(void *ptr,
1566 size_t size,
1567 size_t nmemb,
1568 void *stream)
1451{ 1569{
1452 struct Session * ps = stream; 1570 struct Session * ps = stream;
1453 1571
@@ -1458,43 +1576,45 @@ static size_t curl_put_header_cb( void *ptr, size_t size, size_t nmemb, void *st
1458 1576
1459 /* Getting last http result code */ 1577 /* Getting last http result code */
1460 GNUNET_assert(NULL!=ps); 1578 GNUNET_assert(NULL!=ps);
1461 res = curl_easy_getinfo(ps->send_endpoint, CURLINFO_RESPONSE_CODE, &http_result); 1579 res = curl_easy_getinfo (ps->send_endpoint, CURLINFO_RESPONSE_CODE, &http_result);
1462 if (CURLE_OK == res) 1580 if (CURLE_OK == res)
1463 {
1464 if ((http_result == 100) && (ps->send_connected==GNUNET_NO))
1465 { 1581 {
1466 ps->send_connected = GNUNET_YES; 1582 if ((http_result == 100) && (ps->send_connected==GNUNET_NO))
1467 ps->send_active = GNUNET_YES; 1583 {
1584 ps->send_connected = GNUNET_YES;
1585 ps->send_active = GNUNET_YES;
1468#if DEBUG_CONNECTIONS 1586#if DEBUG_CONNECTIONS
1469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: connected to send data\n",ps); 1587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1588 "Connection %X: connected to send data\n",
1589 ps);
1470#endif 1590#endif
1471 } 1591 }
1472 if ((http_result == 200) && (ps->send_connected==GNUNET_YES)) 1592 if ((http_result == 200) && (ps->send_connected==GNUNET_YES))
1473 { 1593 {
1474 ps->send_connected = GNUNET_NO; 1594 ps->send_connected = GNUNET_NO;
1475 ps->send_active = GNUNET_NO; 1595 ps->send_active = GNUNET_NO;
1476#if DEBUG_CONNECTIONS 1596#if DEBUG_CONNECTIONS
1477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: sending disconnected\n",ps); 1597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1598 "Connection %X: sending disconnected\n",
1599 ps);
1478#endif 1600#endif
1601 }
1479 } 1602 }
1480 } 1603
1481
1482 tmp = NULL; 1604 tmp = NULL;
1483 if ((size * nmemb) < SIZE_MAX) 1605 if ((size * nmemb) < SIZE_MAX)
1484 tmp = GNUNET_malloc (len+1); 1606 tmp = GNUNET_malloc (len+1);
1485 1607
1486 if ((tmp != NULL) && (len > 0)) 1608 if ((tmp != NULL) && (len > 0))
1487 {
1488 memcpy(tmp,ptr,len);
1489 if (len>=2)
1490 { 1609 {
1491 if (tmp[len-2] == 13) 1610 memcpy(tmp,ptr,len);
1492 tmp[len-2]= '\0'; 1611 if (len>=2)
1612 {
1613 if (tmp[len-2] == 13)
1614 tmp[len-2]= '\0';
1615 }
1493 } 1616 }
1494 }
1495
1496 GNUNET_free_non_null (tmp); 1617 GNUNET_free_non_null (tmp);
1497
1498 return size * nmemb; 1618 return size * nmemb;
1499} 1619}
1500 1620
@@ -1507,7 +1627,10 @@ static size_t curl_put_header_cb( void *ptr, size_t size, size_t nmemb, void *st
1507 * @param ptr source pointer, passed to the libcurl handle 1627 * @param ptr source pointer, passed to the libcurl handle
1508 * @return bytes written to stream 1628 * @return bytes written to stream
1509 */ 1629 */
1510static size_t curl_send_cb(void *stream, size_t size, size_t nmemb, void *ptr) 1630static size_t
1631curl_send_cb(void *stream,
1632 size_t size, size_t nmemb,
1633 void *ptr)
1511{ 1634{
1512 struct Session * ps = ptr; 1635 struct Session * ps = ptr;
1513 struct HTTP_Message * msg = ps->pending_msgs_tail; 1636 struct HTTP_Message * msg = ps->pending_msgs_tail;
@@ -1515,63 +1638,70 @@ static size_t curl_send_cb(void *stream, size_t size, size_t nmemb, void *ptr)
1515 size_t len; 1638 size_t len;
1516 1639
1517 if (ps->send_active == GNUNET_NO) 1640 if (ps->send_active == GNUNET_NO)
1518 { 1641 return CURL_READFUNC_PAUSE;
1519 return CURL_READFUNC_PAUSE; 1642 if ( (ps->pending_msgs_tail == NULL) &&
1520 } 1643 (ps->send_active == GNUNET_YES) )
1521 1644 {
1522 if ((ps->pending_msgs_tail == NULL) && (ps->send_active == GNUNET_YES))
1523 {
1524#if DEBUG_CONNECTIONS 1645#if DEBUG_CONNECTIONS
1525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: No Message to send, pausing connection\n",ps); 1646 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1647 "Connection %X: No Message to send, pausing connection\n",
1648 ps);
1526#endif 1649#endif
1527 ps->send_active = GNUNET_NO; 1650 ps->send_active = GNUNET_NO;
1528 return CURL_READFUNC_PAUSE; 1651 return CURL_READFUNC_PAUSE;
1529 } 1652 }
1530 1653
1531 GNUNET_assert (msg!=NULL); 1654 GNUNET_assert (msg!=NULL);
1532 1655
1533 /* data to send */ 1656 /* data to send */
1534 if (msg->pos < msg->size) 1657 if (msg->pos < msg->size)
1535 {
1536 /* data fit in buffer */
1537 if ((msg->size - msg->pos) <= (size * nmemb))
1538 {
1539 len = (msg->size - msg->pos);
1540 memcpy(stream, &msg->buf[msg->pos], len);
1541 msg->pos += len;
1542 bytes_sent = len;
1543 }
1544 else
1545 { 1658 {
1546 len = size*nmemb; 1659 /* data fit in buffer */
1547 memcpy(stream, &msg->buf[msg->pos], len); 1660 if ((msg->size - msg->pos) <= (size * nmemb))
1548 msg->pos += len; 1661 {
1549 bytes_sent = len; 1662 len = (msg->size - msg->pos);
1663 memcpy(stream, &msg->buf[msg->pos], len);
1664 msg->pos += len;
1665 bytes_sent = len;
1666 }
1667 else
1668 {
1669 len = size*nmemb;
1670 memcpy(stream, &msg->buf[msg->pos], len);
1671 msg->pos += len;
1672 bytes_sent = len;
1673 }
1550 } 1674 }
1551 }
1552 /* no data to send */ 1675 /* no data to send */
1553 else 1676 else
1554 { 1677 {
1555 bytes_sent = 0; 1678 bytes_sent = 0;
1556 } 1679 }
1557 1680
1558 if ( msg->pos == msg->size) 1681 if ( msg->pos == msg->size)
1559 { 1682 {
1560#if DEBUG_CONNECTIONS 1683#if DEBUG_CONNECTIONS
1561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Message with %u bytes sent, removing message from queue \n",ps, msg->pos); 1684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1562#endif 1685 "Connection %X: Message with %u bytes sent, removing message from queue\n",
1563 /* Calling transmit continuation */ 1686 ps,
1564 if (NULL != ps->pending_msgs_tail->transmit_cont) 1687 msg->pos);
1565 msg->transmit_cont (ps->pending_msgs_tail->transmit_cont_cls,&(ps->peercontext)->identity,GNUNET_OK); 1688#endif
1566 ps->queue_length_cur -= msg->size; 1689 /* Calling transmit continuation */
1567 remove_http_message(ps, msg); 1690 if (NULL != ps->pending_msgs_tail->transmit_cont)
1568 } 1691 msg->transmit_cont (ps->pending_msgs_tail->transmit_cont_cls,
1692 &(ps->peercontext)->identity,
1693 GNUNET_OK);
1694 ps->queue_length_cur -= msg->size;
1695 remove_http_message(ps, msg);
1696 }
1569 return bytes_sent; 1697 return bytes_sent;
1570} 1698}
1571 1699
1572static void curl_receive_mst_cb (void *cls, 1700
1573 void *client, 1701static void
1574 const struct GNUNET_MessageHeader *message) 1702curl_receive_mst_cb (void *cls,
1703 void *client,
1704 const struct GNUNET_MessageHeader *message)
1575{ 1705{
1576 struct Session *ps = cls; 1706 struct Session *ps = cls;
1577 struct GNUNET_TIME_Relative delay; 1707 struct GNUNET_TIME_Relative delay;
@@ -1585,7 +1715,8 @@ static void curl_receive_mst_cb (void *cls,
1585 ps, 1715 ps,
1586 ntohs(message->type), 1716 ntohs(message->type),
1587 ntohs(message->size), 1717 ntohs(message->size),
1588 GNUNET_i2s(&(pc->identity)),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); 1718 GNUNET_i2s(&(pc->identity)),
1719 http_plugin_address_to_string(NULL,ps->addr,ps->addrlen));
1589#endif 1720#endif
1590 struct GNUNET_TRANSPORT_ATS_Information distance[2]; 1721 struct GNUNET_TRANSPORT_ATS_Information distance[2];
1591 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 1722 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
@@ -1594,24 +1725,25 @@ static void curl_receive_mst_cb (void *cls,
1594 distance[1].value = htonl (0); 1725 distance[1].value = htonl (0);
1595 1726
1596 delay = pc->plugin->env->receive (pc->plugin->env->cls, 1727 delay = pc->plugin->env->receive (pc->plugin->env->cls,
1597 &pc->identity, 1728 &pc->identity,
1598 message, 1729 message,
1599 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2, 1730 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2,
1600 ps, 1731 ps,
1601 ps->addr, 1732 ps->addr,
1602 ps->addrlen); 1733 ps->addrlen);
1603
1604 pc->delay = delay; 1734 pc->delay = delay;
1605 if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK) 1735 if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK)
1606 GNUNET_SCHEDULER_cancel (pc->reset_task); 1736 GNUNET_SCHEDULER_cancel (pc->reset_task);
1607 1737
1608 if (delay.rel_value > 0) 1738 if (delay.rel_value > 0)
1609 { 1739 {
1610#if DEBUG_HTTP 1740#if DEBUG_HTTP
1611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.rel_value); 1741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1742 "Connection %X: Inbound quota management: delay next read for %llu ms\n",
1743 ps, delay.rel_value);
1612#endif 1744#endif
1613 pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc); 1745 pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc);
1614 } 1746 }
1615} 1747}
1616 1748
1617 1749
@@ -1624,165 +1756,170 @@ static void curl_receive_mst_cb (void *cls,
1624* @param ptr destination pointer, passed to the libcurl handle 1756* @param ptr destination pointer, passed to the libcurl handle
1625* @return bytes read from stream 1757* @return bytes read from stream
1626*/ 1758*/
1627static size_t curl_receive_cb( void *stream, size_t size, size_t nmemb, void *ptr) 1759static size_t
1760curl_receive_cb( void *stream, size_t size, size_t nmemb, void *ptr)
1628{ 1761{
1629 struct Session * ps = ptr; 1762 struct Session * ps = ptr;
1630 1763
1631 if (ps->peercontext->delay.rel_value > 0) 1764 if (ps->peercontext->delay.rel_value > 0)
1632 { 1765 {
1633#if DEBUG_HTTP 1766#if DEBUG_HTTP
1634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: no inbound bandwidth available! Next read was delayed for %llu ms\n", ps, ps->peercontext->delay.rel_value); 1767 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1768 "Connection %X: no inbound bandwidth available! Next read was delayed for %llu ms\n",
1769 ps, ps->peercontext->delay.rel_value);
1635#endif 1770#endif
1636 return (0); 1771 return 0;
1637 } 1772 }
1638
1639#if DEBUG_CONNECTIONS 1773#if DEBUG_CONNECTIONS
1640 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: %u bytes received\n",ps, size*nmemb); 1774 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1775 "Connection %X: %u bytes received\n",
1776 ps, size*nmemb);
1641#endif 1777#endif
1642 GNUNET_SERVER_mst_receive(ps->msgtok, ps, stream, size*nmemb, GNUNET_NO, GNUNET_NO); 1778 GNUNET_SERVER_mst_receive(ps->msgtok, ps,
1779 stream, size*nmemb,
1780 GNUNET_NO, GNUNET_NO);
1643 return (size * nmemb); 1781 return (size * nmemb);
1644
1645} 1782}
1646 1783
1647static void curl_handle_finished (struct Plugin *plugin) 1784
1785static void
1786curl_handle_finished (struct Plugin *plugin)
1648{ 1787{
1649 struct Session *ps = NULL; 1788 struct Session *ps = NULL;
1650 struct HTTP_PeerContext *pc = NULL; 1789 struct HTTP_PeerContext *pc = NULL;
1651 struct CURLMsg *msg; 1790 struct CURLMsg *msg;
1652 struct HTTP_Message * cur_msg = NULL; 1791 struct HTTP_Message * cur_msg = NULL;
1653 1792 int msgs_in_queue;
1654 int msgs_in_queue; 1793 char * tmp;
1655 char * tmp; 1794 long http_result;
1656 long http_result; 1795
1657 1796 do
1658 do 1797 {
1659 { 1798 msg = curl_multi_info_read (plugin->multi_handle, &msgs_in_queue);
1660 msg = curl_multi_info_read (plugin->multi_handle, &msgs_in_queue); 1799 if ((msgs_in_queue == 0) || (msg == NULL))
1661 if ((msgs_in_queue == 0) || (msg == NULL)) 1800 break;
1662 break; 1801 /* get session for affected curl handle */
1663 /* get session for affected curl handle */ 1802 GNUNET_assert ( msg->easy_handle != NULL );
1664 GNUNET_assert ( msg->easy_handle != NULL ); 1803 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &tmp);
1665 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &tmp); 1804 ps = (struct Session *) tmp;
1666 ps = (struct Session *) tmp; 1805 GNUNET_assert ( ps != NULL );
1667 GNUNET_assert ( ps != NULL ); 1806 pc = ps->peercontext;
1668 pc = ps->peercontext; 1807 GNUNET_assert ( pc != NULL );
1669 GNUNET_assert ( pc != NULL ); 1808 switch (msg->msg)
1670 switch (msg->msg) 1809 {
1671 { 1810 case CURLMSG_DONE:
1672 1811 if ( (msg->data.result != CURLE_OK) &&
1673 case CURLMSG_DONE: 1812 (msg->data.result != CURLE_GOT_NOTHING) )
1674 if ( (msg->data.result != CURLE_OK) && 1813 {
1675 (msg->data.result != CURLE_GOT_NOTHING) ) 1814 /* sending msg failed*/
1676 { 1815 if (msg->easy_handle == ps->send_endpoint)
1677 /* sending msg failed*/ 1816 {
1678 if (msg->easy_handle == ps->send_endpoint) 1817#if DEBUG_CONNECTIONS
1679 { 1818 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1680 #if DEBUG_CONNECTIONS 1819 _("Connection %X: HTTP PUT to peer `%s' (`%s') failed: `%s' `%s'\n"),
1681 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1820 ps,
1682 _("Connection %X: HTTP PUT to peer `%s' (`%s') failed: `%s' `%s'\n"), 1821 GNUNET_i2s(&pc->identity),
1683 ps, 1822 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
1684 GNUNET_i2s(&pc->identity), 1823 "curl_multi_perform",
1685 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen), 1824 curl_easy_strerror (msg->data.result));
1686 "curl_multi_perform", 1825#endif
1687 curl_easy_strerror (msg->data.result)); 1826 ps->send_connected = GNUNET_NO;
1688 #endif 1827 ps->send_active = GNUNET_NO;
1689 ps->send_connected = GNUNET_NO; 1828 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
1690 ps->send_active = GNUNET_NO; 1829 //curl_easy_cleanup(ps->send_endpoint);
1691 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint); 1830 //ps->send_endpoint=NULL;
1692 //curl_easy_cleanup(ps->send_endpoint); 1831 while (ps->pending_msgs_tail != NULL)
1693 //ps->send_endpoint=NULL; 1832 {
1694 while (ps->pending_msgs_tail != NULL) 1833 cur_msg = ps->pending_msgs_tail;
1695 { 1834 if ( NULL != cur_msg->transmit_cont)
1696 cur_msg = ps->pending_msgs_tail; 1835 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
1697 if ( NULL != cur_msg->transmit_cont) 1836 ps->queue_length_cur -= cur_msg->size;
1698 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); 1837 remove_http_message(ps,cur_msg);
1699 ps->queue_length_cur -= cur_msg->size; 1838 }
1700 remove_http_message(ps,cur_msg); 1839 }
1701 } 1840 /* GET connection failed */
1702 } 1841 if (msg->easy_handle == ps->recv_endpoint)
1703 /* GET connection failed */ 1842 {
1704 if (msg->easy_handle == ps->recv_endpoint) 1843#if DEBUG_CONNECTIONS
1705 { 1844 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1706 #if DEBUG_CONNECTIONS 1845 _("Connection %X: HTTP GET to peer `%s' (`%s') failed: `%s' `%s'\n"),
1707 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1846 ps,
1708 _("Connection %X: HTTP GET to peer `%s' (`%s') failed: `%s' `%s'\n"), 1847 GNUNET_i2s(&pc->identity),
1709 ps, 1848 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
1710 GNUNET_i2s(&pc->identity), 1849 "curl_multi_perform",
1711 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen), 1850 curl_easy_strerror (msg->data.result));
1712 "curl_multi_perform", 1851#endif
1713 curl_easy_strerror (msg->data.result)); 1852 ps->recv_connected = GNUNET_NO;
1714 #endif 1853 ps->recv_active = GNUNET_NO;
1715 ps->recv_connected = GNUNET_NO; 1854 curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
1716 ps->recv_active = GNUNET_NO; 1855 //curl_easy_cleanup(ps->recv_endpoint);
1717 curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint); 1856 //ps->recv_endpoint=NULL;
1718 //curl_easy_cleanup(ps->recv_endpoint); 1857 }
1719 //ps->recv_endpoint=NULL; 1858 }
1720 } 1859 else
1721 } 1860 {
1722 else 1861 if (msg->easy_handle == ps->send_endpoint)
1862 {
1863 GNUNET_assert (CURLE_OK == curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &http_result));
1864#if DEBUG_CONNECTIONS
1865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1866 "Connection %X: HTTP PUT connection to peer `%s' (`%s') was closed with HTTP code %u\n",
1867 ps,
1868 GNUNET_i2s(&pc->identity),
1869 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
1870 http_result);
1871#endif
1872 /* Calling transmit continuation */
1873 while (ps->pending_msgs_tail != NULL)
1874 {
1875 cur_msg = ps->pending_msgs_tail;
1876 if ( NULL != cur_msg->transmit_cont)
1723 { 1877 {
1724 if (msg->easy_handle == ps->send_endpoint) 1878 /* HTTP 1xx : Last message before here was informational */
1725 { 1879 if ((http_result >=100) && (http_result < 200))
1726 GNUNET_assert (CURLE_OK == curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &http_result)); 1880 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1727 #if DEBUG_CONNECTIONS 1881 /* HTTP 2xx: successful operations */
1728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1882 if ((http_result >=200) && (http_result < 300))
1729 "Connection %X: HTTP PUT connection to peer `%s' (`%s') was closed with HTTP code %u\n", 1883 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1730 ps, 1884 /* HTTP 3xx..5xx: error */
1731 GNUNET_i2s(&pc->identity), 1885 if ((http_result >=300) && (http_result < 600))
1732 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen), 1886 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
1733 http_result);
1734 #endif
1735 /* Calling transmit continuation */
1736 while (ps->pending_msgs_tail != NULL)
1737 {
1738 cur_msg = ps->pending_msgs_tail;
1739 if ( NULL != cur_msg->transmit_cont)
1740 {
1741 /* HTTP 1xx : Last message before here was informational */
1742 if ((http_result >=100) && (http_result < 200))
1743 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1744 /* HTTP 2xx: successful operations */
1745 if ((http_result >=200) && (http_result < 300))
1746 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1747 /* HTTP 3xx..5xx: error */
1748 if ((http_result >=300) && (http_result < 600))
1749 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
1750 }
1751 ps->queue_length_cur -= cur_msg->size;
1752 remove_http_message(ps,cur_msg);
1753 }
1754
1755 ps->send_connected = GNUNET_NO;
1756 ps->send_active = GNUNET_NO;
1757 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
1758 //curl_easy_cleanup(ps->send_endpoint);
1759 //ps->send_endpoint =NULL;
1760 }
1761 if (msg->easy_handle == ps->recv_endpoint)
1762 {
1763 #if DEBUG_CONNECTIONS
1764 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1765 "Connection %X: HTTP GET connection to peer `%s' (`%s') was closed with HTTP code %u\n",
1766 ps,
1767 GNUNET_i2s(&pc->identity),
1768 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
1769 http_result);
1770 #endif
1771 ps->recv_connected = GNUNET_NO;
1772 ps->recv_active = GNUNET_NO;
1773 curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
1774 //curl_easy_cleanup(ps->recv_endpoint);
1775 //ps->recv_endpoint=NULL;
1776 }
1777 } 1887 }
1778 if ((ps->recv_connected == GNUNET_NO) && (ps->send_connected == GNUNET_NO)) 1888 ps->queue_length_cur -= cur_msg->size;
1779 remove_session (pc, ps, GNUNET_YES, GNUNET_SYSERR); 1889 remove_http_message(ps,cur_msg);
1780 break; 1890 }
1781 default: 1891
1782 break; 1892 ps->send_connected = GNUNET_NO;
1783 } 1893 ps->send_active = GNUNET_NO;
1784 } 1894 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
1785 while ( (msgs_in_queue > 0) ); 1895 //curl_easy_cleanup(ps->send_endpoint);
1896 //ps->send_endpoint =NULL;
1897 }
1898 if (msg->easy_handle == ps->recv_endpoint)
1899 {
1900#if DEBUG_CONNECTIONS
1901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1902 "Connection %X: HTTP GET connection to peer `%s' (`%s') was closed with HTTP code %u\n",
1903 ps,
1904 GNUNET_i2s(&pc->identity),
1905 http_plugin_address_to_string(NULL, ps->addr, ps->addrlen),
1906 http_result);
1907#endif
1908 ps->recv_connected = GNUNET_NO;
1909 ps->recv_active = GNUNET_NO;
1910 curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint);
1911 //curl_easy_cleanup(ps->recv_endpoint);
1912 //ps->recv_endpoint=NULL;
1913 }
1914 }
1915 if ((ps->recv_connected == GNUNET_NO) && (ps->send_connected == GNUNET_NO))
1916 remove_session (pc, ps, GNUNET_YES, GNUNET_SYSERR);
1917 break;
1918 default:
1919 break;
1920 }
1921 }
1922 while ( (msgs_in_queue > 0) );
1786} 1923}
1787 1924
1788 1925
@@ -1792,7 +1929,7 @@ static void curl_handle_finished (struct Plugin *plugin)
1792 * @param tc gnunet scheduler task context 1929 * @param tc gnunet scheduler task context
1793 */ 1930 */
1794static void curl_perform (void *cls, 1931static void curl_perform (void *cls,
1795 const struct GNUNET_SCHEDULER_TaskContext *tc) 1932 const struct GNUNET_SCHEDULER_TaskContext *tc)
1796{ 1933{
1797 struct Plugin *plugin = cls; 1934 struct Plugin *plugin = cls;
1798 static unsigned int handles_last_run; 1935 static unsigned int handles_last_run;
@@ -1823,7 +1960,8 @@ static void curl_perform (void *cls,
1823 * @param plugin plugin as closure 1960 * @param plugin plugin as closure
1824 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok 1961 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok
1825 */ 1962 */
1826static int curl_schedule(struct Plugin *plugin) 1963static int
1964curl_schedule(struct Plugin *plugin)
1827{ 1965{
1828 fd_set rs; 1966 fd_set rs;
1829 fd_set ws; 1967 fd_set ws;
@@ -1836,11 +1974,11 @@ static int curl_schedule(struct Plugin *plugin)
1836 1974
1837 /* Cancel previous scheduled task */ 1975 /* Cancel previous scheduled task */
1838 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) 1976 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
1839 { 1977 {
1840 GNUNET_SCHEDULER_cancel(plugin->http_curl_task); 1978 GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
1841 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; 1979 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
1842 } 1980 }
1843 1981
1844 max = -1; 1982 max = -1;
1845 FD_ZERO (&rs); 1983 FD_ZERO (&rs);
1846 FD_ZERO (&ws); 1984 FD_ZERO (&ws);
@@ -1869,17 +2007,21 @@ static int curl_schedule(struct Plugin *plugin)
1869 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); 2007 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
1870 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); 2008 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
1871 plugin->http_curl_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 2009 plugin->http_curl_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1872 GNUNET_SCHEDULER_NO_TASK, 2010 GNUNET_SCHEDULER_NO_TASK,
1873 (to == -1) ? GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) : GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to), 2011 (to == -1)
1874 grs, 2012 ? GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
1875 gws, 2013 : GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to),
1876 &curl_perform, 2014 grs,
1877 plugin); 2015 gws,
2016 &curl_perform,
2017 plugin);
1878 GNUNET_NETWORK_fdset_destroy (gws); 2018 GNUNET_NETWORK_fdset_destroy (gws);
1879 GNUNET_NETWORK_fdset_destroy (grs); 2019 GNUNET_NETWORK_fdset_destroy (grs);
1880 return GNUNET_OK; 2020 return GNUNET_OK;
1881} 2021}
1882 2022
2023
2024#if DEBUG_CURL
1883/** 2025/**
1884 * Function to log curl debug messages with GNUNET_log 2026 * Function to log curl debug messages with GNUNET_log
1885 * @param curl handle 2027 * @param curl handle
@@ -1889,24 +2031,32 @@ static int curl_schedule(struct Plugin *plugin)
1889 * @param cls closure 2031 * @param cls closure
1890 * @return 0 2032 * @return 0
1891 */ 2033 */
1892int curl_logger (CURL * curl, curl_infotype type , char * data, size_t size , void * cls) 2034static int
2035curl_logger (CURL * curl,
2036 curl_infotype type,
2037 char * data, size_t size,
2038 void * cls)
1893{ 2039{
1894 2040 if (type == CURLINFO_TEXT)
1895 if (type == CURLINFO_TEXT) 2041 {
2042 char text[size+2];
2043 memcpy(text,data,size);
2044 if (text[size-1] == '\n')
2045 text[size] = '\0';
2046 else
1896 { 2047 {
1897 char text[size+2]; 2048 text[size] = '\n';
1898 memcpy(text,data,size); 2049 text[size+1] = '\0';
1899 if (text[size-1] == '\n')
1900 text[size] = '\0';
1901 else
1902 {
1903 text[size] = '\n';
1904 text[size+1] = '\0';
1905 }
1906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"CURL: Connection %X - %s", cls, text);
1907 } 2050 }
1908 return 0; 2051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2052 "CURL: Connection %X - %s",
2053 cls,
2054 text);
2055 }
2056 return 0;
1909} 2057}
2058#endif
2059
1910 2060
1911/** 2061/**
1912 * Function setting up curl handle and selecting message to send 2062 * Function setting up curl handle and selecting message to send
@@ -1915,181 +2065,185 @@ int curl_logger (CURL * curl, curl_infotype type , char * data, size_t size , vo
1915 * @param ps session 2065 * @param ps session
1916 * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok 2066 * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok
1917 */ 2067 */
1918static int send_check_connections (struct Plugin *plugin, struct Session *ps) 2068static int
2069send_check_connections (struct Plugin *plugin,
2070 struct Session *ps)
1919{ 2071{
1920 CURLMcode mret; 2072 CURLMcode mret;
1921 struct HTTP_Message * msg;
1922
1923 struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; 2073 struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT;
1924 2074
1925 if (ps->direction == OUTBOUND) 2075 if (ps->direction == OUTBOUND)
1926 {
1927 /* RECV DIRECTION */
1928 /* Check if session is connected to receive data, otherwise connect to peer */
1929 if (ps->recv_connected == GNUNET_NO)
1930 { 2076 {
1931 int fresh = GNUNET_NO; 2077 /* RECV DIRECTION */
1932 if (ps->recv_endpoint == NULL) 2078 /* Check if session is connected to receive data, otherwise connect to peer */
1933 { 2079 if (ps->recv_connected == GNUNET_NO)
1934 fresh = GNUNET_YES; 2080 {
1935 ps->recv_endpoint = curl_easy_init(); 2081 int fresh = GNUNET_NO;
1936 } 2082 if (ps->recv_endpoint == NULL)
2083 {
2084 fresh = GNUNET_YES;
2085 ps->recv_endpoint = curl_easy_init();
2086 }
1937#if DEBUG_CURL 2087#if DEBUG_CURL
1938 curl_easy_setopt(ps->recv_endpoint, CURLOPT_VERBOSE, 1L); 2088 curl_easy_setopt(ps->recv_endpoint, CURLOPT_VERBOSE, 1L);
1939 curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger); 2089 curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger);
1940 curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGDATA , ps->recv_endpoint); 2090 curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGDATA , ps->recv_endpoint);
1941#endif 2091#endif
1942#if BUILD_HTTPS 2092#if BUILD_HTTPS
1943 curl_easy_setopt (ps->recv_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 2093 curl_easy_setopt (ps->recv_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
1944 curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYPEER, 0); 2094 curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYPEER, 0);
1945 curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYHOST, 0); 2095 curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYHOST, 0);
1946#endif 2096#endif
1947 curl_easy_setopt(ps->recv_endpoint, CURLOPT_URL, ps->url); 2097 curl_easy_setopt(ps->recv_endpoint, CURLOPT_URL, ps->url);
1948 curl_easy_setopt(ps->recv_endpoint, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); 2098 curl_easy_setopt(ps->recv_endpoint, CURLOPT_HEADERFUNCTION, &curl_get_header_cb);
1949 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEHEADER, ps); 2099 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEHEADER, ps);
1950 curl_easy_setopt(ps->recv_endpoint, CURLOPT_READFUNCTION, curl_send_cb); 2100 curl_easy_setopt(ps->recv_endpoint, CURLOPT_READFUNCTION, curl_send_cb);
1951 curl_easy_setopt(ps->recv_endpoint, CURLOPT_READDATA, ps); 2101 curl_easy_setopt(ps->recv_endpoint, CURLOPT_READDATA, ps);
1952 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); 2102 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb);
1953 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEDATA, ps); 2103 curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEDATA, ps);
1954 curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value); 2104 curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value);
1955 curl_easy_setopt(ps->recv_endpoint, CURLOPT_PRIVATE, ps); 2105 curl_easy_setopt(ps->recv_endpoint, CURLOPT_PRIVATE, ps);
1956 curl_easy_setopt(ps->recv_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); 2106 curl_easy_setopt(ps->recv_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT);
1957 curl_easy_setopt(ps->recv_endpoint, CURLOPT_BUFFERSIZE, 2*GNUNET_SERVER_MAX_MESSAGE_SIZE); 2107 curl_easy_setopt(ps->recv_endpoint, CURLOPT_BUFFERSIZE, 2*GNUNET_SERVER_MAX_MESSAGE_SIZE);
1958#if CURL_TCP_NODELAY 2108#if CURL_TCP_NODELAY
1959 curl_easy_setopt(ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); 2109 curl_easy_setopt(ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1);
1960#endif 2110#endif
1961 2111 if (fresh==GNUNET_YES)
1962 if (fresh==GNUNET_YES) 2112 {
1963 { 2113 mret = curl_multi_add_handle(plugin->multi_handle, ps->recv_endpoint);
1964 mret = curl_multi_add_handle(plugin->multi_handle, ps->recv_endpoint); 2114 if (mret != CURLM_OK)
1965 if (mret != CURLM_OK)
1966 {
1967 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1968 _("Connection: %X: %s failed at %s:%d: `%s'\n"),
1969 ps,
1970 "curl_multi_add_handle", __FILE__, __LINE__,
1971 curl_multi_strerror (mret));
1972 return GNUNET_SYSERR;
1973 }
1974 }
1975 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
1976 { 2115 {
1977 GNUNET_SCHEDULER_cancel(plugin->http_curl_task); 2116 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1978 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; 2117 _("Connection: %X: %s failed at %s:%d: `%s'\n"),
2118 ps,
2119 "curl_multi_add_handle", __FILE__, __LINE__,
2120 curl_multi_strerror (mret));
2121 return GNUNET_SYSERR;
1979 } 2122 }
1980 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); 2123 }
1981 } 2124 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
1982 2125 {
1983 /* waiting for receive direction */ 2126 GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
1984 if (ps->recv_connected==GNUNET_NO) 2127 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
1985 return GNUNET_NO; 2128 }
1986 2129 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin);
1987 /* SEND DIRECTION */ 2130 }
1988 /* Check if session is connected to send data, otherwise connect to peer */ 2131
1989 if ((ps->send_connected == GNUNET_YES) && (ps->send_endpoint!= NULL)) 2132 /* waiting for receive direction */
1990 { 2133 if (ps->recv_connected==GNUNET_NO)
1991 if (ps->send_active == GNUNET_YES) 2134 return GNUNET_NO;
1992 { 2135
2136 /* SEND DIRECTION */
2137 /* Check if session is connected to send data, otherwise connect to peer */
2138 if ((ps->send_connected == GNUNET_YES) && (ps->send_endpoint!= NULL))
2139 {
2140 if (ps->send_active == GNUNET_YES)
2141 {
1993#if DEBUG_CONNECTIONS 2142#if DEBUG_CONNECTIONS
1994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound active, enqueueing message\n",ps); 2143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1995#endif 2144 "Connection %X: outbound active, enqueueing message\n",
1996 return GNUNET_YES; 2145 ps);
1997 } 2146#endif
1998 if (ps->send_active == GNUNET_NO) 2147 return GNUNET_YES;
1999 { 2148 }
2149 if (ps->send_active == GNUNET_NO)
2150 {
2000#if DEBUG_CONNECTIONS 2151#if DEBUG_CONNECTIONS
2001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound paused, unpausing existing connection and enqueueing message\n",ps); 2152 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2153 "Connection %X: outbound paused, unpausing existing connection and enqueueing message\n",
2154 ps);
2002#endif 2155#endif
2003 if (CURLE_OK == curl_easy_pause(ps->send_endpoint,CURLPAUSE_CONT)) 2156 if (CURLE_OK == curl_easy_pause(ps->send_endpoint,CURLPAUSE_CONT))
2004 { 2157 {
2005 ps->send_active=GNUNET_YES; 2158 ps->send_active=GNUNET_YES;
2006 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) 2159 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
2007 { 2160 {
2008 GNUNET_SCHEDULER_cancel(plugin->http_curl_task); 2161 GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
2009 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; 2162 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
2010 } 2163 }
2011 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); 2164 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin);
2012 return GNUNET_YES; 2165 return GNUNET_YES;
2013 } 2166 }
2014 else 2167 else
2015 return GNUNET_SYSERR; 2168 return GNUNET_SYSERR;
2016 } 2169 }
2017 } 2170 }
2018 /* not connected, initiate connection */ 2171 /* not connected, initiate connection */
2019 if (ps->send_connected==GNUNET_NO) 2172 if (ps->send_connected==GNUNET_NO)
2020 { 2173 {
2021 int fresh = GNUNET_NO; 2174 int fresh = GNUNET_NO;
2022 if (NULL == ps->send_endpoint) 2175 if (NULL == ps->send_endpoint)
2023 { 2176 {
2024 ps->send_endpoint = curl_easy_init(); 2177 ps->send_endpoint = curl_easy_init();
2025 fresh = GNUNET_YES; 2178 fresh = GNUNET_YES;
2026 } 2179 }
2027 GNUNET_assert (ps->send_endpoint != NULL); 2180 GNUNET_assert (ps->send_endpoint != NULL);
2028 GNUNET_assert (NULL != ps->pending_msgs_tail); 2181 GNUNET_assert (NULL != ps->pending_msgs_tail);
2029#if DEBUG_CONNECTIONS 2182#if DEBUG_CONNECTIONS
2030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound not connected, initiating connection\n",ps); 2183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2184 "Connection %X: outbound not connected, initiating connection\n",
2185 ps);
2031#endif 2186#endif
2032 ps->send_active = GNUNET_NO; 2187 ps->send_active = GNUNET_NO;
2033 msg = ps->pending_msgs_tail; 2188
2034
2035#if DEBUG_CURL 2189#if DEBUG_CURL
2036 curl_easy_setopt(ps->send_endpoint, CURLOPT_VERBOSE, 1L); 2190 curl_easy_setopt(ps->send_endpoint, CURLOPT_VERBOSE, 1L);
2037 curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger); 2191 curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger);
2038 curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGDATA , ps->send_endpoint); 2192 curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGDATA , ps->send_endpoint);
2039#endif 2193#endif
2040#if BUILD_HTTPS 2194#if BUILD_HTTPS
2041 curl_easy_setopt (ps->send_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); 2195 curl_easy_setopt (ps->send_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
2042 curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYPEER, 0); 2196 curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYPEER, 0);
2043 curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYHOST, 0); 2197 curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYHOST, 0);
2044#endif 2198#endif
2045 curl_easy_setopt(ps->send_endpoint, CURLOPT_URL, ps->url); 2199 curl_easy_setopt(ps->send_endpoint, CURLOPT_URL, ps->url);
2046 curl_easy_setopt(ps->send_endpoint, CURLOPT_PUT, 1L); 2200 curl_easy_setopt(ps->send_endpoint, CURLOPT_PUT, 1L);
2047 curl_easy_setopt(ps->send_endpoint, CURLOPT_HEADERFUNCTION, &curl_put_header_cb); 2201 curl_easy_setopt(ps->send_endpoint, CURLOPT_HEADERFUNCTION, &curl_put_header_cb);
2048 curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEHEADER, ps); 2202 curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEHEADER, ps);
2049 curl_easy_setopt(ps->send_endpoint, CURLOPT_READFUNCTION, curl_send_cb); 2203 curl_easy_setopt(ps->send_endpoint, CURLOPT_READFUNCTION, curl_send_cb);
2050 curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); 2204 curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps);
2051 curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); 2205 curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb);
2052 curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); 2206 curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps);
2053 curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value); 2207 curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value);
2054 curl_easy_setopt(ps->send_endpoint, CURLOPT_PRIVATE, ps); 2208 curl_easy_setopt(ps->send_endpoint, CURLOPT_PRIVATE, ps);
2055 curl_easy_setopt(ps->send_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); 2209 curl_easy_setopt(ps->send_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT);
2056 curl_easy_setopt(ps->send_endpoint, CURLOPT_BUFFERSIZE, 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 2210 curl_easy_setopt(ps->send_endpoint, CURLOPT_BUFFERSIZE, 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE);
2057#if CURL_TCP_NODELAY 2211#if CURL_TCP_NODELAY
2058 curl_easy_setopt(ps->send_endpoint, CURLOPT_TCP_NODELAY, 1); 2212 curl_easy_setopt(ps->send_endpoint, CURLOPT_TCP_NODELAY, 1);
2059#endif 2213#endif
2060 2214 if (fresh==GNUNET_YES)
2061 if (fresh==GNUNET_YES) 2215 {
2216 mret = curl_multi_add_handle(plugin->multi_handle, ps->send_endpoint);
2217 if (mret != CURLM_OK)
2062 { 2218 {
2063 mret = curl_multi_add_handle(plugin->multi_handle, ps->send_endpoint); 2219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2064 if (mret != CURLM_OK) 2220 _("Connection: %X: %s failed at %s:%d: `%s'\n"),
2065 { 2221 ps,
2066 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2222 "curl_multi_add_handle", __FILE__, __LINE__,
2067 _("Connection: %X: %s failed at %s:%d: `%s'\n"), 2223 curl_multi_strerror (mret));
2068 ps, 2224 return GNUNET_SYSERR;
2069 "curl_multi_add_handle", __FILE__, __LINE__,
2070 curl_multi_strerror (mret));
2071 return GNUNET_SYSERR;
2072 }
2073 } 2225 }
2074 } 2226 }
2075 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) 2227 }
2228 if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
2076 { 2229 {
2077 GNUNET_SCHEDULER_cancel(plugin->http_curl_task); 2230 GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
2078 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; 2231 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
2079 } 2232 }
2080 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); 2233 plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin);
2081 return GNUNET_YES; 2234 return GNUNET_YES;
2082 } 2235 }
2083 if (ps->direction == INBOUND) 2236 if (ps->direction == INBOUND)
2084 { 2237 {
2085 GNUNET_assert (NULL != ps->pending_msgs_tail); 2238 GNUNET_assert (NULL != ps->pending_msgs_tail);
2086 if ((ps->recv_connected==GNUNET_YES) && (ps->send_connected==GNUNET_YES) && 2239 if ((ps->recv_connected==GNUNET_YES) && (ps->send_connected==GNUNET_YES) &&
2087 (ps->recv_force_disconnect==GNUNET_NO) && (ps->recv_force_disconnect==GNUNET_NO)) 2240 (ps->recv_force_disconnect==GNUNET_NO) && (ps->recv_force_disconnect==GNUNET_NO))
2088 return GNUNET_YES; 2241 return GNUNET_YES;
2089 } 2242 }
2090 return GNUNET_SYSERR; 2243 return GNUNET_SYSERR;
2091} 2244}
2092 2245
2246
2093/** 2247/**
2094 * select best session to transmit data to peer 2248 * select best session to transmit data to peer
2095 * 2249 *
@@ -2101,114 +2255,134 @@ static int send_check_connections (struct Plugin *plugin, struct Session *ps)
2101 * @return selected session 2255 * @return selected session
2102 * 2256 *
2103 */ 2257 */
2104static struct Session * send_select_session (struct HTTP_PeerContext *pc, const void * addr, size_t addrlen, int force_address, struct Session * session) 2258static struct Session *
2259send_select_session (struct HTTP_PeerContext *pc,
2260 const void * addr, size_t addrlen,
2261 int force_address,
2262 struct Session * session)
2105{ 2263{
2106 struct Session * tmp = NULL; 2264 struct Session * tmp = NULL;
2107 int addr_given = GNUNET_NO; 2265 int addr_given = GNUNET_NO;
2108 2266
2109 if ((addr!=NULL) && (addrlen>0)) 2267 if ((addr!=NULL) && (addrlen>0))
2110 addr_given = GNUNET_YES; 2268 addr_given = GNUNET_YES;
2111 2269
2112 if (force_address == GNUNET_YES) 2270 if (force_address == GNUNET_YES)
2271 {
2272 /* check session given as argument */
2273 if ((session != NULL) && (addr_given == GNUNET_YES))
2113 { 2274 {
2114 /* check session given as argument */ 2275 if (0 == memcmp(session->addr, addr, addrlen))
2115 if ((session != NULL) && (addr_given == GNUNET_YES)) 2276 {
2277 /* connection can not be used, since it is disconnected */
2278 if ( (session->recv_force_disconnect==GNUNET_NO) &&
2279 (session->send_force_disconnect==GNUNET_NO) )
2116 { 2280 {
2117 if (0 == memcmp(session->addr, addr, addrlen))
2118 {
2119 /* connection can not be used, since it is disconnected */
2120 if ((session->recv_force_disconnect==GNUNET_NO) && (session->send_force_disconnect==GNUNET_NO))
2121 {
2122#if DEBUG_SESSION_SELECTION 2281#if DEBUG_SESSION_SELECTION
2123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using session passed by transport to send to forced address \n", session); 2282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2283 "Session %X selected: Using session passed by transport to send to forced address \n",
2284 session);
2124#endif 2285#endif
2125 return session; 2286 return session;
2126 }
2127 }
2128 } 2287 }
2129 /* check last session used */ 2288 }
2130 if ((pc->last_session != NULL)&& (addr_given == GNUNET_YES)) 2289 }
2290 /* check last session used */
2291 if ((pc->last_session != NULL)&& (addr_given == GNUNET_YES))
2292 {
2293 if (0 == memcmp(pc->last_session->addr, addr, addrlen))
2294 {
2295 /* connection can not be used, since it is disconnected */
2296 if ( (pc->last_session->recv_force_disconnect==GNUNET_NO) &&
2297 (pc->last_session->send_force_disconnect==GNUNET_NO) )
2131 { 2298 {
2132 if (0 == memcmp(pc->last_session->addr, addr, addrlen))
2133 {
2134 /* connection can not be used, since it is disconnected */
2135 if ((pc->last_session->recv_force_disconnect==GNUNET_NO) && (pc->last_session->send_force_disconnect==GNUNET_NO))
2136 {
2137#if DEBUG_SESSION_SELECTION 2299#if DEBUG_SESSION_SELECTION
2138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using last session used to send to forced address \n", pc->last_session); 2300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2301 "Session %X selected: Using last session used to send to forced address \n",
2302 pc->last_session);
2139#endif 2303#endif
2140 return pc->last_session; 2304 return pc->last_session;
2141 }
2142 }
2143 } 2305 }
2144 /* find session in existing sessions */ 2306 }
2145 tmp = pc->head; 2307 }
2146 while ((tmp!=NULL) && (addr_given == GNUNET_YES)) 2308 /* find session in existing sessions */
2309 tmp = pc->head;
2310 while ((tmp!=NULL) && (addr_given == GNUNET_YES))
2311 {
2312 if (0 == memcmp(tmp->addr, addr, addrlen))
2313 {
2314 /* connection can not be used, since it is disconnected */
2315 if ( (tmp->recv_force_disconnect==GNUNET_NO) &&
2316 (tmp->send_force_disconnect==GNUNET_NO) )
2147 { 2317 {
2148
2149 if (0 == memcmp(tmp->addr, addr, addrlen))
2150 {
2151 /* connection can not be used, since it is disconnected */
2152 if ((tmp->recv_force_disconnect==GNUNET_NO) && (tmp->send_force_disconnect==GNUNET_NO))
2153 {
2154#if DEBUG_SESSION_SELECTION 2318#if DEBUG_SESSION_SELECTION
2155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using existing session to send to forced address \n", session); 2319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2156#endif 2320 "Session %X selected: Using existing session to send to forced address \n",
2157 return session; 2321 session);
2158 } 2322#endif
2159 2323 return session;
2160 } 2324 }
2161 tmp=tmp->next; 2325 }
2162 } 2326 tmp=tmp->next;
2163 /* no session to use */
2164 return NULL;
2165 } 2327 }
2166 if ((force_address == GNUNET_NO) || (force_address == GNUNET_SYSERR)) 2328 /* no session to use */
2329 return NULL;
2330 }
2331 if ((force_address == GNUNET_NO) || (force_address == GNUNET_SYSERR))
2332 {
2333 /* check session given as argument */
2334 if (session != NULL)
2167 { 2335 {
2168 /* check session given as argument */ 2336 /* connection can not be used, since it is disconnected */
2169 if (session != NULL) 2337 if ( (session->recv_force_disconnect==GNUNET_NO) &&
2170 { 2338 (session->send_force_disconnect==GNUNET_NO) )
2171 /* connection can not be used, since it is disconnected */ 2339 {
2172 if ((session->recv_force_disconnect==GNUNET_NO) && (session->send_force_disconnect==GNUNET_NO))
2173 {
2174#if DEBUG_SESSION_SELECTION 2340#if DEBUG_SESSION_SELECTION
2175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using session passed by transport to send not-forced address \n", session); 2341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2342 "Session %X selected: Using session passed by transport to send not-forced address\n",
2343 session);
2176#endif 2344#endif
2177 return session; 2345 return session;
2178 } 2346 }
2179 2347 }
2180 } 2348 /* check last session used */
2181 /* check last session used */ 2349 if (pc->last_session != NULL)
2182 if (pc->last_session != NULL) 2350 {
2183 { 2351 /* connection can not be used, since it is disconnected */
2184 /* connection can not be used, since it is disconnected */ 2352 if ( (pc->last_session->recv_force_disconnect==GNUNET_NO) &&
2185 if ((pc->last_session->recv_force_disconnect==GNUNET_NO) && (pc->last_session->send_force_disconnect==GNUNET_NO)) 2353 (pc->last_session->send_force_disconnect==GNUNET_NO) )
2186 { 2354 {
2187#if DEBUG_SESSION_SELECTION 2355#if DEBUG_SESSION_SELECTION
2188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using last session to send to not-forced address \n", pc->last_session); 2356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2357 "Session %X selected: Using last session to send to not-forced address\n",
2358 pc->last_session);
2189#endif 2359#endif
2190 return pc->last_session; 2360 return pc->last_session;
2191 } 2361 }
2192 } 2362 }
2193 /* find session in existing sessions */ 2363 /* find session in existing sessions */
2194 tmp = pc->head; 2364 tmp = pc->head;
2195 while (tmp!=NULL) 2365 while (tmp!=NULL)
2196 { 2366 {
2197 /* connection can not be used, since it is disconnected */ 2367 /* connection can not be used, since it is disconnected */
2198 if ((tmp->recv_force_disconnect==GNUNET_NO) && (tmp->send_force_disconnect==GNUNET_NO)) 2368 if ( (tmp->recv_force_disconnect==GNUNET_NO) &&
2199 { 2369 (tmp->send_force_disconnect==GNUNET_NO) )
2370 {
2200#if DEBUG_SESSION_SELECTION 2371#if DEBUG_SESSION_SELECTION
2201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using existing session to send to not-forced address \n", tmp); 2372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2373 "Session %X selected: Using existing session to send to not-forced address\n",
2374 tmp);
2202#endif 2375#endif
2203 return tmp; 2376 return tmp;
2204 } 2377 }
2205 tmp=tmp->next; 2378 tmp=tmp->next;
2206 }
2207 return NULL;
2208 } 2379 }
2209 return NULL; 2380 return NULL;
2381 }
2382 return NULL;
2210} 2383}
2211 2384
2385
2212/** 2386/**
2213 * Function that can be used by the transport service to transmit 2387 * Function that can be used by the transport service to transmit
2214 * a message using the plugin. Note that in the case of a 2388 * a message using the plugin. Note that in the case of a
@@ -2268,62 +2442,63 @@ http_plugin_send (void *cls,
2268 2442
2269#if DEBUG_HTTP 2443#if DEBUG_HTTP
2270 char * force; 2444 char * force;
2271 if (force_address == GNUNET_YES)
2272 GNUNET_asprintf(&force, "forced addr.");
2273 if (force_address == GNUNET_NO)
2274 GNUNET_asprintf(&force, "any addr.");
2275 if (force_address == GNUNET_SYSERR)
2276 GNUNET_asprintf(&force,"reliable bi-direc. address addr.");
2277
2278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Transport tells me to send %u bytes to `%s' using %s (%s) and session: %X\n",
2279 msgbuf_size,
2280 GNUNET_i2s(target),
2281 force,
2282 http_plugin_address_to_string(NULL, addr, addrlen),
2283 session);
2284 2445
2446 if (force_address == GNUNET_YES)
2447 GNUNET_asprintf(&force, "forced addr.");
2448 else if (force_address == GNUNET_NO)
2449 GNUNET_asprintf(&force, "any addr.");
2450 else if (force_address == GNUNET_SYSERR)
2451 GNUNET_asprintf(&force,"reliable bi-direc. address addr.");
2452 else
2453 GNUNET_assert (0);
2454 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2455 "Transport tells me to send %u bytes to `%s' using %s (%s) and session: %X\n",
2456 msgbuf_size,
2457 GNUNET_i2s(target),
2458 force,
2459 http_plugin_address_to_string(NULL, addr, addrlen),
2460 session);
2285 GNUNET_free(force); 2461 GNUNET_free(force);
2286#endif 2462#endif
2287 2463
2288 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &target->hashPubKey); 2464 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &target->hashPubKey);
2289 /* Peer unknown */ 2465 /* Peer unknown */
2290 if (pc==NULL) 2466 if (pc==NULL)
2291 { 2467 {
2292 pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext)); 2468 pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext));
2293 pc->plugin = plugin; 2469 pc->plugin = plugin;
2294 pc->session_id_counter=1; 2470 pc->session_id_counter=1;
2295 pc->last_session = NULL; 2471 pc->last_session = NULL;
2296 memcpy(&pc->identity, target, sizeof(struct GNUNET_PeerIdentity)); 2472 memcpy(&pc->identity, target, sizeof(struct GNUNET_PeerIdentity));
2297 GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 2473 GNUNET_CONTAINER_multihashmap_put (plugin->peers,
2298 GNUNET_STATISTICS_update (plugin->env->stats, 2474 &pc->identity.hashPubKey,
2299 gettext_noop ("# HTTP peers active"), 2475 pc,
2300 1, 2476 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2301 GNUNET_NO); 2477 GNUNET_STATISTICS_update (plugin->env->stats,
2302 } 2478 gettext_noop ("# HTTP peers active"),
2303 2479 1,
2480 GNUNET_NO);
2481 }
2304 ps = send_select_session (pc, addr, addrlen, force_address, session); 2482 ps = send_select_session (pc, addr, addrlen, force_address, session);
2305
2306 /* session not existing, but address forced -> creating new session */ 2483 /* session not existing, but address forced -> creating new session */
2307 if (ps==NULL) 2484 if (ps==NULL)
2308 { 2485 {
2309 if ((addr!=NULL) && (addrlen!=0)) 2486 if ((addr!=NULL) && (addrlen!=0))
2310 { 2487 {
2311 ps = GNUNET_malloc(sizeof (struct Session)); 2488 ps = GNUNET_malloc(sizeof (struct Session));
2312#if DEBUG_SESSION_SELECTION 2489#if DEBUG_SESSION_SELECTION
2313 if (force_address == GNUNET_YES) 2490 if (force_address == GNUNET_YES)
2314 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection & forced address: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); 2491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2315 if (force_address != GNUNET_YES) 2492 "No existing connection & forced address: creating new session %X to peer %s\n",
2316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); 2493 ps, GNUNET_i2s(target));
2494 if (force_address != GNUNET_YES)
2495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2496 "No existing connection: creating new session %X to peer %s\n",
2497 ps, GNUNET_i2s(target));
2317#endif 2498#endif
2318 ps->addr = GNUNET_malloc(addrlen); 2499 ps->addr = GNUNET_malloc(addrlen);
2319 memcpy(ps->addr,addr,addrlen); 2500 memcpy(ps->addr,addr,addrlen);
2320 ps->addrlen = addrlen; 2501 ps->addrlen = addrlen;
2321 /*
2322 else
2323 {
2324 ps->addr = NULL;
2325 ps->addrlen = 0;
2326 }*/
2327 ps->direction=OUTBOUND; 2502 ps->direction=OUTBOUND;
2328 ps->recv_connected = GNUNET_NO; 2503 ps->recv_connected = GNUNET_NO;
2329 ps->recv_force_disconnect = GNUNET_NO; 2504 ps->recv_force_disconnect = GNUNET_NO;
@@ -2338,28 +2513,34 @@ http_plugin_send (void *cls,
2338 pc->session_id_counter++; 2513 pc->session_id_counter++;
2339 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); 2514 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id);
2340 if (ps->msgtok == NULL) 2515 if (ps->msgtok == NULL)
2341 ps->msgtok = GNUNET_SERVER_mst_create (&curl_receive_mst_cb, ps); 2516 ps->msgtok = GNUNET_SERVER_mst_create (&curl_receive_mst_cb, ps);
2342 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); 2517 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps);
2343 GNUNET_STATISTICS_update (plugin->env->stats, 2518 GNUNET_STATISTICS_update (plugin->env->stats,
2344 gettext_noop ("# HTTP outbound sessions for peers active"), 2519 gettext_noop ("# HTTP outbound sessions for peers active"),
2345 1, 2520 1,
2346 GNUNET_NO); 2521 GNUNET_NO);
2347 } 2522 }
2348 else 2523 else
2349 { 2524 {
2350#if DEBUG_HTTP 2525#if DEBUG_HTTP
2351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing session found & and no address given: no way to send this message to peer `%s'!\n", GNUNET_i2s(target)); 2526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2527 "No existing session found & and no address given: no way to send this message to peer `%s'!\n",
2528 GNUNET_i2s(target));
2352#endif 2529#endif
2353 return GNUNET_SYSERR; 2530 return GNUNET_SYSERR;
2531 }
2354 } 2532 }
2355 } 2533
2356
2357 if (msgbuf_size >= (ps->queue_length_max - ps->queue_length_cur)) 2534 if (msgbuf_size >= (ps->queue_length_max - ps->queue_length_cur))
2358 { 2535 {
2359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Queue %X full: %u bytes in queue available, message with %u is too big\n", ps, (ps->queue_length_max - ps->queue_length_cur), msgbuf_size); 2536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2360 //return GNUNET_SYSERR; 2537 "Queue %X full: %u bytes in queue available, message with %u is too big\n",
2361 } 2538 ps,
2362 2539 (ps->queue_length_max - ps->queue_length_cur),
2540 msgbuf_size);
2541 //return GNUNET_SYSERR;
2542 }
2543
2363 /* create msg */ 2544 /* create msg */
2364 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); 2545 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
2365 msg->next = NULL; 2546 msg->next = NULL;
@@ -2377,14 +2558,12 @@ http_plugin_send (void *cls,
2377 return GNUNET_SYSERR; 2558 return GNUNET_SYSERR;
2378 if (force_address != GNUNET_YES) 2559 if (force_address != GNUNET_YES)
2379 pc->last_session = ps; 2560 pc->last_session = ps;
2380
2381 if (pc->last_session==NULL) 2561 if (pc->last_session==NULL)
2382 pc->last_session = ps; 2562 pc->last_session = ps;
2383 return msg->size; 2563 return msg->size;
2384} 2564}
2385 2565
2386 2566
2387
2388/** 2567/**
2389 * Function that can be used to force the plugin to disconnect 2568 * Function that can be used to force the plugin to disconnect
2390 * from the given peer and cancel all previous transmissions 2569 * from the given peer and cancel all previous transmissions
@@ -2397,54 +2576,46 @@ static void
2397http_plugin_disconnect (void *cls, 2576http_plugin_disconnect (void *cls,
2398 const struct GNUNET_PeerIdentity *target) 2577 const struct GNUNET_PeerIdentity *target)
2399{ 2578{
2400
2401
2402 struct Plugin *plugin = cls; 2579 struct Plugin *plugin = cls;
2403 struct HTTP_PeerContext *pc = NULL; 2580 struct HTTP_PeerContext *pc = NULL;
2404 struct Session *ps = NULL; 2581 struct Session *ps = NULL;
2405 //struct Session *tmp = NULL;
2406 2582
2407 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &target->hashPubKey); 2583 pc = GNUNET_CONTAINER_multihashmap_get (plugin->peers, &target->hashPubKey);
2408 if (pc==NULL) 2584 if (pc==NULL)
2409 return; 2585 return;
2410 ps = pc->head; 2586 ps = pc->head;
2411
2412 while (ps!=NULL) 2587 while (ps!=NULL)
2413 {
2414 /* Telling transport that session is getting disconnected */
2415 plugin->env->session_end(plugin, target, ps);
2416 if (ps->direction==OUTBOUND)
2417 { 2588 {
2418 if (ps->send_endpoint!=NULL) 2589 /* Telling transport that session is getting disconnected */
2419 { 2590 plugin->env->session_end(plugin, target, ps);
2420 //GNUNET_assert(CURLM_OK == curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint)); 2591 if (ps->direction==OUTBOUND)
2421 //curl_easy_cleanup(ps->send_endpoint); 2592 {
2422 //ps->send_endpoint=NULL; 2593 if (ps->send_endpoint!=NULL)
2423 ps->send_force_disconnect = GNUNET_YES; 2594 {
2424 } 2595 //GNUNET_assert(CURLM_OK == curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint));
2425 if (ps->recv_endpoint!=NULL) 2596 //curl_easy_cleanup(ps->send_endpoint);
2426 { 2597 //ps->send_endpoint=NULL;
2427 //GNUNET_assert(CURLM_OK == curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint)); 2598 ps->send_force_disconnect = GNUNET_YES;
2428 //curl_easy_cleanup(ps->recv_endpoint); 2599 }
2429 //ps->recv_endpoint=NULL; 2600 if (ps->recv_endpoint!=NULL)
2430 ps->recv_force_disconnect = GNUNET_YES; 2601 {
2431 } 2602 //GNUNET_assert(CURLM_OK == curl_multi_remove_handle(plugin->multi_handle,ps->recv_endpoint));
2432 } 2603 //curl_easy_cleanup(ps->recv_endpoint);
2433 2604 //ps->recv_endpoint=NULL;
2434 if (ps->direction==INBOUND) 2605 ps->recv_force_disconnect = GNUNET_YES;
2435 { 2606 }
2436 ps->recv_force_disconnect = GNUNET_YES; 2607 }
2437 ps->send_force_disconnect = GNUNET_YES; 2608 if (ps->direction==INBOUND)
2438 } 2609 {
2439 2610 ps->recv_force_disconnect = GNUNET_YES;
2440 while (ps->pending_msgs_head!=NULL) 2611 ps->send_force_disconnect = GNUNET_YES;
2441 { 2612 }
2442 remove_http_message(ps, ps->pending_msgs_head); 2613 while (ps->pending_msgs_head!=NULL)
2614 remove_http_message(ps, ps->pending_msgs_head);
2615 ps->recv_active = GNUNET_NO;
2616 ps->send_active = GNUNET_NO;
2617 ps=ps->next;
2443 } 2618 }
2444 ps->recv_active = GNUNET_NO;
2445 ps->send_active = GNUNET_NO;
2446 ps=ps->next;
2447 }
2448} 2619}
2449 2620
2450 2621
@@ -2483,28 +2654,28 @@ http_plugin_address_pretty_printer (void *cls,
2483 2654
2484 GNUNET_assert(cls !=NULL); 2655 GNUNET_assert(cls !=NULL);
2485 if (addrlen == sizeof (struct IPv6HttpAddress)) 2656 if (addrlen == sizeof (struct IPv6HttpAddress))
2486 { 2657 {
2487 address = GNUNET_malloc (INET6_ADDRSTRLEN); 2658 address = GNUNET_malloc (INET6_ADDRSTRLEN);
2488 t6 = addr; 2659 t6 = addr;
2489 a6.sin6_addr = t6->ipv6_addr; 2660 a6.sin6_addr = t6->ipv6_addr;
2490 inet_ntop(AF_INET6, &(a6.sin6_addr),address,INET6_ADDRSTRLEN); 2661 inet_ntop(AF_INET6, &(a6.sin6_addr),address,INET6_ADDRSTRLEN);
2491 port = ntohs(t6->u6_port); 2662 port = ntohs(t6->u6_port);
2492 } 2663 }
2493 else if (addrlen == sizeof (struct IPv4HttpAddress)) 2664 else if (addrlen == sizeof (struct IPv4HttpAddress))
2494 { 2665 {
2495 address = GNUNET_malloc (INET_ADDRSTRLEN); 2666 address = GNUNET_malloc (INET_ADDRSTRLEN);
2496 t4 = addr; 2667 t4 = addr;
2497 a4.sin_addr.s_addr = t4->ipv4_addr; 2668 a4.sin_addr.s_addr = t4->ipv4_addr;
2498 inet_ntop(AF_INET, &(a4.sin_addr),address,INET_ADDRSTRLEN); 2669 inet_ntop(AF_INET, &(a4.sin_addr),address,INET_ADDRSTRLEN);
2499 port = ntohs(t4->u_port); 2670 port = ntohs(t4->u_port);
2500 } 2671 }
2501 else 2672 else
2502 { 2673 {
2503 /* invalid address */ 2674 /* invalid address */
2504 GNUNET_break_op (0); 2675 GNUNET_break_op (0);
2505 asc (asc_cls, NULL); 2676 asc (asc_cls, NULL);
2506 return; 2677 return;
2507 } 2678 }
2508 res = GNUNET_asprintf(&ret,"%s://%s:%u/", PROTOCOL_PREFIX, address, port); 2679 res = GNUNET_asprintf(&ret,"%s://%s:%u/", PROTOCOL_PREFIX, address, port);
2509 GNUNET_free (address); 2680 GNUNET_free (address);
2510 GNUNET_assert(res != 0); 2681 GNUNET_assert(res != 0);
@@ -2533,62 +2704,55 @@ http_plugin_address_suggested (void *cls,
2533 struct Plugin *plugin = cls; 2704 struct Plugin *plugin = cls;
2534 struct IPv4HttpAddress *v4; 2705 struct IPv4HttpAddress *v4;
2535 struct IPv6HttpAddress *v6; 2706 struct IPv6HttpAddress *v6;
2536
2537 struct IPv4HttpAddress *tv4 = plugin->ipv4_addr_head; 2707 struct IPv4HttpAddress *tv4 = plugin->ipv4_addr_head;
2538 struct IPv6HttpAddress *tv6 = plugin->ipv6_addr_head; 2708 struct IPv6HttpAddress *tv6 = plugin->ipv6_addr_head;
2539 2709
2540 GNUNET_assert(cls !=NULL); 2710 GNUNET_assert(cls !=NULL);
2541 if ((addrlen != sizeof (struct IPv4HttpAddress)) && 2711 if ((addrlen != sizeof (struct IPv4HttpAddress)) &&
2542 (addrlen != sizeof (struct IPv6HttpAddress))) 2712 (addrlen != sizeof (struct IPv6HttpAddress)))
2543 { 2713 return GNUNET_SYSERR;
2544 return GNUNET_SYSERR;
2545 }
2546 if (addrlen == sizeof (struct IPv4HttpAddress)) 2714 if (addrlen == sizeof (struct IPv4HttpAddress))
2547 { 2715 {
2548 v4 = (struct IPv4HttpAddress *) addr; 2716 v4 = (struct IPv4HttpAddress *) addr;
2549
2550 if (plugin->bind4_address!=NULL) 2717 if (plugin->bind4_address!=NULL)
2551 { 2718 {
2552 if (0 == memcmp (&plugin->bind4_address->sin_addr, &v4->ipv4_addr, sizeof(uint32_t))) 2719 if (0 == memcmp (&plugin->bind4_address->sin_addr, &v4->ipv4_addr, sizeof(uint32_t)))
2553 return GNUNET_OK; 2720 return GNUNET_OK;
2554 else 2721 else
2555 return GNUNET_SYSERR; 2722 return GNUNET_SYSERR;
2556 } 2723 }
2557 while (tv4!=NULL) 2724 while (tv4!=NULL)
2558 { 2725 {
2559 if (0==memcmp (&tv4->ipv4_addr, &v4->ipv4_addr, sizeof(uint32_t))) 2726 if (0==memcmp (&tv4->ipv4_addr, &v4->ipv4_addr, sizeof(uint32_t)))
2560 break; 2727 break;
2561 tv4 = tv4->next; 2728 tv4 = tv4->next;
2562 } 2729 }
2563 if (tv4 != NULL) 2730 if (tv4 != NULL)
2564 return GNUNET_OK; 2731 return GNUNET_OK;
2565 else 2732 else
2566 return GNUNET_SYSERR; 2733 return GNUNET_SYSERR;
2567 } 2734 }
2568 if (addrlen == sizeof (struct IPv6HttpAddress)) 2735 if (addrlen == sizeof (struct IPv6HttpAddress))
2569 { 2736 {
2570 v6 = (struct IPv6HttpAddress *) addr; 2737 v6 = (struct IPv6HttpAddress *) addr;
2571
2572 if (plugin->bind6_address!=NULL) 2738 if (plugin->bind6_address!=NULL)
2573 { 2739 {
2574 if (0 == memcmp (&plugin->bind6_address->sin6_addr, &v6->ipv6_addr, sizeof(struct in6_addr))) 2740 if (0 == memcmp (&plugin->bind6_address->sin6_addr, &v6->ipv6_addr, sizeof(struct in6_addr)))
2575 return GNUNET_OK; 2741 return GNUNET_OK;
2576 else 2742 else
2577 return GNUNET_SYSERR; 2743 return GNUNET_SYSERR;
2578 } 2744 }
2579
2580 while (tv6!=NULL) 2745 while (tv6!=NULL)
2581 { 2746 {
2582 if (0 == memcmp (&tv6->ipv6_addr, &v6->ipv6_addr, sizeof(struct in6_addr))) 2747 if (0 == memcmp (&tv6->ipv6_addr, &v6->ipv6_addr, sizeof(struct in6_addr)))
2583 break; 2748 break;
2584 tv6 = tv6->next; 2749 tv6 = tv6->next;
2585 } 2750 }
2586 if (tv6 !=NULL) 2751 if (tv6 !=NULL)
2587 return GNUNET_OK; 2752 return GNUNET_OK;
2588 else 2753 else
2589 return GNUNET_SYSERR; 2754 return GNUNET_SYSERR;
2590 } 2755 }
2591
2592 return GNUNET_SYSERR; 2756 return GNUNET_SYSERR;
2593} 2757}
2594 2758
@@ -2660,67 +2824,64 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
2660 GNUNET_assert(cls !=NULL); 2824 GNUNET_assert(cls !=NULL);
2661 2825
2662 if (plugin->http_server_daemon_v4 != NULL) 2826 if (plugin->http_server_daemon_v4 != NULL)
2663 { 2827 {
2664 MHD_stop_daemon (plugin->http_server_daemon_v4); 2828 MHD_stop_daemon (plugin->http_server_daemon_v4);
2665 plugin->http_server_daemon_v4 = NULL; 2829 plugin->http_server_daemon_v4 = NULL;
2666 } 2830 }
2667 if (plugin->http_server_daemon_v6 != NULL) 2831 if (plugin->http_server_daemon_v6 != NULL)
2668 { 2832 {
2669 MHD_stop_daemon (plugin->http_server_daemon_v6); 2833 MHD_stop_daemon (plugin->http_server_daemon_v6);
2670 plugin->http_server_daemon_v6 = NULL; 2834 plugin->http_server_daemon_v6 = NULL;
2671 } 2835 }
2672
2673 if ( plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) 2836 if ( plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK)
2674 { 2837 {
2675 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4); 2838 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4);
2676 plugin->http_server_task_v4 = GNUNET_SCHEDULER_NO_TASK; 2839 plugin->http_server_task_v4 = GNUNET_SCHEDULER_NO_TASK;
2677 } 2840 }
2678
2679 if ( plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) 2841 if ( plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK)
2680 { 2842 {
2681 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6); 2843 GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6);
2682 plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK; 2844 plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK;
2683 } 2845 }
2684 2846
2685 while (plugin->ipv4_addr_head!=NULL) 2847 while (plugin->ipv4_addr_head!=NULL)
2686 { 2848 {
2687 ipv4addr = plugin->ipv4_addr_head; 2849 ipv4addr = plugin->ipv4_addr_head;
2688 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,ipv4addr); 2850 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,ipv4addr);
2689 GNUNET_free(ipv4addr); 2851 GNUNET_free(ipv4addr);
2690 } 2852 }
2691 2853
2692 while (plugin->ipv6_addr_head!=NULL) 2854 while (plugin->ipv6_addr_head!=NULL)
2693 { 2855 {
2694 ipv6addr = plugin->ipv6_addr_head; 2856 ipv6addr = plugin->ipv6_addr_head;
2695 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,ipv6addr); 2857 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,ipv6addr);
2696 GNUNET_free(ipv6addr); 2858 GNUNET_free(ipv6addr);
2697 } 2859 }
2698 2860
2699 /* free all peer information */ 2861 /* free all peer information */
2700 if (plugin->peers!=NULL) 2862 if (plugin->peers!=NULL)
2701 { 2863 {
2702 GNUNET_CONTAINER_multihashmap_iterate (plugin->peers, 2864 GNUNET_CONTAINER_multihashmap_iterate (plugin->peers,
2703 &remove_peer_context_Iterator, 2865 &remove_peer_context_Iterator,
2704 plugin); 2866 plugin);
2705 GNUNET_CONTAINER_multihashmap_destroy (plugin->peers); 2867 GNUNET_CONTAINER_multihashmap_destroy (plugin->peers);
2706 } 2868 }
2707 if (plugin->multi_handle!=NULL) 2869 if (plugin->multi_handle!=NULL)
2708 { 2870 {
2709 mret = curl_multi_cleanup(plugin->multi_handle); 2871 mret = curl_multi_cleanup(plugin->multi_handle);
2710#if DEBUG_HTTP 2872 if (CURLM_OK != mret)
2711 if ( CURLM_OK != mret) 2873 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"curl multihandle clean up failed\n"); 2874 "curl multihandle clean up failed\n");
2713#endif 2875 plugin->multi_handle = NULL;
2714 plugin->multi_handle = NULL; 2876 }
2715 }
2716 curl_global_cleanup(); 2877 curl_global_cleanup();
2717 2878
2718 if ( plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) 2879 if ( plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK)
2719 { 2880 {
2720 GNUNET_SCHEDULER_cancel(plugin->http_curl_task); 2881 GNUNET_SCHEDULER_cancel(plugin->http_curl_task);
2721 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; 2882 plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK;
2722 } 2883 }
2723 2884
2724 GNUNET_free_non_null (plugin->bind4_address); 2885 GNUNET_free_non_null (plugin->bind4_address);
2725 GNUNET_free_non_null (plugin->bind6_address); 2886 GNUNET_free_non_null (plugin->bind6_address);
2726 GNUNET_free_non_null(plugin->bind_hostname); 2887 GNUNET_free_non_null(plugin->bind_hostname);
@@ -2732,7 +2893,9 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls)
2732 GNUNET_free (plugin); 2893 GNUNET_free (plugin);
2733 GNUNET_free (api); 2894 GNUNET_free (api);
2734#if DEBUG_HTTP 2895#if DEBUG_HTTP
2735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Unload %s plugin complete...\n", PROTOCOL_PREFIX); 2896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2897 "Unload %s plugin complete...\n",
2898 PROTOCOL_PREFIX);
2736#endif 2899#endif
2737 return NULL; 2900 return NULL;
2738} 2901}
@@ -2742,28 +2905,26 @@ static char *
2742load_certificate( const char * file ) 2905load_certificate( const char * file )
2743{ 2906{
2744 struct GNUNET_DISK_FileHandle * gn_file; 2907 struct GNUNET_DISK_FileHandle * gn_file;
2745
2746 struct stat fstat; 2908 struct stat fstat;
2747 char * text = NULL; 2909 char * text = NULL;
2748 2910
2749 if (0!=STAT(file, &fstat)) 2911 if (0!=STAT(file, &fstat))
2750 return NULL; 2912 return NULL;
2751 text = GNUNET_malloc (fstat.st_size+1); 2913 text = GNUNET_malloc (fstat.st_size+1);
2752 gn_file = GNUNET_DISK_file_open(file,GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ); 2914 gn_file = GNUNET_DISK_file_open(file, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_USER_READ);
2753 if (gn_file==NULL) 2915 if (gn_file==NULL)
2754 { 2916 {
2755 GNUNET_free(text); 2917 GNUNET_free(text);
2756 return NULL; 2918 return NULL;
2757 } 2919 }
2758 if (GNUNET_SYSERR == GNUNET_DISK_file_read(gn_file, text, fstat.st_size)) 2920 if (GNUNET_SYSERR == GNUNET_DISK_file_read(gn_file, text, fstat.st_size))
2759 { 2921 {
2760 GNUNET_free(text); 2922 GNUNET_free(text);
2761 GNUNET_DISK_file_close(gn_file); 2923 GNUNET_DISK_file_close(gn_file);
2762 return NULL; 2924 return NULL;
2763 } 2925 }
2764 text[fstat.st_size] = '\0'; 2926 text[fstat.st_size] = '\0';
2765 GNUNET_DISK_file_close(gn_file); 2927 GNUNET_DISK_file_close(gn_file);
2766
2767 return text; 2928 return text;
2768} 2929}
2769#endif 2930#endif
@@ -2788,9 +2949,13 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
2788 2949
2789 GNUNET_assert(cls !=NULL); 2950 GNUNET_assert(cls !=NULL);
2790#if DEBUG_HTTP 2951#if DEBUG_HTTP
2791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting %s plugin...\n", PROTOCOL_PREFIX); 2952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2953 "Starting %s plugin...\n",
2954 PROTOCOL_PREFIX);
2792#endif 2955#endif
2793 GNUNET_asprintf(&component_name,"transport-%s",PROTOCOL_PREFIX); 2956 GNUNET_asprintf(&component_name,
2957 "transport-%s",
2958 PROTOCOL_PREFIX);
2794 2959
2795 plugin = GNUNET_malloc (sizeof (struct Plugin)); 2960 plugin = GNUNET_malloc (sizeof (struct Plugin));
2796 plugin->stats = env->stats; 2961 plugin->stats = env->stats;
@@ -2809,33 +2974,34 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
2809 api->address_to_string = &http_plugin_address_to_string; 2974 api->address_to_string = &http_plugin_address_to_string;
2810 2975
2811 /* Hashing our identity to use it in URLs */ 2976 /* Hashing our identity to use it in URLs */
2812 GNUNET_CRYPTO_hash_to_enc ( &(plugin->env->my_identity->hashPubKey), &plugin->my_ascii_hash_ident); 2977 GNUNET_CRYPTO_hash_to_enc (&(plugin->env->my_identity->hashPubKey),
2978 &plugin->my_ascii_hash_ident);
2813 2979
2814 /* Use IPv6? */ 2980 /* Use IPv6? */
2815 if (GNUNET_CONFIGURATION_have_value (env->cfg, 2981 if (GNUNET_CONFIGURATION_have_value (env->cfg,
2816 component_name, "USE_IPv6")) 2982 component_name, "USE_IPv6"))
2817 { 2983 {
2818 plugin->use_ipv6 = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 2984 plugin->use_ipv6 = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2819 component_name, 2985 component_name,
2820 "USE_IPv6"); 2986 "USE_IPv6");
2821 } 2987 }
2822 /* Use IPv4? */ 2988 /* Use IPv4? */
2823 if (GNUNET_CONFIGURATION_have_value (env->cfg, 2989 if (GNUNET_CONFIGURATION_have_value (env->cfg,
2824 component_name, "USE_IPv4")) 2990 component_name, "USE_IPv4"))
2825 { 2991 {
2826 plugin->use_ipv4 = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 2992 plugin->use_ipv4 = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2827 component_name,"USE_IPv4"); 2993 component_name,"USE_IPv4");
2828 } 2994 }
2829 /* Reading port number from config file */ 2995 /* Reading port number from config file */
2830 if ((GNUNET_OK != 2996 if ((GNUNET_OK !=
2831 GNUNET_CONFIGURATION_get_value_number (env->cfg, 2997 GNUNET_CONFIGURATION_get_value_number (env->cfg,
2832 component_name, 2998 component_name,
2833 "PORT", 2999 "PORT",
2834 &port)) || 3000 &port)) ||
2835 (port > 65535) ) 3001 (port > 65535) )
2836 { 3002 {
2837 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 3003 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2838 component_name, 3004 component_name,
2839 _("Require valid port number for transport plugin `%s' in configuration!\n"), 3005 _("Require valid port number for transport plugin `%s' in configuration!\n"),
2840 PROTOCOL_PREFIX); 3006 PROTOCOL_PREFIX);
2841 GNUNET_free(component_name); 3007 GNUNET_free(component_name);
@@ -2844,151 +3010,153 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
2844 } 3010 }
2845 3011
2846 /* Reading ipv4 addresse to bind to from config file */ 3012 /* Reading ipv4 addresse to bind to from config file */
2847 if ((plugin->use_ipv4==GNUNET_YES) && (GNUNET_CONFIGURATION_have_value (env->cfg, 3013 if ( (plugin->use_ipv4==GNUNET_YES) &&
2848 component_name, "BINDTO4"))) 3014 (GNUNET_CONFIGURATION_have_value (env->cfg,
2849 { 3015 component_name, "BINDTO4")))
2850 GNUNET_break (GNUNET_OK == 3016 {
2851 GNUNET_CONFIGURATION_get_value_string (env->cfg, 3017 GNUNET_break (GNUNET_OK ==
2852 component_name, 3018 GNUNET_CONFIGURATION_get_value_string (env->cfg,
2853 "BINDTO4",
2854 &plugin->bind_hostname));
2855 plugin->bind4_address = GNUNET_malloc(sizeof(struct sockaddr_in));
2856 plugin->bind4_address->sin_family = AF_INET;
2857 plugin->bind4_address->sin_port = htons (port);
2858
2859 if (plugin->bind_hostname!=NULL)
2860 {
2861 if (inet_pton(AF_INET,plugin->bind_hostname, &plugin->bind4_address->sin_addr)<=0)
2862 {
2863 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2864 component_name, 3019 component_name,
2865 _("Misconfigured address to bind to in configuration!\n")); 3020 "BINDTO4",
2866 GNUNET_free(plugin->bind4_address); 3021 &plugin->bind_hostname));
2867 GNUNET_free(plugin->bind_hostname); 3022 plugin->bind4_address = GNUNET_malloc(sizeof(struct sockaddr_in));
2868 plugin->bind_hostname = NULL; 3023 plugin->bind4_address->sin_family = AF_INET;
2869 plugin->bind4_address = NULL; 3024 plugin->bind4_address->sin_port = htons (port);
2870 } 3025
2871 } 3026 if (plugin->bind_hostname!=NULL)
2872 } 3027 {
2873 3028 if (inet_pton(AF_INET,plugin->bind_hostname, &plugin->bind4_address->sin_addr)<=0)
3029 {
3030 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
3031 component_name,
3032 _("Misconfigured address to bind to in configuration!\n"));
3033 GNUNET_free(plugin->bind4_address);
3034 GNUNET_free(plugin->bind_hostname);
3035 plugin->bind_hostname = NULL;
3036 plugin->bind4_address = NULL;
3037 }
3038 }
3039 }
3040
2874 /* Reading ipv4 addresse to bind to from config file */ 3041 /* Reading ipv4 addresse to bind to from config file */
2875 if ((plugin->use_ipv6==GNUNET_YES) && (GNUNET_CONFIGURATION_have_value (env->cfg, 3042 if ( (plugin->use_ipv6==GNUNET_YES) &&
2876 component_name, "BINDTO6"))) 3043 (GNUNET_CONFIGURATION_have_value (env->cfg,
2877 { 3044 component_name, "BINDTO6")))
2878 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (env->cfg, 3045 {
2879 component_name, 3046 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (env->cfg,
2880 "BINDTO6", 3047 component_name,
2881 &plugin->bind_hostname)) 3048 "BINDTO6",
2882 { 3049 &plugin->bind_hostname))
2883 plugin->bind6_address = GNUNET_malloc(sizeof(struct sockaddr_in6)); 3050 {
2884 plugin->bind6_address->sin6_family = AF_INET6; 3051 plugin->bind6_address = GNUNET_malloc(sizeof(struct sockaddr_in6));
2885 plugin->bind6_address->sin6_port = htons (port); 3052 plugin->bind6_address->sin6_family = AF_INET6;
2886 if (plugin->bind_hostname!=NULL) 3053 plugin->bind6_address->sin6_port = htons (port);
2887 { 3054 if (plugin->bind_hostname!=NULL)
2888 if (inet_pton(AF_INET6,plugin->bind_hostname, &plugin->bind6_address->sin6_addr)<=0) 3055 {
2889 { 3056 if (inet_pton(AF_INET6,plugin->bind_hostname, &plugin->bind6_address->sin6_addr)<=0)
2890 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 3057 {
2891 component_name, 3058 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2892 _("Misconfigured address to bind to in configuration!\n")); 3059 component_name,
2893 GNUNET_free(plugin->bind6_address); 3060 _("Misconfigured address to bind to in configuration!\n"));
2894 GNUNET_free(plugin->bind_hostname); 3061 GNUNET_free(plugin->bind6_address);
2895 plugin->bind_hostname = NULL; 3062 GNUNET_free(plugin->bind_hostname);
2896 plugin->bind6_address = NULL; 3063 plugin->bind_hostname = NULL;
2897 } 3064 plugin->bind6_address = NULL;
2898 } 3065 }
2899 } 3066 }
2900 } 3067 }
2901 3068 }
3069
2902#if BUILD_HTTPS 3070#if BUILD_HTTPS
2903 /* Reading HTTPS crypto related configuration */ 3071 /* Reading HTTPS crypto related configuration */
2904 /* Get crypto init string from config */ 3072 /* Get crypto init string from config */
2905 if (GNUNET_CONFIGURATION_have_value (env->cfg, 3073 if (GNUNET_CONFIGURATION_have_value (env->cfg,
2906 "transport-https", "CRYPTO_INIT")) 3074 "transport-https", "CRYPTO_INIT"))
2907 { 3075 {
2908 GNUNET_CONFIGURATION_get_value_string (env->cfg, 3076 GNUNET_CONFIGURATION_get_value_string (env->cfg,
2909 "transport-https", 3077 "transport-https",
2910 "CRYPTO_INIT", 3078 "CRYPTO_INIT",
2911 &plugin->crypto_init); 3079 &plugin->crypto_init);
2912 } 3080 }
2913 else 3081 else
2914 { 3082 {
2915 GNUNET_asprintf(&plugin->crypto_init,"NORMAL"); 3083 GNUNET_asprintf(&plugin->crypto_init,"NORMAL");
2916 } 3084 }
2917 3085
2918/* Get private key file from config */ 3086 /* Get private key file from config */
2919 if (GNUNET_CONFIGURATION_have_value (env->cfg, 3087 if (GNUNET_CONFIGURATION_have_value (env->cfg,
2920 "transport-https", "KEY_FILE")) 3088 "transport-https", "KEY_FILE"))
2921 { 3089 {
2922 GNUNET_CONFIGURATION_get_value_string (env->cfg, 3090 GNUNET_CONFIGURATION_get_value_string (env->cfg,
2923 "transport-https", 3091 "transport-https",
2924 "KEY_FILE", 3092 "KEY_FILE",
2925 &key_file); 3093 &key_file);
2926 } 3094 }
2927 if (key_file==NULL) 3095 if (key_file==NULL)
2928 GNUNET_asprintf(&key_file,"https.key"); 3096 GNUNET_asprintf(&key_file,"https.key");
2929 3097
2930/* Get private key file from config */ 3098 /* Get private key file from config */
2931 if (GNUNET_CONFIGURATION_have_value (env->cfg,"transport-https", "CERT_FILE")) 3099 if (GNUNET_CONFIGURATION_have_value (env->cfg,"transport-https", "CERT_FILE"))
2932 { 3100 {
2933 GNUNET_CONFIGURATION_get_value_string (env->cfg, 3101 GNUNET_CONFIGURATION_get_value_string (env->cfg,
2934 "transport-https", 3102 "transport-https",
2935 "CERT_FILE", 3103 "CERT_FILE",
2936 &cert_file); 3104 &cert_file);
2937 } 3105 }
2938 if (cert_file==NULL) 3106 if (cert_file==NULL)
2939 GNUNET_asprintf(&cert_file,"https.cert"); 3107 GNUNET_asprintf(&cert_file,"https.cert");
2940 3108
2941 /* read key & certificates from file */ 3109 /* read key & certificates from file */
2942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading TLS certificate `%s' `%s'\n", key_file, cert_file); 3110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3111 "Loading TLS certificate `%s' `%s'\n",
3112 key_file, cert_file);
2943 3113
2944 plugin->key = load_certificate( key_file ); 3114 plugin->key = load_certificate( key_file );
2945 plugin->cert = load_certificate( cert_file ); 3115 plugin->cert = load_certificate( cert_file );
2946 3116
2947 if ((plugin->key==NULL) || (plugin->cert==NULL)) 3117 if ((plugin->key==NULL) || (plugin->cert==NULL))
2948 { 3118 {
2949 char * cmd; 3119 char * cmd;
2950 int ret = 0; 3120 int ret = 0;
2951 GNUNET_asprintf(&cmd,"gnunet-transport-certificate-creation %s %s", key_file, cert_file); 3121 GNUNET_asprintf(&cmd,
2952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No usable TLS certificate found, creating certificate \n"); 3122 "gnunet-transport-certificate-creation %s %s",
2953 ret = system(cmd); 3123 key_file, cert_file);
2954 3124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2955 if (ret != 0) 3125 "No usable TLS certificate found, creating certificate \n");
2956 { 3126 ret = system(cmd);
2957 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 3127 if (ret != 0)
2958 "https", 3128 {
2959 _("Could not create a new TLS certificate, shell script `%s' failed!\n"),cmd, 3129 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2960 "transport-https"); 3130 "https",
2961 GNUNET_free (key_file); 3131 _("Could not create a new TLS certificate, shell script `%s' failed!\n"),cmd,
2962 GNUNET_free (cert_file); 3132 "transport-https");
2963 GNUNET_free (component_name); 3133 GNUNET_free (key_file);
2964 3134 GNUNET_free (cert_file);
2965 LIBGNUNET_PLUGIN_TRANSPORT_DONE(api); 3135 GNUNET_free (component_name);
2966 GNUNET_free (cmd); 3136 LIBGNUNET_PLUGIN_TRANSPORT_DONE(api);
2967 return NULL;
2968 }
2969
2970 GNUNET_free (cmd); 3137 GNUNET_free (cmd);
2971 3138 return NULL;
2972 plugin->key = load_certificate( key_file ); 3139 }
2973 plugin->cert = load_certificate( cert_file ); 3140 GNUNET_free (cmd);
2974 3141 plugin->key = load_certificate( key_file );
2975 if ((plugin->key==NULL) || (plugin->cert==NULL)) 3142 plugin->cert = load_certificate( cert_file );
2976 { 3143 if ((plugin->key==NULL) || (plugin->cert==NULL))
2977 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 3144 {
2978 "https", 3145 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2979 _("No usable TLS certificate found and creating one failed! \n"), 3146 "https",
2980 "transport-https"); 3147 _("No usable TLS certificate found and creating one failed! \n"),
2981 GNUNET_free (key_file); 3148 "transport-https");
2982 GNUNET_free (cert_file); 3149 GNUNET_free (key_file);
2983 GNUNET_free (component_name); 3150 GNUNET_free (cert_file);
2984 3151 GNUNET_free (component_name);
2985 LIBGNUNET_PLUGIN_TRANSPORT_DONE(api); 3152
2986 return NULL; 3153 LIBGNUNET_PLUGIN_TRANSPORT_DONE(api);
2987 } 3154 return NULL;
2988 } 3155 }
3156 }
2989 GNUNET_free (key_file); 3157 GNUNET_free (key_file);
2990 GNUNET_free (cert_file); 3158 GNUNET_free (cert_file);
2991 3159
2992 GNUNET_assert((plugin->key!=NULL) && (plugin->cert!=NULL)); 3160 GNUNET_assert((plugin->key!=NULL) && (plugin->cert!=NULL));
2993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n"); 3161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n");
2994#endif 3162#endif
@@ -2997,123 +3165,138 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls)
2997 plugin->port_inbound = port; 3165 plugin->port_inbound = port;
2998 gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; 3166 gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT;
2999 unsigned int timeout = (gn_timeout.rel_value) / 1000; 3167 unsigned int timeout = (gn_timeout.rel_value) / 1000;
3000 if ((plugin->http_server_daemon_v6 == NULL) && (plugin->use_ipv6 == GNUNET_YES) && (port != 0)) 3168 if ( (plugin->http_server_daemon_v6 == NULL) &&
3001 { 3169 (plugin->use_ipv6 == GNUNET_YES) &&
3002 struct sockaddr * tmp = (struct sockaddr *) plugin->bind6_address; 3170 (port != 0) )
3003 plugin->http_server_daemon_v6 = MHD_start_daemon ( 3171 {
3172 struct sockaddr * tmp = (struct sockaddr *) plugin->bind6_address;
3173 plugin->http_server_daemon_v6 = MHD_start_daemon (
3004#if DEBUG_MHD 3174#if DEBUG_MHD
3005 MHD_USE_DEBUG | 3175 MHD_USE_DEBUG |
3006#endif 3176#endif
3007#if BUILD_HTTPS 3177#if BUILD_HTTPS
3008 MHD_USE_SSL | 3178 MHD_USE_SSL |
3009#endif 3179#endif
3010 MHD_USE_IPv6, 3180 MHD_USE_IPv6,
3011 port, 3181 port,
3012 &mhd_accept_cb, 3182 &mhd_accept_cb,
3013 plugin , &mhd_access_cb, plugin, 3183 plugin , &mhd_access_cb, plugin,
3014 MHD_OPTION_SOCK_ADDR, tmp, 3184 MHD_OPTION_SOCK_ADDR, tmp,
3015 MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, 3185 MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32,
3016 //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, 3186 //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6,
3017#if BUILD_HTTPS 3187#if BUILD_HTTPS
3018 MHD_OPTION_HTTPS_PRIORITIES, plugin->crypto_init, 3188 MHD_OPTION_HTTPS_PRIORITIES, plugin->crypto_init,
3019 MHD_OPTION_HTTPS_MEM_KEY, plugin->key, 3189 MHD_OPTION_HTTPS_MEM_KEY, plugin->key,
3020 MHD_OPTION_HTTPS_MEM_CERT, plugin->cert, 3190 MHD_OPTION_HTTPS_MEM_CERT, plugin->cert,
3021#endif 3191#endif
3022 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, 3192 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout,
3023 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE), 3193 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE),
3024 MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL, 3194 MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL,
3025 MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log, 3195 MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log,
3026 MHD_OPTION_END); 3196 MHD_OPTION_END);
3027 } 3197 }
3028 if ((plugin->http_server_daemon_v4 == NULL) && (plugin->use_ipv4 == GNUNET_YES) && (port != 0)) 3198 if ( (plugin->http_server_daemon_v4 == NULL) &&
3029 { 3199 (plugin->use_ipv4 == GNUNET_YES) &&
3030 plugin->http_server_daemon_v4 = MHD_start_daemon ( 3200 (port != 0) )
3201 {
3202 plugin->http_server_daemon_v4 = MHD_start_daemon (
3031#if DEBUG_MHD 3203#if DEBUG_MHD
3032 MHD_USE_DEBUG | 3204 MHD_USE_DEBUG |
3033#endif 3205#endif
3034#if BUILD_HTTPS 3206#if BUILD_HTTPS
3035 MHD_USE_SSL | 3207 MHD_USE_SSL |
3036#endif 3208#endif
3037 MHD_NO_FLAG, 3209 MHD_NO_FLAG,
3038 port, 3210 port,
3039 &mhd_accept_cb, 3211 &mhd_accept_cb,
3040 plugin , &mhd_access_cb, plugin, 3212 plugin , &mhd_access_cb, plugin,
3041 MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *)plugin->bind4_address, 3213 MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *)plugin->bind4_address,
3042 MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, 3214 MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32,
3043 //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, 3215 //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6,
3044#if BUILD_HTTPS 3216#if BUILD_HTTPS
3045 MHD_OPTION_HTTPS_PRIORITIES, plugin->crypto_init, 3217 MHD_OPTION_HTTPS_PRIORITIES, plugin->crypto_init,
3046 MHD_OPTION_HTTPS_MEM_KEY, plugin->key, 3218 MHD_OPTION_HTTPS_MEM_KEY, plugin->key,
3047 MHD_OPTION_HTTPS_MEM_CERT, plugin->cert, 3219 MHD_OPTION_HTTPS_MEM_CERT, plugin->cert,
3048#endif 3220#endif
3049 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, 3221 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout,
3050 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE), 3222 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (2 * GNUNET_SERVER_MAX_MESSAGE_SIZE),
3051 MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL, 3223 MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL,
3052 MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log, 3224 MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, plugin->mhd_log,
3053 MHD_OPTION_END); 3225 MHD_OPTION_END);
3054 } 3226 }
3055 if (plugin->http_server_daemon_v4 != NULL) 3227 if (plugin->http_server_daemon_v4 != NULL)
3056 plugin->http_server_task_v4 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v4); 3228 plugin->http_server_task_v4 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v4);
3057 if (plugin->http_server_daemon_v6 != NULL) 3229 if (plugin->http_server_daemon_v6 != NULL)
3058 plugin->http_server_task_v6 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v6); 3230 plugin->http_server_task_v6 = http_server_daemon_prepare (plugin, plugin->http_server_daemon_v6);
3059 3231
3060 3232
3061 if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) 3233 if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK)
3062 { 3234 {
3063#if DEBUG_HTTP 3235#if DEBUG_HTTP
3064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 bound to %s with port %u\n",(plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address",port); 3236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3237 "Starting MHD with IPv4 bound to %s with port %u\n",
3238 (plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address",port);
3065#endif 3239#endif
3066 } 3240 }
3067 else if ((plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) && (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK)) 3241 else if ( (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) &&
3068 { 3242 (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) )
3243 {
3069#if DEBUG_HTTP 3244#if DEBUG_HTTP
3070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv6 bound to %s with port %u\n",(plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address", port); 3245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3246 "Starting MHD with IPv6 bound to %s with port %u\n",
3247 (plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address", port);
3071#endif 3248#endif
3072 } 3249 }
3073 else if ((plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) && (plugin->http_server_task_v4 == GNUNET_SCHEDULER_NO_TASK)) 3250 else if ( (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) &&
3074 { 3251 (plugin->http_server_task_v4 == GNUNET_SCHEDULER_NO_TASK) )
3252 {
3075#if DEBUG_HTTP 3253#if DEBUG_HTTP
3076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 and IPv6 bound to %s with port %u\n",(plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address", port); 3254 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3255 "Starting MHD with IPv4 and IPv6 bound to %s with port %u\n",
3256 (plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address",
3257 port);
3077#endif 3258#endif
3078 } 3259 }
3079 else 3260 else
3080 { 3261 {
3081 char * tmp = NULL; 3262 char * tmp = NULL;
3082 if ((plugin->use_ipv6 == GNUNET_YES) && (plugin->use_ipv4 == GNUNET_YES)) 3263 if ((plugin->use_ipv6 == GNUNET_YES) && (plugin->use_ipv4 == GNUNET_YES))
3083 GNUNET_asprintf(&tmp,"with IPv4 and IPv6 enabled"); 3264 GNUNET_asprintf(&tmp,"with IPv4 and IPv6 enabled");
3084 if ((plugin->use_ipv6 == GNUNET_NO) && (plugin->use_ipv4 == GNUNET_YES)) 3265 if ((plugin->use_ipv6 == GNUNET_NO) && (plugin->use_ipv4 == GNUNET_YES))
3085 GNUNET_asprintf(&tmp,"with IPv4 enabled"); 3266 GNUNET_asprintf(&tmp,"with IPv4 enabled");
3086 if ((plugin->use_ipv6 == GNUNET_YES) && (plugin->use_ipv4 == GNUNET_NO)) 3267 if ((plugin->use_ipv6 == GNUNET_YES) && (plugin->use_ipv4 == GNUNET_NO))
3087 GNUNET_asprintf(&tmp,"with IPv6 enabled"); 3268 GNUNET_asprintf(&tmp,"with IPv6 enabled");
3088 if ((plugin->use_ipv6 == GNUNET_NO) && (plugin->use_ipv4 == GNUNET_NO)) 3269 if ((plugin->use_ipv6 == GNUNET_NO) && (plugin->use_ipv4 == GNUNET_NO))
3089 GNUNET_asprintf(&tmp,"with NO IP PROTOCOL enabled"); 3270 GNUNET_asprintf(&tmp,"with NO IP PROTOCOL enabled");
3090 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,_("HTTP Server with %s could not be started on port %u! %s plugin failed!\n"),tmp, port, PROTOCOL_PREFIX); 3271 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3091 GNUNET_free (tmp); 3272 _("HTTP Server with %s could not be started on port %u! %s plugin failed!\n"),
3092 GNUNET_free (component_name); 3273 tmp, port, PROTOCOL_PREFIX);
3093 LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); 3274 GNUNET_free (tmp);
3094 return NULL; 3275 GNUNET_free (component_name);
3095 } 3276 LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
3096 3277 return NULL;
3278 }
3279
3097 /* Initializing cURL */ 3280 /* Initializing cURL */
3098 curl_global_init(CURL_GLOBAL_ALL); 3281 curl_global_init(CURL_GLOBAL_ALL);
3099 plugin->multi_handle = curl_multi_init(); 3282 plugin->multi_handle = curl_multi_init();
3100 3283
3101 if ( NULL == plugin->multi_handle ) 3284 if ( NULL == plugin->multi_handle )
3102 { 3285 {
3103 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 3286 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
3104 component_name, 3287 component_name,
3105 _("Could not initialize curl multi handle, failed to start %s plugin!\n"), 3288 _("Could not initialize curl multi handle, failed to start %s plugin!\n"),
3106 PROTOCOL_PREFIX); 3289 PROTOCOL_PREFIX);
3107 GNUNET_free(component_name); 3290 GNUNET_free(component_name);
3108 LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); 3291 LIBGNUNET_PLUGIN_TRANSPORT_DONE (api);
3109 return NULL; 3292 return NULL;
3110 } 3293 }
3111 3294
3112 plugin->peers = GNUNET_CONTAINER_multihashmap_create (10); 3295 plugin->peers = GNUNET_CONTAINER_multihashmap_create (10);
3113 GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); 3296 GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
3114 3297
3115 GNUNET_free(component_name); 3298 GNUNET_free(component_name);
3116 return api; 3299 return api;
3117} 3300}
3118 3301
3119/* end of gnunet_transport_plugin.http.c */ 3302/* end of plugin_transport_http.c */