From 848b8efdcaf178ee11ad4970ed7ddd56e2e2a0b6 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Thu, 20 Jun 2019 11:19:08 +0800 Subject: [PATCH] feature: supported to match remote ip address. --- include/r3.h | 4 ++ src/node.c | 21 +++++--- tests/Makefile.am | 3 ++ tests/check_remote_addr.c | 102 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 tests/check_remote_addr.c diff --git a/include/r3.h b/include/r3.h index 993decb..8bc4c63 100644 --- a/include/r3.h +++ b/include/r3.h @@ -84,6 +84,10 @@ struct _R3Route { void * data; r3_iovec_t remote_addr_pattern; + + unsigned int remote_addr_v4; + int remote_addr_v4_bits; + } __attribute__((aligned(64))); typedef struct _R3Entry match_entry; diff --git a/src/node.c b/src/node.c index c4d63e4..1c3a76d 100644 --- a/src/node.c +++ b/src/node.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include // PCRE #include @@ -902,16 +904,23 @@ inline int r3_route_cmp(const R3Route *r1, const match_entry *r2) { } if (r1->remote_addr_pattern.len && r2->remote_addr.len) { - /* - * XXX: consider "netinet/in.h" - if (r2->remote_addr) { - inet_addr(r2->remote_addr); - } - */ if ( strncmp(r1->remote_addr_pattern.base, r2->remote_addr.base, r2->remote_addr.len) ) { return -1; } } + + if (r1->remote_addr_v4 > 0 && r1->remote_addr_v4_bits > 0) { + if (!r2->remote_addr.base) { + return -1; + } + + unsigned int r2_addr2 = inet_network(r2->remote_addr.base); + int bits = 32 - r1->remote_addr_v4_bits; + if (r1->remote_addr_v4 >> bits != r2_addr2 >> bits) { + return -1; + } + } + return 0; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 5f4660b..6183225 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,6 +30,9 @@ check_str_array_SOURCES = check_str_array.c TESTS += check_host check_host_SOURCES = check_host.c +TESTS += check_remote_addr +check_remote_addr_SOURCES = check_remote_addr.c + if ENABLE_JSON TESTS += check_json diff --git a/tests/check_remote_addr.c b/tests/check_remote_addr.c new file mode 100644 index 0000000..4393046 --- /dev/null +++ b/tests/check_remote_addr.c @@ -0,0 +1,102 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include + +#include "r3.h" +#include "r3_slug.h" + +START_TEST (test_remote_addrs) +{ + R3Node * n = r3_tree_create(10); + R3Route * route = NULL; + match_entry * entry; + R3Route *matched_route; + + char * uri0 = "/foo"; + route = r3_tree_insert_routel(n, 0, uri0, strlen(uri0), &uri0); + route->remote_addr_v4 = 0; + route->remote_addr_v4_bits = 0; + + char * uri1 = "/bar"; + route = r3_tree_insert_routel(n, 0, uri1, strlen(uri1), &uri1); + route->remote_addr_v4 = inet_network("127.0.0.1"); + route->remote_addr_v4_bits = 32; + + char * uri2 = "/boo"; + route = r3_tree_insert_routel(n, 0, uri2, strlen(uri2), &uri2); + route->remote_addr_v4 = inet_network("127.0.0.1"); + route->remote_addr_v4_bits = 24; + + char * err = NULL; + r3_tree_compile(n, &err); + ck_assert(err == NULL); + + + entry = match_entry_create("/foo"); + entry->remote_addr.base = "127.0.0.1"; + entry->remote_addr.len = sizeof("127.0.0.1") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri0); + + entry = match_entry_create("/bar"); + entry->remote_addr.base = "127.0.0.1"; + entry->remote_addr.len = sizeof("127.0.0.1") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri1); + + entry = match_entry_create("/bar"); + entry->remote_addr.base = "127.0.0.2"; + entry->remote_addr.len = sizeof("127.0.0.2") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route == NULL); + + + entry = match_entry_create("/boo"); + entry->remote_addr.base = "127.0.0.1"; + entry->remote_addr.len = sizeof("127.0.0.1") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri2); + + entry = match_entry_create("/boo"); + entry->remote_addr.base = "127.0.0.2"; + entry->remote_addr.len = sizeof("127.0.0.2") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route != NULL); + ck_assert(matched_route->data == &uri2); + + entry = match_entry_create("/boo"); + entry->remote_addr.base = "127.0.1.2"; + entry->remote_addr.len = sizeof("127.0.1.2") - 1; + matched_route = r3_tree_match_route(n, entry); + ck_assert(matched_route == NULL); + + r3_tree_free(n); +} +END_TEST + + + +Suite* r3_suite (void) { + Suite *suite = suite_create("r3 remote_addr tests"); + TCase *tcase = tcase_create("testcase"); + tcase_add_test(tcase, test_remote_addrs); + suite_add_tcase(suite, tcase); + return suite; +} + +int main (int argc, char *argv[]) { + int number_failed; + Suite *suite = r3_suite(); + SRunner *runner = srunner_create(suite); + srunner_run_all(runner, CK_NORMAL); + number_failed = srunner_ntests_failed(runner); + srunner_free(runner); + return number_failed; +}