GNUnet 0.27.0
 
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_hmac (const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
 Calculate HMAC.
 
static void t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
 Perform a HMAC.
 
static void t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *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)
 Encrypt header with the axolotl header key.
 
static void t_h_decrypt (struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, 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_SymmetricSessionKey *HKr)
 Delete a key from the list of skipped keys.
 
static int store_ax_keys (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *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
753static void
754t_hmac (const void *plaintext,
755 size_t size,
756 uint32_t iv,
758 struct GNUNET_ShortHashCode *hmac)
759{
760 static const char ctx[] = "cadet authentication key";
761 struct GNUNET_CRYPTO_AuthKey auth_key;
762 struct GNUNET_HashCode hash;
763
764 // FIXME now that we directly invoke HKDF instead of a
765 // thin wrapper we can clearly see the sillyness of adding
766 // the key parameter twice...
768 &auth_key,
769 sizeof auth_key,
770 &iv,
771 sizeof(iv),
772 key,
773 sizeof(*key),
776 /* Two step: GNUNET_ShortHash is only 256 bits,
777 GNUNET_HashCode is 512, so we truncate. */
778 GNUNET_CRYPTO_hmac (&auth_key,
779 plaintext,
780 size,
781 &hash);
782 GNUNET_memcpy (hmac,
783 &hash,
784 sizeof(*hmac));
785}
786
787
796static void
798 struct GNUNET_HashCode *hash,
799 const void *source,
800 unsigned int len)
801{
802 static const char ctx[] = "axolotl HMAC-HASH";
803 struct GNUNET_CRYPTO_AuthKey auth_key;
804
806 &auth_key,
807 sizeof auth_key,
808 ctx,
809 sizeof(ctx),
810 key,
811 sizeof *key);
812 GNUNET_CRYPTO_hmac (&auth_key,
813 source,
814 len,
815 hash);
816}
817
818
827static void
830 const void *source,
831 unsigned int len)
832{
833 static const char ctx[] = "axolotl derive key";
834 struct GNUNET_HashCode h;
835
837 &h,
838 source,
839 len);
841 out, sizeof(*out),
842 ctx, sizeof(ctx),
843 &h, sizeof(h));
844}
845
846
855static void
857 void *dst,
858 const void *src,
859 size_t size)
860{
863 size_t out_size;
864
865 ax->ratchet_counter++;
866 if ((GNUNET_YES == ax->ratchet_allowed) &&
867 ((ratchet_messages <= ax->ratchet_counter) ||
870 {
872 }
873 if (GNUNET_YES == ax->ratchet_flag)
874 {
875 /* Advance ratchet */
877 struct GNUNET_HashCode dh;
878 struct GNUNET_HashCode hmac;
879 static const char ctx[] = "axolotl ratchet";
880
881 new_ephemeral (ax);
882 ax->HKs = ax->NHKs;
883
884 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
886 &ax->DHRr,
887 &dh);
888 t_ax_hmac_hash (&ax->RK,
889 &hmac,
890 &dh,
891 sizeof(dh));
893 keys, sizeof(keys),
894 ctx, sizeof(ctx),
895 &hmac, sizeof(hmac));
896 ax->RK = keys[0];
897 ax->NHKs = keys[1];
898 ax->CKs = keys[2];
899
900 ax->PNs = ax->Ns;
901 ax->Ns = 0;
904 ax->ratchet_counter = 0;
908 }
909
911 &MK,
912 "0",
913 1);
914
916 sizeof iv,
917 NULL,
918 0,
919 &MK,
920 sizeof MK);
921
922 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
923 size,
924 &MK,
925 &iv,
926 dst);
927 GNUNET_assert (size == out_size);
929 &ax->CKs,
930 "1",
931 1);
932}
933
934
943static void
945 void *dst,
946 const void *src,
947 size_t size)
948{
951 size_t out_size;
952
954 &MK,
955 "0",
956 1);
957
959 sizeof iv,
960 NULL,
961 0,
962 &MK,
963 sizeof MK);
964 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
965 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
966 size,
967 &MK,
968 &iv,
969 dst);
970 GNUNET_assert (out_size == size);
972 &ax->CKr,
973 "1",
974 1);
975}
976
977
984static void
987{
989 size_t out_size;
990
992 sizeof iv,
993 NULL,
994 0,
995 &ax->HKs,
996 sizeof ax->HKs);
997 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
998 sizeof(struct
1000 &ax->HKs,
1001 &iv,
1002 &msg->ax_header);
1003 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1004}
1005
1006
1014static void
1016 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1018{
1020 size_t out_size;
1021
1023 sizeof iv,
1024 NULL,
1025 0,
1026 &ax->HKr,
1027 sizeof ax->HKr);
1028
1029
1031 sizeof(struct
1033 &ax->HKr,
1034 &iv,
1035 &dst->ax_header.Ns);
1036 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1037}
1038
1039
1046static void
1048 struct CadetTunnelSkippedKey *key)
1049{
1051 ax->skipped_tail,
1052 key);
1053 GNUNET_free (key);
1054 ax->skipped--;
1055}
1056
1057
1068static ssize_t
1070 void *dst,
1071 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1072 size_t size)
1073{
1074 struct CadetTunnelSkippedKey *key;
1075 struct GNUNET_ShortHashCode *hmac;
1077 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1078 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
1079 size_t esize;
1080 size_t res;
1081 size_t len;
1082 unsigned int N;
1083
1085 "Trying skipped keys\n");
1086 hmac = &plaintext_header.hmac;
1087 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1088
1089 /* Find a correct Header Key */
1090 valid_HK = NULL;
1091 for (key = ax->skipped_head; NULL != key; key = key->next)
1092 {
1093 t_hmac (&src->ax_header,
1094 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1095 0,
1096 &key->HK,
1097 hmac);
1098 if (0 == GNUNET_memcmp (hmac,
1099 &src->hmac))
1100 {
1101 valid_HK = &key->HK;
1102 break;
1103 }
1104 }
1105 if (NULL == key)
1106 return -1;
1107
1108 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1110 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1111 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1112
1113 /* Decrypt header */
1115 sizeof iv,
1116 NULL,
1117 0,
1118 &key->HK,
1119 sizeof key->HK);
1120
1122 sizeof(struct GNUNET_CADET_AxHeader),
1123 &key->HK,
1124 &iv,
1125 &plaintext_header.ax_header.Ns);
1126 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1127
1128 /* Find the correct message key */
1129 N = ntohl (plaintext_header.ax_header.Ns);
1130 while ((NULL != key) &&
1131 (N != key->Kn))
1132 key = key->next;
1133 if ((NULL == key) ||
1134 (0 != GNUNET_memcmp (&key->HK,
1135 valid_HK)))
1136 return -1;
1137
1138 /* Decrypt payload */
1140 sizeof iv,
1141 NULL,
1142 0,
1143 &key->MK,
1144 sizeof key->MK);
1145
1147 len,
1148 &key->MK,
1149 &iv,
1150 dst);
1152 key);
1153 return res;
1154}
1155
1156
1163static void
1165 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1166{
1167 struct CadetTunnelSkippedKey *key;
1168
1170 key->timestamp = GNUNET_TIME_absolute_get ();
1171 key->Kn = ax->Nr;
1172 key->HK = ax->HKr;
1173 t_hmac_derive_key (&ax->CKr,
1174 &key->MK,
1175 "0",
1176 1);
1177 t_hmac_derive_key (&ax->CKr,
1178 &ax->CKr,
1179 "1",
1180 1);
1182 ax->skipped_tail,
1183 key);
1184 ax->skipped++;
1185 ax->Nr++;
1186}
1187
1188
1199static int
1201 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1202 uint32_t Np)
1203{
1204 int gap;
1205
1206 gap = Np - ax->Nr;
1208 "Storing skipped keys [%u, %u)\n",
1209 ax->Nr,
1210 Np);
1211 if (MAX_KEY_GAP < gap)
1212 {
1213 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1214 /* TODO: start new key exchange on return */
1215 GNUNET_break_op (0);
1217 "Got message %u, expected %u+\n",
1218 Np,
1219 ax->Nr);
1220 return GNUNET_SYSERR;
1221 }
1222 if (0 > gap)
1223 {
1224 /* Delayed message: don't store keys, flag to try old keys. */
1225 return GNUNET_SYSERR;
1226 }
1227
1228 while (ax->Nr < Np)
1230 HKr);
1231
1232 while (ax->skipped > MAX_SKIPPED_KEYS)
1234 ax->skipped_tail);
1235 return GNUNET_OK;
1236}
1237
1238
1249static ssize_t
1251 void *dst,
1252 const struct
1254 size_t size)
1255{
1256 struct GNUNET_ShortHashCode msg_hmac;
1257 struct GNUNET_HashCode hmac;
1258 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1259 uint32_t Np;
1260 uint32_t PNp;
1261 size_t esize; /* Size of encrypted payload */
1262
1263 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1264
1265 /* Try current HK */
1266 t_hmac (&src->ax_header,
1267 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1268 0, &ax->HKr,
1269 &msg_hmac);
1270 if (0 != GNUNET_memcmp (&msg_hmac,
1271 &src->hmac))
1272 {
1273 static const char ctx[] = "axolotl ratchet";
1274 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1276 struct GNUNET_HashCode dh;
1277 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1278
1279 /* Try Next HK */
1280 t_hmac (&src->ax_header,
1281 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1282 0,
1283 &ax->NHKr,
1284 &msg_hmac);
1285 if (0 != GNUNET_memcmp (&msg_hmac,
1286 &src->hmac))
1287 {
1288 /* Try the skipped keys, if that fails, we're out of luck. */
1289 return try_old_ax_keys (ax,
1290 dst,
1291 src,
1292 size);
1293 }
1294 HK = ax->HKr;
1295 ax->HKr = ax->NHKr;
1296 t_h_decrypt (ax,
1297 src,
1298 &plaintext_header);
1299 Np = ntohl (plaintext_header.ax_header.Ns);
1300 PNp = ntohl (plaintext_header.ax_header.PNs);
1301 DHRp = &plaintext_header.ax_header.DHRs;
1302 store_ax_keys (ax,
1303 &HK,
1304 PNp);
1305
1306 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1308 DHRp,
1309 &dh);
1310 t_ax_hmac_hash (&ax->RK,
1311 &hmac,
1312 &dh, sizeof(dh));
1314 keys, sizeof(keys),
1315 ctx, sizeof(ctx),
1316 &hmac, sizeof(hmac));
1317
1318 /* Commit "purported" keys */
1319 ax->RK = keys[0];
1320 ax->NHKr = keys[1];
1321 ax->CKr = keys[2];
1322 ax->DHRr = *DHRp;
1323 ax->Nr = 0;
1325 }
1326 else
1327 {
1328 t_h_decrypt (ax,
1329 src,
1330 &plaintext_header);
1331 Np = ntohl (plaintext_header.ax_header.Ns);
1332 PNp = ntohl (plaintext_header.ax_header.PNs);
1333 }
1334 if ((Np != ax->Nr) &&
1335 (GNUNET_OK != store_ax_keys (ax,
1336 &ax->HKr,
1337 Np)))
1338 {
1339 /* Try the skipped keys, if that fails, we're out of luck. */
1340 return try_old_ax_keys (ax,
1341 dst,
1342 src,
1343 size);
1344 }
1345
1346 t_ax_decrypt (ax,
1347 dst,
1348 &src[1],
1349 esize);
1350 ax->Nr = Np + 1;
1351 return esize;
1352}
1353
1354
1364static int
1365notify_tunnel_up_cb (void *cls,
1366 uint32_t key,
1367 void *value)
1368{
1369 struct CadetChannel *ch = value;
1370
1372 return GNUNET_OK;
1373}
1374
1375
1383void
1386{
1387 enum CadetTunnelEState old = t->estate;
1388
1389 t->estate = state;
1391 "%s estate changed from %s to %s\n",
1392 GCT_2s (t),
1393 estate2s (old),
1394 estate2s (state));
1395
1396 if ((CADET_TUNNEL_KEY_OK != old) &&
1397 (CADET_TUNNEL_KEY_OK == t->estate))
1398 {
1399 if (NULL != t->kx_task)
1400 {
1401 GNUNET_SCHEDULER_cancel (t->kx_task);
1402 t->kx_task = NULL;
1403 }
1404 /* notify all channels that have been waiting */
1407 t);
1408 if (NULL != t->send_task)
1409 GNUNET_SCHEDULER_cancel (t->send_task);
1411 t);
1412 }
1413}
1414
1415
1424static void
1425send_kx (struct CadetTunnel *t,
1426 struct CadetTConnection *ct,
1427 struct CadetTunnelAxolotl *ax)
1428{
1429 struct CadetConnection *cc;
1430 struct GNUNET_MQ_Envelope *env;
1433
1434 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1435 return; /* only Alice may send KX */
1436 if ((NULL == ct) ||
1437 (GNUNET_NO == ct->is_ready))
1438 ct = get_ready_connection (t);
1439 if (NULL == ct)
1440 {
1442 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1443 GCT_2s (t),
1444 estate2s (t->estate));
1445 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1446 return;
1447 }
1448 cc = ct->cc;
1451 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1452 msg->flags = htonl (flags);
1453 msg->cid = *GCC_get_id (cc);
1455 &msg->ephemeral_key);
1456#if DEBUG_KX
1457 msg->ephemeral_key_XXX = ax->kx_0;
1458#endif
1460 "Sending KX message to %s with ephemeral %s on CID %s\n",
1461 GCT_2s (t),
1462 GNUNET_e2s (&msg->ephemeral_key),
1463 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1465 &msg->ratchet_key);
1467 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1468 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1469 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1472 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1475 GCC_transmit (cc,
1476 env);
1478 "# KX transmitted",
1479 1,
1480 GNUNET_NO);
1481}
1482
1483
1494static void
1495send_kx_auth (struct CadetTunnel *t,
1496 struct CadetTConnection *ct,
1497 struct CadetTunnelAxolotl *ax,
1498 int force_reply)
1499{
1500 struct CadetConnection *cc;
1501 struct GNUNET_MQ_Envelope *env;
1503 enum GNUNET_CADET_KX_Flags flags;
1504
1505 if ((NULL == ct) ||
1506 (GNUNET_NO == ct->is_ready))
1507 ct = get_ready_connection (t);
1508 if (NULL == ct)
1509 {
1511 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1512 GCT_2s (t));
1513 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1514 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1515 return;
1516 }
1517 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1518 cc = ct->cc;
1522 if (GNUNET_YES == force_reply)
1524 msg->kx.flags = htonl (flags);
1525 msg->kx.cid = *GCC_get_id (cc);
1527 &msg->kx.ephemeral_key);
1529 &msg->kx.ratchet_key);
1530#if DEBUG_KX
1531 msg->kx.ephemeral_key_XXX = ax->kx_0;
1532 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1533#endif
1535 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1536 GCT_2s (t),
1537 GNUNET_e2s (&msg->kx.ephemeral_key),
1538 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1539
1540 /* Compute authenticator (this is the main difference to #send_kx()) */
1541 GNUNET_CRYPTO_hash (&ax->RK,
1542 sizeof(ax->RK),
1543 &msg->auth);
1544 /* Compute when to be triggered again; actual job will
1545 be scheduled via #connection_ready_cb() */
1546 t->kx_retry_delay
1547 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1548 t->next_kx_attempt
1549 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1550
1551 /* Send via cc, mark it as unready */
1553
1554 /* Update state machine, unless we are already OK */
1555 if (CADET_TUNNEL_KEY_OK != t->estate)
1558 GCC_transmit (cc,
1559 env);
1561 "# KX_AUTH transmitted",
1562 1,
1563 GNUNET_NO);
1564}
1565
1566
1572static void
1573cleanup_ax (struct CadetTunnelAxolotl *ax)
1574{
1575 while (NULL != ax->skipped_head)
1577 ax->skipped_head);
1578 GNUNET_assert (0 == ax->skipped);
1581}
1582
1583
1595static void
1596update_ax_by_kx (void *cls,
1597 const struct GNUNET_HashCode *key_result)
1598{
1599 struct CadetTunnelAsync *as;
1600 struct GNUNET_HashCode key_material[3];
1601 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1602 struct CadetTunnelAxolotl *ax;
1603 const struct GNUNET_PeerIdentity *pid;
1604 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1605 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1606 const char salt[] = "CADET Axolotl salt";
1607 int am_I_alice;
1608
1609 as = cls;
1610 ax = &as->ax;
1611 pid = &as->peer_id;
1612 ephemeral_key = &as->ephemeral_key;
1613 ratchet_key = &as->ratchet_key;
1614
1615 as->ecdh_op = NULL;
1616
1618 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1619 GNUNET_e2s (ephemeral_key));
1620
1621 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1622 {
1623 GNUNET_break_op (0);
1624 if (as->cb)
1625 as->cb (as->cb_cls, GNUNET_SYSERR);
1626 return;
1627 }
1628
1629 if (0 == GNUNET_memcmp (&ax->DHRr,
1630 ratchet_key))
1631 {
1633 "# Ratchet key already known",
1634 1,
1635 GNUNET_NO);
1637 "Ratchet key already known. Ignoring KX.\n");
1638 if (as->cb)
1639 as->cb (as->cb_cls, GNUNET_NO);
1640 return;
1641 }
1642
1643 ax->DHRr = *ratchet_key;
1644 ax->last_ephemeral = *ephemeral_key;
1645 /* ECDH A B0 */
1646 if (GNUNET_YES == am_I_alice)
1647 {
1648 GNUNET_memcpy (&key_material[0], key_result,
1649 sizeof (*key_result));
1650 }
1651 else
1652 {
1653 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1654 &pid->public_key, /* A */
1655 &key_material[0]);
1656 }
1657 /* ECDH A0 B */
1658 if (GNUNET_YES == am_I_alice)
1659 {
1660 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1661 &pid->public_key, /* B */
1662 &key_material[1]);
1663 }
1664 else
1665 {
1666 GNUNET_memcpy (&key_material[1], key_result,
1667 sizeof (*key_result));
1668 }
1669
1670 /* ECDH A0 B0 */
1671 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1672 ephemeral_key, /* B0 or A0 */
1673 &key_material[2]);
1674 /* KDF */
1676 keys, sizeof(keys),
1677 salt, sizeof(salt),
1678 &key_material, sizeof(key_material));
1679
1680 if (0 == memcmp (&ax->RK,
1681 &keys[0],
1682 sizeof(ax->RK)))
1683 {
1685 "Root key already known. Ignoring KX.\n");
1687 "# Root key already known",
1688 1,
1689 GNUNET_NO);
1690 if (as->cb)
1691 as->cb (as->cb_cls, GNUNET_NO);
1692 return;
1693 }
1694
1695 ax->RK = keys[0];
1696 if (GNUNET_YES == am_I_alice)
1697 {
1698 ax->HKr = keys[1];
1699 ax->NHKs = keys[2];
1700 ax->NHKr = keys[3];
1701 ax->CKr = keys[4];
1703 }
1704 else
1705 {
1706 ax->HKs = keys[1];
1707 ax->NHKr = keys[2];
1708 ax->NHKs = keys[3];
1709 ax->CKs = keys[4];
1710 ax->ratchet_flag = GNUNET_NO;
1713 ratchet_time);
1714 }
1715
1716 if (as->cb)
1717 as->cb (as->cb_cls, GNUNET_OK);
1718}
1719
1720
1726static void
1727retry_kx (void *cls)
1728{
1729 struct CadetTunnel *t = cls;
1730 struct CadetTunnelAxolotl *ax;
1731
1732 t->kx_task = NULL;
1734 "Trying to make KX progress on %s in state %s\n",
1735 GCT_2s (t),
1736 estate2s (t->estate));
1737 switch (t->estate)
1738 {
1739 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1740 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1741 send_kx (t,
1742 NULL,
1743 &t->ax);
1744 break;
1745
1748 /* We are responding, so only require reply
1749 if WE have a channel waiting. */
1750 if (NULL != t->unverified_ax)
1751 {
1752 /* Send AX_AUTH so we might get this one verified */
1753 ax = t->unverified_ax;
1754 }
1755 else
1756 {
1757 /* How can this be? */
1758 GNUNET_break (0);
1759 ax = &t->ax;
1760 }
1761 send_kx_auth (t,
1762 NULL,
1763 ax,
1764 (0 == GCT_count_channels (t))
1765 ? GNUNET_NO
1766 : GNUNET_YES);
1767 break;
1768
1770 /* We are responding, so only require reply
1771 if WE have a channel waiting. */
1772 if (NULL != t->unverified_ax)
1773 {
1774 /* Send AX_AUTH so we might get this one verified */
1775 ax = t->unverified_ax;
1776 }
1777 else
1778 {
1779 /* How can this be? */
1780 GNUNET_break (0);
1781 ax = &t->ax;
1782 }
1783 send_kx_auth (t,
1784 NULL,
1785 ax,
1786 (0 == GCT_count_channels (t))
1787 ? GNUNET_NO
1788 : GNUNET_YES);
1789 break;
1790
1792 /* Must have been the *other* peer asking us to
1793 respond with a KX_AUTH. */
1794 if (NULL != t->unverified_ax)
1795 {
1796 /* Sending AX_AUTH in response to AX so we might get this one verified */
1797 ax = t->unverified_ax;
1798 }
1799 else
1800 {
1801 /* Sending AX_AUTH in response to AX_AUTH */
1802 ax = &t->ax;
1803 }
1804 send_kx_auth (t,
1805 NULL,
1806 ax,
1807 GNUNET_NO);
1808 break;
1809 }
1810}
1811
1812
1819static void
1820cont_GCT_handle_kx (void *cls,
1822{
1823 struct CadetTunnel *t = cls;
1824
1825 if (t->unverified_ax)
1826 *(t->unverified_ax) = t->as.ax;
1827
1829 "Continue handling KX message from %s from %s\n",
1830 GCT_2s (t),
1831 GNUNET_i2s (GCP_get_id (t->destination)));
1832
1834 if (GNUNET_OK != ret)
1835 {
1837 "# Useless KX",
1838 1,
1839 GNUNET_NO);
1840 return; /* duplicate KX, nothing to do */
1841 }
1842 /* move ahead in our state machine */
1843 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1846 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1849
1850 /* KX is still not done, try again our end. */
1851 if (CADET_TUNNEL_KEY_OK != t->estate)
1852 {
1853 if (NULL != t->kx_task)
1854 GNUNET_SCHEDULER_cancel (t->kx_task);
1855 t->kx_task
1857 t);
1858 }
1859}
1860
1861
1868void
1871{
1872 struct CadetTunnel *t = ct->t;
1873
1875 "# KX received",
1876 1,
1877 GNUNET_NO);
1878 if (GNUNET_YES ==
1879 GCT_alice_or_betty (GCP_get_id (t->destination)))
1880 {
1881 /* Betty/Bob is not allowed to send KX! */
1882 GNUNET_break_op (0);
1883 return;
1884 }
1886 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1887 GCT_2s (t),
1888 GNUNET_e2s (&msg->ephemeral_key),
1889 GNUNET_i2s (GCP_get_id (t->destination)),
1890 GCC_2s (ct->cc));
1891#if 1
1892 if ((0 ==
1893 memcmp (&t->ax.DHRr,
1894 &msg->ratchet_key,
1895 sizeof(msg->ratchet_key))) &&
1896 (0 ==
1897 memcmp (&t->ax.last_ephemeral,
1898 &msg->ephemeral_key,
1899 sizeof(msg->ephemeral_key))))
1900
1901 {
1903 "# Duplicate KX received",
1904 1,
1905 GNUNET_NO);
1906 send_kx_auth (t,
1907 ct,
1908 &t->ax,
1909 GNUNET_NO);
1910 return;
1911 }
1912#endif
1913 /* We only keep ONE unverified KX around, so if there is an existing one,
1914 clean it up. */
1915 if (NULL != t->unverified_ax)
1916 {
1917 if ((0 ==
1918 memcmp (&t->unverified_ax->DHRr,
1919 &msg->ratchet_key,
1920 sizeof(msg->ratchet_key))) &&
1921 (0 ==
1922 memcmp (&t->unverified_ax->last_ephemeral,
1923 &msg->ephemeral_key,
1924 sizeof(msg->ephemeral_key))))
1925 {
1927 "# Duplicate unverified KX received",
1928 1,
1929 GNUNET_NO);
1930#if 1
1931 send_kx_auth (t,
1932 ct,
1933 t->unverified_ax,
1934 GNUNET_NO);
1935 return;
1936#endif
1937 }
1938 if ((t->as.ecdh_op) &&
1939 (0 ==
1940 memcmp (&t->as.ratchet_key,
1941 &msg->ratchet_key,
1942 sizeof(msg->ratchet_key))) &&
1943 (0 ==
1944 memcmp (&t->as.ephemeral_key,
1945 &msg->ephemeral_key,
1946 sizeof(msg->ephemeral_key))))
1947 {
1949 "Waiting for previous ECDH operation\n");
1950 return;
1951 }
1953 "Dropping old unverified KX state.\n");
1955 "# Unverified KX dropped for fresh KX",
1956 1,
1957 GNUNET_NO);
1958 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1959 memset (t->unverified_ax,
1960 0,
1961 sizeof(struct CadetTunnelAxolotl));
1962 }
1963 else
1964 {
1966 "Creating fresh unverified KX for %s\n",
1967 GCT_2s (t));
1969 "# Fresh KX setup",
1970 1,
1971 GNUNET_NO);
1972 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1973 }
1974 /* Set as the 'current' RK/DHRr the one we are currently using,
1975 so that the duplicate-detection logic of
1976 #update_ax_by_kx can work. */
1977 t->unverified_ax->RK = t->ax.RK;
1978 t->unverified_ax->DHRr = t->ax.DHRr;
1979 t->unverified_ax->DHRs = t->ax.DHRs;
1980 t->unverified_ax->kx_0 = t->ax.kx_0;
1981 t->unverified_attempts = 0;
1982
1983 t->as.ax = *(t->unverified_ax);
1984 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1985 sizeof (t->as.peer_id));
1986 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1987 sizeof (t->as.ephemeral_key));
1988 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1989 sizeof (t->as.ratchet_key));
1990 memset (&t->as.auth, 0, sizeof (t->as.auth));
1991 t->as.flags = 0;
1992 t->as.cb_cls = t;
1993 t->as.cb = &cont_GCT_handle_kx;
1994
1995 if (t->as.ecdh_op)
1996 {
1998 "Cancelling previous ECDH operation\n");
1999
2000 GNUNET_PILS_cancel (t->as.ecdh_op);
2001 }
2002
2003 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
2004 &update_ax_by_kx, &t->as);
2005}
2006
2007
2014static void
2015cont_GCT_handle_kx_auth (void *cls,
2017{
2018 struct CadetTunnel *t = cls;
2019 struct CadetTunnelAxolotl *ax_tmp;
2020 struct GNUNET_HashCode kx_auth;
2021
2022 ax_tmp = &t->as.ax;
2023
2025 "Continue handling KX_AUTH message from %s\n",
2026 GCT_2s (t));
2027
2028 if (GNUNET_OK != ret)
2029 {
2030 if (GNUNET_NO == ret)
2032 "# redundant KX_AUTH received",
2033 1,
2034 GNUNET_NO);
2035 else
2036 GNUNET_break (0); /* connect to self!? */
2037 return;
2038 }
2039 GNUNET_CRYPTO_hash (&ax_tmp->RK,
2040 sizeof(ax_tmp->RK),
2041 &kx_auth);
2042 if (0 != GNUNET_memcmp (&kx_auth,
2043 &t->as.auth))
2044 {
2045 /* This KX_AUTH is not using the latest KX/KX_AUTH data
2046 we transmitted to the sender, refuse it, try KX again. */
2048 "# KX_AUTH not using our last KX received (auth failure)",
2049 1,
2050 GNUNET_NO);
2052 "KX AUTH mismatch!\n");
2053#if DEBUG_KX
2054 {
2055 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2056
2058 &ephemeral_key);
2059 if (0 != GNUNET_memcmp (&ephemeral_key,
2060 &msg->r_ephemeral_key_XXX))
2061 {
2063 "My ephemeral is %s!\n",
2064 GNUNET_e2s (&ephemeral_key));
2066 "Response is for ephemeral %s!\n",
2067 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2068 }
2069 }
2070#endif
2071 if (NULL == t->kx_task)
2072 t->kx_task
2073 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2074 &retry_kx,
2075 t);
2076 return;
2077 }
2078 /* Yep, we're good. */
2079 t->ax = *ax_tmp;
2080 if (NULL != t->unverified_ax)
2081 {
2082 /* We got some "stale" KX before, drop that. */
2083 cleanup_ax (t->unverified_ax);
2084 GNUNET_free (t->unverified_ax);
2085 t->unverified_ax = NULL;
2086 }
2087
2088 /* move ahead in our state machine */
2089 switch (t->estate)
2090 {
2093 /* Checked above, this is impossible. */
2094 GNUNET_assert (0);
2095 break;
2096
2097 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2098 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2099 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2102 break;
2103
2105 /* Did not expect another KX_AUTH, but so what, still acceptable.
2106 Nothing to do here. */
2107 break;
2108 }
2109 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2110 {
2111 send_kx_auth (t,
2112 NULL,
2113 &t->ax,
2114 GNUNET_NO);
2115 }
2116}
2117
2118
2125void
2128{
2129 struct CadetTunnel *t = ct->t;
2130
2132 "# KX_AUTH received",
2133 1,
2134 GNUNET_NO);
2135 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2136 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2137 {
2138 /* Confusing, we got a KX_AUTH before we even send our own
2139 KX. This should not happen. We'll send our own KX ASAP anyway,
2140 so let's ignore this here. */
2141 GNUNET_break_op (0);
2142 return;
2143 }
2145 "Handling KX_AUTH message from %s with ephemeral %s\n",
2146 GCT_2s (t),
2147 GNUNET_e2s (&msg->kx.ephemeral_key));
2148 if ((t->as.ecdh_op) &&
2149 (0 ==
2150 memcmp (&t->as.ratchet_key,
2151 &msg->kx.ratchet_key,
2152 sizeof(msg->kx.ratchet_key))) &&
2153 (0 ==
2154 memcmp (&t->as.ephemeral_key,
2155 &msg->kx.ephemeral_key,
2156 sizeof(msg->kx.ephemeral_key))))
2157 {
2159 "Waiting for previous ECDH operation\n");
2160 return;
2161 }
2162 /* We do everything in a copy until we've checked the authentication
2163 so we don't clobber anything we care about by accident. */
2164 t->as.ax = t->ax;
2165 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2166 sizeof (t->as.peer_id));
2167 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2168 sizeof (t->as.ephemeral_key));
2169 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2170 sizeof (t->as.ratchet_key));
2171 t->as.auth = msg->auth;
2172 t->as.flags = msg->kx.flags;
2173 t->as.cb_cls = t;
2174 t->as.cb = &cont_GCT_handle_kx_auth;
2175
2176 if (t->as.ecdh_op)
2177 {
2179 "Cancelling previous ECDH operation\n");
2180
2181 GNUNET_PILS_cancel (t->as.ecdh_op);
2182 }
2183
2184 /* Update 'ax' by the new key material */
2185 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2186 &update_ax_by_kx, &t->as);
2187}
2188
2189
2190/* ************************************** end core crypto ***************************** */
2191
2192
2201{
2202#define HIGH_BIT 0x8000000
2203 const struct GNUNET_PeerIdentity *my_identity;
2205 uint32_t ctn;
2206 int cmp;
2207 uint32_t highbit;
2208
2211
2214 if (0 < cmp)
2215 highbit = HIGH_BIT;
2216 else if (0 > cmp)
2217 highbit = 0;
2218 else
2219 GNUNET_assert (0); // loopback must never go here!
2220 ctn = ntohl (t->next_ctn.cn);
2221 while (NULL !=
2223 ctn | highbit))
2224 {
2225 ctn = ((ctn + 1) & (~HIGH_BIT));
2226 }
2227 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2228 ret.cn = htonl (ctn | highbit);
2229 return ret;
2230}
2231
2232
2244 struct CadetChannel *ch)
2245{
2247
2248 ctn = get_next_free_ctn (t);
2249 if (NULL != t->destroy_task)
2250 {
2251 GNUNET_SCHEDULER_cancel (t->destroy_task);
2252 t->destroy_task = NULL;
2253 }
2256 ntohl (ctn.cn),
2257 ch,
2260 "Adding %s to %s with state %d\n",
2261 GCCH_2s (ch),
2262 GCT_2s (t),
2263 t->estate);
2264 switch (t->estate)
2265 {
2267 /* waiting for connection to start KX */
2268 break;
2269
2273 /* we're currently waiting for KX to complete */
2274 break;
2275
2277 /* waiting for OTHER peer to send us data,
2278 we might need to prompt more aggressively! */
2279 if (NULL == t->kx_task)
2280 t->kx_task
2281 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2282 &retry_kx,
2283 t);
2284 break;
2285
2287 /* We are ready. Tell the new channel that we are up. */
2289 break;
2290 }
2291 return ctn;
2292}
2293
2294
2301void
2303{
2304 struct CadetTunnel *t = ct->t;
2305
2306 if (GNUNET_YES == ct->is_ready)
2307 {
2308 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2309 t->connection_ready_tail,
2310 ct);
2311 t->num_ready_connections--;
2312 }
2313 else
2314 {
2315 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2316 t->connection_busy_tail,
2317 ct);
2318 t->num_busy_connections--;
2319 }
2320 GNUNET_free (ct);
2321}
2322
2323
2330static void
2331destroy_t_connection (void *cls,
2332 struct CadetTConnection *ct)
2333{
2334 struct CadetTunnel *t = cls;
2335 struct CadetConnection *cc = ct->cc;
2336
2337 GNUNET_assert (ct->t == t);
2340}
2341
2342
2348static void
2349destroy_tunnel (void *cls)
2350{
2351 struct CadetTunnel *t = cls;
2352 struct CadetTunnelQueueEntry *tq;
2353
2354 t->destroy_task = NULL;
2356 "Destroying idle %s\n",
2357 GCT_2s (t));
2361 t);
2362 GNUNET_assert (NULL == t->connection_ready_head);
2363 GNUNET_assert (NULL == t->connection_busy_head);
2364 while (NULL != (tq = t->tq_head))
2365 {
2366 if (NULL != tq->cont)
2367 tq->cont (tq->cont_cls,
2368 NULL);
2369 GCT_send_cancel (tq);
2370 }
2371 GCP_drop_tunnel (t->destination,
2372 t);
2374 if (NULL != t->maintain_connections_task)
2375 {
2376 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2377 t->maintain_connections_task = NULL;
2378 }
2379 if (NULL != t->send_task)
2380 {
2381 GNUNET_SCHEDULER_cancel (t->send_task);
2382 t->send_task = NULL;
2383 }
2384 if (NULL != t->kx_task)
2385 {
2386 GNUNET_SCHEDULER_cancel (t->kx_task);
2387 t->kx_task = NULL;
2388 }
2389 if (NULL != t->as.ecdh_op)
2390 {
2391 GNUNET_PILS_cancel (t->as.ecdh_op);
2392 t->as.ecdh_op = NULL;
2393 }
2394 GNUNET_MST_destroy (t->mst);
2395 GNUNET_MQ_destroy (t->mq);
2396 if (NULL != t->unverified_ax)
2397 {
2398 cleanup_ax (t->unverified_ax);
2399 GNUNET_free (t->unverified_ax);
2400 }
2401 cleanup_ax (&t->ax);
2402 GNUNET_assert (NULL == t->destroy_task);
2403 GNUNET_free (t);
2404}
2405
2406
2414void
2416 struct CadetChannel *ch,
2418{
2420 "Removing %s from %s\n",
2421 GCCH_2s (ch),
2422 GCT_2s (t));
2425 ntohl (ctn.cn),
2426 ch));
2427 if ((0 ==
2428 GCT_count_channels (t)) &&
2429 (NULL == t->destroy_task))
2430 {
2431 t->destroy_task
2434 t);
2435 }
2436}
2437
2438
2447static int
2449 uint32_t key,
2450 void *value)
2451{
2452 struct CadetChannel *ch = value;
2453
2455 NULL);
2456 return GNUNET_OK;
2457}
2458
2459
2465void
2467{
2471 t);
2472 GNUNET_assert (0 ==
2474 if (NULL != t->destroy_task)
2475 {
2476 GNUNET_SCHEDULER_cancel (t->destroy_task);
2477 t->destroy_task = NULL;
2478 }
2479 destroy_tunnel (t);
2480}
2481
2482
2490static void
2492 struct CadetTConnection *ct)
2493{
2494 struct CadetTunnelQueueEntry *tq;
2495
2497 tq = t->tq_head;
2498 if (NULL == tq)
2499 {
2500 /* no messages pending right now */
2502 "Not sending payload of %s on ready %s (nothing pending)\n",
2503 GCT_2s (t),
2504 GCC_2s (ct->cc));
2505 return;
2506 }
2507 /* ready to send message 'tq' on tunnel 'ct' */
2508 GNUNET_assert (t == tq->t);
2510 t->tq_tail,
2511 tq);
2512 if (NULL != tq->cid)
2513 *tq->cid = *GCC_get_id (ct->cc);
2516 "Sending payload of %s on %s\n",
2517 GCT_2s (t),
2518 GCC_2s (ct->cc));
2519 GCC_transmit (ct->cc,
2520 tq->env);
2521 if (NULL != tq->cont)
2522 tq->cont (tq->cont_cls,
2523 GCC_get_id (ct->cc));
2524 GNUNET_free (tq);
2525}
2526
2527
2536static void
2537connection_ready_cb (void *cls,
2538 int is_ready)
2539{
2540 struct CadetTConnection *ct = cls;
2541 struct CadetTunnel *t = ct->t;
2542
2543 if (GNUNET_NO == is_ready)
2544 {
2546 "%s no longer ready for %s\n",
2547 GCC_2s (ct->cc),
2548 GCT_2s (t));
2550 return;
2551 }
2553 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2554 t->connection_busy_tail,
2555 ct);
2556 GNUNET_assert (0 < t->num_busy_connections);
2557 t->num_busy_connections--;
2558 ct->is_ready = GNUNET_YES;
2559 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2560 t->connection_ready_tail,
2561 ct);
2562 t->num_ready_connections++;
2563
2565 "%s now ready for %s in state %s\n",
2566 GCC_2s (ct->cc),
2567 GCT_2s (t),
2568 estate2s (t->estate));
2569 switch (t->estate)
2570 {
2573 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2574 GCT_2s (t),
2575 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2576 t->next_kx_attempt).rel_value_us);
2577 /* Do not begin KX if WE have no channels waiting! */
2579 t->next_kx_attempt).rel_value_us)
2580 return; /* wait for timeout before retrying */
2581 /* We are uninitialized, just transmit immediately,
2582 without undue delay. */
2583
2585 "Why for %s \n",
2586 GCT_2s (t));
2587
2588 if (NULL != t->kx_task)
2589 {
2590 GNUNET_SCHEDULER_cancel (t->kx_task);
2591 t->kx_task = NULL;
2592 }
2593 send_kx (t,
2594 ct,
2595 &t->ax);
2596 if ((0 ==
2597 GCT_count_channels (t)) &&
2598 (NULL == t->destroy_task))
2599 {
2600 t->destroy_task
2603 t);
2604 }
2605 break;
2606
2611 /* we're currently waiting for KX to complete, schedule job */
2612 if (NULL == t->kx_task)
2613 t->kx_task
2614 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2615 &retry_kx,
2616 t);
2617 break;
2618
2620 if (GNUNET_YES == t->kx_auth_requested)
2621 {
2623 t->next_kx_attempt).rel_value_us)
2624 return; /* wait for timeout */
2625 if (NULL != t->kx_task)
2626 {
2627 GNUNET_SCHEDULER_cancel (t->kx_task);
2628 t->kx_task = NULL;
2629 }
2630 send_kx_auth (t,
2631 ct,
2632 &t->ax,
2633 GNUNET_NO);
2634 return;
2635 }
2637 ct);
2638 break;
2639 }
2640}
2641
2642
2651static void
2652trigger_transmissions (void *cls)
2653{
2654 struct CadetTunnel *t = cls;
2655 struct CadetTConnection *ct;
2656
2657 t->send_task = NULL;
2658 if (NULL == t->tq_head)
2659 return; /* no messages pending right now */
2660 ct = get_ready_connection (t);
2661 if (NULL == ct)
2662 return; /* no connections ready */
2664 ct);
2665}
2666
2667
2672struct EvaluationSummary
2673{
2677 unsigned int min_length;
2678
2682 unsigned int max_length;
2683
2688
2693
2697 struct CadetPeerPath *path;
2698
2703 struct CadetTConnection *worst;
2704
2708 double worst_score;
2709
2713 int duplicate;
2714};
2715
2716
2724static void
2725evaluate_connection (void *cls,
2726 struct CadetTConnection *ct)
2727{
2728 struct EvaluationSummary *es = cls;
2729 struct CadetConnection *cc = ct->cc;
2730 unsigned int ct_length;
2731 struct CadetPeerPath *ps;
2732 const struct CadetConnectionMetrics *metrics;
2733 GNUNET_CONTAINER_HeapCostType ct_desirability;
2734 struct GNUNET_TIME_Relative uptime;
2735 struct GNUNET_TIME_Relative last_use;
2736 double score;
2737 double success_rate;
2738
2739 ps = GCC_get_path (cc,
2740 &ct_length);
2742 "Evaluating path %s of existing %s\n",
2743 GCPP_2s (ps),
2744 GCC_2s (cc));
2745 if (ps == es->path)
2746 {
2748 "Ignoring duplicate path %s.\n",
2749 GCPP_2s (es->path));
2750 es->duplicate = GNUNET_YES;
2751 return;
2752 }
2753 if (NULL != es->path)
2754 {
2755 int duplicate = GNUNET_YES;
2756
2757 for (unsigned int i = 0; i < ct_length; i++)
2758 {
2761 i) !=
2763 i))
2764 {
2765 duplicate = GNUNET_NO;
2766 break;
2767 }
2768 }
2769 if (GNUNET_YES == duplicate)
2770 {
2772 "Ignoring overlapping path %s.\n",
2773 GCPP_2s (es->path));
2774 es->duplicate = GNUNET_YES;
2775 return;
2776 }
2777 else
2778 {
2780 "Known path %s differs from proposed path\n",
2781 GCPP_2s (ps));
2782 }
2783 }
2784
2785 ct_desirability = GCPP_get_desirability (ps);
2786 metrics = GCC_get_metrics (cc);
2787 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2788 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2789 /* We add 1.0 here to avoid division by zero. */
2790 success_rate = (metrics->num_acked_transmissions + 1.0)
2791 / (metrics->num_successes + 1.0);
2792 score
2793 = ct_desirability
2794 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2795 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2796 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2797 score *= success_rate; /* weigh overall by success rate */
2798
2799 if ((NULL == es->worst) ||
2800 (score < es->worst_score))
2801 {
2802 es->worst = ct;
2803 es->worst_score = score;
2804 }
2805 es->min_length = GNUNET_MIN (es->min_length,
2806 ct_length);
2807 es->max_length = GNUNET_MAX (es->max_length,
2808 ct_length);
2809 es->min_desire = GNUNET_MIN (es->min_desire,
2810 ct_desirability);
2811 es->max_desire = GNUNET_MAX (es->max_desire,
2812 ct_desirability);
2813}
2814
2815
2825static int
2826consider_path_cb (void *cls,
2827 struct CadetPeerPath *path,
2828 unsigned int off)
2829{
2830 struct CadetTunnel *t = cls;
2831 struct EvaluationSummary es;
2832 struct CadetTConnection *ct;
2833
2834 GNUNET_assert (off < GCPP_get_length (path));
2836 off) == t->destination);
2837 es.min_length = UINT_MAX;
2838 es.max_length = 0;
2839 es.max_desire = 0;
2840 es.min_desire = UINT64_MAX;
2841 es.path = path;
2842 es.duplicate = GNUNET_NO;
2843 es.worst = NULL;
2844
2845 /* Compute evaluation summary over existing connections. */
2847 "Evaluating proposed path %s for target %s\n",
2848 GCPP_2s (path),
2849 GCT_2s (t));
2850 /* FIXME: suspect this does not ACTUALLY iterate
2851 over all existing paths, otherwise dup detection
2852 should work!!! */
2855 &es);
2856 if (GNUNET_YES == es.duplicate)
2857 return GNUNET_YES;
2858
2859 /* FIXME: not sure we should really just count
2860 'num_connections' here, as they may all have
2861 consistently failed to connect. */
2862
2863 /* We iterate by increasing path length; if we have enough paths and
2864 this one is more than twice as long than what we are currently
2865 using, then ignore all of these super-long ones! */
2867 (es.min_length * 2 < off) &&
2868 (es.max_length < off))
2869 {
2871 "Ignoring paths of length %u, they are way too long.\n",
2872 es.min_length * 2);
2873 return GNUNET_NO;
2874 }
2875 /* If we have enough paths and this one looks no better, ignore it. */
2877 (es.min_length < GCPP_get_length (path)) &&
2878 (es.min_desire > GCPP_get_desirability (path)) &&
2879 (es.max_length < off))
2880 {
2882 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2883 GCPP_get_length (path),
2884 (unsigned long long) GCPP_get_desirability (path),
2885 GCP_2s (t->destination));
2886 return GNUNET_YES;
2887 }
2888
2889 /* Path is interesting (better by some metric, or we don't have
2890 enough paths yet). */
2891 ct = GNUNET_new (struct CadetTConnection);
2893 ct->t = t;
2894 ct->cc = GCC_create (t->destination,
2895 path,
2896 off,
2897 ct,
2899 ct);
2900
2901 /* FIXME: schedule job to kill connection (and path?) if it takes
2902 too long to get ready! (And track performance data on how long
2903 other connections took with the tunnel!)
2904 => Note: to be done within 'connection'-logic! */
2905 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2906 t->connection_busy_tail,
2907 ct);
2908 t->num_busy_connections++;
2910 "Found interesting path %s for %s, created %s\n",
2911 GCPP_2s (path),
2912 GCT_2s (t),
2913 GCC_2s (ct->cc));
2914 return GNUNET_YES;
2915}
2916
2917
2931static void
2932maintain_connections_cb (void *cls)
2933{
2934 struct CadetTunnel *t = cls;
2935 struct GNUNET_TIME_Relative delay;
2936 struct EvaluationSummary es;
2937
2938 t->maintain_connections_task = NULL;
2940 "Performing connection maintenance for %s.\n",
2941 GCT_2s (t));
2942
2943 es.min_length = UINT_MAX;
2944 es.max_length = 0;
2945 es.max_desire = 0;
2946 es.min_desire = UINT64_MAX;
2947 es.path = NULL;
2948 es.worst = NULL;
2949 es.duplicate = GNUNET_NO;
2952 &es);
2953 if ((NULL != es.worst) &&
2955 {
2956 /* Clear out worst-performing connection 'es.worst'. */
2958 es.worst);
2959 }
2960
2961 /* Consider additional paths */
2962 (void) GCP_iterate_paths (t->destination,
2964 t);
2965
2966 /* FIXME: calculate when to try again based on how well we are doing;
2967 in particular, if we have to few connections, we might be able
2968 to do without this (as PATHS should tell us whenever a new path
2969 is available instantly; however, need to make sure this job is
2970 restarted after that happens).
2971 Furthermore, if the paths we do know are in a reasonably narrow
2972 quality band and are plentyful, we might also consider us stabilized
2973 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2974 t->maintain_connections_task
2977 t);
2978}
2979
2980
2981void
2983 struct CadetPeerPath *p,
2984 unsigned int off)
2985{
2987 "Considering %s for %s (offset %u)\n",
2988 GCPP_2s (p),
2989 GCT_2s (t),
2990 off);
2991 (void) consider_path_cb (t,
2992 p,
2993 off);
2994}
2995
2996
3003static void
3005 const struct GNUNET_MessageHeader *msg)
3006{
3007 struct CadetTunnel *t = cls;
3008
3010 "Received KEEPALIVE on %s\n",
3011 GCT_2s (t));
3013 "# keepalives received",
3014 1,
3015 GNUNET_NO);
3016}
3017
3018
3026static int
3027check_plaintext_data (void *cls,
3029{
3030 return GNUNET_OK;
3031}
3032
3033
3041static void
3042handle_plaintext_data (void *cls,
3044{
3045 struct CadetTunnel *t = cls;
3046 struct CadetChannel *ch;
3047
3048 ch = lookup_channel (t,
3049 msg->ctn);
3050 if (NULL == ch)
3051 {
3052 /* We don't know about such a channel, might have been destroyed on our
3053 end in the meantime, or never existed. Send back a DESTROY. */
3055 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3056 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3057 ntohl (msg->ctn.cn));
3059 msg->ctn);
3060 return;
3061 }
3063 GCC_get_id (t->current_ct->cc),
3064 msg);
3065}
3066
3067
3076static void
3077handle_plaintext_data_ack (void *cls,
3078 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
3079{
3080 struct CadetTunnel *t = cls;
3081 struct CadetChannel *ch;
3082
3083 ch = lookup_channel (t,
3084 ack->ctn);
3085 if (NULL == ch)
3086 {
3087 /* We don't know about such a channel, might have been destroyed on our
3088 end in the meantime, or never existed. Send back a DESTROY. */
3090 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3091 ntohl (ack->ctn.cn));
3093 ack->ctn);
3094 return;
3095 }
3097 GCC_get_id (t->current_ct->cc),
3098 ack);
3099}
3100
3101
3109static void
3111 const struct
3113{
3114 struct CadetTunnel *t = cls;
3115 struct CadetChannel *ch;
3116
3118 ntohl (copen->ctn.cn));
3119 if (NULL != ch)
3120 {
3122 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3123 GNUNET_h2s (&copen->h_port),
3124 GCT_2s (t),
3125 GCCH_2s (ch));
3127 GCC_get_id (t->current_ct->cc));
3128 return;
3129 }
3131 "Received CHANNEL_OPEN on h_port %s from %s\n",
3132 GNUNET_h2s (&copen->h_port),
3133 GCT_2s (t));
3135 copen->ctn,
3136 &copen->h_port,
3137 ntohl (copen->opt));
3138 if (NULL != t->destroy_task)
3139 {
3140 GNUNET_SCHEDULER_cancel (t->destroy_task);
3141 t->destroy_task = NULL;
3142 }
3145 ntohl (copen->ctn.cn),
3146 ch,
3148}
3149
3150
3157void
3160{
3162
3164 "Sending DESTROY message for channel ID %u\n",
3165 ntohl (ctn.cn));
3166 msg.header.size = htons (sizeof(msg));
3168 msg.reserved = htonl (0);
3169 msg.ctn = ctn;
3170 GCT_send (t,
3171 &msg.header,
3172 NULL,
3173 NULL,
3174 &ctn);
3175}
3176
3177
3186static void
3188 const struct
3190{
3191 struct CadetTunnel *t = cls;
3192 struct CadetChannel *ch;
3193
3194 ch = lookup_channel (t,
3195 cm->ctn);
3196 if (NULL == ch)
3197 {
3198 /* We don't know about such a channel, might have been destroyed on our
3199 end in the meantime, or never existed. Send back a DESTROY. */
3201 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3202 ntohl (cm->ctn.cn));
3204 cm->ctn);
3205 return;
3206 }
3208 "Received channel OPEN_ACK on channel %s from %s\n",
3209 GCCH_2s (ch),
3210 GCT_2s (t));
3212 GCC_get_id (t->current_ct->cc),
3213 &cm->port);
3214}
3215
3216
3224static void
3226 const struct
3228{
3229 struct CadetTunnel *t = cls;
3230 struct CadetChannel *ch;
3231
3232 ch = lookup_channel (t,
3233 cm->ctn);
3234 if (NULL == ch)
3235 {
3236 /* We don't know about such a channel, might have been destroyed on our
3237 end in the meantime, or never existed. */
3239 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3240 ntohl (cm->ctn.cn));
3241 return;
3242 }
3244 "Received channel DESTROY on %s from %s\n",
3245 GCCH_2s (ch),
3246 GCT_2s (t));
3248 GCC_get_id (t->current_ct->cc));
3249}
3250
3251
3262static int
3263handle_decrypted (void *cls,
3264 const struct GNUNET_MessageHeader *msg)
3265{
3266 struct CadetTunnel *t = cls;
3267
3268 GNUNET_assert (NULL != t->current_ct);
3270 msg);
3271 return GNUNET_OK;
3272}
3273
3274
3282static void
3283decrypted_error_cb (void *cls,
3284 enum GNUNET_MQ_Error error)
3285{
3286 GNUNET_break_op (0);
3287}
3288
3289
3297struct CadetTunnel *
3299{
3300 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3302 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3304 struct GNUNET_MessageHeader,
3305 t),
3306 GNUNET_MQ_hd_var_size (plaintext_data,
3309 t),
3310 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3313 t),
3314 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3317 t),
3318 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3321 t),
3322 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3325 t),
3327 };
3328
3329 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3330 new_ephemeral (&t->ax);
3332 t->destination = destination;
3334 t->maintain_connections_task
3336 t);
3337 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3338 NULL,
3339 NULL,
3340 NULL,
3341 handlers,
3343 t);
3345 t);
3346 return t;
3347}
3348
3349
3350int
3352 const struct
3354 struct CadetPeerPath *path)
3355{
3356 struct CadetTConnection *ct;
3357
3358 ct = GNUNET_new (struct CadetTConnection);
3360 ct->t = t;
3361 ct->cc = GCC_create_inbound (t->destination,
3362 path,
3363 ct,
3364 cid,
3366 ct);
3367 if (NULL == ct->cc)
3368 {
3370 "%s refused inbound %s (duplicate)\n",
3371 GCT_2s (t),
3372 GCC_2s (ct->cc));
3373 GNUNET_free (ct);
3374 return GNUNET_SYSERR;
3375 }
3376 /* FIXME: schedule job to kill connection (and path?) if it takes
3377 too long to get ready! (And track performance data on how long
3378 other connections took with the tunnel!)
3379 => Note: to be done within 'connection'-logic! */
3380 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3381 t->connection_busy_tail,
3382 ct);
3383 t->num_busy_connections++;
3385 "%s has new %s\n",
3386 GCT_2s (t),
3387 GCC_2s (ct->cc));
3388 return GNUNET_OK;
3389}
3390
3391
3398void
3401{
3402 struct CadetTunnel *t = ct->t;
3403 uint16_t size = ntohs (msg->header.size);
3404 char cbuf[size] GNUNET_ALIGN;
3405 ssize_t decrypted_size;
3406
3408 "%s received %u bytes of encrypted data in state %d\n",
3409 GCT_2s (t),
3410 (unsigned int) size,
3411 t->estate);
3412
3413 switch (t->estate)
3414 {
3417 /* We did not even SEND our KX, how can the other peer
3418 send us encrypted data? Must have been that we went
3419 down and the other peer still things we are up.
3420 Let's send it KX back. */
3422 "# received encrypted without any KX",
3423 1,
3424 GNUNET_NO);
3425 if (NULL != t->kx_task)
3426 {
3427 GNUNET_SCHEDULER_cancel (t->kx_task);
3428 t->kx_task = NULL;
3429 }
3430 send_kx (t,
3431 ct,
3432 &t->ax);
3433 return;
3434
3436 /* We send KX, and other peer send KX to us at the same time.
3437 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3439 "# received encrypted without KX_AUTH",
3440 1,
3441 GNUNET_NO);
3442 if (NULL != t->kx_task)
3443 {
3444 GNUNET_SCHEDULER_cancel (t->kx_task);
3445 t->kx_task = NULL;
3446 }
3447 send_kx_auth (t,
3448 ct,
3449 &t->ax,
3450 GNUNET_YES);
3451 return;
3452
3454 /* We did not get the KX of the other peer, but that
3455 might have been lost. Send our KX again immediately. */
3457 "# received encrypted without KX",
3458 1,
3459 GNUNET_NO);
3460 if (NULL != t->kx_task)
3461 {
3462 GNUNET_SCHEDULER_cancel (t->kx_task);
3463 t->kx_task = NULL;
3464 }
3465 send_kx (t,
3466 ct,
3467 &t->ax);
3468 return;
3469
3471 /* Great, first payload, we might graduate to OK! */
3473 /* We are up and running, all good. */
3474 break;
3475 }
3476
3477 decrypted_size = -1;
3478 if (CADET_TUNNEL_KEY_OK == t->estate)
3479 {
3480 /* We have well-established key material available,
3481 try that. (This is the common case.) */
3482 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3483 cbuf,
3484 msg,
3485 size);
3486 }
3487
3488 if ((-1 == decrypted_size) &&
3489 (NULL != t->unverified_ax))
3490 {
3491 /* We have un-authenticated KX material available. We should try
3492 this as a back-up option, in case the sender crashed and
3493 switched keys. */
3494 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3495 cbuf,
3496 msg,
3497 size);
3498 if (-1 != decrypted_size)
3499 {
3500 /* It worked! Treat this as authentication of the AX data! */
3501 cleanup_ax (&t->ax);
3502 t->ax = *t->unverified_ax;
3503 GNUNET_free (t->unverified_ax);
3504 t->unverified_ax = NULL;
3505 }
3506 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3507 {
3508 /* First time it worked, move tunnel into production! */
3511 if (NULL != t->send_task)
3512 GNUNET_SCHEDULER_cancel (t->send_task);
3514 t);
3515 }
3516 }
3517 if (NULL != t->unverified_ax)
3518 {
3519 /* We had unverified KX material that was useless; so increment
3520 counter and eventually move to ignore it. Note that we even do
3521 this increment if we successfully decrypted with the old KX
3522 material and thus didn't even both with the new one. This is
3523 the ideal case, as a malicious injection of bogus KX data
3524 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3526 "Failed to decrypt message with unverified KX data %u times\n",
3527 t->unverified_attempts);
3528 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3529 {
3530 cleanup_ax (t->unverified_ax);
3531 GNUNET_free (t->unverified_ax);
3532 t->unverified_ax = NULL;
3533 }
3534 }
3535
3536 if (-1 == decrypted_size)
3537 {
3538 /* Decryption failed for good, complain. */
3540 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3541 GCT_2s (t));
3543 "# unable to decrypt",
3544 1,
3545 GNUNET_NO);
3546 if (NULL != t->kx_task)
3547 {
3548 GNUNET_SCHEDULER_cancel (t->kx_task);
3549 t->kx_task = NULL;
3550 }
3551 send_kx (t,
3552 ct,
3553 &t->ax);
3554 return;
3555 }
3557 "# decrypted bytes",
3558 decrypted_size,
3559 GNUNET_NO);
3560
3561 /* The MST will ultimately call #handle_decrypted() on each message. */
3562 t->current_ct = ct;
3565 cbuf,
3566 decrypted_size,
3567 GNUNET_YES,
3568 GNUNET_NO));
3569 t->current_ct = NULL;
3570}
3571
3572
3573struct CadetTunnelQueueEntry *
3574GCT_send (struct CadetTunnel *t,
3575 const struct GNUNET_MessageHeader *message,
3577 void *cont_cls,
3579{
3580 struct CadetTunnelQueueEntry *tq;
3581 uint16_t payload_size;
3582 struct GNUNET_MQ_Envelope *env;
3584 struct CadetChannel *ch;
3585
3586 if (NULL != ctn)
3587 {
3588 ch = lookup_channel (t,
3589 *ctn);
3590 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3591 {
3592 GNUNET_break (0);
3593 return NULL;
3594 }
3595 }
3596
3597 if (CADET_TUNNEL_KEY_OK != t->estate)
3598 {
3599 GNUNET_break (0);
3600 return NULL;
3601 }
3602 payload_size = ntohs (message->size);
3604 "Encrypting %u bytes for %s\n",
3605 (unsigned int) payload_size,
3606 GCT_2s (t));
3607 env = GNUNET_MQ_msg_extra (ax_msg,
3608 payload_size,
3610 t_ax_encrypt (&t->ax,
3611 &ax_msg[1],
3612 message,
3613 payload_size);
3615 "# encrypted bytes",
3616 payload_size,
3617 GNUNET_NO);
3618 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3619 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3620 /* FIXME: we should do this once, not once per message;
3621 this is a point multiplication, and DHRs does not
3622 change all the time. */
3624 &ax_msg->ax_header.DHRs);
3625 t_h_encrypt (&t->ax,
3626 ax_msg);
3627 t_hmac (&ax_msg->ax_header,
3628 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3629 0,
3630 &t->ax.HKs,
3631 &ax_msg->hmac);
3632
3633 tq = GNUNET_malloc (sizeof(*tq));
3634 tq->t = t;
3635 tq->env = env;
3636 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3637 tq->cont = cont;
3638 tq->cont_cls = cont_cls;
3640 t->tq_tail,
3641 tq);
3642 if (NULL != t->send_task)
3643 GNUNET_SCHEDULER_cancel (t->send_task);
3644 t->send_task
3646 t);
3647 return tq;
3648}
3649
3650
3651void
3653{
3654 struct CadetTunnel *t = tq->t;
3655
3657 t->tq_tail,
3658 tq);
3659 GNUNET_MQ_discard (tq->env);
3660 GNUNET_free (tq);
3661}
3662
3663
3671void
3674 void *iter_cls)
3675{
3676 struct CadetTConnection *n;
3677
3678 for (struct CadetTConnection *ct = t->connection_ready_head;
3679 NULL != ct;
3680 ct = n)
3681 {
3682 n = ct->next;
3683 iter (iter_cls,
3684 ct);
3685 }
3686 for (struct CadetTConnection *ct = t->connection_busy_head;
3687 NULL != ct;
3688 ct = n)
3689 {
3690 n = ct->next;
3691 iter (iter_cls,
3692 ct);
3693 }
3694}
3695
3696
3700struct ChanIterCls
3701{
3706
3710 void *iter_cls;
3711};
3712
3713
3722static int
3723iterate_channels_cb (void *cls,
3724 uint32_t key,
3725 void *value)
3726{
3727 struct ChanIterCls *ctx = cls;
3728 struct CadetChannel *ch = value;
3729
3730 ctx->iter (ctx->iter_cls,
3731 ch);
3732 return GNUNET_OK;
3733}
3734
3735
3743void
3746 void *iter_cls)
3747{
3748 struct ChanIterCls ctx;
3749
3750 ctx.iter = iter;
3751 ctx.iter_cls = iter_cls;
3754 &ctx);
3755}
3756
3757
3766static int
3767debug_channel (void *cls,
3768 uint32_t key,
3769 void *value)
3770{
3771 const enum GNUNET_ErrorType *level = cls;
3772 struct CadetChannel *ch = value;
3773
3774 GCCH_debug (ch, *level);
3775 return GNUNET_OK;
3776}
3777
3778
3779#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3780 __VA_ARGS__)
3781
3782
3789void
3790GCT_debug (const struct CadetTunnel *t,
3791 enum GNUNET_ErrorType level)
3792{
3793#if ! defined(GNUNET_CULL_LOGGING)
3794 struct CadetTConnection *iter_c;
3795 int do_log;
3796
3798 "cadet-tun",
3799 __FILE__, __FUNCTION__, __LINE__);
3800 if (0 == do_log)
3801 return;
3802
3803 LOG2 (level,
3804 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3805 GCT_2s (t),
3806 estate2s (t->estate),
3807 t->tq_len,
3809 LOG2 (level,
3810 "TTT channels:\n");
3813 &level);
3814 LOG2 (level,
3815 "TTT connections:\n");
3816 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3817 GCC_debug (iter_c->cc,
3818 level);
3819 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3820 GCC_debug (iter_c->cc,
3821 level);
3822
3823 LOG2 (level,
3824 "TTT TUNNEL END\n");
3825#endif
3826}
3827
3828
3829/* 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 t_h_decrypt(struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
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...
#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.
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 t_hmac(const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
Calculate HMAC.
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.
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
Delete a key from the list of skipped keys.
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 void t_ax_hmac_hash(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
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 int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
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 t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Encrypt header with the axolotl header key.
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 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.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
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:732
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
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:823
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
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
#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:41
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)
#define GNUNET_CRYPTO_kdf_arg_string(d)
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_CRYPTO_kdf_arg_auto(d)
#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 .
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.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_CRYPTO_SymmetricSessionKey HKs
32-byte header key (currently used for sending).
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_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 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).
struct GNUNET_CRYPTO_SymmetricSessionKey RK
32-byte root key which gets updated by DH ratchet.
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
struct GNUNET_CRYPTO_SymmetricSessionKey HKr
32-byte header key (currently used for receiving)
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_SymmetricSessionKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_SymmetricSessionKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_SymmetricSessionKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
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_SymmetricSessionKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
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 GNUNET_CRYPTO_SymmetricSessionKey d_key
Decryption ("their") key.
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_CRYPTO_SymmetricSessionKey e_key
Encryption ("our") key.
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_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.
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_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_ShortHashCode hmac
MAC of the encrypted message, used to verify message integrity.
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 (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
A 256-bit hashcode.
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 3780 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 2653 of file gnunet-service-cadet_tunnels.c.

2654{
2655 struct CadetTunnel *t = cls;
2656 struct CadetTConnection *ct;
2657
2658 t->send_task = NULL;
2659 if (NULL == t->tq_head)
2660 return; /* no messages pending right now */
2661 ct = get_ready_connection (t);
2662 if (NULL == ct)
2663 return; /* no connections ready */
2665 ct);
2666}

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_hmac()

static void t_hmac ( const void *  plaintext,
size_t  size,
uint32_t  iv,
const struct GNUNET_CRYPTO_SymmetricSessionKey key,
struct GNUNET_ShortHashCode hmac 
)
static

Calculate HMAC.

Parameters
plaintextContent to HMAC.
sizeSize of plaintext.
ivInitialization vector for the message.
keyKey to use.
[out]hmacDestination to store the HMAC.

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

760{
761 static const char ctx[] = "cadet authentication key";
762 struct GNUNET_CRYPTO_AuthKey auth_key;
763 struct GNUNET_HashCode hash;
764
765 // FIXME now that we directly invoke HKDF instead of a
766 // thin wrapper we can clearly see the sillyness of adding
767 // the key parameter twice...
769 &auth_key,
770 sizeof auth_key,
771 &iv,
772 sizeof(iv),
773 key,
774 sizeof(*key),
777 /* Two step: GNUNET_ShortHash is only 256 bits,
778 GNUNET_HashCode is 512, so we truncate. */
779 GNUNET_CRYPTO_hmac (&auth_key,
780 plaintext,
781 size,
782 &hash);
783 GNUNET_memcpy (hmac,
784 &hash,
785 sizeof(*hmac));
786}

References ctx, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_hmac(), GNUNET_CRYPTO_kdf_arg_auto, GNUNET_CRYPTO_kdf_arg_string, GNUNET_memcpy, key, and size.

Referenced by GCT_send(), 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:

◆ t_ax_hmac_hash()

static void t_ax_hmac_hash ( const struct GNUNET_CRYPTO_SymmetricSessionKey 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 798 of file gnunet-service-cadet_tunnels.c.

802{
803 static const char ctx[] = "axolotl HMAC-HASH";
804 struct GNUNET_CRYPTO_AuthKey auth_key;
805
807 &auth_key,
808 sizeof auth_key,
809 ctx,
810 sizeof(ctx),
811 key,
812 sizeof *key);
813 GNUNET_CRYPTO_hmac (&auth_key,
814 source,
815 len,
816 hash);
817}

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_SymmetricSessionKey key,
struct GNUNET_CRYPTO_SymmetricSessionKey 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 829 of file gnunet-service-cadet_tunnels.c.

833{
834 static const char ctx[] = "axolotl derive key";
835 struct GNUNET_HashCode h;
836
838 &h,
839 source,
840 len);
842 out, sizeof(*out),
843 ctx, sizeof(ctx),
844 &h, sizeof(h));
845}

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 857 of file gnunet-service-cadet_tunnels.c.

861{
864 size_t out_size;
865
866 ax->ratchet_counter++;
867 if ((GNUNET_YES == ax->ratchet_allowed) &&
868 ((ratchet_messages <= ax->ratchet_counter) ||
871 {
873 }
874 if (GNUNET_YES == ax->ratchet_flag)
875 {
876 /* Advance ratchet */
878 struct GNUNET_HashCode dh;
879 struct GNUNET_HashCode hmac;
880 static const char ctx[] = "axolotl ratchet";
881
882 new_ephemeral (ax);
883 ax->HKs = ax->NHKs;
884
885 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
887 &ax->DHRr,
888 &dh);
889 t_ax_hmac_hash (&ax->RK,
890 &hmac,
891 &dh,
892 sizeof(dh));
894 keys, sizeof(keys),
895 ctx, sizeof(ctx),
896 &hmac, sizeof(hmac));
897 ax->RK = keys[0];
898 ax->NHKs = keys[1];
899 ax->CKs = keys[2];
900
901 ax->PNs = ax->Ns;
902 ax->Ns = 0;
905 ax->ratchet_counter = 0;
909 }
910
912 &MK,
913 "0",
914 1);
915
917 sizeof iv,
918 NULL,
919 0,
920 &MK,
921 sizeof MK);
922
923 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
924 size,
925 &MK,
926 &iv,
927 dst);
928 GNUNET_assert (size == out_size);
930 &ax->CKs,
931 "1",
932 1);
933}

References CadetTunnelAxolotl::CKs, ctx, CadetTunnelAxolotl::DHRr, CadetTunnelAxolotl::DHRs, GNUNET_assert, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_NO, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, CadetTunnelAxolotl::HKs, 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 945 of file gnunet-service-cadet_tunnels.c.

949{
952 size_t out_size;
953
955 &MK,
956 "0",
957 1);
958
960 sizeof iv,
961 NULL,
962 0,
963 &MK,
964 sizeof MK);
965 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
966 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
967 size,
968 &MK,
969 &iv,
970 dst);
971 GNUNET_assert (out_size == size);
973 &ax->CKr,
974 "1",
975 1);
976}

References CadetTunnelAxolotl::CKr, GNUNET_assert, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_symmetric_decrypt(), 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 
)
static

Encrypt header with the axolotl header key.

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

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

988{
990 size_t out_size;
991
993 sizeof iv,
994 NULL,
995 0,
996 &ax->HKs,
997 sizeof ax->HKs);
998 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
999 sizeof(struct
1001 &ax->HKs,
1002 &iv,
1003 &msg->ax_header);
1004 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1005}

References GNUNET_assert, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_symmetric_encrypt(), 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 void t_h_decrypt ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
struct GNUNET_CADET_TunnelEncryptedMessage dst 
)
static

Decrypt header with the current axolotl header key.

Parameters
axkey material to use.
srcMessage whose header to decrypt.
dstWhere to decrypt header to.

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

1019{
1021 size_t out_size;
1022
1024 sizeof iv,
1025 NULL,
1026 0,
1027 &ax->HKr,
1028 sizeof ax->HKr);
1029
1030
1032 sizeof(struct
1034 &ax->HKr,
1035 &iv,
1036 &dst->ax_header.Ns);
1037 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1038}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, GNUNET_assert, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_symmetric_decrypt(), CadetTunnelAxolotl::HKr, and GNUNET_CADET_AxHeader::Ns.

Referenced by t_ax_decrypt_and_validate().

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 1048 of file gnunet-service-cadet_tunnels.c.

1050{
1052 ax->skipped_tail,
1053 key);
1054 GNUNET_free (key);
1055 ax->skipped--;
1056}

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 1070 of file gnunet-service-cadet_tunnels.c.

1074{
1075 struct CadetTunnelSkippedKey *key;
1076 struct GNUNET_ShortHashCode *hmac;
1078 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1079 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
1080 size_t esize;
1081 size_t res;
1082 size_t len;
1083 unsigned int N;
1084
1086 "Trying skipped keys\n");
1087 hmac = &plaintext_header.hmac;
1088 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1089
1090 /* Find a correct Header Key */
1091 valid_HK = NULL;
1092 for (key = ax->skipped_head; NULL != key; key = key->next)
1093 {
1094 t_hmac (&src->ax_header,
1095 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1096 0,
1097 &key->HK,
1098 hmac);
1099 if (0 == GNUNET_memcmp (hmac,
1100 &src->hmac))
1101 {
1102 valid_HK = &key->HK;
1103 break;
1104 }
1105 }
1106 if (NULL == key)
1107 return -1;
1108
1109 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1111 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1112 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1113
1114 /* Decrypt header */
1116 sizeof iv,
1117 NULL,
1118 0,
1119 &key->HK,
1120 sizeof key->HK);
1121
1123 sizeof(struct GNUNET_CADET_AxHeader),
1124 &key->HK,
1125 &iv,
1126 &plaintext_header.ax_header.Ns);
1127 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1128
1129 /* Find the correct message key */
1130 N = ntohl (plaintext_header.ax_header.Ns);
1131 while ((NULL != key) &&
1132 (N != key->Kn))
1133 key = key->next;
1134 if ((NULL == key) ||
1135 (0 != GNUNET_memcmp (&key->HK,
1136 valid_HK)))
1137 return -1;
1138
1139 /* Decrypt payload */
1141 sizeof iv,
1142 NULL,
1143 0,
1144 &key->MK,
1145 sizeof key->MK);
1146
1148 len,
1149 &key->MK,
1150 &iv,
1151 dst);
1153 key);
1154 return res;
1155}

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, delete_skipped_key(), GNUNET_assert, GNUNET_CRYPTO_hkdf_gnunet, GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_CADET_TunnelEncryptedMessage::hmac, key, LOG, N, GNUNET_CADET_AxHeader::Ns, res, size, CadetTunnelAxolotl::skipped_head, and t_hmac().

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_SymmetricSessionKey HKr 
)
static

Delete a key from the list of skipped keys.

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

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

1167{
1168 struct CadetTunnelSkippedKey *key;
1169
1171 key->timestamp = GNUNET_TIME_absolute_get ();
1172 key->Kn = ax->Nr;
1173 key->HK = ax->HKr;
1174 t_hmac_derive_key (&ax->CKr,
1175 &key->MK,
1176 "0",
1177 1);
1178 t_hmac_derive_key (&ax->CKr,
1179 &ax->CKr,
1180 "1",
1181 1);
1183 ax->skipped_tail,
1184 key);
1185 ax->skipped++;
1186 ax->Nr++;
1187}

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_SymmetricSessionKey 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 1201 of file gnunet-service-cadet_tunnels.c.

1204{
1205 int gap;
1206
1207 gap = Np - ax->Nr;
1209 "Storing skipped keys [%u, %u)\n",
1210 ax->Nr,
1211 Np);
1212 if (MAX_KEY_GAP < gap)
1213 {
1214 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1215 /* TODO: start new key exchange on return */
1216 GNUNET_break_op (0);
1218 "Got message %u, expected %u+\n",
1219 Np,
1220 ax->Nr);
1221 return GNUNET_SYSERR;
1222 }
1223 if (0 > gap)
1224 {
1225 /* Delayed message: don't store keys, flag to try old keys. */
1226 return GNUNET_SYSERR;
1227 }
1228
1229 while (ax->Nr < Np)
1231 HKr);
1232
1233 while (ax->skipped > MAX_SKIPPED_KEYS)
1235 ax->skipped_tail);
1236 return GNUNET_OK;
1237}

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 1251 of file gnunet-service-cadet_tunnels.c.

1256{
1257 struct GNUNET_ShortHashCode msg_hmac;
1258 struct GNUNET_HashCode hmac;
1259 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1260 uint32_t Np;
1261 uint32_t PNp;
1262 size_t esize; /* Size of encrypted payload */
1263
1264 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1265
1266 /* Try current HK */
1267 t_hmac (&src->ax_header,
1268 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1269 0, &ax->HKr,
1270 &msg_hmac);
1271 if (0 != GNUNET_memcmp (&msg_hmac,
1272 &src->hmac))
1273 {
1274 static const char ctx[] = "axolotl ratchet";
1275 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1277 struct GNUNET_HashCode dh;
1278 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1279
1280 /* Try Next HK */
1281 t_hmac (&src->ax_header,
1282 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1283 0,
1284 &ax->NHKr,
1285 &msg_hmac);
1286 if (0 != GNUNET_memcmp (&msg_hmac,
1287 &src->hmac))
1288 {
1289 /* Try the skipped keys, if that fails, we're out of luck. */
1290 return try_old_ax_keys (ax,
1291 dst,
1292 src,
1293 size);
1294 }
1295 HK = ax->HKr;
1296 ax->HKr = ax->NHKr;
1297 t_h_decrypt (ax,
1298 src,
1299 &plaintext_header);
1300 Np = ntohl (plaintext_header.ax_header.Ns);
1301 PNp = ntohl (plaintext_header.ax_header.PNs);
1302 DHRp = &plaintext_header.ax_header.DHRs;
1303 store_ax_keys (ax,
1304 &HK,
1305 PNp);
1306
1307 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1309 DHRp,
1310 &dh);
1311 t_ax_hmac_hash (&ax->RK,
1312 &hmac,
1313 &dh, sizeof(dh));
1315 keys, sizeof(keys),
1316 ctx, sizeof(ctx),
1317 &hmac, sizeof(hmac));
1318
1319 /* Commit "purported" keys */
1320 ax->RK = keys[0];
1321 ax->NHKr = keys[1];
1322 ax->CKr = keys[2];
1323 ax->DHRr = *DHRp;
1324 ax->Nr = 0;
1326 }
1327 else
1328 {
1329 t_h_decrypt (ax,
1330 src,
1331 &plaintext_header);
1332 Np = ntohl (plaintext_header.ax_header.Ns);
1333 PNp = ntohl (plaintext_header.ax_header.PNs);
1334 }
1335 if ((Np != ax->Nr) &&
1336 (GNUNET_OK != store_ax_keys (ax,
1337 &ax->HKr,
1338 Np)))
1339 {
1340 /* Try the skipped keys, if that fails, we're out of luck. */
1341 return try_old_ax_keys (ax,
1342 dst,
1343 src,
1344 size);
1345 }
1346
1347 t_ax_decrypt (ax,
1348 dst,
1349 &src[1],
1350 esize);
1351 ax->Nr = Np + 1;
1352 return esize;
1353}

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_memcmp, GNUNET_OK, GNUNET_YES, CadetTunnelAxolotl::HKr, GNUNET_CADET_TunnelEncryptedMessage::hmac, 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(), t_hmac(), 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 1366 of file gnunet-service-cadet_tunnels.c.

1369{
1370 struct CadetChannel *ch = value;
1371
1373 return GNUNET_OK;
1374}

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 1385 of file gnunet-service-cadet_tunnels.c.

1387{
1388 enum CadetTunnelEState old = t->estate;
1389
1390 t->estate = state;
1392 "%s estate changed from %s to %s\n",
1393 GCT_2s (t),
1394 estate2s (old),
1395 estate2s (state));
1396
1397 if ((CADET_TUNNEL_KEY_OK != old) &&
1398 (CADET_TUNNEL_KEY_OK == t->estate))
1399 {
1400 if (NULL != t->kx_task)
1401 {
1402 GNUNET_SCHEDULER_cancel (t->kx_task);
1403 t->kx_task = NULL;
1404 }
1405 /* notify all channels that have been waiting */
1408 t);
1409 if (NULL != t->send_task)
1410 GNUNET_SCHEDULER_cancel (t->send_task);
1412 t);
1413 }
1414}

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 1426 of file gnunet-service-cadet_tunnels.c.

1429{
1430 struct CadetConnection *cc;
1431 struct GNUNET_MQ_Envelope *env;
1434
1435 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1436 return; /* only Alice may send KX */
1437 if ((NULL == ct) ||
1438 (GNUNET_NO == ct->is_ready))
1439 ct = get_ready_connection (t);
1440 if (NULL == ct)
1441 {
1443 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1444 GCT_2s (t),
1445 estate2s (t->estate));
1446 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1447 return;
1448 }
1449 cc = ct->cc;
1452 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1453 msg->flags = htonl (flags);
1454 msg->cid = *GCC_get_id (cc);
1456 &msg->ephemeral_key);
1457#if DEBUG_KX
1458 msg->ephemeral_key_XXX = ax->kx_0;
1459#endif
1461 "Sending KX message to %s with ephemeral %s on CID %s\n",
1462 GCT_2s (t),
1463 GNUNET_e2s (&msg->ephemeral_key),
1464 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1466 &msg->ratchet_key);
1468 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1469 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1470 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1473 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1476 GCC_transmit (cc,
1477 env);
1479 "# KX transmitted",
1480 1,
1481 GNUNET_NO);
1482}

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 1496 of file gnunet-service-cadet_tunnels.c.

1500{
1501 struct CadetConnection *cc;
1502 struct GNUNET_MQ_Envelope *env;
1504 enum GNUNET_CADET_KX_Flags flags;
1505
1506 if ((NULL == ct) ||
1507 (GNUNET_NO == ct->is_ready))
1508 ct = get_ready_connection (t);
1509 if (NULL == ct)
1510 {
1512 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1513 GCT_2s (t));
1514 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1515 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1516 return;
1517 }
1518 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1519 cc = ct->cc;
1523 if (GNUNET_YES == force_reply)
1525 msg->kx.flags = htonl (flags);
1526 msg->kx.cid = *GCC_get_id (cc);
1528 &msg->kx.ephemeral_key);
1530 &msg->kx.ratchet_key);
1531#if DEBUG_KX
1532 msg->kx.ephemeral_key_XXX = ax->kx_0;
1533 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1534#endif
1536 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1537 GCT_2s (t),
1538 GNUNET_e2s (&msg->kx.ephemeral_key),
1539 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1540
1541 /* Compute authenticator (this is the main difference to #send_kx()) */
1542 GNUNET_CRYPTO_hash (&ax->RK,
1543 sizeof(ax->RK),
1544 &msg->auth);
1545 /* Compute when to be triggered again; actual job will
1546 be scheduled via #connection_ready_cb() */
1547 t->kx_retry_delay
1548 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1549 t->next_kx_attempt
1550 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1551
1552 /* Send via cc, mark it as unready */
1554
1555 /* Update state machine, unless we are already OK */
1556 if (CADET_TUNNEL_KEY_OK != t->estate)
1559 GCC_transmit (cc,
1560 env);
1562 "# KX_AUTH transmitted",
1563 1,
1564 GNUNET_NO);
1565}

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 1574 of file gnunet-service-cadet_tunnels.c.

1575{
1576 while (NULL != ax->skipped_head)
1578 ax->skipped_head);
1579 GNUNET_assert (0 == ax->skipped);
1582}

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 1597 of file gnunet-service-cadet_tunnels.c.

1599{
1600 struct CadetTunnelAsync *as;
1601 struct GNUNET_HashCode key_material[3];
1602 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1603 struct CadetTunnelAxolotl *ax;
1604 const struct GNUNET_PeerIdentity *pid;
1605 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1606 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1607 const char salt[] = "CADET Axolotl salt";
1608 int am_I_alice;
1609
1610 as = cls;
1611 ax = &as->ax;
1612 pid = &as->peer_id;
1613 ephemeral_key = &as->ephemeral_key;
1614 ratchet_key = &as->ratchet_key;
1615
1616 as->ecdh_op = NULL;
1617
1619 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1620 GNUNET_e2s (ephemeral_key));
1621
1622 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1623 {
1624 GNUNET_break_op (0);
1625 if (as->cb)
1626 as->cb (as->cb_cls, GNUNET_SYSERR);
1627 return;
1628 }
1629
1630 if (0 == GNUNET_memcmp (&ax->DHRr,
1631 ratchet_key))
1632 {
1634 "# Ratchet key already known",
1635 1,
1636 GNUNET_NO);
1638 "Ratchet key already known. Ignoring KX.\n");
1639 if (as->cb)
1640 as->cb (as->cb_cls, GNUNET_NO);
1641 return;
1642 }
1643
1644 ax->DHRr = *ratchet_key;
1645 ax->last_ephemeral = *ephemeral_key;
1646 /* ECDH A B0 */
1647 if (GNUNET_YES == am_I_alice)
1648 {
1649 GNUNET_memcpy (&key_material[0], key_result,
1650 sizeof (*key_result));
1651 }
1652 else
1653 {
1654 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1655 &pid->public_key, /* A */
1656 &key_material[0]);
1657 }
1658 /* ECDH A0 B */
1659 if (GNUNET_YES == am_I_alice)
1660 {
1661 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1662 &pid->public_key, /* B */
1663 &key_material[1]);
1664 }
1665 else
1666 {
1667 GNUNET_memcpy (&key_material[1], key_result,
1668 sizeof (*key_result));
1669 }
1670
1671 /* ECDH A0 B0 */
1672 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1673 ephemeral_key, /* B0 or A0 */
1674 &key_material[2]);
1675 /* KDF */
1677 keys, sizeof(keys),
1678 salt, sizeof(salt),
1679 &key_material, sizeof(key_material));
1680
1681 if (0 == memcmp (&ax->RK,
1682 &keys[0],
1683 sizeof(ax->RK)))
1684 {
1686 "Root key already known. Ignoring KX.\n");
1688 "# Root key already known",
1689 1,
1690 GNUNET_NO);
1691 if (as->cb)
1692 as->cb (as->cb_cls, GNUNET_NO);
1693 return;
1694 }
1695
1696 ax->RK = keys[0];
1697 if (GNUNET_YES == am_I_alice)
1698 {
1699 ax->HKr = keys[1];
1700 ax->NHKs = keys[2];
1701 ax->NHKr = keys[3];
1702 ax->CKr = keys[4];
1704 }
1705 else
1706 {
1707 ax->HKs = keys[1];
1708 ax->NHKr = keys[2];
1709 ax->NHKs = keys[3];
1710 ax->CKs = keys[4];
1711 ax->ratchet_flag = GNUNET_NO;
1714 ratchet_time);
1715 }
1716
1717 if (as->cb)
1718 as->cb (as->cb_cls, GNUNET_OK);
1719}

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 1728 of file gnunet-service-cadet_tunnels.c.

1729{
1730 struct CadetTunnel *t = cls;
1731 struct CadetTunnelAxolotl *ax;
1732
1733 t->kx_task = NULL;
1735 "Trying to make KX progress on %s in state %s\n",
1736 GCT_2s (t),
1737 estate2s (t->estate));
1738 switch (t->estate)
1739 {
1740 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1741 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1742 send_kx (t,
1743 NULL,
1744 &t->ax);
1745 break;
1746
1749 /* We are responding, so only require reply
1750 if WE have a channel waiting. */
1751 if (NULL != t->unverified_ax)
1752 {
1753 /* Send AX_AUTH so we might get this one verified */
1754 ax = t->unverified_ax;
1755 }
1756 else
1757 {
1758 /* How can this be? */
1759 GNUNET_break (0);
1760 ax = &t->ax;
1761 }
1762 send_kx_auth (t,
1763 NULL,
1764 ax,
1765 (0 == GCT_count_channels (t))
1766 ? GNUNET_NO
1767 : GNUNET_YES);
1768 break;
1769
1771 /* We are responding, so only require reply
1772 if WE have a channel waiting. */
1773 if (NULL != t->unverified_ax)
1774 {
1775 /* Send AX_AUTH so we might get this one verified */
1776 ax = t->unverified_ax;
1777 }
1778 else
1779 {
1780 /* How can this be? */
1781 GNUNET_break (0);
1782 ax = &t->ax;
1783 }
1784 send_kx_auth (t,
1785 NULL,
1786 ax,
1787 (0 == GCT_count_channels (t))
1788 ? GNUNET_NO
1789 : GNUNET_YES);
1790 break;
1791
1793 /* Must have been the *other* peer asking us to
1794 respond with a KX_AUTH. */
1795 if (NULL != t->unverified_ax)
1796 {
1797 /* Sending AX_AUTH in response to AX so we might get this one verified */
1798 ax = t->unverified_ax;
1799 }
1800 else
1801 {
1802 /* Sending AX_AUTH in response to AX_AUTH */
1803 ax = &t->ax;
1804 }
1805 send_kx_auth (t,
1806 NULL,
1807 ax,
1808 GNUNET_NO);
1809 break;
1810 }
1811}

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 1821 of file gnunet-service-cadet_tunnels.c.

1823{
1824 struct CadetTunnel *t = cls;
1825
1826 if (t->unverified_ax)
1827 *(t->unverified_ax) = t->as.ax;
1828
1830 "Continue handling KX message from %s from %s\n",
1831 GCT_2s (t),
1832 GNUNET_i2s (GCP_get_id (t->destination)));
1833
1835 if (GNUNET_OK != ret)
1836 {
1838 "# Useless KX",
1839 1,
1840 GNUNET_NO);
1841 return; /* duplicate KX, nothing to do */
1842 }
1843 /* move ahead in our state machine */
1844 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1847 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1850
1851 /* KX is still not done, try again our end. */
1852 if (CADET_TUNNEL_KEY_OK != t->estate)
1853 {
1854 if (NULL != t->kx_task)
1855 GNUNET_SCHEDULER_cancel (t->kx_task);
1856 t->kx_task
1858 t);
1859 }
1860}

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 1870 of file gnunet-service-cadet_tunnels.c.

1872{
1873 struct CadetTunnel *t = ct->t;
1874
1876 "# KX received",
1877 1,
1878 GNUNET_NO);
1879 if (GNUNET_YES ==
1880 GCT_alice_or_betty (GCP_get_id (t->destination)))
1881 {
1882 /* Betty/Bob is not allowed to send KX! */
1883 GNUNET_break_op (0);
1884 return;
1885 }
1887 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1888 GCT_2s (t),
1889 GNUNET_e2s (&msg->ephemeral_key),
1890 GNUNET_i2s (GCP_get_id (t->destination)),
1891 GCC_2s (ct->cc));
1892#if 1
1893 if ((0 ==
1894 memcmp (&t->ax.DHRr,
1895 &msg->ratchet_key,
1896 sizeof(msg->ratchet_key))) &&
1897 (0 ==
1898 memcmp (&t->ax.last_ephemeral,
1899 &msg->ephemeral_key,
1900 sizeof(msg->ephemeral_key))))
1901
1902 {
1904 "# Duplicate KX received",
1905 1,
1906 GNUNET_NO);
1907 send_kx_auth (t,
1908 ct,
1909 &t->ax,
1910 GNUNET_NO);
1911 return;
1912 }
1913#endif
1914 /* We only keep ONE unverified KX around, so if there is an existing one,
1915 clean it up. */
1916 if (NULL != t->unverified_ax)
1917 {
1918 if ((0 ==
1919 memcmp (&t->unverified_ax->DHRr,
1920 &msg->ratchet_key,
1921 sizeof(msg->ratchet_key))) &&
1922 (0 ==
1923 memcmp (&t->unverified_ax->last_ephemeral,
1924 &msg->ephemeral_key,
1925 sizeof(msg->ephemeral_key))))
1926 {
1928 "# Duplicate unverified KX received",
1929 1,
1930 GNUNET_NO);
1931#if 1
1932 send_kx_auth (t,
1933 ct,
1934 t->unverified_ax,
1935 GNUNET_NO);
1936 return;
1937#endif
1938 }
1939 if ((t->as.ecdh_op) &&
1940 (0 ==
1941 memcmp (&t->as.ratchet_key,
1942 &msg->ratchet_key,
1943 sizeof(msg->ratchet_key))) &&
1944 (0 ==
1945 memcmp (&t->as.ephemeral_key,
1946 &msg->ephemeral_key,
1947 sizeof(msg->ephemeral_key))))
1948 {
1950 "Waiting for previous ECDH operation\n");
1951 return;
1952 }
1954 "Dropping old unverified KX state.\n");
1956 "# Unverified KX dropped for fresh KX",
1957 1,
1958 GNUNET_NO);
1959 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1960 memset (t->unverified_ax,
1961 0,
1962 sizeof(struct CadetTunnelAxolotl));
1963 }
1964 else
1965 {
1967 "Creating fresh unverified KX for %s\n",
1968 GCT_2s (t));
1970 "# Fresh KX setup",
1971 1,
1972 GNUNET_NO);
1973 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1974 }
1975 /* Set as the 'current' RK/DHRr the one we are currently using,
1976 so that the duplicate-detection logic of
1977 #update_ax_by_kx can work. */
1978 t->unverified_ax->RK = t->ax.RK;
1979 t->unverified_ax->DHRr = t->ax.DHRr;
1980 t->unverified_ax->DHRs = t->ax.DHRs;
1981 t->unverified_ax->kx_0 = t->ax.kx_0;
1982 t->unverified_attempts = 0;
1983
1984 t->as.ax = *(t->unverified_ax);
1985 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1986 sizeof (t->as.peer_id));
1987 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1988 sizeof (t->as.ephemeral_key));
1989 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1990 sizeof (t->as.ratchet_key));
1991 memset (&t->as.auth, 0, sizeof (t->as.auth));
1992 t->as.flags = 0;
1993 t->as.cb_cls = t;
1994 t->as.cb = &cont_GCT_handle_kx;
1995
1996 if (t->as.ecdh_op)
1997 {
1999 "Cancelling previous ECDH operation\n");
2000
2001 GNUNET_PILS_cancel (t->as.ecdh_op);
2002 }
2003
2004 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
2005 &update_ax_by_kx, &t->as);
2006}

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 2016 of file gnunet-service-cadet_tunnels.c.

2018{
2019 struct CadetTunnel *t = cls;
2020 struct CadetTunnelAxolotl *ax_tmp;
2021 struct GNUNET_HashCode kx_auth;
2022
2023 ax_tmp = &t->as.ax;
2024
2026 "Continue handling KX_AUTH message from %s\n",
2027 GCT_2s (t));
2028
2029 if (GNUNET_OK != ret)
2030 {
2031 if (GNUNET_NO == ret)
2033 "# redundant KX_AUTH received",
2034 1,
2035 GNUNET_NO);
2036 else
2037 GNUNET_break (0); /* connect to self!? */
2038 return;
2039 }
2040 GNUNET_CRYPTO_hash (&ax_tmp->RK,
2041 sizeof(ax_tmp->RK),
2042 &kx_auth);
2043 if (0 != GNUNET_memcmp (&kx_auth,
2044 &t->as.auth))
2045 {
2046 /* This KX_AUTH is not using the latest KX/KX_AUTH data
2047 we transmitted to the sender, refuse it, try KX again. */
2049 "# KX_AUTH not using our last KX received (auth failure)",
2050 1,
2051 GNUNET_NO);
2053 "KX AUTH mismatch!\n");
2054#if DEBUG_KX
2055 {
2056 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2057
2059 &ephemeral_key);
2060 if (0 != GNUNET_memcmp (&ephemeral_key,
2061 &msg->r_ephemeral_key_XXX))
2062 {
2064 "My ephemeral is %s!\n",
2065 GNUNET_e2s (&ephemeral_key));
2067 "Response is for ephemeral %s!\n",
2068 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2069 }
2070 }
2071#endif
2072 if (NULL == t->kx_task)
2073 t->kx_task
2074 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2075 &retry_kx,
2076 t);
2077 return;
2078 }
2079 /* Yep, we're good. */
2080 t->ax = *ax_tmp;
2081 if (NULL != t->unverified_ax)
2082 {
2083 /* We got some "stale" KX before, drop that. */
2084 cleanup_ax (t->unverified_ax);
2085 GNUNET_free (t->unverified_ax);
2086 t->unverified_ax = NULL;
2087 }
2088
2089 /* move ahead in our state machine */
2090 switch (t->estate)
2091 {
2094 /* Checked above, this is impossible. */
2095 GNUNET_assert (0);
2096 break;
2097
2098 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2099 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2100 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2103 break;
2104
2106 /* Did not expect another KX_AUTH, but so what, still acceptable.
2107 Nothing to do here. */
2108 break;
2109 }
2110 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2111 {
2112 send_kx_auth (t,
2113 NULL,
2114 &t->ax,
2115 GNUNET_NO);
2116 }
2117}

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 2127 of file gnunet-service-cadet_tunnels.c.

2129{
2130 struct CadetTunnel *t = ct->t;
2131
2133 "# KX_AUTH received",
2134 1,
2135 GNUNET_NO);
2136 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2137 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2138 {
2139 /* Confusing, we got a KX_AUTH before we even send our own
2140 KX. This should not happen. We'll send our own KX ASAP anyway,
2141 so let's ignore this here. */
2142 GNUNET_break_op (0);
2143 return;
2144 }
2146 "Handling KX_AUTH message from %s with ephemeral %s\n",
2147 GCT_2s (t),
2148 GNUNET_e2s (&msg->kx.ephemeral_key));
2149 if ((t->as.ecdh_op) &&
2150 (0 ==
2151 memcmp (&t->as.ratchet_key,
2152 &msg->kx.ratchet_key,
2153 sizeof(msg->kx.ratchet_key))) &&
2154 (0 ==
2155 memcmp (&t->as.ephemeral_key,
2156 &msg->kx.ephemeral_key,
2157 sizeof(msg->kx.ephemeral_key))))
2158 {
2160 "Waiting for previous ECDH operation\n");
2161 return;
2162 }
2163 /* We do everything in a copy until we've checked the authentication
2164 so we don't clobber anything we care about by accident. */
2165 t->as.ax = t->ax;
2166 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2167 sizeof (t->as.peer_id));
2168 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2169 sizeof (t->as.ephemeral_key));
2170 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2171 sizeof (t->as.ratchet_key));
2172 t->as.auth = msg->auth;
2173 t->as.flags = msg->kx.flags;
2174 t->as.cb_cls = t;
2175 t->as.cb = &cont_GCT_handle_kx_auth;
2176
2177 if (t->as.ecdh_op)
2178 {
2180 "Cancelling previous ECDH operation\n");
2181
2182 GNUNET_PILS_cancel (t->as.ecdh_op);
2183 }
2184
2185 /* Update 'ax' by the new key material */
2186 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2187 &update_ax_by_kx, &t->as);
2188}

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 2201 of file gnunet-service-cadet_tunnels.c.

2202{
2203#define HIGH_BIT 0x8000000
2204 const struct GNUNET_PeerIdentity *my_identity;
2206 uint32_t ctn;
2207 int cmp;
2208 uint32_t highbit;
2209
2212
2215 if (0 < cmp)
2216 highbit = HIGH_BIT;
2217 else if (0 > cmp)
2218 highbit = 0;
2219 else
2220 GNUNET_assert (0); // loopback must never go here!
2221 ctn = ntohl (t->next_ctn.cn);
2222 while (NULL !=
2224 ctn | highbit))
2225 {
2226 ctn = ((ctn + 1) & (~HIGH_BIT));
2227 }
2228 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2229 ret.cn = htonl (ctn | highbit);
2230 return ret;
2231}

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 2244 of file gnunet-service-cadet_tunnels.c.

2246{
2248
2249 ctn = get_next_free_ctn (t);
2250 if (NULL != t->destroy_task)
2251 {
2252 GNUNET_SCHEDULER_cancel (t->destroy_task);
2253 t->destroy_task = NULL;
2254 }
2257 ntohl (ctn.cn),
2258 ch,
2261 "Adding %s to %s with state %d\n",
2262 GCCH_2s (ch),
2263 GCT_2s (t),
2264 t->estate);
2265 switch (t->estate)
2266 {
2268 /* waiting for connection to start KX */
2269 break;
2270
2274 /* we're currently waiting for KX to complete */
2275 break;
2276
2278 /* waiting for OTHER peer to send us data,
2279 we might need to prompt more aggressively! */
2280 if (NULL == t->kx_task)
2281 t->kx_task
2282 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2283 &retry_kx,
2284 t);
2285 break;
2286
2288 /* We are ready. Tell the new channel that we are up. */
2290 break;
2291 }
2292 return ctn;
2293}

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 2303 of file gnunet-service-cadet_tunnels.c.

2304{
2305 struct CadetTunnel *t = ct->t;
2306
2307 if (GNUNET_YES == ct->is_ready)
2308 {
2309 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2310 t->connection_ready_tail,
2311 ct);
2312 t->num_ready_connections--;
2313 }
2314 else
2315 {
2316 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2317 t->connection_busy_tail,
2318 ct);
2319 t->num_busy_connections--;
2320 }
2321 GNUNET_free (ct);
2322}

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 2332 of file gnunet-service-cadet_tunnels.c.

2334{
2335 struct CadetTunnel *t = cls;
2336 struct CadetConnection *cc = ct->cc;
2337
2338 GNUNET_assert (ct->t == t);
2341}

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 2350 of file gnunet-service-cadet_tunnels.c.

2351{
2352 struct CadetTunnel *t = cls;
2353 struct CadetTunnelQueueEntry *tq;
2354
2355 t->destroy_task = NULL;
2357 "Destroying idle %s\n",
2358 GCT_2s (t));
2362 t);
2363 GNUNET_assert (NULL == t->connection_ready_head);
2364 GNUNET_assert (NULL == t->connection_busy_head);
2365 while (NULL != (tq = t->tq_head))
2366 {
2367 if (NULL != tq->cont)
2368 tq->cont (tq->cont_cls,
2369 NULL);
2370 GCT_send_cancel (tq);
2371 }
2372 GCP_drop_tunnel (t->destination,
2373 t);
2375 if (NULL != t->maintain_connections_task)
2376 {
2377 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2378 t->maintain_connections_task = NULL;
2379 }
2380 if (NULL != t->send_task)
2381 {
2382 GNUNET_SCHEDULER_cancel (t->send_task);
2383 t->send_task = NULL;
2384 }
2385 if (NULL != t->kx_task)
2386 {
2387 GNUNET_SCHEDULER_cancel (t->kx_task);
2388 t->kx_task = NULL;
2389 }
2390 if (NULL != t->as.ecdh_op)
2391 {
2392 GNUNET_PILS_cancel (t->as.ecdh_op);
2393 t->as.ecdh_op = NULL;
2394 }
2395 GNUNET_MST_destroy (t->mst);
2396 GNUNET_MQ_destroy (t->mq);
2397 if (NULL != t->unverified_ax)
2398 {
2399 cleanup_ax (t->unverified_ax);
2400 GNUNET_free (t->unverified_ax);
2401 }
2402 cleanup_ax (&t->ax);
2403 GNUNET_assert (NULL == t->destroy_task);
2404 GNUNET_free (t);
2405}

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 2416 of file gnunet-service-cadet_tunnels.c.

2419{
2421 "Removing %s from %s\n",
2422 GCCH_2s (ch),
2423 GCT_2s (t));
2426 ntohl (ctn.cn),
2427 ch));
2428 if ((0 ==
2429 GCT_count_channels (t)) &&
2430 (NULL == t->destroy_task))
2431 {
2432 t->destroy_task
2435 t);
2436 }
2437}

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 2449 of file gnunet-service-cadet_tunnels.c.

2452{
2453 struct CadetChannel *ch = value;
2454
2456 NULL);
2457 return GNUNET_OK;
2458}

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 2467 of file gnunet-service-cadet_tunnels.c.

2468{
2472 t);
2473 GNUNET_assert (0 ==
2475 if (NULL != t->destroy_task)
2476 {
2477 GNUNET_SCHEDULER_cancel (t->destroy_task);
2478 t->destroy_task = NULL;
2479 }
2480 destroy_tunnel (t);
2481}

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 2492 of file gnunet-service-cadet_tunnels.c.

2494{
2495 struct CadetTunnelQueueEntry *tq;
2496
2498 tq = t->tq_head;
2499 if (NULL == tq)
2500 {
2501 /* no messages pending right now */
2503 "Not sending payload of %s on ready %s (nothing pending)\n",
2504 GCT_2s (t),
2505 GCC_2s (ct->cc));
2506 return;
2507 }
2508 /* ready to send message 'tq' on tunnel 'ct' */
2509 GNUNET_assert (t == tq->t);
2511 t->tq_tail,
2512 tq);
2513 if (NULL != tq->cid)
2514 *tq->cid = *GCC_get_id (ct->cc);
2517 "Sending payload of %s on %s\n",
2518 GCT_2s (t),
2519 GCC_2s (ct->cc));
2520 GCC_transmit (ct->cc,
2521 tq->env);
2522 if (NULL != tq->cont)
2523 tq->cont (tq->cont_cls,
2524 GCC_get_id (ct->cc));
2525 GNUNET_free (tq);
2526}

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 2538 of file gnunet-service-cadet_tunnels.c.

2540{
2541 struct CadetTConnection *ct = cls;
2542 struct CadetTunnel *t = ct->t;
2543
2544 if (GNUNET_NO == is_ready)
2545 {
2547 "%s no longer ready for %s\n",
2548 GCC_2s (ct->cc),
2549 GCT_2s (t));
2551 return;
2552 }
2554 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2555 t->connection_busy_tail,
2556 ct);
2557 GNUNET_assert (0 < t->num_busy_connections);
2558 t->num_busy_connections--;
2559 ct->is_ready = GNUNET_YES;
2560 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2561 t->connection_ready_tail,
2562 ct);
2563 t->num_ready_connections++;
2564
2566 "%s now ready for %s in state %s\n",
2567 GCC_2s (ct->cc),
2568 GCT_2s (t),
2569 estate2s (t->estate));
2570 switch (t->estate)
2571 {
2574 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2575 GCT_2s (t),
2576 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2577 t->next_kx_attempt).rel_value_us);
2578 /* Do not begin KX if WE have no channels waiting! */
2580 t->next_kx_attempt).rel_value_us)
2581 return; /* wait for timeout before retrying */
2582 /* We are uninitialized, just transmit immediately,
2583 without undue delay. */
2584
2586 "Why for %s \n",
2587 GCT_2s (t));
2588
2589 if (NULL != t->kx_task)
2590 {
2591 GNUNET_SCHEDULER_cancel (t->kx_task);
2592 t->kx_task = NULL;
2593 }
2594 send_kx (t,
2595 ct,
2596 &t->ax);
2597 if ((0 ==
2598 GCT_count_channels (t)) &&
2599 (NULL == t->destroy_task))
2600 {
2601 t->destroy_task
2604 t);
2605 }
2606 break;
2607
2612 /* we're currently waiting for KX to complete, schedule job */
2613 if (NULL == t->kx_task)
2614 t->kx_task
2615 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2616 &retry_kx,
2617 t);
2618 break;
2619
2621 if (GNUNET_YES == t->kx_auth_requested)
2622 {
2624 t->next_kx_attempt).rel_value_us)
2625 return; /* wait for timeout */
2626 if (NULL != t->kx_task)
2627 {
2628 GNUNET_SCHEDULER_cancel (t->kx_task);
2629 t->kx_task = NULL;
2630 }
2631 send_kx_auth (t,
2632 ct,
2633 &t->ax,
2634 GNUNET_NO);
2635 return;
2636 }
2638 ct);
2639 break;
2640 }
2641}

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 2726 of file gnunet-service-cadet_tunnels.c.

2728{
2729 struct EvaluationSummary *es = cls;
2730 struct CadetConnection *cc = ct->cc;
2731 unsigned int ct_length;
2732 struct CadetPeerPath *ps;
2733 const struct CadetConnectionMetrics *metrics;
2734 GNUNET_CONTAINER_HeapCostType ct_desirability;
2735 struct GNUNET_TIME_Relative uptime;
2736 struct GNUNET_TIME_Relative last_use;
2737 double score;
2738 double success_rate;
2739
2740 ps = GCC_get_path (cc,
2741 &ct_length);
2743 "Evaluating path %s of existing %s\n",
2744 GCPP_2s (ps),
2745 GCC_2s (cc));
2746 if (ps == es->path)
2747 {
2749 "Ignoring duplicate path %s.\n",
2750 GCPP_2s (es->path));
2751 es->duplicate = GNUNET_YES;
2752 return;
2753 }
2754 if (NULL != es->path)
2755 {
2756 int duplicate = GNUNET_YES;
2757
2758 for (unsigned int i = 0; i < ct_length; i++)
2759 {
2762 i) !=
2764 i))
2765 {
2766 duplicate = GNUNET_NO;
2767 break;
2768 }
2769 }
2770 if (GNUNET_YES == duplicate)
2771 {
2773 "Ignoring overlapping path %s.\n",
2774 GCPP_2s (es->path));
2775 es->duplicate = GNUNET_YES;
2776 return;
2777 }
2778 else
2779 {
2781 "Known path %s differs from proposed path\n",
2782 GCPP_2s (ps));
2783 }
2784 }
2785
2786 ct_desirability = GCPP_get_desirability (ps);
2787 metrics = GCC_get_metrics (cc);
2788 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2789 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2790 /* We add 1.0 here to avoid division by zero. */
2791 success_rate = (metrics->num_acked_transmissions + 1.0)
2792 / (metrics->num_successes + 1.0);
2793 score
2794 = ct_desirability
2795 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2796 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2797 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2798 score *= success_rate; /* weigh overall by success rate */
2799
2800 if ((NULL == es->worst) ||
2801 (score < es->worst_score))
2802 {
2803 es->worst = ct;
2804 es->worst_score = score;
2805 }
2806 es->min_length = GNUNET_MIN (es->min_length,
2807 ct_length);
2808 es->max_length = GNUNET_MAX (es->max_length,
2809 ct_length);
2810 es->min_desire = GNUNET_MIN (es->min_desire,
2811 ct_desirability);
2812 es->max_desire = GNUNET_MAX (es->max_desire,
2813 ct_desirability);
2814}

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 2827 of file gnunet-service-cadet_tunnels.c.

2830{
2831 struct CadetTunnel *t = cls;
2832 struct EvaluationSummary es;
2833 struct CadetTConnection *ct;
2834
2835 GNUNET_assert (off < GCPP_get_length (path));
2837 off) == t->destination);
2838 es.min_length = UINT_MAX;
2839 es.max_length = 0;
2840 es.max_desire = 0;
2841 es.min_desire = UINT64_MAX;
2842 es.path = path;
2843 es.duplicate = GNUNET_NO;
2844 es.worst = NULL;
2845
2846 /* Compute evaluation summary over existing connections. */
2848 "Evaluating proposed path %s for target %s\n",
2849 GCPP_2s (path),
2850 GCT_2s (t));
2851 /* FIXME: suspect this does not ACTUALLY iterate
2852 over all existing paths, otherwise dup detection
2853 should work!!! */
2856 &es);
2857 if (GNUNET_YES == es.duplicate)
2858 return GNUNET_YES;
2859
2860 /* FIXME: not sure we should really just count
2861 'num_connections' here, as they may all have
2862 consistently failed to connect. */
2863
2864 /* We iterate by increasing path length; if we have enough paths and
2865 this one is more than twice as long than what we are currently
2866 using, then ignore all of these super-long ones! */
2868 (es.min_length * 2 < off) &&
2869 (es.max_length < off))
2870 {
2872 "Ignoring paths of length %u, they are way too long.\n",
2873 es.min_length * 2);
2874 return GNUNET_NO;
2875 }
2876 /* If we have enough paths and this one looks no better, ignore it. */
2878 (es.min_length < GCPP_get_length (path)) &&
2879 (es.min_desire > GCPP_get_desirability (path)) &&
2880 (es.max_length < off))
2881 {
2883 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2884 GCPP_get_length (path),
2885 (unsigned long long) GCPP_get_desirability (path),
2886 GCP_2s (t->destination));
2887 return GNUNET_YES;
2888 }
2889
2890 /* Path is interesting (better by some metric, or we don't have
2891 enough paths yet). */
2892 ct = GNUNET_new (struct CadetTConnection);
2894 ct->t = t;
2895 ct->cc = GCC_create (t->destination,
2896 path,
2897 off,
2898 ct,
2900 ct);
2901
2902 /* FIXME: schedule job to kill connection (and path?) if it takes
2903 too long to get ready! (And track performance data on how long
2904 other connections took with the tunnel!)
2905 => Note: to be done within 'connection'-logic! */
2906 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2907 t->connection_busy_tail,
2908 ct);
2909 t->num_busy_connections++;
2911 "Found interesting path %s for %s, created %s\n",
2912 GCPP_2s (path),
2913 GCT_2s (t),
2914 GCC_2s (ct->cc));
2915 return GNUNET_YES;
2916}

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 2933 of file gnunet-service-cadet_tunnels.c.

2934{
2935 struct CadetTunnel *t = cls;
2936 struct GNUNET_TIME_Relative delay;
2937 struct EvaluationSummary es;
2938
2939 t->maintain_connections_task = NULL;
2941 "Performing connection maintenance for %s.\n",
2942 GCT_2s (t));
2943
2944 es.min_length = UINT_MAX;
2945 es.max_length = 0;
2946 es.max_desire = 0;
2947 es.min_desire = UINT64_MAX;
2948 es.path = NULL;
2949 es.worst = NULL;
2950 es.duplicate = GNUNET_NO;
2953 &es);
2954 if ((NULL != es.worst) &&
2956 {
2957 /* Clear out worst-performing connection 'es.worst'. */
2959 es.worst);
2960 }
2961
2962 /* Consider additional paths */
2963 (void) GCP_iterate_paths (t->destination,
2965 t);
2966
2967 /* FIXME: calculate when to try again based on how well we are doing;
2968 in particular, if we have to few connections, we might be able
2969 to do without this (as PATHS should tell us whenever a new path
2970 is available instantly; however, need to make sure this job is
2971 restarted after that happens).
2972 Furthermore, if the paths we do know are in a reasonably narrow
2973 quality band and are plentyful, we might also consider us stabilized
2974 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2975 t->maintain_connections_task
2978 t);
2979}

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 2983 of file gnunet-service-cadet_tunnels.c.

2986{
2988 "Considering %s for %s (offset %u)\n",
2989 GCPP_2s (p),
2990 GCT_2s (t),
2991 off);
2992 (void) consider_path_cb (t,
2993 p,
2994 off);
2995}

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 3005 of file gnunet-service-cadet_tunnels.c.

3007{
3008 struct CadetTunnel *t = cls;
3009
3011 "Received KEEPALIVE on %s\n",
3012 GCT_2s (t));
3014 "# keepalives received",
3015 1,
3016 GNUNET_NO);
3017}

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 3028 of file gnunet-service-cadet_tunnels.c.

3030{
3031 return GNUNET_OK;
3032}

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 3043 of file gnunet-service-cadet_tunnels.c.

3045{
3046 struct CadetTunnel *t = cls;
3047 struct CadetChannel *ch;
3048
3049 ch = lookup_channel (t,
3050 msg->ctn);
3051 if (NULL == ch)
3052 {
3053 /* We don't know about such a channel, might have been destroyed on our
3054 end in the meantime, or never existed. Send back a DESTROY. */
3056 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3057 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3058 ntohl (msg->ctn.cn));
3060 msg->ctn);
3061 return;
3062 }
3064 GCC_get_id (t->current_ct->cc),
3065 msg);
3066}

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 3078 of file gnunet-service-cadet_tunnels.c.

3080{
3081 struct CadetTunnel *t = cls;
3082 struct CadetChannel *ch;
3083
3084 ch = lookup_channel (t,
3085 ack->ctn);
3086 if (NULL == ch)
3087 {
3088 /* We don't know about such a channel, might have been destroyed on our
3089 end in the meantime, or never existed. Send back a DESTROY. */
3091 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3092 ntohl (ack->ctn.cn));
3094 ack->ctn);
3095 return;
3096 }
3098 GCC_get_id (t->current_ct->cc),
3099 ack);
3100}

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 3111 of file gnunet-service-cadet_tunnels.c.

3114{
3115 struct CadetTunnel *t = cls;
3116 struct CadetChannel *ch;
3117
3119 ntohl (copen->ctn.cn));
3120 if (NULL != ch)
3121 {
3123 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3124 GNUNET_h2s (&copen->h_port),
3125 GCT_2s (t),
3126 GCCH_2s (ch));
3128 GCC_get_id (t->current_ct->cc));
3129 return;
3130 }
3132 "Received CHANNEL_OPEN on h_port %s from %s\n",
3133 GNUNET_h2s (&copen->h_port),
3134 GCT_2s (t));
3136 copen->ctn,
3137 &copen->h_port,
3138 ntohl (copen->opt));
3139 if (NULL != t->destroy_task)
3140 {
3141 GNUNET_SCHEDULER_cancel (t->destroy_task);
3142 t->destroy_task = NULL;
3143 }
3146 ntohl (copen->ctn.cn),
3147 ch,
3149}

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 3159 of file gnunet-service-cadet_tunnels.c.

3161{
3163
3165 "Sending DESTROY message for channel ID %u\n",
3166 ntohl (ctn.cn));
3167 msg.header.size = htons (sizeof(msg));
3169 msg.reserved = htonl (0);
3170 msg.ctn = ctn;
3171 GCT_send (t,
3172 &msg.header,
3173 NULL,
3174 NULL,
3175 &ctn);
3176}

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 3188 of file gnunet-service-cadet_tunnels.c.

3191{
3192 struct CadetTunnel *t = cls;
3193 struct CadetChannel *ch;
3194
3195 ch = lookup_channel (t,
3196 cm->ctn);
3197 if (NULL == ch)
3198 {
3199 /* We don't know about such a channel, might have been destroyed on our
3200 end in the meantime, or never existed. Send back a DESTROY. */
3202 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3203 ntohl (cm->ctn.cn));
3205 cm->ctn);
3206 return;
3207 }
3209 "Received channel OPEN_ACK on channel %s from %s\n",
3210 GCCH_2s (ch),
3211 GCT_2s (t));
3213 GCC_get_id (t->current_ct->cc),
3214 &cm->port);
3215}

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 3226 of file gnunet-service-cadet_tunnels.c.

3229{
3230 struct CadetTunnel *t = cls;
3231 struct CadetChannel *ch;
3232
3233 ch = lookup_channel (t,
3234 cm->ctn);
3235 if (NULL == ch)
3236 {
3237 /* We don't know about such a channel, might have been destroyed on our
3238 end in the meantime, or never existed. */
3240 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3241 ntohl (cm->ctn.cn));
3242 return;
3243 }
3245 "Received channel DESTROY on %s from %s\n",
3246 GCCH_2s (ch),
3247 GCT_2s (t));
3249 GCC_get_id (t->current_ct->cc));
3250}

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 3264 of file gnunet-service-cadet_tunnels.c.

3266{
3267 struct CadetTunnel *t = cls;
3268
3269 GNUNET_assert (NULL != t->current_ct);
3271 msg);
3272 return GNUNET_OK;
3273}

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 3284 of file gnunet-service-cadet_tunnels.c.

3286{
3287 GNUNET_break_op (0);
3288}

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 3299 of file gnunet-service-cadet_tunnels.c.

3300{
3301 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3303 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3305 struct GNUNET_MessageHeader,
3306 t),
3307 GNUNET_MQ_hd_var_size (plaintext_data,
3310 t),
3311 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3314 t),
3315 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3318 t),
3319 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3322 t),
3323 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3326 t),
3328 };
3329
3330 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3331 new_ephemeral (&t->ax);
3333 t->destination = destination;
3335 t->maintain_connections_task
3337 t);
3338 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3339 NULL,
3340 NULL,
3341 NULL,
3342 handlers,
3344 t);
3346 t);
3347 return t;
3348}

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 3352 of file gnunet-service-cadet_tunnels.c.

3356{
3357 struct CadetTConnection *ct;
3358
3359 ct = GNUNET_new (struct CadetTConnection);
3361 ct->t = t;
3362 ct->cc = GCC_create_inbound (t->destination,
3363 path,
3364 ct,
3365 cid,
3367 ct);
3368 if (NULL == ct->cc)
3369 {
3371 "%s refused inbound %s (duplicate)\n",
3372 GCT_2s (t),
3373 GCC_2s (ct->cc));
3374 GNUNET_free (ct);
3375 return GNUNET_SYSERR;
3376 }
3377 /* FIXME: schedule job to kill connection (and path?) if it takes
3378 too long to get ready! (And track performance data on how long
3379 other connections took with the tunnel!)
3380 => Note: to be done within 'connection'-logic! */
3381 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3382 t->connection_busy_tail,
3383 ct);
3384 t->num_busy_connections++;
3386 "%s has new %s\n",
3387 GCT_2s (t),
3388 GCC_2s (ct->cc));
3389 return GNUNET_OK;
3390}

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 3400 of file gnunet-service-cadet_tunnels.c.

3402{
3403 struct CadetTunnel *t = ct->t;
3404 uint16_t size = ntohs (msg->header.size);
3405 char cbuf[size] GNUNET_ALIGN;
3406 ssize_t decrypted_size;
3407
3409 "%s received %u bytes of encrypted data in state %d\n",
3410 GCT_2s (t),
3411 (unsigned int) size,
3412 t->estate);
3413
3414 switch (t->estate)
3415 {
3418 /* We did not even SEND our KX, how can the other peer
3419 send us encrypted data? Must have been that we went
3420 down and the other peer still things we are up.
3421 Let's send it KX back. */
3423 "# received encrypted without any KX",
3424 1,
3425 GNUNET_NO);
3426 if (NULL != t->kx_task)
3427 {
3428 GNUNET_SCHEDULER_cancel (t->kx_task);
3429 t->kx_task = NULL;
3430 }
3431 send_kx (t,
3432 ct,
3433 &t->ax);
3434 return;
3435
3437 /* We send KX, and other peer send KX to us at the same time.
3438 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3440 "# received encrypted without KX_AUTH",
3441 1,
3442 GNUNET_NO);
3443 if (NULL != t->kx_task)
3444 {
3445 GNUNET_SCHEDULER_cancel (t->kx_task);
3446 t->kx_task = NULL;
3447 }
3448 send_kx_auth (t,
3449 ct,
3450 &t->ax,
3451 GNUNET_YES);
3452 return;
3453
3455 /* We did not get the KX of the other peer, but that
3456 might have been lost. Send our KX again immediately. */
3458 "# received encrypted without KX",
3459 1,
3460 GNUNET_NO);
3461 if (NULL != t->kx_task)
3462 {
3463 GNUNET_SCHEDULER_cancel (t->kx_task);
3464 t->kx_task = NULL;
3465 }
3466 send_kx (t,
3467 ct,
3468 &t->ax);
3469 return;
3470
3472 /* Great, first payload, we might graduate to OK! */
3474 /* We are up and running, all good. */
3475 break;
3476 }
3477
3478 decrypted_size = -1;
3479 if (CADET_TUNNEL_KEY_OK == t->estate)
3480 {
3481 /* We have well-established key material available,
3482 try that. (This is the common case.) */
3483 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3484 cbuf,
3485 msg,
3486 size);
3487 }
3488
3489 if ((-1 == decrypted_size) &&
3490 (NULL != t->unverified_ax))
3491 {
3492 /* We have un-authenticated KX material available. We should try
3493 this as a back-up option, in case the sender crashed and
3494 switched keys. */
3495 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3496 cbuf,
3497 msg,
3498 size);
3499 if (-1 != decrypted_size)
3500 {
3501 /* It worked! Treat this as authentication of the AX data! */
3502 cleanup_ax (&t->ax);
3503 t->ax = *t->unverified_ax;
3504 GNUNET_free (t->unverified_ax);
3505 t->unverified_ax = NULL;
3506 }
3507 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3508 {
3509 /* First time it worked, move tunnel into production! */
3512 if (NULL != t->send_task)
3513 GNUNET_SCHEDULER_cancel (t->send_task);
3515 t);
3516 }
3517 }
3518 if (NULL != t->unverified_ax)
3519 {
3520 /* We had unverified KX material that was useless; so increment
3521 counter and eventually move to ignore it. Note that we even do
3522 this increment if we successfully decrypted with the old KX
3523 material and thus didn't even both with the new one. This is
3524 the ideal case, as a malicious injection of bogus KX data
3525 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3527 "Failed to decrypt message with unverified KX data %u times\n",
3528 t->unverified_attempts);
3529 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3530 {
3531 cleanup_ax (t->unverified_ax);
3532 GNUNET_free (t->unverified_ax);
3533 t->unverified_ax = NULL;
3534 }
3535 }
3536
3537 if (-1 == decrypted_size)
3538 {
3539 /* Decryption failed for good, complain. */
3541 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3542 GCT_2s (t));
3544 "# unable to decrypt",
3545 1,
3546 GNUNET_NO);
3547 if (NULL != t->kx_task)
3548 {
3549 GNUNET_SCHEDULER_cancel (t->kx_task);
3550 t->kx_task = NULL;
3551 }
3552 send_kx (t,
3553 ct,
3554 &t->ax);
3555 return;
3556 }
3558 "# decrypted bytes",
3559 decrypted_size,
3560 GNUNET_NO);
3561
3562 /* The MST will ultimately call #handle_decrypted() on each message. */
3563 t->current_ct = ct;
3566 cbuf,
3567 decrypted_size,
3568 GNUNET_YES,
3569 GNUNET_NO));
3570 t->current_ct = NULL;
3571}

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 3575 of file gnunet-service-cadet_tunnels.c.

3580{
3581 struct CadetTunnelQueueEntry *tq;
3582 uint16_t payload_size;
3583 struct GNUNET_MQ_Envelope *env;
3585 struct CadetChannel *ch;
3586
3587 if (NULL != ctn)
3588 {
3589 ch = lookup_channel (t,
3590 *ctn);
3591 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3592 {
3593 GNUNET_break (0);
3594 return NULL;
3595 }
3596 }
3597
3598 if (CADET_TUNNEL_KEY_OK != t->estate)
3599 {
3600 GNUNET_break (0);
3601 return NULL;
3602 }
3603 payload_size = ntohs (message->size);
3605 "Encrypting %u bytes for %s\n",
3606 (unsigned int) payload_size,
3607 GCT_2s (t));
3608 env = GNUNET_MQ_msg_extra (ax_msg,
3609 payload_size,
3611 t_ax_encrypt (&t->ax,
3612 &ax_msg[1],
3613 message,
3614 payload_size);
3616 "# encrypted bytes",
3617 payload_size,
3618 GNUNET_NO);
3619 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3620 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3621 /* FIXME: we should do this once, not once per message;
3622 this is a point multiplication, and DHRs does not
3623 change all the time. */
3625 &ax_msg->ax_header.DHRs);
3626 t_h_encrypt (&t->ax,
3627 ax_msg);
3628 t_hmac (&ax_msg->ax_header,
3629 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3630 0,
3631 &t->ax.HKs,
3632 &ax_msg->hmac);
3633
3634 tq = GNUNET_malloc (sizeof(*tq));
3635 tq->t = t;
3636 tq->env = env;
3637 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3638 tq->cont = cont;
3639 tq->cont_cls = cont_cls;
3641 t->tq_tail,
3642 tq);
3643 if (NULL != t->send_task)
3644 GNUNET_SCHEDULER_cancel (t->send_task);
3645 t->send_task
3647 t);
3648 return tq;
3649}

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(), GNUNET_CADET_TunnelEncryptedMessage::hmac, LOG, lookup_channel(), GNUNET_CADET_AxHeader::Ns, GNUNET_CADET_AxHeader::PNs, GNUNET_MessageHeader::size, stats, t, CadetTunnelQueueEntry::t, t_ax_encrypt(), t_h_encrypt(), t_hmac(), 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 3653 of file gnunet-service-cadet_tunnels.c.

3654{
3655 struct CadetTunnel *t = tq->t;
3656
3658 t->tq_tail,
3659 tq);
3660 GNUNET_MQ_discard (tq->env);
3661 GNUNET_free (tq);
3662}

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 3673 of file gnunet-service-cadet_tunnels.c.

3676{
3677 struct CadetTConnection *n;
3678
3679 for (struct CadetTConnection *ct = t->connection_ready_head;
3680 NULL != ct;
3681 ct = n)
3682 {
3683 n = ct->next;
3684 iter (iter_cls,
3685 ct);
3686 }
3687 for (struct CadetTConnection *ct = t->connection_busy_head;
3688 NULL != ct;
3689 ct = n)
3690 {
3691 n = ct->next;
3692 iter (iter_cls,
3693 ct);
3694 }
3695}

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 3724 of file gnunet-service-cadet_tunnels.c.

3727{
3728 struct ChanIterCls *ctx = cls;
3729 struct CadetChannel *ch = value;
3730
3731 ctx->iter (ctx->iter_cls,
3732 ch);
3733 return GNUNET_OK;
3734}

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 3745 of file gnunet-service-cadet_tunnels.c.

3748{
3749 struct ChanIterCls ctx;
3750
3751 ctx.iter = iter;
3752 ctx.iter_cls = iter_cls;
3755 &ctx);
3756}

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 3768 of file gnunet-service-cadet_tunnels.c.

3771{
3772 const enum GNUNET_ErrorType *level = cls;
3773 struct CadetChannel *ch = value;
3774
3775 GCCH_debug (ch, *level);
3776 return GNUNET_OK;
3777}

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 3791 of file gnunet-service-cadet_tunnels.c.

3793{
3794#if ! defined(GNUNET_CULL_LOGGING)
3795 struct CadetTConnection *iter_c;
3796 int do_log;
3797
3799 "cadet-tun",
3800 __FILE__, __FUNCTION__, __LINE__);
3801 if (0 == do_log)
3802 return;
3803
3804 LOG2 (level,
3805 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3806 GCT_2s (t),
3807 estate2s (t->estate),
3808 t->tq_len,
3810 LOG2 (level,
3811 "TTT channels:\n");
3814 &level);
3815 LOG2 (level,
3816 "TTT connections:\n");
3817 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3818 GCC_debug (iter_c->cc,
3819 level);
3820 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3821 GCC_debug (iter_c->cc,
3822 level);
3823
3824 LOG2 (level,
3825 "TTT TUNNEL END\n");
3826#endif
3827}

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: