GNUnet debian-0.24.3-29-g453fda2cf
 
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  CadetTunnelQueueEntry
 Struct used to save messages in a non-ready tunnel to send once connected. More...
 
struct  CadetTunnel
 Struct containing all information regarding a tunnel to a peer. More...
 
struct  EvaluationSummary
 Closure for evaluate_connection. More...
 
struct  ChanIterCls
 Closure for iterate_channels_cb. More...
 

Macros

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

Functions

int GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
 Am I Alice or Betty (some call her Bob), or talking to myself?
 
static void mark_connection_unready (struct CadetTConnection *ct)
 Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
 
const char * GCT_2s (const struct CadetTunnel *t)
 Get the static string for the peer this tunnel is directed.
 
static const char * estate2s (enum CadetTunnelEState es)
 Get string description for tunnel encryption state.
 
struct CadetPeerGCT_get_destination (struct CadetTunnel *t)
 Return the peer to which this tunnel goes.
 
unsigned int GCT_count_channels (struct CadetTunnel *t)
 Returns the number of channels using a tunnel.
 
static struct CadetChannellookup_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Lookup a channel by its ctn.
 
unsigned int GCT_count_any_connections (const struct CadetTunnel *t)
 Counts the number of connections created for a tunnel, including busy connections.
 
static struct CadetTConnectionget_ready_connection (struct CadetTunnel *t)
 Find first connection that is ready in the list of our connections.
 
enum CadetTunnelEState GCT_get_estate (struct CadetTunnel *t)
 Get the encryption state of a tunnel.
 
static void trigger_transmissions (void *cls)
 Called when either we have a new connection, or a new message in the queue, or some existing connection has transmission capacity.
 
static void new_ephemeral (struct CadetTunnelAxolotl *ax)
 Create a new Axolotl ephemeral (ratchet) key.
 
static void t_hmac (const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
 Calculate HMAC.
 
static void t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
 Perform a HMAC.
 
static void t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
 Derive a symmetric encryption key from an HMAC-HASH.
 
static void t_ax_encrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Encrypt data with the axolotl tunnel key.
 
static void t_ax_decrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Decrypt data with the axolotl tunnel key.
 
static void t_h_encrypt (struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
 Encrypt header with the axolotl header key.
 
static void t_h_decrypt (struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
 Decrypt header with the current axolotl header key.
 
static void delete_skipped_key (struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
 Delete a key from the list of skipped keys.
 
static ssize_t try_old_ax_keys (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.
 
static void store_skipped_key (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
 Delete a key from the list of skipped keys.
 
static int store_ax_keys (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
 Stage skipped AX keys and calculate the message key.
 
static ssize_t t_ax_decrypt_and_validate (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.
 
static int notify_tunnel_up_cb (void *cls, uint32_t key, void *value)
 Our tunnel became ready for the first time, notify channels that have been waiting.
 
void GCT_change_estate (struct CadetTunnel *t, enum CadetTunnelEState state)
 Change the tunnel encryption state.
 
static void send_kx (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
 Send a KX message.
 
static void send_kx_auth (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
 Send a KX_AUTH message.
 
static void cleanup_ax (struct CadetTunnelAxolotl *ax)
 Cleanup state used by ax.
 
static int update_ax_by_kx (struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
 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.
 
void GCT_handle_kx (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
 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).
 
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 45 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 52 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 57 of file gnunet-service-cadet_tunnels.c.

82{
87
92
97
102
107
111 unsigned int Kn;
112};
113
114
119{
126
131
136
141
146
153
160
166
174
179
184
189
195
201
205 unsigned int skipped;
206
210 uint32_t Ns;
211
215 uint32_t Nr;
216
220 uint32_t PNs;
221
225 int ratchet_flag;
226
237 int ratchet_allowed;
238
251 unsigned int ratchet_counter;
252};
253
254
259{
264
269
273 struct CadetTunnel *t;
274
279
283 void *cont_cls;
284
288 struct GNUNET_MQ_Envelope *env;
289
295};
296
297
301struct CadetTunnel
302{
306 struct CadetPeer *destination;
307
313
318
323
327 struct CadetTunnelAxolotl ax;
328
337
342
347
352
357
362
366 struct GNUNET_MQ_Handle *mq;
367
372
377
382
387
393
398
403
408
415
420
425
429 unsigned int num_ready_connections;
430
434 unsigned int num_busy_connections;
435
441 unsigned int unverified_attempts;
442
446 unsigned int tq_len;
447
452
457};
458
459
466int
467GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
468{
469 if (0 > GNUNET_memcmp (&my_full_id,
470 other))
471 return GNUNET_YES;
472 else if (0 < GNUNET_memcmp (&my_full_id,
473 other))
474 return GNUNET_NO;
475 else
476 {
477 GNUNET_break_op (0);
478 return GNUNET_SYSERR;
479 }
480}
481
482
489static void
491{
492 struct CadetTunnel *t = ct->t;
493
495 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
496 t->connection_ready_tail,
497 ct);
498 GNUNET_assert (0 < t->num_ready_connections);
499 t->num_ready_connections--;
500 ct->is_ready = GNUNET_NO;
501 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
502 t->connection_busy_tail,
503 ct);
504 t->num_busy_connections++;
505}
506
507
515const char *
516GCT_2s (const struct CadetTunnel *t)
517{
518 static char buf[64];
519
520 if (NULL == t)
521 return "Tunnel(NULL)";
522 GNUNET_snprintf (buf,
523 sizeof(buf),
524 "Tunnel %s",
525 GNUNET_i2s (GCP_get_id (t->destination)));
526 return buf;
527}
528
529
537static const char *
539{
540 static char buf[32];
541
542 switch (es)
543 {
545 return "CADET_TUNNEL_KEY_UNINITIALIZED";
547 return "CADET_TUNNEL_KEY_AX_RECV";
549 return "CADET_TUNNEL_KEY_AX_SENT";
551 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
553 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
555 return "CADET_TUNNEL_KEY_OK";
556 }
557 GNUNET_snprintf (buf,
558 sizeof(buf),
559 "%u (UNKNOWN STATE)",
560 es);
561 return buf;
562}
563
564
571struct CadetPeer *
573{
574 return t->destination;
575}
576
577
578unsigned int
580{
581 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
582}
583
584
592static struct CadetChannel *
595{
596 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
597 ntohl (ctn.cn));
598}
599
600
601unsigned int
603{
604 return t->num_ready_connections + t->num_busy_connections;
605}
606
607
615static struct CadetTConnection *
617{
618 struct CadetTConnection *hd = t->connection_ready_head;
619
620 GNUNET_assert ((NULL == hd) ||
621 (GNUNET_YES == hd->is_ready));
622 return hd;
623}
624
625
635{
636 return t->estate;
637}
638
639
648static void
649trigger_transmissions (void *cls);
650
651
652/* ************************************** start core crypto ***************************** */
653
654
660static void
662{
664 "Creating new ephemeral ratchet key (DHRs)\n");
666}
667
668
678static void
679t_hmac (const void *plaintext,
680 size_t size,
681 uint32_t iv,
683 struct GNUNET_ShortHashCode *hmac)
684{
685 static const char ctx[] = "cadet authentication key";
686 struct GNUNET_CRYPTO_AuthKey auth_key;
687 struct GNUNET_HashCode hash;
688
690 key,
691 &iv, sizeof(iv),
692 key, sizeof(*key),
693 ctx, sizeof(ctx),
694 NULL);
695 /* Two step: GNUNET_ShortHash is only 256 bits,
696 GNUNET_HashCode is 512, so we truncate. */
697 GNUNET_CRYPTO_hmac (&auth_key,
698 plaintext,
699 size,
700 &hash);
701 GNUNET_memcpy (hmac,
702 &hash,
703 sizeof(*hmac));
704}
705
706
715static void
717 struct GNUNET_HashCode *hash,
718 const void *source,
719 unsigned int len)
720{
721 static const char ctx[] = "axolotl HMAC-HASH";
722 struct GNUNET_CRYPTO_AuthKey auth_key;
723
725 key,
726 ctx, sizeof(ctx),
727 NULL);
728 GNUNET_CRYPTO_hmac (&auth_key,
729 source,
730 len,
731 hash);
732}
733
734
743static void
746 const void *source,
747 unsigned int len)
748{
749 static const char ctx[] = "axolotl derive key";
750 struct GNUNET_HashCode h;
751
753 &h,
754 source,
755 len);
756 GNUNET_CRYPTO_kdf (out, sizeof(*out),
757 ctx, sizeof(ctx),
758 &h, sizeof(h),
759 NULL);
760}
761
762
771static void
773 void *dst,
774 const void *src,
775 size_t size)
776{
779 size_t out_size;
780
781 ax->ratchet_counter++;
782 if ((GNUNET_YES == ax->ratchet_allowed) &&
783 ((ratchet_messages <= ax->ratchet_counter) ||
786 {
788 }
789 if (GNUNET_YES == ax->ratchet_flag)
790 {
791 /* Advance ratchet */
793 struct GNUNET_HashCode dh;
794 struct GNUNET_HashCode hmac;
795 static const char ctx[] = "axolotl ratchet";
796
797 new_ephemeral (ax);
798 ax->HKs = ax->NHKs;
799
800 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
802 &ax->DHRr,
803 &dh);
804 t_ax_hmac_hash (&ax->RK,
805 &hmac,
806 &dh,
807 sizeof(dh));
808 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
809 ctx, sizeof(ctx),
810 &hmac, sizeof(hmac),
811 NULL);
812 ax->RK = keys[0];
813 ax->NHKs = keys[1];
814 ax->CKs = keys[2];
815
816 ax->PNs = ax->Ns;
817 ax->Ns = 0;
820 ax->ratchet_counter = 0;
824 }
825
827 &MK,
828 "0",
829 1);
831 &MK,
832 NULL, 0,
833 NULL);
834
835 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
836 size,
837 &MK,
838 &iv,
839 dst);
840 GNUNET_assert (size == out_size);
842 &ax->CKs,
843 "1",
844 1);
845}
846
847
856static void
858 void *dst,
859 const void *src,
860 size_t size)
861{
864 size_t out_size;
865
867 &MK,
868 "0",
869 1);
871 &MK,
872 NULL, 0,
873 NULL);
874 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
875 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
876 size,
877 &MK,
878 &iv,
879 dst);
880 GNUNET_assert (out_size == size);
882 &ax->CKr,
883 "1",
884 1);
885}
886
887
894static void
897{
899 size_t out_size;
900
902 &ax->HKs,
903 NULL, 0,
904 NULL);
905 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
906 sizeof(struct
908 &ax->HKs,
909 &iv,
910 &msg->ax_header);
911 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
912}
913
914
922static void
924 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
926{
928 size_t out_size;
929
931 &ax->HKr,
932 NULL, 0,
933 NULL);
935 sizeof(struct
937 &ax->HKr,
938 &iv,
939 &dst->ax_header.Ns);
940 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
941}
942
943
950static void
953{
955 ax->skipped_tail,
956 key);
958 ax->skipped--;
959}
960
961
972static ssize_t
974 void *dst,
975 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
976 size_t size)
977{
979 struct GNUNET_ShortHashCode *hmac;
981 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
982 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
983 size_t esize;
984 size_t res;
985 size_t len;
986 unsigned int N;
987
989 "Trying skipped keys\n");
990 hmac = &plaintext_header.hmac;
991 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
992
993 /* Find a correct Header Key */
994 valid_HK = NULL;
995 for (key = ax->skipped_head; NULL != key; key = key->next)
996 {
997 t_hmac (&src->ax_header,
998 sizeof(struct GNUNET_CADET_AxHeader) + esize,
999 0,
1000 &key->HK,
1001 hmac);
1002 if (0 == GNUNET_memcmp (hmac,
1003 &src->hmac))
1004 {
1005 valid_HK = &key->HK;
1006 break;
1007 }
1008 }
1009 if (NULL == key)
1010 return -1;
1011
1012 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1014 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1015 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1016
1017 /* Decrypt header */
1019 &key->HK,
1020 NULL, 0,
1021 NULL);
1023 sizeof(struct GNUNET_CADET_AxHeader),
1024 &key->HK,
1025 &iv,
1026 &plaintext_header.ax_header.Ns);
1027 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1028
1029 /* Find the correct message key */
1030 N = ntohl (plaintext_header.ax_header.Ns);
1031 while ((NULL != key) &&
1032 (N != key->Kn))
1033 key = key->next;
1034 if ((NULL == key) ||
1035 (0 != GNUNET_memcmp (&key->HK,
1036 valid_HK)))
1037 return -1;
1038
1039 /* Decrypt payload */
1041 &key->MK,
1042 NULL,
1043 0,
1044 NULL);
1046 len,
1047 &key->MK,
1048 &iv,
1049 dst);
1051 key);
1052 return res;
1053}
1054
1055
1062static void
1064 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1065{
1066 struct CadetTunnelSkippedKey *key;
1067
1069 key->timestamp = GNUNET_TIME_absolute_get ();
1070 key->Kn = ax->Nr;
1071 key->HK = ax->HKr;
1072 t_hmac_derive_key (&ax->CKr,
1073 &key->MK,
1074 "0",
1075 1);
1076 t_hmac_derive_key (&ax->CKr,
1077 &ax->CKr,
1078 "1",
1079 1);
1081 ax->skipped_tail,
1082 key);
1083 ax->skipped++;
1084 ax->Nr++;
1085}
1086
1087
1098static int
1100 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1101 uint32_t Np)
1102{
1103 int gap;
1104
1105 gap = Np - ax->Nr;
1107 "Storing skipped keys [%u, %u)\n",
1108 ax->Nr,
1109 Np);
1110 if (MAX_KEY_GAP < gap)
1111 {
1112 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1113 /* TODO: start new key exchange on return */
1114 GNUNET_break_op (0);
1116 "Got message %u, expected %u+\n",
1117 Np,
1118 ax->Nr);
1119 return GNUNET_SYSERR;
1120 }
1121 if (0 > gap)
1122 {
1123 /* Delayed message: don't store keys, flag to try old keys. */
1124 return GNUNET_SYSERR;
1125 }
1126
1127 while (ax->Nr < Np)
1129 HKr);
1130
1131 while (ax->skipped > MAX_SKIPPED_KEYS)
1133 ax->skipped_tail);
1134 return GNUNET_OK;
1135}
1136
1137
1148static ssize_t
1150 void *dst,
1151 const struct
1153 size_t size)
1154{
1155 struct GNUNET_ShortHashCode msg_hmac;
1156 struct GNUNET_HashCode hmac;
1157 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1158 uint32_t Np;
1159 uint32_t PNp;
1160 size_t esize; /* Size of encrypted payload */
1161
1162 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1163
1164 /* Try current HK */
1165 t_hmac (&src->ax_header,
1166 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1167 0, &ax->HKr,
1168 &msg_hmac);
1169 if (0 != GNUNET_memcmp (&msg_hmac,
1170 &src->hmac))
1171 {
1172 static const char ctx[] = "axolotl ratchet";
1173 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1175 struct GNUNET_HashCode dh;
1176 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1177
1178 /* Try Next HK */
1179 t_hmac (&src->ax_header,
1180 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1181 0,
1182 &ax->NHKr,
1183 &msg_hmac);
1184 if (0 != GNUNET_memcmp (&msg_hmac,
1185 &src->hmac))
1186 {
1187 /* Try the skipped keys, if that fails, we're out of luck. */
1188 return try_old_ax_keys (ax,
1189 dst,
1190 src,
1191 size);
1192 }
1193 HK = ax->HKr;
1194 ax->HKr = ax->NHKr;
1195 t_h_decrypt (ax,
1196 src,
1197 &plaintext_header);
1198 Np = ntohl (plaintext_header.ax_header.Ns);
1199 PNp = ntohl (plaintext_header.ax_header.PNs);
1200 DHRp = &plaintext_header.ax_header.DHRs;
1201 store_ax_keys (ax,
1202 &HK,
1203 PNp);
1204
1205 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1207 DHRp,
1208 &dh);
1209 t_ax_hmac_hash (&ax->RK,
1210 &hmac,
1211 &dh, sizeof(dh));
1212 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1213 ctx, sizeof(ctx),
1214 &hmac, sizeof(hmac),
1215 NULL);
1216
1217 /* Commit "purported" keys */
1218 ax->RK = keys[0];
1219 ax->NHKr = keys[1];
1220 ax->CKr = keys[2];
1221 ax->DHRr = *DHRp;
1222 ax->Nr = 0;
1224 }
1225 else
1226 {
1227 t_h_decrypt (ax,
1228 src,
1229 &plaintext_header);
1230 Np = ntohl (plaintext_header.ax_header.Ns);
1231 PNp = ntohl (plaintext_header.ax_header.PNs);
1232 }
1233 if ((Np != ax->Nr) &&
1234 (GNUNET_OK != store_ax_keys (ax,
1235 &ax->HKr,
1236 Np)))
1237 {
1238 /* Try the skipped keys, if that fails, we're out of luck. */
1239 return try_old_ax_keys (ax,
1240 dst,
1241 src,
1242 size);
1243 }
1244
1245 t_ax_decrypt (ax,
1246 dst,
1247 &src[1],
1248 esize);
1249 ax->Nr = Np + 1;
1250 return esize;
1251}
1252
1253
1263static int
1264notify_tunnel_up_cb (void *cls,
1265 uint32_t key,
1266 void *value)
1267{
1268 struct CadetChannel *ch = value;
1269
1271 return GNUNET_OK;
1272}
1273
1274
1282void
1285{
1286 enum CadetTunnelEState old = t->estate;
1287
1288 t->estate = state;
1290 "%s estate changed from %s to %s\n",
1291 GCT_2s (t),
1292 estate2s (old),
1293 estate2s (state));
1294
1295 if ((CADET_TUNNEL_KEY_OK != old) &&
1296 (CADET_TUNNEL_KEY_OK == t->estate))
1297 {
1298 if (NULL != t->kx_task)
1299 {
1300 GNUNET_SCHEDULER_cancel (t->kx_task);
1301 t->kx_task = NULL;
1302 }
1303 /* notify all channels that have been waiting */
1306 t);
1307 if (NULL != t->send_task)
1308 GNUNET_SCHEDULER_cancel (t->send_task);
1310 t);
1311 }
1312}
1313
1314
1323static void
1324send_kx (struct CadetTunnel *t,
1325 struct CadetTConnection *ct,
1326 struct CadetTunnelAxolotl *ax)
1327{
1328 struct CadetConnection *cc;
1329 struct GNUNET_MQ_Envelope *env;
1332
1333 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1334 return; /* only Alice may send KX */
1335 if ((NULL == ct) ||
1336 (GNUNET_NO == ct->is_ready))
1337 ct = get_ready_connection (t);
1338 if (NULL == ct)
1339 {
1341 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1342 GCT_2s (t),
1343 estate2s (t->estate));
1344 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1345 return;
1346 }
1347 cc = ct->cc;
1350 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1351 msg->flags = htonl (flags);
1352 msg->cid = *GCC_get_id (cc);
1354 &msg->ephemeral_key);
1355#if DEBUG_KX
1356 msg->ephemeral_key_XXX = ax->kx_0;
1357 msg->private_key_XXX = *my_private_key;
1358#endif
1360 "Sending KX message to %s with ephemeral %s on CID %s\n",
1361 GCT_2s (t),
1362 GNUNET_e2s (&msg->ephemeral_key),
1363 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1365 &msg->ratchet_key);
1367 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1368 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1369 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1372 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1375 GCC_transmit (cc,
1376 env);
1378 "# KX transmitted",
1379 1,
1380 GNUNET_NO);
1381}
1382
1383
1394static void
1395send_kx_auth (struct CadetTunnel *t,
1396 struct CadetTConnection *ct,
1397 struct CadetTunnelAxolotl *ax,
1398 int force_reply)
1399{
1400 struct CadetConnection *cc;
1401 struct GNUNET_MQ_Envelope *env;
1403 enum GNUNET_CADET_KX_Flags flags;
1404
1405 if ((NULL == ct) ||
1406 (GNUNET_NO == ct->is_ready))
1407 ct = get_ready_connection (t);
1408 if (NULL == ct)
1409 {
1411 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1412 GCT_2s (t));
1413 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1414 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1415 return;
1416 }
1417 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1418 cc = ct->cc;
1422 if (GNUNET_YES == force_reply)
1424 msg->kx.flags = htonl (flags);
1425 msg->kx.cid = *GCC_get_id (cc);
1427 &msg->kx.ephemeral_key);
1429 &msg->kx.ratchet_key);
1430#if DEBUG_KX
1431 msg->kx.ephemeral_key_XXX = ax->kx_0;
1432 msg->kx.private_key_XXX = *my_private_key;
1433 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1434#endif
1436 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1437 GCT_2s (t),
1438 GNUNET_e2s (&msg->kx.ephemeral_key),
1439 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1440
1441 /* Compute authenticator (this is the main difference to #send_kx()) */
1442 GNUNET_CRYPTO_hash (&ax->RK,
1443 sizeof(ax->RK),
1444 &msg->auth);
1445 /* Compute when to be triggered again; actual job will
1446 be scheduled via #connection_ready_cb() */
1447 t->kx_retry_delay
1448 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1449 t->next_kx_attempt
1450 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1451
1452 /* Send via cc, mark it as unready */
1454
1455 /* Update state machine, unless we are already OK */
1456 if (CADET_TUNNEL_KEY_OK != t->estate)
1459 GCC_transmit (cc,
1460 env);
1462 "# KX_AUTH transmitted",
1463 1,
1464 GNUNET_NO);
1465}
1466
1467
1473static void
1474cleanup_ax (struct CadetTunnelAxolotl *ax)
1475{
1476 while (NULL != ax->skipped_head)
1478 ax->skipped_head);
1479 GNUNET_assert (0 == ax->skipped);
1482}
1483
1484
1498static int
1500 const struct GNUNET_PeerIdentity *pid,
1501 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
1502 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
1503{
1504 struct GNUNET_HashCode key_material[3];
1505 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1506 const char salt[] = "CADET Axolotl salt";
1507 int am_I_alice;
1508
1509 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1510 {
1511 GNUNET_break_op (0);
1512 return GNUNET_SYSERR;
1513 }
1514 if (0 == GNUNET_memcmp (&ax->DHRr,
1515 ratchet_key))
1516 {
1518 "# Ratchet key already known",
1519 1,
1520 GNUNET_NO);
1522 "Ratchet key already known. Ignoring KX.\n");
1523 return GNUNET_NO;
1524 }
1525
1526 ax->DHRr = *ratchet_key;
1527 ax->last_ephemeral = *ephemeral_key;
1528 /* ECDH A B0 */
1529 if (GNUNET_YES == am_I_alice)
1530 {
1532 ephemeral_key, /* B0 */
1533 &key_material[0]);
1534 }
1535 else
1536 {
1537 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1538 &pid->public_key, /* A */
1539 &key_material[0]);
1540 }
1541 /* ECDH A0 B */
1542 if (GNUNET_YES == am_I_alice)
1543 {
1544 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1545 &pid->public_key, /* B */
1546 &key_material[1]);
1547 }
1548 else
1549 {
1551 ephemeral_key, /* A0 */
1552 &key_material[1]);
1553 }
1554
1555 /* ECDH A0 B0 */
1556 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1557 ephemeral_key, /* B0 or A0 */
1558 &key_material[2]);
1559 /* KDF */
1560 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1561 salt, sizeof(salt),
1562 &key_material, sizeof(key_material),
1563 NULL);
1564
1565 if (0 == memcmp (&ax->RK,
1566 &keys[0],
1567 sizeof(ax->RK)))
1568 {
1570 "Root key already known. Ignoring KX.\n");
1572 "# Root key already known",
1573 1,
1574 GNUNET_NO);
1575 return GNUNET_NO;
1576 }
1577
1578 ax->RK = keys[0];
1579 if (GNUNET_YES == am_I_alice)
1580 {
1581 ax->HKr = keys[1];
1582 ax->NHKs = keys[2];
1583 ax->NHKr = keys[3];
1584 ax->CKr = keys[4];
1586 }
1587 else
1588 {
1589 ax->HKs = keys[1];
1590 ax->NHKr = keys[2];
1591 ax->NHKs = keys[3];
1592 ax->CKs = keys[4];
1593 ax->ratchet_flag = GNUNET_NO;
1596 ratchet_time);
1597 }
1598 return GNUNET_OK;
1599}
1600
1601
1607static void
1608retry_kx (void *cls)
1609{
1610 struct CadetTunnel *t = cls;
1611 struct CadetTunnelAxolotl *ax;
1612
1613 t->kx_task = NULL;
1615 "Trying to make KX progress on %s in state %s\n",
1616 GCT_2s (t),
1617 estate2s (t->estate));
1618 switch (t->estate)
1619 {
1620 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1621 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1622 send_kx (t,
1623 NULL,
1624 &t->ax);
1625 break;
1626
1629 /* We are responding, so only require reply
1630 if WE have a channel waiting. */
1631 if (NULL != t->unverified_ax)
1632 {
1633 /* Send AX_AUTH so we might get this one verified */
1634 ax = t->unverified_ax;
1635 }
1636 else
1637 {
1638 /* How can this be? */
1639 GNUNET_break (0);
1640 ax = &t->ax;
1641 }
1642 send_kx_auth (t,
1643 NULL,
1644 ax,
1645 (0 == GCT_count_channels (t))
1646 ? GNUNET_NO
1647 : GNUNET_YES);
1648 break;
1649
1651 /* We are responding, so only require reply
1652 if WE have a channel waiting. */
1653 if (NULL != t->unverified_ax)
1654 {
1655 /* Send AX_AUTH so we might get this one verified */
1656 ax = t->unverified_ax;
1657 }
1658 else
1659 {
1660 /* How can this be? */
1661 GNUNET_break (0);
1662 ax = &t->ax;
1663 }
1664 send_kx_auth (t,
1665 NULL,
1666 ax,
1667 (0 == GCT_count_channels (t))
1668 ? GNUNET_NO
1669 : GNUNET_YES);
1670 break;
1671
1673 /* Must have been the *other* peer asking us to
1674 respond with a KX_AUTH. */
1675 if (NULL != t->unverified_ax)
1676 {
1677 /* Sending AX_AUTH in response to AX so we might get this one verified */
1678 ax = t->unverified_ax;
1679 }
1680 else
1681 {
1682 /* Sending AX_AUTH in response to AX_AUTH */
1683 ax = &t->ax;
1684 }
1685 send_kx_auth (t,
1686 NULL,
1687 ax,
1688 GNUNET_NO);
1689 break;
1690 }
1691}
1692
1693
1694void
1697{
1698 struct CadetTunnel *t = ct->t;
1699 int ret;
1700
1702 "# KX received",
1703 1,
1704 GNUNET_NO);
1705 if (GNUNET_YES ==
1706 GCT_alice_or_betty (GCP_get_id (t->destination)))
1707 {
1708 /* Betty/Bob is not allowed to send KX! */
1709 GNUNET_break_op (0);
1710 return;
1711 }
1713 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1714 GCT_2s (t),
1715 GNUNET_e2s (&msg->ephemeral_key),
1716 GNUNET_i2s (GCP_get_id (t->destination)),
1717 GCC_2s (ct->cc));
1718#if 1
1719 if ((0 ==
1720 memcmp (&t->ax.DHRr,
1721 &msg->ratchet_key,
1722 sizeof(msg->ratchet_key))) &&
1723 (0 ==
1724 memcmp (&t->ax.last_ephemeral,
1725 &msg->ephemeral_key,
1726 sizeof(msg->ephemeral_key))))
1727
1728 {
1730 "# Duplicate KX received",
1731 1,
1732 GNUNET_NO);
1733 send_kx_auth (t,
1734 ct,
1735 &t->ax,
1736 GNUNET_NO);
1737 return;
1738 }
1739#endif
1740 /* We only keep ONE unverified KX around, so if there is an existing one,
1741 clean it up. */
1742 if (NULL != t->unverified_ax)
1743 {
1744 if ((0 ==
1745 memcmp (&t->unverified_ax->DHRr,
1746 &msg->ratchet_key,
1747 sizeof(msg->ratchet_key))) &&
1748 (0 ==
1749 memcmp (&t->unverified_ax->last_ephemeral,
1750 &msg->ephemeral_key,
1751 sizeof(msg->ephemeral_key))))
1752 {
1754 "# Duplicate unverified KX received",
1755 1,
1756 GNUNET_NO);
1757#if 1
1758 send_kx_auth (t,
1759 ct,
1760 t->unverified_ax,
1761 GNUNET_NO);
1762 return;
1763#endif
1764 }
1766 "Dropping old unverified KX state.\n");
1768 "# Unverified KX dropped for fresh KX",
1769 1,
1770 GNUNET_NO);
1771 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1772 memset (t->unverified_ax,
1773 0,
1774 sizeof(struct CadetTunnelAxolotl));
1775 }
1776 else
1777 {
1779 "Creating fresh unverified KX for %s\n",
1780 GCT_2s (t));
1782 "# Fresh KX setup",
1783 1,
1784 GNUNET_NO);
1785 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1786 }
1787 /* Set as the 'current' RK/DHRr the one we are currently using,
1788 so that the duplicate-detection logic of
1789 #update_ax_by_kx can work. */
1790 t->unverified_ax->RK = t->ax.RK;
1791 t->unverified_ax->DHRr = t->ax.DHRr;
1792 t->unverified_ax->DHRs = t->ax.DHRs;
1793 t->unverified_ax->kx_0 = t->ax.kx_0;
1794 t->unverified_attempts = 0;
1795
1796 /* Update 'ax' by the new key material */
1797 ret = update_ax_by_kx (t->unverified_ax,
1798 GCP_get_id (t->destination),
1799 &msg->ephemeral_key,
1800 &msg->ratchet_key);
1802 if (GNUNET_OK != ret)
1803 {
1805 "# Useless KX",
1806 1,
1807 GNUNET_NO);
1808 return; /* duplicate KX, nothing to do */
1809 }
1810 /* move ahead in our state machine */
1811 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1814 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1817
1818 /* KX is still not done, try again our end. */
1819 if (CADET_TUNNEL_KEY_OK != t->estate)
1820 {
1821 if (NULL != t->kx_task)
1822 GNUNET_SCHEDULER_cancel (t->kx_task);
1823 t->kx_task
1825 t);
1826 }
1827}
1828
1829
1830#if DEBUG_KX
1831static void
1832check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1833 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1834{
1837 struct GNUNET_HashCode hc1;
1838 struct GNUNET_HashCode hc2;
1839
1841 &p1);
1843 &p2);
1846 &p2,
1847 &hc1));
1850 &p1,
1851 &hc2));
1852 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1853 &hc2));
1854}
1855
1856
1857static void
1858check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1859 const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1860{
1863 struct GNUNET_HashCode hc1;
1864 struct GNUNET_HashCode hc2;
1865
1867 &p1);
1869 &p2);
1872 &p2,
1873 &hc1));
1876 &p1,
1877 &hc2));
1878 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1879 &hc2));
1880}
1881
1882
1883static void
1884test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1885 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1886 const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1887 const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1888{
1889 check_ee (e1, e2);
1890 check_ed (e1, d2);
1891 check_ed (e2, d1);
1892}
1893
1894
1895#endif
1896
1897
1904void
1907{
1908 struct CadetTunnel *t = ct->t;
1909 struct CadetTunnelAxolotl ax_tmp;
1910 struct GNUNET_HashCode kx_auth;
1911 int ret;
1912
1914 "# KX_AUTH received",
1915 1,
1916 GNUNET_NO);
1917 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1918 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1919 {
1920 /* Confusing, we got a KX_AUTH before we even send our own
1921 KX. This should not happen. We'll send our own KX ASAP anyway,
1922 so let's ignore this here. */
1923 GNUNET_break_op (0);
1924 return;
1925 }
1927 "Handling KX_AUTH message from %s with ephemeral %s\n",
1928 GCT_2s (t),
1929 GNUNET_e2s (&msg->kx.ephemeral_key));
1930 /* We do everything in ax_tmp until we've checked the authentication
1931 so we don't clobber anything we care about by accident. */
1932 ax_tmp = t->ax;
1933
1934 /* Update 'ax' by the new key material */
1935 ret = update_ax_by_kx (&ax_tmp,
1936 GCP_get_id (t->destination),
1937 &msg->kx.ephemeral_key,
1938 &msg->kx.ratchet_key);
1939 if (GNUNET_OK != ret)
1940 {
1941 if (GNUNET_NO == ret)
1943 "# redundant KX_AUTH received",
1944 1,
1945 GNUNET_NO);
1946 else
1947 GNUNET_break (0); /* connect to self!? */
1948 return;
1949 }
1950 GNUNET_CRYPTO_hash (&ax_tmp.RK,
1951 sizeof(ax_tmp.RK),
1952 &kx_auth);
1953 if (0 != GNUNET_memcmp (&kx_auth,
1954 &msg->auth))
1955 {
1956 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1957 we transmitted to the sender, refuse it, try KX again. */
1959 "# KX_AUTH not using our last KX received (auth failure)",
1960 1,
1961 GNUNET_NO);
1963 "KX AUTH mismatch!\n");
1964#if DEBUG_KX
1965 {
1966 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1967
1969 &ephemeral_key);
1970 if (0 != GNUNET_memcmp (&ephemeral_key,
1971 &msg->r_ephemeral_key_XXX))
1972 {
1974 "My ephemeral is %s!\n",
1975 GNUNET_e2s (&ephemeral_key));
1977 "Response is for ephemeral %s!\n",
1978 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
1979 }
1980 else
1981 {
1982 test_crypto_bug (&ax_tmp.kx_0,
1983 &msg->kx.ephemeral_key_XXX,
1985 &msg->kx.private_key_XXX);
1986 }
1987 }
1988#endif
1989 if (NULL == t->kx_task)
1990 t->kx_task
1991 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1992 &retry_kx,
1993 t);
1994 return;
1995 }
1996 /* Yep, we're good. */
1997 t->ax = ax_tmp;
1998 if (NULL != t->unverified_ax)
1999 {
2000 /* We got some "stale" KX before, drop that. */
2001 cleanup_ax (t->unverified_ax);
2002 GNUNET_free (t->unverified_ax);
2003 t->unverified_ax = NULL;
2004 }
2005
2006 /* move ahead in our state machine */
2007 switch (t->estate)
2008 {
2011 /* Checked above, this is impossible. */
2012 GNUNET_assert (0);
2013 break;
2014
2015 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2016 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2017 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2020 break;
2021
2023 /* Did not expect another KX_AUTH, but so what, still acceptable.
2024 Nothing to do here. */
2025 break;
2026 }
2027 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2028 {
2029 send_kx_auth (t,
2030 NULL,
2031 &t->ax,
2032 GNUNET_NO);
2033 }
2034}
2035
2036
2037/* ************************************** end core crypto ***************************** */
2038
2039
2048{
2049#define HIGH_BIT 0x8000000
2051 uint32_t ctn;
2052 int cmp;
2053 uint32_t highbit;
2054
2055 cmp = GNUNET_memcmp (&my_full_id,
2057 if (0 < cmp)
2058 highbit = HIGH_BIT;
2059 else if (0 > cmp)
2060 highbit = 0;
2061 else
2062 GNUNET_assert (0); // loopback must never go here!
2063 ctn = ntohl (t->next_ctn.cn);
2064 while (NULL !=
2066 ctn | highbit))
2067 {
2068 ctn = ((ctn + 1) & (~HIGH_BIT));
2069 }
2070 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2071 ret.cn = htonl (ctn | highbit);
2072 return ret;
2073}
2074
2075
2087 struct CadetChannel *ch)
2088{
2090
2091 ctn = get_next_free_ctn (t);
2092 if (NULL != t->destroy_task)
2093 {
2094 GNUNET_SCHEDULER_cancel (t->destroy_task);
2095 t->destroy_task = NULL;
2096 }
2099 ntohl (ctn.cn),
2100 ch,
2103 "Adding %s to %s with state %d\n",
2104 GCCH_2s (ch),
2105 GCT_2s (t),
2106 t->estate);
2107 switch (t->estate)
2108 {
2110 /* waiting for connection to start KX */
2111 break;
2112
2116 /* we're currently waiting for KX to complete */
2117 break;
2118
2120 /* waiting for OTHER peer to send us data,
2121 we might need to prompt more aggressively! */
2122 if (NULL == t->kx_task)
2123 t->kx_task
2124 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2125 &retry_kx,
2126 t);
2127 break;
2128
2130 /* We are ready. Tell the new channel that we are up. */
2132 break;
2133 }
2134 return ctn;
2135}
2136
2137
2144void
2146{
2147 struct CadetTunnel *t = ct->t;
2148
2149 if (GNUNET_YES == ct->is_ready)
2150 {
2151 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2152 t->connection_ready_tail,
2153 ct);
2154 t->num_ready_connections--;
2155 }
2156 else
2157 {
2158 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2159 t->connection_busy_tail,
2160 ct);
2161 t->num_busy_connections--;
2162 }
2163 GNUNET_free (ct);
2164}
2165
2166
2173static void
2174destroy_t_connection (void *cls,
2175 struct CadetTConnection *ct)
2176{
2177 struct CadetTunnel *t = cls;
2178 struct CadetConnection *cc = ct->cc;
2179
2180 GNUNET_assert (ct->t == t);
2183}
2184
2185
2191static void
2192destroy_tunnel (void *cls)
2193{
2194 struct CadetTunnel *t = cls;
2195 struct CadetTunnelQueueEntry *tq;
2196
2197 t->destroy_task = NULL;
2199 "Destroying idle %s\n",
2200 GCT_2s (t));
2204 t);
2205 GNUNET_assert (NULL == t->connection_ready_head);
2206 GNUNET_assert (NULL == t->connection_busy_head);
2207 while (NULL != (tq = t->tq_head))
2208 {
2209 if (NULL != tq->cont)
2210 tq->cont (tq->cont_cls,
2211 NULL);
2212 GCT_send_cancel (tq);
2213 }
2214 GCP_drop_tunnel (t->destination,
2215 t);
2217 if (NULL != t->maintain_connections_task)
2218 {
2219 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2220 t->maintain_connections_task = NULL;
2221 }
2222 if (NULL != t->send_task)
2223 {
2224 GNUNET_SCHEDULER_cancel (t->send_task);
2225 t->send_task = NULL;
2226 }
2227 if (NULL != t->kx_task)
2228 {
2229 GNUNET_SCHEDULER_cancel (t->kx_task);
2230 t->kx_task = NULL;
2231 }
2232 GNUNET_MST_destroy (t->mst);
2233 GNUNET_MQ_destroy (t->mq);
2234 if (NULL != t->unverified_ax)
2235 {
2236 cleanup_ax (t->unverified_ax);
2237 GNUNET_free (t->unverified_ax);
2238 }
2239 cleanup_ax (&t->ax);
2240 GNUNET_assert (NULL == t->destroy_task);
2241 GNUNET_free (t);
2242}
2243
2244
2252void
2254 struct CadetChannel *ch,
2256{
2258 "Removing %s from %s\n",
2259 GCCH_2s (ch),
2260 GCT_2s (t));
2263 ntohl (ctn.cn),
2264 ch));
2265 if ((0 ==
2266 GCT_count_channels (t)) &&
2267 (NULL == t->destroy_task))
2268 {
2269 t->destroy_task
2272 t);
2273 }
2274}
2275
2276
2285static int
2287 uint32_t key,
2288 void *value)
2289{
2290 struct CadetChannel *ch = value;
2291
2293 NULL);
2294 return GNUNET_OK;
2295}
2296
2297
2303void
2305{
2309 t);
2310 GNUNET_assert (0 ==
2312 if (NULL != t->destroy_task)
2313 {
2314 GNUNET_SCHEDULER_cancel (t->destroy_task);
2315 t->destroy_task = NULL;
2316 }
2317 destroy_tunnel (t);
2318}
2319
2320
2328static void
2330 struct CadetTConnection *ct)
2331{
2332 struct CadetTunnelQueueEntry *tq;
2333
2335 tq = t->tq_head;
2336 if (NULL == tq)
2337 {
2338 /* no messages pending right now */
2340 "Not sending payload of %s on ready %s (nothing pending)\n",
2341 GCT_2s (t),
2342 GCC_2s (ct->cc));
2343 return;
2344 }
2345 /* ready to send message 'tq' on tunnel 'ct' */
2346 GNUNET_assert (t == tq->t);
2348 t->tq_tail,
2349 tq);
2350 if (NULL != tq->cid)
2351 *tq->cid = *GCC_get_id (ct->cc);
2354 "Sending payload of %s on %s\n",
2355 GCT_2s (t),
2356 GCC_2s (ct->cc));
2357 GCC_transmit (ct->cc,
2358 tq->env);
2359 if (NULL != tq->cont)
2360 tq->cont (tq->cont_cls,
2361 GCC_get_id (ct->cc));
2362 GNUNET_free (tq);
2363}
2364
2365
2374static void
2375connection_ready_cb (void *cls,
2376 int is_ready)
2377{
2378 struct CadetTConnection *ct = cls;
2379 struct CadetTunnel *t = ct->t;
2380
2381 if (GNUNET_NO == is_ready)
2382 {
2384 "%s no longer ready for %s\n",
2385 GCC_2s (ct->cc),
2386 GCT_2s (t));
2388 return;
2389 }
2391 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2392 t->connection_busy_tail,
2393 ct);
2394 GNUNET_assert (0 < t->num_busy_connections);
2395 t->num_busy_connections--;
2396 ct->is_ready = GNUNET_YES;
2397 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2398 t->connection_ready_tail,
2399 ct);
2400 t->num_ready_connections++;
2401
2403 "%s now ready for %s in state %s\n",
2404 GCC_2s (ct->cc),
2405 GCT_2s (t),
2406 estate2s (t->estate));
2407 switch (t->estate)
2408 {
2411 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2412 GCT_2s (t),
2413 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2414 t->next_kx_attempt).rel_value_us);
2415 /* Do not begin KX if WE have no channels waiting! */
2417 t->next_kx_attempt).rel_value_us)
2418 return; /* wait for timeout before retrying */
2419 /* We are uninitialized, just transmit immediately,
2420 without undue delay. */
2421
2423 "Why for %s \n",
2424 GCT_2s (t));
2425
2426 if (NULL != t->kx_task)
2427 {
2428 GNUNET_SCHEDULER_cancel (t->kx_task);
2429 t->kx_task = NULL;
2430 }
2431 send_kx (t,
2432 ct,
2433 &t->ax);
2434 if ((0 ==
2435 GCT_count_channels (t)) &&
2436 (NULL == t->destroy_task))
2437 {
2438 t->destroy_task
2441 t);
2442 }
2443 break;
2444
2449 /* we're currently waiting for KX to complete, schedule job */
2450 if (NULL == t->kx_task)
2451 t->kx_task
2452 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2453 &retry_kx,
2454 t);
2455 break;
2456
2458 if (GNUNET_YES == t->kx_auth_requested)
2459 {
2461 t->next_kx_attempt).rel_value_us)
2462 return; /* wait for timeout */
2463 if (NULL != t->kx_task)
2464 {
2465 GNUNET_SCHEDULER_cancel (t->kx_task);
2466 t->kx_task = NULL;
2467 }
2468 send_kx_auth (t,
2469 ct,
2470 &t->ax,
2471 GNUNET_NO);
2472 return;
2473 }
2475 ct);
2476 break;
2477 }
2478}
2479
2480
2489static void
2490trigger_transmissions (void *cls)
2491{
2492 struct CadetTunnel *t = cls;
2493 struct CadetTConnection *ct;
2494
2495 t->send_task = NULL;
2496 if (NULL == t->tq_head)
2497 return; /* no messages pending right now */
2498 ct = get_ready_connection (t);
2499 if (NULL == ct)
2500 return; /* no connections ready */
2502 ct);
2503}
2504
2505
2510struct EvaluationSummary
2511{
2515 unsigned int min_length;
2516
2520 unsigned int max_length;
2521
2526
2531
2535 struct CadetPeerPath *path;
2536
2541 struct CadetTConnection *worst;
2542
2546 double worst_score;
2547
2551 int duplicate;
2552};
2553
2554
2562static void
2563evaluate_connection (void *cls,
2564 struct CadetTConnection *ct)
2565{
2566 struct EvaluationSummary *es = cls;
2567 struct CadetConnection *cc = ct->cc;
2568 unsigned int ct_length;
2569 struct CadetPeerPath *ps;
2570 const struct CadetConnectionMetrics *metrics;
2571 GNUNET_CONTAINER_HeapCostType ct_desirability;
2572 struct GNUNET_TIME_Relative uptime;
2573 struct GNUNET_TIME_Relative last_use;
2574 double score;
2575 double success_rate;
2576
2577 ps = GCC_get_path (cc,
2578 &ct_length);
2580 "Evaluating path %s of existing %s\n",
2581 GCPP_2s (ps),
2582 GCC_2s (cc));
2583 if (ps == es->path)
2584 {
2586 "Ignoring duplicate path %s.\n",
2587 GCPP_2s (es->path));
2588 es->duplicate = GNUNET_YES;
2589 return;
2590 }
2591 if (NULL != es->path)
2592 {
2593 int duplicate = GNUNET_YES;
2594
2595 for (unsigned int i = 0; i < ct_length; i++)
2596 {
2599 i) !=
2601 i))
2602 {
2603 duplicate = GNUNET_NO;
2604 break;
2605 }
2606 }
2607 if (GNUNET_YES == duplicate)
2608 {
2610 "Ignoring overlapping path %s.\n",
2611 GCPP_2s (es->path));
2612 es->duplicate = GNUNET_YES;
2613 return;
2614 }
2615 else
2616 {
2618 "Known path %s differs from proposed path\n",
2619 GCPP_2s (ps));
2620 }
2621 }
2622
2623 ct_desirability = GCPP_get_desirability (ps);
2624 metrics = GCC_get_metrics (cc);
2625 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2626 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2627 /* We add 1.0 here to avoid division by zero. */
2628 success_rate = (metrics->num_acked_transmissions + 1.0)
2629 / (metrics->num_successes + 1.0);
2630 score
2631 = ct_desirability
2632 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2633 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2634 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2635 score *= success_rate; /* weigh overall by success rate */
2636
2637 if ((NULL == es->worst) ||
2638 (score < es->worst_score))
2639 {
2640 es->worst = ct;
2641 es->worst_score = score;
2642 }
2643 es->min_length = GNUNET_MIN (es->min_length,
2644 ct_length);
2645 es->max_length = GNUNET_MAX (es->max_length,
2646 ct_length);
2647 es->min_desire = GNUNET_MIN (es->min_desire,
2648 ct_desirability);
2649 es->max_desire = GNUNET_MAX (es->max_desire,
2650 ct_desirability);
2651}
2652
2653
2663static int
2664consider_path_cb (void *cls,
2665 struct CadetPeerPath *path,
2666 unsigned int off)
2667{
2668 struct CadetTunnel *t = cls;
2669 struct EvaluationSummary es;
2670 struct CadetTConnection *ct;
2671
2672 GNUNET_assert (off < GCPP_get_length (path));
2674 off) == t->destination);
2675 es.min_length = UINT_MAX;
2676 es.max_length = 0;
2677 es.max_desire = 0;
2678 es.min_desire = UINT64_MAX;
2679 es.path = path;
2680 es.duplicate = GNUNET_NO;
2681 es.worst = NULL;
2682
2683 /* Compute evaluation summary over existing connections. */
2685 "Evaluating proposed path %s for target %s\n",
2686 GCPP_2s (path),
2687 GCT_2s (t));
2688 /* FIXME: suspect this does not ACTUALLY iterate
2689 over all existing paths, otherwise dup detection
2690 should work!!! */
2693 &es);
2694 if (GNUNET_YES == es.duplicate)
2695 return GNUNET_YES;
2696
2697 /* FIXME: not sure we should really just count
2698 'num_connections' here, as they may all have
2699 consistently failed to connect. */
2700
2701 /* We iterate by increasing path length; if we have enough paths and
2702 this one is more than twice as long than what we are currently
2703 using, then ignore all of these super-long ones! */
2705 (es.min_length * 2 < off) &&
2706 (es.max_length < off))
2707 {
2709 "Ignoring paths of length %u, they are way too long.\n",
2710 es.min_length * 2);
2711 return GNUNET_NO;
2712 }
2713 /* If we have enough paths and this one looks no better, ignore it. */
2715 (es.min_length < GCPP_get_length (path)) &&
2716 (es.min_desire > GCPP_get_desirability (path)) &&
2717 (es.max_length < off))
2718 {
2720 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2721 GCPP_get_length (path),
2722 (unsigned long long) GCPP_get_desirability (path),
2723 GCP_2s (t->destination));
2724 return GNUNET_YES;
2725 }
2726
2727 /* Path is interesting (better by some metric, or we don't have
2728 enough paths yet). */
2729 ct = GNUNET_new (struct CadetTConnection);
2731 ct->t = t;
2732 ct->cc = GCC_create (t->destination,
2733 path,
2734 off,
2735 ct,
2737 ct);
2738
2739 /* FIXME: schedule job to kill connection (and path?) if it takes
2740 too long to get ready! (And track performance data on how long
2741 other connections took with the tunnel!)
2742 => Note: to be done within 'connection'-logic! */
2743 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2744 t->connection_busy_tail,
2745 ct);
2746 t->num_busy_connections++;
2748 "Found interesting path %s for %s, created %s\n",
2749 GCPP_2s (path),
2750 GCT_2s (t),
2751 GCC_2s (ct->cc));
2752 return GNUNET_YES;
2753}
2754
2755
2769static void
2770maintain_connections_cb (void *cls)
2771{
2772 struct CadetTunnel *t = cls;
2773 struct GNUNET_TIME_Relative delay;
2774 struct EvaluationSummary es;
2775
2776 t->maintain_connections_task = NULL;
2778 "Performing connection maintenance for %s.\n",
2779 GCT_2s (t));
2780
2781 es.min_length = UINT_MAX;
2782 es.max_length = 0;
2783 es.max_desire = 0;
2784 es.min_desire = UINT64_MAX;
2785 es.path = NULL;
2786 es.worst = NULL;
2787 es.duplicate = GNUNET_NO;
2790 &es);
2791 if ((NULL != es.worst) &&
2793 {
2794 /* Clear out worst-performing connection 'es.worst'. */
2796 es.worst);
2797 }
2798
2799 /* Consider additional paths */
2800 (void) GCP_iterate_paths (t->destination,
2802 t);
2803
2804 /* FIXME: calculate when to try again based on how well we are doing;
2805 in particular, if we have to few connections, we might be able
2806 to do without this (as PATHS should tell us whenever a new path
2807 is available instantly; however, need to make sure this job is
2808 restarted after that happens).
2809 Furthermore, if the paths we do know are in a reasonably narrow
2810 quality band and are plentyful, we might also consider us stabilized
2811 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2812 t->maintain_connections_task
2815 t);
2816}
2817
2818
2819void
2821 struct CadetPeerPath *p,
2822 unsigned int off)
2823{
2825 "Considering %s for %s (offset %u)\n",
2826 GCPP_2s (p),
2827 GCT_2s (t),
2828 off);
2829 (void) consider_path_cb (t,
2830 p,
2831 off);
2832}
2833
2834
2841static void
2843 const struct GNUNET_MessageHeader *msg)
2844{
2845 struct CadetTunnel *t = cls;
2846
2848 "Received KEEPALIVE on %s\n",
2849 GCT_2s (t));
2851 "# keepalives received",
2852 1,
2853 GNUNET_NO);
2854}
2855
2856
2864static int
2865check_plaintext_data (void *cls,
2867{
2868 return GNUNET_OK;
2869}
2870
2871
2879static void
2880handle_plaintext_data (void *cls,
2882{
2883 struct CadetTunnel *t = cls;
2884 struct CadetChannel *ch;
2885
2886 ch = lookup_channel (t,
2887 msg->ctn);
2888 if (NULL == ch)
2889 {
2890 /* We don't know about such a channel, might have been destroyed on our
2891 end in the meantime, or never existed. Send back a DESTROY. */
2893 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2894 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2895 ntohl (msg->ctn.cn));
2897 msg->ctn);
2898 return;
2899 }
2901 GCC_get_id (t->current_ct->cc),
2902 msg);
2903}
2904
2905
2914static void
2915handle_plaintext_data_ack (void *cls,
2916 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
2917{
2918 struct CadetTunnel *t = cls;
2919 struct CadetChannel *ch;
2920
2921 ch = lookup_channel (t,
2922 ack->ctn);
2923 if (NULL == ch)
2924 {
2925 /* We don't know about such a channel, might have been destroyed on our
2926 end in the meantime, or never existed. Send back a DESTROY. */
2928 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2929 ntohl (ack->ctn.cn));
2931 ack->ctn);
2932 return;
2933 }
2935 GCC_get_id (t->current_ct->cc),
2936 ack);
2937}
2938
2939
2947static void
2949 const struct
2951{
2952 struct CadetTunnel *t = cls;
2953 struct CadetChannel *ch;
2954
2956 ntohl (copen->ctn.cn));
2957 if (NULL != ch)
2958 {
2960 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2961 GNUNET_h2s (&copen->h_port),
2962 GCT_2s (t),
2963 GCCH_2s (ch));
2965 GCC_get_id (t->current_ct->cc));
2966 return;
2967 }
2969 "Received CHANNEL_OPEN on h_port %s from %s\n",
2970 GNUNET_h2s (&copen->h_port),
2971 GCT_2s (t));
2973 copen->ctn,
2974 &copen->h_port,
2975 ntohl (copen->opt));
2976 if (NULL != t->destroy_task)
2977 {
2978 GNUNET_SCHEDULER_cancel (t->destroy_task);
2979 t->destroy_task = NULL;
2980 }
2983 ntohl (copen->ctn.cn),
2984 ch,
2986}
2987
2988
2995void
2998{
3000
3002 "Sending DESTROY message for channel ID %u\n",
3003 ntohl (ctn.cn));
3004 msg.header.size = htons (sizeof(msg));
3006 msg.reserved = htonl (0);
3007 msg.ctn = ctn;
3008 GCT_send (t,
3009 &msg.header,
3010 NULL,
3011 NULL,
3012 &ctn);
3013}
3014
3015
3024static void
3026 const struct
3028{
3029 struct CadetTunnel *t = cls;
3030 struct CadetChannel *ch;
3031
3032 ch = lookup_channel (t,
3033 cm->ctn);
3034 if (NULL == ch)
3035 {
3036 /* We don't know about such a channel, might have been destroyed on our
3037 end in the meantime, or never existed. Send back a DESTROY. */
3039 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3040 ntohl (cm->ctn.cn));
3042 cm->ctn);
3043 return;
3044 }
3046 "Received channel OPEN_ACK on channel %s from %s\n",
3047 GCCH_2s (ch),
3048 GCT_2s (t));
3050 GCC_get_id (t->current_ct->cc),
3051 &cm->port);
3052}
3053
3054
3062static void
3064 const struct
3066{
3067 struct CadetTunnel *t = cls;
3068 struct CadetChannel *ch;
3069
3070 ch = lookup_channel (t,
3071 cm->ctn);
3072 if (NULL == ch)
3073 {
3074 /* We don't know about such a channel, might have been destroyed on our
3075 end in the meantime, or never existed. */
3077 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3078 ntohl (cm->ctn.cn));
3079 return;
3080 }
3082 "Received channel DESTROY on %s from %s\n",
3083 GCCH_2s (ch),
3084 GCT_2s (t));
3086 GCC_get_id (t->current_ct->cc));
3087}
3088
3089
3100static int
3101handle_decrypted (void *cls,
3102 const struct GNUNET_MessageHeader *msg)
3103{
3104 struct CadetTunnel *t = cls;
3105
3106 GNUNET_assert (NULL != t->current_ct);
3108 msg);
3109 return GNUNET_OK;
3110}
3111
3112
3120static void
3121decrypted_error_cb (void *cls,
3122 enum GNUNET_MQ_Error error)
3123{
3124 GNUNET_break_op (0);
3125}
3126
3127
3135struct CadetTunnel *
3137{
3138 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3140 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3142 struct GNUNET_MessageHeader,
3143 t),
3144 GNUNET_MQ_hd_var_size (plaintext_data,
3147 t),
3148 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3151 t),
3152 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3155 t),
3156 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3159 t),
3160 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3163 t),
3165 };
3166
3167 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3168 new_ephemeral (&t->ax);
3170 t->destination = destination;
3172 t->maintain_connections_task
3174 t);
3175 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3176 NULL,
3177 NULL,
3178 NULL,
3179 handlers,
3181 t);
3183 t);
3184 return t;
3185}
3186
3187
3188int
3190 const struct
3192 struct CadetPeerPath *path)
3193{
3194 struct CadetTConnection *ct;
3195
3196 ct = GNUNET_new (struct CadetTConnection);
3198 ct->t = t;
3199 ct->cc = GCC_create_inbound (t->destination,
3200 path,
3201 ct,
3202 cid,
3204 ct);
3205 if (NULL == ct->cc)
3206 {
3208 "%s refused inbound %s (duplicate)\n",
3209 GCT_2s (t),
3210 GCC_2s (ct->cc));
3211 GNUNET_free (ct);
3212 return GNUNET_SYSERR;
3213 }
3214 /* FIXME: schedule job to kill connection (and path?) if it takes
3215 too long to get ready! (And track performance data on how long
3216 other connections took with the tunnel!)
3217 => Note: to be done within 'connection'-logic! */
3218 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3219 t->connection_busy_tail,
3220 ct);
3221 t->num_busy_connections++;
3223 "%s has new %s\n",
3224 GCT_2s (t),
3225 GCC_2s (ct->cc));
3226 return GNUNET_OK;
3227}
3228
3229
3236void
3239{
3240 struct CadetTunnel *t = ct->t;
3241 uint16_t size = ntohs (msg->header.size);
3242 char cbuf[size] GNUNET_ALIGN;
3243 ssize_t decrypted_size;
3244
3246 "%s received %u bytes of encrypted data in state %d\n",
3247 GCT_2s (t),
3248 (unsigned int) size,
3249 t->estate);
3250
3251 switch (t->estate)
3252 {
3255 /* We did not even SEND our KX, how can the other peer
3256 send us encrypted data? Must have been that we went
3257 down and the other peer still things we are up.
3258 Let's send it KX back. */
3260 "# received encrypted without any KX",
3261 1,
3262 GNUNET_NO);
3263 if (NULL != t->kx_task)
3264 {
3265 GNUNET_SCHEDULER_cancel (t->kx_task);
3266 t->kx_task = NULL;
3267 }
3268 send_kx (t,
3269 ct,
3270 &t->ax);
3271 return;
3272
3274 /* We send KX, and other peer send KX to us at the same time.
3275 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3277 "# received encrypted without KX_AUTH",
3278 1,
3279 GNUNET_NO);
3280 if (NULL != t->kx_task)
3281 {
3282 GNUNET_SCHEDULER_cancel (t->kx_task);
3283 t->kx_task = NULL;
3284 }
3285 send_kx_auth (t,
3286 ct,
3287 &t->ax,
3288 GNUNET_YES);
3289 return;
3290
3292 /* We did not get the KX of the other peer, but that
3293 might have been lost. Send our KX again immediately. */
3295 "# received encrypted without KX",
3296 1,
3297 GNUNET_NO);
3298 if (NULL != t->kx_task)
3299 {
3300 GNUNET_SCHEDULER_cancel (t->kx_task);
3301 t->kx_task = NULL;
3302 }
3303 send_kx (t,
3304 ct,
3305 &t->ax);
3306 return;
3307
3309 /* Great, first payload, we might graduate to OK! */
3311 /* We are up and running, all good. */
3312 break;
3313 }
3314
3315 decrypted_size = -1;
3316 if (CADET_TUNNEL_KEY_OK == t->estate)
3317 {
3318 /* We have well-established key material available,
3319 try that. (This is the common case.) */
3320 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3321 cbuf,
3322 msg,
3323 size);
3324 }
3325
3326 if ((-1 == decrypted_size) &&
3327 (NULL != t->unverified_ax))
3328 {
3329 /* We have un-authenticated KX material available. We should try
3330 this as a back-up option, in case the sender crashed and
3331 switched keys. */
3332 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3333 cbuf,
3334 msg,
3335 size);
3336 if (-1 != decrypted_size)
3337 {
3338 /* It worked! Treat this as authentication of the AX data! */
3339 cleanup_ax (&t->ax);
3340 t->ax = *t->unverified_ax;
3341 GNUNET_free (t->unverified_ax);
3342 t->unverified_ax = NULL;
3343 }
3344 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3345 {
3346 /* First time it worked, move tunnel into production! */
3349 if (NULL != t->send_task)
3350 GNUNET_SCHEDULER_cancel (t->send_task);
3352 t);
3353 }
3354 }
3355 if (NULL != t->unverified_ax)
3356 {
3357 /* We had unverified KX material that was useless; so increment
3358 counter and eventually move to ignore it. Note that we even do
3359 this increment if we successfully decrypted with the old KX
3360 material and thus didn't even both with the new one. This is
3361 the ideal case, as a malicious injection of bogus KX data
3362 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3364 "Failed to decrypt message with unverified KX data %u times\n",
3365 t->unverified_attempts);
3366 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3367 {
3368 cleanup_ax (t->unverified_ax);
3369 GNUNET_free (t->unverified_ax);
3370 t->unverified_ax = NULL;
3371 }
3372 }
3373
3374 if (-1 == decrypted_size)
3375 {
3376 /* Decryption failed for good, complain. */
3378 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3379 GCT_2s (t));
3381 "# unable to decrypt",
3382 1,
3383 GNUNET_NO);
3384 if (NULL != t->kx_task)
3385 {
3386 GNUNET_SCHEDULER_cancel (t->kx_task);
3387 t->kx_task = NULL;
3388 }
3389 send_kx (t,
3390 ct,
3391 &t->ax);
3392 return;
3393 }
3395 "# decrypted bytes",
3396 decrypted_size,
3397 GNUNET_NO);
3398
3399 /* The MST will ultimately call #handle_decrypted() on each message. */
3400 t->current_ct = ct;
3403 cbuf,
3404 decrypted_size,
3405 GNUNET_YES,
3406 GNUNET_NO));
3407 t->current_ct = NULL;
3408}
3409
3410
3411struct CadetTunnelQueueEntry *
3412GCT_send (struct CadetTunnel *t,
3413 const struct GNUNET_MessageHeader *message,
3415 void *cont_cls,
3417{
3418 struct CadetTunnelQueueEntry *tq;
3419 uint16_t payload_size;
3420 struct GNUNET_MQ_Envelope *env;
3422 struct CadetChannel *ch;
3423
3424 if (NULL != ctn)
3425 {
3426 ch = lookup_channel (t,
3427 *ctn);
3428 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3429 {
3430 GNUNET_break (0);
3431 return NULL;
3432 }
3433 }
3434
3435 if (CADET_TUNNEL_KEY_OK != t->estate)
3436 {
3437 GNUNET_break (0);
3438 return NULL;
3439 }
3440 payload_size = ntohs (message->size);
3442 "Encrypting %u bytes for %s\n",
3443 (unsigned int) payload_size,
3444 GCT_2s (t));
3445 env = GNUNET_MQ_msg_extra (ax_msg,
3446 payload_size,
3448 t_ax_encrypt (&t->ax,
3449 &ax_msg[1],
3450 message,
3451 payload_size);
3453 "# encrypted bytes",
3454 payload_size,
3455 GNUNET_NO);
3456 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3457 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3458 /* FIXME: we should do this once, not once per message;
3459 this is a point multiplication, and DHRs does not
3460 change all the time. */
3462 &ax_msg->ax_header.DHRs);
3463 t_h_encrypt (&t->ax,
3464 ax_msg);
3465 t_hmac (&ax_msg->ax_header,
3466 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3467 0,
3468 &t->ax.HKs,
3469 &ax_msg->hmac);
3470
3471 tq = GNUNET_malloc (sizeof(*tq));
3472 tq->t = t;
3473 tq->env = env;
3474 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3475 tq->cont = cont;
3476 tq->cont_cls = cont_cls;
3478 t->tq_tail,
3479 tq);
3480 if (NULL != t->send_task)
3481 GNUNET_SCHEDULER_cancel (t->send_task);
3482 t->send_task
3484 t);
3485 return tq;
3486}
3487
3488
3489void
3491{
3492 struct CadetTunnel *t = tq->t;
3493
3495 t->tq_tail,
3496 tq);
3497 GNUNET_MQ_discard (tq->env);
3498 GNUNET_free (tq);
3499}
3500
3501
3509void
3512 void *iter_cls)
3513{
3514 struct CadetTConnection *n;
3515
3516 for (struct CadetTConnection *ct = t->connection_ready_head;
3517 NULL != ct;
3518 ct = n)
3519 {
3520 n = ct->next;
3521 iter (iter_cls,
3522 ct);
3523 }
3524 for (struct CadetTConnection *ct = t->connection_busy_head;
3525 NULL != ct;
3526 ct = n)
3527 {
3528 n = ct->next;
3529 iter (iter_cls,
3530 ct);
3531 }
3532}
3533
3534
3538struct ChanIterCls
3539{
3544
3548 void *iter_cls;
3549};
3550
3551
3560static int
3561iterate_channels_cb (void *cls,
3562 uint32_t key,
3563 void *value)
3564{
3565 struct ChanIterCls *ctx = cls;
3566 struct CadetChannel *ch = value;
3567
3568 ctx->iter (ctx->iter_cls,
3569 ch);
3570 return GNUNET_OK;
3571}
3572
3573
3581void
3584 void *iter_cls)
3585{
3586 struct ChanIterCls ctx;
3587
3588 ctx.iter = iter;
3589 ctx.iter_cls = iter_cls;
3592 &ctx);
3593}
3594
3595
3604static int
3605debug_channel (void *cls,
3606 uint32_t key,
3607 void *value)
3608{
3609 const enum GNUNET_ErrorType *level = cls;
3610 struct CadetChannel *ch = value;
3611
3612 GCCH_debug (ch, *level);
3613 return GNUNET_OK;
3614}
3615
3616
3617#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3618 __VA_ARGS__)
3619
3620
3627void
3628GCT_debug (const struct CadetTunnel *t,
3629 enum GNUNET_ErrorType level)
3630{
3631#if ! defined(GNUNET_CULL_LOGGING)
3632 struct CadetTConnection *iter_c;
3633 int do_log;
3634
3636 "cadet-tun",
3637 __FILE__, __FUNCTION__, __LINE__);
3638 if (0 == do_log)
3639 return;
3640
3641 LOG2 (level,
3642 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3643 GCT_2s (t),
3644 estate2s (t->estate),
3645 t->tq_len,
3647 LOG2 (level,
3648 "TTT channels:\n");
3651 &level);
3652 LOG2 (level,
3653 "TTT connections:\n");
3654 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3655 GCC_debug (iter_c->cc,
3656 level);
3657 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3658 GCC_debug (iter_c->cc,
3659 level);
3660
3661 LOG2 (level,
3662 "TTT TUNNEL END\n");
3663#endif
3664}
3665
3666
3667/* 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 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_CRYPTO_PowSalt salt
Salt for PoW calculations.
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Own private key.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
static void t_h_decrypt(struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
void GCT_handle_kx(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Handle KX message that lacks authentication (and which will thus only be considered authenticated aft...
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 GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
static void handle_plaintext_channel_open_ack(void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
We have received confirmation from the target peer that the given channel could be established (the p...
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
#define LOG2(level,...)
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
static void t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
void GCT_handle_kx_auth(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
void GCT_handle_encrypted(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void t_hmac(const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
Calculate HMAC.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
static void handle_plaintext_channel_destroy(void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
We received a message saying that a channel should be destroyed.
#define HIGH_BIT
static void handle_plaintext_channel_open(void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
We have received a request to open a channel to a port from another peer.
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
Delete a key from the list of skipped keys.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
static int update_ax_by_kx(struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
Update our Axolotl key state based on the KX data we received.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
static int check_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
Check that msg is well-formed.
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
static void handle_plaintext_data_ack(void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We received an acknowledgement for data we sent on a channel.
static void handle_plaintext_keepalive(void *cls, const struct GNUNET_MessageHeader *msg)
We got a keepalive.
static void handle_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We received payload data for a channel.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Encrypt header with the axolotl header key.
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
void GCT_destroy_tunnel_now(struct CadetTunnel *t)
Destroys the tunnel t now, without delay.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
#define LOG(level,...)
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_iterate_channels(struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
Iterate over all channels of a tunnel.
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GCT_debug(const struct CadetTunnel *t, enum GNUNET_ErrorType level)
Log all possible info about the tunnel state.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
CadetTunnelEState
All the encryption states a tunnel can be in.
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
void(* GCT_ConnectionIterator)(void *cls, struct CadetTConnection *ct)
Iterator over connections.
void(* GCT_SendContinuation)(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called when a transmission requested using GCT_send is done.
void(* GCT_ChannelIterator)(void *cls, struct CadetChannel *ch)
Iterator over channels.
#define N
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static struct GNUNET_SCHEDULER_Task * t
Main task.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition crypto_ecc.c:732
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:201
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition crypto_ecc.c:745
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:823
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:433
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:217
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition crypto_kdf.c:62
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
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.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
GNUNET_ErrorType
Types of errors.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition mq.c:187
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1254
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
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:1304
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:1277
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.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_CRYPTO_SymmetricSessionKey HKs
32-byte header key (currently used for sending).
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).
struct GNUNET_CRYPTO_SymmetricSessionKey RK
32-byte root key which gets updated by DH ratchet.
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
struct GNUNET_CRYPTO_SymmetricSessionKey HKr
32-byte header key (currently used for receiving)
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_SymmetricSessionKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_SymmetricSessionKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_SymmetricSessionKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).
struct GNUNET_CRYPTO_SymmetricSessionKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
Struct used to save messages in a non-ready tunnel to send once connected.
struct CadetTunnelQueueEntry * prev
We are entries in a DLL.
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnelQueueEntry * next
We are entries in a DLL.
struct CadetTunnel * t
Tunnel these messages belong in.
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
struct CadetTunnelSkippedKey * next
DLL next.
struct CadetTunnelSkippedKey * prev
DLL prev.
Struct containing all information regarding a tunnel to a peer.
struct GNUNET_SCHEDULER_Task * send_task
Task to send messages from queue (if possible).
struct CadetPeer * destination
Destination of the tunnel.
struct CadetTConnection * connection_ready_head
DLL of ready connections that are actively used to reach the destination peer.
struct CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct GNUNET_CRYPTO_SymmetricSessionKey d_key
Decryption ("their") key.
struct CadetTunnelQueueEntry * tq_tail
Queued messages, to transmit once tunnel gets connected.
struct GNUNET_SCHEDULER_Task * maintain_connections_task
Task to trim connections if too many are present.
struct CadetTConnection * connection_busy_head
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_CRYPTO_SymmetricSessionKey e_key
Encryption ("our") key.
struct GNUNET_TIME_Absolute next_kx_attempt
When do we try the next KX?
struct GNUNET_TIME_Relative kx_retry_delay
How long do we wait until we retry the KX?
struct CadetTConnection * connection_busy_tail
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_MQ_Handle * mq
Dispatcher for decrypted messages only (do NOT use for sending!).
enum CadetTunnelEState estate
State of the tunnel encryption.
struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key
Peer's ephemeral key, to recreate e_key and d_key when own ephemeral key changes.
unsigned int num_busy_connections
Number of connections in the connection_busy_head DLL.
struct CadetTunnelAxolotl ax
Axolotl info.
struct GNUNET_CONTAINER_MultiHashMap32 * channels
Channels inside this tunnel.
struct GNUNET_SCHEDULER_Task * destroy_task
Task scheduled if there are no more channels using the tunnel.
struct CadetTConnection * connection_ready_tail
DLL of ready connections that are actively used to reach the destination peer.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for decrypted messages.
struct CadetTunnelQueueEntry * tq_head
Queued messages, to transmit once tunnel gets connected.
unsigned int num_ready_connections
Number of connections in the connection_ready_head DLL.
struct GNUNET_SCHEDULER_Task * kx_task
Task to trigger KX.
struct CadetTunnelAxolotl * unverified_ax
Unverified Axolotl info, used only if we got a fresh KX (not a KX_AUTH) while our end of the tunnel w...
unsigned int tq_len
Number of entries in the tq_head DLL.
struct GNUNET_CADET_ChannelTunnelNumber next_ctn
Channel ID for the next created channel in this tunnel.
int kx_auth_requested
Force triggering KX_AUTH independent of estate.
unsigned int unverified_attempts
How often have we tried and failed to decrypt a message using the unverified KX material from unverif...
Closure for iterate_channels_cb.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
uint32_t Ns
Number of messages sent with the current ratchet key.
Message for cadet data traffic.
Message to acknowledge end-to-end data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
uint32_t cn
Which number does this channel have that uniquely identifies it within its tunnel,...
Hash uniquely identifying a connection below a tunnel.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_ShortHashCode hmac
MAC of the encrypted message, used to verify message integrity.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
Internal representation of the hash map.
type for (message) authentication keys
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
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:136
A 256-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

◆ INITIAL_KX_RETRY_DELAY

#define INITIAL_KX_RETRY_DELAY
Value:
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.

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

Definition at line 64 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 70 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 76 of file gnunet-service-cadet_tunnels.c.

◆ HIGH_BIT

#define HIGH_BIT   0x8000000

◆ LOG2

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

Definition at line 3618 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 468 of file gnunet-service-cadet_tunnels.c.

469{
470 if (0 > GNUNET_memcmp (&my_full_id,
471 other))
472 return GNUNET_YES;
473 else if (0 < GNUNET_memcmp (&my_full_id,
474 other))
475 return GNUNET_NO;
476 else
477 {
478 GNUNET_break_op (0);
479 return GNUNET_SYSERR;
480 }
481}

References GNUNET_break_op, GNUNET_memcmp, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, and my_full_id.

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

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

492{
493 struct CadetTunnel *t = ct->t;
494
496 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
497 t->connection_ready_tail,
498 ct);
499 GNUNET_assert (0 < t->num_ready_connections);
500 t->num_ready_connections--;
501 ct->is_ready = GNUNET_NO;
502 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
503 t->connection_busy_tail,
504 ct);
505 t->num_busy_connections++;
506}

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

518{
519 static char buf[64];
520
521 if (NULL == t)
522 return "Tunnel(NULL)";
523 GNUNET_snprintf (buf,
524 sizeof(buf),
525 "Tunnel %s",
526 GNUNET_i2s (GCP_get_id (t->destination)));
527 return buf;
528}

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

Referenced by connection_ready_cb(), consider_path_cb(), 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 539 of file gnunet-service-cadet_tunnels.c.

540{
541 static char buf[32];
542
543 switch (es)
544 {
546 return "CADET_TUNNEL_KEY_UNINITIALIZED";
548 return "CADET_TUNNEL_KEY_AX_RECV";
550 return "CADET_TUNNEL_KEY_AX_SENT";
552 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
554 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
556 return "CADET_TUNNEL_KEY_OK";
557 }
558 GNUNET_snprintf (buf,
559 sizeof(buf),
560 "%u (UNKNOWN STATE)",
561 es);
562 return buf;
563}

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

574{
575 return t->destination;
576}

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

581{
582 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
583}

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

596{
597 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
598 ntohl (ctn.cn));
599}

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

604{
605 return t->num_ready_connections + t->num_busy_connections;
606}

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

618{
619 struct CadetTConnection *hd = t->connection_ready_head;
620
621 GNUNET_assert ((NULL == hd) ||
622 (GNUNET_YES == hd->is_ready));
623 return hd;
624}

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

636{
637 return t->estate;
638}

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

2492{
2493 struct CadetTunnel *t = cls;
2494 struct CadetTConnection *ct;
2495
2496 t->send_task = NULL;
2497 if (NULL == t->tq_head)
2498 return; /* no messages pending right now */
2499 ct = get_ready_connection (t);
2500 if (NULL == ct)
2501 return; /* no connections ready */
2503 ct);
2504}

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

663{
665 "Creating new ephemeral ratchet key (DHRs)\n");
667}

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

Referenced by GCT_create_tunnel(), and t_ax_encrypt().

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

◆ t_hmac()

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

Calculate HMAC.

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

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

685{
686 static const char ctx[] = "cadet authentication key";
687 struct GNUNET_CRYPTO_AuthKey auth_key;
688 struct GNUNET_HashCode hash;
689
691 key,
692 &iv, sizeof(iv),
693 key, sizeof(*key),
694 ctx, sizeof(ctx),
695 NULL);
696 /* Two step: GNUNET_ShortHash is only 256 bits,
697 GNUNET_HashCode is 512, so we truncate. */
698 GNUNET_CRYPTO_hmac (&auth_key,
699 plaintext,
700 size,
701 &hash);
702 GNUNET_memcpy (hmac,
703 &hash,
704 sizeof(*hmac));
705}

References ctx, GNUNET_CRYPTO_hmac(), GNUNET_CRYPTO_hmac_derive_key(), GNUNET_memcpy, key, and size.

Referenced by GCT_send(), t_ax_decrypt_and_validate(), and try_old_ax_keys().

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

◆ t_ax_hmac_hash()

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

Perform a HMAC.

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

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

721{
722 static const char ctx[] = "axolotl HMAC-HASH";
723 struct GNUNET_CRYPTO_AuthKey auth_key;
724
726 key,
727 ctx, sizeof(ctx),
728 NULL);
729 GNUNET_CRYPTO_hmac (&auth_key,
730 source,
731 len,
732 hash);
733}

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

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

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

◆ t_hmac_derive_key()

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

Derive a symmetric encryption key from an HMAC-HASH.

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

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

749{
750 static const char ctx[] = "axolotl derive key";
751 struct GNUNET_HashCode h;
752
754 &h,
755 source,
756 len);
757 GNUNET_CRYPTO_kdf (out, sizeof(*out),
758 ctx, sizeof(ctx),
759 &h, sizeof(h),
760 NULL);
761}

References ctx, GNUNET_CRYPTO_kdf(), 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 773 of file gnunet-service-cadet_tunnels.c.

777{
780 size_t out_size;
781
782 ax->ratchet_counter++;
783 if ((GNUNET_YES == ax->ratchet_allowed) &&
784 ((ratchet_messages <= ax->ratchet_counter) ||
787 {
789 }
790 if (GNUNET_YES == ax->ratchet_flag)
791 {
792 /* Advance ratchet */
794 struct GNUNET_HashCode dh;
795 struct GNUNET_HashCode hmac;
796 static const char ctx[] = "axolotl ratchet";
797
798 new_ephemeral (ax);
799 ax->HKs = ax->NHKs;
800
801 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
803 &ax->DHRr,
804 &dh);
805 t_ax_hmac_hash (&ax->RK,
806 &hmac,
807 &dh,
808 sizeof(dh));
809 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
810 ctx, sizeof(ctx),
811 &hmac, sizeof(hmac),
812 NULL);
813 ax->RK = keys[0];
814 ax->NHKs = keys[1];
815 ax->CKs = keys[2];
816
817 ax->PNs = ax->Ns;
818 ax->Ns = 0;
821 ax->ratchet_counter = 0;
825 }
826
828 &MK,
829 "0",
830 1);
832 &MK,
833 NULL, 0,
834 NULL);
835
836 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
837 size,
838 &MK,
839 &iv,
840 dst);
841 GNUNET_assert (size == out_size);
843 &ax->CKs,
844 "1",
845 1);
846}

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

Referenced by GCT_send().

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

◆ t_ax_decrypt()

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

Decrypt data with the axolotl tunnel key.

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

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

862{
865 size_t out_size;
866
868 &MK,
869 "0",
870 1);
872 &MK,
873 NULL, 0,
874 NULL);
875 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
876 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
877 size,
878 &MK,
879 &iv,
880 dst);
881 GNUNET_assert (out_size == size);
883 &ax->CKr,
884 "1",
885 1);
886}

References CadetTunnelAxolotl::CKr, GNUNET_assert, GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_CRYPTO_symmetric_derive_iv(), size, and t_hmac_derive_key().

Referenced by t_ax_decrypt_and_validate().

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

◆ t_h_encrypt()

static void t_h_encrypt ( struct CadetTunnelAxolotl ax,
struct GNUNET_CADET_TunnelEncryptedMessage msg 
)
static

Encrypt header with the axolotl header key.

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

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

898{
900 size_t out_size;
901
903 &ax->HKs,
904 NULL, 0,
905 NULL);
906 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
907 sizeof(struct
909 &ax->HKs,
910 &iv,
911 &msg->ax_header);
912 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
913}

References GNUNET_assert, GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_CRYPTO_symmetric_encrypt(), CadetTunnelAxolotl::HKs, and msg.

Referenced by GCT_send().

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

◆ t_h_decrypt()

static void t_h_decrypt ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
struct GNUNET_CADET_TunnelEncryptedMessage dst 
)
static

Decrypt header with the current axolotl header key.

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

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

927{
929 size_t out_size;
930
932 &ax->HKr,
933 NULL, 0,
934 NULL);
936 sizeof(struct
938 &ax->HKr,
939 &iv,
940 &dst->ax_header.Ns);
941 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
942}

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

Referenced by t_ax_decrypt_and_validate().

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

◆ delete_skipped_key()

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

Delete a key from the list of skipped keys.

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

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

954{
956 ax->skipped_tail,
957 key);
959 ax->skipped--;
960}

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

978{
980 struct GNUNET_ShortHashCode *hmac;
982 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
983 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
984 size_t esize;
985 size_t res;
986 size_t len;
987 unsigned int N;
988
990 "Trying skipped keys\n");
991 hmac = &plaintext_header.hmac;
992 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
993
994 /* Find a correct Header Key */
995 valid_HK = NULL;
996 for (key = ax->skipped_head; NULL != key; key = key->next)
997 {
998 t_hmac (&src->ax_header,
999 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1000 0,
1001 &key->HK,
1002 hmac);
1003 if (0 == GNUNET_memcmp (hmac,
1004 &src->hmac))
1005 {
1006 valid_HK = &key->HK;
1007 break;
1008 }
1009 }
1010 if (NULL == key)
1011 return -1;
1012
1013 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1015 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1016 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1017
1018 /* Decrypt header */
1020 &key->HK,
1021 NULL, 0,
1022 NULL);
1024 sizeof(struct GNUNET_CADET_AxHeader),
1025 &key->HK,
1026 &iv,
1027 &plaintext_header.ax_header.Ns);
1028 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1029
1030 /* Find the correct message key */
1031 N = ntohl (plaintext_header.ax_header.Ns);
1032 while ((NULL != key) &&
1033 (N != key->Kn))
1034 key = key->next;
1035 if ((NULL == key) ||
1036 (0 != GNUNET_memcmp (&key->HK,
1037 valid_HK)))
1038 return -1;
1039
1040 /* Decrypt payload */
1042 &key->MK,
1043 NULL,
1044 0,
1045 NULL);
1047 len,
1048 &key->MK,
1049 &iv,
1050 dst);
1052 key);
1053 return res;
1054}

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

Referenced by t_ax_decrypt_and_validate().

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

◆ store_skipped_key()

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

Delete a key from the list of skipped keys.

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

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

1066{
1067 struct CadetTunnelSkippedKey *key;
1068
1070 key->timestamp = GNUNET_TIME_absolute_get ();
1071 key->Kn = ax->Nr;
1072 key->HK = ax->HKr;
1073 t_hmac_derive_key (&ax->CKr,
1074 &key->MK,
1075 "0",
1076 1);
1077 t_hmac_derive_key (&ax->CKr,
1078 &ax->CKr,
1079 "1",
1080 1);
1082 ax->skipped_tail,
1083 key);
1084 ax->skipped++;
1085 ax->Nr++;
1086}

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

Referenced by store_ax_keys().

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

◆ store_ax_keys()

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

Stage skipped AX keys and calculate the message key.

Stores each HK and MK for skipped messages.

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

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

1103{
1104 int gap;
1105
1106 gap = Np - ax->Nr;
1108 "Storing skipped keys [%u, %u)\n",
1109 ax->Nr,
1110 Np);
1111 if (MAX_KEY_GAP < gap)
1112 {
1113 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1114 /* TODO: start new key exchange on return */
1115 GNUNET_break_op (0);
1117 "Got message %u, expected %u+\n",
1118 Np,
1119 ax->Nr);
1120 return GNUNET_SYSERR;
1121 }
1122 if (0 > gap)
1123 {
1124 /* Delayed message: don't store keys, flag to try old keys. */
1125 return GNUNET_SYSERR;
1126 }
1127
1128 while (ax->Nr < Np)
1130 HKr);
1131
1132 while (ax->skipped > MAX_SKIPPED_KEYS)
1134 ax->skipped_tail);
1135 return GNUNET_OK;
1136}

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

1155{
1156 struct GNUNET_ShortHashCode msg_hmac;
1157 struct GNUNET_HashCode hmac;
1158 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1159 uint32_t Np;
1160 uint32_t PNp;
1161 size_t esize; /* Size of encrypted payload */
1162
1163 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1164
1165 /* Try current HK */
1166 t_hmac (&src->ax_header,
1167 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1168 0, &ax->HKr,
1169 &msg_hmac);
1170 if (0 != GNUNET_memcmp (&msg_hmac,
1171 &src->hmac))
1172 {
1173 static const char ctx[] = "axolotl ratchet";
1174 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1176 struct GNUNET_HashCode dh;
1177 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1178
1179 /* Try Next HK */
1180 t_hmac (&src->ax_header,
1181 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1182 0,
1183 &ax->NHKr,
1184 &msg_hmac);
1185 if (0 != GNUNET_memcmp (&msg_hmac,
1186 &src->hmac))
1187 {
1188 /* Try the skipped keys, if that fails, we're out of luck. */
1189 return try_old_ax_keys (ax,
1190 dst,
1191 src,
1192 size);
1193 }
1194 HK = ax->HKr;
1195 ax->HKr = ax->NHKr;
1196 t_h_decrypt (ax,
1197 src,
1198 &plaintext_header);
1199 Np = ntohl (plaintext_header.ax_header.Ns);
1200 PNp = ntohl (plaintext_header.ax_header.PNs);
1201 DHRp = &plaintext_header.ax_header.DHRs;
1202 store_ax_keys (ax,
1203 &HK,
1204 PNp);
1205
1206 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1208 DHRp,
1209 &dh);
1210 t_ax_hmac_hash (&ax->RK,
1211 &hmac,
1212 &dh, sizeof(dh));
1213 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1214 ctx, sizeof(ctx),
1215 &hmac, sizeof(hmac),
1216 NULL);
1217
1218 /* Commit "purported" keys */
1219 ax->RK = keys[0];
1220 ax->NHKr = keys[1];
1221 ax->CKr = keys[2];
1222 ax->DHRr = *DHRp;
1223 ax->Nr = 0;
1225 }
1226 else
1227 {
1228 t_h_decrypt (ax,
1229 src,
1230 &plaintext_header);
1231 Np = ntohl (plaintext_header.ax_header.Ns);
1232 PNp = ntohl (plaintext_header.ax_header.PNs);
1233 }
1234 if ((Np != ax->Nr) &&
1235 (GNUNET_OK != store_ax_keys (ax,
1236 &ax->HKr,
1237 Np)))
1238 {
1239 /* Try the skipped keys, if that fails, we're out of luck. */
1240 return try_old_ax_keys (ax,
1241 dst,
1242 src,
1243 size);
1244 }
1245
1246 t_ax_decrypt (ax,
1247 dst,
1248 &src[1],
1249 esize);
1250 ax->Nr = Np + 1;
1251 return esize;
1252}

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

Referenced by GCT_handle_encrypted().

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

◆ notify_tunnel_up_cb()

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

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

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

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

1268{
1269 struct CadetChannel *ch = value;
1270
1272 return GNUNET_OK;
1273}

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

1286{
1287 enum CadetTunnelEState old = t->estate;
1288
1289 t->estate = state;
1291 "%s estate changed from %s to %s\n",
1292 GCT_2s (t),
1293 estate2s (old),
1294 estate2s (state));
1295
1296 if ((CADET_TUNNEL_KEY_OK != old) &&
1297 (CADET_TUNNEL_KEY_OK == t->estate))
1298 {
1299 if (NULL != t->kx_task)
1300 {
1301 GNUNET_SCHEDULER_cancel (t->kx_task);
1302 t->kx_task = NULL;
1303 }
1304 /* notify all channels that have been waiting */
1307 t);
1308 if (NULL != t->send_task)
1309 GNUNET_SCHEDULER_cancel (t->send_task);
1311 t);
1312 }
1313}

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 GCT_handle_encrypted(), GCT_handle_kx(), GCT_handle_kx_auth(), 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 1325 of file gnunet-service-cadet_tunnels.c.

1328{
1329 struct CadetConnection *cc;
1330 struct GNUNET_MQ_Envelope *env;
1333
1334 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1335 return; /* only Alice may send KX */
1336 if ((NULL == ct) ||
1337 (GNUNET_NO == ct->is_ready))
1338 ct = get_ready_connection (t);
1339 if (NULL == ct)
1340 {
1342 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1343 GCT_2s (t),
1344 estate2s (t->estate));
1345 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1346 return;
1347 }
1348 cc = ct->cc;
1351 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1352 msg->flags = htonl (flags);
1353 msg->cid = *GCC_get_id (cc);
1355 &msg->ephemeral_key);
1356#if DEBUG_KX
1357 msg->ephemeral_key_XXX = ax->kx_0;
1358 msg->private_key_XXX = *my_private_key;
1359#endif
1361 "Sending KX message to %s with ephemeral %s on CID %s\n",
1362 GCT_2s (t),
1363 GNUNET_e2s (&msg->ephemeral_key),
1364 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1366 &msg->ratchet_key);
1368 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1369 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1370 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1373 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1376 GCC_transmit (cc,
1377 env);
1379 "# KX transmitted",
1380 1,
1381 GNUNET_NO);
1382}

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

1400{
1401 struct CadetConnection *cc;
1402 struct GNUNET_MQ_Envelope *env;
1404 enum GNUNET_CADET_KX_Flags flags;
1405
1406 if ((NULL == ct) ||
1407 (GNUNET_NO == ct->is_ready))
1408 ct = get_ready_connection (t);
1409 if (NULL == ct)
1410 {
1412 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1413 GCT_2s (t));
1414 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1415 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1416 return;
1417 }
1418 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1419 cc = ct->cc;
1423 if (GNUNET_YES == force_reply)
1425 msg->kx.flags = htonl (flags);
1426 msg->kx.cid = *GCC_get_id (cc);
1428 &msg->kx.ephemeral_key);
1430 &msg->kx.ratchet_key);
1431#if DEBUG_KX
1432 msg->kx.ephemeral_key_XXX = ax->kx_0;
1433 msg->kx.private_key_XXX = *my_private_key;
1434 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1435#endif
1437 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1438 GCT_2s (t),
1439 GNUNET_e2s (&msg->kx.ephemeral_key),
1440 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1441
1442 /* Compute authenticator (this is the main difference to #send_kx()) */
1443 GNUNET_CRYPTO_hash (&ax->RK,
1444 sizeof(ax->RK),
1445 &msg->auth);
1446 /* Compute when to be triggered again; actual job will
1447 be scheduled via #connection_ready_cb() */
1448 t->kx_retry_delay
1449 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1450 t->next_kx_attempt
1451 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1452
1453 /* Send via cc, mark it as unready */
1455
1456 /* Update state machine, unless we are already OK */
1457 if (CADET_TUNNEL_KEY_OK != t->estate)
1460 GCC_transmit (cc,
1461 env);
1463 "# KX_AUTH transmitted",
1464 1,
1465 GNUNET_NO);
1466}

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, my_private_key, CadetTunnelAxolotl::RK, stats, and t.

Referenced by connection_ready_cb(), GCT_handle_encrypted(), GCT_handle_kx(), GCT_handle_kx_auth(), 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 1475 of file gnunet-service-cadet_tunnels.c.

1476{
1477 while (NULL != ax->skipped_head)
1479 ax->skipped_head);
1480 GNUNET_assert (0 == ax->skipped);
1483}

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

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

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

◆ update_ax_by_kx()

static int update_ax_by_kx ( struct CadetTunnelAxolotl ax,
const struct GNUNET_PeerIdentity pid,
const struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key,
const struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key 
)
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
[in,out]axchain key state to recompute
pidpeer identity of the other peer
ephemeral_keyephemeral public key of the other peer
ratchet_keysenders next ephemeral public key
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 (i.e. pid is my_full_id)

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

1504{
1505 struct GNUNET_HashCode key_material[3];
1506 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1507 const char salt[] = "CADET Axolotl salt";
1508 int am_I_alice;
1509
1510 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1511 {
1512 GNUNET_break_op (0);
1513 return GNUNET_SYSERR;
1514 }
1515 if (0 == GNUNET_memcmp (&ax->DHRr,
1516 ratchet_key))
1517 {
1519 "# Ratchet key already known",
1520 1,
1521 GNUNET_NO);
1523 "Ratchet key already known. Ignoring KX.\n");
1524 return GNUNET_NO;
1525 }
1526
1527 ax->DHRr = *ratchet_key;
1528 ax->last_ephemeral = *ephemeral_key;
1529 /* ECDH A B0 */
1530 if (GNUNET_YES == am_I_alice)
1531 {
1533 ephemeral_key, /* B0 */
1534 &key_material[0]);
1535 }
1536 else
1537 {
1538 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1539 &pid->public_key, /* A */
1540 &key_material[0]);
1541 }
1542 /* ECDH A0 B */
1543 if (GNUNET_YES == am_I_alice)
1544 {
1545 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1546 &pid->public_key, /* B */
1547 &key_material[1]);
1548 }
1549 else
1550 {
1552 ephemeral_key, /* A0 */
1553 &key_material[1]);
1554 }
1555
1556 /* ECDH A0 B0 */
1557 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1558 ephemeral_key, /* B0 or A0 */
1559 &key_material[2]);
1560 /* KDF */
1561 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1562 salt, sizeof(salt),
1563 &key_material, sizeof(key_material),
1564 NULL);
1565
1566 if (0 == memcmp (&ax->RK,
1567 &keys[0],
1568 sizeof(ax->RK)))
1569 {
1571 "Root key already known. Ignoring KX.\n");
1573 "# Root key already known",
1574 1,
1575 GNUNET_NO);
1576 return GNUNET_NO;
1577 }
1578
1579 ax->RK = keys[0];
1580 if (GNUNET_YES == am_I_alice)
1581 {
1582 ax->HKr = keys[1];
1583 ax->NHKs = keys[2];
1584 ax->NHKr = keys[3];
1585 ax->CKr = keys[4];
1587 }
1588 else
1589 {
1590 ax->HKs = keys[1];
1591 ax->NHKr = keys[2];
1592 ax->NHKs = keys[3];
1593 ax->CKs = keys[4];
1594 ax->ratchet_flag = GNUNET_NO;
1597 ratchet_time);
1598 }
1599 return GNUNET_OK;
1600}

References CadetTunnelAxolotl::CKr, CadetTunnelAxolotl::CKs, CadetTunnelAxolotl::DHRr, GCT_alice_or_betty(), GNUNET_break_op, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_ecdh_eddsa(), GNUNET_CRYPTO_eddsa_ecdh(), GNUNET_CRYPTO_kdf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, 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, my_private_key, CadetTunnelAxolotl::NHKr, CadetTunnelAxolotl::NHKs, pid, GNUNET_PeerIdentity::public_key, CadetTunnelAxolotl::ratchet_expiration, CadetTunnelAxolotl::ratchet_flag, 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 1609 of file gnunet-service-cadet_tunnels.c.

1610{
1611 struct CadetTunnel *t = cls;
1612 struct CadetTunnelAxolotl *ax;
1613
1614 t->kx_task = NULL;
1616 "Trying to make KX progress on %s in state %s\n",
1617 GCT_2s (t),
1618 estate2s (t->estate));
1619 switch (t->estate)
1620 {
1621 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1622 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1623 send_kx (t,
1624 NULL,
1625 &t->ax);
1626 break;
1627
1630 /* We are responding, so only require reply
1631 if WE have a channel waiting. */
1632 if (NULL != t->unverified_ax)
1633 {
1634 /* Send AX_AUTH so we might get this one verified */
1635 ax = t->unverified_ax;
1636 }
1637 else
1638 {
1639 /* How can this be? */
1640 GNUNET_break (0);
1641 ax = &t->ax;
1642 }
1643 send_kx_auth (t,
1644 NULL,
1645 ax,
1646 (0 == GCT_count_channels (t))
1647 ? GNUNET_NO
1648 : GNUNET_YES);
1649 break;
1650
1652 /* We are responding, so only require reply
1653 if WE have a channel waiting. */
1654 if (NULL != t->unverified_ax)
1655 {
1656 /* Send AX_AUTH so we might get this one verified */
1657 ax = t->unverified_ax;
1658 }
1659 else
1660 {
1661 /* How can this be? */
1662 GNUNET_break (0);
1663 ax = &t->ax;
1664 }
1665 send_kx_auth (t,
1666 NULL,
1667 ax,
1668 (0 == GCT_count_channels (t))
1669 ? GNUNET_NO
1670 : GNUNET_YES);
1671 break;
1672
1674 /* Must have been the *other* peer asking us to
1675 respond with a KX_AUTH. */
1676 if (NULL != t->unverified_ax)
1677 {
1678 /* Sending AX_AUTH in response to AX so we might get this one verified */
1679 ax = t->unverified_ax;
1680 }
1681 else
1682 {
1683 /* Sending AX_AUTH in response to AX_AUTH */
1684 ax = &t->ax;
1685 }
1686 send_kx_auth (t,
1687 NULL,
1688 ax,
1689 GNUNET_NO);
1690 break;
1691 }
1692}

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(), GCT_add_channel(), GCT_handle_kx(), and GCT_handle_kx_auth().

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 
)

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
ctconnection/tunnel combo that received encrypted message
msgthe key exchange message

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

1698{
1699 struct CadetTunnel *t = ct->t;
1700 int ret;
1701
1703 "# KX received",
1704 1,
1705 GNUNET_NO);
1706 if (GNUNET_YES ==
1707 GCT_alice_or_betty (GCP_get_id (t->destination)))
1708 {
1709 /* Betty/Bob is not allowed to send KX! */
1710 GNUNET_break_op (0);
1711 return;
1712 }
1714 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1715 GCT_2s (t),
1716 GNUNET_e2s (&msg->ephemeral_key),
1717 GNUNET_i2s (GCP_get_id (t->destination)),
1718 GCC_2s (ct->cc));
1719#if 1
1720 if ((0 ==
1721 memcmp (&t->ax.DHRr,
1722 &msg->ratchet_key,
1723 sizeof(msg->ratchet_key))) &&
1724 (0 ==
1725 memcmp (&t->ax.last_ephemeral,
1726 &msg->ephemeral_key,
1727 sizeof(msg->ephemeral_key))))
1728
1729 {
1731 "# Duplicate KX received",
1732 1,
1733 GNUNET_NO);
1734 send_kx_auth (t,
1735 ct,
1736 &t->ax,
1737 GNUNET_NO);
1738 return;
1739 }
1740#endif
1741 /* We only keep ONE unverified KX around, so if there is an existing one,
1742 clean it up. */
1743 if (NULL != t->unverified_ax)
1744 {
1745 if ((0 ==
1746 memcmp (&t->unverified_ax->DHRr,
1747 &msg->ratchet_key,
1748 sizeof(msg->ratchet_key))) &&
1749 (0 ==
1750 memcmp (&t->unverified_ax->last_ephemeral,
1751 &msg->ephemeral_key,
1752 sizeof(msg->ephemeral_key))))
1753 {
1755 "# Duplicate unverified KX received",
1756 1,
1757 GNUNET_NO);
1758#if 1
1759 send_kx_auth (t,
1760 ct,
1761 t->unverified_ax,
1762 GNUNET_NO);
1763 return;
1764#endif
1765 }
1767 "Dropping old unverified KX state.\n");
1769 "# Unverified KX dropped for fresh KX",
1770 1,
1771 GNUNET_NO);
1772 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1773 memset (t->unverified_ax,
1774 0,
1775 sizeof(struct CadetTunnelAxolotl));
1776 }
1777 else
1778 {
1780 "Creating fresh unverified KX for %s\n",
1781 GCT_2s (t));
1783 "# Fresh KX setup",
1784 1,
1785 GNUNET_NO);
1786 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1787 }
1788 /* Set as the 'current' RK/DHRr the one we are currently using,
1789 so that the duplicate-detection logic of
1790 #update_ax_by_kx can work. */
1791 t->unverified_ax->RK = t->ax.RK;
1792 t->unverified_ax->DHRr = t->ax.DHRr;
1793 t->unverified_ax->DHRs = t->ax.DHRs;
1794 t->unverified_ax->kx_0 = t->ax.kx_0;
1795 t->unverified_attempts = 0;
1796
1797 /* Update 'ax' by the new key material */
1798 ret = update_ax_by_kx (t->unverified_ax,
1799 GCP_get_id (t->destination),
1800 &msg->ephemeral_key,
1801 &msg->ratchet_key);
1803 if (GNUNET_OK != ret)
1804 {
1806 "# Useless KX",
1807 1,
1808 GNUNET_NO);
1809 return; /* duplicate KX, nothing to do */
1810 }
1811 /* move ahead in our state machine */
1812 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1815 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1818
1819 /* KX is still not done, try again our end. */
1820 if (CADET_TUNNEL_KEY_OK != t->estate)
1821 {
1822 if (NULL != t->kx_task)
1823 GNUNET_SCHEDULER_cancel (t->kx_task);
1824 t->kx_task
1826 t);
1827 }
1828}

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, CadetTConnection::cc, GCC_2s(), GCP_get_id(), GCT_2s(), GCT_alice_or_betty(), GCT_change_estate(), GNUNET_break, GNUNET_break_op, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, LOG, msg, ret, retry_kx(), 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:

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

1908{
1909 struct CadetTunnel *t = ct->t;
1910 struct CadetTunnelAxolotl ax_tmp;
1911 struct GNUNET_HashCode kx_auth;
1912 int ret;
1913
1915 "# KX_AUTH received",
1916 1,
1917 GNUNET_NO);
1918 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1919 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1920 {
1921 /* Confusing, we got a KX_AUTH before we even send our own
1922 KX. This should not happen. We'll send our own KX ASAP anyway,
1923 so let's ignore this here. */
1924 GNUNET_break_op (0);
1925 return;
1926 }
1928 "Handling KX_AUTH message from %s with ephemeral %s\n",
1929 GCT_2s (t),
1930 GNUNET_e2s (&msg->kx.ephemeral_key));
1931 /* We do everything in ax_tmp until we've checked the authentication
1932 so we don't clobber anything we care about by accident. */
1933 ax_tmp = t->ax;
1934
1935 /* Update 'ax' by the new key material */
1936 ret = update_ax_by_kx (&ax_tmp,
1937 GCP_get_id (t->destination),
1938 &msg->kx.ephemeral_key,
1939 &msg->kx.ratchet_key);
1940 if (GNUNET_OK != ret)
1941 {
1942 if (GNUNET_NO == ret)
1944 "# redundant KX_AUTH received",
1945 1,
1946 GNUNET_NO);
1947 else
1948 GNUNET_break (0); /* connect to self!? */
1949 return;
1950 }
1951 GNUNET_CRYPTO_hash (&ax_tmp.RK,
1952 sizeof(ax_tmp.RK),
1953 &kx_auth);
1954 if (0 != GNUNET_memcmp (&kx_auth,
1955 &msg->auth))
1956 {
1957 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1958 we transmitted to the sender, refuse it, try KX again. */
1960 "# KX_AUTH not using our last KX received (auth failure)",
1961 1,
1962 GNUNET_NO);
1964 "KX AUTH mismatch!\n");
1965#if DEBUG_KX
1966 {
1967 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1968
1970 &ephemeral_key);
1971 if (0 != GNUNET_memcmp (&ephemeral_key,
1972 &msg->r_ephemeral_key_XXX))
1973 {
1975 "My ephemeral is %s!\n",
1976 GNUNET_e2s (&ephemeral_key));
1978 "Response is for ephemeral %s!\n",
1979 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
1980 }
1981 else
1982 {
1983 test_crypto_bug (&ax_tmp.kx_0,
1984 &msg->kx.ephemeral_key_XXX,
1986 &msg->kx.private_key_XXX);
1987 }
1988 }
1989#endif
1990 if (NULL == t->kx_task)
1991 t->kx_task
1992 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1993 &retry_kx,
1994 t);
1995 return;
1996 }
1997 /* Yep, we're good. */
1998 t->ax = ax_tmp;
1999 if (NULL != t->unverified_ax)
2000 {
2001 /* We got some "stale" KX before, drop that. */
2002 cleanup_ax (t->unverified_ax);
2003 GNUNET_free (t->unverified_ax);
2004 t->unverified_ax = NULL;
2005 }
2006
2007 /* move ahead in our state machine */
2008 switch (t->estate)
2009 {
2012 /* Checked above, this is impossible. */
2013 GNUNET_assert (0);
2014 break;
2015
2016 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2017 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2018 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2021 break;
2022
2024 /* Did not expect another KX_AUTH, but so what, still acceptable.
2025 Nothing to do here. */
2026 break;
2027 }
2028 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2029 {
2030 send_kx_auth (t,
2031 NULL,
2032 &t->ax,
2033 GNUNET_NO);
2034 }
2035}

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(), GCP_get_id(), GCT_2s(), GCT_change_estate(), GNUNET_assert, GNUNET_break, GNUNET_break_op, 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, my_private_key, ret, retry_kx(), CadetTunnelAxolotl::RK, send_kx_auth(), 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 2048 of file gnunet-service-cadet_tunnels.c.

2049{
2050#define HIGH_BIT 0x8000000
2052 uint32_t ctn;
2053 int cmp;
2054 uint32_t highbit;
2055
2056 cmp = GNUNET_memcmp (&my_full_id,
2058 if (0 < cmp)
2059 highbit = HIGH_BIT;
2060 else if (0 > cmp)
2061 highbit = 0;
2062 else
2063 GNUNET_assert (0); // loopback must never go here!
2064 ctn = ntohl (t->next_ctn.cn);
2065 while (NULL !=
2067 ctn | highbit))
2068 {
2069 ctn = ((ctn + 1) & (~HIGH_BIT));
2070 }
2071 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2072 ret.cn = htonl (ctn | highbit);
2073 return ret;
2074}

References GCP_get_id(), GCT_get_destination(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get(), GNUNET_memcmp, HIGH_BIT, my_full_id, 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 2087 of file gnunet-service-cadet_tunnels.c.

2089{
2091
2092 ctn = get_next_free_ctn (t);
2093 if (NULL != t->destroy_task)
2094 {
2095 GNUNET_SCHEDULER_cancel (t->destroy_task);
2096 t->destroy_task = NULL;
2097 }
2100 ntohl (ctn.cn),
2101 ch,
2104 "Adding %s to %s with state %d\n",
2105 GCCH_2s (ch),
2106 GCT_2s (t),
2107 t->estate);
2108 switch (t->estate)
2109 {
2111 /* waiting for connection to start KX */
2112 break;
2113
2117 /* we're currently waiting for KX to complete */
2118 break;
2119
2121 /* waiting for OTHER peer to send us data,
2122 we might need to prompt more aggressively! */
2123 if (NULL == t->kx_task)
2124 t->kx_task
2125 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2126 &retry_kx,
2127 t);
2128 break;
2129
2131 /* We are ready. Tell the new channel that we are up. */
2133 break;
2134 }
2135 return ctn;
2136}

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

2147{
2148 struct CadetTunnel *t = ct->t;
2149
2150 if (GNUNET_YES == ct->is_ready)
2151 {
2152 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2153 t->connection_ready_tail,
2154 ct);
2155 t->num_ready_connections--;
2156 }
2157 else
2158 {
2159 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2160 t->connection_busy_tail,
2161 ct);
2162 t->num_busy_connections--;
2163 }
2164 GNUNET_free (ct);
2165}

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

2177{
2178 struct CadetTunnel *t = cls;
2179 struct CadetConnection *cc = ct->cc;
2180
2181 GNUNET_assert (ct->t == t);
2184}

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

2194{
2195 struct CadetTunnel *t = cls;
2196 struct CadetTunnelQueueEntry *tq;
2197
2198 t->destroy_task = NULL;
2200 "Destroying idle %s\n",
2201 GCT_2s (t));
2205 t);
2206 GNUNET_assert (NULL == t->connection_ready_head);
2207 GNUNET_assert (NULL == t->connection_busy_head);
2208 while (NULL != (tq = t->tq_head))
2209 {
2210 if (NULL != tq->cont)
2211 tq->cont (tq->cont_cls,
2212 NULL);
2213 GCT_send_cancel (tq);
2214 }
2215 GCP_drop_tunnel (t->destination,
2216 t);
2218 if (NULL != t->maintain_connections_task)
2219 {
2220 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2221 t->maintain_connections_task = NULL;
2222 }
2223 if (NULL != t->send_task)
2224 {
2225 GNUNET_SCHEDULER_cancel (t->send_task);
2226 t->send_task = NULL;
2227 }
2228 if (NULL != t->kx_task)
2229 {
2230 GNUNET_SCHEDULER_cancel (t->kx_task);
2231 t->kx_task = NULL;
2232 }
2233 GNUNET_MST_destroy (t->mst);
2234 GNUNET_MQ_destroy (t->mq);
2235 if (NULL != t->unverified_ax)
2236 {
2237 cleanup_ax (t->unverified_ax);
2238 GNUNET_free (t->unverified_ax);
2239 }
2240 cleanup_ax (&t->ax);
2241 GNUNET_assert (NULL == t->destroy_task);
2242 GNUNET_free (t);
2243}

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

2257{
2259 "Removing %s from %s\n",
2260 GCCH_2s (ch),
2261 GCT_2s (t));
2264 ntohl (ctn.cn),
2265 ch));
2266 if ((0 ==
2267 GCT_count_channels (t)) &&
2268 (NULL == t->destroy_task))
2269 {
2270 t->destroy_task
2273 t);
2274 }
2275}

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

2290{
2291 struct CadetChannel *ch = value;
2292
2294 NULL);
2295 return GNUNET_OK;
2296}

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

2306{
2310 t);
2311 GNUNET_assert (0 ==
2313 if (NULL != t->destroy_task)
2314 {
2315 GNUNET_SCHEDULER_cancel (t->destroy_task);
2316 t->destroy_task = NULL;
2317 }
2318 destroy_tunnel (t);
2319}

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

2332{
2333 struct CadetTunnelQueueEntry *tq;
2334
2336 tq = t->tq_head;
2337 if (NULL == tq)
2338 {
2339 /* no messages pending right now */
2341 "Not sending payload of %s on ready %s (nothing pending)\n",
2342 GCT_2s (t),
2343 GCC_2s (ct->cc));
2344 return;
2345 }
2346 /* ready to send message 'tq' on tunnel 'ct' */
2347 GNUNET_assert (t == tq->t);
2349 t->tq_tail,
2350 tq);
2351 if (NULL != tq->cid)
2352 *tq->cid = *GCC_get_id (ct->cc);
2355 "Sending payload of %s on %s\n",
2356 GCT_2s (t),
2357 GCC_2s (ct->cc));
2358 GCC_transmit (ct->cc,
2359 tq->env);
2360 if (NULL != tq->cont)
2361 tq->cont (tq->cont_cls,
2362 GCC_get_id (ct->cc));
2363 GNUNET_free (tq);
2364}

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

2378{
2379 struct CadetTConnection *ct = cls;
2380 struct CadetTunnel *t = ct->t;
2381
2382 if (GNUNET_NO == is_ready)
2383 {
2385 "%s no longer ready for %s\n",
2386 GCC_2s (ct->cc),
2387 GCT_2s (t));
2389 return;
2390 }
2392 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2393 t->connection_busy_tail,
2394 ct);
2395 GNUNET_assert (0 < t->num_busy_connections);
2396 t->num_busy_connections--;
2397 ct->is_ready = GNUNET_YES;
2398 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2399 t->connection_ready_tail,
2400 ct);
2401 t->num_ready_connections++;
2402
2404 "%s now ready for %s in state %s\n",
2405 GCC_2s (ct->cc),
2406 GCT_2s (t),
2407 estate2s (t->estate));
2408 switch (t->estate)
2409 {
2412 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2413 GCT_2s (t),
2414 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2415 t->next_kx_attempt).rel_value_us);
2416 /* Do not begin KX if WE have no channels waiting! */
2418 t->next_kx_attempt).rel_value_us)
2419 return; /* wait for timeout before retrying */
2420 /* We are uninitialized, just transmit immediately,
2421 without undue delay. */
2422
2424 "Why for %s \n",
2425 GCT_2s (t));
2426
2427 if (NULL != t->kx_task)
2428 {
2429 GNUNET_SCHEDULER_cancel (t->kx_task);
2430 t->kx_task = NULL;
2431 }
2432 send_kx (t,
2433 ct,
2434 &t->ax);
2435 if ((0 ==
2436 GCT_count_channels (t)) &&
2437 (NULL == t->destroy_task))
2438 {
2439 t->destroy_task
2442 t);
2443 }
2444 break;
2445
2450 /* we're currently waiting for KX to complete, schedule job */
2451 if (NULL == t->kx_task)
2452 t->kx_task
2453 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2454 &retry_kx,
2455 t);
2456 break;
2457
2459 if (GNUNET_YES == t->kx_auth_requested)
2460 {
2462 t->next_kx_attempt).rel_value_us)
2463 return; /* wait for timeout */
2464 if (NULL != t->kx_task)
2465 {
2466 GNUNET_SCHEDULER_cancel (t->kx_task);
2467 t->kx_task = NULL;
2468 }
2469 send_kx_auth (t,
2470 ct,
2471 &t->ax,
2472 GNUNET_NO);
2473 return;
2474 }
2476 ct);
2477 break;
2478 }
2479}

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

2566{
2567 struct EvaluationSummary *es = cls;
2568 struct CadetConnection *cc = ct->cc;
2569 unsigned int ct_length;
2570 struct CadetPeerPath *ps;
2571 const struct CadetConnectionMetrics *metrics;
2572 GNUNET_CONTAINER_HeapCostType ct_desirability;
2573 struct GNUNET_TIME_Relative uptime;
2574 struct GNUNET_TIME_Relative last_use;
2575 double score;
2576 double success_rate;
2577
2578 ps = GCC_get_path (cc,
2579 &ct_length);
2581 "Evaluating path %s of existing %s\n",
2582 GCPP_2s (ps),
2583 GCC_2s (cc));
2584 if (ps == es->path)
2585 {
2587 "Ignoring duplicate path %s.\n",
2588 GCPP_2s (es->path));
2589 es->duplicate = GNUNET_YES;
2590 return;
2591 }
2592 if (NULL != es->path)
2593 {
2594 int duplicate = GNUNET_YES;
2595
2596 for (unsigned int i = 0; i < ct_length; i++)
2597 {
2600 i) !=
2602 i))
2603 {
2604 duplicate = GNUNET_NO;
2605 break;
2606 }
2607 }
2608 if (GNUNET_YES == duplicate)
2609 {
2611 "Ignoring overlapping path %s.\n",
2612 GCPP_2s (es->path));
2613 es->duplicate = GNUNET_YES;
2614 return;
2615 }
2616 else
2617 {
2619 "Known path %s differs from proposed path\n",
2620 GCPP_2s (ps));
2621 }
2622 }
2623
2624 ct_desirability = GCPP_get_desirability (ps);
2625 metrics = GCC_get_metrics (cc);
2626 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2627 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2628 /* We add 1.0 here to avoid division by zero. */
2629 success_rate = (metrics->num_acked_transmissions + 1.0)
2630 / (metrics->num_successes + 1.0);
2631 score
2632 = ct_desirability
2633 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2634 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2635 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2636 score *= success_rate; /* weigh overall by success rate */
2637
2638 if ((NULL == es->worst) ||
2639 (score < es->worst_score))
2640 {
2641 es->worst = ct;
2642 es->worst_score = score;
2643 }
2644 es->min_length = GNUNET_MIN (es->min_length,
2645 ct_length);
2646 es->max_length = GNUNET_MAX (es->max_length,
2647 ct_length);
2648 es->min_desire = GNUNET_MIN (es->min_desire,
2649 ct_desirability);
2650 es->max_desire = GNUNET_MAX (es->max_desire,
2651 ct_desirability);
2652}

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

2668{
2669 struct CadetTunnel *t = cls;
2670 struct EvaluationSummary es;
2671 struct CadetTConnection *ct;
2672
2673 GNUNET_assert (off < GCPP_get_length (path));
2675 off) == t->destination);
2676 es.min_length = UINT_MAX;
2677 es.max_length = 0;
2678 es.max_desire = 0;
2679 es.min_desire = UINT64_MAX;
2680 es.path = path;
2681 es.duplicate = GNUNET_NO;
2682 es.worst = NULL;
2683
2684 /* Compute evaluation summary over existing connections. */
2686 "Evaluating proposed path %s for target %s\n",
2687 GCPP_2s (path),
2688 GCT_2s (t));
2689 /* FIXME: suspect this does not ACTUALLY iterate
2690 over all existing paths, otherwise dup detection
2691 should work!!! */
2694 &es);
2695 if (GNUNET_YES == es.duplicate)
2696 return GNUNET_YES;
2697
2698 /* FIXME: not sure we should really just count
2699 'num_connections' here, as they may all have
2700 consistently failed to connect. */
2701
2702 /* We iterate by increasing path length; if we have enough paths and
2703 this one is more than twice as long than what we are currently
2704 using, then ignore all of these super-long ones! */
2706 (es.min_length * 2 < off) &&
2707 (es.max_length < off))
2708 {
2710 "Ignoring paths of length %u, they are way too long.\n",
2711 es.min_length * 2);
2712 return GNUNET_NO;
2713 }
2714 /* If we have enough paths and this one looks no better, ignore it. */
2716 (es.min_length < GCPP_get_length (path)) &&
2717 (es.min_desire > GCPP_get_desirability (path)) &&
2718 (es.max_length < off))
2719 {
2721 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2722 GCPP_get_length (path),
2723 (unsigned long long) GCPP_get_desirability (path),
2724 GCP_2s (t->destination));
2725 return GNUNET_YES;
2726 }
2727
2728 /* Path is interesting (better by some metric, or we don't have
2729 enough paths yet). */
2730 ct = GNUNET_new (struct CadetTConnection);
2732 ct->t = t;
2733 ct->cc = GCC_create (t->destination,
2734 path,
2735 off,
2736 ct,
2738 ct);
2739
2740 /* FIXME: schedule job to kill connection (and path?) if it takes
2741 too long to get ready! (And track performance data on how long
2742 other connections took with the tunnel!)
2743 => Note: to be done within 'connection'-logic! */
2744 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2745 t->connection_busy_tail,
2746 ct);
2747 t->num_busy_connections++;
2749 "Found interesting path %s for %s, created %s\n",
2750 GCPP_2s (path),
2751 GCT_2s (t),
2752 GCC_2s (ct->cc));
2753 return GNUNET_YES;
2754}

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

2772{
2773 struct CadetTunnel *t = cls;
2774 struct GNUNET_TIME_Relative delay;
2775 struct EvaluationSummary es;
2776
2777 t->maintain_connections_task = NULL;
2779 "Performing connection maintenance for %s.\n",
2780 GCT_2s (t));
2781
2782 es.min_length = UINT_MAX;
2783 es.max_length = 0;
2784 es.max_desire = 0;
2785 es.min_desire = UINT64_MAX;
2786 es.path = NULL;
2787 es.worst = NULL;
2788 es.duplicate = GNUNET_NO;
2791 &es);
2792 if ((NULL != es.worst) &&
2794 {
2795 /* Clear out worst-performing connection 'es.worst'. */
2797 es.worst);
2798 }
2799
2800 /* Consider additional paths */
2801 (void) GCP_iterate_paths (t->destination,
2803 t);
2804
2805 /* FIXME: calculate when to try again based on how well we are doing;
2806 in particular, if we have to few connections, we might be able
2807 to do without this (as PATHS should tell us whenever a new path
2808 is available instantly; however, need to make sure this job is
2809 restarted after that happens).
2810 Furthermore, if the paths we do know are in a reasonably narrow
2811 quality band and are plentyful, we might also consider us stabilized
2812 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2813 t->maintain_connections_task
2816 t);
2817}

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

2824{
2826 "Considering %s for %s (offset %u)\n",
2827 GCPP_2s (p),
2828 GCT_2s (t),
2829 off);
2830 (void) consider_path_cb (t,
2831 p,
2832 off);
2833}

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

2845{
2846 struct CadetTunnel *t = cls;
2847
2849 "Received KEEPALIVE on %s\n",
2850 GCT_2s (t));
2852 "# keepalives received",
2853 1,
2854 GNUNET_NO);
2855}

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

2868{
2869 return GNUNET_OK;
2870}

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

2883{
2884 struct CadetTunnel *t = cls;
2885 struct CadetChannel *ch;
2886
2887 ch = lookup_channel (t,
2888 msg->ctn);
2889 if (NULL == ch)
2890 {
2891 /* We don't know about such a channel, might have been destroyed on our
2892 end in the meantime, or never existed. Send back a DESTROY. */
2894 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2895 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2896 ntohl (msg->ctn.cn));
2898 msg->ctn);
2899 return;
2900 }
2902 GCC_get_id (t->current_ct->cc),
2903 msg);
2904}

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

2918{
2919 struct CadetTunnel *t = cls;
2920 struct CadetChannel *ch;
2921
2922 ch = lookup_channel (t,
2923 ack->ctn);
2924 if (NULL == ch)
2925 {
2926 /* We don't know about such a channel, might have been destroyed on our
2927 end in the meantime, or never existed. Send back a DESTROY. */
2929 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2930 ntohl (ack->ctn.cn));
2932 ack->ctn);
2933 return;
2934 }
2936 GCC_get_id (t->current_ct->cc),
2937 ack);
2938}

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

2952{
2953 struct CadetTunnel *t = cls;
2954 struct CadetChannel *ch;
2955
2957 ntohl (copen->ctn.cn));
2958 if (NULL != ch)
2959 {
2961 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2962 GNUNET_h2s (&copen->h_port),
2963 GCT_2s (t),
2964 GCCH_2s (ch));
2966 GCC_get_id (t->current_ct->cc));
2967 return;
2968 }
2970 "Received CHANNEL_OPEN on h_port %s from %s\n",
2971 GNUNET_h2s (&copen->h_port),
2972 GCT_2s (t));
2974 copen->ctn,
2975 &copen->h_port,
2976 ntohl (copen->opt));
2977 if (NULL != t->destroy_task)
2978 {
2979 GNUNET_SCHEDULER_cancel (t->destroy_task);
2980 t->destroy_task = NULL;
2981 }
2984 ntohl (copen->ctn.cn),
2985 ch,
2987}

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

2999{
3001
3003 "Sending DESTROY message for channel ID %u\n",
3004 ntohl (ctn.cn));
3005 msg.header.size = htons (sizeof(msg));
3007 msg.reserved = htonl (0);
3008 msg.ctn = ctn;
3009 GCT_send (t,
3010 &msg.header,
3011 NULL,
3012 NULL,
3013 &ctn);
3014}

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

3029{
3030 struct CadetTunnel *t = cls;
3031 struct CadetChannel *ch;
3032
3033 ch = lookup_channel (t,
3034 cm->ctn);
3035 if (NULL == ch)
3036 {
3037 /* We don't know about such a channel, might have been destroyed on our
3038 end in the meantime, or never existed. Send back a DESTROY. */
3040 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3041 ntohl (cm->ctn.cn));
3043 cm->ctn);
3044 return;
3045 }
3047 "Received channel OPEN_ACK on channel %s from %s\n",
3048 GCCH_2s (ch),
3049 GCT_2s (t));
3051 GCC_get_id (t->current_ct->cc),
3052 &cm->port);
3053}

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

3067{
3068 struct CadetTunnel *t = cls;
3069 struct CadetChannel *ch;
3070
3071 ch = lookup_channel (t,
3072 cm->ctn);
3073 if (NULL == ch)
3074 {
3075 /* We don't know about such a channel, might have been destroyed on our
3076 end in the meantime, or never existed. */
3078 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3079 ntohl (cm->ctn.cn));
3080 return;
3081 }
3083 "Received channel DESTROY on %s from %s\n",
3084 GCCH_2s (ch),
3085 GCT_2s (t));
3087 GCC_get_id (t->current_ct->cc));
3088}

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

3104{
3105 struct CadetTunnel *t = cls;
3106
3107 GNUNET_assert (NULL != t->current_ct);
3109 msg);
3110 return GNUNET_OK;
3111}

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

3124{
3125 GNUNET_break_op (0);
3126}

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

3138{
3139 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3141 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3143 struct GNUNET_MessageHeader,
3144 t),
3145 GNUNET_MQ_hd_var_size (plaintext_data,
3148 t),
3149 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3152 t),
3153 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3156 t),
3157 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3160 t),
3161 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3164 t),
3166 };
3167
3168 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3169 new_ephemeral (&t->ax);
3171 t->destination = destination;
3173 t->maintain_connections_task
3175 t);
3176 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3177 NULL,
3178 NULL,
3179 NULL,
3180 handlers,
3182 t);
3184 t);
3185 return t;
3186}

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

3194{
3195 struct CadetTConnection *ct;
3196
3197 ct = GNUNET_new (struct CadetTConnection);
3199 ct->t = t;
3200 ct->cc = GCC_create_inbound (t->destination,
3201 path,
3202 ct,
3203 cid,
3205 ct);
3206 if (NULL == ct->cc)
3207 {
3209 "%s refused inbound %s (duplicate)\n",
3210 GCT_2s (t),
3211 GCC_2s (ct->cc));
3212 GNUNET_free (ct);
3213 return GNUNET_SYSERR;
3214 }
3215 /* FIXME: schedule job to kill connection (and path?) if it takes
3216 too long to get ready! (And track performance data on how long
3217 other connections took with the tunnel!)
3218 => Note: to be done within 'connection'-logic! */
3219 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3220 t->connection_busy_tail,
3221 ct);
3222 t->num_busy_connections++;
3224 "%s has new %s\n",
3225 GCT_2s (t),
3226 GCC_2s (ct->cc));
3227 return GNUNET_OK;
3228}

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

3240{
3241 struct CadetTunnel *t = ct->t;
3242 uint16_t size = ntohs (msg->header.size);
3243 char cbuf[size] GNUNET_ALIGN;
3244 ssize_t decrypted_size;
3245
3247 "%s received %u bytes of encrypted data in state %d\n",
3248 GCT_2s (t),
3249 (unsigned int) size,
3250 t->estate);
3251
3252 switch (t->estate)
3253 {
3256 /* We did not even SEND our KX, how can the other peer
3257 send us encrypted data? Must have been that we went
3258 down and the other peer still things we are up.
3259 Let's send it KX back. */
3261 "# received encrypted without any KX",
3262 1,
3263 GNUNET_NO);
3264 if (NULL != t->kx_task)
3265 {
3266 GNUNET_SCHEDULER_cancel (t->kx_task);
3267 t->kx_task = NULL;
3268 }
3269 send_kx (t,
3270 ct,
3271 &t->ax);
3272 return;
3273
3275 /* We send KX, and other peer send KX to us at the same time.
3276 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3278 "# received encrypted without KX_AUTH",
3279 1,
3280 GNUNET_NO);
3281 if (NULL != t->kx_task)
3282 {
3283 GNUNET_SCHEDULER_cancel (t->kx_task);
3284 t->kx_task = NULL;
3285 }
3286 send_kx_auth (t,
3287 ct,
3288 &t->ax,
3289 GNUNET_YES);
3290 return;
3291
3293 /* We did not get the KX of the other peer, but that
3294 might have been lost. Send our KX again immediately. */
3296 "# received encrypted without KX",
3297 1,
3298 GNUNET_NO);
3299 if (NULL != t->kx_task)
3300 {
3301 GNUNET_SCHEDULER_cancel (t->kx_task);
3302 t->kx_task = NULL;
3303 }
3304 send_kx (t,
3305 ct,
3306 &t->ax);
3307 return;
3308
3310 /* Great, first payload, we might graduate to OK! */
3312 /* We are up and running, all good. */
3313 break;
3314 }
3315
3316 decrypted_size = -1;
3317 if (CADET_TUNNEL_KEY_OK == t->estate)
3318 {
3319 /* We have well-established key material available,
3320 try that. (This is the common case.) */
3321 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3322 cbuf,
3323 msg,
3324 size);
3325 }
3326
3327 if ((-1 == decrypted_size) &&
3328 (NULL != t->unverified_ax))
3329 {
3330 /* We have un-authenticated KX material available. We should try
3331 this as a back-up option, in case the sender crashed and
3332 switched keys. */
3333 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3334 cbuf,
3335 msg,
3336 size);
3337 if (-1 != decrypted_size)
3338 {
3339 /* It worked! Treat this as authentication of the AX data! */
3340 cleanup_ax (&t->ax);
3341 t->ax = *t->unverified_ax;
3342 GNUNET_free (t->unverified_ax);
3343 t->unverified_ax = NULL;
3344 }
3345 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3346 {
3347 /* First time it worked, move tunnel into production! */
3350 if (NULL != t->send_task)
3351 GNUNET_SCHEDULER_cancel (t->send_task);
3353 t);
3354 }
3355 }
3356 if (NULL != t->unverified_ax)
3357 {
3358 /* We had unverified KX material that was useless; so increment
3359 counter and eventually move to ignore it. Note that we even do
3360 this increment if we successfully decrypted with the old KX
3361 material and thus didn't even both with the new one. This is
3362 the ideal case, as a malicious injection of bogus KX data
3363 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3365 "Failed to decrypt message with unverified KX data %u times\n",
3366 t->unverified_attempts);
3367 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3368 {
3369 cleanup_ax (t->unverified_ax);
3370 GNUNET_free (t->unverified_ax);
3371 t->unverified_ax = NULL;
3372 }
3373 }
3374
3375 if (-1 == decrypted_size)
3376 {
3377 /* Decryption failed for good, complain. */
3379 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3380 GCT_2s (t));
3382 "# unable to decrypt",
3383 1,
3384 GNUNET_NO);
3385 if (NULL != t->kx_task)
3386 {
3387 GNUNET_SCHEDULER_cancel (t->kx_task);
3388 t->kx_task = NULL;
3389 }
3390 send_kx (t,
3391 ct,
3392 &t->ax);
3393 return;
3394 }
3396 "# decrypted bytes",
3397 decrypted_size,
3398 GNUNET_NO);
3399
3400 /* The MST will ultimately call #handle_decrypted() on each message. */
3401 t->current_ct = ct;
3404 cbuf,
3405 decrypted_size,
3406 GNUNET_YES,
3407 GNUNET_NO));
3408 t->current_ct = NULL;
3409}

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

3418{
3419 struct CadetTunnelQueueEntry *tq;
3420 uint16_t payload_size;
3421 struct GNUNET_MQ_Envelope *env;
3423 struct CadetChannel *ch;
3424
3425 if (NULL != ctn)
3426 {
3427 ch = lookup_channel (t,
3428 *ctn);
3429 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3430 {
3431 GNUNET_break (0);
3432 return NULL;
3433 }
3434 }
3435
3436 if (CADET_TUNNEL_KEY_OK != t->estate)
3437 {
3438 GNUNET_break (0);
3439 return NULL;
3440 }
3441 payload_size = ntohs (message->size);
3443 "Encrypting %u bytes for %s\n",
3444 (unsigned int) payload_size,
3445 GCT_2s (t));
3446 env = GNUNET_MQ_msg_extra (ax_msg,
3447 payload_size,
3449 t_ax_encrypt (&t->ax,
3450 &ax_msg[1],
3451 message,
3452 payload_size);
3454 "# encrypted bytes",
3455 payload_size,
3456 GNUNET_NO);
3457 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3458 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3459 /* FIXME: we should do this once, not once per message;
3460 this is a point multiplication, and DHRs does not
3461 change all the time. */
3463 &ax_msg->ax_header.DHRs);
3464 t_h_encrypt (&t->ax,
3465 ax_msg);
3466 t_hmac (&ax_msg->ax_header,
3467 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3468 0,
3469 &t->ax.HKs,
3470 &ax_msg->hmac);
3471
3472 tq = GNUNET_malloc (sizeof(*tq));
3473 tq->t = t;
3474 tq->env = env;
3475 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3476 tq->cont = cont;
3477 tq->cont_cls = cont_cls;
3479 t->tq_tail,
3480 tq);
3481 if (NULL != t->send_task)
3482 GNUNET_SCHEDULER_cancel (t->send_task);
3483 t->send_task
3485 t);
3486 return tq;
3487}

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

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

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

◆ GCT_send_cancel()

void GCT_send_cancel ( struct CadetTunnelQueueEntry q)

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

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

Parameters
qHandle to the queue entry to cancel.

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

3492{
3493 struct CadetTunnel *t = tq->t;
3494
3496 t->tq_tail,
3497 tq);
3498 GNUNET_MQ_discard (tq->env);
3499 GNUNET_free (tq);
3500}

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

3514{
3515 struct CadetTConnection *n;
3516
3517 for (struct CadetTConnection *ct = t->connection_ready_head;
3518 NULL != ct;
3519 ct = n)
3520 {
3521 n = ct->next;
3522 iter (iter_cls,
3523 ct);
3524 }
3525 for (struct CadetTConnection *ct = t->connection_busy_head;
3526 NULL != ct;
3527 ct = n)
3528 {
3529 n = ct->next;
3530 iter (iter_cls,
3531 ct);
3532 }
3533}

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

3565{
3566 struct ChanIterCls *ctx = cls;
3567 struct CadetChannel *ch = value;
3568
3569 ctx->iter (ctx->iter_cls,
3570 ch);
3571 return GNUNET_OK;
3572}

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

3586{
3587 struct ChanIterCls ctx;
3588
3589 ctx.iter = iter;
3590 ctx.iter_cls = iter_cls;
3593 &ctx);
3594}

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

3609{
3610 const enum GNUNET_ErrorType *level = cls;
3611 struct CadetChannel *ch = value;
3612
3613 GCCH_debug (ch, *level);
3614 return GNUNET_OK;
3615}

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

3631{
3632#if ! defined(GNUNET_CULL_LOGGING)
3633 struct CadetTConnection *iter_c;
3634 int do_log;
3635
3637 "cadet-tun",
3638 __FILE__, __FUNCTION__, __LINE__);
3639 if (0 == do_log)
3640 return;
3641
3642 LOG2 (level,
3643 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3644 GCT_2s (t),
3645 estate2s (t->estate),
3646 t->tq_len,
3648 LOG2 (level,
3649 "TTT channels:\n");
3652 &level);
3653 LOG2 (level,
3654 "TTT connections:\n");
3655 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3656 GCC_debug (iter_c->cc,
3657 level);
3658 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3659 GCC_debug (iter_c->cc,
3660 level);
3661
3662 LOG2 (level,
3663 "TTT TUNNEL END\n");
3664#endif
3665}

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: