Add helper for matching topdomain and getting data length
This commit is contained in:
parent
589027568b
commit
f1e7823a3d
46
src/common.c
46
src/common.c
|
@ -404,6 +404,52 @@ check_topdomain(char *str, int allow_wildcard, char **errormsg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
query_datalen(const char *qname, const char *topdomain)
|
||||||
|
{
|
||||||
|
/* Return number of data bytes embedded in DNS query name,
|
||||||
|
* or -1 if domains do not match.
|
||||||
|
*/
|
||||||
|
int qpos = strlen(qname);
|
||||||
|
int tpos = strlen(topdomain);
|
||||||
|
if (tpos < 3 || qpos < tpos) {
|
||||||
|
/* Domain or query name too short */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Backward string compare */
|
||||||
|
qpos--;
|
||||||
|
tpos--;
|
||||||
|
while (qpos >= 0) {
|
||||||
|
if (topdomain[tpos] == '*') {
|
||||||
|
/* Wild match, is first in topdomain */
|
||||||
|
if (qname[qpos] == '*') {
|
||||||
|
/* Don't match against stars in query name */
|
||||||
|
return -1;
|
||||||
|
} else if (qpos == 0 || qname[qpos-1] == '.') {
|
||||||
|
/* Reached start of query name or chunk separator */
|
||||||
|
return qpos;
|
||||||
|
}
|
||||||
|
qpos--;
|
||||||
|
} else if (tolower(qname[qpos]) == tolower(topdomain[tpos])) {
|
||||||
|
/* Matching char, exclude wildcard in query name */
|
||||||
|
if (tpos == 0) {
|
||||||
|
/* Fully matched domain */
|
||||||
|
if (qpos == 0 || qname[qpos-1] == '.') {
|
||||||
|
/* Start of name or has dot before matching topdomain */
|
||||||
|
return qpos;
|
||||||
|
}
|
||||||
|
/* Query name has longer chunk than topdomain */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tpos--;
|
||||||
|
qpos--;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(WINDOWS32) || defined(ANDROID)
|
#if defined(WINDOWS32) || defined(ANDROID)
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
int
|
int
|
||||||
|
|
|
@ -128,6 +128,8 @@ void read_password(char*, size_t);
|
||||||
|
|
||||||
int check_topdomain(char *, int, char **);
|
int check_topdomain(char *, int, char **);
|
||||||
|
|
||||||
|
int query_datalen(const char *qname, const char *topdomain);
|
||||||
|
|
||||||
#if defined(WINDOWS32) || defined(ANDROID)
|
#if defined(WINDOWS32) || defined(ANDROID)
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
int inet_aton(const char *cp, struct in_addr *inp);
|
int inet_aton(const char *cp, struct in_addr *inp);
|
||||||
|
|
|
@ -143,6 +143,52 @@ START_TEST(test_topdomain_wild)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_query_datalen)
|
||||||
|
{
|
||||||
|
char *topdomain = "r.foo.com";
|
||||||
|
/* With data */
|
||||||
|
ck_assert(query_datalen("foobar.r.foo.com", topdomain) == 7);
|
||||||
|
ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
|
||||||
|
ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
|
||||||
|
ck_assert(query_datalen(".r.foo.com", topdomain) == 1);
|
||||||
|
/* Without data */
|
||||||
|
ck_assert(query_datalen("r.foo.com", topdomain) == 0);
|
||||||
|
ck_assert(query_datalen("R.foo.com", topdomain) == 0);
|
||||||
|
/* Shorter query name */
|
||||||
|
ck_assert(query_datalen("foo.com", topdomain) == -1);
|
||||||
|
/* Mismatched query name */
|
||||||
|
ck_assert(query_datalen("b.foo.com", topdomain) == -1);
|
||||||
|
ck_assert(query_datalen("*.foo.com", topdomain) == -1);
|
||||||
|
/* Query name overlaps topdomain, but is longer */
|
||||||
|
ck_assert(query_datalen("bar.foo.com", topdomain) == -1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_query_datalen_wild)
|
||||||
|
{
|
||||||
|
char *topdomain = "*.foo.com";
|
||||||
|
/* With data */
|
||||||
|
ck_assert(query_datalen("foobar.a.foo.com", topdomain) == 7);
|
||||||
|
ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
|
||||||
|
ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
|
||||||
|
ck_assert(query_datalen("foo.Ab.foo.cOm", topdomain) == 4);
|
||||||
|
ck_assert(query_datalen("foo.Abcd.Foo.com", topdomain) == 4);
|
||||||
|
ck_assert(query_datalen("***.STARs.foo.com", topdomain) == 4);
|
||||||
|
ck_assert(query_datalen(".a.foo.com", topdomain) == 1);
|
||||||
|
ck_assert(query_datalen(".ab.foo.com", topdomain) == 1);
|
||||||
|
/* Without data */
|
||||||
|
ck_assert(query_datalen("rr.foo.com", topdomain) == 0);
|
||||||
|
ck_assert(query_datalen("b.foo.com", topdomain) == 0);
|
||||||
|
ck_assert(query_datalen("B.foo.com", topdomain) == 0);
|
||||||
|
/* Shorter query name */
|
||||||
|
ck_assert(query_datalen("foo.com", topdomain) == -1);
|
||||||
|
/* Wildcard part of query name matching topdomain */
|
||||||
|
ck_assert(query_datalen("aa.*.foo.com", topdomain) == -1);
|
||||||
|
/* Mismatched query name */
|
||||||
|
ck_assert(query_datalen("bar.r.boo.com", topdomain) == -1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_parse_format_ipv4)
|
START_TEST(test_parse_format_ipv4)
|
||||||
{
|
{
|
||||||
char *host = "192.168.2.10";
|
char *host = "192.168.2.10";
|
||||||
|
@ -245,6 +291,8 @@ test_common_create_tests()
|
||||||
tcase_add_test(tc, test_topdomain_length);
|
tcase_add_test(tc, test_topdomain_length);
|
||||||
tcase_add_test(tc, test_topdomain_chunks);
|
tcase_add_test(tc, test_topdomain_chunks);
|
||||||
tcase_add_test(tc, test_topdomain_wild);
|
tcase_add_test(tc, test_topdomain_wild);
|
||||||
|
tcase_add_test(tc, test_query_datalen);
|
||||||
|
tcase_add_test(tc, test_query_datalen_wild);
|
||||||
tcase_add_test(tc, test_parse_format_ipv4);
|
tcase_add_test(tc, test_parse_format_ipv4);
|
||||||
tcase_add_test(tc, test_parse_format_ipv4_listen_all);
|
tcase_add_test(tc, test_parse_format_ipv4_listen_all);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue