wireaddr: adds helper is_ipaddr, is_toraddr and is_dnsaddr

This commit is contained in:
Michael Schmoock 2021-10-01 13:14:46 +02:00 committed by Rusty Russell
parent 300303a8f2
commit 25bd09716f
4 changed files with 121 additions and 2 deletions

View File

@ -117,6 +117,26 @@ int main(int argc, char *argv[])
common_setup(argv[0]);
/* Check IP/TOR/DNS parser */
assert(is_ipaddr("192.168.1.2"));
assert(!is_ipaddr("foo.bar.1.2"));
assert(is_toraddr("qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion"));
assert(is_toraddr("qubesos4rrrrz6n4.onion"));
assert(!is_toraddr("QUBESOSfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion"));
assert(!is_toraddr("QUBESOS4rrrrz6n4.onion"));
assert(!is_toraddr("qubesos-asa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion"));
assert(is_dnsaddr("example.com"));
assert(is_dnsaddr("example.digits123.com"));
assert(is_dnsaddr("example-hyphen.com"));
assert(is_dnsaddr("123example.com"));
assert(is_dnsaddr("example123.com"));
assert(is_dnsaddr("is-valid.3hostname123.com"));
assert(!is_dnsaddr("UPPERCASE.invalid.com"));
assert(!is_dnsaddr("-.invalid.com"));
assert(!is_dnsaddr("invalid.-example.com"));
assert(!is_dnsaddr("invalid.example-.com"));
assert(!is_dnsaddr("invalid..example.com"));
/* Grossly invalid. */
assert(!separate_address_and_port(tmpctx, "[", &ip, &port));
assert(!separate_address_and_port(tmpctx, "[123", &ip, &port));
@ -148,6 +168,19 @@ int main(int argc, char *argv[])
assert(streq(ip, "192.168.2.255"));
assert(port == 0);
/* DNS types */
assert(separate_address_and_port(tmpctx, "example.com:42", &ip, &port));
assert(streq(ip, "example.com"));
assert(port == 42);
assert(separate_address_and_port(tmpctx, "sub.example.com:21", &ip, &port));
assert(streq(ip, "sub.example.com"));
assert(port == 21);
port = 123;
assert(separate_address_and_port(tmpctx, "sub.example.com", &ip, &port));
assert(streq(ip, "sub.example.com"));
assert(port == 123);
port = 0;
// unusual but possibly valid case
assert(separate_address_and_port(tmpctx, "[::1]", &ip, &port));
assert(streq(ip, "::1"));

View File

@ -287,8 +287,8 @@ REGISTER_TYPE_TO_STRING(wireaddr, fmt_wireaddr);
* Returns false if it wasn't one of these forms. If it returns true,
* it only overwrites *port if it was specified by <number> above.
*/
static bool separate_address_and_port(const tal_t *ctx, const char *arg,
char **addr, u16 *port)
bool separate_address_and_port(const tal_t *ctx, const char *arg,
char **addr, u16 *port)
{
char *portcolon;
@ -322,6 +322,81 @@ static bool separate_address_and_port(const tal_t *ctx, const char *arg,
return true;
}
bool is_ipaddr(const char *arg)
{
struct in_addr v4;
struct in6_addr v6;
if (inet_pton(AF_INET, arg, &v4))
return true;
if (inet_pton(AF_INET6, arg, &v6))
return true;
return false;
}
bool is_toraddr(const char *arg)
{
size_t i, arglen;
arglen = strlen(arg);
if (!strends(arg, ".onion"))
return false;
if (arglen != 16 + 6 && arglen != 56 + 6)
return false;
for (i = 0; i < arglen - 6; i++) {
if (arg[i] >= 'a' && arg[i] <= 'z')
continue;
if (arg[i] >= '0' && arg[i] <= '9')
continue;
return false;
}
return true;
}
/* Rules:
*
* - not longer than 255
* - segments are separated with . dot
* - segments do not start or end with - hyphen
* - segments must be longer thant zero
* - lowercase a-z and digits 0-9 and - hyphen
*/
bool is_dnsaddr(const char *arg)
{
size_t i, arglen;
int lastdot;
if (is_ipaddr(arg) || is_toraddr(arg))
return false;
/* now that its not IP or TOR, check its a DNS name */
arglen = strlen(arg);
if (arglen > 255)
return false;
lastdot = -1;
for (i = 0; i < arglen; i++) {
if (arg[i] == '.') {
/* segment must be longer than zero */
if (i - lastdot == 1)
return false;
/* last segment can not end with hypen */
if (i != 0 && arg[i-1] == '-')
return false;
lastdot = i;
continue;
}
/* segment cannot start with hyphen */
if (i == lastdot + 1 && arg[i] == '-')
return false;
if (arg[i] >= 'a' && arg[i] <= 'z')
continue;
if (arg[i] >= '0' && arg[i] <= '9')
continue;
if (arg[i] == '-')
continue;
return false;
}
return true;
}
struct wireaddr *
wireaddr_from_hostname(const tal_t *ctx,
const char *hostname,

View File

@ -149,6 +149,16 @@ struct wireaddr_internal {
bool wireaddr_internal_eq(const struct wireaddr_internal *a,
const struct wireaddr_internal *b);
bool separate_address_and_port(const tal_t *ctx, const char *arg,
char **addr, u16 *port);
bool is_ipaddr(const char *arg);
bool is_toraddr(const char *arg);
bool is_dnsaddr(const char *arg);
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
u16 port, bool wildcard_ok, bool dns_ok,
bool unresolved_ok, bool allow_deprecated,

View File

@ -875,6 +875,7 @@ static struct io_plan *conn_init(struct io_conn *conn,
break;
case ADDR_INTERNAL_WIREADDR:
/* If it was a Tor address, we wouldn't be here. */
assert(!is_toraddr((char*)addr->u.wireaddr.addr));
ai = wireaddr_to_addrinfo(tmpctx, &addr->u.wireaddr);
break;
}