GNUnet 0.28.1-dev.4-47-g3e168ca2d
 
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   0x08000000
 
#define LOG2(level, ...)
 

Typedefs

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

Functions

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

Detailed Description

Information we track per tunnel.

Author
Bartlomiej Polot
Christian Grothoff

FIXME:

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

Definition in file gnunet-service-cadet_tunnels.c.

Macro Definition Documentation

◆ LOG

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

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

◆ MAX_UNVERIFIED_ATTEMPTS

#define MAX_UNVERIFIED_ATTEMPTS   16

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

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

◆ IDLE_DESTROY_DELAY

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

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

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

84{
89
94
99
104
109
113 unsigned int Kn;
114};
115
116
121{
128
133
138
143
148
155
162
168
176
181
186
191
197
203
207 unsigned int skipped;
208
212 uint32_t Ns;
213
217 uint32_t Nr;
218
222 uint32_t PNs;
223
227 int ratchet_flag;
228
239 int ratchet_allowed;
240
253 unsigned int ratchet_counter;
254};
255
256
263typedef void
264(*CadetTunnelAxolotlCallback) (void *cls,
266
267
271struct CadetTunnelAsync
272{
276 struct CadetTunnelAxolotl ax;
277
282
287
292
297 struct GNUNET_HashCode auth;
298
303 uint32_t flags;
304
309
313 void *cb_cls;
314
319};
320
321
326{
331
336
340 struct CadetTunnel *t;
341
346
350 void *cont_cls;
351
355 struct GNUNET_MQ_Envelope *env;
356
362};
363
364
368struct CadetTunnel
369{
373 struct CadetPeer *destination;
374
380
385
390
394 struct CadetTunnelAxolotl ax;
395
404
408 struct CadetTunnelAsync as;
409
414
419
424
429
434
438 struct GNUNET_MQ_Handle *mq;
439
444
449
454
459
465
470
475
480
487
492
497
501 unsigned int num_ready_connections;
502
506 unsigned int num_busy_connections;
507
513 unsigned int unverified_attempts;
514
518 unsigned int tq_len;
519
524
529};
530
531
538int
539GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
540{
541 const struct GNUNET_PeerIdentity *my_identity;
542
545
546 if (0 > GNUNET_memcmp (my_identity, other))
547 return GNUNET_YES;
548 else if (0 < GNUNET_memcmp (my_identity, other))
549 return GNUNET_NO;
550 else
551 {
552 GNUNET_break_op (0);
553 return GNUNET_SYSERR;
554 }
555}
556
557
564static void
566{
567 struct CadetTunnel *t = ct->t;
568
570 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
571 t->connection_ready_tail,
572 ct);
573 GNUNET_assert (0 < t->num_ready_connections);
574 t->num_ready_connections--;
575 ct->is_ready = GNUNET_NO;
576 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
577 t->connection_busy_tail,
578 ct);
579 t->num_busy_connections++;
580}
581
582
590const char *
591GCT_2s (const struct CadetTunnel *t)
592{
593 static char buf[64];
594
595 if (NULL == t)
596 return "Tunnel(NULL)";
597 GNUNET_snprintf (buf,
598 sizeof(buf),
599 "Tunnel %s",
600 GNUNET_i2s (GCP_get_id (t->destination)));
601 return buf;
602}
603
604
612static const char *
614{
615 static char buf[32];
616
617 switch (es)
618 {
620 return "CADET_TUNNEL_KEY_UNINITIALIZED";
622 return "CADET_TUNNEL_KEY_AX_RECV";
624 return "CADET_TUNNEL_KEY_AX_SENT";
626 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
628 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
630 return "CADET_TUNNEL_KEY_OK";
631 }
632 GNUNET_snprintf (buf,
633 sizeof(buf),
634 "%u (UNKNOWN STATE)",
635 es);
636 return buf;
637}
638
639
646struct CadetPeer *
648{
649 return t->destination;
650}
651
652
653unsigned int
655{
656 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
657}
658
659
667static struct CadetChannel *
670{
671 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
672 ntohl (ctn.cn));
673}
674
675
676unsigned int
678{
679 return t->num_ready_connections + t->num_busy_connections;
680}
681
682
690static struct CadetTConnection *
692{
693 struct CadetTConnection *hd = t->connection_ready_head;
694
695 GNUNET_assert ((NULL == hd) ||
696 (GNUNET_YES == hd->is_ready));
697 return hd;
698}
699
700
710{
711 return t->estate;
712}
713
714
723static void
724trigger_transmissions (void *cls);
725
726
727/* ************************************** start core crypto ***************************** */
728
729
735static void
737{
739 "Creating new ephemeral ratchet key (DHRs)\n");
741}
742
743
752static void
754 struct GNUNET_HashCode *hash,
755 const void *source,
756 unsigned int len)
757{
758 static const char ctx[] = "axolotl HMAC-HASH";
759 struct GNUNET_CRYPTO_AuthKey auth_key;
760
762 &auth_key,
763 sizeof auth_key,
764 ctx,
765 sizeof(ctx),
766 key,
767 sizeof *key);
768 GNUNET_CRYPTO_hmac (&auth_key,
769 source,
770 len,
771 hash);
772}
773
774
783static void
785 struct GNUNET_CRYPTO_AeadSecretKey *out,
786 const void *source,
787 unsigned int len)
788{
789 static const char ctx[] = "axolotl derive key";
790 struct GNUNET_HashCode h;
791
793 &h,
794 source,
795 len);
797 out, sizeof(*out),
798 ctx, sizeof(ctx),
799 &h, sizeof(h));
800}
801
802
811static void
813 void *dst,
814 const void *src,
815 size_t size)
816{
818 struct GNUNET_CRYPTO_AeadNonce iv;
820
821 ax->ratchet_counter++;
822 if ((GNUNET_YES == ax->ratchet_allowed) &&
823 ((ratchet_messages <= ax->ratchet_counter) ||
826 {
828 }
829 if (GNUNET_YES == ax->ratchet_flag)
830 {
831 /* Advance ratchet */
832 struct GNUNET_CRYPTO_AeadSecretKey keys[3];
833 struct GNUNET_HashCode dh;
834 struct GNUNET_HashCode hmac;
835 static const char ctx[] = "axolotl ratchet";
836
837 new_ephemeral (ax);
838 ax->HKs = ax->NHKs;
839
840 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
842 &ax->DHRr,
843 &dh);
844 t_ax_hmac_hash (&ax->RK,
845 &hmac,
846 &dh,
847 sizeof(dh));
849 keys, sizeof(keys),
850 ctx, sizeof(ctx),
851 &hmac, sizeof(hmac));
852 ax->RK = keys[0];
853 ax->NHKs = keys[1];
854 ax->CKs = keys[2];
855
856 ax->PNs = ax->Ns;
857 ax->Ns = 0;
860 ax->ratchet_counter = 0;
864 }
865
867 &MK,
868 "0",
869 1);
870
872 sizeof iv,
873 NULL,
874 0,
875 &MK,
876 sizeof MK);
877
878 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) dst)[size];
880 src,
881 0,
882 NULL,
883 &MK,
884 &iv,
885 dst,
886 mac));
888 &ax->CKs,
889 "1",
890 1);
891}
892
893
904 void *dst,
905 const void *src,
906 size_t size)
907{
909 struct GNUNET_CRYPTO_AeadNonce iv;
911 size_t macoffset;
912
913 /* A short (or absent) payload is what a remote peer sends, not something
914 we may compute @a macoffset from: the subtraction below underflows. */
915 if (size < sizeof(struct GNUNET_MessageHeader)
916 + sizeof(struct GNUNET_CRYPTO_AeadMac))
917 {
918 GNUNET_break_op (0);
919 return GNUNET_SYSERR;
920 }
921 macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
923 &MK,
924 "0",
925 1);
926
928 sizeof iv,
929 NULL,
930 0,
931 &MK,
932 sizeof MK);
933 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) src)[macoffset];
934 /* Failing to authenticate is what a corrupt or forged ciphertext looks
935 like, and the callers all handle it -- #try_old_ax_keys() returns -1 on
936 exactly this. Aborting here let any peer take the service down. */
938 src,
939 0,
940 NULL,
941 &MK,
942 &iv,
943 mac,
944 dst))
945 return GNUNET_SYSERR;
946 /* Only a message we actually accepted advances the receive chain. */
948 &ax->CKr,
949 "1",
950 1);
951 return GNUNET_OK;
952}
953
954
961static void
964 size_t additional_data_size,
965 const unsigned char *additional_data)
966{
967 struct GNUNET_CRYPTO_AeadNonce nonce;
968
970 sizeof nonce,
971 NULL,
972 0,
973 &ax->HKs,
974 sizeof ax->HKs);
976 ,
977 (unsigned char*) &msg
978 ->ax_header,
979 additional_data_size,
980 additional_data,
981 &ax->HKs,
982 &nonce,
983 &msg->ax_header,
984 &msg->mac));
985}
986
987
999 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1000 size_t esize,
1002{
1003 struct GNUNET_CRYPTO_AeadNonce iv;
1004
1006 sizeof iv,
1007 NULL,
1008 0,
1009 hkr,
1010 sizeof *hkr);
1011
1012
1014 (unsigned char*) &src->ax_header,
1015 esize,
1016 (unsigned char*) &src[1],
1017 hkr,
1018 &iv,
1019 &dst->mac,
1020 &dst->ax_header);
1021}
1022
1023
1030static void
1032 struct CadetTunnelSkippedKey *key)
1033{
1035 ax->skipped_tail,
1036 key);
1037 GNUNET_free (key);
1038 ax->skipped--;
1039}
1040
1041
1052static ssize_t
1054 void *dst,
1055 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1056 size_t size)
1057{
1058 struct CadetTunnelSkippedKey *key;
1059 struct GNUNET_CRYPTO_AeadNonce iv;
1060 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1061 struct GNUNET_CRYPTO_AeadSecretKey *valid_HK;
1062 size_t esize;
1063 size_t len;
1064 unsigned int N;
1065 const unsigned char *payload;
1066
1068 "Trying skipped keys\n");
1069 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1070 len = esize;
1071 /* @a size comes off the wire; #check_tunnel_encrypted() used to accept
1072 anything, so this must not be an assertion. */
1073 if ((size <= sizeof(struct GNUNET_CADET_TunnelEncryptedMessage)) ||
1074 (len < sizeof(struct GNUNET_MessageHeader)
1075 + sizeof(struct GNUNET_CRYPTO_AeadMac)))
1076 {
1077 GNUNET_break_op (0);
1078 return -1;
1079 }
1080 payload = (const unsigned char *) &src[1];
1081
1082 /* Find a correct Header Key */
1083 valid_HK = NULL;
1084 for (key = ax->skipped_head; NULL != key; key = key->next)
1085 {
1086 /* Try decrypt header */
1087 if (GNUNET_OK == t_h_decrypt (&key->HK,
1088 src,
1089 esize,
1090 &plaintext_header))
1091 {
1092 valid_HK = &key->HK;
1093 break;
1094 }
1095 }
1096 if (NULL == key)
1097 return -1;
1098
1099 /* Find the correct message key */
1100 N = ntohl (plaintext_header.ax_header.Ns);
1101 while ((NULL != key) &&
1102 (N != key->Kn))
1103 key = key->next;
1104 if ((NULL == key) ||
1105 (0 != GNUNET_memcmp (&key->HK,
1106 valid_HK)))
1107 return -1;
1108
1109 /* Decrypt payload */
1111 sizeof iv,
1112 NULL,
1113 0,
1114 &key->MK,
1115 sizeof key->MK);
1116
1117 /* NOTE: the MAC sits at the end of the *payload*. Indexing @a src, a
1118 `struct GNUNET_CADET_TunnelEncryptedMessage *', scaled the offset by the
1119 size of that struct and read far past the end of the message -- so this
1120 never authenticated anything it was given and no skipped key ever
1121 worked. */
1123 len,
1124 payload,
1125 0,
1126 NULL,
1127 &key->MK,
1128 &iv,
1129 (const struct GNUNET_CRYPTO_AeadMac*)
1130 &payload[len - sizeof (struct GNUNET_CRYPTO_AeadMac)],
1131 dst))
1132 {
1133 return -1;
1134 }
1136 key);
1137 return len - sizeof (struct GNUNET_CRYPTO_AeadMac);
1138}
1139
1140
1147static void
1149 const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
1150{
1151 struct CadetTunnelSkippedKey *key;
1152
1154 key->timestamp = GNUNET_TIME_absolute_get ();
1155 key->Kn = ax->Nr;
1156 key->HK = ax->HKr;
1157 t_hmac_derive_key (&ax->CKr,
1158 &key->MK,
1159 "0",
1160 1);
1161 t_hmac_derive_key (&ax->CKr,
1162 &ax->CKr,
1163 "1",
1164 1);
1166 ax->skipped_tail,
1167 key);
1168 ax->skipped++;
1169 ax->Nr++;
1170}
1171
1172
1183static int
1185 const struct GNUNET_CRYPTO_AeadSecretKey *HKr,
1186 uint32_t Np)
1187{
1188 int gap;
1189
1190 gap = Np - ax->Nr;
1192 "Storing skipped keys [%u, %u)\n",
1193 ax->Nr,
1194 Np);
1195 if (MAX_KEY_GAP < gap)
1196 {
1197 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1198 /* TODO: start new key exchange on return */
1199 GNUNET_break_op (0);
1201 "Got message %u, expected %u+\n",
1202 Np,
1203 ax->Nr);
1204 return GNUNET_SYSERR;
1205 }
1206 if (0 > gap)
1207 {
1208 /* Delayed message: don't store keys, flag to try old keys. */
1209 return GNUNET_SYSERR;
1210 }
1211
1212 while (ax->Nr < Np)
1214 HKr);
1215
1216 while (ax->skipped > MAX_SKIPPED_KEYS)
1218 ax->skipped_tail);
1219 return GNUNET_OK;
1220}
1221
1222
1233static ssize_t
1235 void *dst,
1236 const struct
1238 size_t size)
1239{
1240 struct GNUNET_HashCode hmac;
1241 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1242 uint32_t Np;
1243 uint32_t PNp;
1244 size_t esize; /* Size of encrypted payload */
1245
1246 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1247
1248 if (GNUNET_OK == t_h_decrypt (&ax->HKr,
1249 src,
1250 esize,
1251 &plaintext_header))
1252 {
1253 Np = ntohl (plaintext_header.ax_header.Ns);
1254 PNp = ntohl (plaintext_header.ax_header.PNs);
1255 }
1256 else
1257 {
1258 static const char ctx[] = "axolotl ratchet";
1259 struct GNUNET_CRYPTO_AeadSecretKey keys[3]; /* RKp, NHKp, CKp */
1261 struct GNUNET_HashCode dh;
1262 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1263
1264 /* Try Next HK */
1265 if (GNUNET_OK == t_h_decrypt (&ax->NHKr,
1266 src,
1267 esize,
1268 &plaintext_header))
1269 {
1270 /* Try the skipped keys, if that fails, we're out of luck. */
1271 return try_old_ax_keys (ax,
1272 dst,
1273 src,
1274 size);
1275 }
1276 HK = ax->HKr;
1277 ax->HKr = ax->NHKr;
1278 Np = ntohl (plaintext_header.ax_header.Ns);
1279 PNp = ntohl (plaintext_header.ax_header.PNs);
1280 DHRp = &plaintext_header.ax_header.DHRs;
1281 store_ax_keys (ax,
1282 &HK,
1283 PNp);
1284
1285 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1287 DHRp,
1288 &dh);
1289 t_ax_hmac_hash (&ax->RK,
1290 &hmac,
1291 &dh, sizeof(dh));
1293 keys, sizeof(keys),
1294 ctx, sizeof(ctx),
1295 &hmac, sizeof(hmac));
1296
1297 /* Commit "purported" keys */
1298 ax->RK = keys[0];
1299 ax->NHKr = keys[1];
1300 ax->CKr = keys[2];
1301 ax->DHRr = *DHRp;
1302 ax->Nr = 0;
1304
1305 }
1306 if ((Np != ax->Nr) &&
1307 (GNUNET_OK != store_ax_keys (ax,
1308 &ax->HKr,
1309 Np)))
1310 {
1311 /* Try the skipped keys, if that fails, we're out of luck. */
1312 return try_old_ax_keys (ax,
1313 dst,
1314 src,
1315 size);
1316 }
1317
1318 if (GNUNET_OK != t_ax_decrypt (ax,
1319 dst,
1320 &src[1],
1321 esize))
1322 return -1;
1323 ax->Nr = Np + 1;
1324 return esize - sizeof (struct GNUNET_CRYPTO_AeadMac);
1325}
1326
1327
1337static int
1338notify_tunnel_up_cb (void *cls,
1339 uint32_t key,
1340 void *value)
1341{
1342 struct CadetChannel *ch = value;
1343
1345 return GNUNET_OK;
1346}
1347
1348
1356void
1359{
1360 enum CadetTunnelEState old = t->estate;
1361
1362 t->estate = state;
1364 "%s estate changed from %s to %s\n",
1365 GCT_2s (t),
1366 estate2s (old),
1367 estate2s (state));
1368
1369 if ((CADET_TUNNEL_KEY_OK != old) &&
1370 (CADET_TUNNEL_KEY_OK == t->estate))
1371 {
1372 if (NULL != t->kx_task)
1373 {
1374 GNUNET_SCHEDULER_cancel (t->kx_task);
1375 t->kx_task = NULL;
1376 }
1377 /* notify all channels that have been waiting */
1380 t);
1381 if (NULL != t->send_task)
1382 GNUNET_SCHEDULER_cancel (t->send_task);
1384 t);
1385 }
1386}
1387
1388
1397static void
1398send_kx (struct CadetTunnel *t,
1399 struct CadetTConnection *ct,
1400 struct CadetTunnelAxolotl *ax)
1401{
1402 struct CadetConnection *cc;
1403 struct GNUNET_MQ_Envelope *env;
1406
1407 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1408 return; /* only Alice may send KX */
1409 if ((NULL == ct) ||
1410 (GNUNET_NO == ct->is_ready))
1411 ct = get_ready_connection (t);
1412 if (NULL == ct)
1413 {
1415 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1416 GCT_2s (t),
1417 estate2s (t->estate));
1418 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1419 return;
1420 }
1421 cc = ct->cc;
1424 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1425 msg->flags = htonl (flags);
1426 msg->cid = *GCC_get_id (cc);
1428 &msg->ephemeral_key);
1429#if DEBUG_KX
1430 msg->ephemeral_key_XXX = ax->kx_0;
1431#endif
1433 "Sending KX message to %s with ephemeral %s on CID %s\n",
1434 GCT_2s (t),
1435 GNUNET_e2s (&msg->ephemeral_key),
1436 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1438 &msg->ratchet_key);
1440 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1441 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1442 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1445 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1448 GCC_transmit (cc,
1449 env);
1451 "# KX transmitted",
1452 1,
1453 GNUNET_NO);
1454}
1455
1456
1467static void
1468send_kx_auth (struct CadetTunnel *t,
1469 struct CadetTConnection *ct,
1470 struct CadetTunnelAxolotl *ax,
1471 int force_reply)
1472{
1473 struct CadetConnection *cc;
1474 struct GNUNET_MQ_Envelope *env;
1476 enum GNUNET_CADET_KX_Flags flags;
1477
1478 if ((NULL == ct) ||
1479 (GNUNET_NO == ct->is_ready))
1480 ct = get_ready_connection (t);
1481 if (NULL == ct)
1482 {
1484 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1485 GCT_2s (t));
1486 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1487 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1488 return;
1489 }
1490 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1491 cc = ct->cc;
1495 if (GNUNET_YES == force_reply)
1497 msg->kx.flags = htonl (flags);
1498 msg->kx.cid = *GCC_get_id (cc);
1500 &msg->kx.ephemeral_key);
1502 &msg->kx.ratchet_key);
1503#if DEBUG_KX
1504 msg->kx.ephemeral_key_XXX = ax->kx_0;
1505 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1506#endif
1508 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1509 GCT_2s (t),
1510 GNUNET_e2s (&msg->kx.ephemeral_key),
1511 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1512
1513 /* Compute authenticator (this is the main difference to #send_kx()) */
1514 GNUNET_CRYPTO_hash (&ax->RK,
1515 sizeof(ax->RK),
1516 &msg->auth);
1517 /* Compute when to be triggered again; actual job will
1518 be scheduled via #connection_ready_cb() */
1519 t->kx_retry_delay
1520 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1521 t->next_kx_attempt
1522 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1523
1524 /* Send via cc, mark it as unready */
1526
1527 /* Update state machine, unless we are already OK */
1528 if (CADET_TUNNEL_KEY_OK != t->estate)
1531 GCC_transmit (cc,
1532 env);
1534 "# KX_AUTH transmitted",
1535 1,
1536 GNUNET_NO);
1537}
1538
1539
1545static void
1546cleanup_ax (struct CadetTunnelAxolotl *ax)
1547{
1548 while (NULL != ax->skipped_head)
1550 ax->skipped_head);
1551 GNUNET_assert (0 == ax->skipped);
1554}
1555
1556
1568static void
1569update_ax_by_kx (void *cls,
1570 const struct GNUNET_HashCode *key_result)
1571{
1572 struct CadetTunnelAsync *as;
1573 struct GNUNET_HashCode key_material[3];
1574 struct GNUNET_CRYPTO_AeadSecretKey keys[5];
1575 struct CadetTunnelAxolotl *ax;
1576 const struct GNUNET_PeerIdentity *pid;
1577 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1578 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1579 const char salt[] = "CADET Axolotl salt";
1580 int am_I_alice;
1581
1582 as = cls;
1583 ax = &as->ax;
1584 pid = &as->peer_id;
1585 ephemeral_key = &as->ephemeral_key;
1586 ratchet_key = &as->ratchet_key;
1587
1588 as->ecdh_op = NULL;
1589
1591 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1592 GNUNET_e2s (ephemeral_key));
1593
1594 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1595 {
1596 GNUNET_break_op (0);
1597 if (as->cb)
1598 as->cb (as->cb_cls, GNUNET_SYSERR);
1599 return;
1600 }
1601
1602 if (0 == GNUNET_memcmp (&ax->DHRr,
1603 ratchet_key))
1604 {
1606 "# Ratchet key already known",
1607 1,
1608 GNUNET_NO);
1610 "Ratchet key already known. Ignoring KX.\n");
1611 if (as->cb)
1612 as->cb (as->cb_cls, GNUNET_NO);
1613 return;
1614 }
1615
1616 ax->DHRr = *ratchet_key;
1617 ax->last_ephemeral = *ephemeral_key;
1618 /* ECDH A B0 */
1619 if (GNUNET_YES == am_I_alice)
1620 {
1621 GNUNET_memcpy (&key_material[0], key_result,
1622 sizeof (*key_result));
1623 }
1624 else
1625 {
1626 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1627 &pid->public_key, /* A */
1628 &key_material[0]);
1629 }
1630 /* ECDH A0 B */
1631 if (GNUNET_YES == am_I_alice)
1632 {
1633 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1634 &pid->public_key, /* B */
1635 &key_material[1]);
1636 }
1637 else
1638 {
1639 GNUNET_memcpy (&key_material[1], key_result,
1640 sizeof (*key_result));
1641 }
1642
1643 /* ECDH A0 B0 */
1644 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1645 ephemeral_key, /* B0 or A0 */
1646 &key_material[2]);
1647 /* KDF */
1649 keys, sizeof(keys),
1650 salt, sizeof(salt),
1651 &key_material, sizeof(key_material));
1652
1653 if (0 == memcmp (&ax->RK,
1654 &keys[0],
1655 sizeof(ax->RK)))
1656 {
1658 "Root key already known. Ignoring KX.\n");
1660 "# Root key already known",
1661 1,
1662 GNUNET_NO);
1663 if (as->cb)
1664 as->cb (as->cb_cls, GNUNET_NO);
1665 return;
1666 }
1667
1668 ax->RK = keys[0];
1669 if (GNUNET_YES == am_I_alice)
1670 {
1671 ax->HKr = keys[1];
1672 ax->NHKs = keys[2];
1673 ax->NHKr = keys[3];
1674 ax->CKr = keys[4];
1676 }
1677 else
1678 {
1679 ax->HKs = keys[1];
1680 ax->NHKr = keys[2];
1681 ax->NHKs = keys[3];
1682 ax->CKs = keys[4];
1683 ax->ratchet_flag = GNUNET_NO;
1686 ratchet_time);
1687 }
1688
1689 if (as->cb)
1690 as->cb (as->cb_cls, GNUNET_OK);
1691}
1692
1693
1699static void
1700retry_kx (void *cls)
1701{
1702 struct CadetTunnel *t = cls;
1703 struct CadetTunnelAxolotl *ax;
1704
1705 t->kx_task = NULL;
1707 "Trying to make KX progress on %s in state %s\n",
1708 GCT_2s (t),
1709 estate2s (t->estate));
1710 switch (t->estate)
1711 {
1712 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1713 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1714 send_kx (t,
1715 NULL,
1716 &t->ax);
1717 break;
1718
1721 /* We are responding, so only require reply
1722 if WE have a channel waiting. */
1723 if (NULL != t->unverified_ax)
1724 {
1725 /* Send AX_AUTH so we might get this one verified */
1726 ax = t->unverified_ax;
1727 }
1728 else
1729 {
1730 /* How can this be? */
1731 GNUNET_break (0);
1732 ax = &t->ax;
1733 }
1734 send_kx_auth (t,
1735 NULL,
1736 ax,
1737 (0 == GCT_count_channels (t))
1738 ? GNUNET_NO
1739 : GNUNET_YES);
1740 break;
1741
1743 /* We are responding, so only require reply
1744 if WE have a channel waiting. */
1745 if (NULL != t->unverified_ax)
1746 {
1747 /* Send AX_AUTH so we might get this one verified */
1748 ax = t->unverified_ax;
1749 }
1750 else
1751 {
1752 /* How can this be? */
1753 GNUNET_break (0);
1754 ax = &t->ax;
1755 }
1756 send_kx_auth (t,
1757 NULL,
1758 ax,
1759 (0 == GCT_count_channels (t))
1760 ? GNUNET_NO
1761 : GNUNET_YES);
1762 break;
1763
1765 /* Must have been the *other* peer asking us to
1766 respond with a KX_AUTH. */
1767 if (NULL != t->unverified_ax)
1768 {
1769 /* Sending AX_AUTH in response to AX so we might get this one verified */
1770 ax = t->unverified_ax;
1771 }
1772 else
1773 {
1774 /* Sending AX_AUTH in response to AX_AUTH */
1775 ax = &t->ax;
1776 }
1777 send_kx_auth (t,
1778 NULL,
1779 ax,
1780 GNUNET_NO);
1781 break;
1782 }
1783}
1784
1785
1792static void
1793cont_GCT_handle_kx (void *cls,
1795{
1796 struct CadetTunnel *t = cls;
1797
1798 if (t->unverified_ax)
1799 *(t->unverified_ax) = t->as.ax;
1800
1802 "Continue handling KX message from %s from %s\n",
1803 GCT_2s (t),
1804 GNUNET_i2s (GCP_get_id (t->destination)));
1805
1807 if (GNUNET_OK != ret)
1808 {
1810 "# Useless KX",
1811 1,
1812 GNUNET_NO);
1813 return; /* duplicate KX, nothing to do */
1814 }
1815 /* move ahead in our state machine */
1816 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1819 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1822
1823 /* KX is still not done, try again our end. */
1824 if (CADET_TUNNEL_KEY_OK != t->estate)
1825 {
1826 if (NULL != t->kx_task)
1827 GNUNET_SCHEDULER_cancel (t->kx_task);
1828 t->kx_task
1830 t);
1831 }
1832}
1833
1834
1841void
1844{
1845 struct CadetTunnel *t = ct->t;
1846
1848 "# KX received",
1849 1,
1850 GNUNET_NO);
1851 if (GNUNET_YES ==
1852 GCT_alice_or_betty (GCP_get_id (t->destination)))
1853 {
1854 /* Betty/Bob is not allowed to send KX! */
1855 GNUNET_break_op (0);
1856 return;
1857 }
1859 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1860 GCT_2s (t),
1861 GNUNET_e2s (&msg->ephemeral_key),
1862 GNUNET_i2s (GCP_get_id (t->destination)),
1863 GCC_2s (ct->cc));
1864#if 1
1865 if ((0 ==
1866 memcmp (&t->ax.DHRr,
1867 &msg->ratchet_key,
1868 sizeof(msg->ratchet_key))) &&
1869 (0 ==
1870 memcmp (&t->ax.last_ephemeral,
1871 &msg->ephemeral_key,
1872 sizeof(msg->ephemeral_key))))
1873
1874 {
1876 "# Duplicate KX received",
1877 1,
1878 GNUNET_NO);
1879 send_kx_auth (t,
1880 ct,
1881 &t->ax,
1882 GNUNET_NO);
1883 return;
1884 }
1885#endif
1886 /* We only keep ONE unverified KX around, so if there is an existing one,
1887 clean it up. */
1888 if (NULL != t->unverified_ax)
1889 {
1890 if ((0 ==
1891 memcmp (&t->unverified_ax->DHRr,
1892 &msg->ratchet_key,
1893 sizeof(msg->ratchet_key))) &&
1894 (0 ==
1895 memcmp (&t->unverified_ax->last_ephemeral,
1896 &msg->ephemeral_key,
1897 sizeof(msg->ephemeral_key))))
1898 {
1900 "# Duplicate unverified KX received",
1901 1,
1902 GNUNET_NO);
1903#if 1
1904 send_kx_auth (t,
1905 ct,
1906 t->unverified_ax,
1907 GNUNET_NO);
1908 return;
1909#endif
1910 }
1911 if ((t->as.ecdh_op) &&
1912 (0 ==
1913 memcmp (&t->as.ratchet_key,
1914 &msg->ratchet_key,
1915 sizeof(msg->ratchet_key))) &&
1916 (0 ==
1917 memcmp (&t->as.ephemeral_key,
1918 &msg->ephemeral_key,
1919 sizeof(msg->ephemeral_key))))
1920 {
1922 "Waiting for previous ECDH operation\n");
1923 return;
1924 }
1926 "Dropping old unverified KX state.\n");
1928 "# Unverified KX dropped for fresh KX",
1929 1,
1930 GNUNET_NO);
1931 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1932 memset (t->unverified_ax,
1933 0,
1934 sizeof(struct CadetTunnelAxolotl));
1935 }
1936 else
1937 {
1939 "Creating fresh unverified KX for %s\n",
1940 GCT_2s (t));
1942 "# Fresh KX setup",
1943 1,
1944 GNUNET_NO);
1945 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1946 }
1947 /* Set as the 'current' RK/DHRr the one we are currently using,
1948 so that the duplicate-detection logic of
1949 #update_ax_by_kx can work. */
1950 t->unverified_ax->RK = t->ax.RK;
1951 t->unverified_ax->DHRr = t->ax.DHRr;
1952 t->unverified_ax->DHRs = t->ax.DHRs;
1953 t->unverified_ax->kx_0 = t->ax.kx_0;
1954 t->unverified_attempts = 0;
1955
1956 t->as.ax = *(t->unverified_ax);
1957 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1958 sizeof (t->as.peer_id));
1959 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1960 sizeof (t->as.ephemeral_key));
1961 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1962 sizeof (t->as.ratchet_key));
1963 memset (&t->as.auth, 0, sizeof (t->as.auth));
1964 t->as.flags = 0;
1965 t->as.cb_cls = t;
1966 t->as.cb = &cont_GCT_handle_kx;
1967
1968 if (t->as.ecdh_op)
1969 {
1971 "Cancelling previous ECDH operation\n");
1972
1973 GNUNET_PILS_cancel (t->as.ecdh_op);
1974 }
1975
1976 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
1977 &update_ax_by_kx, &t->as);
1978}
1979
1980
1987static void
1988cont_GCT_handle_kx_auth (void *cls,
1990{
1991 struct CadetTunnel *t = cls;
1992 struct CadetTunnelAxolotl *ax_tmp;
1993 struct GNUNET_HashCode kx_auth;
1994
1995 ax_tmp = &t->as.ax;
1996
1998 "Continue handling KX_AUTH message from %s\n",
1999 GCT_2s (t));
2000
2001 if (GNUNET_OK != ret)
2002 {
2003 if (GNUNET_NO == ret)
2005 "# redundant KX_AUTH received",
2006 1,
2007 GNUNET_NO);
2008 else
2009 GNUNET_break (0); /* connect to self!? */
2010 return;
2011 }
2012 GNUNET_CRYPTO_hash (&ax_tmp->RK,
2013 sizeof(ax_tmp->RK),
2014 &kx_auth);
2015 if (0 != GNUNET_memcmp (&kx_auth,
2016 &t->as.auth))
2017 {
2018 /* This KX_AUTH is not using the latest KX/KX_AUTH data
2019 we transmitted to the sender, refuse it, try KX again. */
2021 "# KX_AUTH not using our last KX received (auth failure)",
2022 1,
2023 GNUNET_NO);
2025 "KX AUTH mismatch!\n");
2026#if DEBUG_KX
2027 {
2028 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2029
2031 &ephemeral_key);
2032 if (0 != GNUNET_memcmp (&ephemeral_key,
2033 &msg->r_ephemeral_key_XXX))
2034 {
2036 "My ephemeral is %s!\n",
2037 GNUNET_e2s (&ephemeral_key));
2039 "Response is for ephemeral %s!\n",
2040 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2041 }
2042 }
2043#endif
2044 if (NULL == t->kx_task)
2045 t->kx_task
2046 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2047 &retry_kx,
2048 t);
2049 return;
2050 }
2051 /* Yep, we're good. */
2052 t->ax = *ax_tmp;
2053 if (NULL != t->unverified_ax)
2054 {
2055 /* We got some "stale" KX before, drop that. */
2056 cleanup_ax (t->unverified_ax);
2057 GNUNET_free (t->unverified_ax);
2058 t->unverified_ax = NULL;
2059 }
2060
2061 /* move ahead in our state machine */
2062 switch (t->estate)
2063 {
2066 /* Checked above, this is impossible. */
2067 GNUNET_assert (0);
2068 break;
2069
2070 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2071 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2072 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2075 break;
2076
2078 /* Did not expect another KX_AUTH, but so what, still acceptable.
2079 Nothing to do here. */
2080 break;
2081 }
2082 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2083 {
2084 send_kx_auth (t,
2085 NULL,
2086 &t->ax,
2087 GNUNET_NO);
2088 }
2089}
2090
2091
2098void
2101{
2102 struct CadetTunnel *t = ct->t;
2103
2105 "# KX_AUTH received",
2106 1,
2107 GNUNET_NO);
2108 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2109 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2110 {
2111 /* Confusing, we got a KX_AUTH before we even send our own
2112 KX. This should not happen. We'll send our own KX ASAP anyway,
2113 so let's ignore this here. */
2114 GNUNET_break_op (0);
2115 return;
2116 }
2118 "Handling KX_AUTH message from %s with ephemeral %s\n",
2119 GCT_2s (t),
2120 GNUNET_e2s (&msg->kx.ephemeral_key));
2121 if ((t->as.ecdh_op) &&
2122 (0 ==
2123 memcmp (&t->as.ratchet_key,
2124 &msg->kx.ratchet_key,
2125 sizeof(msg->kx.ratchet_key))) &&
2126 (0 ==
2127 memcmp (&t->as.ephemeral_key,
2128 &msg->kx.ephemeral_key,
2129 sizeof(msg->kx.ephemeral_key))))
2130 {
2132 "Waiting for previous ECDH operation\n");
2133 return;
2134 }
2135 /* We do everything in a copy until we've checked the authentication
2136 so we don't clobber anything we care about by accident. */
2137 t->as.ax = t->ax;
2138 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2139 sizeof (t->as.peer_id));
2140 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2141 sizeof (t->as.ephemeral_key));
2142 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2143 sizeof (t->as.ratchet_key));
2144 t->as.auth = msg->auth;
2145 t->as.flags = msg->kx.flags;
2146 t->as.cb_cls = t;
2147 t->as.cb = &cont_GCT_handle_kx_auth;
2148
2149 if (t->as.ecdh_op)
2150 {
2152 "Cancelling previous ECDH operation\n");
2153
2154 GNUNET_PILS_cancel (t->as.ecdh_op);
2155 }
2156
2157 /* Update 'ax' by the new key material */
2158 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2159 &update_ax_by_kx, &t->as);
2160}
2161
2162
2163/* ************************************** end core crypto ***************************** */
2164
2165
2174{
2175#define HIGH_BIT 0x08000000
2176 const struct GNUNET_PeerIdentity *my_identity;
2178 uint32_t ctn;
2179 int cmp;
2180 uint32_t highbit;
2181
2184
2187 if (0 < cmp)
2188 highbit = HIGH_BIT;
2189 else if (0 > cmp)
2190 highbit = 0;
2191 else
2192 GNUNET_assert (0); // loopback must never go here!
2193 ctn = ntohl (t->next_ctn.cn);
2194 while (NULL !=
2196 ctn | highbit))
2197 {
2198 ctn = ((ctn + 1) & (~HIGH_BIT));
2199 }
2200 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2201 ret.cn = htonl (ctn | highbit);
2202 return ret;
2203}
2204
2205
2217 struct CadetChannel *ch)
2218{
2220
2221 ctn = get_next_free_ctn (t);
2222 if (NULL != t->destroy_task)
2223 {
2224 GNUNET_SCHEDULER_cancel (t->destroy_task);
2225 t->destroy_task = NULL;
2226 }
2229 ntohl (ctn.cn),
2230 ch,
2233 "Adding %s to %s with state %d\n",
2234 GCCH_2s (ch),
2235 GCT_2s (t),
2236 t->estate);
2237 switch (t->estate)
2238 {
2240 /* waiting for connection to start KX */
2241 break;
2242
2246 /* we're currently waiting for KX to complete */
2247 break;
2248
2250 /* waiting for OTHER peer to send us data,
2251 we might need to prompt more aggressively! */
2252 if (NULL == t->kx_task)
2253 t->kx_task
2254 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2255 &retry_kx,
2256 t);
2257 break;
2258
2260 /* We are ready. Tell the new channel that we are up. */
2262 break;
2263 }
2264 return ctn;
2265}
2266
2267
2274void
2276{
2277 struct CadetTunnel *t = ct->t;
2278
2279 if (GNUNET_YES == ct->is_ready)
2280 {
2281 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2282 t->connection_ready_tail,
2283 ct);
2284 t->num_ready_connections--;
2285 }
2286 else
2287 {
2288 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2289 t->connection_busy_tail,
2290 ct);
2291 t->num_busy_connections--;
2292 }
2293 GNUNET_free (ct);
2294}
2295
2296
2303static void
2304destroy_t_connection (void *cls,
2305 struct CadetTConnection *ct)
2306{
2307 struct CadetTunnel *t = cls;
2308 struct CadetConnection *cc = ct->cc;
2309
2310 GNUNET_assert (ct->t == t);
2313}
2314
2315
2321static void
2322destroy_tunnel (void *cls)
2323{
2324 struct CadetTunnel *t = cls;
2325 struct CadetTunnelQueueEntry *tq;
2326
2327 t->destroy_task = NULL;
2329 "Destroying idle %s\n",
2330 GCT_2s (t));
2334 t);
2335 GNUNET_assert (NULL == t->connection_ready_head);
2336 GNUNET_assert (NULL == t->connection_busy_head);
2337 while (NULL != (tq = t->tq_head))
2338 {
2339 if (NULL != tq->cont)
2340 tq->cont (tq->cont_cls,
2341 NULL);
2342 GCT_send_cancel (tq);
2343 }
2344 GCP_drop_tunnel (t->destination,
2345 t);
2347 if (NULL != t->maintain_connections_task)
2348 {
2349 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2350 t->maintain_connections_task = NULL;
2351 }
2352 if (NULL != t->send_task)
2353 {
2354 GNUNET_SCHEDULER_cancel (t->send_task);
2355 t->send_task = NULL;
2356 }
2357 if (NULL != t->kx_task)
2358 {
2359 GNUNET_SCHEDULER_cancel (t->kx_task);
2360 t->kx_task = NULL;
2361 }
2362 if (NULL != t->as.ecdh_op)
2363 {
2364 GNUNET_PILS_cancel (t->as.ecdh_op);
2365 t->as.ecdh_op = NULL;
2366 }
2367 GNUNET_MST_destroy (t->mst);
2368 GNUNET_MQ_destroy (t->mq);
2369 if (NULL != t->unverified_ax)
2370 {
2371 cleanup_ax (t->unverified_ax);
2372 GNUNET_free (t->unverified_ax);
2373 }
2374 cleanup_ax (&t->ax);
2375 GNUNET_assert (NULL == t->destroy_task);
2376 GNUNET_free (t);
2377}
2378
2379
2387void
2389 struct CadetChannel *ch,
2391{
2393 "Removing %s from %s\n",
2394 GCCH_2s (ch),
2395 GCT_2s (t));
2398 ntohl (ctn.cn),
2399 ch));
2400 if ((0 ==
2401 GCT_count_channels (t)) &&
2402 (NULL == t->destroy_task))
2403 {
2404 t->destroy_task
2407 t);
2408 }
2409}
2410
2411
2420static int
2422 uint32_t key,
2423 void *value)
2424{
2425 struct CadetChannel *ch = value;
2426
2428 NULL);
2429 return GNUNET_OK;
2430}
2431
2432
2438void
2440{
2444 t);
2445 GNUNET_assert (0 ==
2447 if (NULL != t->destroy_task)
2448 {
2449 GNUNET_SCHEDULER_cancel (t->destroy_task);
2450 t->destroy_task = NULL;
2451 }
2452 destroy_tunnel (t);
2453}
2454
2455
2463static void
2465 struct CadetTConnection *ct)
2466{
2467 struct CadetTunnelQueueEntry *tq;
2468
2470 tq = t->tq_head;
2471 if (NULL == tq)
2472 {
2473 /* no messages pending right now */
2475 "Not sending payload of %s on ready %s (nothing pending)\n",
2476 GCT_2s (t),
2477 GCC_2s (ct->cc));
2478 return;
2479 }
2480 /* ready to send message 'tq' on tunnel 'ct' */
2481 GNUNET_assert (t == tq->t);
2483 t->tq_tail,
2484 tq);
2485 if (NULL != tq->cid)
2486 *tq->cid = *GCC_get_id (ct->cc);
2489 "Sending payload of %s on %s\n",
2490 GCT_2s (t),
2491 GCC_2s (ct->cc));
2492 GCC_transmit (ct->cc,
2493 tq->env);
2494 if (NULL != tq->cont)
2495 tq->cont (tq->cont_cls,
2496 GCC_get_id (ct->cc));
2497 GNUNET_free (tq);
2498}
2499
2500
2509static void
2510connection_ready_cb (void *cls,
2511 int is_ready)
2512{
2513 struct CadetTConnection *ct = cls;
2514 struct CadetTunnel *t = ct->t;
2515
2516 if (GNUNET_NO == is_ready)
2517 {
2519 "%s no longer ready for %s\n",
2520 GCC_2s (ct->cc),
2521 GCT_2s (t));
2523 return;
2524 }
2526 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2527 t->connection_busy_tail,
2528 ct);
2529 GNUNET_assert (0 < t->num_busy_connections);
2530 t->num_busy_connections--;
2531 ct->is_ready = GNUNET_YES;
2532 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2533 t->connection_ready_tail,
2534 ct);
2535 t->num_ready_connections++;
2536
2538 "%s now ready for %s in state %s\n",
2539 GCC_2s (ct->cc),
2540 GCT_2s (t),
2541 estate2s (t->estate));
2542 switch (t->estate)
2543 {
2546 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2547 GCT_2s (t),
2548 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2549 t->next_kx_attempt).rel_value_us);
2550 /* Do not begin KX if WE have no channels waiting! */
2552 t->next_kx_attempt).rel_value_us)
2553 return; /* wait for timeout before retrying */
2554 /* We are uninitialized, just transmit immediately,
2555 without undue delay. */
2556
2558 "Why for %s \n",
2559 GCT_2s (t));
2560
2561 if (NULL != t->kx_task)
2562 {
2563 GNUNET_SCHEDULER_cancel (t->kx_task);
2564 t->kx_task = NULL;
2565 }
2566 send_kx (t,
2567 ct,
2568 &t->ax);
2569 if ((0 ==
2570 GCT_count_channels (t)) &&
2571 (NULL == t->destroy_task))
2572 {
2573 t->destroy_task
2576 t);
2577 }
2578 break;
2579
2584 /* we're currently waiting for KX to complete, schedule job */
2585 if (NULL == t->kx_task)
2586 t->kx_task
2587 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2588 &retry_kx,
2589 t);
2590 break;
2591
2593 if (GNUNET_YES == t->kx_auth_requested)
2594 {
2596 t->next_kx_attempt).rel_value_us)
2597 return; /* wait for timeout */
2598 if (NULL != t->kx_task)
2599 {
2600 GNUNET_SCHEDULER_cancel (t->kx_task);
2601 t->kx_task = NULL;
2602 }
2603 send_kx_auth (t,
2604 ct,
2605 &t->ax,
2606 GNUNET_NO);
2607 return;
2608 }
2610 ct);
2611 break;
2612 }
2613}
2614
2615
2624static void
2625trigger_transmissions (void *cls)
2626{
2627 struct CadetTunnel *t = cls;
2628 struct CadetTConnection *ct;
2629
2630 t->send_task = NULL;
2631 if (NULL == t->tq_head)
2632 return; /* no messages pending right now */
2633 ct = get_ready_connection (t);
2634 if (NULL == ct)
2635 return; /* no connections ready */
2637 ct);
2638}
2639
2640
2645struct EvaluationSummary
2646{
2650 unsigned int min_length;
2651
2655 unsigned int max_length;
2656
2661
2666
2670 struct CadetPeerPath *path;
2671
2676 struct CadetTConnection *worst;
2677
2681 double worst_score;
2682
2686 int duplicate;
2687};
2688
2689
2697static void
2698evaluate_connection (void *cls,
2699 struct CadetTConnection *ct)
2700{
2701 struct EvaluationSummary *es = cls;
2702 struct CadetConnection *cc = ct->cc;
2703 unsigned int ct_length;
2704 struct CadetPeerPath *ps;
2705 const struct CadetConnectionMetrics *metrics;
2706 GNUNET_CONTAINER_HeapCostType ct_desirability;
2707 struct GNUNET_TIME_Relative uptime;
2708 struct GNUNET_TIME_Relative last_use;
2709 double score;
2710 double success_rate;
2711
2712 ps = GCC_get_path (cc,
2713 &ct_length);
2715 "Evaluating path %s of existing %s\n",
2716 GCPP_2s (ps),
2717 GCC_2s (cc));
2718 if (ps == es->path)
2719 {
2721 "Ignoring duplicate path %s.\n",
2722 GCPP_2s (es->path));
2723 es->duplicate = GNUNET_YES;
2724 return;
2725 }
2726 if (NULL != es->path)
2727 {
2728 int duplicate = GNUNET_YES;
2729
2730 for (unsigned int i = 0; i < ct_length; i++)
2731 {
2734 i) !=
2736 i))
2737 {
2738 duplicate = GNUNET_NO;
2739 break;
2740 }
2741 }
2742 if (GNUNET_YES == duplicate)
2743 {
2745 "Ignoring overlapping path %s.\n",
2746 GCPP_2s (es->path));
2747 es->duplicate = GNUNET_YES;
2748 return;
2749 }
2750 else
2751 {
2753 "Known path %s differs from proposed path\n",
2754 GCPP_2s (ps));
2755 }
2756 }
2757
2758 ct_desirability = GCPP_get_desirability (ps);
2759 metrics = GCC_get_metrics (cc);
2760 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2761 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2762 /* We add 1.0 here to avoid division by zero. */
2763 success_rate = (metrics->num_acked_transmissions + 1.0)
2764 / (metrics->num_successes + 1.0);
2765 score
2766 = ct_desirability
2767 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2768 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2769 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2770 score *= success_rate; /* weigh overall by success rate */
2771
2772 if ((NULL == es->worst) ||
2773 (score < es->worst_score))
2774 {
2775 es->worst = ct;
2776 es->worst_score = score;
2777 }
2778 es->min_length = GNUNET_MIN (es->min_length,
2779 ct_length);
2780 es->max_length = GNUNET_MAX (es->max_length,
2781 ct_length);
2782 es->min_desire = GNUNET_MIN (es->min_desire,
2783 ct_desirability);
2784 es->max_desire = GNUNET_MAX (es->max_desire,
2785 ct_desirability);
2786}
2787
2788
2798static int
2799consider_path_cb (void *cls,
2800 struct CadetPeerPath *path,
2801 unsigned int off)
2802{
2803 struct CadetTunnel *t = cls;
2804 struct EvaluationSummary es;
2805 struct CadetTConnection *ct;
2806
2807 GNUNET_assert (off < GCPP_get_length (path));
2809 off) == t->destination);
2810 es.min_length = UINT_MAX;
2811 es.max_length = 0;
2812 es.max_desire = 0;
2813 es.min_desire = UINT64_MAX;
2814 es.path = path;
2815 es.duplicate = GNUNET_NO;
2816 es.worst = NULL;
2817
2818 /* Compute evaluation summary over existing connections. */
2820 "Evaluating proposed path %s for target %s\n",
2821 GCPP_2s (path),
2822 GCT_2s (t));
2823 /* FIXME: suspect this does not ACTUALLY iterate
2824 over all existing paths, otherwise dup detection
2825 should work!!! */
2828 &es);
2829 if (GNUNET_YES == es.duplicate)
2830 return GNUNET_YES;
2831
2832 /* FIXME: not sure we should really just count
2833 'num_connections' here, as they may all have
2834 consistently failed to connect. */
2835
2836 /* We iterate by increasing path length; if we have enough paths and
2837 this one is more than twice as long than what we are currently
2838 using, then ignore all of these super-long ones! */
2840 (es.min_length * 2 < off) &&
2841 (es.max_length < off))
2842 {
2844 "Ignoring paths of length %u, they are way too long.\n",
2845 es.min_length * 2);
2846 return GNUNET_NO;
2847 }
2848 /* If we have enough paths and this one looks no better, ignore it. */
2850 (es.min_length < GCPP_get_length (path)) &&
2851 (es.min_desire > GCPP_get_desirability (path)) &&
2852 (es.max_length < off))
2853 {
2855 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2856 GCPP_get_length (path),
2857 (unsigned long long) GCPP_get_desirability (path),
2858 GCP_2s (t->destination));
2859 return GNUNET_YES;
2860 }
2861
2862 /* Path is interesting (better by some metric, or we don't have
2863 enough paths yet). */
2864 ct = GNUNET_new (struct CadetTConnection);
2866 ct->t = t;
2867 ct->cc = GCC_create (t->destination,
2868 path,
2869 off,
2870 ct,
2872 ct);
2873
2874 /* FIXME: schedule job to kill connection (and path?) if it takes
2875 too long to get ready! (And track performance data on how long
2876 other connections took with the tunnel!)
2877 => Note: to be done within 'connection'-logic! */
2878 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2879 t->connection_busy_tail,
2880 ct);
2881 t->num_busy_connections++;
2883 "Found interesting path %s for %s, created %s\n",
2884 GCPP_2s (path),
2885 GCT_2s (t),
2886 GCC_2s (ct->cc));
2887 return GNUNET_YES;
2888}
2889
2890
2904static void
2905maintain_connections_cb (void *cls)
2906{
2907 struct CadetTunnel *t = cls;
2908 struct GNUNET_TIME_Relative delay;
2909 struct EvaluationSummary es;
2910
2911 t->maintain_connections_task = NULL;
2913 "Performing connection maintenance for %s.\n",
2914 GCT_2s (t));
2915
2916 es.min_length = UINT_MAX;
2917 es.max_length = 0;
2918 es.max_desire = 0;
2919 es.min_desire = UINT64_MAX;
2920 es.path = NULL;
2921 es.worst = NULL;
2922 es.duplicate = GNUNET_NO;
2925 &es);
2926 if ((NULL != es.worst) &&
2928 {
2929 /* Clear out worst-performing connection 'es.worst'. */
2931 es.worst);
2932 }
2933
2934 /* Consider additional paths */
2935 (void) GCP_iterate_paths (t->destination,
2937 t);
2938
2939 /* FIXME: calculate when to try again based on how well we are doing;
2940 in particular, if we have to few connections, we might be able
2941 to do without this (as PATHS should tell us whenever a new path
2942 is available instantly; however, need to make sure this job is
2943 restarted after that happens).
2944 Furthermore, if the paths we do know are in a reasonably narrow
2945 quality band and are plentyful, we might also consider us stabilized
2946 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2947 t->maintain_connections_task
2950 t);
2951}
2952
2953
2954void
2956 struct CadetPeerPath *p,
2957 unsigned int off)
2958{
2960 "Considering %s for %s (offset %u)\n",
2961 GCPP_2s (p),
2962 GCT_2s (t),
2963 off);
2964 (void) consider_path_cb (t,
2965 p,
2966 off);
2967}
2968
2969
2976static void
2978 const struct GNUNET_MessageHeader *msg)
2979{
2980 struct CadetTunnel *t = cls;
2981
2983 "Received KEEPALIVE on %s\n",
2984 GCT_2s (t));
2986 "# keepalives received",
2987 1,
2988 GNUNET_NO);
2989}
2990
2991
2999static int
3000check_plaintext_data (void *cls,
3002{
3003 return GNUNET_OK;
3004}
3005
3006
3014static void
3015handle_plaintext_data (void *cls,
3017{
3018 struct CadetTunnel *t = cls;
3019 struct CadetChannel *ch;
3020
3021 ch = lookup_channel (t,
3022 msg->ctn);
3023 if (NULL == ch)
3024 {
3025 /* We don't know about such a channel, might have been destroyed on our
3026 end in the meantime, or never existed. Send back a DESTROY. */
3028 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3029 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3030 ntohl (msg->ctn.cn));
3032 msg->ctn);
3033 return;
3034 }
3036 GCC_get_id (t->current_ct->cc),
3037 msg);
3038}
3039
3040
3049static void
3050handle_plaintext_data_ack (void *cls,
3051 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
3052{
3053 struct CadetTunnel *t = cls;
3054 struct CadetChannel *ch;
3055
3056 ch = lookup_channel (t,
3057 ack->ctn);
3058 if (NULL == ch)
3059 {
3060 /* We don't know about such a channel, might have been destroyed on our
3061 end in the meantime, or never existed. Send back a DESTROY. */
3063 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3064 ntohl (ack->ctn.cn));
3066 ack->ctn);
3067 return;
3068 }
3070 GCC_get_id (t->current_ct->cc),
3071 ack);
3072}
3073
3074
3082static void
3084 const struct
3086{
3087 struct CadetTunnel *t = cls;
3088 struct CadetChannel *ch;
3089
3091 ntohl (copen->ctn.cn));
3092 if (NULL != ch)
3093 {
3095 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3096 GNUNET_h2s (&copen->h_port),
3097 GCT_2s (t),
3098 GCCH_2s (ch));
3100 GCC_get_id (t->current_ct->cc));
3101 return;
3102 }
3104 "Received CHANNEL_OPEN on h_port %s from %s\n",
3105 GNUNET_h2s (&copen->h_port),
3106 GCT_2s (t));
3108 copen->ctn,
3109 &copen->h_port,
3110 ntohl (copen->opt));
3111 if (NULL != t->destroy_task)
3112 {
3113 GNUNET_SCHEDULER_cancel (t->destroy_task);
3114 t->destroy_task = NULL;
3115 }
3118 ntohl (copen->ctn.cn),
3119 ch,
3121}
3122
3123
3130void
3133{
3135
3137 "Sending DESTROY message for channel ID %u\n",
3138 ntohl (ctn.cn));
3139 msg.header.size = htons (sizeof(msg));
3141 msg.reserved = htonl (0);
3142 msg.ctn = ctn;
3143 GCT_send (t,
3144 &msg.header,
3145 NULL,
3146 NULL,
3147 &ctn);
3148}
3149
3150
3159static void
3161 const struct
3163{
3164 struct CadetTunnel *t = cls;
3165 struct CadetChannel *ch;
3166
3167 ch = lookup_channel (t,
3168 cm->ctn);
3169 if (NULL == ch)
3170 {
3171 /* We don't know about such a channel, might have been destroyed on our
3172 end in the meantime, or never existed. Send back a DESTROY. */
3174 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3175 ntohl (cm->ctn.cn));
3177 cm->ctn);
3178 return;
3179 }
3181 "Received channel OPEN_ACK on channel %s from %s\n",
3182 GCCH_2s (ch),
3183 GCT_2s (t));
3185 GCC_get_id (t->current_ct->cc),
3186 &cm->port);
3187}
3188
3189
3197static void
3199 const struct
3201{
3202 struct CadetTunnel *t = cls;
3203 struct CadetChannel *ch;
3204
3205 ch = lookup_channel (t,
3206 cm->ctn);
3207 if (NULL == ch)
3208 {
3209 /* We don't know about such a channel, might have been destroyed on our
3210 end in the meantime, or never existed. */
3212 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3213 ntohl (cm->ctn.cn));
3214 return;
3215 }
3217 "Received channel DESTROY on %s from %s\n",
3218 GCCH_2s (ch),
3219 GCT_2s (t));
3221 GCC_get_id (t->current_ct->cc));
3222}
3223
3224
3235static int
3236handle_decrypted (void *cls,
3237 const struct GNUNET_MessageHeader *msg)
3238{
3239 struct CadetTunnel *t = cls;
3240
3241 GNUNET_assert (NULL != t->current_ct);
3243 msg);
3244 return GNUNET_OK;
3245}
3246
3247
3255static void
3256decrypted_error_cb (void *cls,
3257 enum GNUNET_MQ_Error error)
3258{
3259 GNUNET_break_op (0);
3260}
3261
3262
3270struct CadetTunnel *
3272{
3273 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3275 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3277 struct GNUNET_MessageHeader,
3278 t),
3279 GNUNET_MQ_hd_var_size (plaintext_data,
3282 t),
3283 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3286 t),
3287 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3290 t),
3291 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3294 t),
3295 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3298 t),
3300 };
3301
3302 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3303 new_ephemeral (&t->ax);
3305 t->destination = destination;
3307 t->maintain_connections_task
3309 t);
3310 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3311 NULL,
3312 NULL,
3313 NULL,
3314 handlers,
3316 t);
3318 t);
3319 return t;
3320}
3321
3322
3323int
3325 const struct
3327 struct CadetPeerPath *path)
3328{
3329 struct CadetTConnection *ct;
3330
3331 ct = GNUNET_new (struct CadetTConnection);
3333 ct->t = t;
3334 ct->cc = GCC_create_inbound (t->destination,
3335 path,
3336 ct,
3337 cid,
3339 ct);
3340 if (NULL == ct->cc)
3341 {
3343 "%s refused inbound %s (duplicate)\n",
3344 GCT_2s (t),
3345 GCC_2s (ct->cc));
3346 GNUNET_free (ct);
3347 return GNUNET_SYSERR;
3348 }
3349 /* FIXME: schedule job to kill connection (and path?) if it takes
3350 too long to get ready! (And track performance data on how long
3351 other connections took with the tunnel!)
3352 => Note: to be done within 'connection'-logic! */
3353 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3354 t->connection_busy_tail,
3355 ct);
3356 t->num_busy_connections++;
3358 "%s has new %s\n",
3359 GCT_2s (t),
3360 GCC_2s (ct->cc));
3361 return GNUNET_OK;
3362}
3363
3364
3371void
3374{
3375 struct CadetTunnel *t = ct->t;
3376 uint16_t size = ntohs (msg->header.size);
3377 char cbuf[size] GNUNET_ALIGN;
3378 ssize_t decrypted_size;
3379
3381 "%s received %u bytes of encrypted data in state %d\n",
3382 GCT_2s (t),
3383 (unsigned int) size,
3384 t->estate);
3385
3386 switch (t->estate)
3387 {
3390 /* We did not even SEND our KX, how can the other peer
3391 send us encrypted data? Must have been that we went
3392 down and the other peer still things we are up.
3393 Let's send it KX back. */
3395 "# received encrypted without any KX",
3396 1,
3397 GNUNET_NO);
3398 if (NULL != t->kx_task)
3399 {
3400 GNUNET_SCHEDULER_cancel (t->kx_task);
3401 t->kx_task = NULL;
3402 }
3403 send_kx (t,
3404 ct,
3405 &t->ax);
3406 return;
3407
3409 /* We send KX, and other peer send KX to us at the same time.
3410 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3412 "# received encrypted without KX_AUTH",
3413 1,
3414 GNUNET_NO);
3415 if (NULL != t->kx_task)
3416 {
3417 GNUNET_SCHEDULER_cancel (t->kx_task);
3418 t->kx_task = NULL;
3419 }
3420 send_kx_auth (t,
3421 ct,
3422 &t->ax,
3423 GNUNET_YES);
3424 return;
3425
3427 /* We did not get the KX of the other peer, but that
3428 might have been lost. Send our KX again immediately. */
3430 "# received encrypted without KX",
3431 1,
3432 GNUNET_NO);
3433 if (NULL != t->kx_task)
3434 {
3435 GNUNET_SCHEDULER_cancel (t->kx_task);
3436 t->kx_task = NULL;
3437 }
3438 send_kx (t,
3439 ct,
3440 &t->ax);
3441 return;
3442
3444 /* Great, first payload, we might graduate to OK! */
3446 /* We are up and running, all good. */
3447 break;
3448 }
3449
3450 decrypted_size = -1;
3451 if (CADET_TUNNEL_KEY_OK == t->estate)
3452 {
3453 /* We have well-established key material available,
3454 try that. (This is the common case.) */
3455 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3456 cbuf,
3457 msg,
3458 size);
3459 }
3460
3461 if ((-1 == decrypted_size) &&
3462 (NULL != t->unverified_ax))
3463 {
3464 /* We have un-authenticated KX material available. We should try
3465 this as a back-up option, in case the sender crashed and
3466 switched keys. */
3467 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3468 cbuf,
3469 msg,
3470 size);
3471 if (-1 != decrypted_size)
3472 {
3473 /* It worked! Treat this as authentication of the AX data! */
3474 cleanup_ax (&t->ax);
3475 t->ax = *t->unverified_ax;
3476 GNUNET_free (t->unverified_ax);
3477 t->unverified_ax = NULL;
3478 }
3479 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3480 {
3481 /* First time it worked, move tunnel into production! */
3484 if (NULL != t->send_task)
3485 GNUNET_SCHEDULER_cancel (t->send_task);
3487 t);
3488 }
3489 }
3490 if (NULL != t->unverified_ax)
3491 {
3492 /* We had unverified KX material that was useless; so increment
3493 counter and eventually move to ignore it. Note that we even do
3494 this increment if we successfully decrypted with the old KX
3495 material and thus didn't even both with the new one. This is
3496 the ideal case, as a malicious injection of bogus KX data
3497 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3499 "Failed to decrypt message with unverified KX data %u times\n",
3500 t->unverified_attempts);
3501 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3502 {
3503 cleanup_ax (t->unverified_ax);
3504 GNUNET_free (t->unverified_ax);
3505 t->unverified_ax = NULL;
3506 }
3507 }
3508
3509 if (-1 == decrypted_size)
3510 {
3511 /* Decryption failed for good, complain. */
3513 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3514 GCT_2s (t));
3516 "# unable to decrypt",
3517 1,
3518 GNUNET_NO);
3519 if (NULL != t->kx_task)
3520 {
3521 GNUNET_SCHEDULER_cancel (t->kx_task);
3522 t->kx_task = NULL;
3523 }
3524 send_kx (t,
3525 ct,
3526 &t->ax);
3527 return;
3528 }
3530 "# decrypted bytes",
3531 decrypted_size,
3532 GNUNET_NO);
3533
3534 /* The MST will ultimately call #handle_decrypted() on each message. */
3535 t->current_ct = ct;
3538 cbuf,
3539 decrypted_size,
3540 GNUNET_YES,
3541 GNUNET_NO));
3542 t->current_ct = NULL;
3543}
3544
3545
3546struct CadetTunnelQueueEntry *
3547GCT_send (struct CadetTunnel *t,
3548 const struct GNUNET_MessageHeader *message,
3550 void *cont_cls,
3552{
3553 struct CadetTunnelQueueEntry *tq;
3554 uint16_t message_size;
3555 uint16_t payload_size;
3556 struct GNUNET_MQ_Envelope *env;
3558 struct CadetChannel *ch;
3559
3560 if (NULL != ctn)
3561 {
3562 ch = lookup_channel (t,
3563 *ctn);
3564 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3565 {
3566 GNUNET_break (0);
3567 return NULL;
3568 }
3569 }
3570
3571 if (CADET_TUNNEL_KEY_OK != t->estate)
3572 {
3573 GNUNET_break (0);
3574 return NULL;
3575 }
3576 message_size = ntohs (message->size);
3577 payload_size = message_size + sizeof (struct GNUNET_CRYPTO_AeadMac);
3579 "Encrypting %u bytes for %s\n",
3580 (unsigned int) message_size,
3581 GCT_2s (t));
3582 env = GNUNET_MQ_msg_extra (ax_msg,
3583 payload_size,
3585 t_ax_encrypt (&t->ax,
3586 &ax_msg[1],
3587 message,
3588 message_size);
3590 "# encrypted bytes",
3591 payload_size,
3592 GNUNET_NO);
3593 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3594 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3595 /* FIXME: we should do this once, not once per message;
3596 this is a point multiplication, and DHRs does not
3597 change all the time. */
3599 &ax_msg->ax_header.DHRs);
3600 t_h_encrypt (&t->ax,
3601 ax_msg,
3602 payload_size,
3603 (unsigned char*) &ax_msg[1]);
3604
3605 tq = GNUNET_malloc (sizeof(*tq));
3606 tq->t = t;
3607 tq->env = env;
3608 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3609 tq->cont = cont;
3610 tq->cont_cls = cont_cls;
3612 t->tq_tail,
3613 tq);
3614 if (NULL != t->send_task)
3615 GNUNET_SCHEDULER_cancel (t->send_task);
3616 t->send_task
3618 t);
3619 return tq;
3620}
3621
3622
3623void
3625{
3626 struct CadetTunnel *t = tq->t;
3627
3629 t->tq_tail,
3630 tq);
3631 GNUNET_MQ_discard (tq->env);
3632 GNUNET_free (tq);
3633}
3634
3635
3643void
3646 void *iter_cls)
3647{
3648 struct CadetTConnection *n;
3649
3650 for (struct CadetTConnection *ct = t->connection_ready_head;
3651 NULL != ct;
3652 ct = n)
3653 {
3654 n = ct->next;
3655 iter (iter_cls,
3656 ct);
3657 }
3658 for (struct CadetTConnection *ct = t->connection_busy_head;
3659 NULL != ct;
3660 ct = n)
3661 {
3662 n = ct->next;
3663 iter (iter_cls,
3664 ct);
3665 }
3666}
3667
3668
3672struct ChanIterCls
3673{
3678
3682 void *iter_cls;
3683};
3684
3685
3694static int
3695iterate_channels_cb (void *cls,
3696 uint32_t key,
3697 void *value)
3698{
3699 struct ChanIterCls *ctx = cls;
3700 struct CadetChannel *ch = value;
3701
3702 ctx->iter (ctx->iter_cls,
3703 ch);
3704 return GNUNET_OK;
3705}
3706
3707
3715void
3718 void *iter_cls)
3719{
3720 struct ChanIterCls ctx;
3721
3722 ctx.iter = iter;
3723 ctx.iter_cls = iter_cls;
3726 &ctx);
3727}
3728
3729
3738static int
3739debug_channel (void *cls,
3740 uint32_t key,
3741 void *value)
3742{
3743 const enum GNUNET_ErrorType *level = cls;
3744 struct CadetChannel *ch = value;
3745
3746 GCCH_debug (ch, *level);
3747 return GNUNET_OK;
3748}
3749
3750
3751#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3752 __VA_ARGS__)
3753
3754
3761void
3762GCT_debug (const struct CadetTunnel *t,
3763 enum GNUNET_ErrorType level)
3764{
3765#if ! defined(GNUNET_CULL_LOGGING)
3766 struct CadetTConnection *iter_c;
3767 int do_log;
3768
3770 "cadet-tun",
3771 __FILE__, __FUNCTION__, __LINE__);
3772 if (0 == do_log)
3773 return;
3774
3775 LOG2 (level,
3776 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3777 GCT_2s (t),
3778 estate2s (t->estate),
3779 t->tq_len,
3781 LOG2 (level,
3782 "TTT channels:\n");
3785 &level);
3786 LOG2 (level,
3787 "TTT connections:\n");
3788 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3789 GCC_debug (iter_c->cc,
3790 level);
3791 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3792 GCC_debug (iter_c->cc,
3793 level);
3794
3795 LOG2 (level,
3796 "TTT TUNNEL END\n");
3797#endif
3798}
3799
3800
3801/* end of gnunet-service-cadet_tunnels.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
GNUNET_CADET_KX_Flags
Flags to be used in GNUNET_CADET_KX.
@ GNUNET_CADET_KX_FLAG_NONE
Should the peer reply with its KX details?
@ GNUNET_CADET_KX_FLAG_FORCE_REPLY
The peer should reply with its KX details?
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CADET_Channel * ch
Channel handle.
static uint64_t timestamp(void)
Get current timestamp.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static struct GNUNET_PILS_Handle * pils
Handle to PILS.
Definition gnunet-pils.c:44
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
void GCT_handle_kx(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Continue to handle KX message.
static int consider_path_cb(void *cls, struct CadetPeerPath *path, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn(struct CadetTunnel *t)
Compute the next free channel tunnel number for this tunnel.
static struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
static int notify_tunnel_up_cb(void *cls, uint32_t key, void *value)
Our tunnel became ready for the first time, notify channels that have been waiting.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
void(* CadetTunnelAxolotlCallback)(void *cls, enum GNUNET_GenericReturnValue res)
Signature of the follow up function from an udate AX by KX.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
static void handle_plaintext_channel_open_ack(void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
We have received confirmation from the target peer that the given channel could be established (the p...
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
Delete a key from the list of skipped keys.
#define LOG2(level,...)
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg, size_t additional_data_size, const unsigned char *additional_data)
Encrypt header with the axolotl header key.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
void GCT_handle_kx_auth(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
void GCT_handle_encrypted(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
static enum GNUNET_GenericReturnValue t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void cont_GCT_handle_kx(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX message.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
static void handle_plaintext_channel_destroy(void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
We received a message saying that a channel should be destroyed.
#define HIGH_BIT
static void handle_plaintext_channel_open(void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
We have received a request to open a channel to a port from another peer.
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
static int check_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
Check that msg is well-formed.
static void handle_plaintext_data_ack(void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We received an acknowledgement for data we sent on a channel.
static void handle_plaintext_keepalive(void *cls, const struct GNUNET_MessageHeader *msg)
We got a keepalive.
static void handle_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We received payload data for a channel.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
static void cont_GCT_handle_kx_auth(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX_AUTH message.
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
void GCT_destroy_tunnel_now(struct CadetTunnel *t)
Destroys the tunnel t now, without delay.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
#define LOG(level,...)
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_iterate_channels(struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
Iterate over all channels of a tunnel.
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GCT_debug(const struct CadetTunnel *t, enum GNUNET_ErrorType level)
Log all possible info about the tunnel state.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_CRYPTO_AeadSecretKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
static enum GNUNET_GenericReturnValue t_h_decrypt(const struct GNUNET_CRYPTO_AeadSecretKey *hkr, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t esize, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
static void update_ax_by_kx(void *cls, const struct GNUNET_HashCode *key_result)
Update our Axolotl key state based on the KX data we received.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
CadetTunnelEState
All the encryption states a tunnel can be in.
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
void(* GCT_ConnectionIterator)(void *cls, struct CadetTConnection *ct)
Iterator over connections.
void(* GCT_SendContinuation)(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called when a transmission requested using GCT_send is done.
void(* GCT_ChannelIterator)(void *cls, struct CadetChannel *ch)
Iterator over channels.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static unsigned long long payload
How much data are we currently storing in the database?
#define N
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:751
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:776
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:875
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:772
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:455
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_decrypt(size_t ct_len, const unsigned char ct[ct_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, const struct GNUNET_CRYPTO_AeadMac *mac, void *pt)
Decrypt the given data using XChaCha20-Poly1305.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:863
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_encrypt(size_t pt_len, const unsigned char pt[pt_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, void *ct, struct GNUNET_CRYPTO_AeadMac *mac)
Encrypt the given data using XChaCha20-Poly1305.
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:434
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:218
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
#define GNUNET_CRYPTO_hkdf_gnunet(result, out_len, xts, xts_len, skm, skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MAX(a, b)
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
GNUNET_ErrorType
Types of errors.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:514
#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:317
#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:732
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1260
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition mst.c:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition mst.c:404
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Performance metrics for a connection.
unsigned long long num_acked_transmissions
How many packets that ought to generate an ACK did we send via this connection?
struct GNUNET_TIME_Absolute age
When was this connection first established? (by us sending or receiving the CREATE_ACK for the first ...
unsigned long long num_successes
Number of packets that were sent via this connection did actually receive an ACK? (Note: ACKs may be ...
struct GNUNET_TIME_Absolute last_use
When was this connection last used? (by us sending or receiving a PAYLOAD message on it)
Low-level connection to a destination.
struct CadetTConnection * ct
Which tunnel is using this connection?
unsigned int off
Offset of our destination in path.
Information regarding a possible path to reach a peer.
Struct containing all information regarding a given peer.
Entry in list of connections used by tunnel, with metadata.
struct CadetTConnection * next
Next in DLL.
struct CadetConnection * cc
Connection handle.
struct GNUNET_TIME_Absolute created
Creation time, to keep oldest connection alive.
int is_ready
Is the connection currently ready for transmission?
struct CadetTunnel * t
Tunnel this connection belongs to.
Struct used to store data required for an async update AX by KX process.
struct GNUNET_PeerIdentity peer_id
Peer identity of other peer.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
void * cb_cls
Update callback closure.
struct GNUNET_HashCode auth
KDF-proof that sender could compute the 3-DH, used in lieu of a signature or payload data.
struct CadetTunnelAxolotl ax
Struct used for Axolotl.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public key of other key.
struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key
Ratchet key.
struct GNUNET_PILS_Operation * ecdh_op
Operation to derive key material.
CadetTunnelAxolotlCallback cb
Update callback.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
struct GNUNET_CRYPTO_AeadSecretKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
struct GNUNET_CRYPTO_AeadSecretKey RK
32-byte root key which gets updated by DH ratchet.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_AeadSecretKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct GNUNET_CRYPTO_AeadSecretKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_AeadSecretKey HKs
32-byte header key (currently used for sending).
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_AeadSecretKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).
struct GNUNET_CRYPTO_AeadSecretKey HKr
32-byte header key (currently used for receiving)
Struct used to save messages in a non-ready tunnel to send once connected.
struct CadetTunnelQueueEntry * prev
We are entries in a DLL.
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnelQueueEntry * next
We are entries in a DLL.
struct CadetTunnel * t
Tunnel these messages belong in.
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
struct CadetTunnelSkippedKey * next
DLL next.
struct CadetTunnelSkippedKey * prev
DLL prev.
Struct containing all information regarding a tunnel to a peer.
struct GNUNET_SCHEDULER_Task * send_task
Task to send messages from queue (if possible).
struct CadetPeer * destination
Destination of the tunnel.
struct CadetTConnection * connection_ready_head
DLL of ready connections that are actively used to reach the destination peer.
struct CadetTunnelAsync as
Structure to store data temporally for async operations.
struct CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct CadetTunnelQueueEntry * tq_tail
Queued messages, to transmit once tunnel gets connected.
struct GNUNET_SCHEDULER_Task * maintain_connections_task
Task to trim connections if too many are present.
struct CadetTConnection * connection_busy_head
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_TIME_Absolute next_kx_attempt
When do we try the next KX?
struct GNUNET_TIME_Relative kx_retry_delay
How long do we wait until we retry the KX?
struct CadetTConnection * connection_busy_tail
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_MQ_Handle * mq
Dispatcher for decrypted messages only (do NOT use for sending!).
enum CadetTunnelEState estate
State of the tunnel encryption.
struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key
Peer's ephemeral key, to recreate e_key and d_key when own ephemeral key changes.
unsigned int num_busy_connections
Number of connections in the connection_busy_head DLL.
struct CadetTunnelAxolotl ax
Axolotl info.
struct GNUNET_CONTAINER_MultiHashMap32 * channels
Channels inside this tunnel.
struct GNUNET_CRYPTO_AeadSecretKey e_key
Encryption ("our") key.
struct GNUNET_SCHEDULER_Task * destroy_task
Task scheduled if there are no more channels using the tunnel.
struct CadetTConnection * connection_ready_tail
DLL of ready connections that are actively used to reach the destination peer.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for decrypted messages.
struct CadetTunnelQueueEntry * tq_head
Queued messages, to transmit once tunnel gets connected.
unsigned int num_ready_connections
Number of connections in the connection_ready_head DLL.
struct GNUNET_SCHEDULER_Task * kx_task
Task to trigger KX.
struct CadetTunnelAxolotl * unverified_ax
Unverified Axolotl info, used only if we got a fresh KX (not a KX_AUTH) while our end of the tunnel w...
unsigned int tq_len
Number of entries in the tq_head DLL.
struct GNUNET_CADET_ChannelTunnelNumber next_ctn
Channel ID for the next created channel in this tunnel.
int kx_auth_requested
Force triggering KX_AUTH independent of estate.
struct GNUNET_CRYPTO_AeadSecretKey d_key
Decryption ("their") key.
unsigned int unverified_attempts
How often have we tried and failed to decrypt a message using the unverified KX material from unverif...
Closure for iterate_channels_cb.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
uint32_t Ns
Number of messages sent with the current ratchet key.
Message for cadet data traffic.
Message to acknowledge end-to-end data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
uint32_t cn
Which number does this channel have that uniquely identifies it within its tunnel,...
Hash uniquely identifying a connection below a tunnel.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.
struct GNUNET_CRYPTO_AeadMac mac
MAC of the encrypted message, used to verify message integrity.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
Internal representation of the hash map.
type for session keys
unsigned char mac[16]
Initialization vector.
type for session keys
type for (message) authentication keys
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to a message stream tokenizer.
Definition mst.c:45
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

◆ INITIAL_KX_RETRY_DELAY

#define INITIAL_KX_RETRY_DELAY
Value:
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.

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

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

◆ MAX_SKIPPED_KEYS

#define MAX_SKIPPED_KEYS   64

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

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

◆ MAX_KEY_GAP

#define MAX_KEY_GAP   256

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

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

◆ HIGH_BIT

#define HIGH_BIT   0x08000000

◆ 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 3752 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 2626 of file gnunet-service-cadet_tunnels.c.

2627{
2628 struct CadetTunnel *t = cls;
2629 struct CadetTConnection *ct;
2630
2631 t->send_task = NULL;
2632 if (NULL == t->tq_head)
2633 return; /* no messages pending right now */
2634 ct = get_ready_connection (t);
2635 if (NULL == ct)
2636 return; /* no connections ready */
2638 ct);
2639}

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

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

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

◆ new_ephemeral()

static void new_ephemeral ( struct CadetTunnelAxolotl ax)
static

Create a new Axolotl ephemeral (ratchet) key.

Parameters
axkey material to update

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

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

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

Referenced by GCT_create_tunnel(), and t_ax_encrypt().

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

◆ t_ax_hmac_hash()

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

Perform a HMAC.

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

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

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

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

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

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

◆ t_hmac_derive_key()

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

Derive a symmetric encryption key from an HMAC-HASH.

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

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

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

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

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

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

◆ t_ax_encrypt()

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

Encrypt data with the axolotl tunnel key.

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

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

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

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

Referenced by GCT_send().

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

◆ t_ax_decrypt()

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

Decrypt data with the axolotl tunnel key.

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

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

908{
910 struct GNUNET_CRYPTO_AeadNonce iv;
912 size_t macoffset;
913
914 /* A short (or absent) payload is what a remote peer sends, not something
915 we may compute @a macoffset from: the subtraction below underflows. */
916 if (size < sizeof(struct GNUNET_MessageHeader)
917 + sizeof(struct GNUNET_CRYPTO_AeadMac))
918 {
919 GNUNET_break_op (0);
920 return GNUNET_SYSERR;
921 }
922 macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
924 &MK,
925 "0",
926 1);
927
929 sizeof iv,
930 NULL,
931 0,
932 &MK,
933 sizeof MK);
934 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) src)[macoffset];
935 /* Failing to authenticate is what a corrupt or forged ciphertext looks
936 like, and the callers all handle it -- #try_old_ax_keys() returns -1 on
937 exactly this. Aborting here let any peer take the service down. */
939 src,
940 0,
941 NULL,
942 &MK,
943 &iv,
944 mac,
945 dst))
946 return GNUNET_SYSERR;
947 /* Only a message we actually accepted advances the receive chain. */
949 &ax->CKr,
950 "1",
951 1);
952 return GNUNET_OK;
953}

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

Referenced by t_ax_decrypt_and_validate().

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

◆ t_h_encrypt()

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

Encrypt header with the axolotl header key.

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

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

967{
968 struct GNUNET_CRYPTO_AeadNonce nonce;
969
971 sizeof nonce,
972 NULL,
973 0,
974 &ax->HKs,
975 sizeof ax->HKs);
977 ,
978 (unsigned char*) &msg
979 ->ax_header,
980 additional_data_size,
981 additional_data,
982 &ax->HKs,
983 &nonce,
984 &msg->ax_header,
985 &msg->mac));
986}

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

Referenced by GCT_send().

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

◆ t_h_decrypt()

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

Decrypt header with the current axolotl header key.

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

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

1003{
1004 struct GNUNET_CRYPTO_AeadNonce iv;
1005
1007 sizeof iv,
1008 NULL,
1009 0,
1010 hkr,
1011 sizeof *hkr);
1012
1013
1015 (unsigned char*) &src->ax_header,
1016 esize,
1017 (unsigned char*) &src[1],
1018 hkr,
1019 &iv,
1020 &dst->mac,
1021 &dst->ax_header);
1022}

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

Referenced by t_ax_decrypt_and_validate(), and try_old_ax_keys().

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

◆ delete_skipped_key()

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

Delete a key from the list of skipped keys.

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

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

1034{
1036 ax->skipped_tail,
1037 key);
1038 GNUNET_free (key);
1039 ax->skipped--;
1040}

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

1058{
1059 struct CadetTunnelSkippedKey *key;
1060 struct GNUNET_CRYPTO_AeadNonce iv;
1061 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1062 struct GNUNET_CRYPTO_AeadSecretKey *valid_HK;
1063 size_t esize;
1064 size_t len;
1065 unsigned int N;
1066 const unsigned char *payload;
1067
1069 "Trying skipped keys\n");
1070 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1071 len = esize;
1072 /* @a size comes off the wire; #check_tunnel_encrypted() used to accept
1073 anything, so this must not be an assertion. */
1074 if ((size <= sizeof(struct GNUNET_CADET_TunnelEncryptedMessage)) ||
1075 (len < sizeof(struct GNUNET_MessageHeader)
1076 + sizeof(struct GNUNET_CRYPTO_AeadMac)))
1077 {
1078 GNUNET_break_op (0);
1079 return -1;
1080 }
1081 payload = (const unsigned char *) &src[1];
1082
1083 /* Find a correct Header Key */
1084 valid_HK = NULL;
1085 for (key = ax->skipped_head; NULL != key; key = key->next)
1086 {
1087 /* Try decrypt header */
1088 if (GNUNET_OK == t_h_decrypt (&key->HK,
1089 src,
1090 esize,
1091 &plaintext_header))
1092 {
1093 valid_HK = &key->HK;
1094 break;
1095 }
1096 }
1097 if (NULL == key)
1098 return -1;
1099
1100 /* Find the correct message key */
1101 N = ntohl (plaintext_header.ax_header.Ns);
1102 while ((NULL != key) &&
1103 (N != key->Kn))
1104 key = key->next;
1105 if ((NULL == key) ||
1106 (0 != GNUNET_memcmp (&key->HK,
1107 valid_HK)))
1108 return -1;
1109
1110 /* Decrypt payload */
1112 sizeof iv,
1113 NULL,
1114 0,
1115 &key->MK,
1116 sizeof key->MK);
1117
1118 /* NOTE: the MAC sits at the end of the *payload*. Indexing @a src, a
1119 `struct GNUNET_CADET_TunnelEncryptedMessage *', scaled the offset by the
1120 size of that struct and read far past the end of the message -- so this
1121 never authenticated anything it was given and no skipped key ever
1122 worked. */
1124 len,
1125 payload,
1126 0,
1127 NULL,
1128 &key->MK,
1129 &iv,
1130 (const struct GNUNET_CRYPTO_AeadMac*)
1131 &payload[len - sizeof (struct GNUNET_CRYPTO_AeadMac)],
1132 dst))
1133 {
1134 return -1;
1135 }
1137 key);
1138 return len - sizeof (struct GNUNET_CRYPTO_AeadMac);
1139}

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

Referenced by t_ax_decrypt_and_validate().

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

◆ store_skipped_key()

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

Delete a key from the list of skipped keys.

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

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

1151{
1152 struct CadetTunnelSkippedKey *key;
1153
1155 key->timestamp = GNUNET_TIME_absolute_get ();
1156 key->Kn = ax->Nr;
1157 key->HK = ax->HKr;
1158 t_hmac_derive_key (&ax->CKr,
1159 &key->MK,
1160 "0",
1161 1);
1162 t_hmac_derive_key (&ax->CKr,
1163 &ax->CKr,
1164 "1",
1165 1);
1167 ax->skipped_tail,
1168 key);
1169 ax->skipped++;
1170 ax->Nr++;
1171}

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

Referenced by store_ax_keys().

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

◆ store_ax_keys()

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

Stage skipped AX keys and calculate the message key.

Stores each HK and MK for skipped messages.

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

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

1188{
1189 int gap;
1190
1191 gap = Np - ax->Nr;
1193 "Storing skipped keys [%u, %u)\n",
1194 ax->Nr,
1195 Np);
1196 if (MAX_KEY_GAP < gap)
1197 {
1198 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1199 /* TODO: start new key exchange on return */
1200 GNUNET_break_op (0);
1202 "Got message %u, expected %u+\n",
1203 Np,
1204 ax->Nr);
1205 return GNUNET_SYSERR;
1206 }
1207 if (0 > gap)
1208 {
1209 /* Delayed message: don't store keys, flag to try old keys. */
1210 return GNUNET_SYSERR;
1211 }
1212
1213 while (ax->Nr < Np)
1215 HKr);
1216
1217 while (ax->skipped > MAX_SKIPPED_KEYS)
1219 ax->skipped_tail);
1220 return GNUNET_OK;
1221}

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

1240{
1241 struct GNUNET_HashCode hmac;
1242 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1243 uint32_t Np;
1244 uint32_t PNp;
1245 size_t esize; /* Size of encrypted payload */
1246
1247 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1248
1249 if (GNUNET_OK == t_h_decrypt (&ax->HKr,
1250 src,
1251 esize,
1252 &plaintext_header))
1253 {
1254 Np = ntohl (plaintext_header.ax_header.Ns);
1255 PNp = ntohl (plaintext_header.ax_header.PNs);
1256 }
1257 else
1258 {
1259 static const char ctx[] = "axolotl ratchet";
1260 struct GNUNET_CRYPTO_AeadSecretKey keys[3]; /* RKp, NHKp, CKp */
1262 struct GNUNET_HashCode dh;
1263 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1264
1265 /* Try Next HK */
1266 if (GNUNET_OK == t_h_decrypt (&ax->NHKr,
1267 src,
1268 esize,
1269 &plaintext_header))
1270 {
1271 /* Try the skipped keys, if that fails, we're out of luck. */
1272 return try_old_ax_keys (ax,
1273 dst,
1274 src,
1275 size);
1276 }
1277 HK = ax->HKr;
1278 ax->HKr = ax->NHKr;
1279 Np = ntohl (plaintext_header.ax_header.Ns);
1280 PNp = ntohl (plaintext_header.ax_header.PNs);
1281 DHRp = &plaintext_header.ax_header.DHRs;
1282 store_ax_keys (ax,
1283 &HK,
1284 PNp);
1285
1286 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1288 DHRp,
1289 &dh);
1290 t_ax_hmac_hash (&ax->RK,
1291 &hmac,
1292 &dh, sizeof(dh));
1294 keys, sizeof(keys),
1295 ctx, sizeof(ctx),
1296 &hmac, sizeof(hmac));
1297
1298 /* Commit "purported" keys */
1299 ax->RK = keys[0];
1300 ax->NHKr = keys[1];
1301 ax->CKr = keys[2];
1302 ax->DHRr = *DHRp;
1303 ax->Nr = 0;
1305
1306 }
1307 if ((Np != ax->Nr) &&
1308 (GNUNET_OK != store_ax_keys (ax,
1309 &ax->HKr,
1310 Np)))
1311 {
1312 /* Try the skipped keys, if that fails, we're out of luck. */
1313 return try_old_ax_keys (ax,
1314 dst,
1315 src,
1316 size);
1317 }
1318
1319 if (GNUNET_OK != t_ax_decrypt (ax,
1320 dst,
1321 &src[1],
1322 esize))
1323 return -1;
1324 ax->Nr = Np + 1;
1325 return esize - sizeof (struct GNUNET_CRYPTO_AeadMac);
1326}

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

Referenced by GCT_handle_encrypted().

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

◆ notify_tunnel_up_cb()

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

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

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

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

1342{
1343 struct CadetChannel *ch = value;
1344
1346 return GNUNET_OK;
1347}

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

1360{
1361 enum CadetTunnelEState old = t->estate;
1362
1363 t->estate = state;
1365 "%s estate changed from %s to %s\n",
1366 GCT_2s (t),
1367 estate2s (old),
1368 estate2s (state));
1369
1370 if ((CADET_TUNNEL_KEY_OK != old) &&
1371 (CADET_TUNNEL_KEY_OK == t->estate))
1372 {
1373 if (NULL != t->kx_task)
1374 {
1375 GNUNET_SCHEDULER_cancel (t->kx_task);
1376 t->kx_task = NULL;
1377 }
1378 /* notify all channels that have been waiting */
1381 t);
1382 if (NULL != t->send_task)
1383 GNUNET_SCHEDULER_cancel (t->send_task);
1385 t);
1386 }
1387}

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

1402{
1403 struct CadetConnection *cc;
1404 struct GNUNET_MQ_Envelope *env;
1407
1408 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1409 return; /* only Alice may send KX */
1410 if ((NULL == ct) ||
1411 (GNUNET_NO == ct->is_ready))
1412 ct = get_ready_connection (t);
1413 if (NULL == ct)
1414 {
1416 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1417 GCT_2s (t),
1418 estate2s (t->estate));
1419 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1420 return;
1421 }
1422 cc = ct->cc;
1425 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1426 msg->flags = htonl (flags);
1427 msg->cid = *GCC_get_id (cc);
1429 &msg->ephemeral_key);
1430#if DEBUG_KX
1431 msg->ephemeral_key_XXX = ax->kx_0;
1432#endif
1434 "Sending KX message to %s with ephemeral %s on CID %s\n",
1435 GCT_2s (t),
1436 GNUNET_e2s (&msg->ephemeral_key),
1437 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1439 &msg->ratchet_key);
1441 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1442 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1443 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1446 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1449 GCC_transmit (cc,
1450 env);
1452 "# KX transmitted",
1453 1,
1454 GNUNET_NO);
1455}

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

1473{
1474 struct CadetConnection *cc;
1475 struct GNUNET_MQ_Envelope *env;
1477 enum GNUNET_CADET_KX_Flags flags;
1478
1479 if ((NULL == ct) ||
1480 (GNUNET_NO == ct->is_ready))
1481 ct = get_ready_connection (t);
1482 if (NULL == ct)
1483 {
1485 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1486 GCT_2s (t));
1487 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1488 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1489 return;
1490 }
1491 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1492 cc = ct->cc;
1496 if (GNUNET_YES == force_reply)
1498 msg->kx.flags = htonl (flags);
1499 msg->kx.cid = *GCC_get_id (cc);
1501 &msg->kx.ephemeral_key);
1503 &msg->kx.ratchet_key);
1504#if DEBUG_KX
1505 msg->kx.ephemeral_key_XXX = ax->kx_0;
1506 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1507#endif
1509 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1510 GCT_2s (t),
1511 GNUNET_e2s (&msg->kx.ephemeral_key),
1512 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1513
1514 /* Compute authenticator (this is the main difference to #send_kx()) */
1515 GNUNET_CRYPTO_hash (&ax->RK,
1516 sizeof(ax->RK),
1517 &msg->auth);
1518 /* Compute when to be triggered again; actual job will
1519 be scheduled via #connection_ready_cb() */
1520 t->kx_retry_delay
1521 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1522 t->next_kx_attempt
1523 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1524
1525 /* Send via cc, mark it as unready */
1527
1528 /* Update state machine, unless we are already OK */
1529 if (CADET_TUNNEL_KEY_OK != t->estate)
1532 GCC_transmit (cc,
1533 env);
1535 "# KX_AUTH transmitted",
1536 1,
1537 GNUNET_NO);
1538}

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

1548{
1549 while (NULL != ax->skipped_head)
1551 ax->skipped_head);
1552 GNUNET_assert (0 == ax->skipped);
1555}

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

1572{
1573 struct CadetTunnelAsync *as;
1574 struct GNUNET_HashCode key_material[3];
1575 struct GNUNET_CRYPTO_AeadSecretKey keys[5];
1576 struct CadetTunnelAxolotl *ax;
1577 const struct GNUNET_PeerIdentity *pid;
1578 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1579 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1580 const char salt[] = "CADET Axolotl salt";
1581 int am_I_alice;
1582
1583 as = cls;
1584 ax = &as->ax;
1585 pid = &as->peer_id;
1586 ephemeral_key = &as->ephemeral_key;
1587 ratchet_key = &as->ratchet_key;
1588
1589 as->ecdh_op = NULL;
1590
1592 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1593 GNUNET_e2s (ephemeral_key));
1594
1595 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1596 {
1597 GNUNET_break_op (0);
1598 if (as->cb)
1599 as->cb (as->cb_cls, GNUNET_SYSERR);
1600 return;
1601 }
1602
1603 if (0 == GNUNET_memcmp (&ax->DHRr,
1604 ratchet_key))
1605 {
1607 "# Ratchet key already known",
1608 1,
1609 GNUNET_NO);
1611 "Ratchet key already known. Ignoring KX.\n");
1612 if (as->cb)
1613 as->cb (as->cb_cls, GNUNET_NO);
1614 return;
1615 }
1616
1617 ax->DHRr = *ratchet_key;
1618 ax->last_ephemeral = *ephemeral_key;
1619 /* ECDH A B0 */
1620 if (GNUNET_YES == am_I_alice)
1621 {
1622 GNUNET_memcpy (&key_material[0], key_result,
1623 sizeof (*key_result));
1624 }
1625 else
1626 {
1627 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1628 &pid->public_key, /* A */
1629 &key_material[0]);
1630 }
1631 /* ECDH A0 B */
1632 if (GNUNET_YES == am_I_alice)
1633 {
1634 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1635 &pid->public_key, /* B */
1636 &key_material[1]);
1637 }
1638 else
1639 {
1640 GNUNET_memcpy (&key_material[1], key_result,
1641 sizeof (*key_result));
1642 }
1643
1644 /* ECDH A0 B0 */
1645 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1646 ephemeral_key, /* B0 or A0 */
1647 &key_material[2]);
1648 /* KDF */
1650 keys, sizeof(keys),
1651 salt, sizeof(salt),
1652 &key_material, sizeof(key_material));
1653
1654 if (0 == memcmp (&ax->RK,
1655 &keys[0],
1656 sizeof(ax->RK)))
1657 {
1659 "Root key already known. Ignoring KX.\n");
1661 "# Root key already known",
1662 1,
1663 GNUNET_NO);
1664 if (as->cb)
1665 as->cb (as->cb_cls, GNUNET_NO);
1666 return;
1667 }
1668
1669 ax->RK = keys[0];
1670 if (GNUNET_YES == am_I_alice)
1671 {
1672 ax->HKr = keys[1];
1673 ax->NHKs = keys[2];
1674 ax->NHKr = keys[3];
1675 ax->CKr = keys[4];
1677 }
1678 else
1679 {
1680 ax->HKs = keys[1];
1681 ax->NHKr = keys[2];
1682 ax->NHKs = keys[3];
1683 ax->CKs = keys[4];
1684 ax->ratchet_flag = GNUNET_NO;
1687 ratchet_time);
1688 }
1689
1690 if (as->cb)
1691 as->cb (as->cb_cls, GNUNET_OK);
1692}

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

1702{
1703 struct CadetTunnel *t = cls;
1704 struct CadetTunnelAxolotl *ax;
1705
1706 t->kx_task = NULL;
1708 "Trying to make KX progress on %s in state %s\n",
1709 GCT_2s (t),
1710 estate2s (t->estate));
1711 switch (t->estate)
1712 {
1713 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1714 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1715 send_kx (t,
1716 NULL,
1717 &t->ax);
1718 break;
1719
1722 /* We are responding, so only require reply
1723 if WE have a channel waiting. */
1724 if (NULL != t->unverified_ax)
1725 {
1726 /* Send AX_AUTH so we might get this one verified */
1727 ax = t->unverified_ax;
1728 }
1729 else
1730 {
1731 /* How can this be? */
1732 GNUNET_break (0);
1733 ax = &t->ax;
1734 }
1735 send_kx_auth (t,
1736 NULL,
1737 ax,
1738 (0 == GCT_count_channels (t))
1739 ? GNUNET_NO
1740 : GNUNET_YES);
1741 break;
1742
1744 /* We are responding, so only require reply
1745 if WE have a channel waiting. */
1746 if (NULL != t->unverified_ax)
1747 {
1748 /* Send AX_AUTH so we might get this one verified */
1749 ax = t->unverified_ax;
1750 }
1751 else
1752 {
1753 /* How can this be? */
1754 GNUNET_break (0);
1755 ax = &t->ax;
1756 }
1757 send_kx_auth (t,
1758 NULL,
1759 ax,
1760 (0 == GCT_count_channels (t))
1761 ? GNUNET_NO
1762 : GNUNET_YES);
1763 break;
1764
1766 /* Must have been the *other* peer asking us to
1767 respond with a KX_AUTH. */
1768 if (NULL != t->unverified_ax)
1769 {
1770 /* Sending AX_AUTH in response to AX so we might get this one verified */
1771 ax = t->unverified_ax;
1772 }
1773 else
1774 {
1775 /* Sending AX_AUTH in response to AX_AUTH */
1776 ax = &t->ax;
1777 }
1778 send_kx_auth (t,
1779 NULL,
1780 ax,
1781 GNUNET_NO);
1782 break;
1783 }
1784}

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

1796{
1797 struct CadetTunnel *t = cls;
1798
1799 if (t->unverified_ax)
1800 *(t->unverified_ax) = t->as.ax;
1801
1803 "Continue handling KX message from %s from %s\n",
1804 GCT_2s (t),
1805 GNUNET_i2s (GCP_get_id (t->destination)));
1806
1808 if (GNUNET_OK != ret)
1809 {
1811 "# Useless KX",
1812 1,
1813 GNUNET_NO);
1814 return; /* duplicate KX, nothing to do */
1815 }
1816 /* move ahead in our state machine */
1817 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1820 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1823
1824 /* KX is still not done, try again our end. */
1825 if (CADET_TUNNEL_KEY_OK != t->estate)
1826 {
1827 if (NULL != t->kx_task)
1828 GNUNET_SCHEDULER_cancel (t->kx_task);
1829 t->kx_task
1831 t);
1832 }
1833}

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

1845{
1846 struct CadetTunnel *t = ct->t;
1847
1849 "# KX received",
1850 1,
1851 GNUNET_NO);
1852 if (GNUNET_YES ==
1853 GCT_alice_or_betty (GCP_get_id (t->destination)))
1854 {
1855 /* Betty/Bob is not allowed to send KX! */
1856 GNUNET_break_op (0);
1857 return;
1858 }
1860 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1861 GCT_2s (t),
1862 GNUNET_e2s (&msg->ephemeral_key),
1863 GNUNET_i2s (GCP_get_id (t->destination)),
1864 GCC_2s (ct->cc));
1865#if 1
1866 if ((0 ==
1867 memcmp (&t->ax.DHRr,
1868 &msg->ratchet_key,
1869 sizeof(msg->ratchet_key))) &&
1870 (0 ==
1871 memcmp (&t->ax.last_ephemeral,
1872 &msg->ephemeral_key,
1873 sizeof(msg->ephemeral_key))))
1874
1875 {
1877 "# Duplicate KX received",
1878 1,
1879 GNUNET_NO);
1880 send_kx_auth (t,
1881 ct,
1882 &t->ax,
1883 GNUNET_NO);
1884 return;
1885 }
1886#endif
1887 /* We only keep ONE unverified KX around, so if there is an existing one,
1888 clean it up. */
1889 if (NULL != t->unverified_ax)
1890 {
1891 if ((0 ==
1892 memcmp (&t->unverified_ax->DHRr,
1893 &msg->ratchet_key,
1894 sizeof(msg->ratchet_key))) &&
1895 (0 ==
1896 memcmp (&t->unverified_ax->last_ephemeral,
1897 &msg->ephemeral_key,
1898 sizeof(msg->ephemeral_key))))
1899 {
1901 "# Duplicate unverified KX received",
1902 1,
1903 GNUNET_NO);
1904#if 1
1905 send_kx_auth (t,
1906 ct,
1907 t->unverified_ax,
1908 GNUNET_NO);
1909 return;
1910#endif
1911 }
1912 if ((t->as.ecdh_op) &&
1913 (0 ==
1914 memcmp (&t->as.ratchet_key,
1915 &msg->ratchet_key,
1916 sizeof(msg->ratchet_key))) &&
1917 (0 ==
1918 memcmp (&t->as.ephemeral_key,
1919 &msg->ephemeral_key,
1920 sizeof(msg->ephemeral_key))))
1921 {
1923 "Waiting for previous ECDH operation\n");
1924 return;
1925 }
1927 "Dropping old unverified KX state.\n");
1929 "# Unverified KX dropped for fresh KX",
1930 1,
1931 GNUNET_NO);
1932 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1933 memset (t->unverified_ax,
1934 0,
1935 sizeof(struct CadetTunnelAxolotl));
1936 }
1937 else
1938 {
1940 "Creating fresh unverified KX for %s\n",
1941 GCT_2s (t));
1943 "# Fresh KX setup",
1944 1,
1945 GNUNET_NO);
1946 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1947 }
1948 /* Set as the 'current' RK/DHRr the one we are currently using,
1949 so that the duplicate-detection logic of
1950 #update_ax_by_kx can work. */
1951 t->unverified_ax->RK = t->ax.RK;
1952 t->unverified_ax->DHRr = t->ax.DHRr;
1953 t->unverified_ax->DHRs = t->ax.DHRs;
1954 t->unverified_ax->kx_0 = t->ax.kx_0;
1955 t->unverified_attempts = 0;
1956
1957 t->as.ax = *(t->unverified_ax);
1958 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1959 sizeof (t->as.peer_id));
1960 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1961 sizeof (t->as.ephemeral_key));
1962 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1963 sizeof (t->as.ratchet_key));
1964 memset (&t->as.auth, 0, sizeof (t->as.auth));
1965 t->as.flags = 0;
1966 t->as.cb_cls = t;
1967 t->as.cb = &cont_GCT_handle_kx;
1968
1969 if (t->as.ecdh_op)
1970 {
1972 "Cancelling previous ECDH operation\n");
1973
1974 GNUNET_PILS_cancel (t->as.ecdh_op);
1975 }
1976
1977 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
1978 &update_ax_by_kx, &t->as);
1979}

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

1991{
1992 struct CadetTunnel *t = cls;
1993 struct CadetTunnelAxolotl *ax_tmp;
1994 struct GNUNET_HashCode kx_auth;
1995
1996 ax_tmp = &t->as.ax;
1997
1999 "Continue handling KX_AUTH message from %s\n",
2000 GCT_2s (t));
2001
2002 if (GNUNET_OK != ret)
2003 {
2004 if (GNUNET_NO == ret)
2006 "# redundant KX_AUTH received",
2007 1,
2008 GNUNET_NO);
2009 else
2010 GNUNET_break (0); /* connect to self!? */
2011 return;
2012 }
2013 GNUNET_CRYPTO_hash (&ax_tmp->RK,
2014 sizeof(ax_tmp->RK),
2015 &kx_auth);
2016 if (0 != GNUNET_memcmp (&kx_auth,
2017 &t->as.auth))
2018 {
2019 /* This KX_AUTH is not using the latest KX/KX_AUTH data
2020 we transmitted to the sender, refuse it, try KX again. */
2022 "# KX_AUTH not using our last KX received (auth failure)",
2023 1,
2024 GNUNET_NO);
2026 "KX AUTH mismatch!\n");
2027#if DEBUG_KX
2028 {
2029 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2030
2032 &ephemeral_key);
2033 if (0 != GNUNET_memcmp (&ephemeral_key,
2034 &msg->r_ephemeral_key_XXX))
2035 {
2037 "My ephemeral is %s!\n",
2038 GNUNET_e2s (&ephemeral_key));
2040 "Response is for ephemeral %s!\n",
2041 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2042 }
2043 }
2044#endif
2045 if (NULL == t->kx_task)
2046 t->kx_task
2047 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2048 &retry_kx,
2049 t);
2050 return;
2051 }
2052 /* Yep, we're good. */
2053 t->ax = *ax_tmp;
2054 if (NULL != t->unverified_ax)
2055 {
2056 /* We got some "stale" KX before, drop that. */
2057 cleanup_ax (t->unverified_ax);
2058 GNUNET_free (t->unverified_ax);
2059 t->unverified_ax = NULL;
2060 }
2061
2062 /* move ahead in our state machine */
2063 switch (t->estate)
2064 {
2067 /* Checked above, this is impossible. */
2068 GNUNET_assert (0);
2069 break;
2070
2071 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2072 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2073 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2076 break;
2077
2079 /* Did not expect another KX_AUTH, but so what, still acceptable.
2080 Nothing to do here. */
2081 break;
2082 }
2083 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2084 {
2085 send_kx_auth (t,
2086 NULL,
2087 &t->ax,
2088 GNUNET_NO);
2089 }
2090}

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

2102{
2103 struct CadetTunnel *t = ct->t;
2104
2106 "# KX_AUTH received",
2107 1,
2108 GNUNET_NO);
2109 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2110 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2111 {
2112 /* Confusing, we got a KX_AUTH before we even send our own
2113 KX. This should not happen. We'll send our own KX ASAP anyway,
2114 so let's ignore this here. */
2115 GNUNET_break_op (0);
2116 return;
2117 }
2119 "Handling KX_AUTH message from %s with ephemeral %s\n",
2120 GCT_2s (t),
2121 GNUNET_e2s (&msg->kx.ephemeral_key));
2122 if ((t->as.ecdh_op) &&
2123 (0 ==
2124 memcmp (&t->as.ratchet_key,
2125 &msg->kx.ratchet_key,
2126 sizeof(msg->kx.ratchet_key))) &&
2127 (0 ==
2128 memcmp (&t->as.ephemeral_key,
2129 &msg->kx.ephemeral_key,
2130 sizeof(msg->kx.ephemeral_key))))
2131 {
2133 "Waiting for previous ECDH operation\n");
2134 return;
2135 }
2136 /* We do everything in a copy until we've checked the authentication
2137 so we don't clobber anything we care about by accident. */
2138 t->as.ax = t->ax;
2139 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2140 sizeof (t->as.peer_id));
2141 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2142 sizeof (t->as.ephemeral_key));
2143 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2144 sizeof (t->as.ratchet_key));
2145 t->as.auth = msg->auth;
2146 t->as.flags = msg->kx.flags;
2147 t->as.cb_cls = t;
2148 t->as.cb = &cont_GCT_handle_kx_auth;
2149
2150 if (t->as.ecdh_op)
2151 {
2153 "Cancelling previous ECDH operation\n");
2154
2155 GNUNET_PILS_cancel (t->as.ecdh_op);
2156 }
2157
2158 /* Update 'ax' by the new key material */
2159 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2160 &update_ax_by_kx, &t->as);
2161}

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

2175{
2176#define HIGH_BIT 0x08000000
2177 const struct GNUNET_PeerIdentity *my_identity;
2179 uint32_t ctn;
2180 int cmp;
2181 uint32_t highbit;
2182
2185
2188 if (0 < cmp)
2189 highbit = HIGH_BIT;
2190 else if (0 > cmp)
2191 highbit = 0;
2192 else
2193 GNUNET_assert (0); // loopback must never go here!
2194 ctn = ntohl (t->next_ctn.cn);
2195 while (NULL !=
2197 ctn | highbit))
2198 {
2199 ctn = ((ctn + 1) & (~HIGH_BIT));
2200 }
2201 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2202 ret.cn = htonl (ctn | highbit);
2203 return ret;
2204}

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

2219{
2221
2222 ctn = get_next_free_ctn (t);
2223 if (NULL != t->destroy_task)
2224 {
2225 GNUNET_SCHEDULER_cancel (t->destroy_task);
2226 t->destroy_task = NULL;
2227 }
2230 ntohl (ctn.cn),
2231 ch,
2234 "Adding %s to %s with state %d\n",
2235 GCCH_2s (ch),
2236 GCT_2s (t),
2237 t->estate);
2238 switch (t->estate)
2239 {
2241 /* waiting for connection to start KX */
2242 break;
2243
2247 /* we're currently waiting for KX to complete */
2248 break;
2249
2251 /* waiting for OTHER peer to send us data,
2252 we might need to prompt more aggressively! */
2253 if (NULL == t->kx_task)
2254 t->kx_task
2255 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2256 &retry_kx,
2257 t);
2258 break;
2259
2261 /* We are ready. Tell the new channel that we are up. */
2263 break;
2264 }
2265 return ctn;
2266}

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

2277{
2278 struct CadetTunnel *t = ct->t;
2279
2280 if (GNUNET_YES == ct->is_ready)
2281 {
2282 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2283 t->connection_ready_tail,
2284 ct);
2285 t->num_ready_connections--;
2286 }
2287 else
2288 {
2289 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2290 t->connection_busy_tail,
2291 ct);
2292 t->num_busy_connections--;
2293 }
2294 GNUNET_free (ct);
2295}

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

2307{
2308 struct CadetTunnel *t = cls;
2309 struct CadetConnection *cc = ct->cc;
2310
2311 GNUNET_assert (ct->t == t);
2314}

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

2324{
2325 struct CadetTunnel *t = cls;
2326 struct CadetTunnelQueueEntry *tq;
2327
2328 t->destroy_task = NULL;
2330 "Destroying idle %s\n",
2331 GCT_2s (t));
2335 t);
2336 GNUNET_assert (NULL == t->connection_ready_head);
2337 GNUNET_assert (NULL == t->connection_busy_head);
2338 while (NULL != (tq = t->tq_head))
2339 {
2340 if (NULL != tq->cont)
2341 tq->cont (tq->cont_cls,
2342 NULL);
2343 GCT_send_cancel (tq);
2344 }
2345 GCP_drop_tunnel (t->destination,
2346 t);
2348 if (NULL != t->maintain_connections_task)
2349 {
2350 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2351 t->maintain_connections_task = NULL;
2352 }
2353 if (NULL != t->send_task)
2354 {
2355 GNUNET_SCHEDULER_cancel (t->send_task);
2356 t->send_task = NULL;
2357 }
2358 if (NULL != t->kx_task)
2359 {
2360 GNUNET_SCHEDULER_cancel (t->kx_task);
2361 t->kx_task = NULL;
2362 }
2363 if (NULL != t->as.ecdh_op)
2364 {
2365 GNUNET_PILS_cancel (t->as.ecdh_op);
2366 t->as.ecdh_op = NULL;
2367 }
2368 GNUNET_MST_destroy (t->mst);
2369 GNUNET_MQ_destroy (t->mq);
2370 if (NULL != t->unverified_ax)
2371 {
2372 cleanup_ax (t->unverified_ax);
2373 GNUNET_free (t->unverified_ax);
2374 }
2375 cleanup_ax (&t->ax);
2376 GNUNET_assert (NULL == t->destroy_task);
2377 GNUNET_free (t);
2378}

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

2392{
2394 "Removing %s from %s\n",
2395 GCCH_2s (ch),
2396 GCT_2s (t));
2399 ntohl (ctn.cn),
2400 ch));
2401 if ((0 ==
2402 GCT_count_channels (t)) &&
2403 (NULL == t->destroy_task))
2404 {
2405 t->destroy_task
2408 t);
2409 }
2410}

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

2425{
2426 struct CadetChannel *ch = value;
2427
2429 NULL);
2430 return GNUNET_OK;
2431}

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

2441{
2445 t);
2446 GNUNET_assert (0 ==
2448 if (NULL != t->destroy_task)
2449 {
2450 GNUNET_SCHEDULER_cancel (t->destroy_task);
2451 t->destroy_task = NULL;
2452 }
2453 destroy_tunnel (t);
2454}

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

2467{
2468 struct CadetTunnelQueueEntry *tq;
2469
2471 tq = t->tq_head;
2472 if (NULL == tq)
2473 {
2474 /* no messages pending right now */
2476 "Not sending payload of %s on ready %s (nothing pending)\n",
2477 GCT_2s (t),
2478 GCC_2s (ct->cc));
2479 return;
2480 }
2481 /* ready to send message 'tq' on tunnel 'ct' */
2482 GNUNET_assert (t == tq->t);
2484 t->tq_tail,
2485 tq);
2486 if (NULL != tq->cid)
2487 *tq->cid = *GCC_get_id (ct->cc);
2490 "Sending payload of %s on %s\n",
2491 GCT_2s (t),
2492 GCC_2s (ct->cc));
2493 GCC_transmit (ct->cc,
2494 tq->env);
2495 if (NULL != tq->cont)
2496 tq->cont (tq->cont_cls,
2497 GCC_get_id (ct->cc));
2498 GNUNET_free (tq);
2499}

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

2513{
2514 struct CadetTConnection *ct = cls;
2515 struct CadetTunnel *t = ct->t;
2516
2517 if (GNUNET_NO == is_ready)
2518 {
2520 "%s no longer ready for %s\n",
2521 GCC_2s (ct->cc),
2522 GCT_2s (t));
2524 return;
2525 }
2527 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2528 t->connection_busy_tail,
2529 ct);
2530 GNUNET_assert (0 < t->num_busy_connections);
2531 t->num_busy_connections--;
2532 ct->is_ready = GNUNET_YES;
2533 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2534 t->connection_ready_tail,
2535 ct);
2536 t->num_ready_connections++;
2537
2539 "%s now ready for %s in state %s\n",
2540 GCC_2s (ct->cc),
2541 GCT_2s (t),
2542 estate2s (t->estate));
2543 switch (t->estate)
2544 {
2547 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2548 GCT_2s (t),
2549 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2550 t->next_kx_attempt).rel_value_us);
2551 /* Do not begin KX if WE have no channels waiting! */
2553 t->next_kx_attempt).rel_value_us)
2554 return; /* wait for timeout before retrying */
2555 /* We are uninitialized, just transmit immediately,
2556 without undue delay. */
2557
2559 "Why for %s \n",
2560 GCT_2s (t));
2561
2562 if (NULL != t->kx_task)
2563 {
2564 GNUNET_SCHEDULER_cancel (t->kx_task);
2565 t->kx_task = NULL;
2566 }
2567 send_kx (t,
2568 ct,
2569 &t->ax);
2570 if ((0 ==
2571 GCT_count_channels (t)) &&
2572 (NULL == t->destroy_task))
2573 {
2574 t->destroy_task
2577 t);
2578 }
2579 break;
2580
2585 /* we're currently waiting for KX to complete, schedule job */
2586 if (NULL == t->kx_task)
2587 t->kx_task
2588 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2589 &retry_kx,
2590 t);
2591 break;
2592
2594 if (GNUNET_YES == t->kx_auth_requested)
2595 {
2597 t->next_kx_attempt).rel_value_us)
2598 return; /* wait for timeout */
2599 if (NULL != t->kx_task)
2600 {
2601 GNUNET_SCHEDULER_cancel (t->kx_task);
2602 t->kx_task = NULL;
2603 }
2604 send_kx_auth (t,
2605 ct,
2606 &t->ax,
2607 GNUNET_NO);
2608 return;
2609 }
2611 ct);
2612 break;
2613 }
2614}

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

2701{
2702 struct EvaluationSummary *es = cls;
2703 struct CadetConnection *cc = ct->cc;
2704 unsigned int ct_length;
2705 struct CadetPeerPath *ps;
2706 const struct CadetConnectionMetrics *metrics;
2707 GNUNET_CONTAINER_HeapCostType ct_desirability;
2708 struct GNUNET_TIME_Relative uptime;
2709 struct GNUNET_TIME_Relative last_use;
2710 double score;
2711 double success_rate;
2712
2713 ps = GCC_get_path (cc,
2714 &ct_length);
2716 "Evaluating path %s of existing %s\n",
2717 GCPP_2s (ps),
2718 GCC_2s (cc));
2719 if (ps == es->path)
2720 {
2722 "Ignoring duplicate path %s.\n",
2723 GCPP_2s (es->path));
2724 es->duplicate = GNUNET_YES;
2725 return;
2726 }
2727 if (NULL != es->path)
2728 {
2729 int duplicate = GNUNET_YES;
2730
2731 for (unsigned int i = 0; i < ct_length; i++)
2732 {
2735 i) !=
2737 i))
2738 {
2739 duplicate = GNUNET_NO;
2740 break;
2741 }
2742 }
2743 if (GNUNET_YES == duplicate)
2744 {
2746 "Ignoring overlapping path %s.\n",
2747 GCPP_2s (es->path));
2748 es->duplicate = GNUNET_YES;
2749 return;
2750 }
2751 else
2752 {
2754 "Known path %s differs from proposed path\n",
2755 GCPP_2s (ps));
2756 }
2757 }
2758
2759 ct_desirability = GCPP_get_desirability (ps);
2760 metrics = GCC_get_metrics (cc);
2761 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2762 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2763 /* We add 1.0 here to avoid division by zero. */
2764 success_rate = (metrics->num_acked_transmissions + 1.0)
2765 / (metrics->num_successes + 1.0);
2766 score
2767 = ct_desirability
2768 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2769 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2770 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2771 score *= success_rate; /* weigh overall by success rate */
2772
2773 if ((NULL == es->worst) ||
2774 (score < es->worst_score))
2775 {
2776 es->worst = ct;
2777 es->worst_score = score;
2778 }
2779 es->min_length = GNUNET_MIN (es->min_length,
2780 ct_length);
2781 es->max_length = GNUNET_MAX (es->max_length,
2782 ct_length);
2783 es->min_desire = GNUNET_MIN (es->min_desire,
2784 ct_desirability);
2785 es->max_desire = GNUNET_MAX (es->max_desire,
2786 ct_desirability);
2787}

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

2803{
2804 struct CadetTunnel *t = cls;
2805 struct EvaluationSummary es;
2806 struct CadetTConnection *ct;
2807
2808 GNUNET_assert (off < GCPP_get_length (path));
2810 off) == t->destination);
2811 es.min_length = UINT_MAX;
2812 es.max_length = 0;
2813 es.max_desire = 0;
2814 es.min_desire = UINT64_MAX;
2815 es.path = path;
2816 es.duplicate = GNUNET_NO;
2817 es.worst = NULL;
2818
2819 /* Compute evaluation summary over existing connections. */
2821 "Evaluating proposed path %s for target %s\n",
2822 GCPP_2s (path),
2823 GCT_2s (t));
2824 /* FIXME: suspect this does not ACTUALLY iterate
2825 over all existing paths, otherwise dup detection
2826 should work!!! */
2829 &es);
2830 if (GNUNET_YES == es.duplicate)
2831 return GNUNET_YES;
2832
2833 /* FIXME: not sure we should really just count
2834 'num_connections' here, as they may all have
2835 consistently failed to connect. */
2836
2837 /* We iterate by increasing path length; if we have enough paths and
2838 this one is more than twice as long than what we are currently
2839 using, then ignore all of these super-long ones! */
2841 (es.min_length * 2 < off) &&
2842 (es.max_length < off))
2843 {
2845 "Ignoring paths of length %u, they are way too long.\n",
2846 es.min_length * 2);
2847 return GNUNET_NO;
2848 }
2849 /* If we have enough paths and this one looks no better, ignore it. */
2851 (es.min_length < GCPP_get_length (path)) &&
2852 (es.min_desire > GCPP_get_desirability (path)) &&
2853 (es.max_length < off))
2854 {
2856 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2857 GCPP_get_length (path),
2858 (unsigned long long) GCPP_get_desirability (path),
2859 GCP_2s (t->destination));
2860 return GNUNET_YES;
2861 }
2862
2863 /* Path is interesting (better by some metric, or we don't have
2864 enough paths yet). */
2865 ct = GNUNET_new (struct CadetTConnection);
2867 ct->t = t;
2868 ct->cc = GCC_create (t->destination,
2869 path,
2870 off,
2871 ct,
2873 ct);
2874
2875 /* FIXME: schedule job to kill connection (and path?) if it takes
2876 too long to get ready! (And track performance data on how long
2877 other connections took with the tunnel!)
2878 => Note: to be done within 'connection'-logic! */
2879 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2880 t->connection_busy_tail,
2881 ct);
2882 t->num_busy_connections++;
2884 "Found interesting path %s for %s, created %s\n",
2885 GCPP_2s (path),
2886 GCT_2s (t),
2887 GCC_2s (ct->cc));
2888 return GNUNET_YES;
2889}

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

2907{
2908 struct CadetTunnel *t = cls;
2909 struct GNUNET_TIME_Relative delay;
2910 struct EvaluationSummary es;
2911
2912 t->maintain_connections_task = NULL;
2914 "Performing connection maintenance for %s.\n",
2915 GCT_2s (t));
2916
2917 es.min_length = UINT_MAX;
2918 es.max_length = 0;
2919 es.max_desire = 0;
2920 es.min_desire = UINT64_MAX;
2921 es.path = NULL;
2922 es.worst = NULL;
2923 es.duplicate = GNUNET_NO;
2926 &es);
2927 if ((NULL != es.worst) &&
2929 {
2930 /* Clear out worst-performing connection 'es.worst'. */
2932 es.worst);
2933 }
2934
2935 /* Consider additional paths */
2936 (void) GCP_iterate_paths (t->destination,
2938 t);
2939
2940 /* FIXME: calculate when to try again based on how well we are doing;
2941 in particular, if we have to few connections, we might be able
2942 to do without this (as PATHS should tell us whenever a new path
2943 is available instantly; however, need to make sure this job is
2944 restarted after that happens).
2945 Furthermore, if the paths we do know are in a reasonably narrow
2946 quality band and are plentyful, we might also consider us stabilized
2947 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2948 t->maintain_connections_task
2951 t);
2952}

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

2959{
2961 "Considering %s for %s (offset %u)\n",
2962 GCPP_2s (p),
2963 GCT_2s (t),
2964 off);
2965 (void) consider_path_cb (t,
2966 p,
2967 off);
2968}

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

2980{
2981 struct CadetTunnel *t = cls;
2982
2984 "Received KEEPALIVE on %s\n",
2985 GCT_2s (t));
2987 "# keepalives received",
2988 1,
2989 GNUNET_NO);
2990}

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

3003{
3004 return GNUNET_OK;
3005}

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

3018{
3019 struct CadetTunnel *t = cls;
3020 struct CadetChannel *ch;
3021
3022 ch = lookup_channel (t,
3023 msg->ctn);
3024 if (NULL == ch)
3025 {
3026 /* We don't know about such a channel, might have been destroyed on our
3027 end in the meantime, or never existed. Send back a DESTROY. */
3029 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3030 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3031 ntohl (msg->ctn.cn));
3033 msg->ctn);
3034 return;
3035 }
3037 GCC_get_id (t->current_ct->cc),
3038 msg);
3039}

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

3053{
3054 struct CadetTunnel *t = cls;
3055 struct CadetChannel *ch;
3056
3057 ch = lookup_channel (t,
3058 ack->ctn);
3059 if (NULL == ch)
3060 {
3061 /* We don't know about such a channel, might have been destroyed on our
3062 end in the meantime, or never existed. Send back a DESTROY. */
3064 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3065 ntohl (ack->ctn.cn));
3067 ack->ctn);
3068 return;
3069 }
3071 GCC_get_id (t->current_ct->cc),
3072 ack);
3073}

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

3087{
3088 struct CadetTunnel *t = cls;
3089 struct CadetChannel *ch;
3090
3092 ntohl (copen->ctn.cn));
3093 if (NULL != ch)
3094 {
3096 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3097 GNUNET_h2s (&copen->h_port),
3098 GCT_2s (t),
3099 GCCH_2s (ch));
3101 GCC_get_id (t->current_ct->cc));
3102 return;
3103 }
3105 "Received CHANNEL_OPEN on h_port %s from %s\n",
3106 GNUNET_h2s (&copen->h_port),
3107 GCT_2s (t));
3109 copen->ctn,
3110 &copen->h_port,
3111 ntohl (copen->opt));
3112 if (NULL != t->destroy_task)
3113 {
3114 GNUNET_SCHEDULER_cancel (t->destroy_task);
3115 t->destroy_task = NULL;
3116 }
3119 ntohl (copen->ctn.cn),
3120 ch,
3122}

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

3134{
3136
3138 "Sending DESTROY message for channel ID %u\n",
3139 ntohl (ctn.cn));
3140 msg.header.size = htons (sizeof(msg));
3142 msg.reserved = htonl (0);
3143 msg.ctn = ctn;
3144 GCT_send (t,
3145 &msg.header,
3146 NULL,
3147 NULL,
3148 &ctn);
3149}

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

3164{
3165 struct CadetTunnel *t = cls;
3166 struct CadetChannel *ch;
3167
3168 ch = lookup_channel (t,
3169 cm->ctn);
3170 if (NULL == ch)
3171 {
3172 /* We don't know about such a channel, might have been destroyed on our
3173 end in the meantime, or never existed. Send back a DESTROY. */
3175 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3176 ntohl (cm->ctn.cn));
3178 cm->ctn);
3179 return;
3180 }
3182 "Received channel OPEN_ACK on channel %s from %s\n",
3183 GCCH_2s (ch),
3184 GCT_2s (t));
3186 GCC_get_id (t->current_ct->cc),
3187 &cm->port);
3188}

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

3202{
3203 struct CadetTunnel *t = cls;
3204 struct CadetChannel *ch;
3205
3206 ch = lookup_channel (t,
3207 cm->ctn);
3208 if (NULL == ch)
3209 {
3210 /* We don't know about such a channel, might have been destroyed on our
3211 end in the meantime, or never existed. */
3213 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3214 ntohl (cm->ctn.cn));
3215 return;
3216 }
3218 "Received channel DESTROY on %s from %s\n",
3219 GCCH_2s (ch),
3220 GCT_2s (t));
3222 GCC_get_id (t->current_ct->cc));
3223}

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

3239{
3240 struct CadetTunnel *t = cls;
3241
3242 GNUNET_assert (NULL != t->current_ct);
3244 msg);
3245 return GNUNET_OK;
3246}

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

3259{
3260 GNUNET_break_op (0);
3261}

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

3273{
3274 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3276 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3278 struct GNUNET_MessageHeader,
3279 t),
3280 GNUNET_MQ_hd_var_size (plaintext_data,
3283 t),
3284 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3287 t),
3288 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3291 t),
3292 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3295 t),
3296 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3299 t),
3301 };
3302
3303 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3304 new_ephemeral (&t->ax);
3306 t->destination = destination;
3308 t->maintain_connections_task
3310 t);
3311 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3312 NULL,
3313 NULL,
3314 NULL,
3315 handlers,
3317 t);
3319 t);
3320 return t;
3321}

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

3329{
3330 struct CadetTConnection *ct;
3331
3332 ct = GNUNET_new (struct CadetTConnection);
3334 ct->t = t;
3335 ct->cc = GCC_create_inbound (t->destination,
3336 path,
3337 ct,
3338 cid,
3340 ct);
3341 if (NULL == ct->cc)
3342 {
3344 "%s refused inbound %s (duplicate)\n",
3345 GCT_2s (t),
3346 GCC_2s (ct->cc));
3347 GNUNET_free (ct);
3348 return GNUNET_SYSERR;
3349 }
3350 /* FIXME: schedule job to kill connection (and path?) if it takes
3351 too long to get ready! (And track performance data on how long
3352 other connections took with the tunnel!)
3353 => Note: to be done within 'connection'-logic! */
3354 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3355 t->connection_busy_tail,
3356 ct);
3357 t->num_busy_connections++;
3359 "%s has new %s\n",
3360 GCT_2s (t),
3361 GCC_2s (ct->cc));
3362 return GNUNET_OK;
3363}

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

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

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

3553{
3554 struct CadetTunnelQueueEntry *tq;
3555 uint16_t message_size;
3556 uint16_t payload_size;
3557 struct GNUNET_MQ_Envelope *env;
3559 struct CadetChannel *ch;
3560
3561 if (NULL != ctn)
3562 {
3563 ch = lookup_channel (t,
3564 *ctn);
3565 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3566 {
3567 GNUNET_break (0);
3568 return NULL;
3569 }
3570 }
3571
3572 if (CADET_TUNNEL_KEY_OK != t->estate)
3573 {
3574 GNUNET_break (0);
3575 return NULL;
3576 }
3577 message_size = ntohs (message->size);
3578 payload_size = message_size + sizeof (struct GNUNET_CRYPTO_AeadMac);
3580 "Encrypting %u bytes for %s\n",
3581 (unsigned int) message_size,
3582 GCT_2s (t));
3583 env = GNUNET_MQ_msg_extra (ax_msg,
3584 payload_size,
3586 t_ax_encrypt (&t->ax,
3587 &ax_msg[1],
3588 message,
3589 message_size);
3591 "# encrypted bytes",
3592 payload_size,
3593 GNUNET_NO);
3594 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3595 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3596 /* FIXME: we should do this once, not once per message;
3597 this is a point multiplication, and DHRs does not
3598 change all the time. */
3600 &ax_msg->ax_header.DHRs);
3601 t_h_encrypt (&t->ax,
3602 ax_msg,
3603 payload_size,
3604 (unsigned char*) &ax_msg[1]);
3605
3606 tq = GNUNET_malloc (sizeof(*tq));
3607 tq->t = t;
3608 tq->env = env;
3609 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3610 tq->cont = cont;
3611 tq->cont_cls = cont_cls;
3613 t->tq_tail,
3614 tq);
3615 if (NULL != t->send_task)
3616 GNUNET_SCHEDULER_cancel (t->send_task);
3617 t->send_task
3619 t);
3620 return tq;
3621}

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

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

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

◆ GCT_send_cancel()

void GCT_send_cancel ( struct CadetTunnelQueueEntry q)

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

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

Parameters
qHandle to the queue entry to cancel.

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

3626{
3627 struct CadetTunnel *t = tq->t;
3628
3630 t->tq_tail,
3631 tq);
3632 GNUNET_MQ_discard (tq->env);
3633 GNUNET_free (tq);
3634}

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

3648{
3649 struct CadetTConnection *n;
3650
3651 for (struct CadetTConnection *ct = t->connection_ready_head;
3652 NULL != ct;
3653 ct = n)
3654 {
3655 n = ct->next;
3656 iter (iter_cls,
3657 ct);
3658 }
3659 for (struct CadetTConnection *ct = t->connection_busy_head;
3660 NULL != ct;
3661 ct = n)
3662 {
3663 n = ct->next;
3664 iter (iter_cls,
3665 ct);
3666 }
3667}

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

3699{
3700 struct ChanIterCls *ctx = cls;
3701 struct CadetChannel *ch = value;
3702
3703 ctx->iter (ctx->iter_cls,
3704 ch);
3705 return GNUNET_OK;
3706}

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

3720{
3721 struct ChanIterCls ctx;
3722
3723 ctx.iter = iter;
3724 ctx.iter_cls = iter_cls;
3727 &ctx);
3728}

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

3743{
3744 const enum GNUNET_ErrorType *level = cls;
3745 struct CadetChannel *ch = value;
3746
3747 GCCH_debug (ch, *level);
3748 return GNUNET_OK;
3749}

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

3765{
3766#if ! defined(GNUNET_CULL_LOGGING)
3767 struct CadetTConnection *iter_c;
3768 int do_log;
3769
3771 "cadet-tun",
3772 __FILE__, __FUNCTION__, __LINE__);
3773 if (0 == do_log)
3774 return;
3775
3776 LOG2 (level,
3777 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3778 GCT_2s (t),
3779 estate2s (t->estate),
3780 t->tq_len,
3782 LOG2 (level,
3783 "TTT channels:\n");
3786 &level);
3787 LOG2 (level,
3788 "TTT connections:\n");
3789 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3790 GCC_debug (iter_c->cc,
3791 level);
3792 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3793 GCC_debug (iter_c->cc,
3794 level);
3795
3796 LOG2 (level,
3797 "TTT TUNNEL END\n");
3798#endif
3799}

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: