diff options
-rw-r--r-- | src/transport/gnunet-communicator-quic.c | 187 |
1 files changed, 106 insertions, 81 deletions
diff --git a/src/transport/gnunet-communicator-quic.c b/src/transport/gnunet-communicator-quic.c index 22e567a81..cdbd05477 100644 --- a/src/transport/gnunet-communicator-quic.c +++ b/src/transport/gnunet-communicator-quic.c | |||
@@ -42,10 +42,12 @@ static unsigned long long rekey_max_bytes; | |||
42 | static quiche_config *config = NULL; | 42 | static quiche_config *config = NULL; |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * Information we track per receiving address we have recently been | 45 | * Information we track per peer we have recently been in contact with. |
46 | * in contact with (encryption to receiver). | 46 | * |
47 | * (Since quiche handles crypto, handshakes, etc. we don't differentiate | ||
48 | * between SenderAddress and ReceiverAddress) | ||
47 | */ | 49 | */ |
48 | struct ReceiverAddress | 50 | struct PeerAddress |
49 | { | 51 | { |
50 | /** | 52 | /** |
51 | * To whom are we talking to. | 53 | * To whom are we talking to. |
@@ -79,13 +81,13 @@ struct ReceiverAddress | |||
79 | struct GNUNET_TRANSPORT_QueueHandle *d_qh; | 81 | struct GNUNET_TRANSPORT_QueueHandle *d_qh; |
80 | 82 | ||
81 | /** | 83 | /** |
82 | * Timeout for this receiver address. | 84 | * Timeout for this peer address. |
83 | */ | 85 | */ |
84 | struct GNUNET_TIME_Absolute timeout; | 86 | struct GNUNET_TIME_Absolute timeout; |
85 | 87 | ||
86 | /** | 88 | /** |
87 | * MTU we allowed transport for this receiver's default queue. | 89 | * MTU we allowed transport for this peer's default queue. |
88 | * FIXME: You may want to get the MTU from quiche, possibly from quiche_path_stats struct. | 90 | * FIXME: MTU from quiche |
89 | */ | 91 | */ |
90 | size_t d_mtu; | 92 | size_t d_mtu; |
91 | 93 | ||
@@ -97,7 +99,7 @@ struct ReceiverAddress | |||
97 | /** | 99 | /** |
98 | * receiver_destroy already called on receiver. | 100 | * receiver_destroy already called on receiver. |
99 | */ | 101 | */ |
100 | int receiver_destroy_called; | 102 | int peer_destroy_called; |
101 | 103 | ||
102 | /** | 104 | /** |
103 | * Entry in sender expiration heap. | 105 | * Entry in sender expiration heap. |
@@ -106,19 +108,14 @@ struct ReceiverAddress | |||
106 | }; | 108 | }; |
107 | 109 | ||
108 | /** | 110 | /** |
109 | * Receivers (map from peer identity to `struct ReceiverAddress`) | 111 | * Peers (map from peer identity to `struct PeerAddress`) |
110 | */ | 112 | */ |
111 | static struct GNUNET_CONTAINER_MultiPeerMap *receivers; | 113 | static struct GNUNET_CONTAINER_MultiPeerMap *peers; |
112 | 114 | ||
113 | /** | 115 | /** |
114 | * Expiration heap for senders (contains `struct SenderAddress`) | 116 | * Expiration heap for peers (contains `struct PeerAddress`) |
115 | */ | 117 | */ |
116 | static struct GNUNET_CONTAINER_Heap *senders_heap; | 118 | static struct GNUNET_CONTAINER_Heap *peers_heap; |
117 | |||
118 | /** | ||
119 | * Expiration heap for receivers (contains `struct ReceiverAddress`) | ||
120 | */ | ||
121 | static struct GNUNET_CONTAINER_Heap *receivers_heap; | ||
122 | 119 | ||
123 | /** | 120 | /** |
124 | * ID of timeout task | 121 | * ID of timeout task |
@@ -270,13 +267,7 @@ create_conn (uint8_t *scid, size_t scid_len, | |||
270 | struct quic_conn *conn; | 267 | struct quic_conn *conn; |
271 | quiche_conn *q_conn; | 268 | quiche_conn *q_conn; |
272 | struct GNUNET_HashCode conn_key; | 269 | struct GNUNET_HashCode conn_key; |
273 | 270 | conn = GNUNET_new (struct quic_conn); | |
274 | /** | ||
275 | * FIXME: | ||
276 | * GNUnet has a convienience function: | ||
277 | * conn = GNUNET_new (struct quic_conn); | ||
278 | */ | ||
279 | conn = GNUNET_malloc (sizeof(struct quic_conn)); | ||
280 | if (scid_len != LOCAL_CONN_ID_LEN) | 271 | if (scid_len != LOCAL_CONN_ID_LEN) |
281 | { | 272 | { |
282 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 273 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -351,39 +342,39 @@ flush_egress (struct quic_conn *conn) | |||
351 | * | 342 | * |
352 | * @param mq the message queue | 343 | * @param mq the message queue |
353 | * @param msg the message to send | 344 | * @param msg the message to send |
354 | * @param impl_state our `struct ReceiverAddress` | 345 | * @param impl_state our `struct PeerAddress` |
355 | */ | 346 | */ |
356 | static void | 347 | static void |
357 | mq_send_d (struct GNUNET_MQ_Handle *mq, | 348 | mq_send_d (struct GNUNET_MQ_Handle *mq, |
358 | const struct GNUNET_MessageHeader *msg, | 349 | const struct GNUNET_MessageHeader *msg, |
359 | void *impl_state) | 350 | void *impl_state) |
360 | { | 351 | { |
361 | struct ReceiverAddress *receiver = impl_state; | 352 | struct PeerAddress *peer = impl_state; |
362 | uint16_t msize = ntohs (msg->size); | 353 | uint16_t msize = ntohs (msg->size); |
363 | 354 | ||
364 | GNUNET_assert (mq == receiver->d_mq); | 355 | GNUNET_assert (mq == peer->d_mq); |
365 | if (msize > receiver->d_mtu) | 356 | if (msize > peer->d_mtu) |
366 | { | 357 | { |
367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 358 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
368 | "msize: %u, mtu: %lu\n", | 359 | "msize: %u, mtu: %lu\n", |
369 | msize, | 360 | msize, |
370 | receiver->d_mtu); | 361 | peer->d_mtu); |
371 | GNUNET_break (0); | 362 | GNUNET_break (0); |
372 | if (GNUNET_YES != receiver->receiver_destroy_called) | 363 | if (GNUNET_YES != peer->peer_destroy_called) |
373 | receiver_destroy (receiver); | 364 | peer_destroy (peer); |
374 | return; | 365 | return; |
375 | } | 366 | } |
376 | reschedule_receiver_timeout (receiver); | 367 | reschedule_peer_timeout (peer); |
377 | // if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, | 368 | // if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, |
378 | // dgram, | 369 | // dgram, |
379 | // sizeof(dgram), | 370 | // sizeof(dgram), |
380 | // receiver->address, | 371 | // peer->address, |
381 | // receiver->address_len)) | 372 | // peer->address_len)) |
382 | // GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); | 373 | // GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); |
383 | // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 374 | // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
384 | // "Sending UDPBox with payload size %u, %u acks left\n", | 375 | // "Sending UDPBox with payload size %u, %u acks left\n", |
385 | // msize, | 376 | // msize, |
386 | // receiver->acks_available); | 377 | // peer->acks_available); |
387 | // GNUNET_MQ_impl_send_continue (mq); | 378 | // GNUNET_MQ_impl_send_continue (mq); |
388 | // return; | 379 | // return; |
389 | } | 380 | } |
@@ -525,18 +516,18 @@ udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len) | |||
525 | 516 | ||
526 | 517 | ||
527 | /** | 518 | /** |
528 | * Setup the MQ for the @a receiver. If a queue exists, | 519 | * Setup the MQ for the @a peer. If a queue exists, |
529 | * the existing one is destroyed. Then the MTU is | 520 | * the existing one is destroyed. Then the MTU is |
530 | * recalculated and a fresh queue is initialized. | 521 | * recalculated and a fresh queue is initialized. |
531 | * | 522 | * |
532 | * @param receiver receiver to setup MQ for | 523 | * @param peer peer to setup MQ for |
533 | */ | 524 | */ |
534 | static void | 525 | static void |
535 | setup_receiver_mq (struct ReceiverAddress *receiver) | 526 | setup_peer_mq (struct PeerAddress *peer) |
536 | { | 527 | { |
537 | size_t base_mtu; | 528 | size_t base_mtu; |
538 | 529 | ||
539 | switch (receiver->address->sa_family) | 530 | switch (peer->address->sa_family) |
540 | { | 531 | { |
541 | case AF_INET: | 532 | case AF_INET: |
542 | base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ | 533 | base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ |
@@ -555,30 +546,31 @@ setup_receiver_mq (struct ReceiverAddress *receiver) | |||
555 | break; | 546 | break; |
556 | } | 547 | } |
557 | /* MTU == base_mtu */ | 548 | /* MTU == base_mtu */ |
558 | receiver->d_mtu = base_mtu; | 549 | peer->d_mtu = base_mtu; |
559 | 550 | ||
560 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 551 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
561 | "Setting up MQs and QHs\n"); | 552 | "Setting up MQs and QHs\n"); |
562 | /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to | 553 | /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to |
563 | 1404 (IPv4 + Box) bytes, depending on circumstances... */ | 554 | 1404 (IPv4 + Box) bytes, depending on circumstances... */ |
564 | if (NULL == receiver->d_mq) | 555 | |
565 | receiver->d_mq = GNUNET_MQ_queue_for_callbacks (&mq_send_d, | 556 | if (NULL == peer->d_mq) |
566 | &mq_destroy_d, | 557 | peer->d_mq = GNUNET_MQ_queue_for_callbacks (&mq_send_d, |
567 | &mq_cancel, | 558 | &mq_destroy_d, |
568 | receiver, | 559 | &mq_cancel, |
569 | NULL, | 560 | receiver, |
570 | &mq_error, | 561 | NULL, |
571 | receiver); | 562 | &mq_error, |
572 | receiver->d_qh = | 563 | receiver); |
564 | peer->d_qh = | ||
573 | GNUNET_TRANSPORT_communicator_mq_add (ch, | 565 | GNUNET_TRANSPORT_communicator_mq_add (ch, |
574 | &receiver->target, | 566 | &peer->target, |
575 | receiver->foreign_addr, | 567 | peer->foreign_addr, |
576 | receiver->d_mtu, | 568 | peer->d_mtu, |
577 | GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, | 569 | GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, |
578 | 0, /* Priority */ | 570 | 0, /* Priority */ |
579 | receiver->nt, | 571 | peer->nt, |
580 | GNUNET_TRANSPORT_CS_OUTBOUND, | 572 | GNUNET_TRANSPORT_CS_OUTBOUND, |
581 | receiver->d_mq); | 573 | peer->d_mq); |
582 | } | 574 | } |
583 | 575 | ||
584 | 576 | ||
@@ -681,12 +673,32 @@ check_timeouts (void *cls) | |||
681 | * invalid | 673 | * invalid |
682 | */ | 674 | */ |
683 | static int | 675 | static int |
684 | mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | 676 | mq_init (void *cls, const struct GNUNET_PeerIdentity *peer_id, const |
677 | char *address) | ||
685 | { | 678 | { |
686 | struct ReceiverAddress *receiver; | 679 | struct PeerAddress *peer; |
687 | const char *path; | 680 | const char *path; |
688 | struct sockaddr *in; | 681 | struct sockaddr *in; |
689 | socklen_t in_len; | 682 | socklen_t in_len; |
683 | uint8_t scid[LOCAL_CONN_ID_LEN]; | ||
684 | |||
685 | struct quic_conn *conn; | ||
686 | char *bindto; | ||
687 | socklen_t in_len; | ||
688 | struct sockaddr *local_addr; | ||
689 | |||
690 | if (GNUNET_OK != | ||
691 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
692 | COMMUNICATOR_CONFIG_SECTION, | ||
693 | "BINDTO", | ||
694 | &bindto)) | ||
695 | { | ||
696 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
697 | COMMUNICATOR_CONFIG_SECTION, | ||
698 | "BINDTO"); | ||
699 | return; | ||
700 | } | ||
701 | local_addr = udp_address_to_sockaddr (bindto, &in_len); | ||
690 | 702 | ||
691 | if (0 != strncmp (address, | 703 | if (0 != strncmp (address, |
692 | COMMUNICATOR_ADDRESS_PREFIX "-", | 704 | COMMUNICATOR_ADDRESS_PREFIX "-", |
@@ -698,31 +710,51 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) | |||
698 | path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; | 710 | path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; |
699 | in = udp_address_to_sockaddr (path, &in_len); | 711 | in = udp_address_to_sockaddr (path, &in_len); |
700 | 712 | ||
701 | receiver = GNUNET_new (struct ReceiverAddress); | 713 | peer = GNUNET_new (struct PeerAddress); |
702 | receiver->address = in; | 714 | peer->address = in; |
703 | receiver->address_len = in_len; | 715 | peer->address_len = in_len; |
704 | receiver->target = *peer; | 716 | peer->target = *peer_id; |
705 | receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len); | 717 | peer->nt = GNUNET_NT_scanner_get_type (is, in, in_len); |
706 | (void) GNUNET_CONTAINER_multipeermap_put ( | 718 | (void) GNUNET_CONTAINER_multipeermap_put ( |
707 | receivers, | 719 | peers, |
708 | &receiver->target, | 720 | &peer->target, |
709 | receiver, | 721 | peer, |
710 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 722 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
711 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
712 | "Added %s to receivers\n", | 724 | "Added %s to peers\n", |
713 | GNUNET_i2s_full (&receiver->target)); | 725 | GNUNET_i2s_full (&peer->target)); |
714 | receiver->timeout = | 726 | peer->timeout = |
715 | GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 727 | GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
716 | receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap, | 728 | peer->hn = GNUNET_CONTAINER_heap_insert (peers_heap, |
717 | receiver, | 729 | peer, |
718 | receiver->timeout.abs_value_us); | 730 | peer->timeout.abs_value_us); |
719 | GNUNET_STATISTICS_set (stats, | 731 | GNUNET_STATISTICS_set (stats, |
720 | "# receivers active", | 732 | "# peers active", |
721 | GNUNET_CONTAINER_multipeermap_size (receivers), | 733 | GNUNET_CONTAINER_multipeermap_size (peers), |
722 | GNUNET_NO); | 734 | GNUNET_NO); |
723 | receiver->foreign_addr = | 735 | peer->foreign_addr = |
724 | sockaddr_to_udpaddr_string (receiver->address, receiver->address_len); | 736 | sockaddr_to_udpaddr_string (peer->address, peer->address_len); |
725 | setup_receiver_mq (receiver); | 737 | /** |
738 | * Before setting up peer mq, initiate a quic connection to the target (perform handshake w/ quiche) | ||
739 | */ | ||
740 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, scid, | ||
741 | LOCAL_CONN_ID_LEN); | ||
742 | conn = GNUNET_new (struct quic_conn); | ||
743 | GNUNET_memcpy (conn->cid, scid, LOCAL_CONN_ID_LEN); | ||
744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
745 | "Attempting to perform handshake with peer\n"); | ||
746 | conn->conn = quiche_connect (peer->foreign_addr, scid, LOCAL_CONN_ID_LEN, | ||
747 | local_addr, | ||
748 | in_len, peer->address, peer->address_len, | ||
749 | config); | ||
750 | /** | ||
751 | * Insert connection into hashmap | ||
752 | */ | ||
753 | struct GNUNET_HashCode key; | ||
754 | GNUNET_CRYPTO_hash (conn->cid, LOCAL_CONN_ID_LEN, &key); | ||
755 | GNUNET_CONTAINER_multihashmap_put (conn_map, &key, conn, | ||
756 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
757 | setup_peer_mq (peer); | ||
726 | if (NULL == timeout_task) | 758 | if (NULL == timeout_task) |
727 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL); | 759 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL); |
728 | return GNUNET_OK; | 760 | return GNUNET_OK; |
@@ -911,7 +943,6 @@ sock_read (void *cls) | |||
911 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
912 | "quiche failed to write retry packet\n"); | 944 | "quiche failed to write retry packet\n"); |
913 | } | 945 | } |
914 | |||
915 | ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock, | 946 | ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock, |
916 | out, | 947 | out, |
917 | written, | 948 | written, |
@@ -932,7 +963,6 @@ sock_read (void *cls) | |||
932 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 963 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
933 | "invalid address validation token created\n"); | 964 | "invalid address validation token created\n"); |
934 | } | 965 | } |
935 | |||
936 | conn = create_conn (quic_header.dcid, quic_header.dcid_len, | 966 | conn = create_conn (quic_header.dcid, quic_header.dcid_len, |
937 | quic_header.odcid, quic_header.odcid_len, | 967 | quic_header.odcid, quic_header.odcid_len, |
938 | local_addr, in_len, | 968 | local_addr, in_len, |
@@ -942,7 +972,6 @@ sock_read (void *cls) | |||
942 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 972 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
943 | "failed to create quic connection with peer\n"); | 973 | "failed to create quic connection with peer\n"); |
944 | } | 974 | } |
945 | |||
946 | } // null connection | 975 | } // null connection |
947 | 976 | ||
948 | quiche_recv_info recv_info = { | 977 | quiche_recv_info recv_info = { |
@@ -952,9 +981,7 @@ sock_read (void *cls) | |||
952 | local_addr, | 981 | local_addr, |
953 | in_len, | 982 | in_len, |
954 | }; | 983 | }; |
955 | |||
956 | process_pkt = quiche_conn_recv (conn->conn, buf, rcvd, &recv_info); | 984 | process_pkt = quiche_conn_recv (conn->conn, buf, rcvd, &recv_info); |
957 | |||
958 | if (0 > process_pkt) | 985 | if (0 > process_pkt) |
959 | { | 986 | { |
960 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 987 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -962,10 +989,8 @@ sock_read (void *cls) | |||
962 | process_pkt); | 989 | process_pkt); |
963 | return; | 990 | return; |
964 | } | 991 | } |
965 | |||
966 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 992 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
967 | "quiche processed %zd bytes\n", process_pkt); | 993 | "quiche processed %zd bytes\n", process_pkt); |
968 | |||
969 | /** | 994 | /** |
970 | * Check for connection establishment | 995 | * Check for connection establishment |
971 | */ | 996 | */ |