LCOV - code coverage report
Current view: top level - home/net-next/net/quic - connid.h (source / functions) Hit Total Coverage
Test: quic.info Lines: 43 43 100.0 %
Date: 2025-07-04 13:24:45 Functions: 3 3 100.0 %

          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);

Generated by: LCOV version 1.14