aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2010-06-28 13:22:04 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2010-06-28 13:22:04 +0000
commite20a9ae6460ba00b0e7994e16cdb063ea802a09a (patch)
treea66805f07edcef0e51223ebcfd15fb3382c671ba
parent046b26c62c7ebb678be1ffe5c2ea6450d7ae0722 (diff)
downloadgnunet-e20a9ae6460ba00b0e7994e16cdb063ea802a09a.tar.gz
gnunet-e20a9ae6460ba00b0e7994e16cdb063ea802a09a.zip
-rw-r--r--src/transport/plugin_transport_http.c487
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
107struct 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
159struct HTTP_Connection 152struct 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
175struct 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
413static 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 */
454static 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 */
499static 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 */
410static void requestCompletedCallback (void *cls, struct MHD_Connection * connection, void **httpSessionCache) 537static 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 */
464static int 591static int
465accessHandlerCallback (void *cls, 592accessHandlerCallback (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
801static int remove_http_message(struct HTTP_Connection * con, struct HTTP_Message * msg) 848static 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 */
845static size_t send_read_callback(void *stream, size_t size, size_t nmemb, void *ptr) 892static 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 */
947static ssize_t send_initiate (void *cls, struct Session* ses , struct HTTP_Connection *con) 979static 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
1172static 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 */
1213static 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 */
1426static int 1383static int
1427http_plugin_address_suggested (void *cls, 1384http_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,
1592int hashMapFreeIterator (void *cls, const GNUNET_HashCode *key, void *value) 1547int 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}