Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 : /* QUIC kernel implementation 3 : * (C) Copyright Red Hat Corp. 2023 4 : * 5 : * This file is part of the QUIC kernel implementation 6 : * 7 : * Written or modified by: 8 : * Xin Long <lucien.xin@gmail.com> 9 : */ 10 : 11 : #define QUIC_CONN_ID_LIMIT 8 12 : #define QUIC_CONN_ID_DEF 7 13 : #define QUIC_CONN_ID_LEAST 2 14 : 15 : #define QUIC_CONN_ID_TOKEN_LEN 16 16 : 17 : /* Common fields shared by both source and destination Connection IDs */ 18 : struct quic_common_conn_id { 19 : struct quic_conn_id id; /* The actual Connection ID value and its length */ 20 : struct list_head list; /* Linked list node for conn_id list management */ 21 : u32 number; /* Sequence number assigned to this Connection ID */ 22 : u8 hashed; /* Non-zero if this ID is stored in source_conn_id hashtable */ 23 : }; 24 : 25 : struct quic_source_conn_id { 26 : struct quic_common_conn_id common; 27 : struct hlist_node node; /* Hash table node for fast lookup by Connection ID */ 28 : struct rcu_head rcu; /* RCU header for deferred destruction */ 29 : struct sock *sk; /* Pointer to sk associated with this Connection ID */ 30 : }; 31 : 32 : struct quic_dest_conn_id { 33 : struct quic_common_conn_id common; 34 : u8 token[QUIC_CONN_ID_TOKEN_LEN]; /* Stateless reset token in rfc9000#section-10.3 */ 35 : }; 36 : 37 : struct quic_conn_id_set { 38 : /* Connection ID in use on the current path */ 39 : struct quic_common_conn_id *active; 40 : /* Connection ID to use for a new path (e.g., after migration) */ 41 : struct quic_common_conn_id *alt; 42 : struct list_head head; /* Head of the linked list of available connection IDs */ 43 : u8 entry_size; /* Size of each connection ID entry (in bytes) in the list */ 44 : u8 max_count; /* active_connection_id_limit in rfc9000#section-18.2 */ 45 : u8 count; /* Current number of connection IDs in the list */ 46 : }; 47 : 48 25958 : static inline u32 quic_conn_id_first_number(struct quic_conn_id_set *id_set) 49 : { 50 25958 : struct quic_common_conn_id *common; 51 : 52 25959 : common = list_first_entry(&id_set->head, struct quic_common_conn_id, list); 53 18831 : return common->number; 54 : } 55 : 56 20188 : static inline u32 quic_conn_id_last_number(struct quic_conn_id_set *id_set) 57 : { 58 20144 : return quic_conn_id_first_number(id_set) + id_set->count - 1; 59 : } 60 : 61 7693 : static inline void quic_conn_id_generate(struct quic_conn_id *conn_id) 62 : { 63 7693 : get_random_bytes(conn_id->data, QUIC_CONN_ID_DEF_LEN); 64 7693 : conn_id->len = QUIC_CONN_ID_DEF_LEN; 65 : } 66 : 67 : /* Select an alternate destination Connection ID for a new path (e.g., after migration). */ 68 358 : static inline bool quic_conn_id_select_alt(struct quic_conn_id_set *id_set, bool active) 69 : { 70 358 : if (id_set->alt) 71 : return true; 72 : /* NAT rebinding: peer keeps using the current source conn_id. 73 : * In this case, continue using the same dest conn_id for the new path. 74 : */ 75 99 : if (active) { 76 12 : id_set->alt = id_set->active; 77 12 : return true; 78 : } 79 : /* Treat the prev conn_ids as used. 80 : * Try selecting the next conn_id in the list, unless at the end. 81 : */ 82 87 : if (id_set->active->number != quic_conn_id_last_number(id_set)) { 83 86 : id_set->alt = list_next_entry(id_set->active, list); 84 86 : return true; 85 : } 86 : /* If there's only one conn_id in the list, reuse the active one. */ 87 1 : if (id_set->active->number == quic_conn_id_first_number(id_set)) { 88 1 : id_set->alt = id_set->active; 89 1 : return true; 90 : } 91 : /* No alternate conn_id could be selected. Caller should send a 92 : * QUIC_FRAME_RETIRE_CONNECTION_ID frame to request new connection IDs from the peer. 93 : */ 94 : return false; 95 : } 96 : 97 81 : static inline void quic_conn_id_set_alt(struct quic_conn_id_set *id_set, struct quic_conn_id *alt) 98 : { 99 81 : id_set->alt = (struct quic_common_conn_id *)alt; 100 : } 101 : 102 : /* Swap the active and alternate destination Connection IDs after path migration completes, 103 : * since the path has already been switched accordingly. 104 : */ 105 97 : static inline void quic_conn_id_swap_active(struct quic_conn_id_set *id_set) 106 : { 107 97 : void *active = id_set->active; 108 : 109 97 : id_set->active = id_set->alt; 110 97 : id_set->alt = active; 111 97 : } 112 : 113 : /* Choose which destination Connection ID to use for a new path migration if alt is true. */ 114 17563103 : static inline struct quic_conn_id *quic_conn_id_choose(struct quic_conn_id_set *id_set, u8 alt) 115 : { 116 17563103 : return (alt && id_set->alt) ? &id_set->alt->id : &id_set->active->id; 117 : } 118 : 119 24166 : static inline struct quic_conn_id *quic_conn_id_active(struct quic_conn_id_set *id_set) 120 : { 121 24166 : return &id_set->active->id; 122 : } 123 : 124 104 : static inline void quic_conn_id_set_active(struct quic_conn_id_set *id_set, 125 : struct quic_conn_id *active) 126 : { 127 84 : id_set->active = (struct quic_common_conn_id *)active; 128 88 : } 129 : 130 6573480 : static inline u32 quic_conn_id_number(struct quic_conn_id *conn_id) 131 : { 132 6573480 : return ((struct quic_common_conn_id *)conn_id)->number; 133 : } 134 : 135 6573105 : static inline struct sock *quic_conn_id_sk(struct quic_conn_id *conn_id) 136 : { 137 6573105 : return ((struct quic_source_conn_id *)conn_id)->sk; 138 : } 139 : 140 272 : static inline void quic_conn_id_set_token(struct quic_conn_id *conn_id, u8 *token) 141 : { 142 544 : memcpy(((struct quic_dest_conn_id *)conn_id)->token, token, QUIC_CONN_ID_TOKEN_LEN); 143 272 : } 144 : 145 2466 : static inline int quic_conn_id_cmp(struct quic_conn_id *a, struct quic_conn_id *b) 146 : { 147 4809 : return a->len != b->len || memcmp(a->data, b->data, a->len); 148 : } 149 : 150 : int quic_conn_id_add(struct quic_conn_id_set *id_set, struct quic_conn_id *conn_id, 151 : u32 number, void *data); 152 : bool quic_conn_id_token_exists(struct quic_conn_id_set *id_set, u8 *token); 153 : void quic_conn_id_remove(struct quic_conn_id_set *id_set, u32 number); 154 : 155 : struct quic_conn_id *quic_conn_id_find(struct quic_conn_id_set *id_set, u32 number); 156 : struct quic_conn_id *quic_conn_id_lookup(struct net *net, u8 *scid, u32 len); 157 : void quic_conn_id_update_active(struct quic_conn_id_set *id_set, u32 number); 158 : 159 : void quic_conn_id_get_param(struct quic_conn_id_set *id_set, struct quic_transport_param *p); 160 : void quic_conn_id_set_param(struct quic_conn_id_set *id_set, struct quic_transport_param *p); 161 : void quic_conn_id_set_init(struct quic_conn_id_set *id_set, bool source); 162 : void quic_conn_id_set_free(struct quic_conn_id_set *id_set);