[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r11948 - in gnunet/src: include transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r11948 - in gnunet/src: include transport |
Date: |
Fri, 25 Jun 2010 14:57:38 +0200 |
Author: grothoff
Date: 2010-06-25 14:57:38 +0200 (Fri, 25 Jun 2010)
New Revision: 11948
Modified:
gnunet/src/include/gnunet_signatures.h
gnunet/src/transport/gnunet-service-transport.c
gnunet/src/transport/plugin_transport.h
gnunet/src/transport/plugin_transport_http.c
gnunet/src/transport/plugin_transport_tcp.c
gnunet/src/transport/test_transport_api.c
gnunet/src/transport/test_transport_api_tcp_peer1.conf
gnunet/src/transport/test_transport_api_tcp_peer2.conf
Log:
new transport address validation code -- see Mantis 1556
Modified: gnunet/src/include/gnunet_signatures.h
===================================================================
--- gnunet/src/include/gnunet_signatures.h 2010-06-25 12:21:37 UTC (rev
11947)
+++ gnunet/src/include/gnunet_signatures.h 2010-06-25 12:57:38 UTC (rev
11948)
@@ -43,53 +43,59 @@
#define GNUNET_SIGNATURE_PURPOSE_TEST 0
/**
- * Signature for confirming HELLOs for transport.
+ * Signature for confirming that this peer uses a particular address.
*/
-#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PING 1
+#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN 1
+/**
+ * Signature for confirming that this peer connected to another peer
+ * using a particular address.
+ */
+#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING 2
+
/**
* Purpose is to set a session key.
*/
-#define GNUNET_SIGNATURE_PURPOSE_SET_KEY 2
+#define GNUNET_SIGNATURE_PURPOSE_SET_KEY 3
/**
* Signature for a namespace/pseudonym advertisement (by
* the namespace owner).
*/
-#define GNUNET_SIGNATURE_PURPOSE_NAMESPACE_ADVERTISEMENT 3
+#define GNUNET_SIGNATURE_PURPOSE_NAMESPACE_ADVERTISEMENT 4
/**
* Signature by which a peer affirms that it is
* providing a certain bit of content (used
* in LOCation URIs).
*/
-#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT 4
+#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT 5
/**
* Signature in a KBlock of the FS module.
*/
-#define GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK 5
+#define GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK 6
/**
* Signature of content URI placed into a namespace.
*/
-#define GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK 6
+#define GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK 7
/**
* Signature of advertisment for a namespace.
*/
-#define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK 7
+#define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK 8
/**
* Keyword-based signature of advertisment for a namespace.
*/
-#define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG 8
+#define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG 9
/**
*
*/
-#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 9
+#define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 10
#if 0 /* keep Emacsens' auto-indent happy */
Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c 2010-06-25 12:21:37 UTC
(rev 11947)
+++ gnunet/src/transport/gnunet-service-transport.c 2010-06-25 12:57:38 UTC
(rev 11948)
@@ -103,6 +103,15 @@
#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 15)
/**
+ * How long is a PONG signature valid? We'll recycle a signature until
+ * 1/4 of this time is remaining. PONGs should expire so that if our
+ * external addresses change an adversary cannot replay them indefinitely.
+ * OTOH, we don't want to spend too much time generating PONG signatures,
+ * so they must have some lifetime to reduce our CPU usage.
+ */
+#define PONG_SIGNATURE_LIFETIME GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_HOURS, 1)
+
+/**
* Priority to use for PONG messages.
*/
#define TRANSPORT_PONG_PRIORITY 4
@@ -241,7 +250,8 @@
/**
- * Entry in linked list of network addresses for ourselves.
+ * Entry in linked list of network addresses for ourselves. Also
+ * includes a cached signature for 'struct TransportPongMessage's.
*/
struct OwnAddressList
{
@@ -251,21 +261,26 @@
struct OwnAddressList *next;
/**
- * The address, actually a pointer to the end
- * of this struct. Do not free!
- */
- const void *addr;
-
- /**
- * How long until we auto-expire this address (unless it is
+ * How long until we actually auto-expire this address (unless it is
* re-confirmed by the transport)?
*/
struct GNUNET_TIME_Absolute expires;
/**
+ * How long until the current signature expires? (ZERO if the
+ * signature was never created).
+ */
+ struct GNUNET_TIME_Absolute pong_sig_expires;
+
+ /**
+ * Signature for a 'struct TransportPongMessage' for this address.
+ */
+ struct GNUNET_CRYPTO_RsaSignature pong_signature;
+
+ /**
* Length of addr.
*/
- uint16_t addrlen;
+ uint32_t addrlen;
};
@@ -553,7 +568,9 @@
/**
* Message used to ask a peer to validate receipt (to check an address
- * from a HELLO).
+ * from a HELLO). Followed by the address we are trying to validate,
+ * or an empty address if we are just sending a PING to confirm that a
+ * connection which the receiver (of the PING) initiated is still valid.
*/
struct TransportPingMessage
{
@@ -564,7 +581,7 @@
struct GNUNET_MessageHeader header;
/**
- * Random challenge number (in network byte order).
+ * Challenge code (to ensure fresh reply).
*/
uint32_t challenge GNUNET_PACKED;
@@ -579,14 +596,12 @@
/**
* Message used to validate a HELLO. The challenge is included in the
* confirmation to make matching of replies to requests possible. The
- * signature signs the original challenge number, our public key, the
- * sender's address (so that the sender can check that the address we
- * saw is plausible for him and possibly detect a MiM attack) and a
- * timestamp (to limit replay).<p>
+ * signature signs our public key, an expiration time and our address.<p>
*
- * This message is followed by the address of the
- * client that we are observing (which is part of what
- * is being signed).
+ * This message is followed by our transport address that the PING tried
+ * to confirm (if we liked it). The address can be empty (zero bytes)
+ * if the PING had not address either (and we received the request via
+ * a connection that we initiated).
*/
struct TransportPongMessage
{
@@ -597,9 +612,10 @@
struct GNUNET_MessageHeader header;
/**
- * For padding, always zero.
+ * Challenge code from PING (showing freshness). Not part of what
+ * is signed so that we can re-use signatures.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t challenge GNUNET_PACKED;
/**
* Signature.
@@ -607,24 +623,31 @@
struct GNUNET_CRYPTO_RsaSignature signature;
/**
- * What are we signing and why?
+ * What are we signing and why? Two possible reason codes can be here:
+ * GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN to confirm that this is a
+ * plausible address for this peer (pid is set to identity of signer); or
+ * GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING to confirm that this is
+ * an address we used to connect to the peer with the given pid.
*/
struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
/**
- * Random challenge number (in network byte order).
+ * When does this signature expire?
*/
- uint32_t challenge GNUNET_PACKED;
+ struct GNUNET_TIME_AbsoluteNBO expiration;
/**
- * Who signed this message?
+ * Either the identity of the peer Who signed this message, or the
+ * identity of the peer that we're connected to using the given
+ * address (depending on purpose.type).
*/
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded signer;
+ struct GNUNET_PeerIdentity pid;
/**
- * Size of address appended to this message
+ * Size of address appended to this message (part of what is
+ * being signed, hence not redundant).
*/
- uint16_t addrlen;
+ uint32_t addrlen;
};
@@ -877,7 +900,6 @@
*/
static struct GNUNET_STATISTICS_Handle *stats;
-
/**
* The peer specified by the given neighbour has timed-out or a plugin
* has disconnected. We may either need to do nothing (other plugins
@@ -1526,9 +1548,11 @@
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Best address found (`%s') has latency of %llu ms.\n",
- a2s (best_address->ready_list->plugin->short_name,
+ (best_address->addrlen > 0)
+ ? a2s (best_address->ready_list->plugin->short_name,
best_address->addr,
- best_address->addrlen),
+ best_address->addrlen)
+ : "<inbound>",
best_address->latency.value);
#endif
}
@@ -1800,7 +1824,7 @@
}
ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name,
gc->expiration,
- gc->addr_pos->addr,
+ &gc->addr_pos[1],
gc->addr_pos->addrlen, buf, max);
gc->addr_pos = gc->addr_pos->next;
return ret;
@@ -2097,7 +2121,6 @@
}
al = GNUNET_malloc (sizeof (struct OwnAddressList) + addrlen);
- al->addr = &al[1];
al->next = p->addresses;
p->addresses = al;
al->expires = abex;
@@ -3076,6 +3099,7 @@
struct CheckAddressExistsClosure caec;
char * message_buf;
uint16_t hello_size;
+ size_t slen;
size_t tsize;
peer_address->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
@@ -3143,18 +3167,39 @@
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
hello_size = GNUNET_HELLO_size(our_hello);
tsize = sizeof(struct TransportPingMessage) + hello_size;
+ if (peer_address->addr != NULL)
+ {
+ slen = strlen (tp->short_name) + 1;
+ tsize += slen + peer_address->addrlen;
+ }
message_buf = GNUNET_malloc(tsize);
+ ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
ping.challenge = htonl(va->challenge);
- ping.header.size = htons(sizeof(struct TransportPingMessage));
- ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity));
memcpy(message_buf, our_hello, hello_size);
+ if (peer_address->addr != NULL)
+ {
+ ping.header.size = htons(sizeof(struct TransportPingMessage) +
+ peer_address->addrlen +
+ slen);
+ memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage)],
+ tp->short_name,
+ slen);
+ memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage) +
slen],
+ peer_address->addr,
+ peer_address->addrlen);
+ }
+ else
+ {
+ ping.header.size = htons(sizeof(struct TransportPingMessage));
+ }
memcpy(&message_buf[hello_size],
&ping,
sizeof(struct TransportPingMessage));
+
#if DEBUG_TRANSPORT_REVALIDATION
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Performing re-validation of address `%s' via `%s' for peer
`%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n",
+ "Performing re-validation of address `%s' via `%s' for peer
`%4s' sending `%s' (%u bytes) and `%s'\n",
(peer_address->addr != NULL)
? a2s (peer_address->plugin->short_name,
peer_address->addr,
@@ -3163,7 +3208,7 @@
tp->short_name,
GNUNET_i2s (&neighbour->id),
"HELLO", hello_size,
- "PING", sizeof (struct TransportPingMessage));
+ "PING");
#endif
GNUNET_STATISTICS_update (stats,
gettext_noop ("# PING messages sent for
re-validation"),
@@ -3321,34 +3366,133 @@
struct GNUNET_PeerIdentity target;
struct NeighbourList *n;
struct ForeignAddressList *fal;
+ struct OwnAddressList *oal;
+ struct TransportPlugin *tp;
struct GNUNET_MessageHeader *prem;
+ uint16_t ps;
+ const char *addr;
+ size_t slen;
+ size_t alen;
- if (ve->challenge != challenge)
- return GNUNET_YES;
-
-#if SIGN_USELESS
- if (GNUNET_OK !=
- GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PING,
- &pong->purpose,
- &pong->signature,
- &ve->publicKey))
+ ps = ntohs (pong->header.size);
+ if (ps < sizeof (struct TransportPongMessage))
{
GNUNET_break_op (0);
- return GNUNET_YES;
+ return GNUNET_NO;
}
+ addr = (const char*) &pong[1];
+ slen = strlen (ve->transport_name) + 1;
+ if ( (ps - sizeof (struct TransportPongMessage) != ve->addrlen + slen) ||
+ (ve->challenge != challenge) ||
+ (addr[slen-1] != '\0') ||
+ (0 != strcmp (addr, ve->transport_name)) ||
+ (ntohl (pong->purpose.size)
+ != sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+ sizeof (uint32_t) +
+ sizeof (struct GNUNET_TIME_AbsoluteNBO) +
+ sizeof (struct GNUNET_PeerIdentity) + ve->addrlen + slen) )
+ return GNUNET_YES;
+ alen = ps - sizeof (struct TransportPongMessage) - slen;
+ switch (ntohl (pong->purpose.purpose))
+ {
+ case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN:
+ if ( (ve->addrlen + slen != ntohl (pong->addrlen)) ||
+ (0 != memcmp (&addr[slen],
+ ve->addr,
+ ve->addrlen)) )
+ return GNUNET_YES; /* different entry, keep trying! */
+ if ( (0 != memcmp (&pong->pid,
+ key,
+ sizeof (struct GNUNET_PeerIdentity))) ||
+ (ve->addrlen == 0) )
+ {
+ GNUNET_break_op (0);
+ return GNUNET_NO;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
+ &pong->purpose,
+ &pong->signature,
+ &ve->publicKey))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_NO;
+ }
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Confirmed validity of address, peer `%4s' has address `%s'
(%s).\n",
+ GNUNET_h2s (key),
+ a2s (ve->transport_name,
+ (const struct sockaddr *) ve->addr,
+ ve->addrlen),
+ ve->transport_name);
#endif
-
+ break;
+ case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING:
+ if (ve->addrlen != 0)
+ return GNUNET_YES; /* different entry, keep trying */
+ if ( (0 != memcmp (&pong->pid,
+ &my_identity,
+ sizeof (struct GNUNET_PeerIdentity))) ||
+ (ve->addrlen != 0) )
+ {
+ GNUNET_break_op (0);
+ return GNUNET_NO;
+ }
+ tp = find_transport (ve->transport_name);
+ if (tp == NULL)
+ {
+ GNUNET_break (0);
+ return GNUNET_YES;
+ }
+ oal = tp->addresses;
+ while (NULL != oal)
+ {
+ if ( (oal->addrlen == alen) &&
+ (0 == memcmp (&oal[1],
+ &addr[slen],
+ alen)) )
+ break;
+ oal = oal->next;
+ }
+ if (oal == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Not accepting PONG with address `%s' since I cannot
confirm having this address.\n"),
+ a2s (ve->transport_name,
+ &addr[slen],
+ alen));
+ return GNUNET_NO;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_rsa_verify
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING,
+ &pong->purpose,
+ &pong->signature,
+ &ve->publicKey))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_NO;
+ }
#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Confirmed validity of address, peer `%4s' has address `%s'
(%s).\n",
- GNUNET_h2s (key),
- (ve->addr != NULL)
- ? a2s (ve->transport_name,
- (const struct sockaddr *) ve->addr,
- ve->addrlen)
- : "<inbound>",
- ve->transport_name);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Confirmed that peer `%4s' is talking to us using address
`%s' (%s) for us.\n",
+ GNUNET_h2s (key),
+ a2s (ve->transport_name,
+ &addr[slen],
+ alen),
+ ve->transport_name);
#endif
+ break;
+ default:
+ GNUNET_break_op (0);
+ return GNUNET_NO;
+ }
+ if (GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh
(pong->expiration)).value == 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Received expired signature. Check system time.\n"));
+ return GNUNET_NO;
+ }
GNUNET_STATISTICS_update (stats,
gettext_noop ("# address validation successes"),
1,
@@ -3498,6 +3642,7 @@
size_t tsize;
char * message_buf;
struct GNUNET_PeerIdentity id;
+ size_t slen;
GNUNET_CRYPTO_hash (&va->publicKey,
sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
@@ -3532,25 +3677,34 @@
return;
}
hello_size = GNUNET_HELLO_size(our_hello);
- tsize = sizeof(struct TransportPingMessage) + hello_size;
+ slen = strlen(va->transport_name) + 1;
+ tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen +
slen;
message_buf = GNUNET_malloc(tsize);
ping.challenge = htonl(va->challenge);
- ping.header.size = htons(sizeof(struct TransportPingMessage));
+ ping.header.size = htons(sizeof(struct TransportPingMessage) + slen +
va->addrlen);
ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity));
memcpy(message_buf, our_hello, hello_size);
memcpy(&message_buf[hello_size],
&ping,
sizeof(struct TransportPingMessage));
+ memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage)],
+ va->transport_name,
+ slen);
+ memcpy(&message_buf[hello_size + sizeof (struct TransportPingMessage) +
slen],
+ &va[1],
+ va->addrlen);
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Performing validation of address `%s' via `%s' for peer `%4s'
sending `%s' (%u bytes) and `%s' (%u bytes)\n",
- a2s (va->transport_name,
- (const void*) &va[1], va->addrlen),
+ (va->addrlen == 0)
+ ? "<inbound>"
+ : a2s (va->transport_name,
+ (const void*) &va[1], va->addrlen),
va->transport_name,
GNUNET_i2s (&neighbour->id),
"HELLO", hello_size,
- "PING", sizeof (struct TransportPingMessage));
+ "PING", sizeof (struct TransportPingMessage) + va->addrlen +
slen);
#endif
GNUNET_STATISTICS_update (stats,
@@ -3618,7 +3772,7 @@
while (NULL != oal)
{
if ( (oal->addrlen == addrlen) &&
- (0 == memcmp (oal->addr,
+ (0 == memcmp (&oal[1],
addr,
addrlen)) )
{
@@ -4073,17 +4227,23 @@
static int
handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
const struct GNUNET_PeerIdentity *peer,
+ struct Session *session,
const char *sender_address,
uint16_t sender_address_len)
{
struct TransportPlugin *plugin = cls;
+ struct SessionHeader *session_header = (struct SessionHeader*) session;
struct TransportPingMessage *ping;
struct TransportPongMessage *pong;
struct NeighbourList *n;
struct ReadyList *rl;
struct ForeignAddressList *fal;
+ struct OwnAddressList *oal;
+ const char *addr;
+ size_t alen;
+ size_t slen;
- if (ntohs (message->size) != sizeof (struct TransportPingMessage))
+ if (ntohs (message->size) < sizeof (struct TransportPingMessage))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -4113,26 +4273,126 @@
gettext_noop ("# PING messages received"),
1,
GNUNET_NO);
- pong = GNUNET_malloc (sizeof (struct TransportPongMessage) +
sender_address_len);
- pong->header.size = htons (sizeof (struct TransportPongMessage) +
sender_address_len);
- pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
- pong->purpose.size =
- htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
- sizeof (uint32_t) +
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
sender_address_len);
- pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PING);
- pong->challenge = ping->challenge;
- pong->addrlen = htons(sender_address_len);
- memcpy(&pong->signer,
- &my_public_key,
- sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
- if (sender_address != NULL)
- memcpy (&pong[1], sender_address, sender_address_len);
-#if SIGN_USELESS
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_rsa_sign (my_private_key,
- &pong->purpose, &pong->signature));
+ addr = (const char*) &ping[1];
+ alen = ntohs (message->size) - sizeof (struct TransportPingMessage);
+ slen = strlen (plugin->short_name) + 1;
+ if (alen == 0)
+ {
+ /* peer wants to confirm that we have an outbound connection to him */
+ if (session == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Refusing to create PONG since I do not have a session
with `%s'.\n"),
+ GNUNET_i2s (peer));
+ return GNUNET_SYSERR;
+ }
+ pong = GNUNET_malloc (sizeof (struct TransportPongMessage) +
sender_address_len + slen);
+ pong->header.size = htons (sizeof (struct TransportPongMessage) +
sender_address_len + slen);
+ pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
+ pong->purpose.size =
+ htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+ sizeof (uint32_t) +
+ sizeof (struct GNUNET_TIME_AbsoluteNBO) +
+ sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen);
+ pong->purpose.purpose = htonl
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING);
+ pong->challenge = ping->challenge;
+ pong->addrlen = htonl(sender_address_len + slen);
+ memcpy(&pong->pid,
+ peer,
+ sizeof(struct GNUNET_PeerIdentity));
+ memcpy (&pong[1],
+ plugin->short_name,
+ slen);
+ memcpy (&((char*)&pong[1])[slen],
+ sender_address,
+ sender_address_len);
+ if (GNUNET_TIME_absolute_get_remaining
(session_header->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4)
+ {
+ /* create / update cached sig */
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating PONG signature to indicate active
connection.\n");
#endif
+ session_header->pong_sig_expires = GNUNET_TIME_relative_to_absolute
(PONG_SIGNATURE_LIFETIME);
+ pong->expiration = GNUNET_TIME_absolute_hton
(session_header->pong_sig_expires);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (my_private_key,
+ &pong->purpose,
+
&session_header->pong_signature));
+ }
+ else
+ {
+ pong->expiration = GNUNET_TIME_absolute_hton
(session_header->pong_sig_expires);
+ }
+ memcpy (&pong->signature,
+ &session_header->pong_signature,
+ sizeof (struct GNUNET_CRYPTO_RsaSignature));
+
+
+ }
+ else
+ {
+ /* peer wants to confirm that this is one of our addresses */
+ addr += slen;
+ alen -= slen;
+ oal = plugin->addresses;
+ while (NULL != oal)
+ {
+ if ( (oal->addrlen == alen) &&
+ (0 == memcmp (addr,
+ &oal[1],
+ alen)) )
+ break;
+ oal = oal->next;
+ }
+ if (oal == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Not confirming PING with address `%s' since I cannot
confirm having this address.\n"),
+ a2s (plugin->short_name,
+ addr,
+ alen));
+ return GNUNET_NO;
+ }
+ pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen +
slen);
+ pong->header.size = htons (sizeof (struct TransportPongMessage) + alen +
slen);
+ pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
+ pong->purpose.size =
+ htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+ sizeof (uint32_t) +
+ sizeof (struct GNUNET_TIME_AbsoluteNBO) +
+ sizeof (struct GNUNET_PeerIdentity) + alen + slen);
+ pong->purpose.purpose = htonl
(GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
+ pong->challenge = ping->challenge;
+ pong->addrlen = htonl(alen + slen);
+ memcpy(&pong->pid,
+ &my_identity,
+ sizeof(struct GNUNET_PeerIdentity));
+ memcpy (&pong[1], plugin->short_name, slen);
+ memcpy (&((char*)&pong[1])[slen], &oal[1], alen);
+ if (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value <
PONG_SIGNATURE_LIFETIME.value / 4)
+ {
+ /* create / update cached sig */
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating PONG signature to indicate ownership.\n");
+#endif
+ oal->pong_sig_expires = GNUNET_TIME_absolute_min (oal->expires,
+
GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
+ pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (my_private_key,
+ &pong->purpose,
+ &oal->pong_signature));
+ }
+ else
+ {
+ pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+ }
+ memcpy (&pong->signature,
+ &oal->pong_signature,
+ sizeof (struct GNUNET_CRYPTO_RsaSignature));
+ }
n = find_neighbour(peer);
GNUNET_assert (n != NULL);
/* first try reliable response transmission */
@@ -4304,7 +4564,7 @@
process_hello (plugin, message);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
- handle_ping (plugin, message, peer, sender_address,
sender_address_len);
+ handle_ping (plugin, message, peer, session, sender_address,
sender_address_len);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
handle_pong (plugin, message, peer, sender_address,
sender_address_len);
Modified: gnunet/src/transport/plugin_transport.h
===================================================================
--- gnunet/src/transport/plugin_transport.h 2010-06-25 12:21:37 UTC (rev
11947)
+++ gnunet/src/transport/plugin_transport.h 2010-06-25 12:57:38 UTC (rev
11948)
@@ -47,7 +47,25 @@
*/
struct Session;
+/**
+ * Every 'struct Session' must begin with this header.
+ */
+struct SessionHeader
+{
+ /**
+ * Cached signature for PONG generation for the session. Do not use
+ * in the plugin!
+ */
+ struct GNUNET_CRYPTO_RsaSignature pong_signature;
+
+ /**
+ * Expiration time for signature. Do not use in the plugin!
+ */
+ struct GNUNET_TIME_Absolute pong_sig_expires;
+
+};
+
/**
* Function that will be called whenever the plugin internally
* cleans up a session pointer and hence the service needs to
@@ -74,8 +92,14 @@
* @param message the message, NULL if we only care about
* learning about the delay until we should receive again --
FIXME!
* @param distance in overlay hops; use 1 unless DV (or 0 if message == NULL)
- * @param session identifier used for this session (can be NULL)
- * @param sender_address binary address of the sender (if observed)
+ * @param session identifier used for this session (NULL for plugins
+ * that do not offer bi-directional communication to the sender
+ * using the same "connection")
+ * @param sender_address binary address of the sender (if we established the
+ * connection or are otherwise sure of it; should be NULL
+ * for inbound TCP/UDP connections since it it not clear
+ * that we could establish ourselves a connection to that
+ * IP address and get the same system)
* @param sender_address_len number of bytes in sender_address
* @return how long the plugin should wait until receiving more data
* (plugins that do not support this, can ignore the return value)
Modified: gnunet/src/transport/plugin_transport_http.c
===================================================================
--- gnunet/src/transport/plugin_transport_http.c 2010-06-25 12:21:37 UTC
(rev 11947)
+++ gnunet/src/transport/plugin_transport_http.c 2010-06-25 12:57:38 UTC
(rev 11948)
@@ -187,6 +187,11 @@
{
/**
+ * API requirement.
+ */
+ struct SessionHeader header;
+
+ /**
* Stored in a linked list.
*/
struct Session *next;
@@ -346,7 +351,13 @@
* @param peer identity
* @return created session object
*/
-static struct Session * create_session (void * cls, char * addr_in, size_t
addrlen_in, char * addr_out, size_t addrlen_out, const struct
GNUNET_PeerIdentity *peer)
+static struct Session *
+create_session (void * cls,
+ char * addr_in,
+ size_t addrlen_in,
+ char * addr_out,
+ size_t addrlen_out,
+ const struct GNUNET_PeerIdentity *peer)
{
struct Plugin *plugin = cls;
struct Session * cs = GNUNET_malloc ( sizeof( struct Session) );
@@ -404,10 +415,11 @@
ntohs(message->type),
ntohs(message->size),
GNUNET_i2s(&(cs->identity)));
- cs->plugin->env->receive(cs->plugin->env->cls,
- &cs->identity,
- message, 1, NULL,
- NULL, 0);
+ cs->plugin->env->receive (cs->plugin->env->cls,
+ &cs->identity,
+ message, 1, cs,
+ cs->addr_out,
+ cs->addr_out_len);
}
/**
Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2010-06-25 12:21:37 UTC (rev
11947)
+++ gnunet/src/transport/plugin_transport_tcp.c 2010-06-25 12:57:38 UTC (rev
11948)
@@ -205,6 +205,11 @@
{
/**
+ * API requirement.
+ */
+ struct SessionHeader header;
+
+ /**
* Stored in a linked list.
*/
struct Session *next;
Modified: gnunet/src/transport/test_transport_api.c
===================================================================
--- gnunet/src/transport/test_transport_api.c 2010-06-25 12:21:37 UTC (rev
11947)
+++ gnunet/src/transport/test_transport_api.c 2010-06-25 12:57:38 UTC (rev
11948)
@@ -36,7 +36,7 @@
#include "gnunet_transport_service.h"
#include "transport.h"
-#define VERBOSE GNUNET_YES
+#define VERBOSE GNUNET_NO
#define VERBOSE_ARM GNUNET_NO
Modified: gnunet/src/transport/test_transport_api_tcp_peer1.conf
===================================================================
--- gnunet/src/transport/test_transport_api_tcp_peer1.conf 2010-06-25
12:21:37 UTC (rev 11947)
+++ gnunet/src/transport/test_transport_api_tcp_peer1.conf 2010-06-25
12:57:38 UTC (rev 11948)
@@ -32,7 +32,7 @@
[transport]
PLUGINS = tcp
-DEBUG = NO
+#DEBUG = YES
#PREFIX = xterm -T transport2 -e gdb --command=cmd --args
#PREFIX = valgrind --leak-check=full
ACCEPT_FROM6 = ::1;
Modified: gnunet/src/transport/test_transport_api_tcp_peer2.conf
===================================================================
--- gnunet/src/transport/test_transport_api_tcp_peer2.conf 2010-06-25
12:21:37 UTC (rev 11947)
+++ gnunet/src/transport/test_transport_api_tcp_peer2.conf 2010-06-25
12:57:38 UTC (rev 11948)
@@ -32,7 +32,6 @@
[transport]
PLUGINS = tcp
-DEBUG = NO
#DEBUG = YES
ACCEPT_FROM6 = ::1;
ACCEPT_FROM = 127.0.0.1;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r11948 - in gnunet/src: include transport,
gnunet <=