* starts the task waiting for them.
* @param plugin plugin
* @param daemon_handle the MHD daemon handle
+ * @param now schedule now or with MHD delay
* @return gnunet task identifier
*/
static GNUNET_SCHEDULER_TaskIdentifier
-server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle,
+server_schedule (struct Plugin *plugin,
+ struct MHD_Daemon *daemon_handle,
int now);
static void
vsnprintf (text, sizeof (text), fmt, ap);
va_end (ap);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Server: %s\n", text);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server: %s\n", text);
}
/**
server_load_file (const char *file)
{
struct GNUNET_DISK_FileHandle *gn_file;
- struct stat fstat;
+ uint64_t fsize;
char *text = NULL;
- if (0 != STAT (file, &fstat))
+ if (GNUNET_OK != GNUNET_DISK_file_size (file,
+ &fsize, GNUNET_NO, GNUNET_YES))
return NULL;
- text = GNUNET_malloc (fstat.st_size + 1);
+ text = GNUNET_malloc (fsize + 1);
gn_file =
GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_USER_READ);
GNUNET_free (text);
return NULL;
}
- if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fstat.st_size))
+ if (GNUNET_SYSERR == GNUNET_DISK_file_read (gn_file, text, fsize))
{
GNUNET_free (text);
GNUNET_DISK_file_close (gn_file);
return NULL;
}
- text[fstat.st_size] = '\0';
+ text[fsize] = '\0';
GNUNET_DISK_file_close (gn_file);
return text;
}
}
/* read key & certificates from file */
-#if VERBOSE_SERVER
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Loading TLS certificate from key-file `%s' cert-file`%s'\n",
key_file, cert_file);
-#endif
plugin->key = server_load_file (key_file);
plugin->cert = server_load_file (cert_file);
#endif
errno = 0;
cert_creation =
- GNUNET_OS_start_process (NULL, NULL,
+ GNUNET_OS_start_process (GNUNET_NO, NULL, NULL,
"gnunet-transport-certificate-creation",
"gnunet-transport-certificate-creation",
key_file, cert_file, NULL);
/**
* Reschedule the execution of both IPv4 and IPv6 server
* @param plugin the plugin
+ * @param server which server to schedule v4 or v6?
* @param now GNUNET_YES to schedule execution immediately, GNUNET_NO to wait
* until timeout
*/
static void
-server_reschedule (struct Plugin *plugin, int now)
+server_reschedule (struct Plugin *plugin, struct MHD_Daemon *server, int now)
{
- if (plugin->server_v4 != NULL)
+ if ((server == plugin->server_v4) && (plugin->server_v4 != NULL))
{
if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK)
{
plugin->server_v4_task = server_schedule (plugin, plugin->server_v4, now);
}
- if (plugin->server_v6 != NULL)
+ if ((server == plugin->server_v6) && (plugin->server_v6 != NULL))
{
if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK)
{
const struct GNUNET_MessageHeader *message)
{
struct Session *s = cls;
-
-#if VERBOSE_SERVER
struct Plugin *plugin = s->plugin;
-#endif
struct GNUNET_TIME_Relative delay;
delay = http_plugin_receive (s, &s->target, message, s, s->addr, s->addrlen);
if (delay.rel_value > 0)
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: peer `%s' address `%s' next read delayed for %llu ms\n",
GNUNET_i2s (&s->target),
http_plugin_address_to_string (NULL, s->addr, s->addrlen),
delay);
-#endif
}
}
server_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
{
struct Session *s = cls;
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, s->plugin->name,
- "Server: %X can sent maximum %u \n", s, max);
-#endif
+
struct HTTP_Message *msg;
int bytes_read = 0;
}
}
-#if VERBOSE_CLIENT
struct Plugin *plugin = s->plugin;
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: %X: sent %u bytes\n", s, bytes_read);
-#endif
+
return bytes_read;
}
struct Session *t;
struct ServerConnection *sc = NULL;
const union MHD_ConnectionInfo *conn_info;
-
+ struct GNUNET_ATS_Information ats;
struct IPv4HttpAddress a4;
struct IPv6HttpAddress a6;
struct sockaddr_in *s4;
struct GNUNET_PeerIdentity target;
int check = GNUNET_NO;
uint32_t tag = 0;
- int direction;
+ int direction = GNUNET_SYSERR;
conn_info =
MHD_get_connection_info (mhd_connection,
if (0 == strcmp (MHD_HTTP_METHOD_PUT, method))
direction = _RECEIVE;
- if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
+ else if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
direction = _SEND;
+ else
+ {
+ GNUNET_break_op (0);
+ goto error;
+ }
+
if (check == GNUNET_NO)
goto error;
plugin->cur_connections++;
-
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: New inbound connection from %s with tag %u\n",
GNUNET_i2s (&target), tag);
-#endif
/* find duplicate session */
t = plugin->head;
}
if (t != NULL)
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Duplicate session, dismissing new connection from peer `%s'\n",
GNUNET_i2s (&target));
-#endif
goto error;
}
if (t == NULL)
goto create;
-
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Found existing semi-session for `%s'\n",
GNUNET_i2s (&target));
-#endif
if ((direction == _SEND) && (t->server_send != NULL))
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Duplicate GET session, dismissing new connection from peer `%s'\n",
GNUNET_i2s (&target));
-#endif
goto error;
}
else
GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head,
plugin->server_semi_tail, s);
GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Found matching semi-session, merging session for peer `%s'\n",
GNUNET_i2s (&target));
-#endif
goto found;
}
if ((direction == _RECEIVE) && (t->server_recv != NULL))
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Duplicate PUT session, dismissing new connection from peer `%s'\n",
GNUNET_i2s (&target));
-#endif
goto error;
}
else
GNUNET_CONTAINER_DLL_remove (plugin->server_semi_head,
plugin->server_semi_tail, s);
GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Found matching semi-session, merging session for peer `%s'\n",
GNUNET_i2s (&target));
-#endif
goto found;
}
create:
/* create new session */
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Creating new session for peer `%s' \n",
GNUNET_i2s (&target));
-#endif
-
switch (conn_info->client_addr->sa_family)
{
case (AF_INET):
memcpy (&a4.ipv4_addr, &s4->sin_addr, sizeof (struct in_addr));
a = &a4;
a_len = sizeof (struct IPv4HttpAddress);
+ ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) s4, sizeof (struct sockaddr_in));
break;
case (AF_INET6):
s6 = ((struct sockaddr_in6 *) conn_info->client_addr);
memcpy (&a6.ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
a = &a6;
a_len = sizeof (struct IPv6HttpAddress);
+ ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) s6, sizeof (struct sockaddr_in6));
break;
default:
GNUNET_break (0);
goto error;
}
-
s = create_session (plugin, &target, a, a_len, NULL, NULL);
+ s->ats_address_network_type = ats.value;
s->inbound = GNUNET_YES;
s->next_receive = GNUNET_TIME_absolute_get_zero ();
goto found;
error:
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Invalid connection request\n");
-#endif
return NULL;
found:
#if MHD_VERSION >= 0x00090E00
int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000);
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Setting timeout for %X to %u sec.\n", sc, to);
-#endif
MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to);
- server_reschedule (plugin, GNUNET_NO);
+
+ struct MHD_Daemon *d = NULL;
+
+ if (s->addrlen == sizeof (struct IPv6HttpAddress))
+ d = plugin->server_v6;
+ if (s->addrlen == sizeof (struct IPv4HttpAddress))
+ d = plugin->server_v4;
+
+ server_reschedule (plugin, d, GNUNET_NO);
#endif
return sc;
}
/* connection is to be disconnected */
if (sc->disconnect == GNUNET_YES)
{
+ /* 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);
-#if VERBOSE_SERVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sent HTTP/1.1: 200 OK as PUT Response\n");
-#endif
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)
{
response =
MHD_create_response_from_callback (-1, 32 * 1024, &server_send_callback,
s, NULL);
- res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
+ MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return MHD_YES;
}
{
if (*upload_data_size == 0)
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Peer `%s' PUT on address `%s' connected\n",
GNUNET_i2s (&s->target),
- http_plugin_address_to_string (NULL, s->addr, s->addrlen));
-#endif
+ http_plugin_address_to_string (NULL, s->addr,
+ s->addrlen));
return MHD_YES;
}
- /* Recieving data */
+ /* Receiving data */
if ((*upload_data_size > 0))
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
- "Server: peer `%s' PUT on address `%s' received %Zu bytes\n",
+ "Server: peer `%s' PUT on address `%s' received %u bytes\n",
GNUNET_i2s (&s->target),
- http_plugin_address_to_string (NULL,s->addr, s->addrlen),
+ http_plugin_address_to_string (NULL, s->addr,
+ s->addrlen),
*upload_data_size);
-#endif
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
if ((s->next_receive.abs_value <= now.abs_value))
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: %X: PUT with %u bytes forwarded to MST\n", s,
*upload_data_size);
-#endif
if (s->msg_tk == NULL)
{
s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s);
}
- res =
GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data,
*upload_data_size, GNUNET_NO, GNUNET_NO);
int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000);
struct ServerConnection *t = NULL;
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
- "Server: Received %Zu bytes\n", *upload_data_size);
-#endif
-
+ "Server: Received %u bytes\n", *upload_data_size);
/* Setting timeouts for other connections */
if (s->server_recv != NULL)
{
t = s->server_recv;
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Setting timeout for %X to %u sec.\n", t,
to);
-#endif
MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT,
to);
}
if (s->server_send != NULL)
{
t = s->server_send;
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: Setting timeout for %X to %u sec.\n", t,
to);
-#endif
MHD_set_connection_option (t->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT,
to);
}
- server_reschedule (plugin, GNUNET_NO);
+ struct MHD_Daemon *d = NULL;
+
+ if (s->addrlen == sizeof (struct IPv6HttpAddress))
+ d = plugin->server_v6;
+ if (s->addrlen == sizeof (struct IPv4HttpAddress))
+ d = plugin->server_v4;
+ server_reschedule (plugin, d, GNUNET_NO);
#endif
(*upload_data_size) = 0;
}
else
{
-#if DEBUG_HTTP
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Server: %X no inbound bandwidth available! Next read was delayed by %llu ms\n",
s, now.abs_value - s->next_receive.abs_value);
-#endif
}
return MHD_YES;
}
void **httpSessionCache)
{
struct ServerConnection *sc = *httpSessionCache;
- struct ServerConnection *tc = *httpSessionCache;
+ struct ServerConnection *tc = NULL;
struct Session *s = NULL;
struct Session *t = NULL;
struct Plugin *plugin = NULL;
plugin = s->plugin;
if (sc->direction == _SEND)
{
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: %X peer `%s' GET on address `%s' disconnected\n",
s->server_send, GNUNET_i2s (&s->target),
http_plugin_address_to_string (NULL, s->addr, s->addrlen));
-#endif
+
s->server_send = NULL;
if (s->server_recv != NULL)
}
if (sc->direction == _RECEIVE)
{
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: %X peer `%s' PUT on address `%s' disconnected\n",
s->server_recv, GNUNET_i2s (&s->target),
http_plugin_address_to_string (NULL, s->addr, s->addrlen));
-#endif
s->server_recv = NULL;
if (s->server_send != NULL)
{
}
plugin->cur_connections--;
- server_reschedule (plugin, GNUNET_NO);
+ struct MHD_Daemon *d = NULL;
+
+ if (s->addrlen == sizeof (struct IPv6HttpAddress))
+ d = plugin->server_v6;
+ if (s->addrlen == sizeof (struct IPv4HttpAddress))
+ d = plugin->server_v4;
+ server_reschedule (plugin, d, GNUNET_NO);
if ((s->server_send == NULL) && (s->server_recv == NULL))
{
-#if VERBOSE_SERVER
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Server: peer `%s' on address `%s' disconnected\n",
GNUNET_i2s (&s->target),
http_plugin_address_to_string (NULL, s->addr, s->addrlen));
-#endif
if (s->msg_tk != NULL)
{
GNUNET_SERVER_mst_destroy (s->msg_tk);
server_send (struct Session *s, struct HTTP_Message *msg)
{
GNUNET_CONTAINER_DLL_insert (s->msg_head, s->msg_tail, msg);
- server_reschedule (s->plugin, GNUNET_YES);
+
+ if (s->addrlen == sizeof (struct IPv4HttpAddress))
+ {
+ server_reschedule (s->plugin, s->plugin->server_v4, GNUNET_YES);
+ }
+ else if (s->addrlen == sizeof (struct IPv6HttpAddress))
+ {
+ server_reschedule (s->plugin, s->plugin->server_v6, GNUNET_YES);
+ }
+ else
+ return GNUNET_SYSERR;
return GNUNET_OK;
}
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
- "Running IPv6 server\n");
+#if 0
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+ "Running IPv4 server\n");
#endif
GNUNET_assert (MHD_YES == MHD_run (plugin->server_v4));
if (plugin->server_v4 != NULL)
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
- "Running IPv6 server\n");
+#if 0
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+ "Running IPv6 server\n");
#endif
GNUNET_assert (MHD_YES == MHD_run (plugin->server_v6));
if (plugin->server_v6 != NULL)
GNUNET_SCHEDULER_cancel (plugin->server_v4_task);
plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK;
}
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
- "Scheduling IPv4 server task in %llu ms\n", tv);
+#if 0
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+ "Scheduling IPv4 server task in %llu ms\n", tv);
#endif
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
GNUNET_SCHEDULER_cancel (plugin->server_v6_task);
plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK;
}
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
- "Scheduling IPv6 server task in %llu ms\n", tv);
+#if 0
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+ "Scheduling IPv6 server task in %llu ms\n", tv);
#endif
ret =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
#if MHD_VERSION >= 0x00090E00
- timeout = GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT.rel_value / 1000;
+ timeout = HTTP_NOT_VALIDATED_TIMEOUT.rel_value / 1000;
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"MHD can set timeout per connection! Default time out %u sec.\n",
timeout);
plugin->name, plugin->port);
return GNUNET_SYSERR;
}
+ server_reschedule (plugin, plugin->server_v4, GNUNET_NO);
+
if ((plugin->ipv6 == GNUNET_YES) && (plugin->server_v6 == NULL))
{
GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
plugin->name, plugin->port);
return GNUNET_SYSERR;
}
+ server_reschedule (plugin, plugin->server_v6, GNUNET_NO);
- server_reschedule (plugin, GNUNET_NO);
#if DEBUG_HTTP
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
struct Session *s = NULL;
struct Session *t = NULL;
-#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
- "server_stop\n");
-#endif
-
struct MHD_Daemon *server_v4_tmp = plugin->server_v4;
plugin->server_v4 = NULL;
while (s != NULL)
{
#if VERBOSE_SERVER
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
"Deleting semi-sessions %p\n", s);
#endif
t = s->next;
- struct HTTP_Message * msg = s->msg_head;
- struct HTTP_Message * tmp = s->msg_head;
+ struct HTTP_Message *msg = s->msg_head;
+ struct HTTP_Message *tmp = NULL;
+
while (msg != NULL)
{
tmp = msg->next;
- GNUNET_CONTAINER_DLL_remove(s->msg_head,s->msg_tail, msg);
+ 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);
}
GNUNET_free (msg);
msg = tmp;