diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-10-12 15:48:30 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-10-12 15:48:30 +0000 |
commit | 8b037509f3b6f065a467900a5f4d01e21b98f152 (patch) | |
tree | 24d57f0050d07a280dc2700e76e9d42c6263ef70 | |
parent | 1efad74164fb02fbe493bd2c0366936940c879aa (diff) | |
download | tor-8b037509f3b6f065a467900a5f4d01e21b98f152.tar tor-8b037509f3b6f065a467900a5f4d01e21b98f152.tar.gz |
Add functions to parse addr[:port] consistently
svn:r2440
-rw-r--r-- | src/common/util.c | 56 | ||||
-rw-r--r-- | src/common/util.h | 2 | ||||
-rw-r--r-- | src/or/test.c | 31 |
3 files changed, 89 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c index 5d5f3b554..4391ac241 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2028,6 +2028,62 @@ int tor_lookup_hostname(const char *name, uint32_t *addr) } } +/** Parse a string of the form "host[:port]" from <b>addrport</b>. If + * <b>address</b> is provided, set *<b>address</b> to a copy of the + * host portion of the string. If <b>addr</b> is provided, try to + * resolve the host portion of the string and store it into + * *<b>addr</b>. If <b>port</b> is provided, store the port number + * into *<b>port</b>, or 0 if no port is given. Return 0 on success, + * -1 on failure. + */ +int +parse_addr_port(const char *addrport, char **address, uint32_t *addr, + uint16_t *port) +{ + const char *colon; + char *_address = NULL; + int _port; + int ok = 1; + + tor_assert(addrport); + tor_assert(port); + + colon = strchr(addrport, ':'); + if (colon) { + _address = tor_strndup(addrport, colon-addrport); + _port = atoi(colon+1); + if (_port<1 || _port>65536) { + log_fn(LOG_WARN, "Port '%s' out of range", colon+1); + _port = 0; + ok = 0; + } + } else { + _address = tor_strdup(addrport); + _port = 0; + } + + if (addr) { + /* There's an addr pointer, so we need to resolve the hostname. */ + if (tor_lookup_hostname(_address,addr)) { + log_fn(LOG_WARN, "Couldn't look up '%s'", _address); + ok = 0; + *addr = 0; + } + } + + if (address && ok) { + *address = _address; + } else { + if (address) + *address = NULL; + tor_free(_address); + } + if (port) + *port = ok ? ((uint16_t) _port) : 0; + + return ok ? 0 : -1; +} + #ifndef MS_WINDOWS struct tor_mutex_t { }; diff --git a/src/common/util.h b/src/common/util.h index 2b13f92b4..d3a3d6241 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -260,6 +260,8 @@ int switch_id(char *user, char *group); struct in_addr; int tor_inet_aton(const char *cp, struct in_addr *addr); int tor_lookup_hostname(const char *name, uint32_t *addr); +int parse_addr_port(const char *addrport, char **address, uint32_t *addr, + uint16_t *port); /* For stupid historical reasons, windows sockets have an independent * set of errnos, and an independent way to get them. Also, you can't diff --git a/src/or/test.c b/src/or/test.c index 8b4917f38..4d74651ed 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -500,6 +500,9 @@ test_util() { char buf[1024]; time_t t_res; int i; + uint32_t u32; + uint16_t u16; + char *cp; start.tv_sec = 5; start.tv_usec = 5000; @@ -633,6 +636,34 @@ test_util() { NEVER_TERMINATE)); test_streq(buf, "abc##def##ghi"); + /* Test parse_addr_port */ + cp = NULL; u32 = 3; u16 = 3; + test_assert(!parse_addr_port("1.2.3.4", &cp, &u32, &u16)); + test_streq(cp, "1.2.3.4"); + test_eq(u32, 0x01020304u); + test_eq(u16, 0); + tor_free(cp); + test_assert(!parse_addr_port("4.3.2.1:99", &cp, &u32, &u16)); + test_streq(cp, "4.3.2.1"); + test_eq(u32, 0x04030201u); + test_eq(u16, 99); + tor_free(cp); + test_assert(!parse_addr_port("nonexistent.address:4040", &cp, NULL, &u16)); + test_streq(cp, "nonexistent.address"); + test_eq(u16, 4040); + tor_free(cp); + test_assert(!parse_addr_port("localhost:9999", &cp, &u32, &u16)); + test_streq(cp, "localhost"); + test_eq(u32, 0x7f000001u); + test_eq(u16, 9999); + tor_free(cp); + u32 = 3; + test_assert(!parse_addr_port("localhost", NULL, &u32, &u16)); + test_eq(cp, NULL); + test_eq(u32, 0x7f000001u); + test_eq(u16, 0); + tor_free(cp); + /* XXXX test older functions. */ smartlist_free(sl); } |