Home | History | Annotate | Line # | Download | only in ServiceRegistration
      1 /* nat64-macos.h
      2  *
      3  * Copyright (c) 2022-2023 Apple Inc. All rights reserved.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     https://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #ifndef NAT64_H
     19 #define NAT64_H
     20 
     21 #include "srp.h"
     22 #include "dns-msg.h"
     23 #include "srp-crypto.h"
     24 #include "ioloop.h"
     25 #include "dnssd-proxy.h"
     26 #include "srp-gw.h"
     27 #include "srp-proxy.h"
     28 #include "srp-mdns-proxy.h"
     29 #include "config-parse.h"
     30 #include "cti-services.h"
     31 #include "route.h"
     32 #define DNSMessageHeader dns_wire_t
     33 #include "ioloop-common.h" // for service_connection_t
     34 
     35 #define NAT64_PREFIX_LLQ_QUERY_DOMAIN        "ipv4only.arpa"
     36 #define NAT64_PREFIX_SLASH_96_BYTES          12                // Thread spec limit NAT64 prefix to /96
     37 #define NAT64_THREAD_PREFIX_SETTLING_TIME    10                // In seconds
     38 #define NAT64_BR_PREFIX_PUBLISHER_WAIT_TIME  30                // In seconds
     39 #define NAT64_INFRA_PREFIX_LIMIT             3                 // Max number of allowed nat64 prefixes from infra on thread network
     40 
     41 
     42 // Refer to https://www.rfc-editor.org/rfc/rfc4191
     43 typedef enum {
     44     nat64_preference_medium     = 0,
     45     nat64_preference_high       = 1,
     46     nat64_preference_low        = 3,
     47     nat64_preference_reserved   = 2,
     48 } nat64_preference;
     49 
     50 typedef enum {
     51     nat64_prefix_action_none      = 0,
     52     nat64_prefix_action_add       = 1,
     53     nat64_prefix_action_remove    = 2,
     54 } nat64_prefix_action;
     55 
     56 typedef struct nat64_prefix nat64_prefix_t;
     57 typedef struct nat64 nat64_t;
     58 
     59 struct nat64_prefix {
     60     uint32_t ref_count;
     61     nat64_prefix_t *NULLABLE next;
     62     struct in6_addr prefix;
     63     int prefix_len;
     64     nat64_preference priority;
     65     nat64_prefix_action action;
     66     int rloc;
     67     bool pending;
     68 };
     69 
     70 // ipv4 default route monitor
     71 typedef enum nat64_ipv4_default_route_monitor_event_type {
     72     nat64_event_ipv4_default_route_invalid = 0,
     73     nat64_event_ipv4_default_route_update,
     74     nat64_event_ipv4_default_route_showed_up,
     75     nat64_event_ipv4_default_route_went_away,
     76 } nat64_ipv4_default_route_monitor_event_type_t;
     77 
     78 typedef enum {
     79     nat64_ipv4_default_route_monitor_state_invalid = 0,
     80     nat64_ipv4_default_route_monitor_state_init,
     81     nat64_ipv4_default_route_monitor_state_wait_for_event,
     82 } nat64_ipv4_default_route_monitor_state_type_t;
     83 
     84 typedef struct nat64_ipv4_default_route_monitor_event {
     85     char *NONNULL name;
     86     union {
     87         bool has_ipv4_connectivity;
     88         bool has_ipv4_default_route;
     89     };
     90     nat64_ipv4_default_route_monitor_event_type_t event_type;
     91 } nat64_ipv4_default_route_monitor_event_t;
     92 
     93 typedef struct {
     94     uint32_t ref_count;
     95     nat64_ipv4_default_route_monitor_state_type_t state;
     96     bool has_ipv4_default_route;
     97     char *NONNULL state_name;
     98     nat64_t *NONNULL nat64;
     99 } nat64_ipv4_default_route_monitor_t;
    100 
    101 // Infrastructure prefix monitor
    102 typedef enum nat64_infra_prefix_monitor_event_type {
    103     nat64_event_infra_prefix_invalid = 0,
    104     nat64_event_infra_prefix_update,
    105 } nat64_infra_prefix_monitor_event_type_t;
    106 
    107 typedef struct nat64_infra_prefix_monitor_event {
    108     char *NONNULL name;
    109     DNSServiceFlags flags;
    110     union {
    111         const void *NULLABLE rdata;
    112         nat64_prefix_t *NULLABLE prefix;
    113     };
    114     nat64_infra_prefix_monitor_event_type_t event_type;
    115 } nat64_infra_prefix_monitor_event_t;
    116 
    117 typedef enum {
    118     nat64_infra_prefix_monitor_state_invalid = 0,
    119     nat64_infra_prefix_monitor_state_init,
    120     nat64_infra_prefix_monitor_state_wait_for_change,
    121     nat64_infra_prefix_monitor_state_change_occurred,
    122 } nat64_infra_prefix_monitor_state_type_t;
    123 
    124 typedef struct {
    125     uint32_t ref_count;
    126     nat64_infra_prefix_monitor_state_type_t state;
    127     char *NONNULL state_name;
    128     DNSServiceRef NULLABLE sdRef;    // LLQ sdRef
    129     nat64_prefix_t *NULLABLE infra_nat64_prefixes;
    130     nat64_t *NONNULL nat64;
    131     bool canceled;
    132 } nat64_infra_prefix_monitor_t;
    133 
    134 
    135 // Thread prefix monitor
    136 typedef enum nat64_thread_prefix_monitor_event_type {
    137     nat64_event_thread_prefix_invalid = 0,
    138     nat64_event_thread_prefix_init_wait_ended,
    139     nat64_event_thread_prefix_update,
    140 } nat64_thread_prefix_monitor_event_type_t;
    141 
    142 typedef struct nat64_thread_prefix_monitor_event {
    143     char *NONNULL name;
    144     union {
    145         nat64_prefix_t *NULLABLE prefix;
    146         cti_route_vec_t *NULLABLE routes;
    147     };
    148     nat64_thread_prefix_monitor_event_type_t event_type;
    149 } nat64_thread_prefix_monitor_event_t;
    150 
    151 typedef enum {
    152     nat64_thread_prefix_monitor_state_invalid = 0,
    153     nat64_thread_prefix_monitor_state_init,
    154     nat64_thread_prefix_monitor_state_wait_for_settling,
    155     nat64_thread_prefix_monitor_state_wait_for_change,
    156     nat64_thread_prefix_monitor_state_change_occurred,
    157 } nat64_thread_prefix_monitor_state_type_t;
    158 
    159 typedef struct {
    160     uint32_t ref_count;
    161     nat64_thread_prefix_monitor_state_type_t state;
    162     char *NONNULL state_name;
    163     nat64_prefix_t *NULLABLE thread_nat64_prefixes;
    164     wakeup_t *NULLABLE timer;
    165     nat64_t *NONNULL nat64;
    166 } nat64_thread_prefix_monitor_t;
    167 
    168 // Infra nat64 prefix publisher
    169 typedef enum nat64_infra_prefix_publisher_event_type {
    170     nat64_event_nat64_infra_prefix_publisher_invalid = 0,
    171     nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed,
    172     nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed,
    173     nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_went_away,
    174     nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_showed_up,
    175     nat64_event_nat64_infra_prefix_publisher_shutdown,
    176 } nat64_infra_prefix_publisher_event_type_t;
    177 
    178 typedef struct nat64_infra_prefix_publisher_event {
    179     char *NONNULL name;
    180     nat64_prefix_t *NULLABLE prefix;
    181     nat64_infra_prefix_publisher_event_type_t event_type;
    182 } nat64_infra_prefix_publisher_event_t;
    183 
    184 typedef enum {
    185     nat64_infra_prefix_publisher_state_invalid = 0,
    186     nat64_infra_prefix_publisher_state_init,
    187     nat64_infra_prefix_publisher_state_wait,        // Wait for infra prefix
    188     nat64_infra_prefix_publisher_state_ignore,      // Ignore infra prefix
    189     nat64_infra_prefix_publisher_state_check,       // Check infra prefix
    190     nat64_infra_prefix_publisher_state_publish,     // Publish infra prefix
    191     nat64_infra_prefix_publisher_state_publishing,  // Publishing infra prefix
    192 } nat64_infra_prefix_publisher_state_type_t;
    193 
    194 typedef struct {
    195     uint32_t ref_count;
    196     nat64_infra_prefix_publisher_state_type_t state;
    197     char *NONNULL state_name;
    198     bool routable_omr_prefix_present;
    199     nat64_prefix_t *NULLABLE proposed_prefix;
    200     nat64_t *NONNULL nat64;
    201 } nat64_infra_prefix_publisher_t;
    202 
    203 // BR nat64 prefix publisher
    204 typedef enum nat64_br_prefix_publisher_event_type {
    205     nat64_event_nat64_br_prefix_publisher_invalid = 0,
    206     nat64_event_nat64_br_prefix_publisher_okay_to_publish,
    207     nat64_event_nat64_br_prefix_publisher_ipv4_default_route_showed_up,
    208     nat64_event_nat64_br_prefix_publisher_ipv4_default_route_went_away,
    209     nat64_event_nat64_br_prefix_publisher_thread_prefix_changed,
    210     nat64_event_nat64_br_prefix_publisher_infra_prefix_changed,
    211     nat64_event_nat64_br_prefix_publisher_shutdown,
    212 } nat64_br_prefix_publisher_event_type_t;
    213 
    214 typedef struct nat64_br_prefix_publisher_event {
    215     char *NONNULL name;
    216     nat64_prefix_t *NULLABLE prefix;
    217     nat64_br_prefix_publisher_event_type_t event_type;
    218 } nat64_br_prefix_publisher_event_t;
    219 
    220 typedef enum {
    221     nat64_br_prefix_publisher_state_invalid = 0,
    222     nat64_br_prefix_publisher_state_init,
    223     nat64_br_prefix_publisher_state_start_timer,
    224     nat64_br_prefix_publisher_state_wait_for_anything,
    225     nat64_br_prefix_publisher_state_publish,
    226     nat64_br_prefix_publisher_state_publishing,
    227 } nat64_br_prefix_publisher_state_type_t;
    228 
    229 typedef struct {
    230     uint32_t ref_count;
    231     nat64_br_prefix_publisher_state_type_t state;
    232     char *NONNULL state_name;
    233     nat64_prefix_t *NULLABLE br_prefix;
    234     wakeup_t *NULLABLE timer;
    235     bool wait_finished;
    236     nat64_t *NONNULL nat64;
    237 } nat64_br_prefix_publisher_t;
    238 
    239 struct nat64 {
    240     uint32_t ref_count;
    241     route_state_t *NONNULL route_state;
    242     nat64_prefix_t *NULLABLE update_queue;
    243 
    244     // State machines
    245     nat64_ipv4_default_route_monitor_t *NULLABLE ipv4_monitor;
    246     nat64_infra_prefix_monitor_t *NULLABLE infra_monitor;
    247     nat64_thread_prefix_monitor_t *NULLABLE thread_monitor;
    248     nat64_infra_prefix_publisher_t *NULLABLE nat64_infra_prefix_publisher;
    249     nat64_br_prefix_publisher_t *NULLABLE nat64_br_prefix_publisher;
    250 };
    251 
    252 
    253 nat64_t *NULLABLE nat64_create(route_state_t *NONNULL route_state);
    254 nat64_prefix_t *NULLABLE nat64_prefix_create(struct in6_addr *NONNULL address, int prefix_length,
    255                                              nat64_preference pref, int rloc);
    256 void nat64_add_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL const data,
    257                       offmesh_route_preference_t route_pref);
    258 void nat64_remove_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL const data);
    259 void nat64_offmesh_route_list_callback(route_state_t *NONNULL route_state, cti_route_vec_t *NONNULL routes,
    260                                        cti_status_t status);
    261 void nat64_init(route_state_t *NONNULL route_state);
    262 void nat64_default_route_update(nat64_t *NONNULL nat64, bool has_ipv4_connectivity);
    263 void nat64_omr_route_update(nat64_t *NONNULL nat64, bool has_routable_omr_prefix);
    264 void nat64_stop(route_state_t *NONNULL route_state);
    265 void nat64_start(route_state_t *NONNULL route_state);
    266 void nat64_thread_shutdown(route_state_t *NONNULL route_state);
    267 #endif /* NAT64_H */
    268 
    269 // Local Variables:
    270 // mode: C
    271 // tab-width: 4
    272 // c-file-style: "bsd"
    273 // c-basic-offset: 4
    274 // fill-column: 120
    275 // indent-tabs-mode: nil
    276 // End:
    277