aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-06 19:39:49 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-06 19:39:49 +0000
commit6b14c5b2afa1654e30c61bead981e343f544c23b (patch)
treef1893a812e6af5660feefbd45117c68849a91dd7 /src/transport
parentf2ee6482821a0948e2ceb1d73758dc269eab9a6c (diff)
downloadgnunet-6b14c5b2afa1654e30c61bead981e343f544c23b.tar.gz
gnunet-6b14c5b2afa1654e30c61bead981e343f544c23b.zip
transmit PONGs
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport-new.c14
-rw-r--r--src/transport/gnunet-service-transport.h5
-rw-r--r--src/transport/gnunet-service-transport_validation.c321
-rw-r--r--src/transport/gnunet-service-transport_validation.h3
4 files changed, 324 insertions, 19 deletions
diff --git a/src/transport/gnunet-service-transport-new.c b/src/transport/gnunet-service-transport-new.c
index afbf328a5..061cdd9a3 100644
--- a/src/transport/gnunet-service-transport-new.c
+++ b/src/transport/gnunet-service-transport-new.c
@@ -66,7 +66,7 @@ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
66/** 66/**
67 * Our private key. 67 * Our private key.
68 */ 68 */
69static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; 69struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
70 70
71 71
72/** 72/**
@@ -140,10 +140,10 @@ shutdown_task (void *cls,
140 GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO); 140 GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
141 GST_stats = NULL; 141 GST_stats = NULL;
142 } 142 }
143 if (my_private_key != NULL) 143 if (GST_my_private_key != NULL)
144 { 144 {
145 GNUNET_CRYPTO_rsa_key_free (my_private_key); 145 GNUNET_CRYPTO_rsa_key_free (GST_my_private_key);
146 my_private_key = NULL; 146 GST_my_private_key = NULL;
147 } 147 }
148} 148}
149 149
@@ -180,9 +180,9 @@ run (void *cls,
180 GNUNET_SCHEDULER_shutdown (); 180 GNUNET_SCHEDULER_shutdown ();
181 return; 181 return;
182 } 182 }
183 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); 183 GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
184 GNUNET_free (keyfile); 184 GNUNET_free (keyfile);
185 if (my_private_key == NULL) 185 if (GST_my_private_key == NULL)
186 { 186 {
187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
188 _("Transport service could not access hostkey. Exiting.\n")); 188 _("Transport service could not access hostkey. Exiting.\n"));
@@ -191,7 +191,7 @@ run (void *cls,
191 } 191 }
192 GST_stats = GNUNET_STATISTICS_create ("transport", c); 192 GST_stats = GNUNET_STATISTICS_create ("transport", c);
193 GST_peerinfo = GNUNET_PEERINFO_connect (c); 193 GST_peerinfo = GNUNET_PEERINFO_connect (c);
194 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &GST_my_public_key); 194 GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
195 GNUNET_CRYPTO_hash (&GST_my_public_key, 195 GNUNET_CRYPTO_hash (&GST_my_public_key,
196 sizeof (GST_my_public_key), &GST_my_identity.hashPubKey); 196 sizeof (GST_my_public_key), &GST_my_identity.hashPubKey);
197 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 197 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h
index d6eda464a..38bd8b85a 100644
--- a/src/transport/gnunet-service-transport.h
+++ b/src/transport/gnunet-service-transport.h
@@ -55,5 +55,10 @@ extern struct GNUNET_PEERINFO_Handle *GST_peerinfo;
55 */ 55 */
56extern struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key; 56extern struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
57 57
58/**
59 * Our private key.
60 */
61extern struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
62
58#endif 63#endif
59/* end of file gnunet-service-transport_plugins.h */ 64/* end of file gnunet-service-transport_plugins.h */
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 9583fc1a7..d0331c192 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -29,6 +29,7 @@
29#include "gnunet-service-transport.h" 29#include "gnunet-service-transport.h"
30#include "gnunet_hello_lib.h" 30#include "gnunet_hello_lib.h"
31#include "gnunet_peerinfo_service.h" 31#include "gnunet_peerinfo_service.h"
32#include "gnunet_signatures.h"
32 33
33 34
34/** 35/**
@@ -81,6 +82,12 @@
81#define PING_PRIORITY 1 82#define PING_PRIORITY 1
82 83
83/** 84/**
85 * Priority to use for PINGs and PONGs
86 */
87#define PONG_PRIORITY 1
88
89
90/**
84 * Message used to ask a peer to validate receipt (to check an address 91 * Message used to ask a peer to validate receipt (to check an address
85 * from a HELLO). Followed by the address we are trying to validate, 92 * from a HELLO). Followed by the address we are trying to validate,
86 * or an empty address if we are just sending a PING to confirm that a 93 * or an empty address if we are just sending a PING to confirm that a
@@ -475,10 +482,54 @@ find_validation_entry (struct GNUNET_PeerIdentity *neighbour,
475 482
476 483
477/** 484/**
485 * Send the given PONG to the given address.
486 *
487 * @param cls the PONG message
488 * @param target peer this change is about, never NULL
489 * @param valid_until is ZERO if we never validated the address,
490 * otherwise a time up to when we consider it (or was) valid
491 * @param validation_block is FOREVER if the address is for an unsupported plugin (from PEERINFO)
492 * is ZERO if the address is considered valid (no validation needed)
493 * otherwise a time in the future if we're currently denying re-validation
494 * @param plugin_name name of the plugin
495 * @param plugin_address binary address
496 * @param plugin_address_len length of address
497 */
498static void
499multicast_pong (void *cls,
500 const struct GNUNET_PeerIdentity *target,
501 struct GNUNET_TIME_Absolute valid_until,
502 struct GNUNET_TIME_Absolute validation_block,
503 const char *plugin_name,
504 const void *plugin_address,
505 size_t plugin_address_len)
506{
507 struct TransportPongMessage *pong = cls;
508 struct GNUNET_TRANSPORT_PluginFunctions *papi;
509
510 papi = GST_plugins_find (plugin_name);
511 if (papi == NULL)
512 return;
513 (void) papi->send (papi->cls,
514 target,
515 (const char*) pong,
516 ntohs (pong->header.size),
517 PONG_PRIORITY,
518 HELLO_VERIFICATION_TIMEOUT,
519 NULL,
520 plugin_address,
521 plugin_address_len,
522 GNUNET_YES,
523 NULL, NULL);
524}
525
526
527/**
478 * We've received a PING. If appropriate, generate a PONG. 528 * We've received a PING. If appropriate, generate a PONG.
479 * 529 *
480 * @param sender peer sending the PING 530 * @param sender peer sending the PING
481 * @param hdr the PING 531 * @param hdr the PING
532 * @param session session we got the PING from
482 * @param plugin_name name of plugin that received the PING 533 * @param plugin_name name of plugin that received the PING
483 * @param sender_address address of the sender as known to the plugin, NULL 534 * @param sender_address address of the sender as known to the plugin, NULL
484 * if we did not initiate the connection 535 * if we did not initiate the connection
@@ -488,9 +539,253 @@ void
488GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, 539GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
489 const struct GNUNET_MessageHeader *hdr, 540 const struct GNUNET_MessageHeader *hdr,
490 const char *plugin_name, 541 const char *plugin_name,
542 struct Session *session,
491 const void *sender_address, 543 const void *sender_address,
492 size_t sender_address_len) 544 size_t sender_address_len)
493{ 545{
546
547 const struct TransportPingMessage *ping;
548 struct TransportPongMessage *pong;
549 struct GNUNET_TRANSPORT_PluginFunctions *papi;
550 const char *addr;
551 const char *addrend;
552 size_t alen;
553 size_t slen;
554 ssize_t ret;
555
556 if (ntohs (hdr->size) < sizeof (struct TransportPingMessage))
557 {
558 GNUNET_break_op (0);
559 return;
560 }
561 ping = (const struct TransportPingMessage *) hdr;
562 if (0 != memcmp (&ping->target,
563 &GST_my_identity,
564 sizeof (struct GNUNET_PeerIdentity)))
565 {
566#if DEBUG_TRANSPORT
567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
568 _("Received `%s' message from `%s' destined for `%s' which is not me!\n"),
569 "PING",
570 (sender_address != NULL)
571 ? GST_plugin_a2s (plugin_name,
572 sender_address,
573 sender_address_len)
574 : "<inbound>",
575 GNUNET_i2s (&ping->target));
576#endif
577 return;
578 }
579#if DEBUG_TRANSPORT
580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
581 "Processing `%s' from `%s'\n",
582 "PING",
583 (sender_address != NULL)
584 ? GST_plugin_a2s (plugin_name,
585 sender_address,
586 sender_address_len)
587 : "<inbound>");
588#endif
589 GNUNET_STATISTICS_update (GST_stats,
590 gettext_noop ("# PING messages received"),
591 1,
592 GNUNET_NO);
593 addr = (const char*) &ping[1];
594 alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage);
595 if (alen == 0)
596 {
597 /* peer wants to confirm that we have an outbound connection to him */
598 if (sender_address == NULL)
599 {
600 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
601 _("Refusing to create PONG since I do initiate the session with `%s'.\n"),
602 GNUNET_i2s (sender));
603 return;
604 }
605#if DEBUG_TRANSPORT
606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
607 "Creating PONG indicating that we initiated a connection to peer `%s' using address `%s' \n",
608 GNUNET_i2s (peer),
609 GST_plugin_a2s (plugin_name,
610 sender_address,
611 sender_address_len));
612#endif
613 slen = strlen (plugin_name) + 1;
614 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len + slen);
615 pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len + slen);
616 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
617 pong->purpose.size =
618 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
619 sizeof (uint32_t) +
620 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
621 sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen);
622 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING);
623 pong->challenge = ping->challenge;
624 pong->addrlen = htonl(sender_address_len + slen);
625 pong->pid = *sender;
626 memcpy (&pong[1],
627 plugin_name,
628 slen);
629 memcpy (&((char*)&pong[1])[slen],
630 sender_address,
631 sender_address_len);
632#if 0
633 /* FIXME: lookup signature! */
634 if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).rel_value <
635 PONG_SIGNATURE_LIFETIME.rel_value / 4)
636 {
637 /* create / update cached sig */
638#if DEBUG_TRANSPORT
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
640 "Creating PONG signature to indicate active connection.\n");
641#endif
642 session_header->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME);
643 pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires);
644 GNUNET_assert (GNUNET_OK ==
645 GNUNET_CRYPTO_rsa_sign (my_private_key,
646 &pong->purpose,
647 &session_header->pong_signature));
648 }
649 else
650 {
651 pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires);
652 }
653 memcpy (&pong->signature,
654 &session_header->pong_signature,
655 sizeof (struct GNUNET_CRYPTO_RsaSignature));
656#else
657 pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
658 GNUNET_assert (GNUNET_OK ==
659 GNUNET_CRYPTO_rsa_sign (GST_my_private_key,
660 &pong->purpose,
661 &pong->signature));
662#endif
663 }
664 else
665 {
666 /* peer wants to confirm that this is one of our addresses */
667 addrend = memchr (addr, '\0', alen);
668 if (NULL == addrend)
669 {
670 GNUNET_break_op (0);
671 return;
672 }
673 addrend++;
674 slen = strlen(addr);
675 alen -= slen;
676 papi = GST_plugins_find (addr);
677
678 if ( (NULL == papi) ||
679 (GNUNET_OK !=
680 papi->check_address (papi->cls,
681 addrend,
682 alen)) )
683 {
684 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
685 _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
686 GST_plugins_a2s (addr,
687 addrend,
688 alen));
689 return;
690 }
691
692 pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
693 pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen);
694 pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
695 pong->purpose.size =
696 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
697 sizeof (uint32_t) +
698 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
699 sizeof (struct GNUNET_PeerIdentity) + alen + slen);
700 pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
701 pong->challenge = ping->challenge;
702 pong->addrlen = htonl(alen + slen);
703 pong->pid = GST_my_identity;
704 memcpy (&pong[1], addr, slen);
705 memcpy (&((char*)&pong[1])[slen], addrend, alen);
706#if 0
707 if ( (oal != NULL) &&
708 (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) )
709 {
710 /* create / update cached sig */
711#if DEBUG_TRANSPORT
712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
713 "Creating PONG signature to indicate ownership.\n");
714#endif
715 oal->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME);
716 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
717 GNUNET_assert (GNUNET_OK ==
718 GNUNET_CRYPTO_rsa_sign (my_private_key,
719 &pong->purpose,
720 &oal->pong_signature));
721 memcpy (&pong->signature,
722 &oal->pong_signature,
723 sizeof (struct GNUNET_CRYPTO_RsaSignature));
724 }
725 else if (oal == NULL)
726 {
727#else
728 /* not using cache (typically DV-only) */
729 pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
730 GNUNET_assert (GNUNET_OK ==
731 GNUNET_CRYPTO_rsa_sign (GST_my_private_key,
732 &pong->purpose,
733 &pong->signature));
734#endif
735#if 0
736 }
737 else
738 {
739 /* can used cached version */
740 pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
741 memcpy (&pong->signature,
742 &oal->pong_signature,
743 sizeof (struct GNUNET_CRYPTO_RsaSignature));
744 }
745#endif
746 }
747
748 /* first see if the session we got this PING from can be used to transmit
749 a response reliably */
750 papi = GST_plugins_find (plugin_name);
751 if (papi == NULL)
752 ret = -1;
753 else
754 ret = papi->send (papi->cls,
755 sender,
756 (const char*) pong,
757 ntohs (pong->header.size),
758 PONG_PRIORITY,
759 HELLO_VERIFICATION_TIMEOUT,
760 session,
761 sender_address,
762 sender_address_len,
763 GNUNET_SYSERR,
764 NULL, NULL);
765 if (ret != -1)
766 {
767 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
768 "Transmitted PONG to `%s' via reliable mechanism\n",
769 GNUNET_i2s (sender));
770 /* done! */
771 GNUNET_STATISTICS_update (GST_stats,
772 gettext_noop ("# PONGs unicast via reliable transport"),
773 1,
774 GNUNET_NO);
775 GNUNET_free (pong);
776 return;
777 }
778
779 /* no reliable method found, try transmission via all known addresses */
780 GNUNET_STATISTICS_update (GST_stats,
781 gettext_noop ("# PONGs multicast to all available addresses"),
782 1,
783 GNUNET_NO);
784 (void) GST_validation_get_addresses (sender,
785 GNUNET_YES,
786 &multicast_pong,
787 pong);
788 GNUNET_free (pong);
494} 789}
495 790
496 791
@@ -571,17 +866,20 @@ validate_address (void *cls,
571 ve->addr, 866 ve->addr,
572 ve->addrlen); 867 ve->addrlen);
573 papi = GST_plugins_find (ve->transport_name); 868 papi = GST_plugins_find (ve->transport_name);
574 ret = papi->send (papi->cls, 869 if (papi == NULL)
575 pid, 870 ret = -1;
576 message_buf, 871 else
577 tsize, 872 ret = papi->send (papi->cls,
578 PING_PRIORITY, 873 pid,
579 HELLO_VERIFICATION_TIMEOUT, 874 message_buf,
580 NULL /* no session */, 875 tsize,
581 ve->addr, 876 PING_PRIORITY,
582 ve->addrlen, 877 HELLO_VERIFICATION_TIMEOUT,
583 GNUNET_YES, 878 NULL /* no session */,
584 NULL, NULL); 879 ve->addr,
880 ve->addrlen,
881 GNUNET_YES,
882 NULL, NULL);
585 } 883 }
586 if (-1 != ret) 884 if (-1 != ret)
587 { 885 {
@@ -595,7 +893,6 @@ validate_address (void *cls,
595} 893}
596 894
597 895
598
599/** 896/**
600 * We've received a HELLO, check which addresses are new and trigger 897 * We've received a HELLO, check which addresses are new and trigger
601 * validation. 898 * validation.
diff --git a/src/transport/gnunet-service-transport_validation.h b/src/transport/gnunet-service-transport_validation.h
index 218b45457..27d30d83a 100644
--- a/src/transport/gnunet-service-transport_validation.h
+++ b/src/transport/gnunet-service-transport_validation.h
@@ -27,6 +27,7 @@
27#define GNUNET_SERVICE_TRANSPORT_VALIDATION_H 27#define GNUNET_SERVICE_TRANSPORT_VALIDATION_H
28 28
29#include "gnunet_statistics_service.h" 29#include "gnunet_statistics_service.h"
30#include "gnunet_transport_plugin.h"
30#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
31 32
32 33
@@ -50,6 +51,7 @@ GST_validation_stop (void);
50 * @param sender peer sending the PING 51 * @param sender peer sending the PING
51 * @param hdr the PING 52 * @param hdr the PING
52 * @param plugin_name name of plugin that received the PING 53 * @param plugin_name name of plugin that received the PING
54 * @param session session we got the PING from
53 * @param sender_address address of the sender as known to the plugin, NULL 55 * @param sender_address address of the sender as known to the plugin, NULL
54 * if we did not initiate the connection 56 * if we did not initiate the connection
55 * @param sender_address_len number of bytes in sender_address 57 * @param sender_address_len number of bytes in sender_address
@@ -58,6 +60,7 @@ void
58GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, 60GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
59 const struct GNUNET_MessageHeader *hdr, 61 const struct GNUNET_MessageHeader *hdr,
60 const char *plugin_name, 62 const char *plugin_name,
63 struct Session *session,
61 const void *sender_address, 64 const void *sender_address,
62 size_t sender_address_len); 65 size_t sender_address_len);
63 66