summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-01 16:08:38 +0200
committerMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-01 16:08:38 +0200
commit2bb07d251cc8eead7a0fcf1c0c7100477f107027 (patch)
tree7a5416b77e8a8a69e18a3be524fe078cd381c1b0
parent754d8c1b496624e5c879af7d142fc9fd34de3a21 (diff)
parent54b5a20700a1ed27b1067a7cd55329ddc5b0d611 (diff)
Merge branch 'master' of ssh://gnunet.org/gnunet
-rw-r--r--src/core/gnunet-service-core_kx.c113
-rw-r--r--src/include/gnunet_buffer_lib.h15
-rw-r--r--src/include/gnunet_common.h38
-rw-r--r--src/include/gnunet_core_service.h116
-rw-r--r--src/include/gnunet_crypto_lib.h13
-rw-r--r--src/include/gnunet_json_lib.h2
-rw-r--r--src/include/gnunet_peerstore_service.h18
-rw-r--r--src/include/gnunet_protocols.h5
-rw-r--r--src/include/gnunet_signatures.h5
-rw-r--r--src/json/json.c2
-rw-r--r--src/pq/pq_connect.c4
-rw-r--r--src/transport/Makefile.am1
-rw-r--r--src/transport/gnunet-communicator-tcp.c699
-rw-r--r--src/transport/gnunet-service-tng.c13
-rw-r--r--src/transport/test_communicator_basic.c16
-rw-r--r--src/transport/test_communicator_tcp_basic_peer1.conf5
-rw-r--r--src/transport/test_communicator_tcp_basic_peer2.conf5
-rw-r--r--src/transport/test_communicator_tcp_rekey_peer1.conf9
-rw-r--r--src/transport/test_communicator_tcp_rekey_peer2.conf9
-rw-r--r--src/transport/test_communicator_udp_backchannel_peer1.conf7
-rw-r--r--src/transport/test_communicator_udp_backchannel_peer2.conf7
-rw-r--r--src/transport/test_communicator_udp_basic_peer1.conf7
-rw-r--r--src/transport/test_communicator_udp_basic_peer2.conf8
-rw-r--r--src/transport/test_communicator_udp_rekey_peer1.conf7
-rw-r--r--src/transport/test_communicator_udp_rekey_peer2.conf7
-rw-r--r--src/transport/test_communicator_unix_basic_peer1.conf7
-rw-r--r--src/transport/test_communicator_unix_basic_peer2.conf7
-rw-r--r--src/transport/transport-testing2.c77
-rw-r--r--src/util/buffer.c32
-rw-r--r--src/util/disk.c14
30 files changed, 1021 insertions, 247 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index cafe658e8..a79ef075b 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -77,119 +77,6 @@
GNUNET_NETWORK_STRUCT_BEGIN
/**
- * Message transmitted with the signed ephemeral key of a peer. The
- * session key is then derived from the two ephemeral keys (ECDHE).
- */
-struct EphemeralKeyMessage
-{
- /**
- * Message type is #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Status of the sender (should be in `enum PeerStateMachine`), nbo.
- */
- int32_t sender_status GNUNET_PACKED;
-
- /**
- * An ECC signature of the @e origin_identity asserting the validity
- * of the given ephemeral key.
- */
- struct GNUNET_CRYPTO_EddsaSignature signature;
-
- /**
- * Information about what is being signed.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * At what time was this key created (beginning of validity).
- */
- struct GNUNET_TIME_AbsoluteNBO creation_time;
-
- /**
- * When does the given ephemeral key expire (end of validity).
- */
- struct GNUNET_TIME_AbsoluteNBO expiration_time;
-
- /**
- * Ephemeral public ECC key.
- */
- struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
-
- /**
- * Public key of the signing peer (persistent version, not the
- * ephemeral public key).
- */
- struct GNUNET_PeerIdentity origin_identity;
-};
-
-
-/**
- * We're sending an (encrypted) PING to the other peer to check if it
- * can decrypt. The other peer should respond with a PONG with the
- * same content, except this time encrypted with the receiver's key.
- */
-struct PingMessage
-{
- /**
- * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Seed for the IV
- */
- uint32_t iv_seed GNUNET_PACKED;
-
- /**
- * Intended target of the PING, used primarily to check
- * that decryption actually worked.
- */
- struct GNUNET_PeerIdentity target;
-
- /**
- * Random number chosen to make replay harder.
- */
- uint32_t challenge GNUNET_PACKED;
-};
-
-
-/**
- * Response to a PING. Includes data from the original PING.
- */
-struct PongMessage
-{
- /**
- * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Seed for the IV
- */
- uint32_t iv_seed GNUNET_PACKED;
-
- /**
- * Random number to make replay attacks harder.
- */
- uint32_t challenge GNUNET_PACKED;
-
- /**
- * Reserved, always zero.
- */
- uint32_t reserved;
-
- /**
- * Intended target of the PING, used primarily to check
- * that decryption actually worked.
- */
- struct GNUNET_PeerIdentity target;
-};
-
-
-/**
* Encapsulation for encrypted messages exchanged between
* peers. Followed by the actual encrypted data.
*/
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h
index e09ec130a..046aee72b 100644
--- a/src/include/gnunet_buffer_lib.h
+++ b/src/include/gnunet_buffer_lib.h
@@ -110,6 +110,21 @@ GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str);
/**
+ * Write data encoded via #GNUNET_STRINGS_data_to_string to the buffer.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf buffer to write to
+ * @param data data to read from
+ * @param len number of bytes to copy from @a data to @a buf
+ */
+void
+GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf,
+ const char *data,
+ size_t len);
+
+
+/**
* Write a path component to a buffer, ensuring that
* there is exactly one slash between the previous contents
* of the buffer and the new string.
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 91d4a5bd4..b2f99cd55 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -457,11 +457,11 @@ __attribute__ ((format (printf, 2, 3)));
__extension__ ({ \
int _gnunet_boolean_var_; \
if (expr) \
- _gnunet_boolean_var_ = 1; \
+ _gnunet_boolean_var_ = 1; \
else \
- _gnunet_boolean_var_ = 0; \
+ _gnunet_boolean_var_ = 0; \
_gnunet_boolean_var_; \
- })
+ })
#define GN_LIKELY(expr) (__builtin_expect (_GNUNET_BOOLEAN_EXPR (expr), 1))
#define GN_UNLIKELY(expr) (__builtin_expect (_GNUNET_BOOLEAN_EXPR (expr), 0))
#else
@@ -499,12 +499,12 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \
{ \
if (GN_UNLIKELY (log_call_enabled == -1)) \
- log_call_enabled = \
- GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \
- (comp), \
- __FILE__, \
- __FUNCTION__, \
- __LINE__); \
+ log_call_enabled = \
+ GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \
+ (comp), \
+ __FILE__, \
+ __FUNCTION__, \
+ __LINE__); \
if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \
{ \
GNUNET_log_skip (-1, GNUNET_NO); \
@@ -512,7 +512,7 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
else \
{ \
if (GN_UNLIKELY (log_call_enabled)) \
- GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__); \
+ GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__); \
} \
} \
} while (0)
@@ -525,12 +525,12 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \
{ \
if (GN_UNLIKELY (log_call_enabled == -1)) \
- log_call_enabled = \
- GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \
- NULL, \
- __FILE__, \
- __FUNCTION__, \
- __LINE__); \
+ log_call_enabled = \
+ GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \
+ NULL, \
+ __FILE__, \
+ __FUNCTION__, \
+ __LINE__); \
if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \
{ \
GNUNET_log_skip (-1, GNUNET_NO); \
@@ -538,7 +538,7 @@ GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind,
else \
{ \
if (GN_UNLIKELY (log_call_enabled)) \
- GNUNET_log_nocheck ((kind), __VA_ARGS__); \
+ GNUNET_log_nocheck ((kind), __VA_ARGS__); \
} \
} \
} while (0)
@@ -1319,8 +1319,8 @@ GNUNET_is_zero_ (const void *a,
* been returned by #GNUNET_strdup, #GNUNET_strndup, #GNUNET_malloc or #GNUNET_array_grow earlier. NULL is allowed.
*/
#define GNUNET_free(ptr) do { \
- GNUNET_xfree_ (ptr, __FILE__, __LINE__); \
- ptr = NULL; \
+ GNUNET_xfree_ (ptr, __FILE__, __LINE__); \
+ ptr = NULL; \
} while (0)
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h
index 66b292c3c..60bc3c2a6 100644
--- a/src/include/gnunet_core_service.h
+++ b/src/include/gnunet_core_service.h
@@ -48,6 +48,122 @@ extern "C" {
*/
#define GNUNET_CORE_VERSION 0x00000001
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message transmitted with the signed ephemeral key of a peer. The
+ * session key is then derived from the two ephemeral keys (ECDHE).
+ */
+struct EphemeralKeyMessage
+{
+ /**
+ * Message type is #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Status of the sender (should be in `enum PeerStateMachine`), nbo.
+ */
+ int32_t sender_status GNUNET_PACKED;
+
+ /**
+ * An ECC signature of the @e origin_identity asserting the validity
+ * of the given ephemeral key.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature signature;
+
+ /**
+ * Information about what is being signed.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * At what time was this key created (beginning of validity).
+ */
+ struct GNUNET_TIME_AbsoluteNBO creation_time;
+
+ /**
+ * When does the given ephemeral key expire (end of validity).
+ */
+ struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
+ /**
+ * Ephemeral public ECC key.
+ */
+ struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
+
+ /**
+ * Public key of the signing peer (persistent version, not the
+ * ephemeral public key).
+ */
+ struct GNUNET_PeerIdentity origin_identity;
+};
+
+
+/**
+ * We're sending an (encrypted) PING to the other peer to check if it
+ * can decrypt. The other peer should respond with a PONG with the
+ * same content, except this time encrypted with the receiver's key.
+ */
+struct PingMessage
+{
+ /**
+ * Message type is #GNUNET_MESSAGE_TYPE_CORE_PING.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Seed for the IV
+ */
+ uint32_t iv_seed GNUNET_PACKED;
+
+ /**
+ * Intended target of the PING, used primarily to check
+ * that decryption actually worked.
+ */
+ struct GNUNET_PeerIdentity target;
+
+ /**
+ * Random number chosen to make replay harder.
+ */
+ uint32_t challenge GNUNET_PACKED;
+};
+
+
+/**
+ * Response to a PING. Includes data from the original PING.
+ */
+struct PongMessage
+{
+ /**
+ * Message type is #GNUNET_MESSAGE_TYPE_CORE_PONG.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Seed for the IV
+ */
+ uint32_t iv_seed GNUNET_PACKED;
+
+ /**
+ * Random number to make replay attacks harder.
+ */
+ uint32_t challenge GNUNET_PACKED;
+
+ /**
+ * Reserved, always zero.
+ */
+ uint32_t reserved;
+
+ /**
+ * Intended target of the PING, used primarily to check
+ * that decryption actually worked.
+ */
+ struct GNUNET_PeerIdentity target;
+};
+
+
+GNUNET_NETWORK_STRUCT_END
/**
* Opaque handle to the service.
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 320701643..f8eef5406 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -289,6 +289,17 @@ struct GNUNET_CRYPTO_SymmetricSessionKey
unsigned char twofish_key[GNUNET_CRYPTO_AES_KEY_LENGTH];
};
+/**
+ * Type of a nonce used for challenges.
+ */
+struct ChallengeNonceP
+{
+ /**
+ * The value of the nonce. Note that this is NOT a hash.
+ */
+ struct GNUNET_ShortHashCode value;
+};
+
GNUNET_NETWORK_STRUCT_END
/**
@@ -1779,7 +1790,7 @@ GNUNET_CRYPTO_eddsa_verify_ (
*/
#define GNUNET_CRYPTO_eddsa_verify(purp,ps,sig,pub) ({ \
/* check size is set correctly */ \
- GNUNET_assert (htonl ((ps)->purpose.size) == sizeof (*(ps))); \
+ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \
/* check 'ps' begins with the purpose */ \
GNUNET_static_assert (((void*) (ps)) == \
((void*) &(ps)->purpose)); \
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h
index 95d136239..07a14d329 100644
--- a/src/include/gnunet_json_lib.h
+++ b/src/include/gnunet_json_lib.h
@@ -127,7 +127,7 @@ struct GNUNET_JSON_Specification
* @param[out] which index into @a spec did we encounter an error
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
-int
+enum GNUNET_GenericReturnValue
GNUNET_JSON_parse (const json_t *root,
struct GNUNET_JSON_Specification *spec,
const char **error_json_name,
diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h
index cd68dad66..91a8f2e66 100644
--- a/src/include/gnunet_peerstore_service.h
+++ b/src/include/gnunet_peerstore_service.h
@@ -67,6 +67,24 @@ extern "C" {
#define GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME \
"transport-dv-learn-monotonic-time"
+/**
+ * Key used to store sender's monotonic time from handshake message.
+ */
+#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE \
+ "transport-tcp-communicator-handshake"
+
+/**
+ * Key used to store sender's monotonic time from handshake ack message.
+ */
+#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK \
+ "transport-tcp-communicator-handshake-ack"
+
+/**
+ * Key used to store sender's monotonic time from rekey message.
+ */
+#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY \
+ "transport-tcp-communicator-rekey"
+
/**
* Options for storing values in PEERSTORE
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 0db6150aa..5af58664f 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3293,6 +3293,11 @@ extern "C" {
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH 1452
/**
+ * TCP communicator confirmation ack.
+ */
+#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK 1453
+
+/**
* UDP KX acknowledgement.
*/
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK 1460
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index 503113770..7c0c1d104 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -246,6 +246,11 @@ extern "C"
*/
#define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR 38
+/**
+ * Signature by a peer sending back the nonce received at initial handshake.
+ */
+#define GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK 39
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
diff --git a/src/json/json.c b/src/json/json.c
index f6d2406c4..0631c51bb 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -41,7 +41,7 @@
* @param[out] which index into @a spec did we encounter an error
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
-int
+enum GNUNET_GenericReturnValue
GNUNET_JSON_parse (const json_t *root,
struct GNUNET_JSON_Specification *spec,
const char **error_json_name,
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c
index e3a610922..881a158bb 100644
--- a/src/pq/pq_connect.c
+++ b/src/pq/pq_connect.c
@@ -172,6 +172,8 @@ apply_patch (struct GNUNET_PQ_Context *db,
"-f",
buf,
"-q",
+ "--set",
+ "ON_ERROR_STOP=1",
NULL);
if (NULL == psql)
{
@@ -415,7 +417,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
db->load_path))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load SQL statements from `%s'\n",
+ "Failed to load SQL statements from `%s*'\n",
db->load_path);
PQfinish (db->conn);
db->conn = NULL;
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 354bb1cf4..e0369059d 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -278,6 +278,7 @@ gnunet_communicator_tcp_SOURCES = \
gnunet-communicator-tcp.c
gnunet_communicator_tcp_LDADD = \
libgnunettransportcommunicator.la \
+ $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
$(top_builddir)/src/nat/libgnunetnatnew.la \
$(top_builddir)/src/nt/libgnunetnt.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index 177b5c26c..880145424 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -24,26 +24,22 @@
* @author Christian Grothoff
*
* TODO:
- * - support DNS names in BINDTO option (#5528)
* - support NAT connection reversal method (#5529)
* - support other TCP-specific NAT traversal methods (#5531)
- * - add replay protection support to the protocol by
- * adding a nonce in the KX and requiring (!) a
- * nounce ACK to be send within the first X bytes of
- * data (#5530)
*/
#include "platform.h"
#include "gnunet_util_lib.h"
+#include "gnunet_core_service.h"
+#include "gnunet_peerstore_service.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_constants.h"
#include "gnunet_nt_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet_statistics_service.h"
-#include "gnunet_ats_transport_service.h"
-#include "transport.h"
#include "gnunet_transport_communication_service.h"
#include "gnunet_resolver_service.h"
+
/**
* How long do we believe our addresses to remain up (before
* the other peer should revalidate).
@@ -91,6 +87,13 @@
(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
+ sizeof(struct TCPConfirmation))
+/**
+ * Size of the initial core key exchange messages.
+ */
+#define INITIAL_CORE_KX_SIZE \
+ (sizeof(struct EphemeralKeyMessage) \
+ + sizeof(struct PingMessage) \
+ + sizeof(struct PongMessage))
/**
* Address prefix used by the communicator.
@@ -136,8 +139,45 @@ struct TcpHandshakeSignature
* (if receiver persists times by sender).
*/
struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+ /**
+ * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
+ */
+ struct ChallengeNonceP challenge;
};
+/**
+ * Signature we use to verify that the ack from the receiver of the ephemeral key was really send by
+ * the specified sender.
+ */
+struct TcpHandshakeAckSignature
+{
+ /**
+ * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Identity of the inititor of the TCP connection (TCP client).
+ */
+ struct GNUNET_PeerIdentity sender;
+
+ /**
+ * Presumed identity of the target of the TCP connection (TCP server)
+ */
+ struct GNUNET_PeerIdentity receiver;
+
+ /**
+ * Monotonic time of @e sender, to possibly help detect replay attacks
+ * (if receiver persists times by sender).
+ */
+ struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+ /**
+ * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
+ */
+ struct ChallengeNonceP challenge;
+};
/**
* Encrypted continuation of TCP initial handshake.
@@ -159,8 +199,48 @@ struct TCPConfirmation
* (if receiver persists times by sender).
*/
struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+ /**
+ * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
+ */
+ struct ChallengeNonceP challenge;
+
};
+/**
+ * Ack for the encrypted continuation of TCP initial handshake.
+ */
+struct TCPConfirmationAck
+{
+
+
+ /**
+ * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Sender's identity
+ */
+ struct GNUNET_PeerIdentity sender;
+
+ /**
+ * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK
+ */
+ struct GNUNET_CRYPTO_EddsaSignature sender_sig;
+
+ /**
+ * Monotonic time of @e sender, to possibly help detect replay attacks
+ * (if receiver persists times by sender).
+ */
+ struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+ /**
+ * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
+ */
+ struct ChallengeNonceP challenge;
+
+};
/**
* TCP message box. Always sent encrypted!
@@ -456,6 +536,56 @@ struct Queue
* re-decrypt ciphertext.
*/
int rekeyed;
+
+ /**
+ * Monotonic time value for rekey message.
+ */
+ struct GNUNET_TIME_AbsoluteNBO rekey_monotonic_time;
+
+ /**
+ * Monotonic time value for handshake message.
+ */
+ struct GNUNET_TIME_AbsoluteNBO handshake_monotonic_time;
+
+ /**
+ * Monotonic time value for handshake ack message.
+ */
+ struct GNUNET_TIME_AbsoluteNBO handshake_ack_monotonic_time;
+
+ /**
+ * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
+ */
+ struct ChallengeNonceP challenge;
+
+ /**
+ * Iteration Context for retrieving the monotonic time send with key for rekeying.
+ */
+ struct GNUNET_PEERSTORE_IterateContext *rekey_monotime_get;
+
+ /**
+ * Iteration Context for retrieving the monotonic time send with the handshake.
+ */
+ struct GNUNET_PEERSTORE_IterateContext *handshake_monotime_get;
+
+ /**
+ * Iteration Context for retrieving the monotonic time send with the handshake ack.
+ */
+ struct GNUNET_PEERSTORE_IterateContext *handshake_ack_monotime_get;
+
+ /**
+ * Store Context for retrieving the monotonic time send with key for rekeying.
+ */
+ struct GNUNET_PEERSTORE_StoreContext *rekey_monotime_sc;
+
+ /**
+ * Store Context for retrieving the monotonic time send with the handshake.
+ */
+ struct GNUNET_PEERSTORE_StoreContext *handshake_monotime_sc;
+
+ /**
+ * Store Context for retrieving the monotonic time send with the handshake ack.
+ */
+ struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc;
};
@@ -535,7 +665,7 @@ struct PortOnlyIpv4Ipv6
/**
* Length of ipv4 address.
*/
- socklen_t *addr_len_ipv4;
+ socklen_t addr_len_ipv4;
/**
* Ipv6 address we like to bind to.
@@ -545,7 +675,7 @@ struct PortOnlyIpv4Ipv6
/**
* Length of ipv6 address.
*/
- socklen_t *addr_len_ipv6;
+ socklen_t addr_len_ipv6;
};
@@ -577,6 +707,7 @@ struct Addresses
};
+
/**
* Maximum queue length before we stop reading towards the transport service.
*/
@@ -658,6 +789,16 @@ struct Addresses *addrs_tail;
int addrs_lens;
/**
+ * Size of data received without KX challenge played back.
+ */
+size_t unverified_size;
+
+/**
+ * Database for peer's HELLOs.
+ */
+static struct GNUNET_PEERSTORE_Handle *peerstore;
+
+/**
* We have been notified that our listen socket has something to
* read. Do the read and reschedule this function to be called again
* once more is available.
@@ -687,6 +828,36 @@ queue_destroy (struct Queue *queue)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Disconnecting queue for peer `%s'\n",
GNUNET_i2s (&queue->target));
+ if (NULL != queue->rekey_monotime_sc)
+ {
+ GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
+ queue->rekey_monotime_sc = NULL;
+ }
+ if (NULL != queue->handshake_monotime_sc)
+ {
+ GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
+ queue->handshake_monotime_sc = NULL;
+ }
+ if (NULL != queue->handshake_ack_monotime_sc)
+ {
+ GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
+ queue->handshake_ack_monotime_sc = NULL;
+ }
+ if (NULL != queue->rekey_monotime_get)
+ {
+ GNUNET_PEERSTORE_iterate_cancel (queue->rekey_monotime_get);
+ queue->rekey_monotime_get = NULL;
+ }
+ if (NULL != queue->handshake_monotime_get)
+ {
+ GNUNET_PEERSTORE_iterate_cancel (queue->handshake_monotime_get);
+ queue->handshake_monotime_get = NULL;
+ }
+ if (NULL != queue->handshake_ack_monotime_get)
+ {
+ GNUNET_PEERSTORE_iterate_cancel (queue->handshake_ack_monotime_get);
+ queue->handshake_ack_monotime_get = NULL;
+ }
if (NULL != (mq = queue->mq))
{
queue->mq = NULL;
@@ -964,6 +1135,78 @@ setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
}
+/**
+ * Callback called when peerstore store operation for rekey monotime value is finished.
+ * @param cls Queue context the store operation was executed.
+ * @param success Store operation was successful (GNUNET_OK) or not.
+ */
+static void
+rekey_monotime_store_cb (void *cls, int success)
+{
+ struct Queue *queue = cls;
+ if (GNUNET_OK != success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store rekey monotonic time in PEERSTORE!\n");
+ }
+ queue->rekey_monotime_sc = NULL;
+}
+
+/**
+ * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
+ * where found.
+ * @param cls Queue context the store operation was executed.
+ * @param record The record found or NULL if there is no record left.
+ * @param emsg Message from peerstore.
+ */
+static void
+rekey_monotime_cb (void *cls,
+ const struct GNUNET_PEERSTORE_Record *record,
+ const char *emsg)
+{
+ struct Queue *queue = cls;
+ struct GNUNET_TIME_AbsoluteNBO *mtbe;
+ struct GNUNET_TIME_Absolute mt;
+ const struct GNUNET_PeerIdentity *pid;
+ struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
+
+ (void) emsg;
+
+ rekey_monotonic_time = &queue->rekey_monotonic_time;
+ pid = &queue->target;
+ if (NULL == record)
+ {
+ queue->rekey_monotime_get = NULL;
+ return;
+ }
+ if (sizeof(*mtbe) != record->value_size)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ mtbe = record->value;
+ mt = GNUNET_TIME_absolute_ntoh (*mtbe);
+ if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
+ queue->rekey_monotonic_time).abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Queue from %s dropped, rekey monotime in the past\n",
+ GNUNET_i2s (&queue->target));
+ GNUNET_break (0);
+ queue_finish (queue);
+ return;
+ }
+ queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
+ "transport_tcp_communicator",
+ pid,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
+ rekey_monotonic_time,
+ sizeof(rekey_monotonic_time),
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+ &rekey_monotime_store_cb,
+ queue);
+}
/**
* Handle @a rekey message on @a queue. The message was already
@@ -983,7 +1226,6 @@ do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
thp.receiver = my_identity;
thp.ephemeral = rekey->ephemeral;
thp.monotonic_time = rekey->monotonic_time;
- /* FIXME: check monotonic time is monotonic... */
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
&thp,
@@ -994,11 +1236,93 @@ do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
queue_finish (queue);
return;
}
+ queue->rekey_monotonic_time = rekey->monotonic_time;
+ queue->rekey_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
+ "transport_tcp_communicator",
+ &queue->target,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
+ &rekey_monotime_cb,
+ queue);
gcry_cipher_close (queue->in_cipher);
queue->rekeyed = GNUNET_YES;
setup_in_cipher (&rekey->ephemeral, queue);
}
+/**
+ * Callback called when peerstore store operation for handshake ack monotime value is finished.
+ * @param cls Queue context the store operation was executed.
+ * @param success Store operation was successful (GNUNET_OK) or not.
+ */
+static void
+handshake_ack_monotime_store_cb (void *cls, int success)
+{
+ struct Queue *queue = cls;
+
+ if (GNUNET_OK != success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store handshake ack monotonic time in PEERSTORE!\n");
+ }
+ queue->handshake_ack_monotime_sc = NULL;
+}
+
+/**
+ * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
+ * where found.
+ * @param cls Queue context the store operation was executed.
+ * @param record The record found or NULL if there is no record left.
+ * @param emsg Message from peerstore.
+ */
+static void
+handshake_ack_monotime_cb (void *cls,
+ const struct GNUNET_PEERSTORE_Record *record,
+ const char *emsg)
+{
+ struct Queue *queue = cls;
+ struct GNUNET_TIME_AbsoluteNBO *mtbe;
+ struct GNUNET_TIME_Absolute mt;
+ const struct GNUNET_PeerIdentity *pid;
+ struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
+
+ (void) emsg;
+
+ handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
+ pid = &queue->target;
+ if (NULL == record)
+ {
+ queue->handshake_ack_monotime_get = NULL;
+ return;
+ }
+ if (sizeof(*mtbe) != record->value_size)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ mtbe = record->value;
+ mt = GNUNET_TIME_absolute_ntoh (*mtbe);
+ if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
+ queue->handshake_ack_monotonic_time).abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Queue from %s dropped, handshake ack monotime in the past\n",
+ GNUNET_i2s (&queue->target));
+ GNUNET_break (0);
+ queue_finish (queue);
+ return;
+ }
+ queue->handshake_ack_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
+ "transport_tcp_communicator",
+ pid,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
+ handshake_ack_monotonic_time,
+ sizeof(
+ handshake_ack_monotonic_time),
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+ &
+ handshake_ack_monotime_store_cb,
+ queue);
+}
/**
* Test if we have received a full message in plaintext.
@@ -1012,6 +1336,8 @@ try_handle_plaintext (struct Queue *queue)
{
const struct GNUNET_MessageHeader *hdr =
(const struct GNUNET_MessageHeader *) queue->pread_buf;
+ const struct TCPConfirmationAck *tca = (const struct
+ TCPConfirmationAck *) queue->pread_buf;
const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
@@ -1020,12 +1346,92 @@ try_handle_plaintext (struct Queue *queue)
struct GNUNET_ShortHashCode tmac;
uint16_t type;
size_t size = 0; /* make compiler happy */
+ struct TcpHandshakeAckSignature thas;
+ const struct ChallengeNonceP challenge = queue->challenge;
- if (sizeof(*hdr) > queue->pread_off)
+ if ((sizeof(*hdr) > queue->pread_off))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, not even a header!\n");
return 0; /* not even a header */
+ }
+
+ if ((-1 != unverified_size) && (unverified_size > INITIAL_CORE_KX_SIZE))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Already received data of size %u bigger than KX size %u!\n",
+ unverified_size,
+ INITIAL_CORE_KX_SIZE);
+ GNUNET_break_op (0);
+ queue_finish (queue);
+ return 0;
+ }
+
type = ntohs (hdr->type);
switch (type)
{
+ case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "start processing ack\n");
+ if (sizeof(*tca) > queue->pread_off)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext size of tca greater than pread offset.\n");
+ return 0;
+ }
+ if (ntohs (hdr->size) != sizeof(*tca))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext size does not match message type.\n");
+ GNUNET_break_op (0);
+ queue_finish (queue);
+ return 0;
+ }
+
+ thas.purpose.purpose = htonl (
+ GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
+ thas.purpose.size = htonl (sizeof(thas));
+ thas.sender = tca->sender;
+ thas.receiver = my_identity;
+ thas.monotonic_time = tca->monotonic_time;
+ thas.challenge = tca->challenge;
+
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify (
+ GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK,
+ &thas,
+ &tca->sender_sig,
+ &tca->sender.public_key))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Verification of signature failed!\n");
+ GNUNET_break (0);
+ queue_finish (queue);
+ return 0;
+ }
+ if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Challenge in TCPConfirmationAck not correct!\n");
+ GNUNET_break (0);
+ queue_finish (queue);
+ return 0;
+ }
+
+ queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
+ "transport_tcp_communicator",
+ &queue->target,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
+ &
+ handshake_ack_monotime_cb,
+ queue);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, ack processed!");
+
+ unverified_size = -1;
+
+ size = ntohs (hdr->size);
+ break;
case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
/* Special case: header size excludes box itself! */
if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
@@ -1039,6 +1445,8 @@ try_handle_plaintext (struct Queue *queue)
}
pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
size = ntohs (hdr->size) + sizeof(*box);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, box processed!\n");
break;
case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
@@ -1061,6 +1469,8 @@ try_handle_plaintext (struct Queue *queue)
}
do_rekey (queue, rekey);
size = ntohs (hdr->size);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, rekey processed!\n");
break;
case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
@@ -1083,14 +1493,20 @@ try_handle_plaintext (struct Queue *queue)
}
/* handle FINISH by destroying queue */
queue_destroy (queue);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, finish processed!\n");
break;
default:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling plaintext, nothing processed!\n");
GNUNET_break_op (0);
queue_finish (queue);
return 0;
}
GNUNET_assert (0 != size);
+ if (-1 != unverified_size)
+ unverified_size += size;
return size;
}
@@ -1202,7 +1618,6 @@ queue_read (void *cls)
queue_finish (queue);
}
-
/**
* Convert a `struct sockaddr_in6 to a `struct sockaddr *`
*
@@ -1216,10 +1631,6 @@ tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len, struct sockaddr_in6 v6,
{
struct sockaddr *in;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "1 address %s\n",
- GNUNET_a2s (in, *sock_len));
-
v6.sin6_family = AF_INET6;
v6.sin6_port = htons ((uint16_t) port);
#if HAVE_SOCKADDR_IN_SIN_LEN
@@ -1227,14 +1638,10 @@ tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len, struct sockaddr_in6 v6,
#endif
in = GNUNET_memdup (&v6, sizeof(v6));
*sock_len = sizeof(struct sockaddr_in6);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "address %s\n",
- GNUNET_a2s (in, *sock_len));
return in;
}
-
/**
* Convert a `struct sockaddr_in4 to a `struct sockaddr *`
*
@@ -1258,7 +1665,6 @@ tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len, struct sockaddr_in v4,
return in;
}
-
/**
* Convert TCP bind specification to a `struct PortOnlyIpv4Ipv6 *`
*
@@ -1294,7 +1700,7 @@ tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
*port);
- po->addr_len_ipv4 = &sock_len_ipv4;
+ po->addr_len_ipv4 = sock_len_ipv4;
}
else
{
@@ -1302,25 +1708,22 @@ tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
*port);
- po->addr_len_ipv4 = &sock_len_ipv4;
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "3.5 address %s\n",
- GNUNET_a2s (po->addr_ipv4, sock_len_ipv4));
+ po->addr_len_ipv4 = sock_len_ipv4;
i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
*port);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "3 address %s\n",
- GNUNET_a2s (po->addr_ipv6, sock_len_ipv6));
- po->addr_len_ipv6 = &sock_len_ipv6;
+ po->addr_len_ipv6 = sock_len_ipv6;
+
+ GNUNET_free (i6);
}
+
+ GNUNET_free (i4);
+
return po;
}
-
/**
* This Method extracts the address part of the BINDTO string.
*
@@ -1347,8 +1750,7 @@ extract_address (const char *bindto)
start++; /* skip over '['*/
cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
}
- else
- {
+ else {
token = strtok_r (cp, "]", &rest);
if (strlen (bindto) == strlen (token))
{
@@ -1361,12 +1763,11 @@ extract_address (const char *bindto)
}
}
- // GNUNET_free(cp);
+ GNUNET_free (cp);
return start;
}
-
/**
* This Method extracts the port part of the BINDTO string.
*
@@ -1445,7 +1846,6 @@ extract_port (const char *addr_and_port)
return port;
}
-
/**
* Convert TCP bind specification to a `struct sockaddr *`
*
@@ -1827,12 +2227,16 @@ transmit_kx (struct Queue *queue,
tc.sender = my_identity;
tc.monotonic_time =
GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+ &tc.challenge,
+ sizeof(tc.challenge));
ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE);
ths.purpose.size = htonl (sizeof(ths));
ths.sender = my_identity;
ths.receiver = queue->target;
ths.ephemeral = *epub;
ths.monotonic_time = tc.monotonic_time;
+ ths.challenge = tc.challenge;
GNUNET_CRYPTO_eddsa_sign (my_private_key,
&ths,
&tc.sender_sig);
@@ -1842,7 +2246,12 @@ transmit_kx (struct Queue *queue,
sizeof(tc),
&tc,
sizeof(tc)));
+ queue->challenge = tc.challenge;
queue->cwrite_off += sizeof(tc);
+
+ GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
+ "transport",
+ "handshake written\n");
}
@@ -1864,6 +2273,80 @@ start_initial_kx_out (struct Queue *queue)
transmit_kx (queue, &epub);
}
+/**
+ * Callback called when peerstore store operation for handshake monotime is finished.
+ * @param cls Queue context the store operation was executed.
+ * @param success Store operation was successful (GNUNET_OK) or not.
+ */
+static void
+handshake_monotime_store_cb (void *cls, int success)
+{
+ struct Queue *queue = cls;
+ if (GNUNET_OK != success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store handshake monotonic time in PEERSTORE!\n");
+ }
+ queue->handshake_monotime_sc = NULL;
+}
+
+/**
+ * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
+ * where found.
+ * @param cls Queue context the store operation was executed.
+ * @param record The record found or NULL if there is no record left.
+ * @param emsg Message from peerstore.
+ */
+static void
+handshake_monotime_cb (void *cls,
+ const struct GNUNET_PEERSTORE_Record *record,
+ const char *emsg)
+{
+ struct Queue *queue = cls;
+ struct GNUNET_TIME_AbsoluteNBO *mtbe;
+ struct GNUNET_TIME_Absolute mt;
+ const struct GNUNET_PeerIdentity *pid;
+ struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
+
+ (void) emsg;
+
+ handshake_monotonic_time = &queue->handshake_monotonic_time;
+ pid = &queue->target;
+ if (NULL == record)
+ {
+ queue->handshake_monotime_get = NULL;
+ return;
+ }
+ if (sizeof(*mtbe) != record->value_size)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ mtbe = record->value;
+ mt = GNUNET_TIME_absolute_ntoh (*mtbe);
+ if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
+ queue->handshake_monotonic_time).abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Queue from %s dropped, handshake monotime in the past\n",
+ GNUNET_i2s (&queue->target));
+ GNUNET_break (0);
+ queue_finish (queue);
+ return;
+ }
+ queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
+ "transport_tcp_communicator",
+ pid,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
+ handshake_monotonic_time,
+ sizeof(
+ handshake_monotonic_time),
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+ &
+ handshake_monotime_store_cb,
+ queue);
+}
/**
* We have received the first bytes from the other side on a @a queue.
@@ -1896,13 +2379,19 @@ decrypt_and_check_tc (struct Queue *queue,
ths.receiver = my_identity;
memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
ths.monotonic_time = tc->monotonic_time;
- /* FIXME: check monotonic time against previous mono times
- from this sender! */
+ ths.challenge = tc->challenge;
return GNUNET_CRYPTO_eddsa_verify (
GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
&ths,
&tc->sender_sig,
&tc->sender.public_key);
+ queue->handshake_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
+ "transport_tcp_communicator",
+ &queue->target,
+ GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
+ &
+ handshake_monotime_cb,
+ queue);
}
@@ -1930,6 +2419,47 @@ free_proto_queue (struct ProtoQueue *pq)
GNUNET_free (pq);
}
+/**
+ * Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
+ *
+ * @param tc The TCPConfirmation originally send.
+ * @param queue The queue context.
+ */
+static void
+send_challenge (struct TCPConfirmation tc, struct Queue *queue)
+{
+ struct TCPConfirmationAck tca;
+ struct TcpHandshakeAckSignature thas;
+
+ GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
+ "transport",
+ "sending challenge\n");
+
+ tca.header.type = ntohs (
+ GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK);
+ tca.header.size = ntohs (sizeof(tca));
+ tca.challenge = tc.challenge;
+ tca.sender = my_identity;
+ tca.monotonic_time =
+ GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
+ thas.purpose.purpose = htonl (
+ GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
+ thas.purpose.size = htonl (sizeof(thas));
+ thas.sender = my_identity;
+ thas.receiver = queue->target;
+ thas.monotonic_time = tca.monotonic_time;
+ thas.challenge = tca.challenge;
+ GNUNET_CRYPTO_eddsa_sign (my_private_key,
+ &thas,
+ &tca.sender_sig);
+ GNUNET_assert (0 ==
+ gcry_cipher_encrypt (queue->out_cipher,
+ &queue->cwrite_buf[queue->cwrite_off],
+ sizeof(tca),
+ &tca,
+ sizeof(tca)));
+ queue->cwrite_off += sizeof(tca);
+}
/**
* Read from the socket of the proto queue until we have enough data
@@ -1999,6 +2529,11 @@ proto_read_kx (void *cls)
queue->listen_task = pq->listen_task;
queue->listen_sock = pq->listen_sock;
queue->sock = pq->sock;
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "start kx proto\n");
+
start_initial_kx_out (queue);
boot_queue (queue, GNUNET_TRANSPORT_CS_INBOUND);
queue->read_task =
@@ -2011,6 +2546,8 @@ proto_read_kx (void *cls)
queue->sock,
&queue_write,
queue);
+ send_challenge (tc, queue);
+
GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
GNUNET_free (pq);
}
@@ -2134,7 +2671,7 @@ queue_read_kx (void *cls)
queue_destroy (queue);
return;
}
-
+ send_challenge (tc, queue);
/* update queue timeout */
reschedule_queue_timeout (queue);
/* prepare to continue with regular read task immediately */
@@ -2146,7 +2683,6 @@ queue_read_kx (void *cls)
queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
}
-
/**
* Function called by the transport service to initialize a
* message queue given address information about another peer.
@@ -2227,6 +2763,11 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
queue->sock,
&queue_read_kx,
queue);
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "start kx mq_init\n");
+
start_initial_kx_out (queue);
queue->write_task =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -2236,7 +2777,6 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
return GNUNET_OK;
}
-
/**
* Iterator over all message queues to clean up.
*
@@ -2346,10 +2886,6 @@ nat_address_cb (void *cls,
char *my_addr;
struct GNUNET_TRANSPORT_AddressIdentifier *ai;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "1 nat_address %s\n",
- GNUNET_a2s (addr, addrlen));
-
if (GNUNET_YES == add_remove)
{
enum GNUNET_NetworkType nt;
@@ -2375,7 +2911,6 @@ nat_address_cb (void *cls,
}
}
-
/**
* This method launch network interactions for each address we like to bind to.
*
@@ -2399,10 +2934,6 @@ init_socket (const struct sockaddr *addr,
return GNUNET_SYSERR;
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "4 address %s\n",
- GNUNET_a2s (addr, in_len));
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"address %s\n",
GNUNET_a2s (addr, in_len));
@@ -2465,7 +2996,8 @@ init_socket (const struct sockaddr *addr,
GNUNET_ERROR_TYPE_ERROR,
_ (
"Transport service is lacking key configuration settings. Exiting.\n"));
- GNUNET_RESOLVER_request_cancel (resolve_request_handle);
+ if (NULL != resolve_request_handle)
+ GNUNET_RESOLVER_request_cancel (resolve_request_handle);
GNUNET_SCHEDULER_shutdown ();
return GNUNET_SYSERR;
}
@@ -2483,7 +3015,7 @@ init_socket (const struct sockaddr *addr,
if (NULL == queue_map)
queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
- if (NULL == ch)
+ if (NULL == ch )
ch = GNUNET_TRANSPORT_communicator_connect (cfg,
COMMUNICATOR_CONFIG_SECTION,
COMMUNICATOR_ADDRESS_PREFIX,
@@ -2496,7 +3028,8 @@ init_socket (const struct sockaddr *addr,
if (NULL == ch)
{
GNUNET_break (0);
- GNUNET_RESOLVER_request_cancel (resolve_request_handle);
+ if (NULL != resolve_request_handle)
+ GNUNET_RESOLVER_request_cancel (resolve_request_handle);
GNUNET_SCHEDULER_shutdown ();
return GNUNET_SYSERR;
}
@@ -2505,7 +3038,6 @@ init_socket (const struct sockaddr *addr,
}
-
/**
* This method reads from the DLL addrs_head to register them at the NAT service.
*/
@@ -2518,35 +3050,20 @@ nat_register ()
int i;
struct Addresses *pos;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "nat here\n");
-
i = 0;
saddrs = GNUNET_malloc ((addrs_lens + 1) * sizeof(struct sockaddr *));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "2 nat here\n");
-
saddr_lens = GNUNET_malloc ((addrs_lens + 1) * sizeof(socklen_t));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "3 nat here\n");
-
for (pos = addrs_head; NULL != pos; pos = pos->next)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "5 nat here\n");
-
saddr_lens[i] = addrs_head->addr_len;
saddrs[i] = GNUNET_malloc (saddr_lens[i]);
saddrs[i] = addrs_head->addr;
i++;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "6 nat here\n");
-
}
nat = GNUNET_NAT_register (cfg,
@@ -2559,15 +3076,22 @@ nat_register ()
NULL /* FIXME: support reversal: #5529 */,
NULL /* closure */);
+ i = 0;
+
+ /*for (i = addrs_lens - 1; i >= 0; i--)
+ GNUNET_free (saddrs[i]);*/
+ GNUNET_free (saddrs);
+ GNUNET_free (saddr_lens);
+
if (NULL == nat)
{
GNUNET_break (0);
- GNUNET_RESOLVER_request_cancel (resolve_request_handle);
+ if (NULL != resolve_request_handle)
+ GNUNET_RESOLVER_request_cancel (resolve_request_handle);
GNUNET_SCHEDULER_shutdown ();
}
}
-
/**
* This method adds addresses to the DLL, that are later register at the NAT service.
*/
@@ -2584,7 +3108,6 @@ add_addr (struct sockaddr *in, socklen_t in_len)
addrs_lens++;
}
-
/**
* This method is the callback called by the resolver API, and wraps method init_socket.
*
@@ -2637,7 +3160,6 @@ init_socket_resolv (void *cls,
}
}
-
/**
* Setup communicator and launch network interactions.
*
@@ -2662,6 +3184,8 @@ run (void *cls,
char dummy[2];
char *rest = NULL;
struct PortOnlyIpv4Ipv6 *po;
+ socklen_t addr_len_ipv4;
+ socklen_t addr_len_ipv6;
(void) cls;
cfg = c;
@@ -2689,6 +3213,13 @@ run (void *cls,
&rekey_interval))
rekey_interval = DEFAULT_REKEY_INTERVAL;
+ peerstore = GNUNET_PEERSTORE_connect (cfg);
+ if (NULL == peerstore)
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
// cp = GNUNET_strdup (bindto);
start = extract_address (bindto);
@@ -2697,16 +3228,24 @@ run (void *cls,
{
po = tcp_address_to_sockaddr_port_only (bindto, &port);
- if (NULL != &po->addr_ipv4)
+ addr_len_ipv4 = po->addr_len_ipv4;
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "address po %s\n",
+ GNUNET_a2s (po->addr_ipv4, addr_len_ipv4));
+
+ if (NULL != po->addr_ipv4)
{
- init_socket (po->addr_ipv4, *po->addr_len_ipv4);
- add_addr (po->addr_ipv4, *po->addr_len_ipv4);
+ init_socket (po->addr_ipv4, addr_len_ipv4);
+ add_addr (po->addr_ipv4, addr_len_ipv4);
}
- if (NULL != &po->addr_ipv6)
+ if (NULL != po->addr_ipv6)
{
- init_socket (po->addr_ipv6, *po->addr_len_ipv6);
- add_addr (po->addr_ipv6, *po->addr_len_ipv6);
+ addr_len_ipv6 = po->addr_len_ipv6;
+ init_socket (po->addr_ipv6, addr_len_ipv6);
+ add_addr (po->addr_ipv6, addr_len_ipv6);
}
nat_register ();
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 5f3178939..baefdfa88 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -329,19 +329,6 @@ struct AcknowledgementUUIDP
struct GNUNET_Uuid value;
};
-
-/**
- * Type of a nonce used for challenges.
- */
-struct ChallengeNonceP
-{
- /**
- * The value of the nonce. Note that this is NOT a hash.
- */
- struct GNUNET_ShortHashCode value;
-};
-
-
/**
* Outer layer of an encapsulated backchannel message.
*/
diff --git a/src/transport/test_communicator_basic.c b/src/transport/test_communicator_basic.c
index 45c268684..e2d2eb73c 100644
--- a/src/transport/test_communicator_basic.c
+++ b/src/transport/test_communicator_basic.c
@@ -587,6 +587,7 @@ main (int argc,
GNUNET_asprintf (&communicator_binary,
"gnunet-communicator-%s",
communicator_name);
+
if (GNUNET_OK !=
GNUNET_log_setup ("test_communicator_basic",
"DEBUG",
@@ -645,6 +646,21 @@ main (int argc,
GNUNET_i2s_full (&peer_id[i]));
}
LOG (GNUNET_ERROR_TYPE_MESSAGE, "Starting test...\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "argv[0]: %s\n",
+ argv[0]);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "test_name: %s\n",
+ test_name);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "communicator_name: %s\n",
+ communicator_name);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "communicator_binary: %s\n",
+ communicator_binary);
+
GNUNET_SCHEDULER_run (&run,
NULL);
return ret;
diff --git a/src/transport/test_communicator_tcp_basic_peer1.conf b/src/transport/test_communicator_tcp_basic_peer1.conf
index d0293ff51..c08737b7b 100644
--- a/src/transport/test_communicator_tcp_basic_peer1.conf
+++ b/src/transport/test_communicator_tcp_basic_peer1.conf
@@ -19,10 +19,15 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock
[communicator-tcp]
+#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
+#PREFIX = valgrind --leak-check=full --track-origins=yes
BINDTO = 60002
DISABLE_V6 = NO
diff --git a/src/transport/test_communicator_tcp_basic_peer2.conf b/src/transport/test_communicator_tcp_basic_peer2.conf
index 5b9050547..45b7e7844 100644
--- a/src/transport/test_communicator_tcp_basic_peer2.conf
+++ b/src/transport/test_communicator_tcp_basic_peer2.conf
@@ -20,10 +20,15 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_2.sock
[communicator-tcp]
+#PREFIX = xterm -geometry 100x85 -T peer2 -e gdb --args
+#PREFIX = valgrind --leak-check=full --track-origins=yes
BINDTO = 60003
DISABLE_V6 = NO
diff --git a/src/transport/test_communicator_tcp_rekey_peer1.conf b/src/transport/test_communicator_tcp_rekey_peer1.conf
index 18028cd48..901f415ef 100644
--- a/src/transport/test_communicator_tcp_rekey_peer1.conf
+++ b/src/transport/test_communicator_tcp_rekey_peer1.conf
@@ -20,10 +20,19 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
ENABLE_IPSCAN = YES
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
+[resolver]
+PORT = 62089
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock
[communicator-tcp]
+#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
+#PREFIX = valgrind --leak-check=full --track-origins=yes
BINDTO = 60002
DISABLE_V6 = YES
REKEY_INTERVAL = 100ms
diff --git a/src/transport/test_communicator_tcp_rekey_peer2.conf b/src/transport/test_communicator_tcp_rekey_peer2.conf
index 7d7179578..138650a3b 100644
--- a/src/transport/test_communicator_tcp_rekey_peer2.conf
+++ b/src/transport/test_communicator_tcp_rekey_peer2.conf
@@ -20,10 +20,19 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
+[resolver]
+PORT = 62090
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_2.sock
[communicator-tcp]
+#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
+#PREFIX = valgrind --leak-check=full --track-origins=yes
BINDTO = 60003
DISABLE_V6 = YES
REKEY_INTERVAL = 100ms
diff --git a/src/transport/test_communicator_udp_backchannel_peer1.conf b/src/transport/test_communicator_udp_backchannel_peer1.conf
index 0c595b77b..b99a76d6c 100644
--- a/src/transport/test_communicator_udp_backchannel_peer1.conf
+++ b/src/transport/test_communicator_udp_backchannel_peer1.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
ENABLE_IPSCAN = YES
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
+[resolver]
+PORT = 62089
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock
diff --git a/src/transport/test_communicator_udp_backchannel_peer2.conf b/src/transport/test_communicator_udp_backchannel_peer2.conf
index d29f37ec9..48bd54c8b 100644
--- a/src/transport/test_communicator_udp_backchannel_peer2.conf
+++ b/src/transport/test_communicator_udp_backchannel_peer2.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
+[resolver]
+PORT = 62090
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_2.sock
diff --git a/src/transport/test_communicator_udp_basic_peer1.conf b/src/transport/test_communicator_udp_basic_peer1.conf
index 4cfb6f72f..d53a55210 100644
--- a/src/transport/test_communicator_udp_basic_peer1.conf
+++ b/src/transport/test_communicator_udp_basic_peer1.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
ENABLE_IPSCAN = YES
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
+[resolver]
+PORT = 62089
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
+
[communicator-udp]
BINDTO = 60002
DISABLE_V6 = YES
diff --git a/src/transport/test_communicator_udp_basic_peer2.conf b/src/transport/test_communicator_udp_basic_peer2.conf
index b9bed2756..f05ebc5cb 100644
--- a/src/transport/test_communicator_udp_basic_peer2.conf
+++ b/src/transport/test_communicator_udp_basic_peer2.conf
@@ -20,6 +20,14 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
+
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
+[resolver]
+PORT = 62090
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
+
[communicator-udp]
BINDTO = 60003
DISABLE_V6 = YES
diff --git a/src/transport/test_communicator_udp_rekey_peer1.conf b/src/transport/test_communicator_udp_rekey_peer1.conf
index 18028cd48..e7161e488 100644
--- a/src/transport/test_communicator_udp_rekey_peer1.conf
+++ b/src/transport/test_communicator_udp_rekey_peer1.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
ENABLE_IPSCAN = YES
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
+[resolver]
+PORT = 62089
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock
diff --git a/src/transport/test_communicator_udp_rekey_peer2.conf b/src/transport/test_communicator_udp_rekey_peer2.conf
index 7d7179578..8f175a405 100644
--- a/src/transport/test_communicator_udp_rekey_peer2.conf
+++ b/src/transport/test_communicator_udp_rekey_peer2.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
+[resolver]
+PORT = 62090
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_2.sock
diff --git a/src/transport/test_communicator_unix_basic_peer1.conf b/src/transport/test_communicator_unix_basic_peer1.conf
index d50588007..71283e381 100644
--- a/src/transport/test_communicator_unix_basic_peer1.conf
+++ b/src/transport/test_communicator_unix_basic_peer1.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
UNIXPATH = $GNUNET_TMP/communicator-unix-1/nat.sock
ENABLE_IPSCAN = YES
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
+
+[resolver]
+PORT = 62089
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/communicator-unix-1.sock
diff --git a/src/transport/test_communicator_unix_basic_peer2.conf b/src/transport/test_communicator_unix_basic_peer2.conf
index fe27ef1a6..ac95845b2 100644
--- a/src/transport/test_communicator_unix_basic_peer2.conf
+++ b/src/transport/test_communicator_unix_basic_peer2.conf
@@ -20,6 +20,13 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
[nat]
UNIXPATH = $GNUNET_TMP/communicator-unix-2/nat.sock
+[peerstore]
+UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
+
+[resolver]
+PORT = 62090
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
+
[communicator-unix]
UNIXPATH = $GNUNET_RUNTIME_DIR/communicator-unix-2.sock
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
index 772ad9f2d..10b064241 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -114,6 +114,11 @@ struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle
struct GNUNET_OS_Process *resolver_proc;
/**
+ * peerstore service process
+ */
+ struct GNUNET_OS_Process *ps_proc;
+
+ /**
* @brief Task that will be run on shutdown to stop and clean communicator
*/
struct GNUNET_SCHEDULER_Task *c_shutdown_task;
@@ -892,6 +897,12 @@ shutdown_process (struct GNUNET_OS_Process *proc)
GNUNET_OS_process_destroy (proc);
}
+static void
+shutdown_peerstore (void *cls)
+{
+ struct GNUNET_OS_Process *proc = cls;
+ shutdown_process (proc);
+}
static void
shutdown_communicator (void *cls)
@@ -912,19 +923,31 @@ communicator_start (
const char *binary_name)
{
char *binary;
+ char *loprefix;
+ char *section_name;
LOG (GNUNET_ERROR_TYPE_DEBUG, "communicator_start\n");
+
+ section_name = strchr (binary_name, '-');
+ section_name++;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (tc_h->cfg,
+ section_name,
+ "PREFIX",
+ &loprefix))
+ loprefix = GNUNET_strdup ("");
+
+
binary = GNUNET_OS_get_libexec_binary_path (binary_name);
- tc_h->c_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR
- | GNUNET_OS_USE_PIPE_CONTROL,
- NULL,
- NULL,
- NULL,
- binary,
- binary_name,
- "-c",
- tc_h->cfg_filename,
- NULL);
+ tc_h->c_proc = GNUNET_OS_start_process_s (GNUNET_YES,
+ GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+ NULL,
+ loprefix,
+ binary,
+ binary_name,
+ "-c",
+ tc_h->cfg_filename,
+ NULL);
if (NULL == tc_h->c_proc)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start communicator!");
@@ -992,6 +1015,37 @@ resolver_start (struct
/**
+ * @brief Start Peerstore
+ *
+ */
+static void
+peerstore_start (
+ struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h)
+{
+ char *binary;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start\n");
+ binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-peerstore");
+ tc_h->ps_proc = GNUNET_OS_start_process (GNUNET_YES,
+ GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+ NULL,
+ NULL,
+ NULL,
+ binary,
+ "gnunet-service-peerstore",
+ "-c",
+ tc_h->cfg_filename,
+ NULL);
+ if (NULL == tc_h->ps_proc)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start Peerstore!");
+ return;
+ }
+ LOG (GNUNET_ERROR_TYPE_INFO, "started Peerstore\n");
+ GNUNET_free (binary);
+}
+
+/**
* @brief Start NAT
*
*/
@@ -1087,6 +1141,8 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_service_start (
nat_start (tc_h);
/* Start resolver service */
resolver_start (tc_h);
+ /* Start peerstore service */
+ peerstore_start (tc_h);
/* Schedule start communicator */
communicator_start (tc_h,
binary_name);
@@ -1102,6 +1158,7 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop (
shutdown_service (tc_h->sh);
shutdown_nat (tc_h->nat_proc);
shutdown_resolver (tc_h->resolver_proc);
+ shutdown_peerstore (tc_h->ps_proc);
GNUNET_CONFIGURATION_destroy (tc_h->cfg);
GNUNET_free (tc_h);
}
diff --git a/src/util/buffer.c b/src/util/buffer.c
index d0261889e..8fb10c2a5 100644
--- a/src/util/buffer.c
+++ b/src/util/buffer.c
@@ -248,3 +248,35 @@ GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
buf->position += res;
GNUNET_assert (buf->position <= buf->capacity);
}
+
+
+/**
+ * Write data encoded via #GNUNET_STRINGS_data_to_string to the buffer.
+ *
+ * Grows the buffer if necessary.
+ *
+ * @param buf buffer to write to
+ * @param data data to read from
+ * @param len number of bytes to copy from @a data to @a buf
+ */
+void
+GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf,
+ const char *data,
+ size_t len)
+{
+ size_t outlen = len * 8;
+
+ if (outlen % 5 > 0)
+ outlen += 5 - outlen % 5;
+ outlen /= 5;
+
+ GNUNET_buffer_ensure_remaining (buf, outlen);
+ GNUNET_assert (NULL !=
+ GNUNET_STRINGS_data_to_string (data,
+ len,
+ (buf->mem +
+ buf->position),
+ outlen));
+ buf->position += outlen;
+ GNUNET_assert (buf->position <= buf->capacity);
+}
diff --git a/src/util/disk.c b/src/util/disk.c
index 6560726ea..c95e9753c 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -1377,14 +1377,13 @@ GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
enum GNUNET_DISK_MapType access,
size_t len)
{
+ int prot;
+
if (NULL == h)
{
errno = EINVAL;
return NULL;
}
-
- int prot;
-
prot = 0;
if (access & GNUNET_DISK_MAP_TYPE_READ)
prot = PROT_READ;
@@ -1405,22 +1404,21 @@ GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
/**
* Unmap a file
+ *
* @param h mapping handle
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h)
{
int ret;
- if (h == NULL)
+ if (NULL == h)
{
errno = EINVAL;
return GNUNET_SYSERR;
}
-
ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
-
GNUNET_free (h);
return ret;
}
@@ -1429,7 +1427,7 @@ GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h)
/**
* Write file changes to disk
* @param h handle to an open file
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)