X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fplugin_transport_http.c;h=f879012c92b25ec74c45f489e6dfb57f8e9a0a64;hb=311e9e5636fdd21172f9bca63cc8746c654ae526;hp=775b260c73b9a707dce45956fd8c9adf509cb269;hpb=774871023c74dccb7c9514493cf358785667ed85;p=oweals%2Fgnunet.git diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index 775b260c7..f879012c9 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c @@ -35,27 +35,29 @@ #include "gnunet_resolver_service.h" #include "gnunet_server_lib.h" #include "gnunet_container_lib.h" -#include "plugin_transport.h" +#include "gnunet_transport_plugin.h" #include "gnunet_os_lib.h" #include "microhttpd.h" #include #if BUILD_HTTPS #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_https_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_https_done #define LIBGNUNET_PLUGIN_TRANSPORT_COMPONENT transport_https #define PROTOCOL_PREFIX "https" #else #define LIBGNUNET_PLUGIN_TRANSPORT_INIT libgnunet_plugin_transport_http_init +#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_done #define LIBGNUNET_PLUGIN_TRANSPORT_COMPONENT transport_http #define PROTOCOL_PREFIX "http" #endif -#define DEBUG_HTTP GNUNET_YES +#define DEBUG_HTTP GNUNET_NO #define DEBUG_CURL GNUNET_NO #define DEBUG_MHD GNUNET_NO #define DEBUG_CONNECTIONS GNUNET_NO #define DEBUG_SESSION_SELECTION GNUNET_NO - +#define DEBUG_SCHEDULING GNUNET_NO #define CURL_TCP_NODELAY GNUNET_YES #define INBOUND GNUNET_NO @@ -93,6 +95,16 @@ */ struct IPv4HttpAddress { + /** + * Linked list next + */ + struct IPv4HttpAddress * next; + + /** + * Linked list previous + */ + struct IPv4HttpAddress * prev; + /** * IPv4 address, in network byte order. */ @@ -111,6 +123,16 @@ struct IPv4HttpAddress */ struct IPv6HttpAddress { + /** + * Linked list next + */ + struct IPv6HttpAddress * next; + + /** + * Linked list previous + */ + struct IPv6HttpAddress * prev; + /** * IPv6 address. */ @@ -201,6 +223,16 @@ struct HTTP_PeerContext * Last session used to send data */ struct Session * last_session; + + /** + * The task resetting inbound quota delay + */ + GNUNET_SCHEDULER_TaskIdentifier reset_task; + + /** + * Delay from transport service inbound quota tracker when to receive data again + */ + struct GNUNET_TIME_Relative delay; }; @@ -295,6 +327,7 @@ struct Session */ unsigned int recv_force_disconnect; + /** * id for next session * NOTE: 0 is not an ID, zero is not defined. A correct ID is always > 0 @@ -314,6 +347,17 @@ struct Session * inbound session: mhd_connection * */ void * recv_endpoint; + + /** + * Current queue size + */ + size_t queue_length_cur; + + /** + * Max queue size + */ + size_t queue_length_max; + }; /** @@ -334,7 +378,7 @@ struct Plugin /** * Plugin Port */ - unsigned int port_inbound; + uint16_t port_inbound; struct GNUNET_CONTAINER_MultiHashMap *peers; @@ -368,6 +412,26 @@ struct Plugin */ CURLM * multi_handle; + /** + * ipv4 DLL head + */ + struct IPv4HttpAddress * ipv4_addr_head; + + /** + * ipv4 DLL tail + */ + struct IPv4HttpAddress * ipv4_addr_tail; + + /** + * ipv6 DLL head + */ + struct IPv6HttpAddress * ipv6_addr_head; + + /** + * ipv6 DLL tail + */ + struct IPv6HttpAddress * ipv6_addr_tail; + /** * Our ASCII encoded, hashed peer identity * This string is used to distinguish between connections and is added to the urls @@ -404,6 +468,7 @@ struct Plugin */ void * mhd_log; + /* only needed for HTTPS plugin */ #if BUILD_HTTPS /* The certificate MHD uses as an \0 terminated string */ char * cert; @@ -447,33 +512,53 @@ static void http_server_daemon_v6_run (void *cls, const struct GNUNET_SCHEDULER_ /** * Function setting up curl handle and selecting message to send - * @param cls plugin - * @param ses session to send data to - * @param con connection - * @return bytes sent to peer + * + * @param plugin plugin + * @param ps session + * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok */ -static ssize_t send_check_connections (void *cls, struct Session *ps); +static int send_check_connections (struct Plugin *plugin, struct Session *ps); /** * Function setting up file descriptors and scheduling task to run - * @param cls closure - * @param ses session to send data to - * @param + * + * @param plugin plugin as closure + * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok */ -static int curl_schedule(void *cls ); +static int curl_schedule (struct Plugin *plugin); + +/** + * Task scheduled to reset the inbound quota delay for a specific peer + * @param cls plugin as closure + * @param tc task context + */ +static void reset_inbound_quota_delay (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct HTTP_PeerContext * pc; + + GNUNET_assert(cls !=NULL); + + pc = (struct HTTP_PeerContext *) cls; + pc->reset_task = GNUNET_SCHEDULER_NO_TASK; + + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + pc->delay = GNUNET_TIME_relative_get_zero (); +} /** * Creates a valid url from passed address and id - * @param cls plugin as closure + * @param plugin plugin * @param addr address to create url from * @param addrlen address lenth * @param id session id * @return the created url */ -static char * create_url(void * cls, const void * addr, size_t addrlen, size_t id) +static char * create_url(struct Plugin *plugin, const void * addr, size_t addrlen, size_t id) { - struct Plugin *plugin = cls; char *url = NULL; char *addr_str = (char *) http_plugin_address_to_string(NULL, addr, addrlen); @@ -501,8 +586,8 @@ static int remove_http_message (struct Session * ps, struct HTTP_Message * msg) /** * Iterator to remove peer context * @param cls the plugin - * @key the peers public key hashcode - * @value the peer context + * @param key the peers public key hashcode + * @param value the peer context * @return GNUNET_YES on success */ int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value) @@ -661,14 +746,19 @@ process_interfaces (void *cls, { if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) { - plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4); + plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); + return GNUNET_OK; } + GNUNET_free (t4); + return GNUNET_OK; } else { - plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,t4); + plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); + return GNUNET_OK; } - GNUNET_free (t4); } else if ((af == AF_INET6) && (plugin->use_ipv6 == GNUNET_YES) && (plugin->bind4_address == NULL)) { @@ -687,18 +777,19 @@ process_interfaces (void *cls, &((struct sockaddr_in6 *) addr)->sin6_addr, sizeof (struct in6_addr)); t6->u6_port = htons (plugin->port_inbound); - plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); + plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6); + return GNUNET_OK; } + GNUNET_free (t6); + return GNUNET_OK; } - else - { - memcpy (&t6->ipv6_addr, - &((struct sockaddr_in6 *) addr)->sin6_addr, - sizeof (struct in6_addr)); - t6->u6_port = htons (plugin->port_inbound); - plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); - } - GNUNET_free (t6); + memcpy (&t6->ipv6_addr, + &((struct sockaddr_in6 *) addr)->sin6_addr, + sizeof (struct in6_addr)); + t6->u6_port = htons (plugin->port_inbound); + GNUNET_CONTAINER_DLL_insert(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,t6); + plugin->env->notify_address(plugin->env->cls,PROTOCOL_PREFIX,t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); } return GNUNET_OK; } @@ -718,19 +809,14 @@ void mhd_logger (void * arg, const char * fmt, va_list ap) GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"MHD: %s \n", text); } -/** - * Callback called by MHD when a connection is terminated - * @param cls closure - * @param connection the terminated connection - * @httpSessionCache the mhd session reference - */ + static void mhd_termination_cb (void *cls, struct MHD_Connection * connection, void **httpSessionCache) { struct Session * ps = *httpSessionCache; if (ps == NULL) return; struct HTTP_PeerContext * pc = ps->peercontext; - + if (connection==ps->recv_endpoint) { #if DEBUG_CONNECTIONS @@ -773,7 +859,7 @@ static void mhd_write_mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) { - + struct GNUNET_TIME_Relative delay; struct Session *ps = cls; GNUNET_assert(ps != NULL); @@ -787,11 +873,31 @@ static void mhd_write_mst_cb (void *cls, ntohs(message->size), GNUNET_i2s(&(ps->peercontext)->identity),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); #endif - pc->plugin->env->receive (ps->peercontext->plugin->env->cls, - &pc->identity, - message, 1, ps, - NULL, - 0); + struct GNUNET_TRANSPORT_ATS_Information distance[2]; + distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); + distance[0].value = htonl (1); + distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); + distance[1].value = htonl (0); + + delay = pc->plugin->env->receive (ps->peercontext->plugin->env->cls, + &pc->identity, + message, + (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, + 2, + ps, + NULL, + 0); + pc->delay = delay; + if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (pc->reset_task); + + if (delay.rel_value > 0) + { +#if DEBUG_HTTP + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.rel_value); +#endif + pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc); + } } /** @@ -804,8 +910,7 @@ static void mhd_write_mst_cb (void *cls, * */ static int -mhd_accept_cb (void *cls, - const struct sockaddr *addr, socklen_t addr_len) +mhd_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) { #if 0 struct Plugin *plugin = cls; @@ -823,13 +928,16 @@ mhd_accept_cb (void *cls, * @param max max number of bytes available in buffer * @return bytes written to buffer */ -int mhd_send_callback (void *cls, uint64_t pos, char *buf, int max) +static ssize_t +mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max) { - int bytes_read = 0; struct Session * ps = cls; struct HTTP_PeerContext * pc; struct HTTP_Message * msg; + int bytes_read = 0; + GNUNET_assert (ps!=NULL); + pc = ps->peercontext; msg = ps->pending_msgs_tail; if (ps->send_force_disconnect==GNUNET_YES) @@ -859,9 +967,13 @@ int mhd_send_callback (void *cls, uint64_t pos, char *buf, int max) { if (NULL!=msg->transmit_cont) msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,GNUNET_OK); + ps->queue_length_cur -= msg->size; remove_http_message(ps,msg); } } +#if DEBUG_CONNECTIONS + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: MHD has sent %u bytes\n", ps, bytes_read); +#endif return bytes_read; } @@ -873,13 +985,13 @@ int mhd_send_callback (void *cls, uint64_t pos, char *buf, int max) * already exists and create a new one if not. */ static int -mdh_access_cb (void *cls, - struct MHD_Connection *mhd_connection, - const char *url, - const char *method, - const char *version, - const char *upload_data, - size_t * upload_data_size, void **httpSessionCache) +mhd_access_cb (void *cls, + struct MHD_Connection *mhd_connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t * upload_data_size, void **httpSessionCache) { struct Plugin *plugin = cls; struct MHD_Response *response; @@ -895,7 +1007,7 @@ mdh_access_cb (void *cls, struct IPv4HttpAddress ipv4addr; struct IPv6HttpAddress ipv6addr; - struct HTTP_PeerContext *pc; + struct HTTP_PeerContext *pc = NULL; struct Session *ps = NULL; struct Session *ps_tmp = NULL; @@ -1018,6 +1130,8 @@ mdh_access_cb (void *cls, ps->recv_active=GNUNET_NO; ps->peercontext=pc; ps->session_id =id_num; + ps->queue_length_cur = 0; + ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE; ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); GNUNET_STATISTICS_update (plugin->env->stats, @@ -1077,8 +1191,20 @@ mdh_access_cb (void *cls, /* Recieving data */ if ((*upload_data_size > 0) && (ps->recv_active == GNUNET_YES)) { - res = GNUNET_SERVER_mst_receive(ps->msgtok, ps, upload_data,*upload_data_size, GNUNET_NO, GNUNET_NO); - (*upload_data_size) = 0; + if (pc->delay.rel_value == 0) + { +#if DEBUG_HTTP + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: PUT with %u bytes forwarded to MST\n", ps, *upload_data_size); +#endif + res = GNUNET_SERVER_mst_receive(ps->msgtok, ps, upload_data, *upload_data_size, GNUNET_NO, GNUNET_NO); + (*upload_data_size) = 0; + } + else + { +#if DEBUG_HTTP + 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); +#endif + } return MHD_YES; } else @@ -1112,14 +1238,13 @@ mdh_access_cb (void *cls, /** * Function that queries MHD's select sets and * starts the task waiting for them. - * @param cls plugin as closure + * @param plugin plugin * @param daemon_handle the MHD daemon handle * @return gnunet task identifier */ static GNUNET_SCHEDULER_TaskIdentifier -http_server_daemon_prepare (void * cls, struct MHD_Daemon *daemon_handle) +http_server_daemon_prepare (struct Plugin *plugin , struct MHD_Daemon *daemon_handle) { - struct Plugin *plugin = cls; GNUNET_SCHEDULER_TaskIdentifier ret; fd_set rs; fd_set ws; @@ -1132,7 +1257,6 @@ http_server_daemon_prepare (void * cls, struct MHD_Daemon *daemon_handle) int haveto; struct GNUNET_TIME_Relative tv; - GNUNET_assert(cls !=NULL); ret = GNUNET_SCHEDULER_NO_TASK; FD_ZERO(&rs); FD_ZERO(&ws); @@ -1149,22 +1273,21 @@ http_server_daemon_prepare (void * cls, struct MHD_Daemon *daemon_handle) &max)); haveto = MHD_get_timeout (daemon_handle, &timeout); if (haveto == MHD_YES) - tv.value = (uint64_t) timeout; + tv.rel_value = (uint64_t) timeout; else - tv = GNUNET_TIME_UNIT_FOREVER_REL; - GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max); - GNUNET_NETWORK_fdset_copy_native (wws, &ws, max); - GNUNET_NETWORK_fdset_copy_native (wes, &es, max); + tv = GNUNET_TIME_UNIT_SECONDS; + GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); if (daemon_handle == plugin->http_server_daemon_v4) { if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_server_task_v4); + GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4); plugin->http_server_daemon_v4 = GNUNET_SCHEDULER_NO_TASK; } - ret = GNUNET_SCHEDULER_add_select (plugin->env->sched, - GNUNET_SCHEDULER_PRIORITY_DEFAULT, + ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_SCHEDULER_NO_TASK, tv, wrs, @@ -1176,12 +1299,11 @@ http_server_daemon_prepare (void * cls, struct MHD_Daemon *daemon_handle) { if (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_server_task_v6); + GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6); plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK; } - ret = GNUNET_SCHEDULER_add_select (plugin->env->sched, - GNUNET_SCHEDULER_PRIORITY_DEFAULT, + ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_SCHEDULER_NO_TASK, tv, wrs, @@ -1206,6 +1328,19 @@ static void http_server_daemon_v4_run (void *cls, { struct Plugin *plugin = cls; +#if DEBUG_SCHEDULING + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_READ_READY\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_STARTUP\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v4_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n"); +#endif + GNUNET_assert(cls !=NULL); plugin->http_server_task_v4 = GNUNET_SCHEDULER_NO_TASK; @@ -1227,6 +1362,19 @@ static void http_server_daemon_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Plugin *plugin = cls; + +#if DEBUG_SCHEDULING + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_READ_READY\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_WRITE_READY\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GNUNET_SCHEDULER_REASON_TIMEOUT\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_STARTUP)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_STARTUP\n"); + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"http_server_daemon_v6_run: GGNUNET_SCHEDULER_REASON_SHUTDOWN\n"); +#endif GNUNET_assert(cls !=NULL); plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK; @@ -1408,11 +1556,12 @@ static size_t curl_send_cb(void *stream, size_t size, size_t nmemb, void *ptr) if ( msg->pos == msg->size) { #if DEBUG_CONNECTIONS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Message with %u bytes sent, removing message from queue \n",ps, msg->pos); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Message with %u bytes sent, removing message from queue \n",ps, msg->pos); #endif /* Calling transmit continuation */ if (NULL != ps->pending_msgs_tail->transmit_cont) msg->transmit_cont (ps->pending_msgs_tail->transmit_cont_cls,&(ps->peercontext)->identity,GNUNET_OK); + ps->queue_length_cur -= msg->size; remove_http_message(ps, msg); } return bytes_sent; @@ -1423,6 +1572,7 @@ static void curl_receive_mst_cb (void *cls, const struct GNUNET_MessageHeader *message) { struct Session *ps = cls; + struct GNUNET_TIME_Relative delay; GNUNET_assert(ps != NULL); struct HTTP_PeerContext *pc = ps->peercontext; @@ -1435,11 +1585,31 @@ static void curl_receive_mst_cb (void *cls, ntohs(message->size), GNUNET_i2s(&(pc->identity)),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); #endif - pc->plugin->env->receive (pc->plugin->env->cls, - &pc->identity, - message, 1, ps, - ps->addr, - ps->addrlen); + struct GNUNET_TRANSPORT_ATS_Information distance[2]; + distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); + distance[0].value = htonl (1); + distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); + distance[1].value = htonl (0); + + delay = pc->plugin->env->receive (pc->plugin->env->cls, + &pc->identity, + message, + (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2, + ps, + ps->addr, + ps->addrlen); + + pc->delay = delay; + if (pc->reset_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (pc->reset_task); + + if (delay.rel_value > 0) + { +#if DEBUG_HTTP + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.rel_value); +#endif + pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc); + } } @@ -1455,6 +1625,15 @@ static void curl_receive_mst_cb (void *cls, static size_t curl_receive_cb( void *stream, size_t size, size_t nmemb, void *ptr) { struct Session * ps = ptr; + + if (ps->peercontext->delay.rel_value > 0) + { +#if DEBUG_HTTP + 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); +#endif + return (0); + } + #if DEBUG_CONNECTIONS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: %u bytes received\n",ps, size*nmemb); #endif @@ -1510,9 +1689,14 @@ static void curl_handle_finished (struct Plugin *plugin) curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint); //curl_easy_cleanup(ps->send_endpoint); //ps->send_endpoint=NULL; - cur_msg = ps->pending_msgs_tail; - if (( NULL != cur_msg) && ( NULL != cur_msg->transmit_cont)) - cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); + while (ps->pending_msgs_tail != NULL) + { + cur_msg = ps->pending_msgs_tail; + if ( NULL != cur_msg->transmit_cont) + cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); + ps->queue_length_cur -= cur_msg->size; + remove_http_message(ps,cur_msg); + } } /* GET connection failed */ if (msg->easy_handle == ps->recv_endpoint) @@ -1547,19 +1731,25 @@ static void curl_handle_finished (struct Plugin *plugin) http_result); #endif /* Calling transmit continuation */ - cur_msg = ps->pending_msgs_tail; - if (( NULL != cur_msg) && (NULL != cur_msg->transmit_cont)) + while (ps->pending_msgs_tail != NULL) { - /* HTTP 1xx : Last message before here was informational */ - if ((http_result >=100) && (http_result < 200)) - cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); - /* HTTP 2xx: successful operations */ - if ((http_result >=200) && (http_result < 300)) - cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); - /* HTTP 3xx..5xx: error */ - if ((http_result >=300) && (http_result < 600)) - cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); + cur_msg = ps->pending_msgs_tail; + if ( NULL != cur_msg->transmit_cont) + { + /* HTTP 1xx : Last message before here was informational */ + if ((http_result >=100) && (http_result < 200)) + cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); + /* HTTP 2xx: successful operations */ + if ((http_result >=200) && (http_result < 300)) + cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); + /* HTTP 3xx..5xx: error */ + if ((http_result >=300) && (http_result < 600)) + cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); + } + ps->queue_length_cur -= cur_msg->size; + remove_http_message(ps,cur_msg); } + ps->send_connected = GNUNET_NO; ps->send_active = GNUNET_NO; curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint); @@ -1609,12 +1799,9 @@ static void curl_perform (void *cls, GNUNET_assert(cls !=NULL); - - plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - do { running = 0; @@ -1624,7 +1811,6 @@ static void curl_perform (void *cls, handles_last_run = running; } while (mret == CURLM_CALL_MULTI_PERFORM); - curl_schedule(plugin); } @@ -1632,12 +1818,11 @@ static void curl_perform (void *cls, /** * Function setting up file descriptors and scheduling task to run * - * @param cls plugin as closure + * @param plugin plugin as closure * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok */ -static int curl_schedule(void *cls) +static int curl_schedule(struct Plugin *plugin) { - struct Plugin *plugin = cls; fd_set rs; fd_set ws; fd_set es; @@ -1647,12 +1832,10 @@ static int curl_schedule(void *cls) long to; CURLMcode mret; - GNUNET_assert(cls !=NULL); - /* Cancel previous scheduled task */ if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_curl_task); + GNUNET_SCHEDULER_cancel(plugin->http_curl_task); plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; } @@ -1683,8 +1866,7 @@ static int curl_schedule(void *cls) gws = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); - plugin->http_curl_task = GNUNET_SCHEDULER_add_select (plugin->env->sched, - GNUNET_SCHEDULER_PRIORITY_DEFAULT, + plugin->http_curl_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_SCHEDULER_NO_TASK, (to == -1) ? GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) : GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to), grs, @@ -1696,23 +1878,48 @@ static int curl_schedule(void *cls) return GNUNET_OK; } +/** + * Function to log curl debug messages with GNUNET_log + * @param curl handle + * @param type curl_infotype + * @param data data + * @param size size + * @param cls closure + * @return 0 + */ +int curl_logger (CURL * curl, curl_infotype type , char * data, size_t size , void * cls) +{ + + if (type == CURLINFO_TEXT) + { + char text[size+2]; + memcpy(text,data,size); + if (text[size-1] == '\n') + text[size] = '\0'; + else + { + text[size] = '\n'; + text[size+1] = '\0'; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"CURL: Connection %X - %s", cls, text); + } + return 0; +} + /** * Function setting up curl handle and selecting message to send * - * @param cls plugin + * @param plugin plugin * @param ps session * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok */ -static ssize_t send_check_connections (void *cls, struct Session *ps) +static int send_check_connections (struct Plugin *plugin, struct Session *ps) { - struct Plugin *plugin = cls; CURLMcode mret; struct HTTP_Message * msg; struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; - GNUNET_assert(cls !=NULL); - if (ps->direction == OUTBOUND) { /* RECV DIRECTION */ @@ -1727,6 +1934,13 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) } #if DEBUG_CURL curl_easy_setopt(ps->recv_endpoint, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger); + curl_easy_setopt(ps->recv_endpoint, CURLOPT_DEBUGDATA , ps->recv_endpoint); +#endif +#if BUILD_HTTPS + curl_easy_setopt (ps->recv_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); + curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(ps->recv_endpoint, CURLOPT_SSL_VERIFYHOST, 0); #endif curl_easy_setopt(ps->recv_endpoint, CURLOPT_URL, ps->url); curl_easy_setopt(ps->recv_endpoint, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); @@ -1735,7 +1949,7 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) curl_easy_setopt(ps->recv_endpoint, CURLOPT_READDATA, ps); curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEDATA, ps); - curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); + curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value); curl_easy_setopt(ps->recv_endpoint, CURLOPT_PRIVATE, ps); curl_easy_setopt(ps->recv_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); curl_easy_setopt(ps->recv_endpoint, CURLOPT_BUFFERSIZE, 2*GNUNET_SERVER_MAX_MESSAGE_SIZE); @@ -1758,10 +1972,10 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) } if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_curl_task); + GNUNET_SCHEDULER_cancel(plugin->http_curl_task); plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; } - plugin->http_curl_task = GNUNET_SCHEDULER_add_now (plugin->env->sched, &curl_perform, plugin); + plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); } /* waiting for receive direction */ @@ -1789,10 +2003,10 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) ps->send_active=GNUNET_YES; if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_curl_task); + GNUNET_SCHEDULER_cancel(plugin->http_curl_task); plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; } - plugin->http_curl_task = GNUNET_SCHEDULER_add_now (plugin->env->sched, &curl_perform, plugin); + plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); return GNUNET_YES; } else @@ -1818,6 +2032,13 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) #if DEBUG_CURL curl_easy_setopt(ps->send_endpoint, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGFUNCTION , &curl_logger); + curl_easy_setopt(ps->send_endpoint, CURLOPT_DEBUGDATA , ps->send_endpoint); +#endif +#if BUILD_HTTPS + curl_easy_setopt (ps->send_endpoint, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); + curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(ps->send_endpoint, CURLOPT_SSL_VERIFYHOST, 0); #endif curl_easy_setopt(ps->send_endpoint, CURLOPT_URL, ps->url); curl_easy_setopt(ps->send_endpoint, CURLOPT_PUT, 1L); @@ -1827,7 +2048,7 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); - curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); + curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.rel_value); curl_easy_setopt(ps->send_endpoint, CURLOPT_PRIVATE, ps); curl_easy_setopt(ps->send_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); curl_easy_setopt(ps->send_endpoint, CURLOPT_BUFFERSIZE, 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); @@ -1851,10 +2072,10 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) } if (plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_curl_task); + GNUNET_SCHEDULER_cancel(plugin->http_curl_task); plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; } - plugin->http_curl_task = GNUNET_SCHEDULER_add_now (plugin->env->sched, &curl_perform, plugin); + plugin->http_curl_task = GNUNET_SCHEDULER_add_now (&curl_perform, plugin); return GNUNET_YES; } if (ps->direction == INBOUND) @@ -1870,7 +2091,6 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) /** * select best session to transmit data to peer * - * @param cls closure * @param pc peer context of target peer * @param addr address of target peer * @param addrlen address length @@ -1879,7 +2099,7 @@ static ssize_t send_check_connections (void *cls, struct Session *ps) * @return selected session * */ -static struct Session * send_select_session (void * cls, struct HTTP_PeerContext *pc, const void * addr, size_t addrlen, int force_address, struct Session * session) +static struct Session * send_select_session (struct HTTP_PeerContext *pc, const void * addr, size_t addrlen, int force_address, struct Session * session) { struct Session * tmp = NULL; int addr_given = GNUNET_NO; @@ -2079,73 +2299,79 @@ http_plugin_send (void *cls, GNUNET_NO); } - ps = send_select_session (plugin, pc, addr, addrlen, force_address, session); + ps = send_select_session (pc, addr, addrlen, force_address, session); /* session not existing, but address forced -> creating new session */ if (ps==NULL) { - if ((addr!=NULL) && (addrlen!=0)) - { + if ((addr!=NULL) && (addrlen!=0)) + { ps = GNUNET_malloc(sizeof (struct Session)); #if DEBUG_SESSION_SELECTION if (force_address == GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection & forced address: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection & forced address: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); if (force_address != GNUNET_YES) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); #endif - if ((addrlen!=0) && (addr!=NULL)) - { - ps->addr = GNUNET_malloc(addrlen); - memcpy(ps->addr,addr,addrlen); - ps->addrlen = addrlen; - } - else - { - ps->addr = NULL; - ps->addrlen = 0; - } - ps->direction=OUTBOUND; - ps->recv_connected = GNUNET_NO; - ps->recv_force_disconnect = GNUNET_NO; - ps->send_connected = GNUNET_NO; - ps->send_force_disconnect = GNUNET_NO; - ps->pending_msgs_head = NULL; - ps->pending_msgs_tail = NULL; - ps->peercontext=pc; - ps->session_id = pc->session_id_counter; - pc->session_id_counter++; - ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); - if (ps->msgtok == NULL) - ps->msgtok = GNUNET_SERVER_mst_create (&curl_receive_mst_cb, ps); - GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); -/* FIXME */ - - GNUNET_STATISTICS_update (plugin->env->stats, - gettext_noop ("# HTTP outbound sessions for peers active"), - 1, - GNUNET_NO); - } - else - { + ps->addr = GNUNET_malloc(addrlen); + memcpy(ps->addr,addr,addrlen); + ps->addrlen = addrlen; + /* + else + { + ps->addr = NULL; + ps->addrlen = 0; + }*/ + ps->direction=OUTBOUND; + ps->recv_connected = GNUNET_NO; + ps->recv_force_disconnect = GNUNET_NO; + ps->send_connected = GNUNET_NO; + ps->send_force_disconnect = GNUNET_NO; + ps->pending_msgs_head = NULL; + ps->pending_msgs_tail = NULL; + ps->peercontext=pc; + ps->session_id = pc->session_id_counter; + ps->queue_length_cur = 0; + ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE; + pc->session_id_counter++; + ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); + if (ps->msgtok == NULL) + ps->msgtok = GNUNET_SERVER_mst_create (&curl_receive_mst_cb, ps); + GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# HTTP outbound sessions for peers active"), + 1, + GNUNET_NO); + } + else + { #if DEBUG_HTTP - 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)); + 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)); #endif - return GNUNET_SYSERR; + return GNUNET_SYSERR; } } - /* create msg */ - msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); - msg->next = NULL; - msg->size = msgbuf_size; - msg->pos = 0; - msg->buf = (char *) &msg[1]; - msg->transmit_cont = cont; - msg->transmit_cont_cls = cont_cls; - memcpy (msg->buf,msgbuf, msgbuf_size); - GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg); - - if (send_check_connections (plugin, ps) == GNUNET_SYSERR) + if (msgbuf_size >= (ps->queue_length_max - ps->queue_length_cur)) + { + 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); + //return GNUNET_SYSERR; + } + + /* create msg */ + msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); + msg->next = NULL; + msg->size = msgbuf_size; + msg->pos = 0; + msg->buf = (char *) &msg[1]; + msg->transmit_cont = cont; + msg->transmit_cont_cls = cont_cls; + memcpy (msg->buf,msgbuf, msgbuf_size); + + GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg); + ps->queue_length_cur += msgbuf_size; + + if (send_check_connections (plugin, ps) == GNUNET_SYSERR) return GNUNET_SYSERR; if (force_address != GNUNET_YES) pc->last_session = ps; @@ -2305,7 +2531,9 @@ http_plugin_address_suggested (void *cls, struct Plugin *plugin = cls; struct IPv4HttpAddress *v4; struct IPv6HttpAddress *v6; - unsigned int port; + + struct IPv4HttpAddress *tv4 = plugin->ipv4_addr_head; + struct IPv6HttpAddress *tv6 = plugin->ipv6_addr_head; GNUNET_assert(cls !=NULL); if ((addrlen != sizeof (struct IPv4HttpAddress)) && @@ -2316,32 +2544,50 @@ http_plugin_address_suggested (void *cls, if (addrlen == sizeof (struct IPv4HttpAddress)) { v4 = (struct IPv4HttpAddress *) addr; - /* Not skipping loopback - if (INADDR_LOOPBACK == ntohl(v4->ipv4_addr)) + + if (plugin->bind4_address!=NULL) { - return GNUNET_SYSERR; - } */ - port = ntohs (v4->u_port); - if (port != plugin->port_inbound) + if (0 == memcmp (&plugin->bind4_address->sin_addr, &v4->ipv4_addr, sizeof(uint32_t))) + return GNUNET_OK; + else + return GNUNET_SYSERR; + } + while (tv4!=NULL) { - return GNUNET_SYSERR; + if (0==memcmp (&tv4->ipv4_addr, &v4->ipv4_addr, sizeof(uint32_t))) + break; + tv4 = tv4->next; } + if (tv4 != NULL) + return GNUNET_OK; + else + return GNUNET_SYSERR; } if (addrlen == sizeof (struct IPv6HttpAddress)) { v6 = (struct IPv6HttpAddress *) addr; - if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr)) - { - return GNUNET_SYSERR; - } - port = ntohs (v6->u6_port); - if (port != plugin->port_inbound) + + if (plugin->bind6_address!=NULL) + { + if (0 == memcmp (&plugin->bind6_address->sin6_addr, &v6->ipv6_addr, sizeof(struct in6_addr))) + return GNUNET_OK; + else + return GNUNET_SYSERR; + } + + while (tv6!=NULL) { - return GNUNET_SYSERR; + if (0 == memcmp (&tv6->ipv6_addr, &v6->ipv6_addr, sizeof(struct in6_addr))) + break; + tv6 = tv6->next; } + if (tv6 !=NULL) + return GNUNET_OK; + else + return GNUNET_SYSERR; } - return GNUNET_OK; + return GNUNET_SYSERR; } @@ -2402,11 +2648,13 @@ http_plugin_address_to_string (void *cls, * Exit point from the plugin. */ void * -libgnunet_plugin_transport_http_done (void *cls) +LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) { struct GNUNET_TRANSPORT_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; CURLMcode mret; + struct IPv4HttpAddress * ipv4addr; + struct IPv6HttpAddress * ipv6addr; GNUNET_assert(cls !=NULL); if (plugin->http_server_daemon_v4 != NULL) @@ -2422,16 +2670,29 @@ libgnunet_plugin_transport_http_done (void *cls) if ( plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_server_task_v4); + GNUNET_SCHEDULER_cancel(plugin->http_server_task_v4); plugin->http_server_task_v4 = GNUNET_SCHEDULER_NO_TASK; } if ( plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_server_task_v6); + GNUNET_SCHEDULER_cancel(plugin->http_server_task_v6); plugin->http_server_task_v6 = GNUNET_SCHEDULER_NO_TASK; } + while (plugin->ipv4_addr_head!=NULL) + { + ipv4addr = plugin->ipv4_addr_head; + GNUNET_CONTAINER_DLL_remove(plugin->ipv4_addr_head,plugin->ipv4_addr_tail,ipv4addr); + GNUNET_free(ipv4addr); + } + + while (plugin->ipv6_addr_head!=NULL) + { + ipv6addr = plugin->ipv6_addr_head; + GNUNET_CONTAINER_DLL_remove(plugin->ipv6_addr_head,plugin->ipv6_addr_tail,ipv6addr); + GNUNET_free(ipv6addr); + } /* free all peer information */ if (plugin->peers!=NULL) @@ -2454,7 +2715,7 @@ libgnunet_plugin_transport_http_done (void *cls) if ( plugin->http_curl_task != GNUNET_SCHEDULER_NO_TASK) { - GNUNET_SCHEDULER_cancel(plugin->env->sched, plugin->http_curl_task); + GNUNET_SCHEDULER_cancel(plugin->http_curl_task); plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; } @@ -2576,7 +2837,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) _("Require valid port number for transport plugin `%s' in configuration!\n"), PROTOCOL_PREFIX); GNUNET_free(component_name); - libgnunet_plugin_transport_http_done (api); + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); return NULL; } @@ -2593,15 +2854,18 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) plugin->bind4_address->sin_family = AF_INET; plugin->bind4_address->sin_port = htons (port); - if (inet_pton(AF_INET,plugin->bind_hostname, &plugin->bind4_address->sin_addr)<=0) + if (plugin->bind_hostname!=NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - component_name, - _("Misconfigured address to bind to in configuration!\n")); - GNUNET_free(plugin->bind4_address); - GNUNET_free(plugin->bind_hostname); - plugin->bind_hostname = NULL; - plugin->bind4_address = NULL; + if (inet_pton(AF_INET,plugin->bind_hostname, &plugin->bind4_address->sin_addr)<=0) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + component_name, + _("Misconfigured address to bind to in configuration!\n")); + GNUNET_free(plugin->bind4_address); + GNUNET_free(plugin->bind_hostname); + plugin->bind_hostname = NULL; + plugin->bind4_address = NULL; + } } } @@ -2617,16 +2881,18 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) plugin->bind6_address = GNUNET_malloc(sizeof(struct sockaddr_in6)); plugin->bind6_address->sin6_family = AF_INET6; plugin->bind6_address->sin6_port = htons (port); - - if (inet_pton(AF_INET6,plugin->bind_hostname, &plugin->bind6_address->sin6_addr)<=0) + if (plugin->bind_hostname!=NULL) { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - component_name, - _("Misconfigured address to bind to in configuration!\n")); - GNUNET_free(plugin->bind6_address); - GNUNET_free(plugin->bind_hostname); - plugin->bind_hostname = NULL; - plugin->bind6_address = NULL; + if (inet_pton(AF_INET6,plugin->bind_hostname, &plugin->bind6_address->sin6_addr)<=0) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + component_name, + _("Misconfigured address to bind to in configuration!\n")); + GNUNET_free(plugin->bind6_address); + GNUNET_free(plugin->bind_hostname); + plugin->bind_hostname = NULL; + plugin->bind6_address = NULL; + } } } } @@ -2694,7 +2960,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) GNUNET_free (cert_file); GNUNET_free (component_name); - libgnunet_plugin_transport_http_done(api); + LIBGNUNET_PLUGIN_TRANSPORT_DONE(api); GNUNET_free (cmd); return NULL; } @@ -2714,15 +2980,13 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) GNUNET_free (cert_file); GNUNET_free (component_name); - libgnunet_plugin_transport_http_done(api); + LIBGNUNET_PLUGIN_TRANSPORT_DONE(api); return NULL; } } - GNUNET_free (key_file); GNUNET_free (cert_file); - GNUNET_assert((plugin->key!=NULL) && (plugin->cert!=NULL)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLS certificate loaded\n"); #endif @@ -2730,7 +2994,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) GNUNET_assert ((port > 0) && (port <= 65535)); plugin->port_inbound = port; gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; - unsigned int timeout = (gn_timeout.value) / 1000; + unsigned int timeout = (gn_timeout.rel_value) / 1000; if ((plugin->http_server_daemon_v6 == NULL) && (plugin->use_ipv6 == GNUNET_YES) && (port != 0)) { struct sockaddr * tmp = (struct sockaddr *) plugin->bind6_address; @@ -2744,7 +3008,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) MHD_USE_IPv6, port, &mhd_accept_cb, - plugin , &mdh_access_cb, plugin, + plugin , &mhd_access_cb, plugin, MHD_OPTION_SOCK_ADDR, tmp, MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, @@ -2771,7 +3035,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) MHD_NO_FLAG, port, &mhd_accept_cb, - plugin , &mdh_access_cb, plugin, + plugin , &mhd_access_cb, plugin, MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *)plugin->bind4_address, MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, //MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, @@ -2821,10 +3085,10 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) GNUNET_asprintf(&tmp,"with IPv6 enabled"); if ((plugin->use_ipv6 == GNUNET_NO) && (plugin->use_ipv4 == GNUNET_NO)) GNUNET_asprintf(&tmp,"with NO IP PROTOCOL enabled"); - 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); + 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); GNUNET_free (tmp); GNUNET_free (component_name); - libgnunet_plugin_transport_http_done (api); + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); return NULL; } @@ -2839,7 +3103,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) _("Could not initialize curl multi handle, failed to start %s plugin!\n"), PROTOCOL_PREFIX); GNUNET_free(component_name); - libgnunet_plugin_transport_http_done (api); + LIBGNUNET_PLUGIN_TRANSPORT_DONE (api); return NULL; } @@ -2850,4 +3114,4 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) return api; } -/* end of plugin_transport_http.c */ +/* end of gnunet_transport_plugin.http.c */