aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-07-12 22:11:16 +0000
committerChristian Grothoff <christian@grothoff.org>2009-07-12 22:11:16 +0000
commit434bd08c383c1128e4c95d84d8e546ced6dfb629 (patch)
treec07689baaa32aa123e3bcc5939c74bde1f2a9b06
parent0764da28f2a3003c208703245b2247432855fc90 (diff)
downloadgnunet-434bd08c383c1128e4c95d84d8e546ced6dfb629.tar.gz
gnunet-434bd08c383c1128e4c95d84d8e546ced6dfb629.zip
transport fixes, hello API extension
-rw-r--r--src/datastore/datastore_api.c5
-rw-r--r--src/hello/hello.c22
-rw-r--r--src/include/gnunet_hello_lib.h12
-rw-r--r--src/topology/gnunet-daemon-topology.c4
-rw-r--r--src/transport/gnunet-service-transport.c9
-rw-r--r--src/transport/plugin_transport_tcp.c157
-rw-r--r--src/transport/test_transport_api.c16
-rw-r--r--src/transport/transport_api.c9
8 files changed, 132 insertions, 102 deletions
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index a024d9e96..5e87affaf 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -29,6 +29,9 @@
29#include "datastore.h" 29#include "datastore.h"
30 30
31 31
32/**
33 *
34 */
32struct MessageQueue 35struct MessageQueue
33{ 36{
34 /** 37 /**
@@ -113,7 +116,7 @@ struct GNUNET_DATASTORE_Handle *GNUNET_DATASTORE_connect (struct
113 116
114 117
115/** 118/**
116 * Transmit DROP message to Database service. 119 * Transmit DROP message to datastore service.
117 */ 120 */
118static size_t 121static size_t
119transmit_drop (void *cls, 122transmit_drop (void *cls,
diff --git a/src/hello/hello.c b/src/hello/hello.c
index 79d0edf8d..a7aaf7d54 100644
--- a/src/hello/hello.c
+++ b/src/hello/hello.c
@@ -479,5 +479,27 @@ GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
479} 479}
480 480
481 481
482/**
483 * Get the peer identity from a HELLO message.
484 *
485 * @param hello the hello message
486 * @param peer where to store the peer's identity
487 * @return GNUNET_SYSERR if the HELLO was malformed
488 */
489int
490GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello,
491 struct GNUNET_PeerIdentity *peer)
492{
493 uint16_t ret = ntohs (hello->header.size);
494 if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
495 (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
496 return GNUNET_SYSERR;
497 GNUNET_CRYPTO_hash (&hello->publicKey,
498 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
499 &peer->hashPubKey);
500 return GNUNET_OK;
501}
502
503
482 504
483/* end of hello.c */ 505/* end of hello.c */
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index 2ba6df6ab..8978890f0 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -195,6 +195,18 @@ GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello,
195 *publicKey); 195 *publicKey);
196 196
197 197
198/**
199 * Get the peer identity from a HELLO message.
200 *
201 * @param hello the hello message
202 * @param peer where to store the peer's identity
203 * @return GNUNET_SYSERR if the HELLO was malformed
204 */
205int
206GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello,
207 struct GNUNET_PeerIdentity *peer);
208
209
198 210
199/* ifndef GNUNET_HELLO_LIB_H */ 211/* ifndef GNUNET_HELLO_LIB_H */
200#endif 212#endif
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index 20d541eb2..73fb84981 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -497,7 +497,6 @@ static void
497consider_for_advertising (const struct GNUNET_HELLO_Message *hello) 497consider_for_advertising (const struct GNUNET_HELLO_Message *hello)
498{ 498{
499 int have_address; 499 int have_address;
500 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
501 struct GNUNET_PeerIdentity pid; 500 struct GNUNET_PeerIdentity pid;
502 struct HelloList *pos; 501 struct HelloList *pos;
503 uint16_t size; 502 uint16_t size;
@@ -509,8 +508,7 @@ consider_for_advertising (const struct GNUNET_HELLO_Message *hello)
509 &have_address); 508 &have_address);
510 if (GNUNET_NO == have_address) 509 if (GNUNET_NO == have_address)
511 return; /* no point in advertising this one... */ 510 return; /* no point in advertising this one... */
512 GNUNET_HELLO_get_key (hello, &pkey); 511 GNUNET_HELLO_get_id (hello, &pid);
513 GNUNET_CRYPTO_hash (&pkey, sizeof (pkey), &pid.hashPubKey);
514 pos = hellos; 512 pos = hellos;
515 while (pos != NULL) 513 while (pos != NULL)
516 { 514 {
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index c34efec6c..d7bd13317 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -1649,6 +1649,7 @@ check_hello_validated (void *cls,
1649 struct ValidationAddress *va; 1649 struct ValidationAddress *va;
1650 struct TransportPlugin *tp; 1650 struct TransportPlugin *tp;
1651 int first_call; 1651 int first_call;
1652 struct GNUNET_PeerIdentity apeer;
1652 1653
1653 first_call = GNUNET_NO; 1654 first_call = GNUNET_NO;
1654 if (chvc->e == NULL) 1655 if (chvc->e == NULL)
@@ -1679,6 +1680,9 @@ check_hello_validated (void *cls,
1679 if (h != NULL) 1680 if (h != NULL)
1680 return; /* wait for next call */ 1681 return; /* wait for next call */
1681 /* finally, transmit validation attempts */ 1682 /* finally, transmit validation attempts */
1683 GNUNET_assert (GNUNET_OK ==
1684 GNUNET_HELLO_get_id (chvc->hello,
1685 &apeer));
1682 va = chvc->e->addresses; 1686 va = chvc->e->addresses;
1683 while (va != NULL) 1687 while (va != NULL)
1684 { 1688 {
@@ -1686,13 +1690,14 @@ check_hello_validated (void *cls,
1686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1687 "Establishing `%s' connection to validate `%s' of `%4s'\n", 1691 "Establishing `%s' connection to validate `%s' of `%4s'\n",
1688 va->transport_name, 1692 va->transport_name,
1689 "HELLO", GNUNET_i2s (peer)); 1693 "HELLO",
1694 GNUNET_i2s (&apeer));
1690#endif 1695#endif
1691 tp = find_transport (va->transport_name); 1696 tp = find_transport (va->transport_name);
1692 GNUNET_assert (tp != NULL); 1697 GNUNET_assert (tp != NULL);
1693 if (GNUNET_OK != 1698 if (GNUNET_OK !=
1694 tp->api->validate (tp->api->cls, 1699 tp->api->validate (tp->api->cls,
1695 peer, 1700 &apeer,
1696 va->challenge, 1701 va->challenge,
1697 HELLO_VERIFICATION_TIMEOUT, 1702 HELLO_VERIFICATION_TIMEOUT,
1698 &va[1], 1703 &va[1],
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 9a2a54890..0d08fec69 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -337,6 +337,8 @@ struct Session
337 337
338 /** 338 /**
339 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO) 339 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
340 * GNUNET_SYSERR is used to mark non-welcoming connections (HELLO
341 * validation only).
340 */ 342 */
341 int expecting_welcome; 343 int expecting_welcome;
342 344
@@ -501,80 +503,6 @@ create_session (struct Plugin *plugin,
501 503
502 504
503/** 505/**
504 * Create a new session connecting to the specified
505 * target at the specified address.
506 *
507 * @param plugin us
508 * @param target peer to connect to
509 * @param addrlen IPv4 or IPv6
510 * @param addr either struct sockaddr_in or struct sockaddr_in6
511 * @return NULL connection failed / invalid address
512 */
513static struct Session *
514connect_and_create_session (struct Plugin *plugin,
515 const struct GNUNET_PeerIdentity *target,
516 const void *addr, size_t addrlen)
517{
518 struct GNUNET_SERVER_Client *client;
519 struct GNUNET_NETWORK_SocketHandle *conn;
520 struct Session *session;
521 int af;
522
523 session = plugin->sessions;
524 while (session != NULL)
525 {
526 if ((0 == memcmp (target,
527 &session->target,
528 sizeof (struct GNUNET_PeerIdentity))) &&
529 (session->connect_alen == addrlen) &&
530 (0 == memcmp (session->connect_addr, addr, addrlen)))
531 return session; /* already exists! */
532 session = session->next;
533 }
534
535 if (addrlen == sizeof (struct sockaddr_in))
536 af = AF_INET;
537 else if (addrlen == sizeof (struct sockaddr_in6))
538 af = AF_INET6;
539 else
540 {
541 GNUNET_break_op (0);
542 return NULL; /* invalid address */
543 }
544 conn = GNUNET_NETWORK_socket_create_from_sockaddr (plugin->env->sched,
545 af,
546 addr,
547 addrlen,
548 GNUNET_SERVER_MAX_MESSAGE_SIZE);
549 if (conn == NULL)
550 {
551#if DEBUG_TCP
552 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
553 "tcp",
554 "Failed to create connection to peer at `%s'.\n",
555 GNUNET_a2s(addr, addrlen));
556#endif
557 return NULL;
558 }
559 client = GNUNET_SERVER_connect_socket (plugin->server, conn);
560 GNUNET_assert (client != NULL);
561 session = create_session (plugin, target, client, addr, addrlen);
562 session->connect_alen = addrlen;
563 session->connect_addr = GNUNET_malloc (addrlen);
564 memcpy (session->connect_addr, addr, addrlen);
565#if DEBUG_TCP
566 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
567 "tcp",
568 "Creating new session %p with `%s' based on `%s' request.\n",
569 session,
570 GNUNET_a2s(addr, addrlen),
571 "send_to");
572#endif
573 return session;
574}
575
576
577/**
578 * If we have pending messages, ask the server to 506 * If we have pending messages, ask the server to
579 * transmit them (schedule the respective tasks, etc.) 507 * transmit them (schedule the respective tasks, etc.)
580 * 508 *
@@ -703,6 +631,75 @@ process_pending_messages (struct Session *session)
703} 631}
704 632
705 633
634
635/**
636 * Create a new session connecting to the specified
637 * target at the specified address. The session will
638 * be used to verify an address in a HELLO and should
639 * not expect to receive a WELCOME.
640 *
641 * @param plugin us
642 * @param target peer to connect to
643 * @param addrlen IPv4 or IPv6
644 * @param addr either struct sockaddr_in or struct sockaddr_in6
645 * @return NULL connection failed / invalid address
646 */
647static struct Session *
648connect_and_create_validation_session (struct Plugin *plugin,
649 const struct GNUNET_PeerIdentity *target,
650 const void *addr, size_t addrlen)
651{
652 struct GNUNET_SERVER_Client *client;
653 struct GNUNET_NETWORK_SocketHandle *conn;
654 struct Session *session;
655 int af;
656
657 if (addrlen == sizeof (struct sockaddr_in))
658 af = AF_INET;
659 else if (addrlen == sizeof (struct sockaddr_in6))
660 af = AF_INET6;
661 else
662 {
663 GNUNET_break_op (0);
664 return NULL; /* invalid address */
665 }
666 conn = GNUNET_NETWORK_socket_create_from_sockaddr (plugin->env->sched,
667 af,
668 addr,
669 addrlen,
670 GNUNET_SERVER_MAX_MESSAGE_SIZE);
671 if (conn == NULL)
672 {
673#if DEBUG_TCP
674 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
675 "tcp",
676 "Failed to create connection to peer at `%s'.\n",
677 GNUNET_a2s(addr, addrlen));
678#endif
679 return NULL;
680 }
681 client = GNUNET_SERVER_connect_socket (plugin->server, conn);
682 GNUNET_assert (client != NULL);
683 session = create_session (plugin, target, client, addr, addrlen);
684 /* kill welcome */
685 GNUNET_free (session->pending_messages);
686 session->pending_messages = NULL;
687 session->connect_alen = addrlen;
688 session->connect_addr = GNUNET_malloc (addrlen);
689 session->expecting_welcome = GNUNET_SYSERR;
690 memcpy (session->connect_addr, addr, addrlen);
691#if DEBUG_TCP
692 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
693 "tcp",
694 "Creating new session %p with `%s' based on `%s' request.\n",
695 session,
696 GNUNET_a2s(addr, addrlen),
697 "send_to");
698#endif
699 return session;
700}
701
702
706/** 703/**
707 * Function that can be used by the transport service to validate that 704 * Function that can be used by the transport service to validate that
708 * another peer is reachable at a particular address (even if we 705 * another peer is reachable at a particular address (even if we
@@ -729,7 +726,7 @@ tcp_plugin_validate (void *cls,
729 struct PendingMessage *pm; 726 struct PendingMessage *pm;
730 struct ValidationChallengeMessage *vcm; 727 struct ValidationChallengeMessage *vcm;
731 728
732 session = connect_and_create_session (plugin, target, addr, addrlen); 729 session = connect_and_create_validation_session (plugin, target, addr, addrlen);
733 if (session == NULL) 730 if (session == NULL)
734 { 731 {
735#if DEBUG_TCP 732#if DEBUG_TCP
@@ -1566,7 +1563,7 @@ handle_tcp_pong (void *cls,
1566 } 1563 }
1567 addrlen = ntohs(message->size) - sizeof(struct ValidationChallengeResponse); 1564 addrlen = ntohs(message->size) - sizeof(struct ValidationChallengeResponse);
1568 vcr = (const struct ValidationChallengeResponse *) message; 1565 vcr = (const struct ValidationChallengeResponse *) message;
1569 if ( (ntohs(vcr->purpose.size) != 1566 if ( (ntohl(vcr->purpose.size) !=
1570 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + 1567 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1571 sizeof (uint32_t) + 1568 sizeof (uint32_t) +
1572 sizeof ( struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + 1569 sizeof ( struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
@@ -1658,6 +1655,12 @@ handle_tcp_welcome (void *cls,
1658 GNUNET_free_non_null (vaddr); 1655 GNUNET_free_non_null (vaddr);
1659 process_pending_messages (session_c); 1656 process_pending_messages (session_c);
1660 } 1657 }
1658 if (session_c->expecting_welcome != GNUNET_YES)
1659 {
1660 GNUNET_break_op (0);
1661 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1662 return;
1663 }
1661 session_c->expecting_welcome = GNUNET_NO; 1664 session_c->expecting_welcome = GNUNET_NO;
1662 if (0 < (addrlen = msize - sizeof (struct WelcomeMessage))) 1665 if (0 < (addrlen = msize - sizeof (struct WelcomeMessage)))
1663 { 1666 {
@@ -1747,7 +1750,7 @@ handle_tcp_data (void *cls,
1747 return; 1750 return;
1748 } 1751 }
1749 session = find_session_by_client (plugin, client); 1752 session = find_session_by_client (plugin, client);
1750 if ((NULL == session) || (GNUNET_YES == session->expecting_welcome)) 1753 if ((NULL == session) || (GNUNET_NO != session->expecting_welcome))
1751 { 1754 {
1752 GNUNET_break_op (0); 1755 GNUNET_break_op (0);
1753 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1756 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c
index ea22b9f12..a6a914023 100644
--- a/src/transport/test_transport_api.c
+++ b/src/transport/test_transport_api.c
@@ -185,7 +185,6 @@ exchange_hello_last (void *cls,
185 const struct GNUNET_MessageHeader *message) 185 const struct GNUNET_MessageHeader *message)
186{ 186{
187 struct PeerContext *me = cls; 187 struct PeerContext *me = cls;
188 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
189 188
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "Exchanging HELLO with peer (%p)!\n", cls); 190 "Exchanging HELLO with peer (%p)!\n", cls);
@@ -193,11 +192,8 @@ exchange_hello_last (void *cls,
193 OKPP; 192 OKPP;
194 GNUNET_assert (message != NULL); 193 GNUNET_assert (message != NULL);
195 GNUNET_assert (GNUNET_OK == 194 GNUNET_assert (GNUNET_OK ==
196 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *) 195 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
197 message, &pk)); 196 message, &me->id));
198 GNUNET_CRYPTO_hash (&pk,
199 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
200 &me->id.hashPubKey);
201 GNUNET_TRANSPORT_offer_hello (p1.th, message); 197 GNUNET_TRANSPORT_offer_hello (p1.th, message);
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "Finished exchanging HELLOs, now waiting for transmission!\n"); 199 "Finished exchanging HELLOs, now waiting for transmission!\n");
@@ -215,7 +211,6 @@ exchange_hello (void *cls,
215 const struct GNUNET_MessageHeader *message) 211 const struct GNUNET_MessageHeader *message)
216{ 212{
217 struct PeerContext *me = cls; 213 struct PeerContext *me = cls;
218 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
219 214
220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
221 "Exchanging HELLO with peer (%p)!\n", cls); 216 "Exchanging HELLO with peer (%p)!\n", cls);
@@ -223,11 +218,8 @@ exchange_hello (void *cls,
223 OKPP; 218 OKPP;
224 GNUNET_assert (message != NULL); 219 GNUNET_assert (message != NULL);
225 GNUNET_assert (GNUNET_OK == 220 GNUNET_assert (GNUNET_OK ==
226 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *) 221 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
227 message, &pk)); 222 message, &me->id));
228 GNUNET_CRYPTO_hash (&pk,
229 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
230 &me->id.hashPubKey);
231 GNUNET_TRANSPORT_get_hello (p2.th, GNUNET_TIME_UNIT_MINUTES, 223 GNUNET_TRANSPORT_get_hello (p2.th, GNUNET_TIME_UNIT_MINUTES,
232 &exchange_hello_last, &p2); 224 &exchange_hello_last, &p2);
233} 225}
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index 92f8f1f5c..be811953c 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -1475,7 +1475,6 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg)
1475 const struct SendOkMessage *okm; 1475 const struct SendOkMessage *okm;
1476 struct HelloWaitList *hwl; 1476 struct HelloWaitList *hwl;
1477 struct NeighbourList *n; 1477 struct NeighbourList *n;
1478 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
1479 struct GNUNET_PeerIdentity me; 1478 struct GNUNET_PeerIdentity me;
1480 struct GNUNET_TRANSPORT_TransmitHandle *th; 1479 struct GNUNET_TRANSPORT_TransmitHandle *th;
1481 uint16_t size; 1480 uint16_t size;
@@ -1524,16 +1523,12 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg)
1524 { 1523 {
1525 case GNUNET_MESSAGE_TYPE_HELLO: 1524 case GNUNET_MESSAGE_TYPE_HELLO:
1526 if (GNUNET_OK != 1525 if (GNUNET_OK !=
1527 GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *) msg, 1526 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg,
1528 &pkey)) 1527 &me))
1529 { 1528 {
1530 GNUNET_break (0); 1529 GNUNET_break (0);
1531 break; 1530 break;
1532 } 1531 }
1533 GNUNET_CRYPTO_hash (&pkey,
1534 sizeof (struct
1535 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1536 &me.hashPubKey);
1537#if DEBUG_TRANSPORT 1532#if DEBUG_TRANSPORT
1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1539 "Receiving (my own) `%s' message, I am `%4s'.\n", 1534 "Receiving (my own) `%s' message, I am `%4s'.\n",