X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fplugin_transport_http_server.c;h=a8731907eafe7f3892a6b6ead986bcdde748e2f2;hb=a03f3a1884c6f423cde604ba5b0bba86f43a7113;hp=5e77f71a78ebb794a1f17f368a4e3aa757b416cf;hpb=06d1cff412d88a1d9f4ad0ffaf205244707cd780;p=oweals%2Fgnunet.git diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 5e77f71a7..a8731907e 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -153,6 +153,9 @@ struct ServerConnection /* Should this connection get disconnected? GNUNET_YES/NO */ int disconnect; + /* For PUT connections: Is this the first or last callback with size 0 */ + int connected; + /* The session this server connection belongs to */ struct Session *session; @@ -212,6 +215,16 @@ struct HTTP_Server_Plugin */ unsigned int cur_connections; + /** + * Did we immediately end the session in disconnect_cb + */ + int in_shutdown; + + /** + * Length of peer id + */ + int peer_id_length; + /** * External hostname the plugin can be connected to, can be different to * the host's FQDN, used e.g. for reverse proxying @@ -384,6 +397,11 @@ struct HTTP_Message */ size_t size; + /** + * HTTP/S specific overhead + */ + size_t overhead; + /** * Continuation function to call once the transmission buffer * has again space available. NULL if there is no @@ -497,6 +515,7 @@ http_server_plugin_send (void *cls, struct HTTP_Server_Plugin *plugin = cls; struct HTTP_Message *msg; int bytes_sent = 0; + char *stat_txt; GNUNET_assert (plugin != NULL); GNUNET_assert (session != NULL); @@ -506,7 +525,7 @@ http_server_plugin_send (void *cls, GNUNET_break (0); return GNUNET_SYSERR; } - if ((NULL == session->server_send) || (NULL == session->server_recv)) + if (NULL == session->server_send) { GNUNET_break (0); return GNUNET_SYSERR; @@ -516,6 +535,11 @@ http_server_plugin_send (void *cls, if (GNUNET_YES == session->server_send->disconnect) return GNUNET_SYSERR; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, + "Session %p/connection %p: Sending message with %u to peer `%s' with \n", + session, session->server_send, + msgbuf_size, GNUNET_i2s (&session->target)); + /* create new message and schedule */ bytes_sent = sizeof (struct HTTP_Message) + msgbuf_size; msg = GNUNET_malloc (bytes_sent); @@ -529,6 +553,11 @@ http_server_plugin_send (void *cls, GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, session->msg_tail, msg); + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, msgbuf_size, GNUNET_NO); + GNUNET_free (stat_txt); + server_reschedule (session->plugin, session->server_send->mhd_daemon, GNUNET_YES); server_reschedule_session_timeout (session); @@ -566,7 +595,7 @@ http_server_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *targ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Disconnecting session %p to `%s'\n", pos, GNUNET_i2s (target)); - GNUNET_assert (GNUNET_OK == server_disconnect (pos)); + server_disconnect (pos); } } @@ -639,16 +668,12 @@ http_server_plugin_get_session (void *cls, * * @param s the session to delete */ - static void server_delete_session (struct Session *s) { struct HTTP_Server_Plugin *plugin = s->plugin; server_stop_session_timeout(s); - if ((GNUNET_YES == s->session_passed) && (GNUNET_NO == s->session_ended)) - plugin->env->session_end (plugin->env->cls, &s->target, s); - GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); struct HTTP_Message *msg = s->msg_head; struct HTTP_Message *tmp = NULL; @@ -660,7 +685,8 @@ server_delete_session (struct Session *s) GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); if (msg->transmit_cont != NULL) { - msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); + msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR, + msg->size, msg->pos + msg->overhead); } GNUNET_free (msg); msg = tmp; @@ -771,6 +797,12 @@ server_disconnect (struct Session *s) struct ServerConnection * send = NULL; struct ServerConnection * recv = NULL; + if (GNUNET_NO == server_exist_session (p, s)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + send = (struct ServerConnection *) s->server_send; if (s->server_send != NULL) { @@ -829,6 +861,121 @@ server_mhd_connection_timeout (struct HTTP_Server_Plugin *plugin, struct Session #endif } +/** + * Parse incoming URL for tag and target + * + * @param plugin plugin + * @param url incoming url + * @param target where to store the target + * @param tag where to store the tag + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ + +static int +server_parse_url (struct HTTP_Server_Plugin *plugin, const char * url, struct GNUNET_PeerIdentity * target, uint32_t *tag) +{ + int debug = GNUNET_YES; + + char * tag_start = NULL; + char * tag_end = NULL; + char * target_start = NULL; + char * separator = NULL; + char hash[plugin->peer_id_length+1]; + int hash_length; + unsigned long int ctag; + + /* URL parsing + * URL is valid if it is in the form [prefix with (multiple) '/'][peerid[103];tag]*/ + + if (NULL == url) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + /* convert tag */ + + /* find separator */ + separator = strrchr (url, ';'); + + if (NULL == separator) + { + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + tag_start = separator + 1; + + if (strlen (tag_start) == 0) + { + /* No tag after separator */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + ctag = strtoul (tag_start, &tag_end, 10); + if (ctag == 0) + { + /* tag == 0 , invalid */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + if ((ctag == ULONG_MAX) && (ERANGE == errno)) + { + /* out of range: > ULONG_MAX */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (ctag > UINT32_MAX) + { + /* out of range: > UINT32_MAX */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + (*tag) = (uint32_t) ctag; + if (NULL == tag_end) + { + /* no char after tag */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (url[strlen(url)] != tag_end[0]) + { + /* there are more not converted chars after tag */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + if (debug) + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Found tag `%u' in url\n", (*tag)); + + /* convert peer id */ + target_start = strrchr (url, '/'); + if (NULL == target_start) + { + /* no leading '/' */ + target_start = (char *) url; + } + target_start++; + hash_length = separator - target_start; + if (hash_length != plugin->peer_id_length) + { + /* no char after tag */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + memcpy (hash, target_start, hash_length); + hash[hash_length] = '\0'; + + if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target->hashPubKey))) + { + /* hash conversion failed */ + if (debug) GNUNET_break (0); + return GNUNET_SYSERR; + } + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Found target `%s' in url\n", GNUNET_h2s_full(&target->hashPubKey)); + return GNUNET_OK; +} + /** * Lookup a mhd connection and create one if none is found @@ -857,112 +1004,29 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, int direction = GNUNET_SYSERR; int to; - /* url parsing variables */ - size_t url_len; - char *url_end; - char *hash_start; - char *hash_end; - char *tag_start; - char *tag_end; - conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); if ((conn_info->client_addr->sa_family != AF_INET) && (conn_info->client_addr->sa_family != AF_INET6)) return NULL; - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "New %s connection from %s\n", method, url); - /* URL parsing - * URL is valid if it is in the form [peerid[103];tag]*/ - url_len = strlen (url); - url_end = (char *) &url[url_len]; - - if (url_len < 105) - { - GNUNET_break (0); - goto error; /* too short */ - } - hash_start = strrchr (url, '/'); - if (NULL == hash_start) - { - GNUNET_break (0); - goto error; /* '/' delimiter not found */ - } - if (hash_start >= url_end) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - hash_start++; - - hash_end = strrchr (hash_start, ';'); - if (NULL == hash_end) - { - GNUNET_break (0); - goto error; /* ';' delimiter not found */ - } - - if (hash_end >= url_end) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - - if (hash_start >= hash_end) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - - if ((strlen(hash_start) - strlen(hash_end)) != 103) - { - GNUNET_break (0); - goto error; /* invalid hash length */ - } - - char hash[104]; - memcpy (hash, hash_start, 103); - hash[103] = '\0'; - if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((const char *) hash, &(target.hashPubKey))) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - - if (hash_end >= url_end) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - tag_start = &hash_end[1]; - /* Converting tag */ - tag_end = NULL; - tag = strtoul (tag_start, &tag_end, 10); - if (tag == 0) + if (GNUNET_SYSERR == server_parse_url (plugin, url, &target, &tag)) { - GNUNET_break (0); - goto error; /* mal formed */ - } - if (tag_end == NULL) - { - GNUNET_break (0); - goto error; /* mal formed */ - } - if (tag_end != url_end) - { - GNUNET_break (0); - goto error; /* mal formed */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Invalid url %s\n", url); + return NULL; } - if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) direction = _RECEIVE; else if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) direction = _SEND; else { - goto error; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Invalid method %s connection from %s\n", method, url); + return NULL; } plugin->cur_connections++; @@ -971,7 +1035,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, method, GNUNET_i2s (&target), tag, plugin->cur_connections, plugin->max_connections); - /* find duplicate session */ s = plugin->head; while (s != NULL) @@ -989,7 +1052,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", GNUNET_i2s (&target), tag); - goto error; + return NULL; + } if ((_SEND == direction) && (NULL != s->server_send)) { @@ -997,7 +1061,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, "Duplicate GET connection from `%s' tag %u, dismissing new connection\n", GNUNET_i2s (&target), tag); - goto error; + return NULL; } } else @@ -1017,9 +1081,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, break; default: GNUNET_break (0); - goto error; + return NULL; } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Creating new session for peer `%s' connecting from `%s'\n", GNUNET_i2s (&target), @@ -1040,7 +1103,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, server_start_session_timeout(s); GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); } - sc = GNUNET_malloc (sizeof (struct ServerConnection)); if (conn_info->client_addr->sa_family == AF_INET) sc->mhd_daemon = plugin->server_v4; @@ -1048,12 +1110,12 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, sc->mhd_daemon = plugin->server_v6; sc->mhd_conn = mhd_connection; sc->direction = direction; + sc->connected = GNUNET_NO; sc->session = s; if (direction == _SEND) s->server_send = sc; if (direction == _RECEIVE) s->server_recv = sc; - #if MHD_VERSION >= 0x00090E00 if ((NULL == s->server_recv) || (NULL == s->server_send)) { @@ -1074,12 +1136,6 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, "Setting timeout for %p to %u sec.\n", sc, to); #endif return sc; - -/* Error condition */ - error: - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Invalid connection request\n"); - return NULL; } @@ -1134,6 +1190,7 @@ server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) struct Session *s = cls; ssize_t bytes_read = 0; struct HTTP_Message *msg; + char *stat_txt; GNUNET_assert (NULL != p); if (GNUNET_NO == server_exist_session (p, s)) @@ -1152,15 +1209,24 @@ server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) { GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); if (NULL != msg->transmit_cont) - msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK); + msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK, + msg->size, msg->size + msg->overhead); GNUNET_free (msg); } } - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, + if (0 < bytes_read) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, "Sent %u bytes to peer `%s' with session %p \n", bytes_read, GNUNET_i2s (&s->target), s); - - - + GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", p->protocol); + GNUNET_STATISTICS_update (p->env->stats, + stat_txt, -bytes_read, GNUNET_NO); + GNUNET_free (stat_txt); + GNUNET_asprintf (&stat_txt, "# bytes transmitted via %s_server", p->protocol); + GNUNET_STATISTICS_update (p->env->stats, + stat_txt, bytes_read, GNUNET_NO); + GNUNET_free (stat_txt); + } return bytes_read; } @@ -1180,6 +1246,7 @@ server_receive_mst_cb (void *cls, void *client, struct Session *s = cls; struct GNUNET_ATS_Information atsi[2]; struct GNUNET_TIME_Relative delay; + char *stat_txt; GNUNET_assert (NULL != p); if (GNUNET_NO == server_exist_session(p, s)) @@ -1193,11 +1260,18 @@ server_receive_mst_cb (void *cls, void *client, atsi[1].value = s->ats_address_network_type; GNUNET_break (s->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED)); + delay = plugin->env->receive (plugin->env->cls, &s->target, message, (const struct GNUNET_ATS_Information *) &atsi, 2, s, s->addr, s->addrlen); + + GNUNET_asprintf (&stat_txt, "# bytes received via %s_server", plugin->protocol); + GNUNET_STATISTICS_update (plugin->env->stats, + stat_txt, ntohs (message->size), GNUNET_NO); + GNUNET_free (stat_txt); + s->session_passed = GNUNET_YES; s->next_receive = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay); if (delay.rel_value > 0) @@ -1240,10 +1314,10 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, struct MHD_Response *response; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - _("Access from connection %p (%u of %u) for %s %s url `%s' \n"), + _("Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %u\n"), sc, plugin->cur_connections, plugin->max_connections, - method, version, url); + method, version, url, (*upload_data_size)); GNUNET_assert (cls != NULL); if (sc == NULL) @@ -1251,7 +1325,9 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, /* new connection */ sc = server_lookup_connection (plugin, mhd_connection, url, method); if (sc != NULL) + { (*httpSessionCache) = sc; + } else { response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE), HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); @@ -1273,12 +1349,11 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, /* existing connection */ sc = (*httpSessionCache); s = sc->session; - GNUNET_assert (NULL != s); /* connection is to be disconnected */ if (sc->disconnect == GNUNET_YES) { - /* Sent HTTP/1.1: 200 OK as PUT Response\ */ + /* Sent HTTP/1.1: 200 OK as response */ response = MHD_create_response_from_data (strlen ("Thank you!"), "Thank you!", MHD_NO, MHD_NO); @@ -1286,14 +1361,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, MHD_destroy_response (response); return MHD_YES; } - GNUNET_assert (s != NULL); - /* Check if both directions are connected */ - if ((sc->session->server_recv == NULL) || (sc->session->server_send == NULL)) - { - /* Delayed read from since not both semi-connections are connected */ - return MHD_YES; - } if (sc->direction == _SEND) { @@ -1307,22 +1375,44 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, } if (sc->direction == _RECEIVE) { - if (*upload_data_size == 0) + if ((*upload_data_size == 0) && (sc->connected == GNUNET_NO)) { + /* (*upload_data_size == 0) first callback when header are passed */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Peer `%s' PUT on address `%s' connected\n", + "Session %p / Connection %p: Peer `%s' PUT on address `%s' connected\n", + s, sc, GNUNET_i2s (&s->target), http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); + sc->connected = GNUNET_YES; return MHD_YES; } - - /* Receiving data */ - if ((*upload_data_size > 0)) + else if ((*upload_data_size == 0) && (sc->connected == GNUNET_YES)) { + /* (*upload_data_size == 0) when upload is complete */ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, - "Peer `%s' PUT on address `%s' received %u bytes\n", + "Session %p / Connection %p: Peer `%s' PUT on address `%s' finished upload\n", + s, sc, + GNUNET_i2s (&s->target), + http_common_plugin_address_to_string (NULL, + s->addr, + s->addrlen)); + sc->connected = GNUNET_NO; + /* Sent HTTP/1.1: 200 OK as PUT Response\ */ + response = MHD_create_response_from_data (strlen ("Thank you!"), + "Thank you!", + MHD_NO, MHD_NO); + res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); + MHD_destroy_response (response); + return MHD_YES; + } + else if ((*upload_data_size > 0) && (sc->connected == GNUNET_YES)) + { + /* (*upload_data_size > 0) for every segment received */ + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, + "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %u bytes\n", + s, sc, GNUNET_i2s (&s->target), http_common_plugin_address_to_string (NULL, s->addr, @@ -1349,13 +1439,16 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%p no inbound bandwidth available! Next read was delayed by %llu ms\n", - s, now.abs_value - s->next_receive.abs_value); + "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %llu ms\n", + s, sc, now.abs_value - s->next_receive.abs_value); } return MHD_YES; } else + { + GNUNET_break (0); return MHD_NO; + } } return res; } @@ -1377,6 +1470,9 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, struct Session *t = NULL; struct HTTP_Server_Plugin *plugin = NULL; + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, p->name, + "Disconnect for connection %p \n", sc); + if (sc == NULL) return; @@ -1419,6 +1515,7 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, GNUNET_i2s (&s->target), s->server_recv, http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); s->server_recv = NULL; + /* Do not terminate session when PUT disconnects if (NULL != (s->server_send)) { s->server_send->disconnect = GNUNET_YES; @@ -1428,7 +1525,7 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, 1); #endif server_reschedule (plugin, s->server_send->mhd_daemon, GNUNET_NO); - } + }*/ if (s->msg_tk != NULL) { GNUNET_SERVER_mst_destroy (s->msg_tk); @@ -1446,14 +1543,15 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, GNUNET_i2s (&s->target), http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)); + if ((GNUNET_YES == s->session_passed) && (GNUNET_NO == s->session_ended)) + { + /* Notify transport immediately that this session is invalid */ + s->session_ended = GNUNET_YES; + plugin->env->session_end (plugin->env->cls, &s->target, s); + } server_delete_session (s); } - else if ((GNUNET_YES == s->session_passed) && (GNUNET_NO == s->session_ended)) - { - /* Notify transport immediately that this session is invalid */ - s->session_ended = GNUNET_YES; - plugin->env->session_end (plugin->env->cls, &s->target, s); - } + } @@ -1550,6 +1648,8 @@ server_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +#define UNSIGNED_MHD_LONG_LONG unsigned MHD_LONG_LONG + /** * Function that queries MHD's select sets and * starts the task waiting for them. @@ -1571,12 +1671,15 @@ server_schedule (struct HTTP_Server_Plugin *plugin, struct GNUNET_NETWORK_FDSet *wws; struct GNUNET_NETWORK_FDSet *wes; int max; - unsigned MHD_LONG_LONG timeout; + UNSIGNED_MHD_LONG_LONG timeout; static unsigned long long last_timeout = 0; int haveto; struct GNUNET_TIME_Relative tv; + if (GNUNET_YES == plugin->in_shutdown) + return GNUNET_SCHEDULER_NO_TASK; + ret = GNUNET_SCHEDULER_NO_TASK; FD_ZERO (&rs); FD_ZERO (&ws); @@ -1591,14 +1694,16 @@ server_schedule (struct HTTP_Server_Plugin *plugin, { if (timeout != last_timeout) { -#if VERBOSE_SERVER + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "SELECT Timeout changed from %llu to %llu\n", last_timeout, timeout); -#endif last_timeout = timeout; } - tv.rel_value = (uint64_t) timeout; + if (timeout <= GNUNET_TIME_UNIT_SECONDS.rel_value) + tv.rel_value = (uint64_t) timeout; + else + tv = GNUNET_TIME_UNIT_SECONDS; } else tv = GNUNET_TIME_UNIT_SECONDS; @@ -1699,12 +1804,25 @@ server_load_certificate (struct HTTP_Server_Plugin *plugin) { int res = GNUNET_OK; + char *sh; char *key_file; char *cert_file; /* Get crypto init string from config * If not present just use default values */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, + "PATHS", + "SERVICEHOME", + &sh)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, + "Failed to get servicehome!\n"); + return GNUNET_SYSERR; + } + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, @@ -1721,16 +1839,19 @@ server_load_certificate (struct HTTP_Server_Plugin *plugin) GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, "KEY_FILE", &key_file)) { - key_file = GNUNET_strdup ("https_key.key"); + GNUNET_break (0); + GNUNET_asprintf (&key_file, "%s/%s", sh, "https_key.key"); } + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (plugin->env->cfg, plugin->name, "CERT_FILE", &cert_file)) { - GNUNET_asprintf (&cert_file, "%s", "https_cert.crt"); + GNUNET_break (0); + GNUNET_asprintf (&cert_file, "%s/%s", sh, "https_cert.crt"); } - + GNUNET_free (sh); /* read key & certificates from file */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to loading TLS certificate from key-file `%s' cert-file`%s'\n", @@ -2584,6 +2705,14 @@ server_configure_plugin (struct HTTP_Server_Plugin *plugin) if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, "EXTERNAL_HOSTNAME", &plugin->external_hostname)) { + char * tmp = NULL; + if (NULL != strstr(plugin->external_hostname, "://")) + { + tmp = strdup(&strstr(plugin->external_hostname, "://")[3]); + GNUNET_free (plugin->external_hostname); + plugin->external_hostname = tmp; + + } GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, _("Using external hostname `%s'\n"), plugin->external_hostname); plugin->notify_ext_task = GNUNET_SCHEDULER_add_now (&server_notify_external_hostname, plugin); @@ -2617,6 +2746,10 @@ server_configure_plugin (struct HTTP_Server_Plugin *plugin) GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, _("Maximum number of connections is %u\n"), plugin->max_connections); + + + plugin->peer_id_length = strlen (GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey)); + return GNUNET_OK; } @@ -2703,7 +2836,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) GNUNET_free (api); return NULL; } - + plugin->in_shutdown = GNUNET_YES; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, _("Shutting down plugin `%s'\n"), plugin->name); @@ -2746,6 +2879,14 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) next = pos->next; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Removing left over session %p\n", pos); + + if ((GNUNET_YES == pos->session_passed) && (GNUNET_NO == pos->session_ended)) + { + /* Notify transport immediately that this session is invalid */ + pos->session_ended = GNUNET_YES; + plugin->env->session_end (plugin->env->cls, &pos->target, pos); + } + server_delete_session (pos); }