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/transport/plugin_transport_http_server.c | |
parent | 5743ad799f624901abbbf35748d8aeca9edbe66b (diff) | |
download | gnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.tar.gz gnunet-4878053408a3681dca18b6a264d2b6ec719e79b0.zip |
server side connection accepting and merging
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 183 |
1 files changed, 180 insertions, 3 deletions
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 |