aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-09-15 15:54:05 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-09-15 15:54:05 +0000
commit4878053408a3681dca18b6a264d2b6ec719e79b0 (patch)
treef95c77ced25342bc93227873a0d2bc4a86e6345a /src/transport
parent5743ad799f624901abbbf35748d8aeca9edbe66b (diff)
downloadgnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.tar.gz
gnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.zip
server side connection accepting and merging
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_http.h17
-rw-r--r--src/transport/plugin_transport_http_client.c11
-rw-r--r--src/transport/plugin_transport_http_server.c183
3 files changed, 206 insertions, 5 deletions
diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h
index 24752aff3..8ea1b03cf 100644
--- a/src/transport/plugin_transport_http.h
+++ b/src/transport/plugin_transport_http.h
@@ -115,10 +115,12 @@ struct Plugin
115 int max_connections; 115 int max_connections;
116 116
117 117
118
118 /* Plugin values */ 119 /* Plugin values */
119 120
120 121
121 int cur_connections; 122 int cur_connections;
123 uint32_t last_tag;
122 124
123 /* 125 /*
124 * Server handles 126 * Server handles
@@ -134,6 +136,12 @@ struct Plugin
134 char *key; 136 char *key;
135 char *cert; 137 char *cert;
136 138
139 struct Session *server_semi_head;
140
141 struct Session *server_semi_tail;
142
143
144
137 /* 145 /*
138 * Client handles 146 * Client handles
139 */ 147 */
@@ -219,9 +227,18 @@ struct Session
219 void *client_put; 227 void *client_put;
220 void *client_get; 228 void *client_get;
221 229
230 void *server_put;
231 void *server_get;
232
233 uint32_t tag;
222 234
223}; 235};
224 236
237struct Session *
238create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
239 const void *addr, size_t addrlen,
240 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls);
241
225const char * 242const char *
226http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen); 243http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen);
227 244
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index ea8a55614..ca582332a 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -228,6 +228,7 @@ client_disconnect (struct Session *s)
228 GNUNET_break (0); 228 GNUNET_break (0);
229 } 229 }
230 curl_easy_cleanup (s->client_get); 230 curl_easy_cleanup (s->client_get);
231 plugin->cur_connections += 2;
231 232
232 /* Re-schedule since handles have changed */ 233 /* Re-schedule since handles have changed */
233 if (plugin->client_perform_task!= GNUNET_SCHEDULER_NO_TASK) 234 if (plugin->client_perform_task!= GNUNET_SCHEDULER_NO_TASK)
@@ -257,9 +258,14 @@ client_connect (struct Session *s)
257 258
258 s->inbound = GNUNET_NO; 259 s->inbound = GNUNET_NO;
259 260
261 s->plugin->last_tag++;
260 /* create url */ 262 /* create url */
261 GNUNET_asprintf (&url, "%s", http_plugin_address_to_string (s->plugin, s->addr, s->addrlen)); 263 GNUNET_asprintf (&url, "%s%s;%u", http_plugin_address_to_string (s->plugin, s->addr, s->addrlen), GNUNET_h2s_full (&s->plugin->env->my_identity->hashPubKey),s->plugin->last_tag);
262 264#if 0
265 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name,
266 "URL `%s'\n",
267 url);
268#endif
263 /* create get connection */ 269 /* create get connection */
264 s->client_get = curl_easy_init (); 270 s->client_get = curl_easy_init ();
265#if VERBOSE_CLIENT 271#if VERBOSE_CLIENT
@@ -342,6 +348,7 @@ client_connect (struct Session *s)
342 } 348 }
343 349
344 /* Perform connect */ 350 /* Perform connect */
351 s->plugin->cur_connections += 2;
345 s->plugin->client_perform_task = GNUNET_SCHEDULER_add_now (client_run, s->plugin); 352 s->plugin->client_perform_task = GNUNET_SCHEDULER_add_now (client_run, s->plugin);
346 353
347 return res; 354 return res;
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 2260cb74e..9f10958c5 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -26,6 +26,10 @@
26 26
27#include "plugin_transport_http.h" 27#include "plugin_transport_http.h"
28 28
29#define HTTP_ERROR_RESPONSE "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"><HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>Not Found</H1>The requested URL was not found on this server.<P><HR><ADDRESS></ADDRESS></BODY></HTML>"
30#define _RECEIVE 0
31#define _SEND 1
32
29static void 33static void
30server_log (void *arg, const char *fmt, va_list ap) 34server_log (void *arg, const char *fmt, va_list ap)
31{ 35{
@@ -49,11 +53,14 @@ static int
49server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) 53server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len)
50{ 54{
51 struct Plugin * plugin = cls; 55 struct Plugin * plugin = cls;
52 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_accept_cb\n"); 56
53 if (plugin->cur_connections <= plugin->max_connections) 57 if (plugin->cur_connections <= plugin->max_connections)
54 return MHD_YES; 58 return MHD_YES;
55 else 59 else
60 {
61 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: Cannot accept new connections\n");
56 return MHD_NO; 62 return MHD_NO;
63 }
57} 64}
58 65
59 66
@@ -225,8 +232,170 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection,
225 const char *upload_data, size_t * upload_data_size, 232 const char *upload_data, size_t * upload_data_size,
226 void **httpSessionCache) 233 void **httpSessionCache)
227{ 234{
228 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_access_cb\n"); 235 //struct Plugin *plugin = cls;
229 return 0; 236 struct Session *s = *httpSessionCache;
237 int res = MHD_YES;
238 //struct MHD_Response *response;
239
240 GNUNET_assert (cls != NULL);
241 /* new connection */
242 if (s == NULL)
243 {
244#if 0
245 uint32_t tag;
246 const union MHD_ConnectionInfo *conn_info;
247 size_t addrlen;
248 struct GNUNET_PeerIdentity target;
249 int check = GNUNET_NO;
250 struct Session * t;
251 int direction;
252
253 conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
254 if (conn_info->client_addr->sa_family == AF_INET)
255 addrlen = sizeof (struct sockaddr_in);
256 else if (conn_info->client_addr->sa_family == AF_INET6)
257 addrlen = sizeof (struct sockaddr_in6);
258 else
259 return MHD_NO;
260
261 if ((strlen(&url[1]) >= 105) && (url[104] == ';'))
262 {
263 char hash[104];
264 char * tagc = (char *) &url[105];
265 memcpy(&hash, &url[1], 103);
266 hash [103] = '\0';
267 if (GNUNET_OK == GNUNET_CRYPTO_hash_from_string ((const char *) &hash, &(target.hashPubKey)))
268 {
269 tag = strtoul (tagc, NULL, 10);
270 if (tagc > 0)
271 check = GNUNET_YES;
272 }
273 }
274
275 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method))
276 direction = _RECEIVE;
277 if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
278 direction = _SEND;
279
280 if (check == GNUNET_NO)
281 goto error;
282#if VERBOSE_SERVER
283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: New inbound connection from %s with tag %u\n", GNUNET_h2s_full(&(target.hashPubKey)), tag);
284#endif
285 /* find duplicate session */
286
287 t = plugin->head;
288
289 while (t != NULL)
290 {
291 if ((t->inbound) && (0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) &&
292 /* FIXME add source address comparison */
293 (t->tag == tag))
294 break;
295 t = t->next;
296 }
297 if (t != NULL)
298 {
299#if VERBOSE_SERVER
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target));
301#endif
302 goto error;
303 }
304
305 /* find semi-session */
306 t = plugin->server_semi_head;
307
308 while (t != NULL)
309 {
310 /* FIXME add source address comparison */
311 if ((0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) &&
312 (t->tag == tag))
313 {
314 break;
315 }
316 t = t->next;
317 }
318
319 if (t == NULL)
320 goto create;
321
322 if ((direction == _SEND) && (t->server_get != NULL))
323 {
324#if VERBOSE_SERVER
325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate GET session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target));
326#endif
327 goto error;
328 }
329 else
330 {
331 s = t;
332 s->server_get = s;
333 GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s);
334 GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s);
335#if VERBOSE_SERVER
336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Found matching semi-session, merging session for peer `%s' `%s'\n", GNUNET_i2s (&target));
337#endif
338
339 goto found;
340 }
341 if ((direction == _RECEIVE) && (t->server_put != NULL))
342 {
343#if VERBOSE_SERVER
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Duplicate PUT session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target));
345#endif
346 goto error;
347 }
348 else
349 {
350 s = t;
351 s->server_put = s;
352 GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s);
353 GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s);
354#if VERBOSE_SERVER
355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Found matching semi-session, merging session for peer `%s' `%s'\n", GNUNET_i2s (&target));
356#endif
357 goto found;
358 }
359
360create:
361/* create new session */
362#if VERBOSE_SERVER
363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "server: Creating new session for peer `%s' \n", GNUNET_i2s (&target));
364#endif
365
366 s = create_session(plugin,
367 &target,
368 conn_info->client_addr,
369 addrlen,
370 NULL,
371 NULL);
372
373 s->inbound = GNUNET_YES;
374 s->tag= tag;
375 if (0 == strcmp (MHD_HTTP_METHOD_PUT, method))
376 s->server_put = s;
377 if (0 == strcmp (MHD_HTTP_METHOD_GET, method))
378 s->server_get = s;
379 GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s);
380
381 goto found;
382error:
383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: Invalid connection request\n");
384 response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO);
385 res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response);
386 MHD_destroy_response (response);
387 return res;
388
389
390found:
391 (*httpSessionCache) = s;
392 return MHD_YES;
393
394#endif
395 }
396
397
398 return res;
230} 399}
231 400
232static void 401static void
@@ -234,6 +403,14 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection,
234 void **httpSessionCache) 403 void **httpSessionCache)
235{ 404{
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_disconnect_cb\n"); 405 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_disconnect_cb\n");
406 /*
407 struct Session *s = *httpSessionCache;
408
409 if (s != NULL)
410 {
411 notify_session_end(s->plugin, &s->target, s);
412 }
413*/
237} 414}
238 415
239int 416int