diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-15 15:54:05 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-15 15:54:05 +0000 |
commit | 4878053408a3681dca18b6a264d2b6ec719e79b0 (patch) | |
tree | f95c77ced25342bc93227873a0d2bc4a86e6345a /src | |
parent | 5743ad799f624901abbbf35748d8aeca9edbe66b (diff) | |
download | gnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.tar.gz gnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.zip |
server side connection accepting and merging
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_http.h | 17 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 11 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 183 |
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 | ||
237 | struct Session * | ||
238 | create_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 | |||
225 | const char * | 242 | const char * |
226 | http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen); | 243 | http_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 | |||
29 | static void | 33 | static void |
30 | server_log (void *arg, const char *fmt, va_list ap) | 34 | server_log (void *arg, const char *fmt, va_list ap) |
31 | { | 35 | { |
@@ -49,11 +53,14 @@ static int | |||
49 | server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) | 53 | server_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 | |||
360 | create: | ||
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; | ||
382 | error: | ||
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 | |||
390 | found: | ||
391 | (*httpSessionCache) = s; | ||
392 | return MHD_YES; | ||
393 | |||
394 | #endif | ||
395 | } | ||
396 | |||
397 | |||
398 | return res; | ||
230 | } | 399 | } |
231 | 400 | ||
232 | static void | 401 | static 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 | ||
239 | int | 416 | int |