GNUnet 0.28.0-dev.2-27-gc87478450
 
Loading...
Searching...
No Matches
gnunet-service-cadet_tunnels.c File Reference

Information we track per tunnel. More...

Include dependency graph for gnunet-service-cadet_tunnels.c:

Go to the source code of this file.

Data Structures

struct  CadetTunnelSkippedKey
 Struct to old keys for skipped messages while advancing the Axolotl ratchet. More...
 
struct  CadetTunnelAxolotl
 Axolotl data, according to https://github.com/trevp/axolotl/wiki . More...
 
struct  CadetTunnelAsync
 Struct used to store data required for an async update AX by KX process. More...
 
struct  CadetTunnelQueueEntry
 Struct used to save messages in a non-ready tunnel to send once connected. More...
 
struct  CadetTunnel
 Struct containing all information regarding a tunnel to a peer. More...
 
struct  EvaluationSummary
 Closure for evaluate_connection. More...
 
struct  ChanIterCls
 Closure for iterate_channels_cb. More...
 

Macros

#define LOG(level, ...)   GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
 
#define MAX_UNVERIFIED_ATTEMPTS   16
 How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon receiving bogus KX.
 
#define IDLE_DESTROY_DELAY
 How long do we wait until tearing down an idle tunnel?
 
#define INITIAL_KX_RETRY_DELAY
 How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have connection-level RTT data!
 
#define MAX_SKIPPED_KEYS   64
 Maximum number of skipped keys we keep in memory per tunnel.
 
#define MAX_KEY_GAP   256
 Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is either a bogus packet or a DoS-attempt.
 
#define HIGH_BIT   0x8000000
 
#define LOG2(level, ...)
 

Typedefs

typedef void(* CadetTunnelAxolotlCallback) (void *cls, enum GNUNET_GenericReturnValue res)
 Signature of the follow up function from an udate AX by KX.
 

Functions

int GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
 Am I Alice or Betty (some call her Bob), or talking to myself?
 
static void mark_connection_unready (struct CadetTConnection *ct)
 Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
 
const char * GCT_2s (const struct CadetTunnel *t)
 Get the static string for the peer this tunnel is directed.
 
static const char * estate2s (enum CadetTunnelEState es)
 Get string description for tunnel encryption state.
 
struct CadetPeerGCT_get_destination (struct CadetTunnel *t)
 Return the peer to which this tunnel goes.
 
unsigned int GCT_count_channels (struct CadetTunnel *t)
 Returns the number of channels using a tunnel.
 
static struct CadetChannellookup_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Lookup a channel by its ctn.
 
unsigned int GCT_count_any_connections (const struct CadetTunnel *t)
 Counts the number of connections created for a tunnel, including busy connections.
 
static struct CadetTConnectionget_ready_connection (struct CadetTunnel *t)
 Find first connection that is ready in the list of our connections.
 
enum CadetTunnelEState GCT_get_estate (struct CadetTunnel *t)
 Get the encryption state of a tunnel.
 
static void trigger_transmissions (void *cls)
 Called when either we have a new connection, or a new message in the queue, or some existing connection has transmission capacity.
 
static void new_ephemeral (struct CadetTunnelAxolotl *ax)
 Create a new Axolotl ephemeral (ratchet) key.
 
static void t_ax_hmac_hash (const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
 Perform a HMAC.
 
static void t_hmac_derive_key (const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_CRYPTO_AeadSecretKey *out, const void *source, unsigned int len)
 Derive a symmetric encryption key from an HMAC-HASH.
 
static void t_ax_encrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Encrypt data with the axolotl tunnel key.
 
static void t_ax_decrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Decrypt data with the axolotl tunnel key.
 
static void t_h_encrypt (struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg, size_t additional_data_size, const unsigned char *additional_data)
 Encrypt header with the axolotl header key.
 
static enum GNUNET_GenericReturnValue t_h_decrypt (const struct GNUNET_CRYPTO_AeadSecretKey *hkr, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t esize, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
 Decrypt header with the current axolotl header key.
 
static void delete_skipped_key (struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
 Delete a key from the list of skipped keys.
 
static ssize_t try_old_ax_keys (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.
 
static void store_skipped_key (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
 Delete a key from the list of skipped keys.
 
static int store_ax_keys (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr, uint32_t Np)
 Stage skipped AX keys and calculate the message key.
 
static ssize_t t_ax_decrypt_and_validate (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.
 
static int notify_tunnel_up_cb (void *cls, uint32_t key, void *value)
 Our tunnel became ready for the first time, notify channels that have been waiting.
 
void GCT_change_estate (struct CadetTunnel *t, enum CadetTunnelEState state)
 Change the tunnel encryption state.
 
static void send_kx (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
 Send a KX message.
 
static void send_kx_auth (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
 Send a KX_AUTH message.
 
static void cleanup_ax (struct CadetTunnelAxolotl *ax)
 Cleanup state used by ax.
 
static void update_ax_by_kx (void *cls, const struct GNUNET_HashCode *key_result)
 Update our Axolotl key state based on the KX data we received.
 
static void retry_kx (void *cls)
 Try to redo the KX or KX_AUTH handshake, if we can.
 
static void cont_GCT_handle_kx (void *cls, enum GNUNET_GenericReturnValue ret)
 Continue to handle KX message.
 
void GCT_handle_kx (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
 Continue to handle KX message.
 
static void cont_GCT_handle_kx_auth (void *cls, enum GNUNET_GenericReturnValue ret)
 Continue to handle KX_AUTH message.
 
void GCT_handle_kx_auth (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
 Handle KX_AUTH message.
 
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn (struct CadetTunnel *t)
 Compute the next free channel tunnel number for this tunnel.
 
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch)
 Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up.
 
void GCT_connection_lost (struct CadetTConnection *ct)
 We lost a connection, remove it from our list and clean up the connection object itself.
 
static void destroy_t_connection (void *cls, struct CadetTConnection *ct)
 Clean up connection ct of a tunnel.
 
static void destroy_tunnel (void *cls)
 This tunnel is no longer used, destroy it.
 
void GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Remove a channel from a tunnel.
 
static int destroy_remaining_channels (void *cls, uint32_t key, void *value)
 Destroy remaining channels during shutdown.
 
void GCT_destroy_tunnel_now (struct CadetTunnel *t)
 Destroys the tunnel t now, without delay.
 
static void try_send_normal_payload (struct CadetTunnel *t, struct CadetTConnection *ct)
 Send normal payload from queue in t via connection ct.
 
static void connection_ready_cb (void *cls, int is_ready)
 A connection is is_ready for transmission.
 
static void evaluate_connection (void *cls, struct CadetTConnection *ct)
 Evaluate a connection, updating our summary information in cls about what kinds of connections we have.
 
static int consider_path_cb (void *cls, struct CadetPeerPath *path, unsigned int off)
 Consider using the path p for the tunnel t.
 
static void maintain_connections_cb (void *cls)
 Function called to maintain the connections underlying our tunnel.
 
void GCT_consider_path (struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
 Consider using the path p for the tunnel t.
 
static void handle_plaintext_keepalive (void *cls, const struct GNUNET_MessageHeader *msg)
 We got a keepalive.
 
static int check_plaintext_data (void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
 Check that msg is well-formed.
 
static void handle_plaintext_data (void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
 We received payload data for a channel.
 
static void handle_plaintext_data_ack (void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
 We received an acknowledgement for data we sent on a channel.
 
static void handle_plaintext_channel_open (void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
 We have received a request to open a channel to a port from another peer.
 
void GCT_send_channel_destroy (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Send a DESTROY message via the tunnel.
 
static void handle_plaintext_channel_open_ack (void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
 We have received confirmation from the target peer that the given channel could be established (the port is open).
 
static void handle_plaintext_channel_destroy (void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
 We received a message saying that a channel should be destroyed.
 
static int handle_decrypted (void *cls, const struct GNUNET_MessageHeader *msg)
 Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching).
 
static void decrypted_error_cb (void *cls, enum GNUNET_MQ_Error error)
 Function called if we had an error processing an incoming decrypted message.
 
struct CadetTunnelGCT_create_tunnel (struct CadetPeer *destination)
 Create a tunnel to destination.
 
int GCT_add_inbound_connection (struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
 Add a connection to the tunnel.
 
void GCT_handle_encrypted (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
 Handle encrypted message.
 
struct CadetTunnelQueueEntryGCT_send (struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
 Sends an already built message on a tunnel, encrypting it and choosing the best connection if not provided.
 
void GCT_send_cancel (struct CadetTunnelQueueEntry *tq)
 Cancel a previously sent message while it's in the queue.
 
void GCT_iterate_connections (struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
 Iterate over all connections of a tunnel.
 
static int iterate_channels_cb (void *cls, uint32_t key, void *value)
 Helper function for GCT_iterate_channels.
 
void GCT_iterate_channels (struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
 Iterate over all channels of a tunnel.
 
static int debug_channel (void *cls, uint32_t key, void *value)
 Call GCCH_debug() on a channel.
 
void GCT_debug (const struct CadetTunnel *t, enum GNUNET_ErrorType level)
 Log all possible info about the tunnel state.
 

Detailed Description

Information we track per tunnel.

Author
Bartlomiej Polot
Christian Grothoff

FIXME:

  • proper connection evaluation during connection management:
    • consider quality (or quality spread?) of current connection set when deciding how often to do maintenance
    • interact with PEER to drive DHT GET/PUT operations based on how much we like our connections

Definition in file gnunet-service-cadet_tunnels.c.

Macro Definition Documentation

◆ LOG

#define LOG (   level,
  ... 
)    GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)

Definition at line 47 of file gnunet-service-cadet_tunnels.c.

◆ MAX_UNVERIFIED_ATTEMPTS

#define MAX_UNVERIFIED_ATTEMPTS   16

How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon receiving bogus KX.

Definition at line 54 of file gnunet-service-cadet_tunnels.c.

◆ IDLE_DESTROY_DELAY

#define IDLE_DESTROY_DELAY
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How long do we wait until tearing down an idle tunnel?

Definition at line 59 of file gnunet-service-cadet_tunnels.c.

84{
89
94
99
104
109
113 unsigned int Kn;
114};
115
116
121{
128
133
138
143
148
155
162
168
176
181
186
191
197
203
207 unsigned int skipped;
208
212 uint32_t Ns;
213
217 uint32_t Nr;
218
222 uint32_t PNs;
223
227 int ratchet_flag;
228
239 int ratchet_allowed;
240
253 unsigned int ratchet_counter;
254};
255
256
263typedef void
264(*CadetTunnelAxolotlCallback) (void *cls,
266
267
271struct CadetTunnelAsync
272{
276 struct CadetTunnelAxolotl ax;
277
282
287
292
297 struct GNUNET_HashCode auth;
298
303 uint32_t flags;
304
309
313 void *cb_cls;
314
319};
320
321
326{
331
336
340 struct CadetTunnel *t;
341
346
350 void *cont_cls;
351
355 struct GNUNET_MQ_Envelope *env;
356
362};
363
364
368struct CadetTunnel
369{
373 struct CadetPeer *destination;
374
380
385
390
394 struct CadetTunnelAxolotl ax;
395
404
408 struct CadetTunnelAsync as;
409
414
419
424
429
434
438 struct GNUNET_MQ_Handle *mq;
439
444
449
454
459
465
470
475
480
487
492
497
501 unsigned int num_ready_connections;
502
506 unsigned int num_busy_connections;
507
513 unsigned int unverified_attempts;
514
518 unsigned int tq_len;
519
524
529};
530
531
538int
539GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
540{
541 const struct GNUNET_PeerIdentity *my_identity;
542
545
546 if (0 > GNUNET_memcmp (my_identity, other))
547 return GNUNET_YES;
548 else if (0 < GNUNET_memcmp (my_identity, other))
549 return GNUNET_NO;
550 else
551 {
552 GNUNET_break_op (0);
553 return GNUNET_SYSERR;
554 }
555}
556
557
564static void
566{
567 struct CadetTunnel *t = ct->t;
568
570 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
571 t->connection_ready_tail,
572 ct);
573 GNUNET_assert (0 < t->num_ready_connections);
574 t->num_ready_connections--;
575 ct->is_ready = GNUNET_NO;
576 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
577 t->connection_busy_tail,
578 ct);
579 t->num_busy_connections++;
580}
581
582
590const char *
591GCT_2s (const struct CadetTunnel *t)
592{
593 static char buf[64];
594
595 if (NULL == t)
596 return "Tunnel(NULL)";
597 GNUNET_snprintf (buf,
598 sizeof(buf),
599 "Tunnel %s",
600 GNUNET_i2s (GCP_get_id (t->destination)));
601 return buf;
602}
603
604
612static const char *
614{
615 static char buf[32];
616
617 switch (es)
618 {
620 return "CADET_TUNNEL_KEY_UNINITIALIZED";
622 return "CADET_TUNNEL_KEY_AX_RECV";
624 return "CADET_TUNNEL_KEY_AX_SENT";
626 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
628 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
630 return "CADET_TUNNEL_KEY_OK";
631 }
632 GNUNET_snprintf (buf,
633 sizeof(buf),
634 "%u (UNKNOWN STATE)",
635 es);
636 return buf;
637}
638
639
646struct CadetPeer *
648{
649 return t->destination;
650}
651
652
653unsigned int
655{
656 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
657}
658
659
667static struct CadetChannel *
670{
671 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
672 ntohl (ctn.cn));
673}
674
675
676unsigned int
678{
679 return t->num_ready_connections + t->num_busy_connections;
680}
681
682
690static struct CadetTConnection *
692{
693 struct CadetTConnection *hd = t->connection_ready_head;
694
695 GNUNET_assert ((NULL == hd) ||
696 (GNUNET_YES == hd->is_ready));
697 return hd;
698}
699
700
710{
711 return t->estate;
712}
713
714
723static void
724trigger_transmissions (void *cls);
725
726
727/* ************************************** start core crypto ***************************** */
728
729
735static void
737{
739 "Creating new ephemeral ratchet key (DHRs)\n");
741}
742
743
752static void
754 struct GNUNET_HashCode *hash,
755 const void *source,
756 unsigned int len)
757{
758 static const char ctx[] = "axolotl HMAC-HASH";
759 struct GNUNET_CRYPTO_AuthKey auth_key;
760
762 &auth_key,
763 sizeof auth_key,
764 ctx,
765 sizeof(ctx),
766 key,
767 sizeof *key);
768 GNUNET_CRYPTO_hmac (&auth_key,
769 source,
770 len,
771 hash);
772}
773
774
783static void
785 struct GNUNET_CRYPTO_AeadSecretKey *out,
786 const void *source,
787 unsigned int len)
788{
789 static const char ctx[] = "axolotl derive key";
790 struct GNUNET_HashCode h;
791
793 &h,
794 source,
795 len);
797 out, sizeof(*out),
798 ctx, sizeof(ctx),
799 &h, sizeof(h));
800}
801
802
811static void
813 void *dst,
814 const void *src,
815 size_t size)
816{
818 struct GNUNET_CRYPTO_AeadNonce iv;
820
821 ax->ratchet_counter++;
822 if ((GNUNET_YES == ax->ratchet_allowed) &&
823 ((ratchet_messages <= ax->ratchet_counter) ||
826 {
828 }
829 if (GNUNET_YES == ax->ratchet_flag)
830 {
831 /* Advance ratchet */
832 struct GNUNET_CRYPTO_AeadSecretKey keys[3];
833 struct GNUNET_HashCode dh;
834 struct GNUNET_HashCode hmac;
835 static const char ctx[] = "axolotl ratchet";
836
837 new_ephemeral (ax);
838 ax->HKs = ax->NHKs;
839
840 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
842 &ax->DHRr,
843 &dh);
844 t_ax_hmac_hash (&ax->RK,
845 &hmac,
846 &dh,
847 sizeof(dh));
849 keys, sizeof(keys),
850 ctx, sizeof(ctx),
851 &hmac, sizeof(hmac));
852 ax->RK = keys[0];
853 ax->NHKs = keys[1];
854 ax->CKs = keys[2];
855
856 ax->PNs = ax->Ns;
857 ax->Ns = 0;
860 ax->ratchet_counter = 0;
864 }
865
867 &MK,
868 "0",
869 1);
870
872 sizeof iv,
873 NULL,
874 0,
875 &MK,
876 sizeof MK);
877
878 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) dst)[size];
880 src,
881 0,
882 NULL,
883 &MK,
884 &iv,
885 dst,
886 mac));
888 &ax->CKs,
889 "1",
890 1);
891}
892
893
902static void
904 void *dst,
905 const void *src,
906 size_t size)
907{
909 struct GNUNET_CRYPTO_AeadNonce iv;
911 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
912
914 &MK,
915 "0",
916 1);
917
919 sizeof iv,
920 NULL,
921 0,
922 &MK,
923 sizeof MK);
924 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
925 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) src)[macoffset];
927 src,
928 0,
929 NULL,
930 &MK,
931 &iv,
932 mac,
933 dst));
935 &ax->CKr,
936 "1",
937 1);
938}
939
940
947static void
950 size_t additional_data_size,
951 const unsigned char *additional_data)
952{
953 struct GNUNET_CRYPTO_AeadNonce nonce;
954
956 sizeof nonce,
957 NULL,
958 0,
959 &ax->HKs,
960 sizeof ax->HKs);
962 ,
963 (unsigned char*) &msg
964 ->ax_header,
965 additional_data_size,
966 additional_data,
967 &ax->HKs,
968 &nonce,
969 &msg->ax_header,
970 &msg->mac));
971}
972
973
985 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
986 size_t esize,
988{
989 struct GNUNET_CRYPTO_AeadNonce iv;
990
992 sizeof iv,
993 NULL,
994 0,
995 hkr,
996 sizeof *hkr);
997
998
1000 (unsigned char*) &src->ax_header,
1001 esize,
1002 (unsigned char*) &src[1],
1003 hkr,
1004 &iv,
1005 &dst->mac,
1006 &dst->ax_header);
1007}
1008
1009
1016static void
1018 struct CadetTunnelSkippedKey *key)
1019{
1021 ax->skipped_tail,
1022 key);
1023 GNUNET_free (key);
1024 ax->skipped--;
1025}
1026
1027
1038static ssize_t
1040 void *dst,
1041 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1042 size_t size)
1043{
1044 struct CadetTunnelSkippedKey *key;
1045 struct GNUNET_CRYPTO_AeadNonce iv;
1046 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1047 struct GNUNET_CRYPTO_AeadSecretKey *valid_HK;
1048 size_t esize;
1049 size_t len;
1050 unsigned int N;
1051 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
1052
1054 "Trying skipped keys\n");
1055 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1056 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1058 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1059 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1060
1061 /* Find a correct Header Key */
1062 valid_HK = NULL;
1063 for (key = ax->skipped_head; NULL != key; key = key->next)
1064 {
1065 /* Try decrypt header */
1066 if (GNUNET_OK == t_h_decrypt (&key->HK,
1067 src,
1068 esize,
1069 &plaintext_header))
1070 {
1071 valid_HK = &key->HK;
1072 }
1073 }
1074 if (NULL == key)
1075 return -1;
1076
1077 /* Find the correct message key */
1078 N = ntohl (plaintext_header.ax_header.Ns);
1079 while ((NULL != key) &&
1080 (N != key->Kn))
1081 key = key->next;
1082 if ((NULL == key) ||
1083 (0 != GNUNET_memcmp (&key->HK,
1084 valid_HK)))
1085 return -1;
1086
1087 /* Decrypt payload */
1089 sizeof iv,
1090 NULL,
1091 0,
1092 &key->MK,
1093 sizeof key->MK);
1094
1096 len,
1097 (unsigned char*) &src[1],
1098 0,
1099 NULL,
1100 &key->MK,
1101 &iv,
1102 (struct GNUNET_CRYPTO_AeadMac*) &src[macoffset],
1103 dst))
1104 {
1105 return -1;
1106 }
1108 key);
1109 return len - sizeof (struct GNUNET_CRYPTO_AeadMac);
1110}
1111
1112
1119static void
1121 const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
1122{
1123 struct CadetTunnelSkippedKey *key;
1124
1126 key->timestamp = GNUNET_TIME_absolute_get ();
1127 key->Kn = ax->Nr;
1128 key->HK = ax->HKr;
1129 t_hmac_derive_key (&ax->CKr,
1130 &key->MK,
1131 "0",
1132 1);
1133 t_hmac_derive_key (&ax->CKr,
1134 &ax->CKr,
1135 "1",
1136 1);
1138 ax->skipped_tail,
1139 key);
1140 ax->skipped++;
1141 ax->Nr++;
1142}
1143
1144
1155static int
1157 const struct GNUNET_CRYPTO_AeadSecretKey *HKr,
1158 uint32_t Np)
1159{
1160 int gap;
1161
1162 gap = Np - ax->Nr;
1164 "Storing skipped keys [%u, %u)\n",
1165 ax->Nr,
1166 Np);
1167 if (MAX_KEY_GAP < gap)
1168 {
1169 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1170 /* TODO: start new key exchange on return */
1171 GNUNET_break_op (0);
1173 "Got message %u, expected %u+\n",
1174 Np,
1175 ax->Nr);
1176 return GNUNET_SYSERR;
1177 }
1178 if (0 > gap)
1179 {
1180 /* Delayed message: don't store keys, flag to try old keys. */
1181 return GNUNET_SYSERR;
1182 }
1183
1184 while (ax->Nr < Np)
1186 HKr);
1187
1188 while (ax->skipped > MAX_SKIPPED_KEYS)
1190 ax->skipped_tail);
1191 return GNUNET_OK;
1192}
1193
1194
1205static ssize_t
1207 void *dst,
1208 const struct
1210 size_t size)
1211{
1212 struct GNUNET_HashCode hmac;
1213 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1214 uint32_t Np;
1215 uint32_t PNp;
1216 size_t esize; /* Size of encrypted payload */
1217
1218 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1219
1220 if (GNUNET_OK == t_h_decrypt (&ax->HKr,
1221 src,
1222 esize,
1223 &plaintext_header))
1224 {
1225 Np = ntohl (plaintext_header.ax_header.Ns);
1226 PNp = ntohl (plaintext_header.ax_header.PNs);
1227 }
1228 else
1229 {
1230 static const char ctx[] = "axolotl ratchet";
1231 struct GNUNET_CRYPTO_AeadSecretKey keys[3]; /* RKp, NHKp, CKp */
1233 struct GNUNET_HashCode dh;
1234 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1235
1236 /* Try Next HK */
1237 if (GNUNET_OK == t_h_decrypt (&ax->NHKr,
1238 src,
1239 esize,
1240 &plaintext_header))
1241 {
1242 /* Try the skipped keys, if that fails, we're out of luck. */
1243 return try_old_ax_keys (ax,
1244 dst,
1245 src,
1246 size);
1247 }
1248 HK = ax->HKr;
1249 ax->HKr = ax->NHKr;
1250 Np = ntohl (plaintext_header.ax_header.Ns);
1251 PNp = ntohl (plaintext_header.ax_header.PNs);
1252 DHRp = &plaintext_header.ax_header.DHRs;
1253 store_ax_keys (ax,
1254 &HK,
1255 PNp);
1256
1257 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1259 DHRp,
1260 &dh);
1261 t_ax_hmac_hash (&ax->RK,
1262 &hmac,
1263 &dh, sizeof(dh));
1265 keys, sizeof(keys),
1266 ctx, sizeof(ctx),
1267 &hmac, sizeof(hmac));
1268
1269 /* Commit "purported" keys */
1270 ax->RK = keys[0];
1271 ax->NHKr = keys[1];
1272 ax->CKr = keys[2];
1273 ax->DHRr = *DHRp;
1274 ax->Nr = 0;
1276
1277 }
1278 if ((Np != ax->Nr) &&
1279 (GNUNET_OK != store_ax_keys (ax,
1280 &ax->HKr,
1281 Np)))
1282 {
1283 /* Try the skipped keys, if that fails, we're out of luck. */
1284 return try_old_ax_keys (ax,
1285 dst,
1286 src,
1287 size);
1288 }
1289
1290 t_ax_decrypt (ax,
1291 dst,
1292 &src[1],
1293 esize);
1294 ax->Nr = Np + 1;
1295 return esize - sizeof (struct GNUNET_CRYPTO_AeadMac);
1296}
1297
1298
1308static int
1309notify_tunnel_up_cb (void *cls,
1310 uint32_t key,
1311 void *value)
1312{
1313 struct CadetChannel *ch = value;
1314
1316 return GNUNET_OK;
1317}
1318
1319
1327void
1330{
1331 enum CadetTunnelEState old = t->estate;
1332
1333 t->estate = state;
1335 "%s estate changed from %s to %s\n",
1336 GCT_2s (t),
1337 estate2s (old),
1338 estate2s (state));
1339
1340 if ((CADET_TUNNEL_KEY_OK != old) &&
1341 (CADET_TUNNEL_KEY_OK == t->estate))
1342 {
1343 if (NULL != t->kx_task)
1344 {
1345 GNUNET_SCHEDULER_cancel (t->kx_task);
1346 t->kx_task = NULL;
1347 }
1348 /* notify all channels that have been waiting */
1351 t);
1352 if (NULL != t->send_task)
1353 GNUNET_SCHEDULER_cancel (t->send_task);
1355 t);
1356 }
1357}
1358
1359
1368static void
1369send_kx (struct CadetTunnel *t,
1370 struct CadetTConnection *ct,
1371 struct CadetTunnelAxolotl *ax)
1372{
1373 struct CadetConnection *cc;
1374 struct GNUNET_MQ_Envelope *env;
1377
1378 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1379 return; /* only Alice may send KX */
1380 if ((NULL == ct) ||
1381 (GNUNET_NO == ct->is_ready))
1382 ct = get_ready_connection (t);
1383 if (NULL == ct)
1384 {
1386 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1387 GCT_2s (t),
1388 estate2s (t->estate));
1389 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1390 return;
1391 }
1392 cc = ct->cc;
1395 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1396 msg->flags = htonl (flags);
1397 msg->cid = *GCC_get_id (cc);
1399 &msg->ephemeral_key);
1400#if DEBUG_KX
1401 msg->ephemeral_key_XXX = ax->kx_0;
1402#endif
1404 "Sending KX message to %s with ephemeral %s on CID %s\n",
1405 GCT_2s (t),
1406 GNUNET_e2s (&msg->ephemeral_key),
1407 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1409 &msg->ratchet_key);
1411 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1412 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1413 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1416 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1419 GCC_transmit (cc,
1420 env);
1422 "# KX transmitted",
1423 1,
1424 GNUNET_NO);
1425}
1426
1427
1438static void
1439send_kx_auth (struct CadetTunnel *t,
1440 struct CadetTConnection *ct,
1441 struct CadetTunnelAxolotl *ax,
1442 int force_reply)
1443{
1444 struct CadetConnection *cc;
1445 struct GNUNET_MQ_Envelope *env;
1447 enum GNUNET_CADET_KX_Flags flags;
1448
1449 if ((NULL == ct) ||
1450 (GNUNET_NO == ct->is_ready))
1451 ct = get_ready_connection (t);
1452 if (NULL == ct)
1453 {
1455 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1456 GCT_2s (t));
1457 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1458 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1459 return;
1460 }
1461 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1462 cc = ct->cc;
1466 if (GNUNET_YES == force_reply)
1468 msg->kx.flags = htonl (flags);
1469 msg->kx.cid = *GCC_get_id (cc);
1471 &msg->kx.ephemeral_key);
1473 &msg->kx.ratchet_key);
1474#if DEBUG_KX
1475 msg->kx.ephemeral_key_XXX = ax->kx_0;
1476 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1477#endif
1479 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1480 GCT_2s (t),
1481 GNUNET_e2s (&msg->kx.ephemeral_key),
1482 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1483
1484 /* Compute authenticator (this is the main difference to #send_kx()) */
1485 GNUNET_CRYPTO_hash (&ax->RK,
1486 sizeof(ax->RK),
1487 &msg->auth);
1488 /* Compute when to be triggered again; actual job will
1489 be scheduled via #connection_ready_cb() */
1490 t->kx_retry_delay
1491 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1492 t->next_kx_attempt
1493 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1494
1495 /* Send via cc, mark it as unready */
1497
1498 /* Update state machine, unless we are already OK */
1499 if (CADET_TUNNEL_KEY_OK != t->estate)
1502 GCC_transmit (cc,
1503 env);
1505 "# KX_AUTH transmitted",
1506 1,
1507 GNUNET_NO);
1508}
1509
1510
1516static void
1517cleanup_ax (struct CadetTunnelAxolotl *ax)
1518{
1519 while (NULL != ax->skipped_head)
1521 ax->skipped_head);
1522 GNUNET_assert (0 == ax->skipped);
1525}
1526
1527
1539static void
1540update_ax_by_kx (void *cls,
1541 const struct GNUNET_HashCode *key_result)
1542{
1543 struct CadetTunnelAsync *as;
1544 struct GNUNET_HashCode key_material[3];
1545 struct GNUNET_CRYPTO_AeadSecretKey keys[5];
1546 struct CadetTunnelAxolotl *ax;
1547 const struct GNUNET_PeerIdentity *pid;
1548 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1549 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1550 const char salt[] = "CADET Axolotl salt";
1551 int am_I_alice;
1552
1553 as = cls;
1554 ax = &as->ax;
1555 pid = &as->peer_id;
1556 ephemeral_key = &as->ephemeral_key;
1557 ratchet_key = &as->ratchet_key;
1558
1559 as->ecdh_op = NULL;
1560
1562 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1563 GNUNET_e2s (ephemeral_key));
1564
1565 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1566 {
1567 GNUNET_break_op (0);
1568 if (as->cb)
1569 as->cb (as->cb_cls, GNUNET_SYSERR);
1570 return;
1571 }
1572
1573 if (0 == GNUNET_memcmp (&ax->DHRr,
1574 ratchet_key))
1575 {
1577 "# Ratchet key already known",
1578 1,
1579 GNUNET_NO);
1581 "Ratchet key already known. Ignoring KX.\n");
1582 if (as->cb)
1583 as->cb (as->cb_cls, GNUNET_NO);
1584 return;
1585 }
1586
1587 ax->DHRr = *ratchet_key;
1588 ax->last_ephemeral = *ephemeral_key;
1589 /* ECDH A B0 */
1590 if (GNUNET_YES == am_I_alice)
1591 {
1592 GNUNET_memcpy (&key_material[0], key_result,
1593 sizeof (*key_result));
1594 }
1595 else
1596 {
1597 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1598 &pid->public_key, /* A */
1599 &key_material[0]);
1600 }
1601 /* ECDH A0 B */
1602 if (GNUNET_YES == am_I_alice)
1603 {
1604 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1605 &pid->public_key, /* B */
1606 &key_material[1]);
1607 }
1608 else
1609 {
1610 GNUNET_memcpy (&key_material[1], key_result,
1611 sizeof (*key_result));
1612 }
1613
1614 /* ECDH A0 B0 */
1615 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1616 ephemeral_key, /* B0 or A0 */
1617 &key_material[2]);
1618 /* KDF */
1620 keys, sizeof(keys),
1621 salt, sizeof(salt),
1622 &key_material, sizeof(key_material));
1623
1624 if (0 == memcmp (&ax->RK,
1625 &keys[0],
1626 sizeof(ax->RK)))
1627 {
1629 "Root key already known. Ignoring KX.\n");
1631 "# Root key already known",
1632 1,
1633 GNUNET_NO);
1634 if (as->cb)
1635 as->cb (as->cb_cls, GNUNET_NO);
1636 return;
1637 }
1638
1639 ax->RK = keys[0];
1640 if (GNUNET_YES == am_I_alice)
1641 {
1642 ax->HKr = keys[1];
1643 ax->NHKs = keys[2];
1644 ax->NHKr = keys[3];
1645 ax->CKr = keys[4];
1647 }
1648 else
1649 {
1650 ax->HKs = keys[1];
1651 ax->NHKr = keys[2];
1652 ax->NHKs = keys[3];
1653 ax->CKs = keys[4];
1654 ax->ratchet_flag = GNUNET_NO;
1657 ratchet_time);
1658 }
1659
1660 if (as->cb)
1661 as->cb (as->cb_cls, GNUNET_OK);
1662}
1663
1664
1670static void
1671retry_kx (void *cls)
1672{
1673 struct CadetTunnel *t = cls;
1674 struct CadetTunnelAxolotl *ax;
1675
1676 t->kx_task = NULL;
1678 "Trying to make KX progress on %s in state %s\n",
1679 GCT_2s (t),
1680 estate2s (t->estate));
1681 switch (t->estate)
1682 {
1683 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1684 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1685 send_kx (t,
1686 NULL,
1687 &t->ax);
1688 break;
1689
1692 /* We are responding, so only require reply
1693 if WE have a channel waiting. */
1694 if (NULL != t->unverified_ax)
1695 {
1696 /* Send AX_AUTH so we might get this one verified */
1697 ax = t->unverified_ax;
1698 }
1699 else
1700 {
1701 /* How can this be? */
1702 GNUNET_break (0);
1703 ax = &t->ax;
1704 }
1705 send_kx_auth (t,
1706 NULL,
1707 ax,
1708 (0 == GCT_count_channels (t))
1709 ? GNUNET_NO
1710 : GNUNET_YES);
1711 break;
1712
1714 /* We are responding, so only require reply
1715 if WE have a channel waiting. */
1716 if (NULL != t->unverified_ax)
1717 {
1718 /* Send AX_AUTH so we might get this one verified */
1719 ax = t->unverified_ax;
1720 }
1721 else
1722 {
1723 /* How can this be? */
1724 GNUNET_break (0);
1725 ax = &t->ax;
1726 }
1727 send_kx_auth (t,
1728 NULL,
1729 ax,
1730 (0 == GCT_count_channels (t))
1731 ? GNUNET_NO
1732 : GNUNET_YES);
1733 break;
1734
1736 /* Must have been the *other* peer asking us to
1737 respond with a KX_AUTH. */
1738 if (NULL != t->unverified_ax)
1739 {
1740 /* Sending AX_AUTH in response to AX so we might get this one verified */
1741 ax = t->unverified_ax;
1742 }
1743 else
1744 {
1745 /* Sending AX_AUTH in response to AX_AUTH */
1746 ax = &t->ax;
1747 }
1748 send_kx_auth (t,
1749 NULL,
1750 ax,
1751 GNUNET_NO);
1752 break;
1753 }
1754}
1755
1756
1763static void
1764cont_GCT_handle_kx (void *cls,
1766{
1767 struct CadetTunnel *t = cls;
1768
1769 if (t->unverified_ax)
1770 *(t->unverified_ax) = t->as.ax;
1771
1773 "Continue handling KX message from %s from %s\n",
1774 GCT_2s (t),
1775 GNUNET_i2s (GCP_get_id (t->destination)));
1776
1778 if (GNUNET_OK != ret)
1779 {
1781 "# Useless KX",
1782 1,
1783 GNUNET_NO);
1784 return; /* duplicate KX, nothing to do */
1785 }
1786 /* move ahead in our state machine */
1787 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1790 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1793
1794 /* KX is still not done, try again our end. */
1795 if (CADET_TUNNEL_KEY_OK != t->estate)
1796 {
1797 if (NULL != t->kx_task)
1798 GNUNET_SCHEDULER_cancel (t->kx_task);
1799 t->kx_task
1801 t);
1802 }
1803}
1804
1805
1812void
1815{
1816 struct CadetTunnel *t = ct->t;
1817
1819 "# KX received",
1820 1,
1821 GNUNET_NO);
1822 if (GNUNET_YES ==
1823 GCT_alice_or_betty (GCP_get_id (t->destination)))
1824 {
1825 /* Betty/Bob is not allowed to send KX! */
1826 GNUNET_break_op (0);
1827 return;
1828 }
1830 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1831 GCT_2s (t),
1832 GNUNET_e2s (&msg->ephemeral_key),
1833 GNUNET_i2s (GCP_get_id (t->destination)),
1834 GCC_2s (ct->cc));
1835#if 1
1836 if ((0 ==
1837 memcmp (&t->ax.DHRr,
1838 &msg->ratchet_key,
1839 sizeof(msg->ratchet_key))) &&
1840 (0 ==
1841 memcmp (&t->ax.last_ephemeral,
1842 &msg->ephemeral_key,
1843 sizeof(msg->ephemeral_key))))
1844
1845 {
1847 "# Duplicate KX received",
1848 1,
1849 GNUNET_NO);
1850 send_kx_auth (t,
1851 ct,
1852 &t->ax,
1853 GNUNET_NO);
1854 return;
1855 }
1856#endif
1857 /* We only keep ONE unverified KX around, so if there is an existing one,
1858 clean it up. */
1859 if (NULL != t->unverified_ax)
1860 {
1861 if ((0 ==
1862 memcmp (&t->unverified_ax->DHRr,
1863 &msg->ratchet_key,
1864 sizeof(msg->ratchet_key))) &&
1865 (0 ==
1866 memcmp (&t->unverified_ax->last_ephemeral,
1867 &msg->ephemeral_key,
1868 sizeof(msg->ephemeral_key))))
1869 {
1871 "# Duplicate unverified KX received",
1872 1,
1873 GNUNET_NO);
1874#if 1
1875 send_kx_auth (t,
1876 ct,
1877 t->unverified_ax,
1878 GNUNET_NO);
1879 return;
1880#endif
1881 }
1882 if ((t->as.ecdh_op) &&
1883 (0 ==
1884 memcmp (&t->as.ratchet_key,
1885 &msg->ratchet_key,
1886 sizeof(msg->ratchet_key))) &&
1887 (0 ==
1888 memcmp (&t->as.ephemeral_key,
1889 &msg->ephemeral_key,
1890 sizeof(msg->ephemeral_key))))
1891 {
1893 "Waiting for previous ECDH operation\n");
1894 return;
1895 }
1897 "Dropping old unverified KX state.\n");
1899 "# Unverified KX dropped for fresh KX",
1900 1,
1901 GNUNET_NO);
1902 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1903 memset (t->unverified_ax,
1904 0,
1905 sizeof(struct CadetTunnelAxolotl));
1906 }
1907 else
1908 {
1910 "Creating fresh unverified KX for %s\n",
1911 GCT_2s (t));
1913 "# Fresh KX setup",
1914 1,
1915 GNUNET_NO);
1916 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1917 }
1918 /* Set as the 'current' RK/DHRr the one we are currently using,
1919 so that the duplicate-detection logic of
1920 #update_ax_by_kx can work. */
1921 t->unverified_ax->RK = t->ax.RK;
1922 t->unverified_ax->DHRr = t->ax.DHRr;
1923 t->unverified_ax->DHRs = t->ax.DHRs;
1924 t->unverified_ax->kx_0 = t->ax.kx_0;
1925 t->unverified_attempts = 0;
1926
1927 t->as.ax = *(t->unverified_ax);
1928 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1929 sizeof (t->as.peer_id));
1930 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1931 sizeof (t->as.ephemeral_key));
1932 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1933 sizeof (t->as.ratchet_key));
1934 memset (&t->as.auth, 0, sizeof (t->as.auth));
1935 t->as.flags = 0;
1936 t->as.cb_cls = t;
1937 t->as.cb = &cont_GCT_handle_kx;
1938
1939 if (t->as.ecdh_op)
1940 {
1942 "Cancelling previous ECDH operation\n");
1943
1944 GNUNET_PILS_cancel (t->as.ecdh_op);
1945 }
1946
1947 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
1948 &update_ax_by_kx, &t->as);
1949}
1950
1951
1958static void
1959cont_GCT_handle_kx_auth (void *cls,
1961{
1962 struct CadetTunnel *t = cls;
1963 struct CadetTunnelAxolotl *ax_tmp;
1964 struct GNUNET_HashCode kx_auth;
1965
1966 ax_tmp = &t->as.ax;
1967
1969 "Continue handling KX_AUTH message from %s\n",
1970 GCT_2s (t));
1971
1972 if (GNUNET_OK != ret)
1973 {
1974 if (GNUNET_NO == ret)
1976 "# redundant KX_AUTH received",
1977 1,
1978 GNUNET_NO);
1979 else
1980 GNUNET_break (0); /* connect to self!? */
1981 return;
1982 }
1983 GNUNET_CRYPTO_hash (&ax_tmp->RK,
1984 sizeof(ax_tmp->RK),
1985 &kx_auth);
1986 if (0 != GNUNET_memcmp (&kx_auth,
1987 &t->as.auth))
1988 {
1989 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1990 we transmitted to the sender, refuse it, try KX again. */
1992 "# KX_AUTH not using our last KX received (auth failure)",
1993 1,
1994 GNUNET_NO);
1996 "KX AUTH mismatch!\n");
1997#if DEBUG_KX
1998 {
1999 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2000
2002 &ephemeral_key);
2003 if (0 != GNUNET_memcmp (&ephemeral_key,
2004 &msg->r_ephemeral_key_XXX))
2005 {
2007 "My ephemeral is %s!\n",
2008 GNUNET_e2s (&ephemeral_key));
2010 "Response is for ephemeral %s!\n",
2011 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2012 }
2013 }
2014#endif
2015 if (NULL == t->kx_task)
2016 t->kx_task
2017 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2018 &retry_kx,
2019 t);
2020 return;
2021 }
2022 /* Yep, we're good. */
2023 t->ax = *ax_tmp;
2024 if (NULL != t->unverified_ax)
2025 {
2026 /* We got some "stale" KX before, drop that. */
2027 cleanup_ax (t->unverified_ax);
2028 GNUNET_free (t->unverified_ax);
2029 t->unverified_ax = NULL;
2030 }
2031
2032 /* move ahead in our state machine */
2033 switch (t->estate)
2034 {
2037 /* Checked above, this is impossible. */
2038 GNUNET_assert (0);
2039 break;
2040
2041 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2042 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2043 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2046 break;
2047
2049 /* Did not expect another KX_AUTH, but so what, still acceptable.
2050 Nothing to do here. */
2051 break;
2052 }
2053 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2054 {
2055 send_kx_auth (t,
2056 NULL,
2057 &t->ax,
2058 GNUNET_NO);
2059 }
2060}
2061
2062
2069void
2072{
2073 struct CadetTunnel *t = ct->t;
2074
2076 "# KX_AUTH received",
2077 1,
2078 GNUNET_NO);
2079 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2080 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2081 {
2082 /* Confusing, we got a KX_AUTH before we even send our own
2083 KX. This should not happen. We'll send our own KX ASAP anyway,
2084 so let's ignore this here. */
2085 GNUNET_break_op (0);
2086 return;
2087 }
2089 "Handling KX_AUTH message from %s with ephemeral %s\n",
2090 GCT_2s (t),
2091 GNUNET_e2s (&msg->kx.ephemeral_key));
2092 if ((t->as.ecdh_op) &&
2093 (0 ==
2094 memcmp (&t->as.ratchet_key,
2095 &msg->kx.ratchet_key,
2096 sizeof(msg->kx.ratchet_key))) &&
2097 (0 ==
2098 memcmp (&t->as.ephemeral_key,
2099 &msg->kx.ephemeral_key,
2100 sizeof(msg->kx.ephemeral_key))))
2101 {
2103 "Waiting for previous ECDH operation\n");
2104 return;
2105 }
2106 /* We do everything in a copy until we've checked the authentication
2107 so we don't clobber anything we care about by accident. */
2108 t->as.ax = t->ax;
2109 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2110 sizeof (t->as.peer_id));
2111 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2112 sizeof (t->as.ephemeral_key));
2113 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2114 sizeof (t->as.ratchet_key));
2115 t->as.auth = msg->auth;
2116 t->as.flags = msg->kx.flags;
2117 t->as.cb_cls = t;
2118 t->as.cb = &cont_GCT_handle_kx_auth;
2119
2120 if (t->as.ecdh_op)
2121 {
2123 "Cancelling previous ECDH operation\n");
2124
2125 GNUNET_PILS_cancel (t->as.ecdh_op);
2126 }
2127
2128 /* Update 'ax' by the new key material */
2129 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2130 &update_ax_by_kx, &t->as);
2131}
2132
2133
2134/* ************************************** end core crypto ***************************** */
2135
2136
2145{
2146#define HIGH_BIT 0x8000000
2147 const struct GNUNET_PeerIdentity *my_identity;
2149 uint32_t ctn;
2150 int cmp;
2151 uint32_t highbit;
2152
2155
2158 if (0 < cmp)
2159 highbit = HIGH_BIT;
2160 else if (0 > cmp)
2161 highbit = 0;
2162 else
2163 GNUNET_assert (0); // loopback must never go here!
2164 ctn = ntohl (t->next_ctn.cn);
2165 while (NULL !=
2167 ctn | highbit))
2168 {
2169 ctn = ((ctn + 1) & (~HIGH_BIT));
2170 }
2171 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2172 ret.cn = htonl (ctn | highbit);
2173 return ret;
2174}
2175
2176
2188 struct CadetChannel *ch)
2189{
2191
2192 ctn = get_next_free_ctn (t);
2193 if (NULL != t->destroy_task)
2194 {
2195 GNUNET_SCHEDULER_cancel (t->destroy_task);
2196 t->destroy_task = NULL;
2197 }
2200 ntohl (ctn.cn),
2201 ch,
2204 "Adding %s to %s with state %d\n",
2205 GCCH_2s (ch),
2206 GCT_2s (t),
2207 t->estate);
2208 switch (t->estate)
2209 {
2211 /* waiting for connection to start KX */
2212 break;
2213
2217 /* we're currently waiting for KX to complete */
2218 break;
2219
2221 /* waiting for OTHER peer to send us data,
2222 we might need to prompt more aggressively! */
2223 if (NULL == t->kx_task)
2224 t->kx_task
2225 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2226 &retry_kx,
2227 t);
2228 break;
2229
2231 /* We are ready. Tell the new channel that we are up. */
2233 break;
2234 }
2235 return ctn;
2236}
2237
2238
2245void
2247{
2248 struct CadetTunnel *t = ct->t;
2249
2250 if (GNUNET_YES == ct->is_ready)
2251 {
2252 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2253 t->connection_ready_tail,
2254 ct);
2255 t->num_ready_connections--;
2256 }
2257 else
2258 {
2259 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2260 t->connection_busy_tail,
2261 ct);
2262 t->num_busy_connections--;
2263 }
2264 GNUNET_free (ct);
2265}
2266
2267
2274static void
2275destroy_t_connection (void *cls,
2276 struct CadetTConnection *ct)
2277{
2278 struct CadetTunnel *t = cls;
2279 struct CadetConnection *cc = ct->cc;
2280
2281 GNUNET_assert (ct->t == t);
2284}
2285
2286
2292static void
2293destroy_tunnel (void *cls)
2294{
2295 struct CadetTunnel *t = cls;
2296 struct CadetTunnelQueueEntry *tq;
2297
2298 t->destroy_task = NULL;
2300 "Destroying idle %s\n",
2301 GCT_2s (t));
2305 t);
2306 GNUNET_assert (NULL == t->connection_ready_head);
2307 GNUNET_assert (NULL == t->connection_busy_head);
2308 while (NULL != (tq = t->tq_head))
2309 {
2310 if (NULL != tq->cont)
2311 tq->cont (tq->cont_cls,
2312 NULL);
2313 GCT_send_cancel (tq);
2314 }
2315 GCP_drop_tunnel (t->destination,
2316 t);
2318 if (NULL != t->maintain_connections_task)
2319 {
2320 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2321 t->maintain_connections_task = NULL;
2322 }
2323 if (NULL != t->send_task)
2324 {
2325 GNUNET_SCHEDULER_cancel (t->send_task);
2326 t->send_task = NULL;
2327 }
2328 if (NULL != t->kx_task)
2329 {
2330 GNUNET_SCHEDULER_cancel (t->kx_task);
2331 t->kx_task = NULL;
2332 }
2333 if (NULL != t->as.ecdh_op)
2334 {
2335 GNUNET_PILS_cancel (t->as.ecdh_op);
2336 t->as.ecdh_op = NULL;
2337 }
2338 GNUNET_MST_destroy (t->mst);
2339 GNUNET_MQ_destroy (t->mq);
2340 if (NULL != t->unverified_ax)
2341 {
2342 cleanup_ax (t->unverified_ax);
2343 GNUNET_free (t->unverified_ax);
2344 }
2345 cleanup_ax (&t->ax);
2346 GNUNET_assert (NULL == t->destroy_task);
2347 GNUNET_free (t);
2348}
2349
2350
2358void
2360 struct CadetChannel *ch,
2362{
2364 "Removing %s from %s\n",
2365 GCCH_2s (ch),
2366 GCT_2s (t));
2369 ntohl (ctn.cn),
2370 ch));
2371 if ((0 ==
2372 GCT_count_channels (t)) &&
2373 (NULL == t->destroy_task))
2374 {
2375 t->destroy_task
2378 t);
2379 }
2380}
2381
2382
2391static int
2393 uint32_t key,
2394 void *value)
2395{
2396 struct CadetChannel *ch = value;
2397
2399 NULL);
2400 return GNUNET_OK;
2401}
2402
2403
2409void
2411{
2415 t);
2416 GNUNET_assert (0 ==
2418 if (NULL != t->destroy_task)
2419 {
2420 GNUNET_SCHEDULER_cancel (t->destroy_task);
2421 t->destroy_task = NULL;
2422 }
2423 destroy_tunnel (t);
2424}
2425
2426
2434static void
2436 struct CadetTConnection *ct)
2437{
2438 struct CadetTunnelQueueEntry *tq;
2439
2441 tq = t->tq_head;
2442 if (NULL == tq)
2443 {
2444 /* no messages pending right now */
2446 "Not sending payload of %s on ready %s (nothing pending)\n",
2447 GCT_2s (t),
2448 GCC_2s (ct->cc));
2449 return;
2450 }
2451 /* ready to send message 'tq' on tunnel 'ct' */
2452 GNUNET_assert (t == tq->t);
2454 t->tq_tail,
2455 tq);
2456 if (NULL != tq->cid)
2457 *tq->cid = *GCC_get_id (ct->cc);
2460 "Sending payload of %s on %s\n",
2461 GCT_2s (t),
2462 GCC_2s (ct->cc));
2463 GCC_transmit (ct->cc,
2464 tq->env);
2465 if (NULL != tq->cont)
2466 tq->cont (tq->cont_cls,
2467 GCC_get_id (ct->cc));
2468 GNUNET_free (tq);
2469}
2470
2471
2480static void
2481connection_ready_cb (void *cls,
2482 int is_ready)
2483{
2484 struct CadetTConnection *ct = cls;
2485 struct CadetTunnel *t = ct->t;
2486
2487 if (GNUNET_NO == is_ready)
2488 {
2490 "%s no longer ready for %s\n",
2491 GCC_2s (ct->cc),
2492 GCT_2s (t));
2494 return;
2495 }
2497 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2498 t->connection_busy_tail,
2499 ct);
2500 GNUNET_assert (0 < t->num_busy_connections);
2501 t->num_busy_connections--;
2502 ct->is_ready = GNUNET_YES;
2503 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2504 t->connection_ready_tail,
2505 ct);
2506 t->num_ready_connections++;
2507
2509 "%s now ready for %s in state %s\n",
2510 GCC_2s (ct->cc),
2511 GCT_2s (t),
2512 estate2s (t->estate));
2513 switch (t->estate)
2514 {
2517 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2518 GCT_2s (t),
2519 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2520 t->next_kx_attempt).rel_value_us);
2521 /* Do not begin KX if WE have no channels waiting! */
2523 t->next_kx_attempt).rel_value_us)
2524 return; /* wait for timeout before retrying */
2525 /* We are uninitialized, just transmit immediately,
2526 without undue delay. */
2527
2529 "Why for %s \n",
2530 GCT_2s (t));
2531
2532 if (NULL != t->kx_task)
2533 {
2534 GNUNET_SCHEDULER_cancel (t->kx_task);
2535 t->kx_task = NULL;
2536 }
2537 send_kx (t,
2538 ct,
2539 &t->ax);
2540 if ((0 ==
2541 GCT_count_channels (t)) &&
2542 (NULL == t->destroy_task))
2543 {
2544 t->destroy_task
2547 t);
2548 }
2549 break;
2550
2555 /* we're currently waiting for KX to complete, schedule job */
2556 if (NULL == t->kx_task)
2557 t->kx_task
2558 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2559 &retry_kx,
2560 t);
2561 break;
2562
2564 if (GNUNET_YES == t->kx_auth_requested)
2565 {
2567 t->next_kx_attempt).rel_value_us)
2568 return; /* wait for timeout */
2569 if (NULL != t->kx_task)
2570 {
2571 GNUNET_SCHEDULER_cancel (t->kx_task);
2572 t->kx_task = NULL;
2573 }
2574 send_kx_auth (t,
2575 ct,
2576 &t->ax,
2577 GNUNET_NO);
2578 return;
2579 }
2581 ct);
2582 break;
2583 }
2584}
2585
2586
2595static void
2596trigger_transmissions (void *cls)
2597{
2598 struct CadetTunnel *t = cls;
2599 struct CadetTConnection *ct;
2600
2601 t->send_task = NULL;
2602 if (NULL == t->tq_head)
2603 return; /* no messages pending right now */
2604 ct = get_ready_connection (t);
2605 if (NULL == ct)
2606 return; /* no connections ready */
2608 ct);
2609}
2610
2611
2616struct EvaluationSummary
2617{
2621 unsigned int min_length;
2622
2626 unsigned int max_length;
2627
2632
2637
2641 struct CadetPeerPath *path;
2642
2647 struct CadetTConnection *worst;
2648
2652 double worst_score;
2653
2657 int duplicate;
2658};
2659
2660
2668static void
2669evaluate_connection (void *cls,
2670 struct CadetTConnection *ct)
2671{
2672 struct EvaluationSummary *es = cls;
2673 struct CadetConnection *cc = ct->cc;
2674 unsigned int ct_length;
2675 struct CadetPeerPath *ps;
2676 const struct CadetConnectionMetrics *metrics;
2677 GNUNET_CONTAINER_HeapCostType ct_desirability;
2678 struct GNUNET_TIME_Relative uptime;
2679 struct GNUNET_TIME_Relative last_use;
2680 double score;
2681 double success_rate;
2682
2683 ps = GCC_get_path (cc,
2684 &ct_length);
2686 "Evaluating path %s of existing %s\n",
2687 GCPP_2s (ps),
2688 GCC_2s (cc));
2689 if (ps == es->path)
2690 {
2692 "Ignoring duplicate path %s.\n",
2693 GCPP_2s (es->path));
2694 es->duplicate = GNUNET_YES;
2695 return;
2696 }
2697 if (NULL != es->path)
2698 {
2699 int duplicate = GNUNET_YES;
2700
2701 for (unsigned int i = 0; i < ct_length; i++)
2702 {
2705 i) !=
2707 i))
2708 {
2709 duplicate = GNUNET_NO;
2710 break;
2711 }
2712 }
2713 if (GNUNET_YES == duplicate)
2714 {
2716 "Ignoring overlapping path %s.\n",
2717 GCPP_2s (es->path));
2718 es->duplicate = GNUNET_YES;
2719 return;
2720 }
2721 else
2722 {
2724 "Known path %s differs from proposed path\n",
2725 GCPP_2s (ps));
2726 }
2727 }
2728
2729 ct_desirability = GCPP_get_desirability (ps);
2730 metrics = GCC_get_metrics (cc);
2731 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2732 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2733 /* We add 1.0 here to avoid division by zero. */
2734 success_rate = (metrics->num_acked_transmissions + 1.0)
2735 / (metrics->num_successes + 1.0);
2736 score
2737 = ct_desirability
2738 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2739 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2740 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2741 score *= success_rate; /* weigh overall by success rate */
2742
2743 if ((NULL == es->worst) ||
2744 (score < es->worst_score))
2745 {
2746 es->worst = ct;
2747 es->worst_score = score;
2748 }
2749 es->min_length = GNUNET_MIN (es->min_length,
2750 ct_length);
2751 es->max_length = GNUNET_MAX (es->max_length,
2752 ct_length);
2753 es->min_desire = GNUNET_MIN (es->min_desire,
2754 ct_desirability);
2755 es->max_desire = GNUNET_MAX (es->max_desire,
2756 ct_desirability);
2757}
2758
2759
2769static int
2770consider_path_cb (void *cls,
2771 struct CadetPeerPath *path,
2772 unsigned int off)
2773{
2774 struct CadetTunnel *t = cls;
2775 struct EvaluationSummary es;
2776 struct CadetTConnection *ct;
2777
2778 GNUNET_assert (off < GCPP_get_length (path));
2780 off) == t->destination);
2781 es.min_length = UINT_MAX;
2782 es.max_length = 0;
2783 es.max_desire = 0;
2784 es.min_desire = UINT64_MAX;
2785 es.path = path;
2786 es.duplicate = GNUNET_NO;
2787 es.worst = NULL;
2788
2789 /* Compute evaluation summary over existing connections. */
2791 "Evaluating proposed path %s for target %s\n",
2792 GCPP_2s (path),
2793 GCT_2s (t));
2794 /* FIXME: suspect this does not ACTUALLY iterate
2795 over all existing paths, otherwise dup detection
2796 should work!!! */
2799 &es);
2800 if (GNUNET_YES == es.duplicate)
2801 return GNUNET_YES;
2802
2803 /* FIXME: not sure we should really just count
2804 'num_connections' here, as they may all have
2805 consistently failed to connect. */
2806
2807 /* We iterate by increasing path length; if we have enough paths and
2808 this one is more than twice as long than what we are currently
2809 using, then ignore all of these super-long ones! */
2811 (es.min_length * 2 < off) &&
2812 (es.max_length < off))
2813 {
2815 "Ignoring paths of length %u, they are way too long.\n",
2816 es.min_length * 2);
2817 return GNUNET_NO;
2818 }
2819 /* If we have enough paths and this one looks no better, ignore it. */
2821 (es.min_length < GCPP_get_length (path)) &&
2822 (es.min_desire > GCPP_get_desirability (path)) &&
2823 (es.max_length < off))
2824 {
2826 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2827 GCPP_get_length (path),
2828 (unsigned long long) GCPP_get_desirability (path),
2829 GCP_2s (t->destination));
2830 return GNUNET_YES;
2831 }
2832
2833 /* Path is interesting (better by some metric, or we don't have
2834 enough paths yet). */
2835 ct = GNUNET_new (struct CadetTConnection);
2837 ct->t = t;
2838 ct->cc = GCC_create (t->destination,
2839 path,
2840 off,
2841 ct,
2843 ct);
2844
2845 /* FIXME: schedule job to kill connection (and path?) if it takes
2846 too long to get ready! (And track performance data on how long
2847 other connections took with the tunnel!)
2848 => Note: to be done within 'connection'-logic! */
2849 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2850 t->connection_busy_tail,
2851 ct);
2852 t->num_busy_connections++;
2854 "Found interesting path %s for %s, created %s\n",
2855 GCPP_2s (path),
2856 GCT_2s (t),
2857 GCC_2s (ct->cc));
2858 return GNUNET_YES;
2859}
2860
2861
2875static void
2876maintain_connections_cb (void *cls)
2877{
2878 struct CadetTunnel *t = cls;
2879 struct GNUNET_TIME_Relative delay;
2880 struct EvaluationSummary es;
2881
2882 t->maintain_connections_task = NULL;
2884 "Performing connection maintenance for %s.\n",
2885 GCT_2s (t));
2886
2887 es.min_length = UINT_MAX;
2888 es.max_length = 0;
2889 es.max_desire = 0;
2890 es.min_desire = UINT64_MAX;
2891 es.path = NULL;
2892 es.worst = NULL;
2893 es.duplicate = GNUNET_NO;
2896 &es);
2897 if ((NULL != es.worst) &&
2899 {
2900 /* Clear out worst-performing connection 'es.worst'. */
2902 es.worst);
2903 }
2904
2905 /* Consider additional paths */
2906 (void) GCP_iterate_paths (t->destination,
2908 t);
2909
2910 /* FIXME: calculate when to try again based on how well we are doing;
2911 in particular, if we have to few connections, we might be able
2912 to do without this (as PATHS should tell us whenever a new path
2913 is available instantly; however, need to make sure this job is
2914 restarted after that happens).
2915 Furthermore, if the paths we do know are in a reasonably narrow
2916 quality band and are plentyful, we might also consider us stabilized
2917 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2918 t->maintain_connections_task
2921 t);
2922}
2923
2924
2925void
2927 struct CadetPeerPath *p,
2928 unsigned int off)
2929{
2931 "Considering %s for %s (offset %u)\n",
2932 GCPP_2s (p),
2933 GCT_2s (t),
2934 off);
2935 (void) consider_path_cb (t,
2936 p,
2937 off);
2938}
2939
2940
2947static void
2949 const struct GNUNET_MessageHeader *msg)
2950{
2951 struct CadetTunnel *t = cls;
2952
2954 "Received KEEPALIVE on %s\n",
2955 GCT_2s (t));
2957 "# keepalives received",
2958 1,
2959 GNUNET_NO);
2960}
2961
2962
2970static int
2971check_plaintext_data (void *cls,
2973{
2974 return GNUNET_OK;
2975}
2976
2977
2985static void
2986handle_plaintext_data (void *cls,
2988{
2989 struct CadetTunnel *t = cls;
2990 struct CadetChannel *ch;
2991
2992 ch = lookup_channel (t,
2993 msg->ctn);
2994 if (NULL == ch)
2995 {
2996 /* We don't know about such a channel, might have been destroyed on our
2997 end in the meantime, or never existed. Send back a DESTROY. */
2999 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3000 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3001 ntohl (msg->ctn.cn));
3003 msg->ctn);
3004 return;
3005 }
3007 GCC_get_id (t->current_ct->cc),
3008 msg);
3009}
3010
3011
3020static void
3021handle_plaintext_data_ack (void *cls,
3022 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
3023{
3024 struct CadetTunnel *t = cls;
3025 struct CadetChannel *ch;
3026
3027 ch = lookup_channel (t,
3028 ack->ctn);
3029 if (NULL == ch)
3030 {
3031 /* We don't know about such a channel, might have been destroyed on our
3032 end in the meantime, or never existed. Send back a DESTROY. */
3034 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3035 ntohl (ack->ctn.cn));
3037 ack->ctn);
3038 return;
3039 }
3041 GCC_get_id (t->current_ct->cc),
3042 ack);
3043}
3044
3045
3053static void
3055 const struct
3057{
3058 struct CadetTunnel *t = cls;
3059 struct CadetChannel *ch;
3060
3062 ntohl (copen->ctn.cn));
3063 if (NULL != ch)
3064 {
3066 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3067 GNUNET_h2s (&copen->h_port),
3068 GCT_2s (t),
3069 GCCH_2s (ch));
3071 GCC_get_id (t->current_ct->cc));
3072 return;
3073 }
3075 "Received CHANNEL_OPEN on h_port %s from %s\n",
3076 GNUNET_h2s (&copen->h_port),
3077 GCT_2s (t));
3079 copen->ctn,
3080 &copen->h_port,
3081 ntohl (copen->opt));
3082 if (NULL != t->destroy_task)
3083 {
3084 GNUNET_SCHEDULER_cancel (t->destroy_task);
3085 t->destroy_task = NULL;
3086 }
3089 ntohl (copen->ctn.cn),
3090 ch,
3092}
3093
3094
3101void
3104{
3106
3108 "Sending DESTROY message for channel ID %u\n",
3109 ntohl (ctn.cn));
3110 msg.header.size = htons (sizeof(msg));
3112 msg.reserved = htonl (0);
3113 msg.ctn = ctn;
3114 GCT_send (t,
3115 &msg.header,
3116 NULL,
3117 NULL,
3118 &ctn);
3119}
3120
3121
3130static void
3132 const struct
3134{
3135 struct CadetTunnel *t = cls;
3136 struct CadetChannel *ch;
3137
3138 ch = lookup_channel (t,
3139 cm->ctn);
3140 if (NULL == ch)
3141 {
3142 /* We don't know about such a channel, might have been destroyed on our
3143 end in the meantime, or never existed. Send back a DESTROY. */
3145 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3146 ntohl (cm->ctn.cn));
3148 cm->ctn);
3149 return;
3150 }
3152 "Received channel OPEN_ACK on channel %s from %s\n",
3153 GCCH_2s (ch),
3154 GCT_2s (t));
3156 GCC_get_id (t->current_ct->cc),
3157 &cm->port);
3158}
3159
3160
3168static void
3170 const struct
3172{
3173 struct CadetTunnel *t = cls;
3174 struct CadetChannel *ch;
3175
3176 ch = lookup_channel (t,
3177 cm->ctn);
3178 if (NULL == ch)
3179 {
3180 /* We don't know about such a channel, might have been destroyed on our
3181 end in the meantime, or never existed. */
3183 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3184 ntohl (cm->ctn.cn));
3185 return;
3186 }
3188 "Received channel DESTROY on %s from %s\n",
3189 GCCH_2s (ch),
3190 GCT_2s (t));
3192 GCC_get_id (t->current_ct->cc));
3193}
3194
3195
3206static int
3207handle_decrypted (void *cls,
3208 const struct GNUNET_MessageHeader *msg)
3209{
3210 struct CadetTunnel *t = cls;
3211
3212 GNUNET_assert (NULL != t->current_ct);
3214 msg);
3215 return GNUNET_OK;
3216}
3217
3218
3226static void
3227decrypted_error_cb (void *cls,
3228 enum GNUNET_MQ_Error error)
3229{
3230 GNUNET_break_op (0);
3231}
3232
3233
3241struct CadetTunnel *
3243{
3244 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3246 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3248 struct GNUNET_MessageHeader,
3249 t),
3250 GNUNET_MQ_hd_var_size (plaintext_data,
3253 t),
3254 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3257 t),
3258 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3261 t),
3262 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3265 t),
3266 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3269 t),
3271 };
3272
3273 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3274 new_ephemeral (&t->ax);
3276 t->destination = destination;
3278 t->maintain_connections_task
3280 t);
3281 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3282 NULL,
3283 NULL,
3284 NULL,
3285 handlers,
3287 t);
3289 t);
3290 return t;
3291}
3292
3293
3294int
3296 const struct
3298 struct CadetPeerPath *path)
3299{
3300 struct CadetTConnection *ct;
3301
3302 ct = GNUNET_new (struct CadetTConnection);
3304 ct->t = t;
3305 ct->cc = GCC_create_inbound (t->destination,
3306 path,
3307 ct,
3308 cid,
3310 ct);
3311 if (NULL == ct->cc)
3312 {
3314 "%s refused inbound %s (duplicate)\n",
3315 GCT_2s (t),
3316 GCC_2s (ct->cc));
3317 GNUNET_free (ct);
3318 return GNUNET_SYSERR;
3319 }
3320 /* FIXME: schedule job to kill connection (and path?) if it takes
3321 too long to get ready! (And track performance data on how long
3322 other connections took with the tunnel!)
3323 => Note: to be done within 'connection'-logic! */
3324 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3325 t->connection_busy_tail,
3326 ct);
3327 t->num_busy_connections++;
3329 "%s has new %s\n",
3330 GCT_2s (t),
3331 GCC_2s (ct->cc));
3332 return GNUNET_OK;
3333}
3334
3335
3342void
3345{
3346 struct CadetTunnel *t = ct->t;
3347 uint16_t size = ntohs (msg->header.size);
3348 char cbuf[size] GNUNET_ALIGN;
3349 ssize_t decrypted_size;
3350
3352 "%s received %u bytes of encrypted data in state %d\n",
3353 GCT_2s (t),
3354 (unsigned int) size,
3355 t->estate);
3356
3357 switch (t->estate)
3358 {
3361 /* We did not even SEND our KX, how can the other peer
3362 send us encrypted data? Must have been that we went
3363 down and the other peer still things we are up.
3364 Let's send it KX back. */
3366 "# received encrypted without any KX",
3367 1,
3368 GNUNET_NO);
3369 if (NULL != t->kx_task)
3370 {
3371 GNUNET_SCHEDULER_cancel (t->kx_task);
3372 t->kx_task = NULL;
3373 }
3374 send_kx (t,
3375 ct,
3376 &t->ax);
3377 return;
3378
3380 /* We send KX, and other peer send KX to us at the same time.
3381 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3383 "# received encrypted without KX_AUTH",
3384 1,
3385 GNUNET_NO);
3386 if (NULL != t->kx_task)
3387 {
3388 GNUNET_SCHEDULER_cancel (t->kx_task);
3389 t->kx_task = NULL;
3390 }
3391 send_kx_auth (t,
3392 ct,
3393 &t->ax,
3394 GNUNET_YES);
3395 return;
3396
3398 /* We did not get the KX of the other peer, but that
3399 might have been lost. Send our KX again immediately. */
3401 "# received encrypted without KX",
3402 1,
3403 GNUNET_NO);
3404 if (NULL != t->kx_task)
3405 {
3406 GNUNET_SCHEDULER_cancel (t->kx_task);
3407 t->kx_task = NULL;
3408 }
3409 send_kx (t,
3410 ct,
3411 &t->ax);
3412 return;
3413
3415 /* Great, first payload, we might graduate to OK! */
3417 /* We are up and running, all good. */
3418 break;
3419 }
3420
3421 decrypted_size = -1;
3422 if (CADET_TUNNEL_KEY_OK == t->estate)
3423 {
3424 /* We have well-established key material available,
3425 try that. (This is the common case.) */
3426 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3427 cbuf,
3428 msg,
3429 size);
3430 }
3431
3432 if ((-1 == decrypted_size) &&
3433 (NULL != t->unverified_ax))
3434 {
3435 /* We have un-authenticated KX material available. We should try
3436 this as a back-up option, in case the sender crashed and
3437 switched keys. */
3438 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3439 cbuf,
3440 msg,
3441 size);
3442 if (-1 != decrypted_size)
3443 {
3444 /* It worked! Treat this as authentication of the AX data! */
3445 cleanup_ax (&t->ax);
3446 t->ax = *t->unverified_ax;
3447 GNUNET_free (t->unverified_ax);
3448 t->unverified_ax = NULL;
3449 }
3450 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3451 {
3452 /* First time it worked, move tunnel into production! */
3455 if (NULL != t->send_task)
3456 GNUNET_SCHEDULER_cancel (t->send_task);
3458 t);
3459 }
3460 }
3461 if (NULL != t->unverified_ax)
3462 {
3463 /* We had unverified KX material that was useless; so increment
3464 counter and eventually move to ignore it. Note that we even do
3465 this increment if we successfully decrypted with the old KX
3466 material and thus didn't even both with the new one. This is
3467 the ideal case, as a malicious injection of bogus KX data
3468 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3470 "Failed to decrypt message with unverified KX data %u times\n",
3471 t->unverified_attempts);
3472 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3473 {
3474 cleanup_ax (t->unverified_ax);
3475 GNUNET_free (t->unverified_ax);
3476 t->unverified_ax = NULL;
3477 }
3478 }
3479
3480 if (-1 == decrypted_size)
3481 {
3482 /* Decryption failed for good, complain. */
3484 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3485 GCT_2s (t));
3487 "# unable to decrypt",
3488 1,
3489 GNUNET_NO);
3490 if (NULL != t->kx_task)
3491 {
3492 GNUNET_SCHEDULER_cancel (t->kx_task);
3493 t->kx_task = NULL;
3494 }
3495 send_kx (t,
3496 ct,
3497 &t->ax);
3498 return;
3499 }
3501 "# decrypted bytes",
3502 decrypted_size,
3503 GNUNET_NO);
3504
3505 /* The MST will ultimately call #handle_decrypted() on each message. */
3506 t->current_ct = ct;
3509 cbuf,
3510 decrypted_size,
3511 GNUNET_YES,
3512 GNUNET_NO));
3513 t->current_ct = NULL;
3514}
3515
3516
3517struct CadetTunnelQueueEntry *
3518GCT_send (struct CadetTunnel *t,
3519 const struct GNUNET_MessageHeader *message,
3521 void *cont_cls,
3523{
3524 struct CadetTunnelQueueEntry *tq;
3525 uint16_t message_size;
3526 uint16_t payload_size;
3527 struct GNUNET_MQ_Envelope *env;
3529 struct CadetChannel *ch;
3530
3531 if (NULL != ctn)
3532 {
3533 ch = lookup_channel (t,
3534 *ctn);
3535 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3536 {
3537 GNUNET_break (0);
3538 return NULL;
3539 }
3540 }
3541
3542 if (CADET_TUNNEL_KEY_OK != t->estate)
3543 {
3544 GNUNET_break (0);
3545 return NULL;
3546 }
3547 message_size = ntohs (message->size);
3548 payload_size = message_size + sizeof (struct GNUNET_CRYPTO_AeadMac);
3550 "Encrypting %u bytes for %s\n",
3551 (unsigned int) message_size,
3552 GCT_2s (t));
3553 env = GNUNET_MQ_msg_extra (ax_msg,
3554 payload_size,
3556 t_ax_encrypt (&t->ax,
3557 &ax_msg[1],
3558 message,
3559 message_size);
3561 "# encrypted bytes",
3562 payload_size,
3563 GNUNET_NO);
3564 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3565 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3566 /* FIXME: we should do this once, not once per message;
3567 this is a point multiplication, and DHRs does not
3568 change all the time. */
3570 &ax_msg->ax_header.DHRs);
3571 t_h_encrypt (&t->ax,
3572 ax_msg,
3573 payload_size,
3574 (unsigned char*) &ax_msg[1]);
3575
3576 tq = GNUNET_malloc (sizeof(*tq));
3577 tq->t = t;
3578 tq->env = env;
3579 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3580 tq->cont = cont;
3581 tq->cont_cls = cont_cls;
3583 t->tq_tail,
3584 tq);
3585 if (NULL != t->send_task)
3586 GNUNET_SCHEDULER_cancel (t->send_task);
3587 t->send_task
3589 t);
3590 return tq;
3591}
3592
3593
3594void
3596{
3597 struct CadetTunnel *t = tq->t;
3598
3600 t->tq_tail,
3601 tq);
3602 GNUNET_MQ_discard (tq->env);
3603 GNUNET_free (tq);
3604}
3605
3606
3614void
3617 void *iter_cls)
3618{
3619 struct CadetTConnection *n;
3620
3621 for (struct CadetTConnection *ct = t->connection_ready_head;
3622 NULL != ct;
3623 ct = n)
3624 {
3625 n = ct->next;
3626 iter (iter_cls,
3627 ct);
3628 }
3629 for (struct CadetTConnection *ct = t->connection_busy_head;
3630 NULL != ct;
3631 ct = n)
3632 {
3633 n = ct->next;
3634 iter (iter_cls,
3635 ct);
3636 }
3637}
3638
3639
3643struct ChanIterCls
3644{
3649
3653 void *iter_cls;
3654};
3655
3656
3665static int
3666iterate_channels_cb (void *cls,
3667 uint32_t key,
3668 void *value)
3669{
3670 struct ChanIterCls *ctx = cls;
3671 struct CadetChannel *ch = value;
3672
3673 ctx->iter (ctx->iter_cls,
3674 ch);
3675 return GNUNET_OK;
3676}
3677
3678
3686void
3689 void *iter_cls)
3690{
3691 struct ChanIterCls ctx;
3692
3693 ctx.iter = iter;
3694 ctx.iter_cls = iter_cls;
3697 &ctx);
3698}
3699
3700
3709static int
3710debug_channel (void *cls,
3711 uint32_t key,
3712 void *value)
3713{
3714 const enum GNUNET_ErrorType *level = cls;
3715 struct CadetChannel *ch = value;
3716
3717 GCCH_debug (ch, *level);
3718 return GNUNET_OK;
3719}
3720
3721
3722#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3723 __VA_ARGS__)
3724
3725
3732void
3733GCT_debug (const struct CadetTunnel *t,
3734 enum GNUNET_ErrorType level)
3735{
3736#if ! defined(GNUNET_CULL_LOGGING)
3737 struct CadetTConnection *iter_c;
3738 int do_log;
3739
3741 "cadet-tun",
3742 __FILE__, __FUNCTION__, __LINE__);
3743 if (0 == do_log)
3744 return;
3745
3746 LOG2 (level,
3747 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3748 GCT_2s (t),
3749 estate2s (t->estate),
3750 t->tq_len,
3752 LOG2 (level,
3753 "TTT channels:\n");
3756 &level);
3757 LOG2 (level,
3758 "TTT connections:\n");
3759 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3760 GCC_debug (iter_c->cc,
3761 level);
3762 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3763 GCC_debug (iter_c->cc,
3764 level);
3765
3766 LOG2 (level,
3767 "TTT TUNNEL END\n");
3768#endif
3769}
3770
3771
3772/* end of gnunet-service-cadet_tunnels.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
GNUNET_CADET_KX_Flags
Flags to be used in GNUNET_CADET_KX.
@ GNUNET_CADET_KX_FLAG_NONE
Should the peer reply with its KX details?
@ GNUNET_CADET_KX_FLAG_FORCE_REPLY
The peer should reply with its KX details?
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CADET_Channel * ch
Channel handle.
static uint64_t timestamp(void)
Get current timestamp.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static struct GNUNET_PILS_Handle * pils
Handle to PILS.
Definition gnunet-pils.c:44
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
void GCT_handle_kx(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Continue to handle KX message.
static int consider_path_cb(void *cls, struct CadetPeerPath *path, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn(struct CadetTunnel *t)
Compute the next free channel tunnel number for this tunnel.
static struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
static int notify_tunnel_up_cb(void *cls, uint32_t key, void *value)
Our tunnel became ready for the first time, notify channels that have been waiting.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
void(* CadetTunnelAxolotlCallback)(void *cls, enum GNUNET_GenericReturnValue res)
Signature of the follow up function from an udate AX by KX.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
static void handle_plaintext_channel_open_ack(void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
We have received confirmation from the target peer that the given channel could be established (the p...
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
Delete a key from the list of skipped keys.
#define LOG2(level,...)
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
static void t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg, size_t additional_data_size, const unsigned char *additional_data)
Encrypt header with the axolotl header key.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
void GCT_handle_kx_auth(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
void GCT_handle_encrypted(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void cont_GCT_handle_kx(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX message.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
static void handle_plaintext_channel_destroy(void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
We received a message saying that a channel should be destroyed.
#define HIGH_BIT
static void handle_plaintext_channel_open(void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
We have received a request to open a channel to a port from another peer.
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
static int check_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
Check that msg is well-formed.
static void handle_plaintext_data_ack(void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We received an acknowledgement for data we sent on a channel.
static void handle_plaintext_keepalive(void *cls, const struct GNUNET_MessageHeader *msg)
We got a keepalive.
static void handle_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We received payload data for a channel.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
static void cont_GCT_handle_kx_auth(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX_AUTH message.
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
void GCT_destroy_tunnel_now(struct CadetTunnel *t)
Destroys the tunnel t now, without delay.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
#define LOG(level,...)
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_iterate_channels(struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
Iterate over all channels of a tunnel.
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GCT_debug(const struct CadetTunnel *t, enum GNUNET_ErrorType level)
Log all possible info about the tunnel state.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_CRYPTO_AeadSecretKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
static enum GNUNET_GenericReturnValue t_h_decrypt(const struct GNUNET_CRYPTO_AeadSecretKey *hkr, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t esize, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
static void update_ax_by_kx(void *cls, const struct GNUNET_HashCode *key_result)
Update our Axolotl key state based on the KX data we received.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
CadetTunnelEState
All the encryption states a tunnel can be in.
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
void(* GCT_ConnectionIterator)(void *cls, struct CadetTConnection *ct)
Iterator over connections.
void(* GCT_SendContinuation)(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called when a transmission requested using GCT_send is done.
void(* GCT_ChannelIterator)(void *cls, struct CadetChannel *ch)
Iterator over channels.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
#define N
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
struct GNUNET_PILS_Operation * GNUNET_PILS_ecdh(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, GNUNET_PILS_EcdhResultCallback cb, void *cb_cls)
Derive key material from a ECDH public key and our private key.
Definition pils_api.c:595
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition crypto_ecc.c:752
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_decrypt(size_t ct_len, const unsigned char ct[ct_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, const struct GNUNET_CRYPTO_AeadMac *mac, void *pt)
Decrypt the given data using XChaCha20-Poly1305.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:843
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_encrypt(size_t pt_len, const unsigned char pt[pt_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, void *ct, struct GNUNET_CRYPTO_AeadMac *mac)
Encrypt the given data using XChaCha20-Poly1305.
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:433
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:217
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
#define GNUNET_CRYPTO_hkdf_gnunet(result, out_len, xts, xts_len, skm, skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MAX(a, b)
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
GNUNET_ErrorType
Types of errors.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition mq.c:187
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1260
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition mst.c:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition mst.c:404
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Performance metrics for a connection.
unsigned long long num_acked_transmissions
How many packets that ought to generate an ACK did we send via this connection?
struct GNUNET_TIME_Absolute age
When was this connection first established? (by us sending or receiving the CREATE_ACK for the first ...
unsigned long long num_successes
Number of packets that were sent via this connection did actually receive an ACK? (Note: ACKs may be ...
struct GNUNET_TIME_Absolute last_use
When was this connection last used? (by us sending or receiving a PAYLOAD message on it)
Low-level connection to a destination.
struct CadetTConnection * ct
Which tunnel is using this connection?
unsigned int off
Offset of our destination in path.
Information regarding a possible path to reach a peer.
Struct containing all information regarding a given peer.
Entry in list of connections used by tunnel, with metadata.
struct CadetTConnection * next
Next in DLL.
struct CadetConnection * cc
Connection handle.
struct GNUNET_TIME_Absolute created
Creation time, to keep oldest connection alive.
int is_ready
Is the connection currently ready for transmission?
struct CadetTunnel * t
Tunnel this connection belongs to.
Struct used to store data required for an async update AX by KX process.
struct GNUNET_PeerIdentity peer_id
Peer identity of other peer.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
void * cb_cls
Update callback closure.
struct GNUNET_HashCode auth
KDF-proof that sender could compute the 3-DH, used in lieu of a signature or payload data.
struct CadetTunnelAxolotl ax
Struct used for Axolotl.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public key of other key.
struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key
Ratchet key.
struct GNUNET_PILS_Operation * ecdh_op
Operation to derive key material.
CadetTunnelAxolotlCallback cb
Update callback.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
struct GNUNET_CRYPTO_AeadSecretKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
struct GNUNET_CRYPTO_AeadSecretKey RK
32-byte root key which gets updated by DH ratchet.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_AeadSecretKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct GNUNET_CRYPTO_AeadSecretKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_AeadSecretKey HKs
32-byte header key (currently used for sending).
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_AeadSecretKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).
struct GNUNET_CRYPTO_AeadSecretKey HKr
32-byte header key (currently used for receiving)
Struct used to save messages in a non-ready tunnel to send once connected.
struct CadetTunnelQueueEntry * prev
We are entries in a DLL.
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnelQueueEntry * next
We are entries in a DLL.
struct CadetTunnel * t
Tunnel these messages belong in.
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
struct CadetTunnelSkippedKey * next
DLL next.
struct CadetTunnelSkippedKey * prev
DLL prev.
Struct containing all information regarding a tunnel to a peer.
struct GNUNET_SCHEDULER_Task * send_task
Task to send messages from queue (if possible).
struct CadetPeer * destination
Destination of the tunnel.
struct CadetTConnection * connection_ready_head
DLL of ready connections that are actively used to reach the destination peer.
struct CadetTunnelAsync as
Structure to store data temporally for async operations.
struct CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct CadetTunnelQueueEntry * tq_tail
Queued messages, to transmit once tunnel gets connected.
struct GNUNET_SCHEDULER_Task * maintain_connections_task
Task to trim connections if too many are present.
struct CadetTConnection * connection_busy_head
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_TIME_Absolute next_kx_attempt
When do we try the next KX?
struct GNUNET_TIME_Relative kx_retry_delay
How long do we wait until we retry the KX?
struct CadetTConnection * connection_busy_tail
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_MQ_Handle * mq
Dispatcher for decrypted messages only (do NOT use for sending!).
enum CadetTunnelEState estate
State of the tunnel encryption.
struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key
Peer's ephemeral key, to recreate e_key and d_key when own ephemeral key changes.
unsigned int num_busy_connections
Number of connections in the connection_busy_head DLL.
struct CadetTunnelAxolotl ax
Axolotl info.
struct GNUNET_CONTAINER_MultiHashMap32 * channels
Channels inside this tunnel.
struct GNUNET_CRYPTO_AeadSecretKey e_key
Encryption ("our") key.
struct GNUNET_SCHEDULER_Task * destroy_task
Task scheduled if there are no more channels using the tunnel.
struct CadetTConnection * connection_ready_tail
DLL of ready connections that are actively used to reach the destination peer.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for decrypted messages.
struct CadetTunnelQueueEntry * tq_head
Queued messages, to transmit once tunnel gets connected.
unsigned int num_ready_connections
Number of connections in the connection_ready_head DLL.
struct GNUNET_SCHEDULER_Task * kx_task
Task to trigger KX.
struct CadetTunnelAxolotl * unverified_ax
Unverified Axolotl info, used only if we got a fresh KX (not a KX_AUTH) while our end of the tunnel w...
unsigned int tq_len
Number of entries in the tq_head DLL.
struct GNUNET_CADET_ChannelTunnelNumber next_ctn
Channel ID for the next created channel in this tunnel.
int kx_auth_requested
Force triggering KX_AUTH independent of estate.
struct GNUNET_CRYPTO_AeadSecretKey d_key
Decryption ("their") key.
unsigned int unverified_attempts
How often have we tried and failed to decrypt a message using the unverified KX material from unverif...
Closure for iterate_channels_cb.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
uint32_t Ns
Number of messages sent with the current ratchet key.
Message for cadet data traffic.
Message to acknowledge end-to-end data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
uint32_t cn
Which number does this channel have that uniquely identifies it within its tunnel,...
Hash uniquely identifying a connection below a tunnel.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.
struct GNUNET_CRYPTO_AeadMac mac
MAC of the encrypted message, used to verify message integrity.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
Internal representation of the hash map.
type for session keys
unsigned char mac[16]
Initialization vector.
type for session keys
type for (message) authentication keys
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to a message stream tokenizer.
Definition mst.c:45
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

◆ INITIAL_KX_RETRY_DELAY

#define INITIAL_KX_RETRY_DELAY
Value:
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.

How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have connection-level RTT data!

Definition at line 66 of file gnunet-service-cadet_tunnels.c.

◆ MAX_SKIPPED_KEYS

#define MAX_SKIPPED_KEYS   64

Maximum number of skipped keys we keep in memory per tunnel.

Definition at line 72 of file gnunet-service-cadet_tunnels.c.

◆ MAX_KEY_GAP

#define MAX_KEY_GAP   256

Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is either a bogus packet or a DoS-attempt.

Definition at line 78 of file gnunet-service-cadet_tunnels.c.

◆ HIGH_BIT

#define HIGH_BIT   0x8000000

◆ LOG2

#define LOG2 (   level,
  ... 
)
Value:
GNUNET_log_from_nocheck (level, "cadet-tun", \
__VA_ARGS__)
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.

Definition at line 3723 of file gnunet-service-cadet_tunnels.c.

Typedef Documentation

◆ CadetTunnelAxolotlCallback

typedef void(* CadetTunnelAxolotlCallback) (void *cls, enum GNUNET_GenericReturnValue res)

Signature of the follow up function from an udate AX by KX.

Parameters
clsclosure
resresult

Definition at line 264 of file gnunet-service-cadet_tunnels.c.

Function Documentation

◆ GCT_alice_or_betty()

int GCT_alice_or_betty ( const struct GNUNET_PeerIdentity other)

Am I Alice or Betty (some call her Bob), or talking to myself?

Parameters
otherthe other peer
Returns
GNUNET_YES for Alice, GNUNET_NO for Betty, GNUNET_SYSERR if talking to myself

Definition at line 540 of file gnunet-service-cadet_tunnels.c.

541{
542 const struct GNUNET_PeerIdentity *my_identity;
543
546
547 if (0 > GNUNET_memcmp (my_identity, other))
548 return GNUNET_YES;
549 else if (0 < GNUNET_memcmp (my_identity, other))
550 return GNUNET_NO;
551 else
552 {
553 GNUNET_break_op (0);
554 return GNUNET_SYSERR;
555 }
556}

References GNUNET_assert, GNUNET_break_op, GNUNET_memcmp, GNUNET_NO, GNUNET_PILS_get_identity(), GNUNET_SYSERR, GNUNET_YES, my_identity, and pils.

Referenced by GCT_handle_kx(), send_create(), send_kx(), and update_ax_by_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mark_connection_unready()

static void mark_connection_unready ( struct CadetTConnection ct)
static

Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.

Parameters
ctconnection to move to unready status

Definition at line 566 of file gnunet-service-cadet_tunnels.c.

567{
568 struct CadetTunnel *t = ct->t;
569
571 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
572 t->connection_ready_tail,
573 ct);
574 GNUNET_assert (0 < t->num_ready_connections);
575 t->num_ready_connections--;
576 ct->is_ready = GNUNET_NO;
577 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
578 t->connection_busy_tail,
579 ct);
580 t->num_busy_connections++;
581}

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_NO, GNUNET_YES, CadetTConnection::is_ready, t, and CadetTConnection::t.

Referenced by connection_ready_cb(), send_kx(), send_kx_auth(), and try_send_normal_payload().

Here is the caller graph for this function:

◆ GCT_2s()

const char * GCT_2s ( const struct CadetTunnel t)

Get the static string for the peer this tunnel is directed.

Parameters
tTunnel.
Returns
Static string the destination peer's ID.

Definition at line 592 of file gnunet-service-cadet_tunnels.c.

593{
594 static char buf[64];
595
596 if (NULL == t)
597 return "Tunnel(NULL)";
598 GNUNET_snprintf (buf,
599 sizeof(buf),
600 "Tunnel %s",
601 GNUNET_i2s (GCP_get_id (t->destination)));
602 return buf;
603}

References GCP_get_id(), GNUNET_i2s(), GNUNET_snprintf(), and t.

Referenced by connection_ready_cb(), consider_path_cb(), cont_GCT_handle_kx(), cont_GCT_handle_kx_auth(), destroy_tunnel(), GCC_2s(), GCCH_bind(), GCCH_channel_local_new(), GCCH_debug(), GCP_drop_tunnel(), GCT_add_channel(), GCT_add_inbound_connection(), GCT_change_estate(), GCT_consider_path(), GCT_debug(), GCT_handle_encrypted(), GCT_handle_kx(), GCT_handle_kx_auth(), GCT_remove_channel(), GCT_send(), handle_plaintext_channel_destroy(), handle_plaintext_channel_open(), handle_plaintext_channel_open_ack(), handle_plaintext_keepalive(), maintain_connections_cb(), retry_kx(), send_keepalive(), send_kx(), send_kx_auth(), try_send_normal_payload(), and update_state().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ estate2s()

static const char * estate2s ( enum CadetTunnelEState  es)
static

Get string description for tunnel encryption state.

Parameters
esTunnel state.
Returns
String representation.

Definition at line 614 of file gnunet-service-cadet_tunnels.c.

615{
616 static char buf[32];
617
618 switch (es)
619 {
621 return "CADET_TUNNEL_KEY_UNINITIALIZED";
623 return "CADET_TUNNEL_KEY_AX_RECV";
625 return "CADET_TUNNEL_KEY_AX_SENT";
627 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
629 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
631 return "CADET_TUNNEL_KEY_OK";
632 }
633 GNUNET_snprintf (buf,
634 sizeof(buf),
635 "%u (UNKNOWN STATE)",
636 es);
637 return buf;
638}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, and GNUNET_snprintf().

Referenced by connection_ready_cb(), GCT_change_estate(), GCT_debug(), retry_kx(), and send_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_get_destination()

struct CadetPeer * GCT_get_destination ( struct CadetTunnel t)

Return the peer to which this tunnel goes.

Parameters
ta tunnel
Returns
the destination of the tunnel

Definition at line 648 of file gnunet-service-cadet_tunnels.c.

649{
650 return t->destination;
651}

References t.

Referenced by GCCH_2s(), GCCH_bind(), GCCH_channel_incoming_new(), get_next_free_ctn(), and timeout_closed_cb().

Here is the caller graph for this function:

◆ GCT_count_channels()

unsigned int GCT_count_channels ( struct CadetTunnel t)

Returns the number of channels using a tunnel.

Parameters
tTunnel in question.
Returns
Number of channels using the tunnel.

Definition at line 655 of file gnunet-service-cadet_tunnels.c.

656{
657 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
658}

References GNUNET_CONTAINER_multihashmap32_size(), and t.

Referenced by connection_ready_cb(), destroy_tunnel(), GCT_destroy_tunnel_now(), GCT_remove_channel(), get_all_tunnels_iterator(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_channel()

static struct CadetChannel * lookup_channel ( struct CadetTunnel t,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)
static

Lookup a channel by its ctn.

Parameters
ttunnel to look in
ctnnumber of channel to find
Returns
NULL if channel does not exist

Definition at line 669 of file gnunet-service-cadet_tunnels.c.

671{
672 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
673 ntohl (ctn.cn));
674}

References GNUNET_CADET_ChannelTunnelNumber::cn, CadetChannel::ctn, GNUNET_CONTAINER_multihashmap32_get(), and t.

Referenced by GCT_send(), handle_plaintext_channel_destroy(), handle_plaintext_channel_open_ack(), handle_plaintext_data(), and handle_plaintext_data_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_count_any_connections()

unsigned int GCT_count_any_connections ( const struct CadetTunnel t)

Counts the number of connections created for a tunnel, including busy connections.

Parameters
tTunnel to be counted.
Returns
Number of connections created for the tunnel.

Definition at line 678 of file gnunet-service-cadet_tunnels.c.

679{
680 return t->num_ready_connections + t->num_busy_connections;
681}

References t.

Referenced by consider_path_cb(), GCT_debug(), get_all_tunnels_iterator(), and maintain_connections_cb().

Here is the caller graph for this function:

◆ get_ready_connection()

static struct CadetTConnection * get_ready_connection ( struct CadetTunnel t)
static

Find first connection that is ready in the list of our connections.

Picks ready connections round-robin.

Parameters
ttunnel to search
Returns
NULL if we have no connection that is ready

Definition at line 692 of file gnunet-service-cadet_tunnels.c.

693{
694 struct CadetTConnection *hd = t->connection_ready_head;
695
696 GNUNET_assert ((NULL == hd) ||
697 (GNUNET_YES == hd->is_ready));
698 return hd;
699}

References GNUNET_assert, GNUNET_YES, CadetTConnection::is_ready, and t.

Referenced by send_kx(), send_kx_auth(), and trigger_transmissions().

Here is the caller graph for this function:

◆ GCT_get_estate()

enum CadetTunnelEState GCT_get_estate ( struct CadetTunnel t)

Get the encryption state of a tunnel.

Parameters
tTunnel.
Returns
Tunnel's encryption state.

Definition at line 710 of file gnunet-service-cadet_tunnels.c.

711{
712 return t->estate;
713}

References t.

Referenced by get_all_tunnels_iterator(), handle_connection_create(), send_create(), and send_keepalive().

Here is the caller graph for this function:

◆ trigger_transmissions()

static void trigger_transmissions ( void *  cls)
static

Called when either we have a new connection, or a new message in the queue, or some existing connection has transmission capacity.

Looks at our message queue and if there is a message, picks a connection to send it on.

Parameters
clsthe struct CadetTunnel to process messages on

Definition at line 2597 of file gnunet-service-cadet_tunnels.c.

2598{
2599 struct CadetTunnel *t = cls;
2600 struct CadetTConnection *ct;
2601
2602 t->send_task = NULL;
2603 if (NULL == t->tq_head)
2604 return; /* no messages pending right now */
2605 ct = get_ready_connection (t);
2606 if (NULL == ct)
2607 return; /* no connections ready */
2609 ct);
2610}

References get_ready_connection(), t, and try_send_normal_payload().

Referenced by GCT_change_estate(), GCT_handle_encrypted(), and GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_ephemeral()

static void new_ephemeral ( struct CadetTunnelAxolotl ax)
static

Create a new Axolotl ephemeral (ratchet) key.

Parameters
axkey material to update

Definition at line 737 of file gnunet-service-cadet_tunnels.c.

738{
740 "Creating new ephemeral ratchet key (DHRs)\n");
742}

References CadetTunnelAxolotl::DHRs, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_ERROR_TYPE_DEBUG, and LOG.

Referenced by GCT_create_tunnel(), and t_ax_encrypt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_hmac_hash()

static void t_ax_hmac_hash ( const struct GNUNET_CRYPTO_AeadSecretKey key,
struct GNUNET_HashCode hash,
const void *  source,
unsigned int  len 
)
static

Perform a HMAC.

Parameters
keyKey to use.
[out]hashResulting HMAC.
sourceSource key material (data to HMAC).
lenLength of source.

Definition at line 754 of file gnunet-service-cadet_tunnels.c.

758{
759 static const char ctx[] = "axolotl HMAC-HASH";
760 struct GNUNET_CRYPTO_AuthKey auth_key;
761
763 &auth_key,
764 sizeof auth_key,
765 ctx,
766 sizeof(ctx),
767 key,
768 sizeof *key);
769 GNUNET_CRYPTO_hmac (&auth_key,
770 source,
771 len,
772 hash);
773}

References ctx, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_hmac(), key, and source.

Referenced by t_ax_decrypt_and_validate(), t_ax_encrypt(), and t_hmac_derive_key().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_hmac_derive_key()

static void t_hmac_derive_key ( const struct GNUNET_CRYPTO_AeadSecretKey key,
struct GNUNET_CRYPTO_AeadSecretKey out,
const void *  source,
unsigned int  len 
)
static

Derive a symmetric encryption key from an HMAC-HASH.

Parameters
keyKey to use for the HMAC.
[out]outKey to generate.
sourceSource key material (data to HMAC).
lenLength of source.

Definition at line 785 of file gnunet-service-cadet_tunnels.c.

789{
790 static const char ctx[] = "axolotl derive key";
791 struct GNUNET_HashCode h;
792
794 &h,
795 source,
796 len);
798 out, sizeof(*out),
799 ctx, sizeof(ctx),
800 &h, sizeof(h));
801}

References ctx, GNUNET_CRYPTO_hkdf_gnunet, h, key, source, and t_ax_hmac_hash().

Referenced by store_skipped_key(), t_ax_decrypt(), and t_ax_encrypt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_encrypt()

static void t_ax_encrypt ( struct CadetTunnelAxolotl ax,
void *  dst,
const void *  src,
size_t  size 
)
static

Encrypt data with the axolotl tunnel key.

Parameters
axkey material to use.
dstDestination with size bytes for the encrypted data.
srcSource of the plaintext. Can overlap with dst, must contain size bytes
sizeSize of the buffers at src and dst

Definition at line 813 of file gnunet-service-cadet_tunnels.c.

817{
819 struct GNUNET_CRYPTO_AeadNonce iv;
821
822 ax->ratchet_counter++;
823 if ((GNUNET_YES == ax->ratchet_allowed) &&
824 ((ratchet_messages <= ax->ratchet_counter) ||
827 {
829 }
830 if (GNUNET_YES == ax->ratchet_flag)
831 {
832 /* Advance ratchet */
833 struct GNUNET_CRYPTO_AeadSecretKey keys[3];
834 struct GNUNET_HashCode dh;
835 struct GNUNET_HashCode hmac;
836 static const char ctx[] = "axolotl ratchet";
837
838 new_ephemeral (ax);
839 ax->HKs = ax->NHKs;
840
841 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
843 &ax->DHRr,
844 &dh);
845 t_ax_hmac_hash (&ax->RK,
846 &hmac,
847 &dh,
848 sizeof(dh));
850 keys, sizeof(keys),
851 ctx, sizeof(ctx),
852 &hmac, sizeof(hmac));
853 ax->RK = keys[0];
854 ax->NHKs = keys[1];
855 ax->CKs = keys[2];
856
857 ax->PNs = ax->Ns;
858 ax->Ns = 0;
861 ax->ratchet_counter = 0;
865 }
866
868 &MK,
869 "0",
870 1);
871
873 sizeof iv,
874 NULL,
875 0,
876 &MK,
877 sizeof MK);
878
879 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) dst)[size];
881 src,
882 0,
883 NULL,
884 &MK,
885 &iv,
886 dst,
887 mac));
889 &ax->CKs,
890 "1",
891 1);
892}

References CadetTunnelAxolotl::CKs, ctx, CadetTunnelAxolotl::DHRr, CadetTunnelAxolotl::DHRs, GNUNET_assert, GNUNET_CRYPTO_aead_encrypt(), GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_NO, GNUNET_OK, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, CadetTunnelAxolotl::HKs, GNUNET_CRYPTO_AeadMac::mac, new_ephemeral(), CadetTunnelAxolotl::NHKs, CadetTunnelAxolotl::Ns, CadetTunnelAxolotl::PNs, CadetTunnelAxolotl::ratchet_allowed, CadetTunnelAxolotl::ratchet_counter, CadetTunnelAxolotl::ratchet_expiration, CadetTunnelAxolotl::ratchet_flag, ratchet_time, GNUNET_TIME_Relative::rel_value_us, CadetTunnelAxolotl::RK, size, t_ax_hmac_hash(), and t_hmac_derive_key().

Referenced by GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_decrypt()

static void t_ax_decrypt ( struct CadetTunnelAxolotl ax,
void *  dst,
const void *  src,
size_t  size 
)
static

Decrypt data with the axolotl tunnel key.

Parameters
axkey material to use.
dstDestination for the decrypted data, must contain size bytes.
srcSource of the ciphertext. Can overlap with dst, must contain size bytes.
sizeSize of the src and dst buffers

Definition at line 904 of file gnunet-service-cadet_tunnels.c.

908{
910 struct GNUNET_CRYPTO_AeadNonce iv;
912 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
913
915 &MK,
916 "0",
917 1);
918
920 sizeof iv,
921 NULL,
922 0,
923 &MK,
924 sizeof MK);
925 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
926 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) src)[macoffset];
928 src,
929 0,
930 NULL,
931 &MK,
932 &iv,
933 mac,
934 dst));
936 &ax->CKr,
937 "1",
938 1);
939}

References CadetTunnelAxolotl::CKr, GNUNET_assert, GNUNET_CRYPTO_aead_decrypt(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_OK, GNUNET_CRYPTO_AeadMac::mac, size, and t_hmac_derive_key().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_h_encrypt()

static void t_h_encrypt ( struct CadetTunnelAxolotl ax,
struct GNUNET_CADET_TunnelEncryptedMessage msg,
size_t  additional_data_size,
const unsigned char *  additional_data 
)
static

Encrypt header with the axolotl header key.

Parameters
axkey material to use.
[in,out]msgMessage whose header to encrypt.

Definition at line 949 of file gnunet-service-cadet_tunnels.c.

953{
954 struct GNUNET_CRYPTO_AeadNonce nonce;
955
957 sizeof nonce,
958 NULL,
959 0,
960 &ax->HKs,
961 sizeof ax->HKs);
963 ,
964 (unsigned char*) &msg
965 ->ax_header,
966 additional_data_size,
967 additional_data,
968 &ax->HKs,
969 &nonce,
970 &msg->ax_header,
971 &msg->mac));
972}

References GNUNET_assert, GNUNET_CRYPTO_aead_encrypt(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_OK, CadetTunnelAxolotl::HKs, and msg.

Referenced by GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_h_decrypt()

static enum GNUNET_GenericReturnValue t_h_decrypt ( const struct GNUNET_CRYPTO_AeadSecretKey hkr,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
size_t  esize,
struct GNUNET_CADET_TunnelEncryptedMessage dst 
)
static

Decrypt header with the current axolotl header key.

Parameters
hkrkey material to use.
srcMessage whose header to decrypt.
esizesize of encrypted payload after message
dstWhere to decrypt header to.
Returns
GNUNET_OK if MAC was validated successfully

Definition at line 985 of file gnunet-service-cadet_tunnels.c.

989{
990 struct GNUNET_CRYPTO_AeadNonce iv;
991
993 sizeof iv,
994 NULL,
995 0,
996 hkr,
997 sizeof *hkr);
998
999
1001 (unsigned char*) &src->ax_header,
1002 esize,
1003 (unsigned char*) &src[1],
1004 hkr,
1005 &iv,
1006 &dst->mac,
1007 &dst->ax_header);
1008}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, GNUNET_CRYPTO_aead_decrypt(), GNUNET_CRYPTO_hkdf_gnunet, and GNUNET_CADET_TunnelEncryptedMessage::mac.

Referenced by t_ax_decrypt_and_validate(), and try_old_ax_keys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ delete_skipped_key()

static void delete_skipped_key ( struct CadetTunnelAxolotl ax,
struct CadetTunnelSkippedKey key 
)
static

Delete a key from the list of skipped keys.

Parameters
axkey material to delete key from.
keyKey to delete.

Definition at line 1018 of file gnunet-service-cadet_tunnels.c.

1020{
1022 ax->skipped_tail,
1023 key);
1024 GNUNET_free (key);
1025 ax->skipped--;
1026}

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, key, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_head, and CadetTunnelAxolotl::skipped_tail.

Referenced by cleanup_ax(), store_ax_keys(), and try_old_ax_keys().

Here is the caller graph for this function:

◆ try_old_ax_keys()

static ssize_t try_old_ax_keys ( struct CadetTunnelAxolotl ax,
void *  dst,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
size_t  size 
)
static

Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.

Parameters
axkey material to use.
dstDestination for the plaintext.
srcSource of the message. Can overlap with dst.
sizeSize of the message.
Returns
Size of the decrypted data, -1 if an error was encountered.

Definition at line 1040 of file gnunet-service-cadet_tunnels.c.

1044{
1045 struct CadetTunnelSkippedKey *key;
1046 struct GNUNET_CRYPTO_AeadNonce iv;
1047 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1048 struct GNUNET_CRYPTO_AeadSecretKey *valid_HK;
1049 size_t esize;
1050 size_t len;
1051 unsigned int N;
1052 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
1053
1055 "Trying skipped keys\n");
1056 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1057 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1059 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1060 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1061
1062 /* Find a correct Header Key */
1063 valid_HK = NULL;
1064 for (key = ax->skipped_head; NULL != key; key = key->next)
1065 {
1066 /* Try decrypt header */
1067 if (GNUNET_OK == t_h_decrypt (&key->HK,
1068 src,
1069 esize,
1070 &plaintext_header))
1071 {
1072 valid_HK = &key->HK;
1073 }
1074 }
1075 if (NULL == key)
1076 return -1;
1077
1078 /* Find the correct message key */
1079 N = ntohl (plaintext_header.ax_header.Ns);
1080 while ((NULL != key) &&
1081 (N != key->Kn))
1082 key = key->next;
1083 if ((NULL == key) ||
1084 (0 != GNUNET_memcmp (&key->HK,
1085 valid_HK)))
1086 return -1;
1087
1088 /* Decrypt payload */
1090 sizeof iv,
1091 NULL,
1092 0,
1093 &key->MK,
1094 sizeof key->MK);
1095
1097 len,
1098 (unsigned char*) &src[1],
1099 0,
1100 NULL,
1101 &key->MK,
1102 &iv,
1103 (struct GNUNET_CRYPTO_AeadMac*) &src[macoffset],
1104 dst))
1105 {
1106 return -1;
1107 }
1109 key);
1110 return len - sizeof (struct GNUNET_CRYPTO_AeadMac);
1111}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, delete_skipped_key(), GNUNET_assert, GNUNET_CRYPTO_aead_decrypt(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_OK, key, LOG, N, GNUNET_CADET_AxHeader::Ns, size, CadetTunnelAxolotl::skipped_head, and t_h_decrypt().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_skipped_key()

static void store_skipped_key ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CRYPTO_AeadSecretKey HKr 
)
static

Delete a key from the list of skipped keys.

Parameters
axkey material to delete from.
HKrHeader Key to use.

Definition at line 1121 of file gnunet-service-cadet_tunnels.c.

1123{
1124 struct CadetTunnelSkippedKey *key;
1125
1127 key->timestamp = GNUNET_TIME_absolute_get ();
1128 key->Kn = ax->Nr;
1129 key->HK = ax->HKr;
1130 t_hmac_derive_key (&ax->CKr,
1131 &key->MK,
1132 "0",
1133 1);
1134 t_hmac_derive_key (&ax->CKr,
1135 &ax->CKr,
1136 "1",
1137 1);
1139 ax->skipped_tail,
1140 key);
1141 ax->skipped++;
1142 ax->Nr++;
1143}

References CadetTunnelAxolotl::CKr, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_TIME_absolute_get(), CadetTunnelAxolotl::HKr, key, CadetTunnelAxolotl::Nr, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_head, CadetTunnelAxolotl::skipped_tail, and t_hmac_derive_key().

Referenced by store_ax_keys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_ax_keys()

static int store_ax_keys ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CRYPTO_AeadSecretKey HKr,
uint32_t  Np 
)
static

Stage skipped AX keys and calculate the message key.

Stores each HK and MK for skipped messages.

Parameters
axkey material to use
HKrHeader key.
NpReceived message number.
Returns
GNUNET_OK if keys were stored. GNUNET_SYSERR if an error occurred (Np not expected).

Definition at line 1157 of file gnunet-service-cadet_tunnels.c.

1160{
1161 int gap;
1162
1163 gap = Np - ax->Nr;
1165 "Storing skipped keys [%u, %u)\n",
1166 ax->Nr,
1167 Np);
1168 if (MAX_KEY_GAP < gap)
1169 {
1170 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1171 /* TODO: start new key exchange on return */
1172 GNUNET_break_op (0);
1174 "Got message %u, expected %u+\n",
1175 Np,
1176 ax->Nr);
1177 return GNUNET_SYSERR;
1178 }
1179 if (0 > gap)
1180 {
1181 /* Delayed message: don't store keys, flag to try old keys. */
1182 return GNUNET_SYSERR;
1183 }
1184
1185 while (ax->Nr < Np)
1187 HKr);
1188
1189 while (ax->skipped > MAX_SKIPPED_KEYS)
1191 ax->skipped_tail);
1192 return GNUNET_OK;
1193}

References delete_skipped_key(), GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, LOG, MAX_KEY_GAP, MAX_SKIPPED_KEYS, CadetTunnelAxolotl::Nr, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_tail, and store_skipped_key().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_decrypt_and_validate()

static ssize_t t_ax_decrypt_and_validate ( struct CadetTunnelAxolotl ax,
void *  dst,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
size_t  size 
)
static

Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.

Parameters
axkey material to use
dstDestination for the plaintext.
srcSource of the message. Can overlap with dst.
sizeSize of the message.
Returns
Size of the decrypted data, -1 if an error was encountered.

Definition at line 1207 of file gnunet-service-cadet_tunnels.c.

1212{
1213 struct GNUNET_HashCode hmac;
1214 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1215 uint32_t Np;
1216 uint32_t PNp;
1217 size_t esize; /* Size of encrypted payload */
1218
1219 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1220
1221 if (GNUNET_OK == t_h_decrypt (&ax->HKr,
1222 src,
1223 esize,
1224 &plaintext_header))
1225 {
1226 Np = ntohl (plaintext_header.ax_header.Ns);
1227 PNp = ntohl (plaintext_header.ax_header.PNs);
1228 }
1229 else
1230 {
1231 static const char ctx[] = "axolotl ratchet";
1232 struct GNUNET_CRYPTO_AeadSecretKey keys[3]; /* RKp, NHKp, CKp */
1234 struct GNUNET_HashCode dh;
1235 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1236
1237 /* Try Next HK */
1238 if (GNUNET_OK == t_h_decrypt (&ax->NHKr,
1239 src,
1240 esize,
1241 &plaintext_header))
1242 {
1243 /* Try the skipped keys, if that fails, we're out of luck. */
1244 return try_old_ax_keys (ax,
1245 dst,
1246 src,
1247 size);
1248 }
1249 HK = ax->HKr;
1250 ax->HKr = ax->NHKr;
1251 Np = ntohl (plaintext_header.ax_header.Ns);
1252 PNp = ntohl (plaintext_header.ax_header.PNs);
1253 DHRp = &plaintext_header.ax_header.DHRs;
1254 store_ax_keys (ax,
1255 &HK,
1256 PNp);
1257
1258 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1260 DHRp,
1261 &dh);
1262 t_ax_hmac_hash (&ax->RK,
1263 &hmac,
1264 &dh, sizeof(dh));
1266 keys, sizeof(keys),
1267 ctx, sizeof(ctx),
1268 &hmac, sizeof(hmac));
1269
1270 /* Commit "purported" keys */
1271 ax->RK = keys[0];
1272 ax->NHKr = keys[1];
1273 ax->CKr = keys[2];
1274 ax->DHRr = *DHRp;
1275 ax->Nr = 0;
1277
1278 }
1279 if ((Np != ax->Nr) &&
1280 (GNUNET_OK != store_ax_keys (ax,
1281 &ax->HKr,
1282 Np)))
1283 {
1284 /* Try the skipped keys, if that fails, we're out of luck. */
1285 return try_old_ax_keys (ax,
1286 dst,
1287 src,
1288 size);
1289 }
1290
1291 t_ax_decrypt (ax,
1292 dst,
1293 &src[1],
1294 esize);
1295 ax->Nr = Np + 1;
1296 return esize - sizeof (struct GNUNET_CRYPTO_AeadMac);
1297}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, CadetTunnelAxolotl::CKr, ctx, CadetTunnelAxolotl::DHRr, GNUNET_CADET_AxHeader::DHRs, CadetTunnelAxolotl::DHRs, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_OK, GNUNET_YES, CadetTunnelAxolotl::HKr, CadetTunnelAxolotl::NHKr, CadetTunnelAxolotl::Nr, GNUNET_CADET_AxHeader::Ns, GNUNET_CADET_AxHeader::PNs, CadetTunnelAxolotl::ratchet_allowed, CadetTunnelAxolotl::RK, size, store_ax_keys(), t_ax_decrypt(), t_ax_hmac_hash(), t_h_decrypt(), and try_old_ax_keys().

Referenced by GCT_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ notify_tunnel_up_cb()

static int notify_tunnel_up_cb ( void *  cls,
uint32_t  key,
void *  value 
)
static

Our tunnel became ready for the first time, notify channels that have been waiting.

Parameters
clsour tunnel, not used
keyunique ID of the channel, not used
valuethe struct CadetChannel to notify
Returns
GNUNET_OK (continue to iterate)

Definition at line 1310 of file gnunet-service-cadet_tunnels.c.

1313{
1314 struct CadetChannel *ch = value;
1315
1317 return GNUNET_OK;
1318}

References ch, GCCH_tunnel_up(), GNUNET_OK, and value.

Referenced by GCT_change_estate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_change_estate()

void GCT_change_estate ( struct CadetTunnel t,
enum CadetTunnelEState  state 
)

Change the tunnel encryption state.

If the encryption state changes to OK, stop the rekey task.

Parameters
tTunnel whose encryption state to change, or NULL.
stateNew encryption state.

Definition at line 1329 of file gnunet-service-cadet_tunnels.c.

1331{
1332 enum CadetTunnelEState old = t->estate;
1333
1334 t->estate = state;
1336 "%s estate changed from %s to %s\n",
1337 GCT_2s (t),
1338 estate2s (old),
1339 estate2s (state));
1340
1341 if ((CADET_TUNNEL_KEY_OK != old) &&
1342 (CADET_TUNNEL_KEY_OK == t->estate))
1343 {
1344 if (NULL != t->kx_task)
1345 {
1346 GNUNET_SCHEDULER_cancel (t->kx_task);
1347 t->kx_task = NULL;
1348 }
1349 /* notify all channels that have been waiting */
1352 t);
1353 if (NULL != t->send_task)
1354 GNUNET_SCHEDULER_cancel (t->send_task);
1356 t);
1357 }
1358}

References CADET_TUNNEL_KEY_OK, estate2s(), GCT_2s(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), LOG, notify_tunnel_up_cb(), state, t, and trigger_transmissions().

Referenced by cont_GCT_handle_kx(), cont_GCT_handle_kx_auth(), GCT_handle_encrypted(), handle_connection_create(), send_kx(), and send_kx_auth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_kx()

static void send_kx ( struct CadetTunnel t,
struct CadetTConnection ct,
struct CadetTunnelAxolotl ax 
)
static

Send a KX message.

Parameters
ttunnel on which to send the KX_AUTH
ctTunnel and connection on which to send the KX_AUTH, NULL if we are to find one that is ready.
axaxolotl key context to use

Definition at line 1370 of file gnunet-service-cadet_tunnels.c.

1373{
1374 struct CadetConnection *cc;
1375 struct GNUNET_MQ_Envelope *env;
1378
1379 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1380 return; /* only Alice may send KX */
1381 if ((NULL == ct) ||
1382 (GNUNET_NO == ct->is_ready))
1383 ct = get_ready_connection (t);
1384 if (NULL == ct)
1385 {
1387 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1388 GCT_2s (t),
1389 estate2s (t->estate));
1390 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1391 return;
1392 }
1393 cc = ct->cc;
1396 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1397 msg->flags = htonl (flags);
1398 msg->cid = *GCC_get_id (cc);
1400 &msg->ephemeral_key);
1401#if DEBUG_KX
1402 msg->ephemeral_key_XXX = ax->kx_0;
1403#endif
1405 "Sending KX message to %s with ephemeral %s on CID %s\n",
1406 GCT_2s (t),
1407 GNUNET_e2s (&msg->ephemeral_key),
1408 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1410 &msg->ratchet_key);
1412 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1413 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1414 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1417 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1420 GCC_transmit (cc,
1421 env);
1423 "# KX transmitted",
1424 1,
1425 GNUNET_NO);
1426}

References CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_UNINITIALIZED, CadetTConnection::cc, CadetTunnelAxolotl::DHRs, env, estate2s(), GNUNET_CADET_TunnelKeyExchangeMessage::flags, GCC_get_id(), GCC_transmit(), GCP_get_id(), GCT_2s(), GCT_alice_or_betty(), GCT_change_estate(), get_ready_connection(), GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, GNUNET_MQ_msg, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetTConnection::is_ready, CadetTunnelAxolotl::kx_0, LOG, mark_connection_unready(), msg, stats, and t.

Referenced by connection_ready_cb(), GCT_handle_encrypted(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_kx_auth()

static void send_kx_auth ( struct CadetTunnel t,
struct CadetTConnection ct,
struct CadetTunnelAxolotl ax,
int  force_reply 
)
static

Send a KX_AUTH message.

Parameters
ttunnel on which to send the KX_AUTH
ctTunnel and connection on which to send the KX_AUTH, NULL if we are to find one that is ready.
axaxolotl key context to use
force_replyForce the other peer to reply with a KX_AUTH message (set if we would like to transmit right now, but cannot)

Definition at line 1440 of file gnunet-service-cadet_tunnels.c.

1444{
1445 struct CadetConnection *cc;
1446 struct GNUNET_MQ_Envelope *env;
1448 enum GNUNET_CADET_KX_Flags flags;
1449
1450 if ((NULL == ct) ||
1451 (GNUNET_NO == ct->is_ready))
1452 ct = get_ready_connection (t);
1453 if (NULL == ct)
1454 {
1456 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1457 GCT_2s (t));
1458 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1459 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1460 return;
1461 }
1462 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1463 cc = ct->cc;
1467 if (GNUNET_YES == force_reply)
1469 msg->kx.flags = htonl (flags);
1470 msg->kx.cid = *GCC_get_id (cc);
1472 &msg->kx.ephemeral_key);
1474 &msg->kx.ratchet_key);
1475#if DEBUG_KX
1476 msg->kx.ephemeral_key_XXX = ax->kx_0;
1477 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1478#endif
1480 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1481 GCT_2s (t),
1482 GNUNET_e2s (&msg->kx.ephemeral_key),
1483 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1484
1485 /* Compute authenticator (this is the main difference to #send_kx()) */
1486 GNUNET_CRYPTO_hash (&ax->RK,
1487 sizeof(ax->RK),
1488 &msg->auth);
1489 /* Compute when to be triggered again; actual job will
1490 be scheduled via #connection_ready_cb() */
1491 t->kx_retry_delay
1492 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1493 t->next_kx_attempt
1494 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1495
1496 /* Send via cc, mark it as unready */
1498
1499 /* Update state machine, unless we are already OK */
1500 if (CADET_TUNNEL_KEY_OK != t->estate)
1503 GCC_transmit (cc,
1504 env);
1506 "# KX_AUTH transmitted",
1507 1,
1508 GNUNET_NO);
1509}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_OK, CadetTConnection::cc, CadetTunnelAxolotl::DHRs, env, GCC_get_id(), GCC_transmit(), GCT_2s(), GCT_change_estate(), get_ready_connection(), GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CADET_KX_FLAG_NONE, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH, GNUNET_MQ_msg, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetTConnection::is_ready, CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::last_ephemeral, LOG, mark_connection_unready(), msg, CadetTunnelAxolotl::RK, stats, and t.

Referenced by connection_ready_cb(), cont_GCT_handle_kx_auth(), GCT_handle_encrypted(), GCT_handle_kx(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_ax()

static void cleanup_ax ( struct CadetTunnelAxolotl ax)
static

Cleanup state used by ax.

Parameters
axstate to free, but not memory of ax itself

Definition at line 1518 of file gnunet-service-cadet_tunnels.c.

1519{
1520 while (NULL != ax->skipped_head)
1522 ax->skipped_head);
1523 GNUNET_assert (0 == ax->skipped);
1526}

References delete_skipped_key(), CadetTunnelAxolotl::DHRs, GNUNET_assert, GNUNET_CRYPTO_ecdhe_key_clear(), CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::skipped, and CadetTunnelAxolotl::skipped_head.

Referenced by cont_GCT_handle_kx_auth(), destroy_tunnel(), and GCT_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_ax_by_kx()

static void update_ax_by_kx ( void *  cls,
const struct GNUNET_HashCode key_result 
)
static

Update our Axolotl key state based on the KX data we received.

Computes the new chain keys, and root keys, etc, and also checks whether this is a replay of the current chain.

Parameters
clsclosure using the async structure for Axolotl
key_resultecdh result from the ephemeral public key of the other peer
Returns
GNUNET_OK on success, GNUNET_NO if the resulting root key is already in ax and thus the KX is useless; GNUNET_SYSERR on hard errors

Definition at line 1541 of file gnunet-service-cadet_tunnels.c.

1543{
1544 struct CadetTunnelAsync *as;
1545 struct GNUNET_HashCode key_material[3];
1546 struct GNUNET_CRYPTO_AeadSecretKey keys[5];
1547 struct CadetTunnelAxolotl *ax;
1548 const struct GNUNET_PeerIdentity *pid;
1549 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1550 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1551 const char salt[] = "CADET Axolotl salt";
1552 int am_I_alice;
1553
1554 as = cls;
1555 ax = &as->ax;
1556 pid = &as->peer_id;
1557 ephemeral_key = &as->ephemeral_key;
1558 ratchet_key = &as->ratchet_key;
1559
1560 as->ecdh_op = NULL;
1561
1563 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1564 GNUNET_e2s (ephemeral_key));
1565
1566 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1567 {
1568 GNUNET_break_op (0);
1569 if (as->cb)
1570 as->cb (as->cb_cls, GNUNET_SYSERR);
1571 return;
1572 }
1573
1574 if (0 == GNUNET_memcmp (&ax->DHRr,
1575 ratchet_key))
1576 {
1578 "# Ratchet key already known",
1579 1,
1580 GNUNET_NO);
1582 "Ratchet key already known. Ignoring KX.\n");
1583 if (as->cb)
1584 as->cb (as->cb_cls, GNUNET_NO);
1585 return;
1586 }
1587
1588 ax->DHRr = *ratchet_key;
1589 ax->last_ephemeral = *ephemeral_key;
1590 /* ECDH A B0 */
1591 if (GNUNET_YES == am_I_alice)
1592 {
1593 GNUNET_memcpy (&key_material[0], key_result,
1594 sizeof (*key_result));
1595 }
1596 else
1597 {
1598 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1599 &pid->public_key, /* A */
1600 &key_material[0]);
1601 }
1602 /* ECDH A0 B */
1603 if (GNUNET_YES == am_I_alice)
1604 {
1605 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1606 &pid->public_key, /* B */
1607 &key_material[1]);
1608 }
1609 else
1610 {
1611 GNUNET_memcpy (&key_material[1], key_result,
1612 sizeof (*key_result));
1613 }
1614
1615 /* ECDH A0 B0 */
1616 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1617 ephemeral_key, /* B0 or A0 */
1618 &key_material[2]);
1619 /* KDF */
1621 keys, sizeof(keys),
1622 salt, sizeof(salt),
1623 &key_material, sizeof(key_material));
1624
1625 if (0 == memcmp (&ax->RK,
1626 &keys[0],
1627 sizeof(ax->RK)))
1628 {
1630 "Root key already known. Ignoring KX.\n");
1632 "# Root key already known",
1633 1,
1634 GNUNET_NO);
1635 if (as->cb)
1636 as->cb (as->cb_cls, GNUNET_NO);
1637 return;
1638 }
1639
1640 ax->RK = keys[0];
1641 if (GNUNET_YES == am_I_alice)
1642 {
1643 ax->HKr = keys[1];
1644 ax->NHKs = keys[2];
1645 ax->NHKr = keys[3];
1646 ax->CKr = keys[4];
1648 }
1649 else
1650 {
1651 ax->HKs = keys[1];
1652 ax->NHKr = keys[2];
1653 ax->NHKs = keys[3];
1654 ax->CKs = keys[4];
1655 ax->ratchet_flag = GNUNET_NO;
1658 ratchet_time);
1659 }
1660
1661 if (as->cb)
1662 as->cb (as->cb_cls, GNUNET_OK);
1663}

References CadetTunnelAsync::ax, CadetTunnelAsync::cb, CadetTunnelAsync::cb_cls, CadetTunnelAxolotl::CKr, CadetTunnelAxolotl::CKs, CadetTunnelAxolotl::DHRr, CadetTunnelAsync::ecdh_op, CadetTunnelAsync::ephemeral_key, GCT_alice_or_betty(), GNUNET_break_op, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_ecdh_eddsa(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_YES, CadetTunnelAxolotl::HKr, CadetTunnelAxolotl::HKs, CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::last_ephemeral, LOG, CadetTunnelAxolotl::NHKr, CadetTunnelAxolotl::NHKs, CadetTunnelAsync::peer_id, pid, GNUNET_PeerIdentity::public_key, CadetTunnelAxolotl::ratchet_expiration, CadetTunnelAxolotl::ratchet_flag, CadetTunnelAsync::ratchet_key, ratchet_time, CadetTunnelAxolotl::RK, salt, and stats.

Referenced by GCT_handle_kx(), and GCT_handle_kx_auth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retry_kx()

static void retry_kx ( void *  cls)
static

Try to redo the KX or KX_AUTH handshake, if we can.

Parameters
clsthe struct CadetTunnel to do KX for.

Definition at line 1672 of file gnunet-service-cadet_tunnels.c.

1673{
1674 struct CadetTunnel *t = cls;
1675 struct CadetTunnelAxolotl *ax;
1676
1677 t->kx_task = NULL;
1679 "Trying to make KX progress on %s in state %s\n",
1680 GCT_2s (t),
1681 estate2s (t->estate));
1682 switch (t->estate)
1683 {
1684 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1685 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1686 send_kx (t,
1687 NULL,
1688 &t->ax);
1689 break;
1690
1693 /* We are responding, so only require reply
1694 if WE have a channel waiting. */
1695 if (NULL != t->unverified_ax)
1696 {
1697 /* Send AX_AUTH so we might get this one verified */
1698 ax = t->unverified_ax;
1699 }
1700 else
1701 {
1702 /* How can this be? */
1703 GNUNET_break (0);
1704 ax = &t->ax;
1705 }
1706 send_kx_auth (t,
1707 NULL,
1708 ax,
1709 (0 == GCT_count_channels (t))
1710 ? GNUNET_NO
1711 : GNUNET_YES);
1712 break;
1713
1715 /* We are responding, so only require reply
1716 if WE have a channel waiting. */
1717 if (NULL != t->unverified_ax)
1718 {
1719 /* Send AX_AUTH so we might get this one verified */
1720 ax = t->unverified_ax;
1721 }
1722 else
1723 {
1724 /* How can this be? */
1725 GNUNET_break (0);
1726 ax = &t->ax;
1727 }
1728 send_kx_auth (t,
1729 NULL,
1730 ax,
1731 (0 == GCT_count_channels (t))
1732 ? GNUNET_NO
1733 : GNUNET_YES);
1734 break;
1735
1737 /* Must have been the *other* peer asking us to
1738 respond with a KX_AUTH. */
1739 if (NULL != t->unverified_ax)
1740 {
1741 /* Sending AX_AUTH in response to AX so we might get this one verified */
1742 ax = t->unverified_ax;
1743 }
1744 else
1745 {
1746 /* Sending AX_AUTH in response to AX_AUTH */
1747 ax = &t->ax;
1748 }
1749 send_kx_auth (t,
1750 NULL,
1751 ax,
1752 GNUNET_NO);
1753 break;
1754 }
1755}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, estate2s(), GCT_2s(), GCT_count_channels(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_YES, LOG, send_kx(), send_kx_auth(), and t.

Referenced by connection_ready_cb(), cont_GCT_handle_kx(), cont_GCT_handle_kx_auth(), and GCT_add_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cont_GCT_handle_kx()

static void cont_GCT_handle_kx ( void *  cls,
enum GNUNET_GenericReturnValue  ret 
)
static

Continue to handle KX message.

Parameters
clsclosure from updating AX by KX
retresult from the update call

Definition at line 1765 of file gnunet-service-cadet_tunnels.c.

1767{
1768 struct CadetTunnel *t = cls;
1769
1770 if (t->unverified_ax)
1771 *(t->unverified_ax) = t->as.ax;
1772
1774 "Continue handling KX message from %s from %s\n",
1775 GCT_2s (t),
1776 GNUNET_i2s (GCP_get_id (t->destination)));
1777
1779 if (GNUNET_OK != ret)
1780 {
1782 "# Useless KX",
1783 1,
1784 GNUNET_NO);
1785 return; /* duplicate KX, nothing to do */
1786 }
1787 /* move ahead in our state machine */
1788 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1791 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1794
1795 /* KX is still not done, try again our end. */
1796 if (CADET_TUNNEL_KEY_OK != t->estate)
1797 {
1798 if (NULL != t->kx_task)
1799 GNUNET_SCHEDULER_cancel (t->kx_task);
1800 t->kx_task
1802 t);
1803 }
1804}

References CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, GCP_get_id(), GCT_2s(), GCT_change_estate(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, LOG, ret, retry_kx(), stats, and t.

Referenced by GCT_handle_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_kx()

void GCT_handle_kx ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelKeyExchangeMessage msg 
)

Continue to handle KX message.

Handle KX message that lacks authentication (and which will thus only be considered authenticated after we respond with our own KX_AUTH and finally successfully decrypt the payload).

Parameters
clsclosure from updating AX by KX
retresult from the update call

Definition at line 1814 of file gnunet-service-cadet_tunnels.c.

1816{
1817 struct CadetTunnel *t = ct->t;
1818
1820 "# KX received",
1821 1,
1822 GNUNET_NO);
1823 if (GNUNET_YES ==
1824 GCT_alice_or_betty (GCP_get_id (t->destination)))
1825 {
1826 /* Betty/Bob is not allowed to send KX! */
1827 GNUNET_break_op (0);
1828 return;
1829 }
1831 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1832 GCT_2s (t),
1833 GNUNET_e2s (&msg->ephemeral_key),
1834 GNUNET_i2s (GCP_get_id (t->destination)),
1835 GCC_2s (ct->cc));
1836#if 1
1837 if ((0 ==
1838 memcmp (&t->ax.DHRr,
1839 &msg->ratchet_key,
1840 sizeof(msg->ratchet_key))) &&
1841 (0 ==
1842 memcmp (&t->ax.last_ephemeral,
1843 &msg->ephemeral_key,
1844 sizeof(msg->ephemeral_key))))
1845
1846 {
1848 "# Duplicate KX received",
1849 1,
1850 GNUNET_NO);
1851 send_kx_auth (t,
1852 ct,
1853 &t->ax,
1854 GNUNET_NO);
1855 return;
1856 }
1857#endif
1858 /* We only keep ONE unverified KX around, so if there is an existing one,
1859 clean it up. */
1860 if (NULL != t->unverified_ax)
1861 {
1862 if ((0 ==
1863 memcmp (&t->unverified_ax->DHRr,
1864 &msg->ratchet_key,
1865 sizeof(msg->ratchet_key))) &&
1866 (0 ==
1867 memcmp (&t->unverified_ax->last_ephemeral,
1868 &msg->ephemeral_key,
1869 sizeof(msg->ephemeral_key))))
1870 {
1872 "# Duplicate unverified KX received",
1873 1,
1874 GNUNET_NO);
1875#if 1
1876 send_kx_auth (t,
1877 ct,
1878 t->unverified_ax,
1879 GNUNET_NO);
1880 return;
1881#endif
1882 }
1883 if ((t->as.ecdh_op) &&
1884 (0 ==
1885 memcmp (&t->as.ratchet_key,
1886 &msg->ratchet_key,
1887 sizeof(msg->ratchet_key))) &&
1888 (0 ==
1889 memcmp (&t->as.ephemeral_key,
1890 &msg->ephemeral_key,
1891 sizeof(msg->ephemeral_key))))
1892 {
1894 "Waiting for previous ECDH operation\n");
1895 return;
1896 }
1898 "Dropping old unverified KX state.\n");
1900 "# Unverified KX dropped for fresh KX",
1901 1,
1902 GNUNET_NO);
1903 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1904 memset (t->unverified_ax,
1905 0,
1906 sizeof(struct CadetTunnelAxolotl));
1907 }
1908 else
1909 {
1911 "Creating fresh unverified KX for %s\n",
1912 GCT_2s (t));
1914 "# Fresh KX setup",
1915 1,
1916 GNUNET_NO);
1917 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1918 }
1919 /* Set as the 'current' RK/DHRr the one we are currently using,
1920 so that the duplicate-detection logic of
1921 #update_ax_by_kx can work. */
1922 t->unverified_ax->RK = t->ax.RK;
1923 t->unverified_ax->DHRr = t->ax.DHRr;
1924 t->unverified_ax->DHRs = t->ax.DHRs;
1925 t->unverified_ax->kx_0 = t->ax.kx_0;
1926 t->unverified_attempts = 0;
1927
1928 t->as.ax = *(t->unverified_ax);
1929 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1930 sizeof (t->as.peer_id));
1931 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1932 sizeof (t->as.ephemeral_key));
1933 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1934 sizeof (t->as.ratchet_key));
1935 memset (&t->as.auth, 0, sizeof (t->as.auth));
1936 t->as.flags = 0;
1937 t->as.cb_cls = t;
1938 t->as.cb = &cont_GCT_handle_kx;
1939
1940 if (t->as.ecdh_op)
1941 {
1943 "Cancelling previous ECDH operation\n");
1944
1945 GNUNET_PILS_cancel (t->as.ecdh_op);
1946 }
1947
1948 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
1949 &update_ax_by_kx, &t->as);
1950}

References CadetTConnection::cc, cont_GCT_handle_kx(), GCC_2s(), GCP_get_id(), GCT_2s(), GCT_alice_or_betty(), GNUNET_break, GNUNET_break_op, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_PILS_cancel(), GNUNET_PILS_ecdh(), GNUNET_STATISTICS_update(), GNUNET_YES, LOG, msg, pils, send_kx_auth(), stats, t, CadetTConnection::t, and update_ax_by_kx().

Referenced by GCC_handle_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cont_GCT_handle_kx_auth()

static void cont_GCT_handle_kx_auth ( void *  cls,
enum GNUNET_GenericReturnValue  ret 
)
static

Continue to handle KX_AUTH message.

Parameters
clsclosure from updating AX by KX
retresult from the update call

Definition at line 1960 of file gnunet-service-cadet_tunnels.c.

1962{
1963 struct CadetTunnel *t = cls;
1964 struct CadetTunnelAxolotl *ax_tmp;
1965 struct GNUNET_HashCode kx_auth;
1966
1967 ax_tmp = &t->as.ax;
1968
1970 "Continue handling KX_AUTH message from %s\n",
1971 GCT_2s (t));
1972
1973 if (GNUNET_OK != ret)
1974 {
1975 if (GNUNET_NO == ret)
1977 "# redundant KX_AUTH received",
1978 1,
1979 GNUNET_NO);
1980 else
1981 GNUNET_break (0); /* connect to self!? */
1982 return;
1983 }
1984 GNUNET_CRYPTO_hash (&ax_tmp->RK,
1985 sizeof(ax_tmp->RK),
1986 &kx_auth);
1987 if (0 != GNUNET_memcmp (&kx_auth,
1988 &t->as.auth))
1989 {
1990 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1991 we transmitted to the sender, refuse it, try KX again. */
1993 "# KX_AUTH not using our last KX received (auth failure)",
1994 1,
1995 GNUNET_NO);
1997 "KX AUTH mismatch!\n");
1998#if DEBUG_KX
1999 {
2000 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2001
2003 &ephemeral_key);
2004 if (0 != GNUNET_memcmp (&ephemeral_key,
2005 &msg->r_ephemeral_key_XXX))
2006 {
2008 "My ephemeral is %s!\n",
2009 GNUNET_e2s (&ephemeral_key));
2011 "Response is for ephemeral %s!\n",
2012 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2013 }
2014 }
2015#endif
2016 if (NULL == t->kx_task)
2017 t->kx_task
2018 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2019 &retry_kx,
2020 t);
2021 return;
2022 }
2023 /* Yep, we're good. */
2024 t->ax = *ax_tmp;
2025 if (NULL != t->unverified_ax)
2026 {
2027 /* We got some "stale" KX before, drop that. */
2028 cleanup_ax (t->unverified_ax);
2029 GNUNET_free (t->unverified_ax);
2030 t->unverified_ax = NULL;
2031 }
2032
2033 /* move ahead in our state machine */
2034 switch (t->estate)
2035 {
2038 /* Checked above, this is impossible. */
2039 GNUNET_assert (0);
2040 break;
2041
2042 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2043 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2044 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2047 break;
2048
2050 /* Did not expect another KX_AUTH, but so what, still acceptable.
2051 Nothing to do here. */
2052 break;
2053 }
2054 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2055 {
2056 send_kx_auth (t,
2057 NULL,
2058 &t->ax,
2059 GNUNET_NO);
2060 }
2061}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, cleanup_ax(), GCT_2s(), GCT_change_estate(), GNUNET_assert, GNUNET_break, GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_memcmp, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_at(), GNUNET_STATISTICS_update(), CadetTunnelAxolotl::kx_0, LOG, msg, ret, retry_kx(), CadetTunnelAxolotl::RK, send_kx_auth(), stats, and t.

Referenced by GCT_handle_kx_auth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_kx_auth()

void GCT_handle_kx_auth ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage msg 
)

Handle KX_AUTH message.

Parameters
ctconnection/tunnel combo that received encrypted message
msgthe key exchange message

Definition at line 2071 of file gnunet-service-cadet_tunnels.c.

2073{
2074 struct CadetTunnel *t = ct->t;
2075
2077 "# KX_AUTH received",
2078 1,
2079 GNUNET_NO);
2080 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2081 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2082 {
2083 /* Confusing, we got a KX_AUTH before we even send our own
2084 KX. This should not happen. We'll send our own KX ASAP anyway,
2085 so let's ignore this here. */
2086 GNUNET_break_op (0);
2087 return;
2088 }
2090 "Handling KX_AUTH message from %s with ephemeral %s\n",
2091 GCT_2s (t),
2092 GNUNET_e2s (&msg->kx.ephemeral_key));
2093 if ((t->as.ecdh_op) &&
2094 (0 ==
2095 memcmp (&t->as.ratchet_key,
2096 &msg->kx.ratchet_key,
2097 sizeof(msg->kx.ratchet_key))) &&
2098 (0 ==
2099 memcmp (&t->as.ephemeral_key,
2100 &msg->kx.ephemeral_key,
2101 sizeof(msg->kx.ephemeral_key))))
2102 {
2104 "Waiting for previous ECDH operation\n");
2105 return;
2106 }
2107 /* We do everything in a copy until we've checked the authentication
2108 so we don't clobber anything we care about by accident. */
2109 t->as.ax = t->ax;
2110 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2111 sizeof (t->as.peer_id));
2112 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2113 sizeof (t->as.ephemeral_key));
2114 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2115 sizeof (t->as.ratchet_key));
2116 t->as.auth = msg->auth;
2117 t->as.flags = msg->kx.flags;
2118 t->as.cb_cls = t;
2119 t->as.cb = &cont_GCT_handle_kx_auth;
2120
2121 if (t->as.ecdh_op)
2122 {
2124 "Cancelling previous ECDH operation\n");
2125
2126 GNUNET_PILS_cancel (t->as.ecdh_op);
2127 }
2128
2129 /* Update 'ax' by the new key material */
2130 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2131 &update_ax_by_kx, &t->as);
2132}

References CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_UNINITIALIZED, cont_GCT_handle_kx_auth(), GCP_get_id(), GCT_2s(), GNUNET_break_op, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcpy, GNUNET_NO, GNUNET_PILS_cancel(), GNUNET_PILS_ecdh(), GNUNET_STATISTICS_update(), LOG, msg, pils, stats, t, CadetTConnection::t, and update_ax_by_kx().

Referenced by GCC_handle_kx_auth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_next_free_ctn()

static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn ( struct CadetTunnel t)
static

Compute the next free channel tunnel number for this tunnel.

Parameters
tthe tunnel
Returns
unused number that can uniquely identify a channel in the tunnel

Definition at line 2145 of file gnunet-service-cadet_tunnels.c.

2146{
2147#define HIGH_BIT 0x8000000
2148 const struct GNUNET_PeerIdentity *my_identity;
2150 uint32_t ctn;
2151 int cmp;
2152 uint32_t highbit;
2153
2156
2159 if (0 < cmp)
2160 highbit = HIGH_BIT;
2161 else if (0 > cmp)
2162 highbit = 0;
2163 else
2164 GNUNET_assert (0); // loopback must never go here!
2165 ctn = ntohl (t->next_ctn.cn);
2166 while (NULL !=
2168 ctn | highbit))
2169 {
2170 ctn = ((ctn + 1) & (~HIGH_BIT));
2171 }
2172 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2173 ret.cn = htonl (ctn | highbit);
2174 return ret;
2175}

References GCP_get_id(), GCT_get_destination(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get(), GNUNET_memcmp, GNUNET_PILS_get_identity(), HIGH_BIT, my_identity, pils, ret, and t.

Referenced by GCT_add_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_add_channel()

struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel ( struct CadetTunnel t,
struct CadetChannel ch 
)

Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up.

Add a channel to a tunnel.

Otherwise that notification will be done later in notify_tunnel_up_cb().

Parameters
tTunnel.
chChannel
Returns
unique number identifying ch within t

Definition at line 2188 of file gnunet-service-cadet_tunnels.c.

2190{
2192
2193 ctn = get_next_free_ctn (t);
2194 if (NULL != t->destroy_task)
2195 {
2196 GNUNET_SCHEDULER_cancel (t->destroy_task);
2197 t->destroy_task = NULL;
2198 }
2201 ntohl (ctn.cn),
2202 ch,
2205 "Adding %s to %s with state %d\n",
2206 GCCH_2s (ch),
2207 GCT_2s (t),
2208 t->estate);
2209 switch (t->estate)
2210 {
2212 /* waiting for connection to start KX */
2213 break;
2214
2218 /* we're currently waiting for KX to complete */
2219 break;
2220
2222 /* waiting for OTHER peer to send us data,
2223 we might need to prompt more aggressively! */
2224 if (NULL == t->kx_task)
2225 t->kx_task
2226 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2227 &retry_kx,
2228 t);
2229 break;
2230
2232 /* We are ready. Tell the new channel that we are up. */
2234 break;
2235 }
2236 return ctn;
2237}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, ch, GNUNET_CADET_ChannelTunnelNumber::cn, GCCH_2s(), GCCH_tunnel_up(), GCT_2s(), get_next_free_ctn(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, LOG, retry_kx(), and t.

Referenced by GCCH_channel_local_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_connection_lost()

void GCT_connection_lost ( struct CadetTConnection ct)

We lost a connection, remove it from our list and clean up the connection object itself.

Parameters
ctbinding of connection to tunnel of the connection that was lost.

Definition at line 2247 of file gnunet-service-cadet_tunnels.c.

2248{
2249 struct CadetTunnel *t = ct->t;
2250
2251 if (GNUNET_YES == ct->is_ready)
2252 {
2253 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2254 t->connection_ready_tail,
2255 ct);
2256 t->num_ready_connections--;
2257 }
2258 else
2259 {
2260 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2261 t->connection_busy_tail,
2262 ct);
2263 t->num_busy_connections--;
2264 }
2265 GNUNET_free (ct);
2266}

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_YES, CadetTConnection::is_ready, t, and CadetTConnection::t.

Referenced by destroy_t_connection(), GCC_create_inbound(), and GCC_destroy_without_core().

Here is the caller graph for this function:

◆ destroy_t_connection()

static void destroy_t_connection ( void *  cls,
struct CadetTConnection ct 
)
static

Clean up connection ct of a tunnel.

Parameters
clsthe struct CadetTunnel
ctconnection to clean up

Definition at line 2276 of file gnunet-service-cadet_tunnels.c.

2278{
2279 struct CadetTunnel *t = cls;
2280 struct CadetConnection *cc = ct->cc;
2281
2282 GNUNET_assert (ct->t == t);
2285}

References CadetTConnection::cc, CadetConnection::ct, GCC_destroy_without_tunnel(), GCT_connection_lost(), GNUNET_assert, t, and CadetTConnection::t.

Referenced by destroy_tunnel(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_tunnel()

static void destroy_tunnel ( void *  cls)
static

This tunnel is no longer used, destroy it.

Parameters
clsthe idle tunnel

Definition at line 2294 of file gnunet-service-cadet_tunnels.c.

2295{
2296 struct CadetTunnel *t = cls;
2297 struct CadetTunnelQueueEntry *tq;
2298
2299 t->destroy_task = NULL;
2301 "Destroying idle %s\n",
2302 GCT_2s (t));
2306 t);
2307 GNUNET_assert (NULL == t->connection_ready_head);
2308 GNUNET_assert (NULL == t->connection_busy_head);
2309 while (NULL != (tq = t->tq_head))
2310 {
2311 if (NULL != tq->cont)
2312 tq->cont (tq->cont_cls,
2313 NULL);
2314 GCT_send_cancel (tq);
2315 }
2316 GCP_drop_tunnel (t->destination,
2317 t);
2319 if (NULL != t->maintain_connections_task)
2320 {
2321 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2322 t->maintain_connections_task = NULL;
2323 }
2324 if (NULL != t->send_task)
2325 {
2326 GNUNET_SCHEDULER_cancel (t->send_task);
2327 t->send_task = NULL;
2328 }
2329 if (NULL != t->kx_task)
2330 {
2331 GNUNET_SCHEDULER_cancel (t->kx_task);
2332 t->kx_task = NULL;
2333 }
2334 if (NULL != t->as.ecdh_op)
2335 {
2336 GNUNET_PILS_cancel (t->as.ecdh_op);
2337 t->as.ecdh_op = NULL;
2338 }
2339 GNUNET_MST_destroy (t->mst);
2340 GNUNET_MQ_destroy (t->mq);
2341 if (NULL != t->unverified_ax)
2342 {
2343 cleanup_ax (t->unverified_ax);
2344 GNUNET_free (t->unverified_ax);
2345 }
2346 cleanup_ax (&t->ax);
2347 GNUNET_assert (NULL == t->destroy_task);
2348 GNUNET_free (t);
2349}

References cleanup_ax(), CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, destroy_t_connection(), GCP_drop_tunnel(), GCT_2s(), GCT_count_channels(), GCT_iterate_connections(), GCT_send_cancel(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_MST_destroy(), GNUNET_PILS_cancel(), GNUNET_SCHEDULER_cancel(), LOG, and t.

Referenced by callback_room_connect(), connection_ready_cb(), enter_srv_room_at(), GCT_destroy_tunnel_now(), GCT_remove_channel(), and iterate_destroy_tunnels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_remove_channel()

void GCT_remove_channel ( struct CadetTunnel t,
struct CadetChannel ch,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)

Remove a channel from a tunnel.

Parameters
tTunnel.
chChannel
ctnunique number identifying ch within t

Definition at line 2360 of file gnunet-service-cadet_tunnels.c.

2363{
2365 "Removing %s from %s\n",
2366 GCCH_2s (ch),
2367 GCT_2s (t));
2370 ntohl (ctn.cn),
2371 ch));
2372 if ((0 ==
2373 GCT_count_channels (t)) &&
2374 (NULL == t->destroy_task))
2375 {
2376 t->destroy_task
2379 t);
2380 }
2381}

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, destroy_tunnel(), GCCH_2s(), GCT_2s(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_delayed(), GNUNET_YES, IDLE_DESTROY_DELAY, LOG, and t.

Referenced by channel_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_remaining_channels()

static int destroy_remaining_channels ( void *  cls,
uint32_t  key,
void *  value 
)
static

Destroy remaining channels during shutdown.

Parameters
clsthe struct CadetTunnel of the channel
keykey of the channel
valuethe struct CadetChannel
Returns
GNUNET_OK (continue to iterate)

Definition at line 2393 of file gnunet-service-cadet_tunnels.c.

2396{
2397 struct CadetChannel *ch = value;
2398
2400 NULL);
2401 return GNUNET_OK;
2402}

References ch, GCCH_handle_remote_destroy(), GNUNET_OK, and value.

Referenced by GCT_destroy_tunnel_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_destroy_tunnel_now()

void GCT_destroy_tunnel_now ( struct CadetTunnel t)

Destroys the tunnel t now, without delay.

Used during shutdown.

Parameters
ttunnel to destroy

Definition at line 2411 of file gnunet-service-cadet_tunnels.c.

2412{
2416 t);
2417 GNUNET_assert (0 ==
2419 if (NULL != t->destroy_task)
2420 {
2421 GNUNET_SCHEDULER_cancel (t->destroy_task);
2422 t->destroy_task = NULL;
2423 }
2424 destroy_tunnel (t);
2425}

References destroy_remaining_channels(), destroy_tunnel(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, shutting_down, and t.

Referenced by destroy_tunnels_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_send_normal_payload()

static void try_send_normal_payload ( struct CadetTunnel t,
struct CadetTConnection ct 
)
static

Send normal payload from queue in t via connection ct.

Does nothing if our payload queue is empty.

Parameters
ttunnel to send data from
ctconnection to use for transmission (is ready)

Definition at line 2436 of file gnunet-service-cadet_tunnels.c.

2438{
2439 struct CadetTunnelQueueEntry *tq;
2440
2442 tq = t->tq_head;
2443 if (NULL == tq)
2444 {
2445 /* no messages pending right now */
2447 "Not sending payload of %s on ready %s (nothing pending)\n",
2448 GCT_2s (t),
2449 GCC_2s (ct->cc));
2450 return;
2451 }
2452 /* ready to send message 'tq' on tunnel 'ct' */
2453 GNUNET_assert (t == tq->t);
2455 t->tq_tail,
2456 tq);
2457 if (NULL != tq->cid)
2458 *tq->cid = *GCC_get_id (ct->cc);
2461 "Sending payload of %s on %s\n",
2462 GCT_2s (t),
2463 GCC_2s (ct->cc));
2464 GCC_transmit (ct->cc,
2465 tq->env);
2466 if (NULL != tq->cont)
2467 tq->cont (tq->cont_cls,
2468 GCC_get_id (ct->cc));
2469 GNUNET_free (tq);
2470}

References CadetTConnection::cc, CadetTunnelQueueEntry::cid, CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, CadetTunnelQueueEntry::env, GCC_2s(), GCC_get_id(), GCC_transmit(), GCT_2s(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_YES, CadetTConnection::is_ready, LOG, mark_connection_unready(), t, and CadetTunnelQueueEntry::t.

Referenced by connection_ready_cb(), and trigger_transmissions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connection_ready_cb()

static void connection_ready_cb ( void *  cls,
int  is_ready 
)
static

A connection is is_ready for transmission.

Looks at our message queue and if there is a message, sends it out via the connection.

Parameters
clsthe struct CadetTConnection that is is_ready
is_readyGNUNET_YES if connection are now ready, GNUNET_NO if connection are no longer ready

Definition at line 2482 of file gnunet-service-cadet_tunnels.c.

2484{
2485 struct CadetTConnection *ct = cls;
2486 struct CadetTunnel *t = ct->t;
2487
2488 if (GNUNET_NO == is_ready)
2489 {
2491 "%s no longer ready for %s\n",
2492 GCC_2s (ct->cc),
2493 GCT_2s (t));
2495 return;
2496 }
2498 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2499 t->connection_busy_tail,
2500 ct);
2501 GNUNET_assert (0 < t->num_busy_connections);
2502 t->num_busy_connections--;
2503 ct->is_ready = GNUNET_YES;
2504 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2505 t->connection_ready_tail,
2506 ct);
2507 t->num_ready_connections++;
2508
2510 "%s now ready for %s in state %s\n",
2511 GCC_2s (ct->cc),
2512 GCT_2s (t),
2513 estate2s (t->estate));
2514 switch (t->estate)
2515 {
2518 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2519 GCT_2s (t),
2520 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2521 t->next_kx_attempt).rel_value_us);
2522 /* Do not begin KX if WE have no channels waiting! */
2524 t->next_kx_attempt).rel_value_us)
2525 return; /* wait for timeout before retrying */
2526 /* We are uninitialized, just transmit immediately,
2527 without undue delay. */
2528
2530 "Why for %s \n",
2531 GCT_2s (t));
2532
2533 if (NULL != t->kx_task)
2534 {
2535 GNUNET_SCHEDULER_cancel (t->kx_task);
2536 t->kx_task = NULL;
2537 }
2538 send_kx (t,
2539 ct,
2540 &t->ax);
2541 if ((0 ==
2542 GCT_count_channels (t)) &&
2543 (NULL == t->destroy_task))
2544 {
2545 t->destroy_task
2548 t);
2549 }
2550 break;
2551
2556 /* we're currently waiting for KX to complete, schedule job */
2557 if (NULL == t->kx_task)
2558 t->kx_task
2559 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2560 &retry_kx,
2561 t);
2562 break;
2563
2565 if (GNUNET_YES == t->kx_auth_requested)
2566 {
2568 t->next_kx_attempt).rel_value_us)
2569 return; /* wait for timeout */
2570 if (NULL != t->kx_task)
2571 {
2572 GNUNET_SCHEDULER_cancel (t->kx_task);
2573 t->kx_task = NULL;
2574 }
2575 send_kx_auth (t,
2576 ct,
2577 &t->ax,
2578 GNUNET_NO);
2579 return;
2580 }
2582 ct);
2583 break;
2584 }
2585}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, CadetTConnection::cc, destroy_tunnel(), estate2s(), GCC_2s(), GCT_2s(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, IDLE_DESTROY_DELAY, CadetTConnection::is_ready, LOG, mark_connection_unready(), GNUNET_TIME_Relative::rel_value_us, retry_kx(), send_kx(), send_kx_auth(), t, CadetTConnection::t, and try_send_normal_payload().

Referenced by consider_path_cb(), and GCT_add_inbound_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_connection()

static void evaluate_connection ( void *  cls,
struct CadetTConnection ct 
)
static

Evaluate a connection, updating our summary information in cls about what kinds of connections we have.

Parameters
clsthe struct EvaluationSummary * to update
cta connection to include in the summary

Definition at line 2670 of file gnunet-service-cadet_tunnels.c.

2672{
2673 struct EvaluationSummary *es = cls;
2674 struct CadetConnection *cc = ct->cc;
2675 unsigned int ct_length;
2676 struct CadetPeerPath *ps;
2677 const struct CadetConnectionMetrics *metrics;
2678 GNUNET_CONTAINER_HeapCostType ct_desirability;
2679 struct GNUNET_TIME_Relative uptime;
2680 struct GNUNET_TIME_Relative last_use;
2681 double score;
2682 double success_rate;
2683
2684 ps = GCC_get_path (cc,
2685 &ct_length);
2687 "Evaluating path %s of existing %s\n",
2688 GCPP_2s (ps),
2689 GCC_2s (cc));
2690 if (ps == es->path)
2691 {
2693 "Ignoring duplicate path %s.\n",
2694 GCPP_2s (es->path));
2695 es->duplicate = GNUNET_YES;
2696 return;
2697 }
2698 if (NULL != es->path)
2699 {
2700 int duplicate = GNUNET_YES;
2701
2702 for (unsigned int i = 0; i < ct_length; i++)
2703 {
2706 i) !=
2708 i))
2709 {
2710 duplicate = GNUNET_NO;
2711 break;
2712 }
2713 }
2714 if (GNUNET_YES == duplicate)
2715 {
2717 "Ignoring overlapping path %s.\n",
2718 GCPP_2s (es->path));
2719 es->duplicate = GNUNET_YES;
2720 return;
2721 }
2722 else
2723 {
2725 "Known path %s differs from proposed path\n",
2726 GCPP_2s (ps));
2727 }
2728 }
2729
2730 ct_desirability = GCPP_get_desirability (ps);
2731 metrics = GCC_get_metrics (cc);
2732 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2733 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2734 /* We add 1.0 here to avoid division by zero. */
2735 success_rate = (metrics->num_acked_transmissions + 1.0)
2736 / (metrics->num_successes + 1.0);
2737 score
2738 = ct_desirability
2739 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2740 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2741 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2742 score *= success_rate; /* weigh overall by success rate */
2743
2744 if ((NULL == es->worst) ||
2745 (score < es->worst_score))
2746 {
2747 es->worst = ct;
2748 es->worst_score = score;
2749 }
2750 es->min_length = GNUNET_MIN (es->min_length,
2751 ct_length);
2752 es->max_length = GNUNET_MAX (es->max_length,
2753 ct_length);
2754 es->min_desire = GNUNET_MIN (es->min_desire,
2755 ct_desirability);
2756 es->max_desire = GNUNET_MAX (es->max_desire,
2757 ct_desirability);
2758}

References CadetConnectionMetrics::age, CadetTConnection::cc, CadetConnection::ct, EvaluationSummary::duplicate, GCC_2s(), GCC_get_metrics(), GCC_get_path(), GCPP_2s(), GCPP_get_desirability(), GCPP_get_length(), GCPP_get_peer_at_offset(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MAX, GNUNET_MIN, GNUNET_NO, GNUNET_TIME_absolute_get_duration(), GNUNET_YES, CadetConnectionMetrics::last_use, LOG, EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, CadetConnectionMetrics::num_acked_transmissions, CadetConnectionMetrics::num_successes, CadetConnection::off, EvaluationSummary::path, ps, GNUNET_TIME_Relative::rel_value_us, EvaluationSummary::worst, and EvaluationSummary::worst_score.

Referenced by consider_path_cb(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_path_cb()

static int consider_path_cb ( void *  cls,
struct CadetPeerPath path,
unsigned int  off 
)
static

Consider using the path p for the tunnel t.

The tunnel destination is at offset off in path p.

Parameters
clsour tunnel
patha path to our destination
offoffset of the destination on path path
Returns
GNUNET_YES (should keep iterating)

Definition at line 2771 of file gnunet-service-cadet_tunnels.c.

2774{
2775 struct CadetTunnel *t = cls;
2776 struct EvaluationSummary es;
2777 struct CadetTConnection *ct;
2778
2779 GNUNET_assert (off < GCPP_get_length (path));
2781 off) == t->destination);
2782 es.min_length = UINT_MAX;
2783 es.max_length = 0;
2784 es.max_desire = 0;
2785 es.min_desire = UINT64_MAX;
2786 es.path = path;
2787 es.duplicate = GNUNET_NO;
2788 es.worst = NULL;
2789
2790 /* Compute evaluation summary over existing connections. */
2792 "Evaluating proposed path %s for target %s\n",
2793 GCPP_2s (path),
2794 GCT_2s (t));
2795 /* FIXME: suspect this does not ACTUALLY iterate
2796 over all existing paths, otherwise dup detection
2797 should work!!! */
2800 &es);
2801 if (GNUNET_YES == es.duplicate)
2802 return GNUNET_YES;
2803
2804 /* FIXME: not sure we should really just count
2805 'num_connections' here, as they may all have
2806 consistently failed to connect. */
2807
2808 /* We iterate by increasing path length; if we have enough paths and
2809 this one is more than twice as long than what we are currently
2810 using, then ignore all of these super-long ones! */
2812 (es.min_length * 2 < off) &&
2813 (es.max_length < off))
2814 {
2816 "Ignoring paths of length %u, they are way too long.\n",
2817 es.min_length * 2);
2818 return GNUNET_NO;
2819 }
2820 /* If we have enough paths and this one looks no better, ignore it. */
2822 (es.min_length < GCPP_get_length (path)) &&
2823 (es.min_desire > GCPP_get_desirability (path)) &&
2824 (es.max_length < off))
2825 {
2827 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2828 GCPP_get_length (path),
2829 (unsigned long long) GCPP_get_desirability (path),
2830 GCP_2s (t->destination));
2831 return GNUNET_YES;
2832 }
2833
2834 /* Path is interesting (better by some metric, or we don't have
2835 enough paths yet). */
2836 ct = GNUNET_new (struct CadetTConnection);
2838 ct->t = t;
2839 ct->cc = GCC_create (t->destination,
2840 path,
2841 off,
2842 ct,
2844 ct);
2845
2846 /* FIXME: schedule job to kill connection (and path?) if it takes
2847 too long to get ready! (And track performance data on how long
2848 other connections took with the tunnel!)
2849 => Note: to be done within 'connection'-logic! */
2850 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2851 t->connection_busy_tail,
2852 ct);
2853 t->num_busy_connections++;
2855 "Found interesting path %s for %s, created %s\n",
2856 GCPP_2s (path),
2857 GCT_2s (t),
2858 GCC_2s (ct->cc));
2859 return GNUNET_YES;
2860}

References CadetTConnection::cc, connection_ready_cb(), CadetTConnection::created, DESIRED_CONNECTIONS_PER_TUNNEL, EvaluationSummary::duplicate, evaluate_connection(), GCC_2s(), GCC_create(), GCP_2s(), GCPP_2s(), GCPP_get_desirability(), GCPP_get_length(), GCPP_get_peer_at_offset(), GCT_2s(), GCT_count_any_connections(), GCT_iterate_connections(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_NO, GNUNET_TIME_absolute_get(), GNUNET_YES, LOG, EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, EvaluationSummary::path, t, CadetTConnection::t, and EvaluationSummary::worst.

Referenced by GCT_consider_path(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ maintain_connections_cb()

static void maintain_connections_cb ( void *  cls)
static

Function called to maintain the connections underlying our tunnel.

Tries to maintain (incl. tear down) connections for the tunnel, and if there is a significant change, may trigger transmissions.

Basically, needs to check if there are connections that perform badly, and if so eventually kill them and trigger a replacement. The strategy is to open one more connection than DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the least-performing one, and then inquire for new ones.

Parameters
clsthe struct CadetTunnel

Definition at line 2877 of file gnunet-service-cadet_tunnels.c.

2878{
2879 struct CadetTunnel *t = cls;
2880 struct GNUNET_TIME_Relative delay;
2881 struct EvaluationSummary es;
2882
2883 t->maintain_connections_task = NULL;
2885 "Performing connection maintenance for %s.\n",
2886 GCT_2s (t));
2887
2888 es.min_length = UINT_MAX;
2889 es.max_length = 0;
2890 es.max_desire = 0;
2891 es.min_desire = UINT64_MAX;
2892 es.path = NULL;
2893 es.worst = NULL;
2894 es.duplicate = GNUNET_NO;
2897 &es);
2898 if ((NULL != es.worst) &&
2900 {
2901 /* Clear out worst-performing connection 'es.worst'. */
2903 es.worst);
2904 }
2905
2906 /* Consider additional paths */
2907 (void) GCP_iterate_paths (t->destination,
2909 t);
2910
2911 /* FIXME: calculate when to try again based on how well we are doing;
2912 in particular, if we have to few connections, we might be able
2913 to do without this (as PATHS should tell us whenever a new path
2914 is available instantly; however, need to make sure this job is
2915 restarted after that happens).
2916 Furthermore, if the paths we do know are in a reasonably narrow
2917 quality band and are plentyful, we might also consider us stabilized
2918 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2919 t->maintain_connections_task
2922 t);
2923}

References consider_path_cb(), DESIRED_CONNECTIONS_PER_TUNNEL, destroy_t_connection(), EvaluationSummary::duplicate, evaluate_connection(), GCP_iterate_paths(), GCT_2s(), GCT_count_any_connections(), GCT_iterate_connections(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_UNIT_MINUTES, LOG, maintain_connections_cb(), EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, EvaluationSummary::path, t, and EvaluationSummary::worst.

Referenced by GCT_create_tunnel(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_consider_path()

void GCT_consider_path ( struct CadetTunnel t,
struct CadetPeerPath p,
unsigned int  off 
)

Consider using the path p for the tunnel t.

The tunnel destination is at offset off in path p.

Parameters
tour tunnel
pa path to our destination
offoffset of the destination on path path

Definition at line 2927 of file gnunet-service-cadet_tunnels.c.

2930{
2932 "Considering %s for %s (offset %u)\n",
2933 GCPP_2s (p),
2934 GCT_2s (t),
2935 off);
2936 (void) consider_path_cb (t,
2937 p,
2938 off);
2939}

References consider_path_cb(), GCPP_2s(), GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, LOG, p, and t.

Referenced by GCP_path_entry_add(), and GCP_set_mq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_plaintext_keepalive()

static void handle_plaintext_keepalive ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

We got a keepalive.

Track in statistics.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel

Definition at line 2949 of file gnunet-service-cadet_tunnels.c.

2951{
2952 struct CadetTunnel *t = cls;
2953
2955 "Received KEEPALIVE on %s\n",
2956 GCT_2s (t));
2958 "# keepalives received",
2959 1,
2960 GNUNET_NO);
2961}

References GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, stats, and t.

Here is the call graph for this function:

◆ check_plaintext_data()

static int check_plaintext_data ( void *  cls,
const struct GNUNET_CADET_ChannelAppDataMessage msg 
)
static

Check that msg is well-formed.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel
Returns
GNUNET_OK (any variable-size payload goes)

Definition at line 2972 of file gnunet-service-cadet_tunnels.c.

2974{
2975 return GNUNET_OK;
2976}

References GNUNET_OK.

◆ handle_plaintext_data()

static void handle_plaintext_data ( void *  cls,
const struct GNUNET_CADET_ChannelAppDataMessage msg 
)
static

We received payload data for a channel.

Locate the channel and process the data, or return an error if the channel is unknown.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel

Definition at line 2987 of file gnunet-service-cadet_tunnels.c.

2989{
2990 struct CadetTunnel *t = cls;
2991 struct CadetChannel *ch;
2992
2993 ch = lookup_channel (t,
2994 msg->ctn);
2995 if (NULL == ch)
2996 {
2997 /* We don't know about such a channel, might have been destroyed on our
2998 end in the meantime, or never existed. Send back a DESTROY. */
3000 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3001 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3002 ntohl (msg->ctn.cn));
3004 msg->ctn);
3005 return;
3006 }
3008 GCC_get_id (t->current_ct->cc),
3009 msg);
3010}

References ch, GCC_get_id(), GCCH_handle_channel_plaintext_data(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), msg, GNUNET_MessageHeader::size, and t.

Here is the call graph for this function:

◆ handle_plaintext_data_ack()

static void handle_plaintext_data_ack ( void *  cls,
const struct GNUNET_CADET_ChannelDataAckMessage ack 
)
static

We received an acknowledgement for data we sent on a channel.

Locate the channel and process it, or return an error if the channel is unknown.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
ackthe message we received on the tunnel

Definition at line 3022 of file gnunet-service-cadet_tunnels.c.

3024{
3025 struct CadetTunnel *t = cls;
3026 struct CadetChannel *ch;
3027
3028 ch = lookup_channel (t,
3029 ack->ctn);
3030 if (NULL == ch)
3031 {
3032 /* We don't know about such a channel, might have been destroyed on our
3033 end in the meantime, or never existed. Send back a DESTROY. */
3035 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3036 ntohl (ack->ctn.cn));
3038 ack->ctn);
3039 return;
3040 }
3042 GCC_get_id (t->current_ct->cc),
3043 ack);
3044}

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDataAckMessage::ctn, GCC_get_id(), GCCH_handle_channel_plaintext_data_ack(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), and t.

Here is the call graph for this function:

◆ handle_plaintext_channel_open()

static void handle_plaintext_channel_open ( void *  cls,
const struct GNUNET_CADET_ChannelOpenMessage copen 
)
static

We have received a request to open a channel to a port from another peer.

Creates the incoming channel.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
copenthe message we received on the tunnel

Definition at line 3055 of file gnunet-service-cadet_tunnels.c.

3058{
3059 struct CadetTunnel *t = cls;
3060 struct CadetChannel *ch;
3061
3063 ntohl (copen->ctn.cn));
3064 if (NULL != ch)
3065 {
3067 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3068 GNUNET_h2s (&copen->h_port),
3069 GCT_2s (t),
3070 GCCH_2s (ch));
3072 GCC_get_id (t->current_ct->cc));
3073 return;
3074 }
3076 "Received CHANNEL_OPEN on h_port %s from %s\n",
3077 GNUNET_h2s (&copen->h_port),
3078 GCT_2s (t));
3080 copen->ctn,
3081 &copen->h_port,
3082 ntohl (copen->opt));
3083 if (NULL != t->destroy_task)
3084 {
3085 GNUNET_SCHEDULER_cancel (t->destroy_task);
3086 t->destroy_task = NULL;
3087 }
3090 ntohl (copen->ctn.cn),
3091 ch,
3093}

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelOpenMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_channel_incoming_new(), GCCH_handle_duplicate_open(), GCT_2s(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get(), GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_CADET_ChannelOpenMessage::h_port, LOG, GNUNET_CADET_ChannelOpenMessage::opt, and t.

Here is the call graph for this function:

◆ GCT_send_channel_destroy()

void GCT_send_channel_destroy ( struct CadetTunnel t,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)

Send a DESTROY message via the tunnel.

Parameters
tthe tunnel to transmit over
ctnID of the channel to destroy

Definition at line 3103 of file gnunet-service-cadet_tunnels.c.

3105{
3107
3109 "Sending DESTROY message for channel ID %u\n",
3110 ntohl (ctn.cn));
3111 msg.header.size = htons (sizeof(msg));
3113 msg.reserved = htonl (0);
3114 msg.ctn = ctn;
3115 GCT_send (t,
3116 &msg.header,
3117 NULL,
3118 NULL,
3119 &ctn);
3120}

References GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDestroyMessage::ctn, GCT_send(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, LOG, msg, GNUNET_MessageHeader::size, t, and GNUNET_MessageHeader::type.

Referenced by GCCH_channel_local_destroy(), GCCH_handle_channel_plaintext_data(), GCCH_handle_local_ack(), handle_plaintext_channel_open_ack(), handle_plaintext_data(), and handle_plaintext_data_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_plaintext_channel_open_ack()

static void handle_plaintext_channel_open_ack ( void *  cls,
const struct GNUNET_CADET_ChannelOpenAckMessage cm 
)
static

We have received confirmation from the target peer that the given channel could be established (the port is open).

Tell the client.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
cmthe message we received on the tunnel

Definition at line 3132 of file gnunet-service-cadet_tunnels.c.

3135{
3136 struct CadetTunnel *t = cls;
3137 struct CadetChannel *ch;
3138
3139 ch = lookup_channel (t,
3140 cm->ctn);
3141 if (NULL == ch)
3142 {
3143 /* We don't know about such a channel, might have been destroyed on our
3144 end in the meantime, or never existed. Send back a DESTROY. */
3146 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3147 ntohl (cm->ctn.cn));
3149 cm->ctn);
3150 return;
3151 }
3153 "Received channel OPEN_ACK on channel %s from %s\n",
3154 GCCH_2s (ch),
3155 GCT_2s (t));
3157 GCC_get_id (t->current_ct->cc),
3158 &cm->port);
3159}

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelOpenAckMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_handle_channel_open_ack(), GCT_2s(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), GNUNET_CADET_ChannelOpenAckMessage::port, and t.

Here is the call graph for this function:

◆ handle_plaintext_channel_destroy()

static void handle_plaintext_channel_destroy ( void *  cls,
const struct GNUNET_CADET_ChannelDestroyMessage cm 
)
static

We received a message saying that a channel should be destroyed.

Pass it on to the correct channel.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
cmthe message we received on the tunnel

Definition at line 3170 of file gnunet-service-cadet_tunnels.c.

3173{
3174 struct CadetTunnel *t = cls;
3175 struct CadetChannel *ch;
3176
3177 ch = lookup_channel (t,
3178 cm->ctn);
3179 if (NULL == ch)
3180 {
3181 /* We don't know about such a channel, might have been destroyed on our
3182 end in the meantime, or never existed. */
3184 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3185 ntohl (cm->ctn.cn));
3186 return;
3187 }
3189 "Received channel DESTROY on %s from %s\n",
3190 GCCH_2s (ch),
3191 GCT_2s (t));
3193 GCC_get_id (t->current_ct->cc));
3194}

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDestroyMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_handle_remote_destroy(), GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), and t.

Here is the call graph for this function:

◆ handle_decrypted()

static int handle_decrypted ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching).

Parameters
clsthe struct CadetTunnel that got the message
msgthe message
Returns
GNUNET_OK on success (always) GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 3208 of file gnunet-service-cadet_tunnels.c.

3210{
3211 struct CadetTunnel *t = cls;
3212
3213 GNUNET_assert (NULL != t->current_ct);
3215 msg);
3216 return GNUNET_OK;
3217}

References GNUNET_assert, GNUNET_MQ_inject_message(), GNUNET_OK, msg, and t.

Referenced by GCT_create_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decrypted_error_cb()

static void decrypted_error_cb ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Function called if we had an error processing an incoming decrypted message.

Parameters
clsthe struct CadetTunnel
errorerror code

Definition at line 3228 of file gnunet-service-cadet_tunnels.c.

3230{
3231 GNUNET_break_op (0);
3232}

References GNUNET_break_op.

Referenced by GCT_create_tunnel().

Here is the caller graph for this function:

◆ GCT_create_tunnel()

struct CadetTunnel * GCT_create_tunnel ( struct CadetPeer destination)

Create a tunnel to destination.

Must only be called from within GCP_get_tunnel().

Parameters
destinationwhere to create the tunnel to
Returns
new tunnel to destination

Definition at line 3243 of file gnunet-service-cadet_tunnels.c.

3244{
3245 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3247 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3249 struct GNUNET_MessageHeader,
3250 t),
3251 GNUNET_MQ_hd_var_size (plaintext_data,
3254 t),
3255 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3258 t),
3259 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3262 t),
3263 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3266 t),
3267 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3270 t),
3272 };
3273
3274 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3275 new_ephemeral (&t->ax);
3277 t->destination = destination;
3279 t->maintain_connections_task
3281 t);
3282 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3283 NULL,
3284 NULL,
3285 NULL,
3286 handlers,
3288 t);
3290 t);
3291 return t;
3292}

References decrypted_error_cb(), GNUNET_CONTAINER_multihashmap32_create(), GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_MQ_queue_for_callbacks(), GNUNET_MST_create(), GNUNET_new, GNUNET_SCHEDULER_add_now(), handle_decrypted(), handlers, INITIAL_KX_RETRY_DELAY, maintain_connections_cb(), new_ephemeral(), and t.

Referenced by GCP_get_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_add_inbound_connection()

int GCT_add_inbound_connection ( struct CadetTunnel t,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cid,
struct CadetPeerPath path 
)

Add a connection to the tunnel.

Parameters
ta tunnel
cidconnection identifier to use for the connection
pathpath to use for the connection
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure (duplicate connection)

Definition at line 3296 of file gnunet-service-cadet_tunnels.c.

3300{
3301 struct CadetTConnection *ct;
3302
3303 ct = GNUNET_new (struct CadetTConnection);
3305 ct->t = t;
3306 ct->cc = GCC_create_inbound (t->destination,
3307 path,
3308 ct,
3309 cid,
3311 ct);
3312 if (NULL == ct->cc)
3313 {
3315 "%s refused inbound %s (duplicate)\n",
3316 GCT_2s (t),
3317 GCC_2s (ct->cc));
3318 GNUNET_free (ct);
3319 return GNUNET_SYSERR;
3320 }
3321 /* FIXME: schedule job to kill connection (and path?) if it takes
3322 too long to get ready! (And track performance data on how long
3323 other connections took with the tunnel!)
3324 => Note: to be done within 'connection'-logic! */
3325 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3326 t->connection_busy_tail,
3327 ct);
3328 t->num_busy_connections++;
3330 "%s has new %s\n",
3331 GCT_2s (t),
3332 GCC_2s (ct->cc));
3333 return GNUNET_OK;
3334}

References CadetTConnection::cc, connection_ready_cb(), CadetTConnection::created, GCC_2s(), GCC_create_inbound(), GCT_2s(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_absolute_get(), LOG, t, and CadetTConnection::t.

Referenced by handle_connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_encrypted()

void GCT_handle_encrypted ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelEncryptedMessage msg 
)

Handle encrypted message.

Parameters
ctconnection/tunnel combo that received encrypted message
msgthe encrypted message to decrypt

Definition at line 3344 of file gnunet-service-cadet_tunnels.c.

3346{
3347 struct CadetTunnel *t = ct->t;
3348 uint16_t size = ntohs (msg->header.size);
3349 char cbuf[size] GNUNET_ALIGN;
3350 ssize_t decrypted_size;
3351
3353 "%s received %u bytes of encrypted data in state %d\n",
3354 GCT_2s (t),
3355 (unsigned int) size,
3356 t->estate);
3357
3358 switch (t->estate)
3359 {
3362 /* We did not even SEND our KX, how can the other peer
3363 send us encrypted data? Must have been that we went
3364 down and the other peer still things we are up.
3365 Let's send it KX back. */
3367 "# received encrypted without any KX",
3368 1,
3369 GNUNET_NO);
3370 if (NULL != t->kx_task)
3371 {
3372 GNUNET_SCHEDULER_cancel (t->kx_task);
3373 t->kx_task = NULL;
3374 }
3375 send_kx (t,
3376 ct,
3377 &t->ax);
3378 return;
3379
3381 /* We send KX, and other peer send KX to us at the same time.
3382 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3384 "# received encrypted without KX_AUTH",
3385 1,
3386 GNUNET_NO);
3387 if (NULL != t->kx_task)
3388 {
3389 GNUNET_SCHEDULER_cancel (t->kx_task);
3390 t->kx_task = NULL;
3391 }
3392 send_kx_auth (t,
3393 ct,
3394 &t->ax,
3395 GNUNET_YES);
3396 return;
3397
3399 /* We did not get the KX of the other peer, but that
3400 might have been lost. Send our KX again immediately. */
3402 "# received encrypted without KX",
3403 1,
3404 GNUNET_NO);
3405 if (NULL != t->kx_task)
3406 {
3407 GNUNET_SCHEDULER_cancel (t->kx_task);
3408 t->kx_task = NULL;
3409 }
3410 send_kx (t,
3411 ct,
3412 &t->ax);
3413 return;
3414
3416 /* Great, first payload, we might graduate to OK! */
3418 /* We are up and running, all good. */
3419 break;
3420 }
3421
3422 decrypted_size = -1;
3423 if (CADET_TUNNEL_KEY_OK == t->estate)
3424 {
3425 /* We have well-established key material available,
3426 try that. (This is the common case.) */
3427 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3428 cbuf,
3429 msg,
3430 size);
3431 }
3432
3433 if ((-1 == decrypted_size) &&
3434 (NULL != t->unverified_ax))
3435 {
3436 /* We have un-authenticated KX material available. We should try
3437 this as a back-up option, in case the sender crashed and
3438 switched keys. */
3439 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3440 cbuf,
3441 msg,
3442 size);
3443 if (-1 != decrypted_size)
3444 {
3445 /* It worked! Treat this as authentication of the AX data! */
3446 cleanup_ax (&t->ax);
3447 t->ax = *t->unverified_ax;
3448 GNUNET_free (t->unverified_ax);
3449 t->unverified_ax = NULL;
3450 }
3451 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3452 {
3453 /* First time it worked, move tunnel into production! */
3456 if (NULL != t->send_task)
3457 GNUNET_SCHEDULER_cancel (t->send_task);
3459 t);
3460 }
3461 }
3462 if (NULL != t->unverified_ax)
3463 {
3464 /* We had unverified KX material that was useless; so increment
3465 counter and eventually move to ignore it. Note that we even do
3466 this increment if we successfully decrypted with the old KX
3467 material and thus didn't even both with the new one. This is
3468 the ideal case, as a malicious injection of bogus KX data
3469 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3471 "Failed to decrypt message with unverified KX data %u times\n",
3472 t->unverified_attempts);
3473 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3474 {
3475 cleanup_ax (t->unverified_ax);
3476 GNUNET_free (t->unverified_ax);
3477 t->unverified_ax = NULL;
3478 }
3479 }
3480
3481 if (-1 == decrypted_size)
3482 {
3483 /* Decryption failed for good, complain. */
3485 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3486 GCT_2s (t));
3488 "# unable to decrypt",
3489 1,
3490 GNUNET_NO);
3491 if (NULL != t->kx_task)
3492 {
3493 GNUNET_SCHEDULER_cancel (t->kx_task);
3494 t->kx_task = NULL;
3495 }
3496 send_kx (t,
3497 ct,
3498 &t->ax);
3499 return;
3500 }
3502 "# decrypted bytes",
3503 decrypted_size,
3504 GNUNET_NO);
3505
3506 /* The MST will ultimately call #handle_decrypted() on each message. */
3507 t->current_ct = ct;
3510 cbuf,
3511 decrypted_size,
3512 GNUNET_YES,
3513 GNUNET_NO));
3514 t->current_ct = NULL;
3515}

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, cleanup_ax(), GCT_2s(), GCT_change_estate(), GNUNET_ALIGN, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, LOG, MAX_UNVERIFIED_ATTEMPTS, msg, send_kx(), send_kx_auth(), GNUNET_MessageHeader::size, size, stats, t, CadetTConnection::t, t_ax_decrypt_and_validate(), and trigger_transmissions().

Referenced by GCC_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_send()

struct CadetTunnelQueueEntry * GCT_send ( struct CadetTunnel t,
const struct GNUNET_MessageHeader message,
GCT_SendContinuation  cont,
void *  cont_cls,
struct GNUNET_CADET_ChannelTunnelNumber ctn 
)

Sends an already built message on a tunnel, encrypting it and choosing the best connection if not provided.

Parameters
messageMessage to send. Function modifies it.
tTunnel on which this message is transmitted.
contContinuation to call once message is really sent.
cont_clsClosure for cont.
Returns
Handle to cancel message.

Definition at line 3519 of file gnunet-service-cadet_tunnels.c.

3524{
3525 struct CadetTunnelQueueEntry *tq;
3526 uint16_t message_size;
3527 uint16_t payload_size;
3528 struct GNUNET_MQ_Envelope *env;
3530 struct CadetChannel *ch;
3531
3532 if (NULL != ctn)
3533 {
3534 ch = lookup_channel (t,
3535 *ctn);
3536 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3537 {
3538 GNUNET_break (0);
3539 return NULL;
3540 }
3541 }
3542
3543 if (CADET_TUNNEL_KEY_OK != t->estate)
3544 {
3545 GNUNET_break (0);
3546 return NULL;
3547 }
3548 message_size = ntohs (message->size);
3549 payload_size = message_size + sizeof (struct GNUNET_CRYPTO_AeadMac);
3551 "Encrypting %u bytes for %s\n",
3552 (unsigned int) message_size,
3553 GCT_2s (t));
3554 env = GNUNET_MQ_msg_extra (ax_msg,
3555 payload_size,
3557 t_ax_encrypt (&t->ax,
3558 &ax_msg[1],
3559 message,
3560 message_size);
3562 "# encrypted bytes",
3563 payload_size,
3564 GNUNET_NO);
3565 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3566 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3567 /* FIXME: we should do this once, not once per message;
3568 this is a point multiplication, and DHRs does not
3569 change all the time. */
3571 &ax_msg->ax_header.DHRs);
3572 t_h_encrypt (&t->ax,
3573 ax_msg,
3574 payload_size,
3575 (unsigned char*) &ax_msg[1]);
3576
3577 tq = GNUNET_malloc (sizeof(*tq));
3578 tq->t = t;
3579 tq->env = env;
3580 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3581 tq->cont = cont;
3582 tq->cont_cls = cont_cls;
3584 t->tq_tail,
3585 tq);
3586 if (NULL != t->send_task)
3587 GNUNET_SCHEDULER_cancel (t->send_task);
3588 t->send_task
3590 t);
3591 return tq;
3592}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, CADET_TUNNEL_KEY_OK, ch, GNUNET_CADET_TunnelEncryptedMessage::cid, CadetTunnelQueueEntry::cid, CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, CadetChannel::ctn, GNUNET_CADET_AxHeader::DHRs, env, CadetTunnelQueueEntry::env, GCCH_is_type_to_drop(), GCT_2s(), GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_malloc, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED, GNUNET_MQ_msg_extra, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), LOG, lookup_channel(), GNUNET_CADET_AxHeader::Ns, GNUNET_CADET_AxHeader::PNs, GNUNET_MessageHeader::size, stats, t, CadetTunnelQueueEntry::t, t_ax_encrypt(), t_h_encrypt(), and trigger_transmissions().

Referenced by GCCH_handle_local_data(), GCT_send_channel_destroy(), retry_transmission(), send_channel_data_ack(), send_channel_open(), send_keepalive(), and send_open_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_send_cancel()

void GCT_send_cancel ( struct CadetTunnelQueueEntry q)

Cancel a previously sent message while it's in the queue.

ONLY can be called before the continuation given to the send function is called. Once the continuation is called, the message is no longer in the queue!

Parameters
qHandle to the queue entry to cancel.

Definition at line 3596 of file gnunet-service-cadet_tunnels.c.

3597{
3598 struct CadetTunnel *t = tq->t;
3599
3601 t->tq_tail,
3602 tq);
3603 GNUNET_MQ_discard (tq->env);
3604 GNUNET_free (tq);
3605}

References CadetTunnelQueueEntry::env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_discard(), t, and CadetTunnelQueueEntry::t.

Referenced by channel_destroy(), destroy_tunnel(), GCC_destroy(), handle_matching_ack(), send_channel_data_ack(), send_channel_open(), and send_open_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_iterate_connections()

void GCT_iterate_connections ( struct CadetTunnel t,
GCT_ConnectionIterator  iter,
void *  iter_cls 
)

Iterate over all connections of a tunnel.

Parameters
tTunnel whose connections to iterate.
iterIterator.
iter_clsClosure for iter.

Definition at line 3616 of file gnunet-service-cadet_tunnels.c.

3619{
3620 struct CadetTConnection *n;
3621
3622 for (struct CadetTConnection *ct = t->connection_ready_head;
3623 NULL != ct;
3624 ct = n)
3625 {
3626 n = ct->next;
3627 iter (iter_cls,
3628 ct);
3629 }
3630 for (struct CadetTConnection *ct = t->connection_busy_head;
3631 NULL != ct;
3632 ct = n)
3633 {
3634 n = ct->next;
3635 iter (iter_cls,
3636 ct);
3637 }
3638}

References CadetTConnection::next, and t.

Referenced by consider_path_cb(), destroy_tunnel(), and maintain_connections_cb().

Here is the caller graph for this function:

◆ iterate_channels_cb()

static int iterate_channels_cb ( void *  cls,
uint32_t  key,
void *  value 
)
static

Helper function for GCT_iterate_channels.

Parameters
clsthe struct ChanIterCls
keyunused
valuea struct CadetChannel
Returns
GNUNET_OK

Definition at line 3667 of file gnunet-service-cadet_tunnels.c.

3670{
3671 struct ChanIterCls *ctx = cls;
3672 struct CadetChannel *ch = value;
3673
3674 ctx->iter (ctx->iter_cls,
3675 ch);
3676 return GNUNET_OK;
3677}

References ch, ctx, GNUNET_OK, and value.

Referenced by GCT_iterate_channels().

Here is the caller graph for this function:

◆ GCT_iterate_channels()

void GCT_iterate_channels ( struct CadetTunnel t,
GCT_ChannelIterator  iter,
void *  iter_cls 
)

Iterate over all channels of a tunnel.

Parameters
tTunnel whose channels to iterate.
iterIterator.
iter_clsClosure for iter.

Definition at line 3688 of file gnunet-service-cadet_tunnels.c.

3691{
3692 struct ChanIterCls ctx;
3693
3694 ctx.iter = iter;
3695 ctx.iter_cls = iter_cls;
3698 &ctx);
3699}

References ctx, GNUNET_CONTAINER_multihashmap32_iterate(), ChanIterCls::iter, ChanIterCls::iter_cls, iterate_channels_cb(), and t.

Here is the call graph for this function:

◆ debug_channel()

static int debug_channel ( void *  cls,
uint32_t  key,
void *  value 
)
static

Call GCCH_debug() on a channel.

Parameters
clspoints to the log level to use
keyunused
valuethe struct CadetChannel to dump
Returns
GNUNET_OK (continue iteration)

Definition at line 3711 of file gnunet-service-cadet_tunnels.c.

3714{
3715 const enum GNUNET_ErrorType *level = cls;
3716 struct CadetChannel *ch = value;
3717
3718 GCCH_debug (ch, *level);
3719 return GNUNET_OK;
3720}

References ch, GCCH_debug(), GNUNET_OK, and value.

Referenced by GCT_debug().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_debug()

void GCT_debug ( const struct CadetTunnel t,
enum GNUNET_ErrorType  level 
)

Log all possible info about the tunnel state.

Parameters
tTunnel to debug.
levelDebug level to use.

Definition at line 3734 of file gnunet-service-cadet_tunnels.c.

3736{
3737#if ! defined(GNUNET_CULL_LOGGING)
3738 struct CadetTConnection *iter_c;
3739 int do_log;
3740
3742 "cadet-tun",
3743 __FILE__, __FUNCTION__, __LINE__);
3744 if (0 == do_log)
3745 return;
3746
3747 LOG2 (level,
3748 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3749 GCT_2s (t),
3750 estate2s (t->estate),
3751 t->tq_len,
3753 LOG2 (level,
3754 "TTT channels:\n");
3757 &level);
3758 LOG2 (level,
3759 "TTT connections:\n");
3760 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3761 GCC_debug (iter_c->cc,
3762 level);
3763 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3764 GCC_debug (iter_c->cc,
3765 level);
3766
3767 LOG2 (level,
3768 "TTT TUNNEL END\n");
3769#endif
3770}

References CadetTConnection::cc, debug_channel(), estate2s(), GCC_debug(), GCT_2s(), GCT_count_any_connections(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_BULK, GNUNET_get_log_call_status(), LOG2, CadetTConnection::next, and t.

Here is the call graph for this function: