aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_server.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-09-30 13:34:45 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-09-30 13:34:45 +0000
commit73841c2f316bc15237d0e22880fba01b8d09abde (patch)
tree698535becffd29d4353042b8e00e4f41c1913206 /src/transport/plugin_transport_http_server.c
parent07c1b760e47c04a5c6f9a22688b37a4063a22453 (diff)
downloadgnunet-73841c2f316bc15237d0e22880fba01b8d09abde.tar.gz
gnunet-73841c2f316bc15237d0e22880fba01b8d09abde.zip
putting session handling in function
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r--src/transport/plugin_transport_http_server.c337
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/** 297static struct ServerConnection *
298 * Process GET or PUT request received via MHD. For 298server_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 */
304static int
305server_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
449create: 434create:
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;
473error: 459error:
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;
482found: 466found:
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 */
502static int
503server_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