aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-01-26 11:01:28 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-01-26 11:01:28 +0000
commit1d47d5af1a4b114cf3e56b7f4e174cb5878ba30d (patch)
tree1cd906c5996f35f72d8c28fa6a62920db06e9e65 /src/transport/plugin_transport_http.c
parent9d6a89fda9f5a24032087e6030006e55bc7091ce (diff)
downloadgnunet-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.c231
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
388struct Session * 388struct Session *
389lookup_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, 389lookup_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
465struct Session *
466lookup_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
465void 488void
466delete_session (struct Session *s) 489delete_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
543static const struct Session *
544http_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 */
657static ssize_t
658http_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 */
548static ssize_t 763static ssize_t
549http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, 764http_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";