diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-26 11:01:28 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-26 11:01:28 +0000 |
commit | 1d47d5af1a4b114cf3e56b7f4e174cb5878ba30d (patch) | |
tree | 1cd906c5996f35f72d8c28fa6a62920db06e9e65 /src/transport/plugin_transport_http.c | |
parent | 9d6a89fda9f5a24032087e6030006e55bc7091ce (diff) | |
download | gnunet-1d47d5af1a4b114cf3e56b7f4e174cb5878ba30d.tar.gz gnunet-1d47d5af1a4b114cf3e56b7f4e174cb5878ba30d.zip |
- new get_session functions
Diffstat (limited to 'src/transport/plugin_transport_http.c')
-rw-r--r-- | src/transport/plugin_transport_http.c | 231 |
1 files changed, 224 insertions, 7 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index 684612617..ecf32c943 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -386,7 +386,7 @@ http_plugin_address_to_string (void *cls, const void *addr, size_t addrlen) | |||
386 | } | 386 | } |
387 | 387 | ||
388 | struct Session * | 388 | struct Session * |
389 | lookup_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | 389 | lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, |
390 | struct Session *session, const void *addr, size_t addrlen, | 390 | struct Session *session, const void *addr, size_t addrlen, |
391 | int force_address) | 391 | int force_address) |
392 | { | 392 | { |
@@ -462,6 +462,29 @@ lookup_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | |||
462 | return s; | 462 | return s; |
463 | } | 463 | } |
464 | 464 | ||
465 | struct Session * | ||
466 | lookup_session (struct Plugin *plugin, | ||
467 | const struct GNUNET_HELLO_Address *address) | ||
468 | { | ||
469 | struct Session *tmp = NULL; | ||
470 | |||
471 | tmp = plugin->head; | ||
472 | if (tmp == NULL) | ||
473 | return NULL; | ||
474 | while (tmp != NULL) | ||
475 | { | ||
476 | if (0 != memcmp (&address->peer, &tmp->target, sizeof (struct GNUNET_PeerIdentity))) | ||
477 | continue; | ||
478 | if ((address->address_length != tmp->addrlen) && | ||
479 | (0 != memcmp (address->address, tmp->addr, tmp->addrlen))) | ||
480 | continue; | ||
481 | |||
482 | return tmp; | ||
483 | } | ||
484 | return NULL; | ||
485 | } | ||
486 | |||
487 | |||
465 | void | 488 | void |
466 | delete_session (struct Session *s) | 489 | delete_session (struct Session *s) |
467 | { | 490 | { |
@@ -508,6 +531,198 @@ notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
508 | delete_session (s); | 531 | delete_session (s); |
509 | } | 532 | } |
510 | 533 | ||
534 | /** | ||
535 | * Creates a new session the transport service will use to send data to the | ||
536 | * peer | ||
537 | * | ||
538 | * @param cls the plugin | ||
539 | * @param address the address | ||
540 | * @return the session or NULL of max connections exceeded | ||
541 | */ | ||
542 | |||
543 | static const struct Session * | ||
544 | http_get_session (void *cls, | ||
545 | const struct GNUNET_HELLO_Address *address) | ||
546 | { | ||
547 | struct Plugin *plugin = cls; | ||
548 | struct Session * s = NULL; | ||
549 | struct GNUNET_ATS_Information ats; | ||
550 | size_t addrlen; | ||
551 | |||
552 | GNUNET_assert (plugin != NULL); | ||
553 | GNUNET_assert (address != NULL); | ||
554 | |||
555 | /* find existing session */ | ||
556 | s = lookup_session (plugin, address); | ||
557 | if (s != NULL) | ||
558 | return s; | ||
559 | |||
560 | if (plugin->max_connections <= plugin->cur_connections) | ||
561 | { | ||
562 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, | ||
563 | "Maximum number of connections reached, " | ||
564 | "cannot connect to peer `%s'\n", GNUNET_i2s (&address->peer)); | ||
565 | return NULL; | ||
566 | } | ||
567 | |||
568 | /* create new session */ | ||
569 | addrlen = address->address_length; | ||
570 | |||
571 | GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || | ||
572 | (addrlen == sizeof (struct IPv4HttpAddress))); | ||
573 | |||
574 | s = GNUNET_malloc (sizeof (struct Session)); | ||
575 | memcpy (&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); | ||
576 | s->plugin = plugin; | ||
577 | s->addr = GNUNET_malloc (address->address_length); | ||
578 | memcpy (s->addr, address->address, address->address_length); | ||
579 | s->addrlen = addrlen; | ||
580 | s->next = NULL; | ||
581 | s->next_receive = GNUNET_TIME_absolute_get_zero (); | ||
582 | |||
583 | s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); | ||
584 | |||
585 | /* Get ATS type */ | ||
586 | if ((addrlen == sizeof (struct IPv4HttpAddress)) && (address->address != NULL)) | ||
587 | { | ||
588 | struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) address->address; | ||
589 | struct sockaddr_in s4; | ||
590 | |||
591 | s4.sin_family = AF_INET; | ||
592 | s4.sin_addr.s_addr = a4->ipv4_addr; | ||
593 | s4.sin_port = a4->u4_port; | ||
594 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
595 | s4.sin_len = sizeof (struct sockaddr_in); | ||
596 | #endif | ||
597 | ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s4, sizeof (struct sockaddr_in)); | ||
598 | } | ||
599 | if ((addrlen == sizeof (struct IPv6HttpAddress)) && (address->address != NULL)) | ||
600 | { | ||
601 | struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) address->address; | ||
602 | struct sockaddr_in6 s6; | ||
603 | |||
604 | s6.sin6_family = AF_INET6; | ||
605 | s6.sin6_addr = a6->ipv6_addr; | ||
606 | s6.sin6_port = a6->u6_port; | ||
607 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
608 | s6.sin6_len = sizeof (struct sockaddr_in6); | ||
609 | #endif | ||
610 | ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) &s6, sizeof (struct sockaddr_in6)); | ||
611 | } | ||
612 | s->ats_address_network_type = ats.value; | ||
613 | |||
614 | /* add new session */ | ||
615 | GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); | ||
616 | /* initiate new connection */ | ||
617 | if (GNUNET_SYSERR == client_connect (s)) | ||
618 | { | ||
619 | if (s != NULL) | ||
620 | { | ||
621 | GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); | ||
622 | delete_session (s); | ||
623 | } | ||
624 | return NULL; | ||
625 | } | ||
626 | |||
627 | return s; | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * Function that can be used by the transport service to transmit | ||
632 | * a message using the plugin. Note that in the case of a | ||
633 | * peer disconnecting, the continuation MUST be called | ||
634 | * prior to the disconnect notification itself. This function | ||
635 | * will be called with this peer's HELLO message to initiate | ||
636 | * a fresh connection to another peer. | ||
637 | * | ||
638 | * @param cls closure | ||
639 | * @param session which session must be used | ||
640 | * @param msgbuf the message to transmit | ||
641 | * @param msgbuf_size number of bytes in 'msgbuf' | ||
642 | * @param priority how important is the message (most plugins will | ||
643 | * ignore message priority and just FIFO) | ||
644 | * @param to how long to wait at most for the transmission (does not | ||
645 | * require plugins to discard the message after the timeout, | ||
646 | * just advisory for the desired delay; most plugins will ignore | ||
647 | * this as well) | ||
648 | * @param cont continuation to call once the message has | ||
649 | * been transmitted (or if the transport is ready | ||
650 | * for the next transmission call; or if the | ||
651 | * peer disconnected...); can be NULL | ||
652 | * @param cont_cls closure for cont | ||
653 | * @return number of bytes used (on the physical network, with overheads); | ||
654 | * -1 on hard errors (i.e. address invalid); 0 is a legal value | ||
655 | * and does NOT mean that the message was not transmitted (DV) | ||
656 | */ | ||
657 | static ssize_t | ||
658 | http_plugin_send (void *cls, | ||
659 | struct Session *session, | ||
660 | const char *msgbuf, size_t msgbuf_size, | ||
661 | unsigned int priority, | ||
662 | struct GNUNET_TIME_Relative to, | ||
663 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) | ||
664 | { | ||
665 | struct Plugin *plugin = cls; | ||
666 | struct HTTP_Message *msg; | ||
667 | struct Session *tmp; | ||
668 | size_t res = -1; | ||
669 | |||
670 | GNUNET_assert (plugin != NULL); | ||
671 | GNUNET_assert (session != NULL); | ||
672 | |||
673 | /* lookup if session is really existing */ | ||
674 | tmp = plugin->head; | ||
675 | while (tmp != NULL) | ||
676 | { | ||
677 | if ((tmp == session) && | ||
678 | (0 == memcmp (&session->target, &tmp->target, sizeof (struct GNUNET_PeerIdentity))) && | ||
679 | (session->addrlen != tmp->addrlen) && | ||
680 | (0 != memcmp (session->addr, tmp->addr, tmp->addrlen))) | ||
681 | break; | ||
682 | tmp = tmp->next; | ||
683 | } | ||
684 | if (tmp == NULL) | ||
685 | { | ||
686 | GNUNET_break_op (0); | ||
687 | return res; | ||
688 | } | ||
689 | |||
690 | /* create new message and schedule */ | ||
691 | |||
692 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); | ||
693 | msg->next = NULL; | ||
694 | msg->size = msgbuf_size; | ||
695 | msg->pos = 0; | ||
696 | msg->buf = (char *) &msg[1]; | ||
697 | msg->transmit_cont = cont; | ||
698 | msg->transmit_cont_cls = cont_cls; | ||
699 | memcpy (msg->buf, msgbuf, msgbuf_size); | ||
700 | |||
701 | if (session->inbound == GNUNET_NO) | ||
702 | { | ||
703 | #if DEBUG_HTTP | ||
704 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
705 | "Using outbound client session %p to send to `%session'\n", session, | ||
706 | GNUNET_i2s (&session->target)); | ||
707 | #endif | ||
708 | |||
709 | client_send (session, msg); | ||
710 | res = msgbuf_size; | ||
711 | } | ||
712 | if (session->inbound == GNUNET_YES) | ||
713 | { | ||
714 | #if DEBUG_HTTP | ||
715 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
716 | "Using inbound server %p session to send to `%session'\n", session, | ||
717 | GNUNET_i2s (&session->target)); | ||
718 | #endif | ||
719 | |||
720 | server_send (session, msg); | ||
721 | res = msgbuf_size; | ||
722 | } | ||
723 | return res; | ||
724 | |||
725 | } | ||
511 | 726 | ||
512 | /** | 727 | /** |
513 | * Function that can be used by the transport service to transmit | 728 | * Function that can be used by the transport service to transmit |
@@ -546,7 +761,7 @@ notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
546 | * and does NOT mean that the message was not transmitted (DV) | 761 | * and does NOT mean that the message was not transmitted (DV) |
547 | */ | 762 | */ |
548 | static ssize_t | 763 | static ssize_t |
549 | http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | 764 | http_plugin_send_old (void *cls, const struct GNUNET_PeerIdentity *target, |
550 | const char *msgbuf, size_t msgbuf_size, unsigned int priority, | 765 | const char *msgbuf, size_t msgbuf_size, unsigned int priority, |
551 | struct GNUNET_TIME_Relative to, struct Session *session, | 766 | struct GNUNET_TIME_Relative to, struct Session *session, |
552 | const void *addr, size_t addrlen, int force_address, | 767 | const void *addr, size_t addrlen, int force_address, |
@@ -576,10 +791,8 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
576 | if (addrlen != 0) | 791 | if (addrlen != 0) |
577 | GNUNET_assert ((addrlen == sizeof (struct IPv4HttpAddress)) || | 792 | GNUNET_assert ((addrlen == sizeof (struct IPv4HttpAddress)) || |
578 | (addrlen == sizeof (struct IPv6HttpAddress))); | 793 | (addrlen == sizeof (struct IPv6HttpAddress))); |
579 | |||
580 | |||
581 | /* look for existing connection */ | 794 | /* look for existing connection */ |
582 | s = lookup_session (plugin, target, session, addr, addrlen, 1); | 795 | s = lookup_session_old (plugin, target, session, addr, addrlen, 1); |
583 | #if DEBUG_HTTP | 796 | #if DEBUG_HTTP |
584 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 797 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
585 | "%s existing session: %s\n", | 798 | "%s existing session: %s\n", |
@@ -588,7 +801,6 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
588 | GNUNET_YES)) ? | 801 | GNUNET_YES)) ? |
589 | "inbound" : "outbound"); | 802 | "inbound" : "outbound"); |
590 | #endif | 803 | #endif |
591 | |||
592 | /* create new outbound connection */ | 804 | /* create new outbound connection */ |
593 | if (s == NULL) | 805 | if (s == NULL) |
594 | { | 806 | { |
@@ -605,6 +817,7 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
605 | "Initiiating new connection to peer `%s'\n", | 817 | "Initiiating new connection to peer `%s'\n", |
606 | GNUNET_i2s (target)); | 818 | GNUNET_i2s (target)); |
607 | #endif | 819 | #endif |
820 | /* AAAAAAAAAAAAAAAAAAA */ | ||
608 | int res = GNUNET_OK; | 821 | int res = GNUNET_OK; |
609 | struct GNUNET_ATS_Information ats; | 822 | struct GNUNET_ATS_Information ats; |
610 | if ((addrlen == sizeof (struct IPv4HttpAddress)) && (addr != NULL)) | 823 | if ((addrlen == sizeof (struct IPv4HttpAddress)) && (addr != NULL)) |
@@ -658,6 +871,8 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
658 | } | 871 | } |
659 | } | 872 | } |
660 | 873 | ||
874 | /* real sending */ | ||
875 | |||
661 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); | 876 | msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); |
662 | msg->next = NULL; | 877 | msg->next = NULL; |
663 | msg->size = msgbuf_size; | 878 | msg->size = msgbuf_size; |
@@ -1380,11 +1595,13 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
1380 | plugin->env = env; | 1595 | plugin->env = env; |
1381 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1596 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
1382 | api->cls = plugin; | 1597 | api->cls = plugin; |
1383 | api->send = &http_plugin_send; | 1598 | api->send = &http_plugin_send_old; |
1384 | api->disconnect = &http_plugin_disconnect; | 1599 | api->disconnect = &http_plugin_disconnect; |
1385 | api->address_pretty_printer = &http_plugin_address_pretty_printer; | 1600 | api->address_pretty_printer = &http_plugin_address_pretty_printer; |
1386 | api->check_address = &http_plugin_address_suggested; | 1601 | api->check_address = &http_plugin_address_suggested; |
1387 | api->address_to_string = &http_plugin_address_to_string; | 1602 | api->address_to_string = &http_plugin_address_to_string; |
1603 | api->get_session = &http_get_session; | ||
1604 | api->send_with_session = &http_plugin_send; | ||
1388 | 1605 | ||
1389 | #if BUILD_HTTPS | 1606 | #if BUILD_HTTPS |
1390 | plugin->name = "transport-https"; | 1607 | plugin->name = "transport-https"; |