diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2010-06-28 13:22:04 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2010-06-28 13:22:04 +0000 |
commit | e20a9ae6460ba00b0e7994e16cdb063ea802a09a (patch) | |
tree | a66805f07edcef0e51223ebcfd15fb3382c671ba /src | |
parent | 046b26c62c7ebb678be1ffe5c2ea6450d7ae0722 (diff) | |
download | gnunet-e20a9ae6460ba00b0e7994e16cdb063ea802a09a.tar.gz gnunet-e20a9ae6460ba00b0e7994e16cdb063ea802a09a.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_http.c | 487 |
1 files changed, 218 insertions, 269 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index bd129351b..485fccc49 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -104,13 +104,6 @@ struct IPv6HttpAddress | |||
104 | 104 | ||
105 | }; | 105 | }; |
106 | 106 | ||
107 | struct HTTP_inbound_transmission | ||
108 | { | ||
109 | /** | ||
110 | * bytes received | ||
111 | */ | ||
112 | size_t bytes_recv; | ||
113 | }; | ||
114 | 107 | ||
115 | /** | 108 | /** |
116 | * Message to send using http | 109 | * Message to send using http |
@@ -156,11 +149,11 @@ struct HTTP_Message | |||
156 | }; | 149 | }; |
157 | 150 | ||
158 | 151 | ||
159 | struct HTTP_Connection | 152 | struct HTTP_Connection_out |
160 | { | 153 | { |
161 | struct HTTP_Connection * next; | 154 | struct HTTP_Connection_out * next; |
162 | 155 | ||
163 | struct HTTP_Connection * prev; | 156 | struct HTTP_Connection_out * prev; |
164 | 157 | ||
165 | void * addr; | 158 | void * addr; |
166 | size_t addrlen; | 159 | size_t addrlen; |
@@ -179,6 +172,34 @@ struct HTTP_Connection | |||
179 | struct Session * session; | 172 | struct Session * session; |
180 | }; | 173 | }; |
181 | 174 | ||
175 | struct HTTP_Connection_in | ||
176 | { | ||
177 | struct HTTP_Connection_in * next; | ||
178 | |||
179 | struct HTTP_Connection_in * prev; | ||
180 | |||
181 | void * addr; | ||
182 | size_t addrlen; | ||
183 | |||
184 | unsigned int connected; | ||
185 | unsigned int send_paused; | ||
186 | |||
187 | struct GNUNET_SERVER_MessageStreamTokenizer * msgtok; | ||
188 | |||
189 | struct Session * session; | ||
190 | |||
191 | /** | ||
192 | * Is there a HTTP/PUT in progress? | ||
193 | */ | ||
194 | int is_put_in_progress; | ||
195 | |||
196 | /** | ||
197 | * Is the http request invalid? | ||
198 | */ | ||
199 | int is_bad_request; | ||
200 | }; | ||
201 | |||
202 | |||
182 | /** | 203 | /** |
183 | * Session handle for connections. | 204 | * Session handle for connections. |
184 | */ | 205 | */ |
@@ -240,26 +261,11 @@ struct Session | |||
240 | uint32_t quota; | 261 | uint32_t quota; |
241 | 262 | ||
242 | /** | 263 | /** |
243 | * Is there a HTTP/PUT in progress? | ||
244 | */ | ||
245 | int is_put_in_progress; | ||
246 | |||
247 | /** | ||
248 | * Is the http request invalid? | ||
249 | */ | ||
250 | int is_bad_request; | ||
251 | |||
252 | /** | ||
253 | * Encoded hash | 264 | * Encoded hash |
254 | */ | 265 | */ |
255 | struct GNUNET_CRYPTO_HashAsciiEncoded hash; | 266 | struct GNUNET_CRYPTO_HashAsciiEncoded hash; |
256 | 267 | ||
257 | /** | 268 | /** |
258 | * Incoming message | ||
259 | */ | ||
260 | struct HTTP_inbound_transmission pending_inbound_msg; | ||
261 | |||
262 | /** | ||
263 | * curl handle for outbound transmissions | 269 | * curl handle for outbound transmissions |
264 | */ | 270 | */ |
265 | CURL *curl_handle; | 271 | CURL *curl_handle; |
@@ -267,10 +273,13 @@ struct Session | |||
267 | /** | 273 | /** |
268 | * Message tokenizer for incoming data | 274 | * Message tokenizer for incoming data |
269 | */ | 275 | */ |
270 | struct GNUNET_SERVER_MessageStreamTokenizer * msgtok; | 276 | //struct GNUNET_SERVER_MessageStreamTokenizer * msgtok; |
271 | 277 | ||
272 | struct HTTP_Connection *outbound_connections_head; | 278 | struct HTTP_Connection_out *outbound_connections_head; |
273 | struct HTTP_Connection *outbound_connections_tail; | 279 | struct HTTP_Connection_out *outbound_connections_tail; |
280 | |||
281 | struct HTTP_Connection_in *inbound_connections_head; | ||
282 | struct HTTP_Connection_in *inbound_connections_tail; | ||
274 | }; | 283 | }; |
275 | 284 | ||
276 | /** | 285 | /** |
@@ -364,8 +373,6 @@ create_session (void * cls, | |||
364 | cs->plugin = plugin; | 373 | cs->plugin = plugin; |
365 | memcpy(&cs->identity, peer, sizeof (struct GNUNET_PeerIdentity)); | 374 | memcpy(&cs->identity, peer, sizeof (struct GNUNET_PeerIdentity)); |
366 | GNUNET_CRYPTO_hash_to_enc(&cs->identity.hashPubKey,&(cs->hash)); | 375 | GNUNET_CRYPTO_hash_to_enc(&cs->identity.hashPubKey,&(cs->hash)); |
367 | cs->pending_inbound_msg.bytes_recv = 0; | ||
368 | cs->msgtok = NULL; | ||
369 | cs->outbound_connections_head = NULL; | 376 | cs->outbound_connections_head = NULL; |
370 | cs->outbound_connections_tail = NULL; | 377 | cs->outbound_connections_tail = NULL; |
371 | return cs; | 378 | return cs; |
@@ -403,21 +410,141 @@ static struct Session * session_get (void * cls, const struct GNUNET_PeerIdentit | |||
403 | return cs; | 410 | return cs; |
404 | } | 411 | } |
405 | 412 | ||
413 | static char * create_url(void * cls, const void * addr, size_t addrlen) | ||
414 | { | ||
415 | struct Plugin *plugin = cls; | ||
416 | char *address; | ||
417 | char *url = NULL; | ||
418 | |||
419 | GNUNET_assert ((addr!=NULL) && (addrlen != 0)); | ||
420 | if (addrlen == (sizeof (struct IPv4HttpAddress))) | ||
421 | { | ||
422 | address = GNUNET_malloc(INET_ADDRSTRLEN + 1); | ||
423 | inet_ntop(AF_INET, &((struct IPv4HttpAddress *) addr)->ipv4_addr,address,INET_ADDRSTRLEN); | ||
424 | GNUNET_asprintf (&url, | ||
425 | "http://%s:%u/%s", | ||
426 | address, | ||
427 | ntohs(((struct IPv4HttpAddress *) addr)->u_port), | ||
428 | (char *) (&plugin->my_ascii_hash_ident)); | ||
429 | GNUNET_free(address); | ||
430 | } | ||
431 | else if (addrlen == (sizeof (struct IPv6HttpAddress))) | ||
432 | { | ||
433 | address = GNUNET_malloc(INET6_ADDRSTRLEN + 1); | ||
434 | inet_ntop(AF_INET6, &((struct IPv6HttpAddress *) addr)->ipv6_addr,address,INET6_ADDRSTRLEN); | ||
435 | GNUNET_asprintf(&url, | ||
436 | "http://%s:%u/%s", | ||
437 | address, | ||
438 | ntohs(((struct IPv6HttpAddress *) addr)->u6_port), | ||
439 | (char *) (&plugin->my_ascii_hash_ident)); | ||
440 | GNUNET_free(address); | ||
441 | } | ||
442 | return url; | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * Check if session already knows this address for a outbound connection to this peer | ||
447 | * If address not in session, add it to the session | ||
448 | * @param cls the plugin used | ||
449 | * @param p the session | ||
450 | * @param addr address | ||
451 | * @param addr_len address length | ||
452 | * @return the found or created address | ||
453 | */ | ||
454 | static struct HTTP_Connection_out * session_check_outbound_address (void * cls, struct Session *cs, const void * addr, size_t addr_len) | ||
455 | { | ||
456 | struct Plugin *plugin = cls; | ||
457 | struct HTTP_Connection_out * cc = cs->outbound_connections_head; | ||
458 | struct HTTP_Connection_out * con = NULL; | ||
459 | |||
460 | GNUNET_assert((addr_len == sizeof (struct IPv4HttpAddress)) || (addr_len == sizeof (struct IPv6HttpAddress))); | ||
461 | |||
462 | while (cc!=NULL) | ||
463 | { | ||
464 | if (addr_len == cc->addrlen) | ||
465 | { | ||
466 | if (0 == memcmp(cc->addr, addr, addr_len)) | ||
467 | { | ||
468 | con = cc; | ||
469 | break; | ||
470 | } | ||
471 | } | ||
472 | cc=cc->next; | ||
473 | } | ||
474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No connection info for this address was found\n",GNUNET_i2s(&cs->identity)); | ||
475 | if (con==NULL) | ||
476 | { | ||
477 | con = GNUNET_malloc(sizeof(struct HTTP_Connection_out) + addr_len); | ||
478 | con->addrlen = addr_len; | ||
479 | con->addr=&con[1]; | ||
480 | con->url=create_url(plugin, addr, addr_len); | ||
481 | con->connected = GNUNET_NO; | ||
482 | con->session = cs; | ||
483 | memcpy(con->addr, addr, addr_len); | ||
484 | GNUNET_CONTAINER_DLL_insert(cs->outbound_connections_head,cs->outbound_connections_tail,con); | ||
485 | } | ||
486 | return con; | ||
487 | } | ||
488 | |||
489 | |||
490 | /** | ||
491 | * Check if session already knows this address for a inbound connection to this peer | ||
492 | * If address not in session, add it to the session | ||
493 | * @param cls the plugin used | ||
494 | * @param p the session | ||
495 | * @param addr address | ||
496 | * @param addr_len address length | ||
497 | * @return the found or created address | ||
498 | */ | ||
499 | static struct HTTP_Connection_in * session_check_inbound_address (void * cls, struct Session *cs, const void * addr, size_t addr_len) | ||
500 | { | ||
501 | //struct Plugin *plugin = cls; | ||
502 | struct HTTP_Connection_in * cc = cs->inbound_connections_head; | ||
503 | struct HTTP_Connection_in * con = NULL; | ||
504 | |||
505 | GNUNET_assert((addr_len == sizeof (struct IPv4HttpAddress)) || (addr_len == sizeof (struct IPv6HttpAddress))); | ||
506 | |||
507 | while (cc!=NULL) | ||
508 | { | ||
509 | if (addr_len == cc->addrlen) | ||
510 | { | ||
511 | if (0 == memcmp(cc->addr, addr, addr_len)) | ||
512 | { | ||
513 | con = cc; | ||
514 | break; | ||
515 | } | ||
516 | } | ||
517 | cc=cc->next; | ||
518 | } | ||
519 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No connection info for this address was found\n",GNUNET_i2s(&cs->identity)); | ||
520 | if (con==NULL) | ||
521 | { | ||
522 | con = GNUNET_malloc(sizeof(struct HTTP_Connection_in) + addr_len); | ||
523 | con->addrlen = addr_len; | ||
524 | con->addr=&con[1]; | ||
525 | con->connected = GNUNET_NO; | ||
526 | con->session = cs; | ||
527 | memcpy(con->addr, addr, addr_len); | ||
528 | GNUNET_CONTAINER_DLL_insert(cs->inbound_connections_head,cs->inbound_connections_tail,con); | ||
529 | } | ||
530 | return con; | ||
531 | } | ||
532 | |||
406 | 533 | ||
407 | /** | 534 | /** |
408 | * Callback called by MHD when a connection is terminated | 535 | * Callback called by MHD when a connection is terminated |
409 | */ | 536 | */ |
410 | static void requestCompletedCallback (void *cls, struct MHD_Connection * connection, void **httpSessionCache) | 537 | static void requestCompletedCallback (void *cls, struct MHD_Connection * connection, void **httpSessionCache) |
411 | { | 538 | { |
412 | struct Session * cs; | 539 | struct HTTP_Connection_in * con; |
413 | 540 | ||
414 | cs = *httpSessionCache; | 541 | con = *httpSessionCache; |
415 | if (cs == NULL) | 542 | if (con == NULL) |
416 | return; | 543 | return; |
417 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection from peer `%s' was terminated\n",GNUNET_i2s(&cs->identity)); | 544 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection from peer `%s' was terminated\n",GNUNET_i2s(&con->session->identity)); |
418 | /* session set to inactive */ | 545 | /* session set to inactive */ |
419 | cs->is_put_in_progress = GNUNET_NO; | 546 | con->is_put_in_progress = GNUNET_NO; |
420 | cs->is_bad_request = GNUNET_NO; | 547 | con->is_bad_request = GNUNET_NO; |
421 | } | 548 | } |
422 | 549 | ||
423 | 550 | ||
@@ -425,19 +552,19 @@ static void messageTokenizerCallback (void *cls, | |||
425 | void *client, | 552 | void *client, |
426 | const struct GNUNET_MessageHeader *message) | 553 | const struct GNUNET_MessageHeader *message) |
427 | { | 554 | { |
428 | struct Session * cs = cls; | 555 | struct HTTP_Connection_in * con = cls; |
429 | GNUNET_assert(cs != NULL); | 556 | GNUNET_assert(con != NULL); |
430 | 557 | ||
431 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 558 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
432 | "Received message with type %u and size %u from `%s'\n", | 559 | "Received message with type %u and size %u from `%s'\n", |
433 | ntohs(message->type), | 560 | ntohs(message->type), |
434 | ntohs(message->size), | 561 | ntohs(message->size), |
435 | GNUNET_i2s(&(cs->identity))); | 562 | GNUNET_i2s(&(con->session->identity))); |
436 | cs->plugin->env->receive (cs->plugin->env->cls, | 563 | con->session->plugin->env->receive (con->session->plugin->env->cls, |
437 | &cs->identity, | 564 | &con->session->identity, |
438 | message, 1, cs, | 565 | message, 1, con->session, |
439 | cs->addr_out, | 566 | NULL, |
440 | cs->addr_out_len); | 567 | 0); |
441 | } | 568 | } |
442 | 569 | ||
443 | /** | 570 | /** |
@@ -463,7 +590,7 @@ acceptPolicyCallback (void *cls, | |||
463 | */ | 590 | */ |
464 | static int | 591 | static int |
465 | accessHandlerCallback (void *cls, | 592 | accessHandlerCallback (void *cls, |
466 | struct MHD_Connection *session, | 593 | struct MHD_Connection *mhd_connection, |
467 | const char *url, | 594 | const char *url, |
468 | const char *method, | 595 | const char *method, |
469 | const char *version, | 596 | const char *version, |
@@ -473,6 +600,7 @@ accessHandlerCallback (void *cls, | |||
473 | struct Plugin *plugin = cls; | 600 | struct Plugin *plugin = cls; |
474 | struct MHD_Response *response; | 601 | struct MHD_Response *response; |
475 | struct Session * cs; | 602 | struct Session * cs; |
603 | struct HTTP_Connection_in * con; | ||
476 | const union MHD_ConnectionInfo * conn_info; | 604 | const union MHD_ConnectionInfo * conn_info; |
477 | struct sockaddr_in *addrin; | 605 | struct sockaddr_in *addrin; |
478 | struct sockaddr_in6 *addrin6; | 606 | struct sockaddr_in6 *addrin6; |
@@ -485,7 +613,7 @@ accessHandlerCallback (void *cls, | |||
485 | 613 | ||
486 | GNUNET_assert(cls !=NULL); | 614 | GNUNET_assert(cls !=NULL); |
487 | send_error_to_client = GNUNET_NO; | 615 | send_error_to_client = GNUNET_NO; |
488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"accessHandlerCallback, upload_data_size: %u\n", *upload_data_size); | 616 | |
489 | if ( NULL == *httpSessionCache) | 617 | if ( NULL == *httpSessionCache) |
490 | { | 618 | { |
491 | /* check url for peer identity , if invalid send HTTP 404*/ | 619 | /* check url for peer identity , if invalid send HTTP 404*/ |
@@ -493,7 +621,7 @@ accessHandlerCallback (void *cls, | |||
493 | if ( GNUNET_SYSERR == res ) | 621 | if ( GNUNET_SYSERR == res ) |
494 | { | 622 | { |
495 | response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); | 623 | response = MHD_create_response_from_data (strlen (HTTP_ERROR_RESPONSE),HTTP_ERROR_RESPONSE, MHD_NO, MHD_NO); |
496 | res = MHD_queue_response (session, MHD_HTTP_NOT_FOUND, response); | 624 | res = MHD_queue_response (mhd_connection, MHD_HTTP_NOT_FOUND, response); |
497 | MHD_destroy_response (response); | 625 | MHD_destroy_response (response); |
498 | if (res == MHD_YES) | 626 | if (res == MHD_YES) |
499 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Peer has no valid ident, sent HTTP 1.1/404\n"); | 627 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Peer has no valid ident, sent HTTP 1.1/404\n"); |
@@ -502,7 +630,10 @@ accessHandlerCallback (void *cls, | |||
502 | return res; | 630 | return res; |
503 | } | 631 | } |
504 | 632 | ||
505 | conn_info = MHD_get_connection_info(session, MHD_CONNECTION_INFO_CLIENT_ADDRESS ); | 633 | /* get session for peer identity */ |
634 | cs = session_get (plugin ,&pi_in); | ||
635 | |||
636 | conn_info = MHD_get_connection_info(mhd_connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS ); | ||
506 | /* Incoming IPv4 connection */ | 637 | /* Incoming IPv4 connection */ |
507 | if ( AF_INET == conn_info->client_addr->sin_family) | 638 | if ( AF_INET == conn_info->client_addr->sin_family) |
508 | { | 639 | { |
@@ -510,6 +641,7 @@ accessHandlerCallback (void *cls, | |||
510 | inet_ntop(addrin->sin_family, &(addrin->sin_addr),address,INET_ADDRSTRLEN); | 641 | inet_ntop(addrin->sin_family, &(addrin->sin_addr),address,INET_ADDRSTRLEN); |
511 | memcpy(&ipv4addr.ipv4_addr,&(addrin->sin_addr),sizeof(struct in_addr)); | 642 | memcpy(&ipv4addr.ipv4_addr,&(addrin->sin_addr),sizeof(struct in_addr)); |
512 | ipv4addr.u_port = addrin->sin_port; | 643 | ipv4addr.u_port = addrin->sin_port; |
644 | con = session_check_inbound_address (plugin, cs, (const void *) &ipv4addr, sizeof (struct IPv4HttpAddress)); | ||
513 | } | 645 | } |
514 | /* Incoming IPv6 connection */ | 646 | /* Incoming IPv6 connection */ |
515 | if ( AF_INET6 == conn_info->client_addr->sin_family) | 647 | if ( AF_INET6 == conn_info->client_addr->sin_family) |
@@ -518,147 +650,62 @@ accessHandlerCallback (void *cls, | |||
518 | inet_ntop(addrin6->sin6_family, &(addrin6->sin6_addr),address,INET6_ADDRSTRLEN); | 650 | inet_ntop(addrin6->sin6_family, &(addrin6->sin6_addr),address,INET6_ADDRSTRLEN); |
519 | memcpy(&ipv6addr.ipv6_addr,&(addrin6->sin6_addr),sizeof(struct in_addr)); | 651 | memcpy(&ipv6addr.ipv6_addr,&(addrin6->sin6_addr),sizeof(struct in_addr)); |
520 | ipv6addr.u6_port = addrin6->sin6_port; | 652 | ipv6addr.u6_port = addrin6->sin6_port; |
653 | con = session_check_inbound_address (plugin, cs, &ipv6addr, sizeof (struct IPv6HttpAddress)); | ||
521 | } | 654 | } |
522 | /* get session for peer identity */ | ||
523 | cs = session_get (plugin ,&pi_in); | ||
524 | |||
525 | |||
526 | |||
527 | /* no existing session, create a new one*/ | ||
528 | if (cs == NULL ) | ||
529 | { | ||
530 | /* create new session object */ | ||
531 | if ( AF_INET6 == conn_info->client_addr->sin_family) | ||
532 | cs = create_session(plugin, (char *) &ipv6addr, sizeof(struct IPv6HttpAddress),NULL, 0, &pi_in); | ||
533 | if ( AF_INET == conn_info->client_addr->sin_family) | ||
534 | cs = create_session(plugin, (char *) &ipv4addr, sizeof(struct IPv4HttpAddress),NULL, 0, &pi_in); | ||
535 | |||
536 | /* Insert session into hashmap */ | ||
537 | GNUNET_CONTAINER_multihashmap_put ( plugin->sessions, | ||
538 | &cs->identity.hashPubKey, | ||
539 | cs, | ||
540 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
541 | |||
542 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"New Session for peer `%s' inserted\n", GNUNET_i2s(&cs->identity)); | ||
543 | } | ||
544 | |||
545 | /* Set closure and update current session*/ | 655 | /* Set closure and update current session*/ |
546 | if (*httpSessionCache == NULL) | ||
547 | { | ||
548 | *httpSessionCache = cs; | ||
549 | /* Updating session */ | ||
550 | /* | ||
551 | memcpy(cs->addr_inbound,conn_info->client_addr, sizeof(struct sockaddr_in)); | ||
552 | if ( AF_INET == cs->addr_inbound->sin_family) | ||
553 | { | ||
554 | GNUNET_asprintf(&cs->addr_inbound_str,"%s:%u",address,ntohs(cs->addr_inbound->sin_port)); | ||
555 | } | ||
556 | 656 | ||
557 | if ( AF_INET6 == cs->addr_inbound->sin_family) | 657 | *httpSessionCache = con; |
558 | { | 658 | if (con->msgtok==NULL) |
559 | GNUNET_asprintf(&cs->addr_inbound_str,"[%s]:%u",address,ntohs(cs->addr_inbound->sin_port)); | 659 | con->msgtok = GNUNET_SERVER_mst_create (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, &messageTokenizerCallback, con); |
560 | 660 | ||
561 | } | 661 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"HTTP Daemon has new an incoming `%s' request from peer `%s'@`%s'\n",method, GNUNET_i2s(&cs->identity),address); |
562 | */ | ||
563 | if (cs->msgtok==NULL) | ||
564 | cs->msgtok = GNUNET_SERVER_mst_create (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, &messageTokenizerCallback, cs); | ||
565 | } | ||
566 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"HTTP Daemon has new an incoming `%s' request from peer `%s'\n",method, GNUNET_i2s(&cs->identity)); | ||
567 | } | 662 | } |
568 | else | 663 | else |
569 | { | 664 | { |
570 | cs = *httpSessionCache; | 665 | con = *httpSessionCache; |
666 | cs = con->session; | ||
571 | } | 667 | } |
668 | |||
572 | /* Is it a PUT or a GET request */ | 669 | /* Is it a PUT or a GET request */ |
573 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) | 670 | if (0 == strcmp (MHD_HTTP_METHOD_PUT, method)) |
574 | { | 671 | { |
575 | /* New */ | 672 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"PUT, Upload size: %u addrlen %u\n", *upload_data_size, con->addrlen); |
576 | if ((*upload_data_size == 0) && (cs->is_put_in_progress == GNUNET_NO)) | 673 | if ((*upload_data_size == 0) && (con->is_put_in_progress==GNUNET_NO)) |
577 | { | 674 | { |
578 | if (cs->pending_inbound_msg.bytes_recv !=0 ) | 675 | con->is_put_in_progress = GNUNET_YES; |
579 | { | ||
580 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
581 | _("Incoming message from peer `%s', while existing message with %u bytes was not forwarded to transport'\n"), | ||
582 | GNUNET_i2s(&cs->identity), cs->pending_inbound_msg.bytes_recv); | ||
583 | cs->pending_inbound_msg.bytes_recv = 0; | ||
584 | } | ||
585 | /* not yet ready */ | ||
586 | cs->is_put_in_progress = GNUNET_YES; | ||
587 | cs->is_bad_request = GNUNET_NO; | ||
588 | return MHD_YES; | 676 | return MHD_YES; |
589 | } | 677 | } |
590 | 678 | ||
591 | if ((*upload_data_size > 0) && (cs->is_bad_request != GNUNET_YES)) | 679 | /* Transmission of all data complete */ |
680 | if ((*upload_data_size == 0) && (con->is_put_in_progress == GNUNET_YES)) | ||
592 | { | 681 | { |
593 | if (*upload_data_size + cs->pending_inbound_msg.bytes_recv < GNUNET_SERVER_MAX_MESSAGE_SIZE) | 682 | response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); |
594 | { | 683 | res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); |
595 | /* copy uploaded data to buffer */ | 684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sent HTTP/1.1: 200 OK as PUT Response\n",HTTP_PUT_RESPONSE, strlen (HTTP_PUT_RESPONSE), res ); |
596 | 685 | MHD_destroy_response (response); | |
597 | res = GNUNET_SERVER_mst_receive(cs->msgtok, cs, upload_data,*upload_data_size, GNUNET_YES, GNUNET_NO); | ||
598 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"%u bytes forwarded to MST: result: %u\n",*upload_data_size, res); | ||
599 | cs->pending_inbound_msg.bytes_recv += *upload_data_size; | ||
600 | *upload_data_size = 0; | ||
601 | return MHD_YES; | ||
602 | } | ||
603 | else | ||
604 | { | ||
605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"%u bytes not added to message of %u bytes, message to big\n",*upload_data_size, cs->pending_inbound_msg.bytes_recv); | ||
606 | cs->is_bad_request = GNUNET_YES; | ||
607 | /* (*upload_data_size) bytes not processed */ | ||
608 | return MHD_YES; | 686 | return MHD_YES; |
609 | } | ||
610 | } | ||
611 | 687 | ||
612 | if ((cs->is_put_in_progress == GNUNET_YES) && (cs->is_bad_request == GNUNET_YES)) | 688 | con->is_put_in_progress = GNUNET_NO; |
613 | { | 689 | con->is_bad_request = GNUNET_NO; |
614 | *upload_data_size = 0; | 690 | return res; |
615 | response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); | ||
616 | res = MHD_queue_response (session, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, response); | ||
617 | if (res == MHD_YES) | ||
618 | { | ||
619 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sent HTTP/1.1: 413 Request Entity Too Large as PUT Response\n"); | ||
620 | cs->is_bad_request = GNUNET_NO; | ||
621 | cs->is_put_in_progress =GNUNET_NO; | ||
622 | cs->pending_inbound_msg.bytes_recv = 0; | ||
623 | } | ||
624 | MHD_destroy_response (response); | ||
625 | return MHD_YES; | ||
626 | } | 691 | } |
627 | 692 | ||
628 | /* Transmission of all data complete */ | 693 | /* Transmission of all data complete */ |
629 | if ((*upload_data_size == 0) && (cs->is_put_in_progress == GNUNET_YES) && (cs->is_bad_request == GNUNET_NO)) | 694 | if ((*upload_data_size > 0) && (con->is_put_in_progress == GNUNET_YES)) |
630 | { | 695 | { |
631 | send_error_to_client = GNUNET_YES; | 696 | res = GNUNET_SERVER_mst_receive(con->msgtok, cs, upload_data,*upload_data_size, GNUNET_YES, GNUNET_NO); |
632 | if (cs->pending_inbound_msg.bytes_recv >= sizeof (struct GNUNET_MessageHeader)) | 697 | (*upload_data_size) = 0; |
633 | send_error_to_client = GNUNET_NO; | 698 | return MHD_YES; |
634 | |||
635 | if (send_error_to_client == GNUNET_NO) | ||
636 | { | ||
637 | //response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); | ||
638 | //res = MHD_queue_response (session, MHD_HTTP_OK, response); | ||
639 | //GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sent HTTP/1.1: 200 OK as PUT Response\n",HTTP_PUT_RESPONSE, strlen (HTTP_PUT_RESPONSE), res ); | ||
640 | //MHD_destroy_response (response); | ||
641 | return MHD_YES; | ||
642 | } | ||
643 | else | ||
644 | { | ||
645 | response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); | ||
646 | res = MHD_queue_response (session, MHD_HTTP_BAD_REQUEST, response); | ||
647 | MHD_destroy_response (response); | ||
648 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Sent HTTP/1.1: 400 BAD REQUEST as PUT Response\n"); | ||
649 | } | ||
650 | cs->is_put_in_progress = GNUNET_NO; | ||
651 | cs->is_bad_request = GNUNET_NO; | ||
652 | cs->pending_inbound_msg.bytes_recv = 0; | ||
653 | return res; | ||
654 | } | 699 | } |
700 | else | ||
701 | return MHD_NO; | ||
655 | } | 702 | } |
656 | if ( 0 == strcmp (MHD_HTTP_METHOD_GET, method) ) | 703 | if ( 0 == strcmp (MHD_HTTP_METHOD_GET, method) ) |
657 | { | 704 | { |
658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Got GET Request\n"); | 705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Got GET Request\n"); |
659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"URL: `%s'\n",url); | 706 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"URL: `%s'\n",url); |
660 | response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); | 707 | response = MHD_create_response_from_data (strlen (HTTP_PUT_RESPONSE),HTTP_PUT_RESPONSE, MHD_NO, MHD_NO); |
661 | res = MHD_queue_response (session, MHD_HTTP_OK, response); | 708 | res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); |
662 | MHD_destroy_response (response); | 709 | MHD_destroy_response (response); |
663 | return res; | 710 | return res; |
664 | } | 711 | } |
@@ -798,7 +845,7 @@ static void http_server_daemon_v6_run (void *cls, | |||
798 | * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success | 845 | * @return GNUNET_SYSERR if msg not found, GNUNET_OK on success |
799 | */ | 846 | */ |
800 | 847 | ||
801 | static int remove_http_message(struct HTTP_Connection * con, struct HTTP_Message * msg) | 848 | static int remove_http_message(struct HTTP_Connection_out * con, struct HTTP_Message * msg) |
802 | { | 849 | { |
803 | GNUNET_CONTAINER_DLL_remove(con->pending_msgs_head,con->pending_msgs_tail,msg); | 850 | GNUNET_CONTAINER_DLL_remove(con->pending_msgs_head,con->pending_msgs_tail,msg); |
804 | GNUNET_free(msg); | 851 | GNUNET_free(msg); |
@@ -844,26 +891,13 @@ static size_t header_function( void *ptr, size_t size, size_t nmemb, void *strea | |||
844 | */ | 891 | */ |
845 | static size_t send_read_callback(void *stream, size_t size, size_t nmemb, void *ptr) | 892 | static size_t send_read_callback(void *stream, size_t size, size_t nmemb, void *ptr) |
846 | { | 893 | { |
847 | struct HTTP_Connection * con = ptr; | 894 | struct HTTP_Connection_out * con = ptr; |
848 | struct HTTP_Message * msg = con->pending_msgs_tail; | 895 | struct HTTP_Message * msg = con->pending_msgs_tail; |
849 | size_t bytes_sent; | 896 | size_t bytes_sent; |
850 | size_t len; | 897 | size_t len; |
851 | 898 | ||
852 | msg = con->pending_msgs_head; | ||
853 | unsigned int c = 0; | ||
854 | while (msg != NULL) | ||
855 | { | ||
856 | c++; | ||
857 | msg = msg->next; | ||
858 | } | ||
859 | if (con->pending_msgs_tail != NULL) | ||
860 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"readcallback: msg of %u bytes, %u msgs in queue\n", con->pending_msgs_tail->size,c); | ||
861 | else | ||
862 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"readcallback: %u msgs in queue\n", c); | ||
863 | |||
864 | if (con->pending_msgs_tail == NULL) | 899 | if (con->pending_msgs_tail == NULL) |
865 | { | 900 | { |
866 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"no msgs in queue, pausing \n"); | ||
867 | con->send_paused = GNUNET_YES; | 901 | con->send_paused = GNUNET_YES; |
868 | return CURL_READFUNC_PAUSE; | 902 | return CURL_READFUNC_PAUSE; |
869 | } | 903 | } |
@@ -902,8 +936,6 @@ static size_t send_read_callback(void *stream, size_t size, size_t nmemb, void * | |||
902 | msg->transmit_cont (con->pending_msgs_tail->transmit_cont_cls,&(con->session)->identity,GNUNET_OK); | 936 | msg->transmit_cont (con->pending_msgs_tail->transmit_cont_cls,&(con->session)->identity,GNUNET_OK); |
903 | remove_http_message(con, msg); | 937 | remove_http_message(con, msg); |
904 | } | 938 | } |
905 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"readcallback: sent %u bytes \n", bytes_sent); | ||
906 | |||
907 | return bytes_sent; | 939 | return bytes_sent; |
908 | } | 940 | } |
909 | 941 | ||
@@ -944,7 +976,7 @@ static size_t send_schedule(void *cls, struct Session* ses ); | |||
944 | * @param ses session to send data to | 976 | * @param ses session to send data to |
945 | * @return bytes sent to peer | 977 | * @return bytes sent to peer |
946 | */ | 978 | */ |
947 | static ssize_t send_initiate (void *cls, struct Session* ses , struct HTTP_Connection *con) | 979 | static ssize_t send_initiate (void *cls, struct Session* ses , struct HTTP_Connection_out *con) |
948 | { | 980 | { |
949 | struct Plugin *plugin = cls; | 981 | struct Plugin *plugin = cls; |
950 | int bytes_sent = 0; | 982 | int bytes_sent = 0; |
@@ -1015,7 +1047,7 @@ static void send_execute (void *cls, | |||
1015 | int running; | 1047 | int running; |
1016 | struct CURLMsg *msg; | 1048 | struct CURLMsg *msg; |
1017 | CURLMcode mret; | 1049 | CURLMcode mret; |
1018 | struct HTTP_Connection * con = NULL; | 1050 | struct HTTP_Connection_out * con = NULL; |
1019 | struct Session * cs = NULL; | 1051 | struct Session * cs = NULL; |
1020 | long http_result; | 1052 | long http_result; |
1021 | 1053 | ||
@@ -1169,81 +1201,6 @@ static size_t send_schedule(void *cls, struct Session* ses ) | |||
1169 | } | 1201 | } |
1170 | 1202 | ||
1171 | 1203 | ||
1172 | static char * create_url(void * cls, const void * addr, size_t addrlen) | ||
1173 | { | ||
1174 | struct Plugin *plugin = cls; | ||
1175 | char *address; | ||
1176 | char *url = NULL; | ||
1177 | |||
1178 | GNUNET_assert ((addr!=NULL) && (addrlen != 0)); | ||
1179 | if (addrlen == (sizeof (struct IPv4HttpAddress))) | ||
1180 | { | ||
1181 | address = GNUNET_malloc(INET_ADDRSTRLEN + 1); | ||
1182 | inet_ntop(AF_INET, &((struct IPv4HttpAddress *) addr)->ipv4_addr,address,INET_ADDRSTRLEN); | ||
1183 | GNUNET_asprintf (&url, | ||
1184 | "http://%s:%u/%s", | ||
1185 | address, | ||
1186 | ntohs(((struct IPv4HttpAddress *) addr)->u_port), | ||
1187 | (char *) (&plugin->my_ascii_hash_ident)); | ||
1188 | GNUNET_free(address); | ||
1189 | } | ||
1190 | else if (addrlen == (sizeof (struct IPv6HttpAddress))) | ||
1191 | { | ||
1192 | address = GNUNET_malloc(INET6_ADDRSTRLEN + 1); | ||
1193 | inet_ntop(AF_INET6, &((struct IPv6HttpAddress *) addr)->ipv6_addr,address,INET6_ADDRSTRLEN); | ||
1194 | GNUNET_asprintf(&url, | ||
1195 | "http://%s:%u/%s", | ||
1196 | address, | ||
1197 | ntohs(((struct IPv6HttpAddress *) addr)->u6_port), | ||
1198 | (char *) (&plugin->my_ascii_hash_ident)); | ||
1199 | GNUNET_free(address); | ||
1200 | } | ||
1201 | return url; | ||
1202 | } | ||
1203 | |||
1204 | /** | ||
1205 | * Check if session already knows this address for a outbound connection to this peer | ||
1206 | * If address not in session, add it to the session | ||
1207 | * @param cls the plugin used | ||
1208 | * @param p the session | ||
1209 | * @param addr address | ||
1210 | * @param addr_len address length | ||
1211 | * @return GNUNET_NO if address not known, GNUNET_YES if known | ||
1212 | */ | ||
1213 | static struct HTTP_Connection * session_check_address (void * cls, struct Session *cs, const void * addr, size_t addr_len) | ||
1214 | { | ||
1215 | struct Plugin *plugin = cls; | ||
1216 | struct HTTP_Connection * cc = cs->outbound_connections_head; | ||
1217 | struct HTTP_Connection * con = NULL; | ||
1218 | |||
1219 | GNUNET_assert((addr_len == sizeof (struct IPv4HttpAddress)) || (addr_len == sizeof (struct IPv6HttpAddress))); | ||
1220 | |||
1221 | while (cc!=NULL) | ||
1222 | { | ||
1223 | if (addr_len == cc->addrlen) | ||
1224 | { | ||
1225 | if (0 == memcmp(cc->addr, addr, addr_len)) | ||
1226 | { | ||
1227 | con = cc; | ||
1228 | break; | ||
1229 | } | ||
1230 | } | ||
1231 | cc=cc->next; | ||
1232 | } | ||
1233 | if (con==NULL) | ||
1234 | { | ||
1235 | con = GNUNET_malloc(sizeof(struct HTTP_Connection) + addr_len); | ||
1236 | con->addrlen = addr_len; | ||
1237 | con->addr=&con[1]; | ||
1238 | con->url=create_url(plugin, addr, addr_len); | ||
1239 | con->connected = GNUNET_NO; | ||
1240 | con->session = cs; | ||
1241 | memcpy(con->addr, addr, addr_len); | ||
1242 | GNUNET_CONTAINER_DLL_insert(cs->outbound_connections_head,cs->outbound_connections_tail,con); | ||
1243 | } | ||
1244 | return con; | ||
1245 | } | ||
1246 | |||
1247 | /** | 1204 | /** |
1248 | * Function that can be used by the transport service to transmit | 1205 | * Function that can be used by the transport service to transmit |
1249 | * a message using the plugin. | 1206 | * a message using the plugin. |
@@ -1289,7 +1246,7 @@ http_plugin_send (void *cls, | |||
1289 | char *url; | 1246 | char *url; |
1290 | struct Session *cs; | 1247 | struct Session *cs; |
1291 | struct HTTP_Message *msg; | 1248 | struct HTTP_Message *msg; |
1292 | struct HTTP_Connection *con; | 1249 | struct HTTP_Connection_out *con; |
1293 | //unsigned int ret; | 1250 | //unsigned int ret; |
1294 | 1251 | ||
1295 | GNUNET_assert(cls !=NULL); | 1252 | GNUNET_assert(cls !=NULL); |
@@ -1298,7 +1255,7 @@ http_plugin_send (void *cls, | |||
1298 | 1255 | ||
1299 | /* get session from hashmap */ | 1256 | /* get session from hashmap */ |
1300 | cs = session_get(plugin, target); | 1257 | cs = session_get(plugin, target); |
1301 | con = session_check_address(plugin, cs, addr, addrlen); | 1258 | con = session_check_outbound_address(plugin, cs, addr, addrlen); |
1302 | 1259 | ||
1303 | /* create msg */ | 1260 | /* create msg */ |
1304 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); | 1261 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); |
@@ -1425,7 +1382,7 @@ http_plugin_address_pretty_printer (void *cls, | |||
1425 | */ | 1382 | */ |
1426 | static int | 1383 | static int |
1427 | http_plugin_address_suggested (void *cls, | 1384 | http_plugin_address_suggested (void *cls, |
1428 | void *addr, size_t addrlen) | 1385 | const void *addr, size_t addrlen) |
1429 | { | 1386 | { |
1430 | struct Plugin *plugin = cls; | 1387 | struct Plugin *plugin = cls; |
1431 | struct IPv4HttpAddress *v4; | 1388 | struct IPv4HttpAddress *v4; |
@@ -1464,8 +1421,6 @@ http_plugin_address_suggested (void *cls, | |||
1464 | return GNUNET_SYSERR; | 1421 | return GNUNET_SYSERR; |
1465 | } | 1422 | } |
1466 | } | 1423 | } |
1467 | |||
1468 | |||
1469 | return GNUNET_OK; | 1424 | return GNUNET_OK; |
1470 | } | 1425 | } |
1471 | 1426 | ||
@@ -1592,8 +1547,8 @@ process_interfaces (void *cls, | |||
1592 | int hashMapFreeIterator (void *cls, const GNUNET_HashCode *key, void *value) | 1547 | int hashMapFreeIterator (void *cls, const GNUNET_HashCode *key, void *value) |
1593 | { | 1548 | { |
1594 | struct Session * cs = value; | 1549 | struct Session * cs = value; |
1595 | struct HTTP_Connection * con = cs->outbound_connections_head; | 1550 | struct HTTP_Connection_out * con = cs->outbound_connections_head; |
1596 | struct HTTP_Connection * tmp_con = cs->outbound_connections_head; | 1551 | struct HTTP_Connection_out * tmp_con = cs->outbound_connections_head; |
1597 | struct HTTP_Message * msg = NULL; | 1552 | struct HTTP_Message * msg = NULL; |
1598 | struct HTTP_Message * tmp_msg = NULL; | 1553 | struct HTTP_Message * tmp_msg = NULL; |
1599 | 1554 | ||
@@ -1602,13 +1557,10 @@ int hashMapFreeIterator (void *cls, const GNUNET_HashCode *key, void *value) | |||
1602 | /* freeing connections */ | 1557 | /* freeing connections */ |
1603 | while (con!=NULL) | 1558 | while (con!=NULL) |
1604 | { | 1559 | { |
1605 | |||
1606 | |||
1607 | GNUNET_free(con->url); | 1560 | GNUNET_free(con->url); |
1608 | if (con->curl_handle!=NULL) | 1561 | if (con->curl_handle!=NULL) |
1609 | curl_easy_cleanup(con->curl_handle); | 1562 | curl_easy_cleanup(con->curl_handle); |
1610 | con->curl_handle = NULL; | 1563 | con->curl_handle = NULL; |
1611 | |||
1612 | msg = con->pending_msgs_head; | 1564 | msg = con->pending_msgs_head; |
1613 | while (msg!=NULL) | 1565 | while (msg!=NULL) |
1614 | { | 1566 | { |
@@ -1618,13 +1570,10 @@ int hashMapFreeIterator (void *cls, const GNUNET_HashCode *key, void *value) | |||
1618 | } | 1570 | } |
1619 | tmp_con=con->next; | 1571 | tmp_con=con->next; |
1620 | GNUNET_free(con); | 1572 | GNUNET_free(con); |
1621 | con=tmp_con->next; | 1573 | con=tmp_con; |
1622 | } | 1574 | } |
1623 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"All sessions freed \n"); | 1575 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"All sessions freed \n"); |
1624 | 1576 | ||
1625 | GNUNET_SERVER_mst_destroy (cs->msgtok); | ||
1626 | GNUNET_free_non_null (cs->addr_in); | ||
1627 | GNUNET_free_non_null (cs->addr_out); | ||
1628 | GNUNET_free (cs); | 1577 | GNUNET_free (cs); |
1629 | return GNUNET_YES; | 1578 | return GNUNET_YES; |
1630 | } | 1579 | } |