diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-30 13:34:45 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-30 13:34:45 +0000 |
commit | 73841c2f316bc15237d0e22880fba01b8d09abde (patch) | |
tree | 698535becffd29d4353042b8e00e4f41c1913206 /src/transport | |
parent | 07c1b760e47c04a5c6f9a22688b37a4063a22453 (diff) | |
download | gnunet-73841c2f316bc15237d0e22880fba01b8d09abde.tar.gz gnunet-73841c2f316bc15237d0e22880fba01b8d09abde.zip |
putting session handling in function
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 337 |
1 files changed, 183 insertions, 154 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 379cc3fb9..629ea9524 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -294,210 +294,239 @@ server_send_callback (void *cls, uint64_t pos, char *buf, size_t max) | |||
294 | return bytes_read; | 294 | return bytes_read; |
295 | } | 295 | } |
296 | 296 | ||
297 | /** | 297 | static struct ServerConnection * |
298 | * Process GET or PUT request received via MHD. For | 298 | server_lookup_session (struct Plugin *plugin, |
299 | * GET, queue response that will send back our pending | 299 | struct MHD_Connection *mhd_connection, |
300 | * messages. For PUT, process incoming data and send | 300 | const char * url, |
301 | * to GNUnet core. In either case, check if a session | 301 | const char *method) |
302 | * already exists and create a new one if not. | ||
303 | */ | ||
304 | static int | ||
305 | server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | ||
306 | const char *url, const char *method, const char *version, | ||
307 | const char *upload_data, size_t * upload_data_size, | ||
308 | void **httpSessionCache) | ||
309 | { | 302 | { |
310 | |||
311 | struct Plugin *plugin = cls; | ||
312 | struct ServerConnection *sc = *httpSessionCache; | ||
313 | struct Session *s = NULL; | 303 | struct Session *s = NULL; |
304 | struct Session * t; | ||
305 | struct ServerConnection *sc = NULL; | ||
306 | const union MHD_ConnectionInfo *conn_info; | ||
307 | |||
308 | struct GNUNET_PeerIdentity target; | ||
309 | size_t addrlen; | ||
310 | int check = GNUNET_NO; | ||
311 | uint32_t tag = 0; | ||
312 | int direction; | ||
314 | 313 | ||
315 | int res = MHD_YES; | 314 | conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); |
316 | struct MHD_Response *response; | 315 | if (conn_info->client_addr->sa_family == AF_INET) |
317 | 316 | addrlen = sizeof (struct sockaddr_in); | |
318 | GNUNET_assert (cls != NULL); | 317 | else if (conn_info->client_addr->sa_family == AF_INET6) |
319 | /* new connection */ | 318 | addrlen = sizeof (struct sockaddr_in6); |
320 | if (sc == NULL) | 319 | else |
321 | { | 320 | return MHD_NO; |
322 | uint32_t tag = 0; | ||
323 | const union MHD_ConnectionInfo *conn_info; | ||
324 | size_t addrlen; | ||
325 | struct GNUNET_PeerIdentity target; | ||
326 | int check = GNUNET_NO; | ||
327 | struct Session * t; | ||
328 | int direction; | ||
329 | |||
330 | conn_info = MHD_get_connection_info (mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); | ||
331 | if (conn_info->client_addr->sa_family == AF_INET) | ||
332 | addrlen = sizeof (struct sockaddr_in); | ||
333 | else if (conn_info->client_addr->sa_family == AF_INET6) | ||
334 | addrlen = sizeof (struct sockaddr_in6); | ||
335 | else | ||
336 | return MHD_NO; | ||
337 | 321 | ||
338 | if ((strlen(&url[1]) >= 105) && (url[104] == ';')) | 322 | if ((strlen(&url[1]) >= 105) && (url[104] == ';')) |
323 | { | ||
324 | char hash[104]; | ||
325 | char * tagc = (char *) &url[105]; | ||
326 | memcpy(&hash, &url[1], 103); | ||
327 | hash [103] = '\0'; | ||
328 | if (GNUNET_OK == GNUNET_CRYPTO_hash_from_string ((const char *) &hash, | ||
329 | &(target.hashPubKey))) | ||
339 | { | 330 | { |
340 | char hash[104]; | 331 | tag = strtoul (tagc, NULL, 10); |
341 | char * tagc = (char *) &url[105]; | 332 | if (tagc > 0) |
342 | memcpy(&hash, &url[1], 103); | 333 | check = GNUNET_YES; |
343 | hash [103] = '\0'; | ||
344 | if (GNUNET_OK == GNUNET_CRYPTO_hash_from_string ((const char *) &hash, &(target.hashPubKey))) | ||
345 | { | ||
346 | tag = strtoul (tagc, NULL, 10); | ||
347 | if (tagc > 0) | ||
348 | check = GNUNET_YES; | ||
349 | } | ||
350 | } | 334 | } |
335 | } | ||
351 | 336 | ||
352 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) | 337 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) |
353 | direction = _RECEIVE; | 338 | direction = _RECEIVE; |
354 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) | 339 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) |
355 | direction = _SEND; | 340 | direction = _SEND; |
356 | 341 | ||
357 | if (check == GNUNET_NO) | 342 | if (check == GNUNET_NO) |
358 | goto error; | 343 | goto error; |
359 | 344 | ||
360 | plugin->cur_connections++; | 345 | plugin->cur_connections++; |
361 | 346 | ||
362 | #if VERBOSE_SERVER | 347 | #if VERBOSE_SERVER |
363 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 348 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
364 | "Server: New inbound connection from %s with tag %u\n", GNUNET_i2s(&target), tag); | 349 | "Server: New inbound connection from %s with tag %u\n", GNUNET_i2s(&target), tag); |
365 | #endif | 350 | #endif |
366 | /* find duplicate session */ | 351 | /* find duplicate session */ |
367 | 352 | ||
368 | t = plugin->head; | 353 | t = plugin->head; |
369 | 354 | ||
370 | while (t != NULL) | 355 | while (t != NULL) |
371 | { | 356 | { |
372 | if ((t->inbound) && (0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) && | 357 | if ((t->inbound) && (0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) && |
373 | /* FIXME add source address comparison */ | 358 | /* FIXME add source address comparison */ |
374 | (t->tag == tag)) | 359 | (t->tag == tag)) |
375 | break; | 360 | break; |
376 | t = t->next; | 361 | t = t->next; |
377 | } | 362 | } |
378 | if (t != NULL) | 363 | if (t != NULL) |
379 | { | 364 | { |
380 | #if VERBOSE_SERVER | 365 | #if VERBOSE_SERVER |
381 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 366 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
382 | "Server: Duplicate session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); | 367 | "Server: Duplicate session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); |
383 | #endif | 368 | #endif |
384 | goto error; | 369 | goto error; |
385 | } | 370 | } |
386 | 371 | ||
387 | /* find semi-session */ | 372 | /* find semi-session */ |
388 | t = plugin->server_semi_head; | 373 | t = plugin->server_semi_head; |
389 | 374 | ||
390 | while (t != NULL) | 375 | while (t != NULL) |
376 | { | ||
377 | /* FIXME add source address comparison */ | ||
378 | if ((0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) && | ||
379 | (t->tag == tag)) | ||
391 | { | 380 | { |
392 | /* FIXME add source address comparison */ | 381 | break; |
393 | if ((0 == memcmp (&t->target, &target, sizeof (struct GNUNET_PeerIdentity))) && | ||
394 | (t->tag == tag)) | ||
395 | { | ||
396 | break; | ||
397 | } | ||
398 | t = t->next; | ||
399 | } | 382 | } |
383 | t = t->next; | ||
384 | } | ||
400 | 385 | ||
401 | if (t == NULL) | 386 | if (t == NULL) |
402 | goto create; | 387 | goto create; |
403 | 388 | ||
404 | #if VERBOSE_SERVER | 389 | #if VERBOSE_SERVER |
405 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 390 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
406 | "Server: Found existing semi-session for `%s'\n", GNUNET_i2s (&target)); | 391 | "Server: Found existing semi-session for `%s'\n", GNUNET_i2s (&target)); |
407 | #endif | 392 | #endif |
408 | 393 | ||
409 | if ((direction == _SEND) && (t->server_send != NULL)) | 394 | if ((direction == _SEND) && (t->server_send != NULL)) |
410 | { | 395 | { |
411 | #if VERBOSE_SERVER | 396 | #if VERBOSE_SERVER |
412 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 397 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
413 | "Server: Duplicate GET session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); | 398 | "Server: Duplicate GET session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); |
414 | #endif | 399 | #endif |
415 | goto error; | 400 | goto error; |
416 | } | 401 | } |
417 | else | 402 | else |
418 | { | 403 | { |
419 | s = t; | 404 | s = t; |
420 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); | 405 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); |
421 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); | 406 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); |
422 | #if VERBOSE_SERVER | 407 | #if VERBOSE_SERVER |
423 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 408 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
424 | "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); | 409 | "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); |
425 | #endif | 410 | #endif |
426 | 411 | ||
427 | goto found; | 412 | goto found; |
428 | } | 413 | } |
429 | if ((direction == _RECEIVE) && (t->server_recv != NULL)) | 414 | if ((direction == _RECEIVE) && (t->server_recv != NULL)) |
430 | { | 415 | { |
431 | #if VERBOSE_SERVER | 416 | #if VERBOSE_SERVER |
432 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 417 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
433 | "Server: Duplicate PUT session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); | 418 | "Server: Duplicate PUT session, dismissing new connection from peer `%s'\n", GNUNET_i2s (&target)); |
434 | #endif | 419 | #endif |
435 | goto error; | 420 | goto error; |
436 | } | 421 | } |
437 | else | 422 | else |
438 | { | 423 | { |
439 | s = t; | 424 | s = t; |
440 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); | 425 | GNUNET_CONTAINER_DLL_remove(plugin->server_semi_head, plugin->server_semi_tail, s); |
441 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); | 426 | GNUNET_CONTAINER_DLL_insert(plugin->head, plugin->tail, s); |
442 | #if VERBOSE_SERVER | 427 | #if VERBOSE_SERVER |
443 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 428 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
444 | "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); | 429 | "Server: Found matching semi-session, merging session for peer `%s'\n", GNUNET_i2s (&target)); |
445 | #endif | 430 | #endif |
446 | goto found; | 431 | goto found; |
447 | } | 432 | } |
448 | 433 | ||
449 | create: | 434 | create: |
450 | /* create new session */ | 435 | /* create new session */ |
451 | #if VERBOSE_SERVER | 436 | #if VERBOSE_SERVER |
452 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 437 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
453 | "Server: Creating new session for peer `%s' \n", GNUNET_i2s (&target)); | 438 | "Server: Creating new session for peer `%s' \n", GNUNET_i2s (&target)); |
454 | #endif | 439 | #endif |
455 | 440 | ||
456 | s = create_session (plugin, | 441 | s = create_session (plugin, |
457 | &target, | 442 | &target, |
458 | conn_info->client_addr, | 443 | conn_info->client_addr, |
459 | addrlen, | 444 | addrlen, |
460 | NULL, | 445 | NULL, |
461 | NULL); | 446 | NULL); |
462 | 447 | ||
463 | s->inbound = GNUNET_YES; | 448 | s->inbound = GNUNET_YES; |
464 | s->next_receive = GNUNET_TIME_absolute_get_zero(); | 449 | s->next_receive = GNUNET_TIME_absolute_get_zero(); |
465 | s->tag= tag; | 450 | s->tag= tag; |
466 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) | 451 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) |
467 | s->server_recv = s; | 452 | s->server_recv = s; |
468 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) | 453 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) |
469 | s->server_send = s; | 454 | s->server_send = s; |
470 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); | 455 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); |
456 | |||
457 | goto found; | ||
471 | 458 | ||
472 | goto found; | ||
473 | error: | 459 | error: |
474 | #if VERBOSE_SERVER | 460 | #if VERBOSE_SERVER |
475 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 461 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
476 | "Server: Invalid connection request\n"); | 462 | "Server: Invalid connection request\n"); |
477 | #endif | 463 | #endif |
478 | response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); | 464 | return NULL; |
479 | res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); | 465 | |
480 | MHD_destroy_response (response); | ||
481 | return res; | ||
482 | found: | 466 | found: |
483 | sc = GNUNET_malloc (sizeof (struct ServerConnection)); | 467 | sc = GNUNET_malloc (sizeof (struct ServerConnection)); |
484 | sc->mhd_conn = mhd_connection; | 468 | sc->mhd_conn = mhd_connection; |
485 | sc->direction = direction; | 469 | sc->direction = direction; |
486 | sc->session = s; | 470 | sc->session = s; |
487 | if (direction == _SEND) | 471 | if (direction == _SEND) |
488 | s->server_send = sc; | 472 | s->server_send = sc; |
489 | if (direction == _RECEIVE) | 473 | if (direction == _RECEIVE) |
490 | s->server_recv = sc; | 474 | s->server_recv = sc; |
491 | 475 | ||
492 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); | 476 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); |
493 | #if VERBOSE_SERVER | 477 | #if VERBOSE_SERVER |
494 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 478 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
495 | "Server: Setting Timeout to %u\n", to); | 479 | "Server: Setting Timeout to %u\n", to); |
496 | #endif | 480 | #endif |
497 | #if MHD_VERSION >= 0x00090E00 | 481 | #if MHD_VERSION >= 0x00090E00 |
498 | MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); | 482 | #if 0 |
483 | struct ServerConnection *stc = NULL; | ||
484 | stc = s->server_send; | ||
485 | /* Set timeout for this connection */ | ||
486 | MHD_set_connection_option (stc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
487 | /* set timeout for other semi connection */ | ||
488 | stc = s->server_recv; | ||
489 | MHD_set_connection_option (stc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
499 | #endif | 490 | #endif |
500 | (*httpSessionCache) = sc; | 491 | #endif |
492 | return sc; | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Process GET or PUT request received via MHD. For | ||
497 | * GET, queue response that will send back our pending | ||
498 | * messages. For PUT, process incoming data and send | ||
499 | * to GNUnet core. In either case, check if a session | ||
500 | * already exists and create a new one if not. | ||
501 | */ | ||
502 | static int | ||
503 | server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | ||
504 | const char *url, const char *method, const char *version, | ||
505 | const char *upload_data, size_t * upload_data_size, | ||
506 | void **httpSessionCache) | ||
507 | { | ||
508 | |||
509 | struct Plugin *plugin = cls; | ||
510 | struct ServerConnection *sc = *httpSessionCache; | ||
511 | struct Session *s = NULL; | ||
512 | |||
513 | int res = MHD_YES; | ||
514 | struct MHD_Response *response; | ||
515 | |||
516 | GNUNET_assert (cls != NULL); | ||
517 | /* new connection */ | ||
518 | if (sc == NULL) | ||
519 | { | ||
520 | sc = server_lookup_session(plugin, mhd_connection, url, method); | ||
521 | if (sc != NULL) | ||
522 | (*httpSessionCache) = sc; | ||
523 | else | ||
524 | { | ||
525 | response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); | ||
526 | res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); | ||
527 | MHD_destroy_response (response); | ||
528 | return res; | ||
529 | } | ||
501 | } | 530 | } |
502 | 531 | ||
503 | 532 | ||