Merge pull request #741 from Artoria2e5/parseline-cidr

Support CIDR-notated blocklists
This commit is contained in:
Charles Kerr 2019-02-01 23:38:48 -06:00 committed by GitHub
commit b04f2df299
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 6 deletions

View File

@ -19,12 +19,14 @@
#include "libtransmission-test.h"
static char const* contents1 =
"10.5.6.7/8\n"
"Austin Law Firm:216.16.1.144-216.16.1.151\n"
"Sargent Controls and Aerospace:216.19.18.0-216.19.18.255\n"
"Corel Corporation:216.21.157.192-216.21.157.223\n"
"Fox Speed Channel:216.79.131.192-216.79.131.223\n";
static char const* contents2 =
"10.5.6.7/8\n"
"Austin Law Firm:216.16.1.144-216.16.1.151\n"
"Sargent Controls and Aerospace:216.19.18.0-216.19.18.255\n"
"Corel Corporation:216.21.157.192-216.21.157.223\n"
@ -70,7 +72,7 @@ static int test_parsing(void)
tr_free(path);
tr_sessionReloadBlocklists(session);
check(tr_blocklistExists(session));
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* enable the blocklist */
check(!tr_blocklistIsEnabled(session));
@ -78,6 +80,8 @@ static int test_parsing(void)
check(tr_blocklistIsEnabled(session));
/* test blocked addresses */
check(!address_is_blocked(session, "0.0.0.1"));
check(address_is_blocked(session, "10.1.2.3"));
check(!address_is_blocked(session, "216.16.1.143"));
check(address_is_blocked(session, "216.16.1.144"));
check(address_is_blocked(session, "216.16.1.145"));
@ -116,22 +120,22 @@ static int test_updating(void)
/* test that updated source files will get loaded */
create_text_file(path, contents1);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* test that updated source files will get loaded */
create_text_file(path, contents2);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
check_int(tr_blocklistGetRuleCount(session), ==, 6);
/* test that updated source files will get loaded */
create_text_file(path, contents1);
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* ensure that new files, if bad, get skipped */
create_text_file(path, "# nothing useful\n");
tr_sessionReloadBlocklists(session);
check_int(tr_blocklistGetRuleCount(session), ==, 4);
check_int(tr_blocklistGetRuleCount(session), ==, 5);
/* cleanup */
libttest_session_close(session);

View File

@ -301,9 +301,38 @@ static bool parseLine2(char const* line, struct tr_ipv4_range* range)
return true;
}
/*
* CIDR notation: "0.0.0.0/8", IPv4 only
* https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation
*/
static bool parseLine3(char const* line, struct tr_ipv4_range* range) {
unsigned ip[4];
unsigned pflen;
uint32_t ip_u;
uint32_t mask = 0xffffffff;
if (sscanf(line, "%u.%u.%u.%u/%u", &ip[0], &ip[1], &ip[2], &ip[3], &pflen) != 5) {
return false;
}
if (pflen > 32 || ip[0] > 0xff || ip[1] > 0xff || ip[2] > 0xff || ip[3] > 0xff) {
return false;
}
/* this is host order */
mask <<= 32 - pflen;
ip_u = ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3];
/* fill the non-prefix bits the way we need it */
range->begin = ip_u & mask;
range->end = ip_u | (~mask);
return true;
}
static bool parseLine(char const* line, struct tr_ipv4_range* range)
{
return parseLine1(line, range) || parseLine2(line, range);
return parseLine1(line, range) || parseLine2(line, range) || parseLine3(line, range);
}
static int compareAddressRangesByFirstAddress(void const* va, void const* vb)