17typedef enum : uint8_t {
23typedef enum : uint16_t {
41typedef enum : uint8_t {
50typedef enum : uint16_t {
82 while (prefix[i] !=
'\0') {
87 const char la = (char)(((a >=
'A') && (a <=
'Z')) ? (a + (
'a' -
'A')) : a);
88 if (la != prefix[i]) {
98 if ((url ==
nullptr) || (url[0] ==
'\0')) {
124 const unsigned o0 = o[
k_v4_o0];
125 const unsigned o1 = o[
k_v4_o1];
188 for (
size_t i = 0U; i < (size_t)
k_v6_last; ++i) {
239 unsigned char v4[
sizeof(
struct in_addr)] = {};
240 if (inet_pton(AF_INET, ip, v4) == 1) {
243 unsigned char v6[
sizeof(
struct in6_addr)] = {};
244 if (inet_pton(AF_INET6, ip, v6) == 1) {
258 return allow_private;
269 return add > (cap - have);
274 if ((out ==
nullptr) || (cap == 0U)) {
278 if (url ==
nullptr) {
281 const char* sep =
strstr(url,
"://");
282 if (sep ==
nullptr) {
285 const char* host = sep + (
sizeof(
"://") - 1U);
286 const char* at =
strchr(host,
'@');
287 const char* path = strpbrk(host,
"/?#");
289 const bool at_in_authority = (path ==
nullptr) || (at < path);
290 if (at_in_authority) {
298 while ((host[n] !=
'\0') && (host[n] !=
'/') && (host[n] !=
'?') && (host[n] !=
'#')) {
299 if ((n + 1U) >= cap) {
303 const char c = host[n];
304 out[n] = (char)(((c >=
'A') && (c <=
'Z')) ? (c + (
'a' -
'A')) : c);
313 if ((out ==
nullptr) || (cap == 0U)) {
317 if (url ==
nullptr) {
320 const char* sep =
strstr(url,
"://");
321 if (sep ==
nullptr) {
324 const char* host = sep + (
sizeof(
"://") - 1U);
325 const char* path =
strchr(host,
'/');
326 if (path ==
nullptr) {
335 while ((path[n] !=
'\0') && (path[n] !=
'?') && (path[n] !=
'#')) {
336 if ((n + 1U) >= cap) {
static mdl_addr_class_t internal_classify_v6(const unsigned char *b)
Classify the sixteen bytes of an IPv6 address.
bool mdl_url_host(const char *url, char *out, size_t cap)
Extract the authority (host and optional port) from an http(s) URL.
bool mdl_url_scheme_allowed(const char *url)
True when url uses an allowlisted scheme (http:// or https://).
bool mdl_addr_is_fetchable(mdl_addr_class_t cls, bool allow_private)
Decide whether an address class is fetchable under the active policy.
mdl_v4_range_t
IPv4 range boundaries that mark non-public address space.
@ k_v4_linklocal
169.254.0.0/16 first octet.
@ k_v4_private_c
192.168.0.0/16 first octet.
@ k_v4_private_a
10.0.0.0/8.
@ k_v4_private_c_2
192.168 second octet.
@ k_v4_linklocal_2
169.254 second octet.
@ k_v4_private_b
172.16.0.0/12 first octet.
@ k_v4_private_b_lo
172.16 low second octet (inclusive).
@ k_v4_cgnat_lo
100.64 low second octet (inclusive).
@ k_v4_multicast_min
224.0.0.0/4 and up: multicast/reserved.
@ k_v4_private_b_hi
172.31 high second octet (inclusive).
@ k_v4_cgnat_hi
100.127 high second octet (inclusive).
@ k_v4_zero_net
0.0.0.0/8 "this network" (unspecified).
@ k_v4_cgnat
100.64.0.0/10 (RFC6598) first octet.
@ k_v4_loopback_net
127.0.0.0/8 loopback.
static mdl_addr_class_t internal_classify_v4(const unsigned char *o)
Classify the four octets of an IPv4 address.
mdl_v4_index_t
IPv4 address byte layout used while classifying.
@ k_v4_o0
First octet index.
@ k_v4_o1
Second octet index.
static const char *const s_scheme_https
static const char *const s_scheme_http
Scheme prefixes accepted by mdl_url_scheme_allowed.
bool mdl_size_exceeds(uint64_t have, uint64_t add, uint64_t cap)
True when appending add bytes to have would exceed cap.
static bool internal_is_v4_mapped(const unsigned char *b)
True if the 16 IPv6 bytes carry an IPv4-mapped ffff:a.b.c.d.
mdl_addr_class_t mdl_classify_ip(const char *ip)
Classify a resolved peer IP string into a mdl_addr_class_t.
mdl_v6_index_t
IPv6 address byte layout and the bytes classification inspects.
@ k_v6_mapped_v4
Offset of the embedded IPv4 address.
@ k_v6_mapped_ff_b
Second 0xFF byte of the mapped prefix.
@ k_v6_mapped_ff_a
First 0xFF byte of an IPv4-mapped prefix.
@ k_v6_bytes
Total bytes in an IPv6 address.
@ k_v6_last
Index of the final byte (for ::1).
static bool internal_is_v6_loopback(const unsigned char *b)
True if the 16 IPv6 bytes are the loopback address ::1.
static bool internal_starts_with_ci(const char *s, const char *prefix)
Case-insensitive test that s begins with prefix.
bool mdl_url_path(const char *url, char *out, size_t cap)
Extract the path (with leading /, without query/fragment) from a URL.
mdl_v6_prefix_t
IPv6 prefix byte values that mark non-public address space.
@ k_v6_ula_mask
Mask isolating the fc00::/7 prefix.
@ k_v6_ll_value
fe80::/10 masked value.
@ k_v6_ll_lead
fe80::/10 lead byte.
@ k_v6_ll_mask
Mask isolating the /10 boundary.
@ k_v6_loopback_last
Final byte of ::1.
@ k_v6_ula_value
fc00::/7 unique-local value.
@ k_v6_byte_ff
Multicast lead byte / mapped filler.
Pure URL / address safety predicates for the libcurl backend.
mdl_addr_class_t
Reachability class of a resolved peer address.
@ k_mdl_addr_public
Routable public unicast address.
@ k_mdl_addr_unknown
Unparseable, unspecified, or reserved.
@ k_mdl_addr_loopback
127.0.0.0/8 or ::1.
@ k_mdl_addr_private
RFC1918, RFC6598 (CGNAT), or fc00::/7.
@ k_mdl_addr_linklocal
169.254.0.0/16 or fe80::/10.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
char * strstr(const char *haystack, const char *needle)
Locate substring in string.
char * strchr(const char *s, int c)
Locate first occurrence of character in string.