-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move is ipv4/ipv6 functions from Aws-c-sdkutils to Aws-c-common #1105
Merged
Merged
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
cb3d2b5
host utils
waahm7 7b6de23
ipv6 changes
waahm7 2c0c111
EOF
waahm7 69419d3
Disable scanf warnings
waahm7 d4dcd06
Merge branch 'main' into host-utils
waahm7 80e65fb
host utils
waahm7 5e79ea2
Fix
waahm7 2129b2f
Add test for ::1
waahm7 db38337
Fix again
waahm7 7b18784
Add loopback and ecs/eks ipv6 tests
waahm7 802d9ff
rename functions
waahm7 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef AWS_COMMON_HOST_UTILS_H | ||
#define AWS_COMMON_HOST_UTILS_H | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
#include <aws/common/common.h> | ||
|
||
struct aws_byte_cursor; | ||
|
||
AWS_PUSH_SANE_WARNING_LEVEL | ||
AWS_EXTERN_C_BEGIN | ||
|
||
/* | ||
* Determine whether host cursor is IPv4 string. | ||
*/ | ||
AWS_COMMON_API bool aws_is_ipv4(struct aws_byte_cursor host); | ||
|
||
/* | ||
* Determine whether host cursor is IPv6 string. | ||
* Supports checking for uri encoded strings and scoped literals. | ||
*/ | ||
AWS_COMMON_API bool aws_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded); | ||
|
||
AWS_EXTERN_C_END | ||
AWS_POP_SANE_WARNING_LEVEL | ||
|
||
#endif /* AWS_COMMON_HOST_UTILS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
#include <aws/common/host_utils.h> | ||
#include <aws/common/string.h> | ||
#include <inttypes.h> | ||
|
||
#ifdef _MSC_VER /* Disable sscanf warnings on windows. */ | ||
# pragma warning(disable : 4204) | ||
# pragma warning(disable : 4706) | ||
# pragma warning(disable : 4996) | ||
#endif | ||
|
||
/* 4 octets of 3 chars max + 3 separators + null terminator */ | ||
#define AWS_IPV4_STR_LEN 16 | ||
#define IP_CHAR_FMT "%03" SCNu16 | ||
|
||
static bool s_is_ipv6_char(uint8_t value) { | ||
return aws_isxdigit(value) || value == ':'; | ||
} | ||
|
||
static bool s_starts_with(struct aws_byte_cursor cur, uint8_t ch) { | ||
return cur.len > 0 && cur.ptr[0] == ch; | ||
} | ||
|
||
static bool s_ends_with(struct aws_byte_cursor cur, uint8_t ch) { | ||
return cur.len > 0 && cur.ptr[cur.len - 1] == ch; | ||
} | ||
|
||
bool aws_is_ipv4(struct aws_byte_cursor host) { | ||
if (host.len > AWS_IPV4_STR_LEN - 1) { | ||
return false; | ||
} | ||
|
||
char copy[AWS_IPV4_STR_LEN] = {0}; | ||
memcpy(copy, host.ptr, host.len); | ||
|
||
uint16_t octet[4] = {0}; | ||
char remainder[2] = {0}; | ||
if (4 != sscanf( | ||
copy, | ||
IP_CHAR_FMT "." IP_CHAR_FMT "." IP_CHAR_FMT "." IP_CHAR_FMT "%1s", | ||
&octet[0], | ||
&octet[1], | ||
&octet[2], | ||
&octet[3], | ||
remainder)) { | ||
return false; | ||
} | ||
|
||
for (size_t i = 0; i < 4; ++i) { | ||
if (octet[i] > 255) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/* actual encoding is %25, but % is omitted for simplicity, since split removes it */ | ||
static struct aws_byte_cursor s_percent_uri_enc = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("25"); | ||
/* | ||
* IPv6 format: | ||
* 8 groups of 4 hex chars separated by colons (:) | ||
* leading 0s in each group can be skipped | ||
* 2 or more consecutive zero groups can be replaced by double colon (::), | ||
* but only once. | ||
* ipv6 literal can be scoped by to zone by appending % followed by zone name | ||
* ( does not look like there is length reqs on zone name length. this | ||
* implementation enforces that its > 1 ) | ||
* ipv6 can be embedded in url, in which case it must be wrapped inside [] | ||
* and % be uri encoded as %25. | ||
* Implementation is fairly trivial and just iterates through the string | ||
* keeping track of the spec above. | ||
*/ | ||
bool aws_is_ipv6(struct aws_byte_cursor host, bool is_uri_encoded) { | ||
if (host.len == 0) { | ||
return false; | ||
} | ||
|
||
if (is_uri_encoded) { | ||
if (!s_starts_with(host, '[') || !s_ends_with(host, ']')) { | ||
return false; | ||
} | ||
aws_byte_cursor_advance(&host, 1); | ||
--host.len; | ||
} | ||
|
||
struct aws_byte_cursor substr = {0}; | ||
/* first split is required ipv6 part */ | ||
bool is_split = aws_byte_cursor_next_split(&host, '%', &substr); | ||
AWS_ASSERT(is_split); /* function is guaranteed to return at least one split */ | ||
|
||
if (!is_split || substr.len == 0 || s_ends_with(substr, ':') || | ||
!aws_byte_cursor_satisfies_pred(&substr, s_is_ipv6_char)) { | ||
return false; | ||
} | ||
|
||
uint8_t group_count = 0; | ||
bool has_double_colon = false; | ||
struct aws_byte_cursor group = {0}; | ||
while (aws_byte_cursor_next_split(&substr, ':', &group)) { | ||
++group_count; | ||
|
||
if (group_count > 8 || /* too many groups */ | ||
group.len > 4 || /* too many chars in group */ | ||
(has_double_colon && group.len == 0 && group_count > 2)) { /* only one double colon allowed */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To fix the |
||
return false; | ||
} | ||
|
||
has_double_colon = has_double_colon || group.len == 0; | ||
} | ||
|
||
/* second split is optional zone part */ | ||
if (aws_byte_cursor_next_split(&host, '%', &substr)) { | ||
if ((is_uri_encoded && | ||
(substr.len < 3 || | ||
!aws_byte_cursor_starts_with(&substr, &s_percent_uri_enc))) || /* encoding for % + 1 extra char */ | ||
(!is_uri_encoded && substr.len == 0) || /* at least 1 char */ | ||
!aws_byte_cursor_satisfies_pred(&substr, aws_isalnum)) { | ||
return false; | ||
} | ||
} | ||
|
||
return has_double_colon ? group_count < 7 : group_count == 8; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/byte_buf.h> | ||
#include <aws/common/host_utils.h> | ||
#include <aws/testing/aws_test_harness.h> | ||
|
||
AWS_TEST_CASE(host_util_is_ipv4, s_test_is_ipv4) | ||
static int s_test_is_ipv4(struct aws_allocator *allocator, void *ctx) { | ||
(void)allocator; | ||
(void)ctx; | ||
|
||
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("0.0.0.0"))); | ||
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1"))); | ||
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("255.255.255.255"))); | ||
ASSERT_TRUE(aws_is_ipv4(aws_byte_cursor_from_c_str("192.168.1.1"))); | ||
|
||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("256.0.0.1"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str(""))); | ||
|
||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("foo.com"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("a.b.c.d"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("a127.0.0.1"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1a"))); | ||
ASSERT_FALSE(aws_is_ipv4(aws_byte_cursor_from_c_str("127.0.0.1011"))); | ||
|
||
return AWS_OP_SUCCESS; | ||
} | ||
|
||
AWS_TEST_CASE(host_util_is_ipv6, s_test_is_ipv6) | ||
static int s_test_is_ipv6(struct aws_allocator *allocator, void *ctx) { | ||
(void)allocator; | ||
(void)ctx; | ||
|
||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("0:0:0000:0000:0000:0:0:0"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:7334"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0DB8:0000:0000:0000:8a2e:0370:7334"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%en0"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("::1"), false)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[2001:0db8:0000:0000:0000:8a2e:0370:7334]"), true)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1]"), true)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25en0]"), true)); | ||
ASSERT_TRUE(aws_is_ipv6(aws_byte_cursor_from_c_str("[2001:db8:85a3:8d3:1319:8a2e:370:7348]"), true)); | ||
|
||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001::"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("2001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str(":2001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("z001:0db8:0000:0000:0000:8a2e:0370:7334:8745"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("z001::8a2e::8745"), false)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("::2001:0db8:0000:0000:8a2e:0370:7334"), false)); | ||
|
||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0"), true)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%en0]"), true)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%24en0]"), true)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25en0"), true)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("fe80::1%25en0]"), true)); | ||
ASSERT_FALSE(aws_is_ipv6(aws_byte_cursor_from_c_str("[fe80::1%25]"), true)); | ||
|
||
return AWS_OP_SUCCESS; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To fix the
::1
case:Changes made:
removed
_starts_with(substr,':')
condition here.