Skip to content

Commit ce0d656

Browse files
authored
[fix] failed to compile on FreeBSD (#527)
1 parent bfa0392 commit ce0d656

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

source/no_proxy.c

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
5+
#include <aws/common/byte_order.h>
56
#include <aws/common/environment.h>
67
#include <aws/http/private/no_proxy.h>
7-
8-
#ifdef _WIN32
9-
# include <ws2tcpip.h>
10-
#else
11-
# include <arpa/inet.h>
12-
#endif
8+
#include <aws/io/socket.h>
139

1410
enum hostname_type {
1511
HOSTNAME_TYPE_IPV4,
@@ -38,15 +34,15 @@ static bool s_cidr4_match(uint64_t bits, struct aws_string *network_part, uint32
3834
}
3935

4036
/* Convert network pattern to binary */
41-
if (inet_pton(AF_INET, aws_string_c_str(network_part), &check) != 1) {
37+
if (aws_parse_ipv4_address(network_part, &check) != AWS_OP_SUCCESS) {
4238
return false;
4339
}
4440

4541
if (bits > 0 && bits < 32) {
4642
/* Apply the network mask for CIDR comparison */
4743
uint32_t mask = 0xffffffff << (32 - bits);
48-
uint32_t host_network = ntohl(address);
49-
uint32_t check_network = ntohl(check);
44+
uint32_t host_network = aws_ntoh32(address);
45+
uint32_t check_network = aws_ntoh32(check);
5046

5147
/* Compare the masked addresses */
5248
return (host_network & mask) == (check_network & mask);
@@ -66,45 +62,62 @@ static bool s_cidr4_match(uint64_t bits, struct aws_string *network_part, uint32
6662
* @param host_addr Pre-parsed binary representation of the host IP, or NULL to parse from host
6763
* @return true if the IP address matches the CIDR pattern, false otherwise
6864
*/
69-
static bool s_cidr6_match(uint64_t bits, struct aws_string *network_part, uint8_t *address) {
70-
uint8_t check[16] = {0};
71-
65+
static bool s_cidr6_match(
66+
struct aws_allocator *allocator,
67+
uint64_t bits,
68+
struct aws_string *network_part,
69+
struct aws_byte_cursor address) {
70+
bool result = false;
71+
struct aws_byte_buf check_buf;
72+
aws_byte_buf_init(&check_buf, allocator, 16);
7273
/* If no bits specified, use full 128 bits for IPv6 */
7374
if (!bits) {
7475
bits = 128;
7576
}
7677

7778
/* Check for valid bits parameter */
7879
if (bits > 128) {
79-
return false;
80+
goto cleanup;
8081
}
8182
/* Convert network pattern to binary */
82-
if (inet_pton(AF_INET6, aws_string_c_str(network_part), check) != 1) {
83-
return false;
83+
if (aws_parse_ipv6_address(network_part, &check_buf) != AWS_OP_SUCCESS) {
84+
goto cleanup;
8485
}
86+
struct aws_byte_cursor check = aws_byte_cursor_from_buf(&check_buf);
8587

8688
/* Calculate full bytes and remaining bits in the netmask */
8789
uint64_t bytes = bits / 8;
8890
uint64_t rest = bits % 8;
89-
90-
/* Compare full bytes of the network part */
91-
if (bytes > 0 && memcmp(address, check, (size_t)bytes) != 0) {
92-
return false;
91+
if (bytes > address.len || address.len != check_buf.len || check_buf.len != 16) {
92+
goto cleanup;
93+
}
94+
if (bytes > 0 && !aws_array_eq(address.ptr, (size_t)bytes, check.ptr, (size_t)bytes)) {
95+
goto cleanup;
9396
}
9497

9598
/* If we have remaining bits, compare the partial byte */
96-
if (rest > 0 && bytes < 16) {
99+
if (rest > 0) {
97100
/* Create a mask for the remaining bits */
98101
unsigned char mask = (unsigned char)(0xff << (8 - rest));
99-
102+
aws_byte_cursor_advance(&check, (size_t)bytes);
103+
aws_byte_cursor_advance(&address, (size_t)bytes);
104+
uint8_t address_byte = 0;
105+
uint8_t check_byte = 0;
106+
if (aws_byte_cursor_read_u8(&address, &address_byte) == false ||
107+
aws_byte_cursor_read_u8(&check, &check_byte) == false) {
108+
goto cleanup;
109+
}
100110
/* Check if the masked bits match */
101-
if ((address[bytes] & mask) != (check[bytes] & mask)) {
102-
return false;
111+
if ((address_byte & mask) != (check_byte & mask)) {
112+
goto cleanup;
103113
}
104114
}
105115

106116
/* All checks passed, addresses match within the CIDR range */
107-
return true;
117+
result = true;
118+
cleanup:
119+
aws_byte_buf_clean_up(&check_buf);
120+
return result;
108121
}
109122

110123
static bool s_is_dot(uint8_t c) {
@@ -128,6 +141,7 @@ bool aws_http_host_matches_no_proxy(
128141
struct aws_byte_cursor no_proxy_cur = aws_byte_cursor_from_string(no_proxy_str);
129142
struct aws_array_list no_proxy_list;
130143
struct aws_string *host_str = aws_string_new_from_cursor(allocator, &host);
144+
struct aws_byte_buf ipv6_addr = {0};
131145

132146
if (aws_array_list_init_dynamic(&no_proxy_list, allocator, 10, sizeof(struct aws_byte_cursor))) {
133147
goto cleanup;
@@ -139,11 +153,10 @@ bool aws_http_host_matches_no_proxy(
139153

140154
/* Store parsed binary addresses for reuse */
141155
uint32_t ipv4_addr = 0;
142-
uint8_t ipv6_addr[16] = {0};
143156

144157
/* Determine host type and parse address if applicable */
145158
enum hostname_type type = HOSTNAME_TYPE_REGULAR;
146-
if (inet_pton(AF_INET, aws_string_c_str(host_str), &ipv4_addr) == 1) {
159+
if (aws_parse_ipv4_address(host_str, &ipv4_addr) == AWS_OP_SUCCESS) {
147160
type = HOSTNAME_TYPE_IPV4;
148161
} else {
149162
struct aws_string *host_str_copy = host_str;
@@ -155,7 +168,8 @@ bool aws_http_host_matches_no_proxy(
155168
host_str_copy = aws_string_new_from_cursor(allocator, &host_copy);
156169
}
157170

158-
if (inet_pton(AF_INET6, aws_string_c_str(host_str_copy), ipv6_addr) == 1) {
171+
aws_byte_buf_init(&ipv6_addr, allocator, 16);
172+
if (aws_parse_ipv6_address(host_str_copy, &ipv6_addr) == AWS_OP_SUCCESS) {
159173
/* Update the host str */
160174
if (host_str != host_str_copy) {
161175
aws_string_destroy(host_str);
@@ -254,7 +268,8 @@ bool aws_http_host_matches_no_proxy(
254268
goto cleanup;
255269
}
256270
} else {
257-
if (s_cidr6_match(network_bits, network_part_str, ipv6_addr)) {
271+
if (s_cidr6_match(
272+
allocator, network_bits, network_part_str, aws_byte_cursor_from_buf(&ipv6_addr))) {
258273
bypass = true;
259274
aws_string_destroy(network_part_str);
260275
goto cleanup;
@@ -271,6 +286,7 @@ bool aws_http_host_matches_no_proxy(
271286
}
272287

273288
cleanup:
289+
aws_byte_buf_clean_up(&ipv6_addr);
274290
aws_string_destroy(host_str);
275291
aws_array_list_clean_up(&no_proxy_list);
276292
return bypass;

0 commit comments

Comments
 (0)