Commit 83539eb7 authored by Vladimír Čunát's avatar Vladimír Čunát

lib/utils kr_straddr_split(): tweak meaning, use more

Now we don't rewrite the port-splitters in command line by zero bytes.
That was confusing the output of some SW showing the command-line
of running kresd.
parent b52fb759
......@@ -14,6 +14,10 @@ Improvements
- policy module: policy.rpz() will watch the file for changes by default
- packaging: lua cqueues added to default dependencies where available
Module API changes
------------------
- kr_straddr_split() changed API a bit (compiler will catch that)
Knot Resolver 3.2.1 (2019-01-10)
================================
......
......@@ -373,17 +373,14 @@ static int net_tls_client(lua_State *L)
lua_error(L);
}
char addr[INET6_ADDRSTRLEN];
uint16_t port = 0;
if (kr_straddr_split(full_addr, addr, sizeof(addr), &port) != kr_ok()) {
char buf[INET6_ADDRSTRLEN + 1];
uint16_t port = 853;
const char *addr = kr_straddr_split(full_addr, buf, &port);
if (!addr) {
format_error(L, "invalid IP address");
lua_error(L);
}
if (port == 0) {
port = 853;
}
if (!pin_exists && !hostname_exists) {
int r = tls_client_params_set(&net->tls_client_params,
addr, port, NULL,
......@@ -494,17 +491,14 @@ static int net_tls_client_clear(lua_State *L)
const char *full_addr = lua_tostring(L, 1);
char addr[INET6_ADDRSTRLEN];
uint16_t port = 0;
if (kr_straddr_split(full_addr, addr, sizeof(addr), &port) != kr_ok()) {
char buf[INET6_ADDRSTRLEN + 1];
uint16_t port = 853;
const char *addr = kr_straddr_split(full_addr, buf, &port);
if (!addr) {
format_error(L, "invalid IP address");
lua_error(L);
}
if (port == 0) {
port = 853;
}
int r = tls_client_params_clear(&net->tls_client_params, addr, port);
if (r != 0) {
lua_pushstring(L, kr_strerror(r));
......
......@@ -337,20 +337,6 @@ static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
#pragma GCC diagnostic pop
}
/** Split away port from the address. */
static const char *set_addr(char *addr, int *port)
{
char *p = strchr(addr, '@');
if (!p) {
p = strchr(addr, '#');
}
if (p) {
*port = strtol(p + 1, NULL, 10);
*p = '\0';
}
return addr;
}
/*
* Server operation.
......@@ -641,20 +627,21 @@ static int bind_fds(struct network *net, fd_array_t *fd_set, bool tls) {
return ret;
}
static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {
static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {
uint32_t flags = tls ? NET_TCP|NET_TLS : NET_UDP|NET_TCP;
int ret = 0;
for (size_t i = 0; i < addr_set->len; ++i) {
int port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
const char *addr = set_addr(addr_set->at[i], &port);
ret = network_listen(net, addr, (uint16_t)port, flags);
uint16_t port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
char buf[INET6_ADDRSTRLEN + 1];
const char *addr = kr_straddr_split(addr_set->at[i], buf, &port);
/* NULL will result into kr_strerror(EINVAL) -> correct. */
int ret = network_listen(net, addr, (uint16_t)port, flags);
if (ret != 0) {
kr_log_error("[system] bind to '%s@%d' %s%s\n",
kr_log_error("[system] bind to '%s@%d' %s%s\n",
addr, port, tls ? "(TLS) " : "", kr_strerror(ret));
break;
return ret;
}
}
return ret;
return kr_ok();
}
int main(int argc, char **argv)
......
......@@ -491,55 +491,29 @@ int kr_straddr_subnet(void *dst, const char *addr)
return bit_len;
}
int kr_straddr_split(const char *addr, char *buf, size_t buflen, uint16_t *port)
const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port)
{
const int base = 10;
long p = 0;
size_t addrlen = strlen(addr);
char *p_start = strchr(addr, '@');
char *p_end;
if (!p_start) {
assert(addr && buf && port);
/* Find where port number starts. */
const char *p_start = strchr(addr, '@');
if (!p_start)
p_start = strchr(addr, '#');
}
if (p_start) {
if (p_start[1] != '\0'){
p = strtol(p_start + 1, &p_end, base);
if (*p_end != '\0' || p <= 0 || p > UINT16_MAX) {
return kr_error(EINVAL);
}
}
addrlen = p_start - addr;
}
/* Check if address is valid. */
if (addrlen >= INET6_ADDRSTRLEN) {
return kr_error(EINVAL);
}
char str[INET6_ADDRSTRLEN];
struct sockaddr_storage ss;
memcpy(str, addr, addrlen); str[addrlen] = '\0';
int family = kr_straddr_family(str);
if (family == kr_error(EINVAL) || !inet_pton(family, str, &ss)) {
return kr_error(EINVAL);
}
/* Address and port contains valid values, return it to caller */
if (buf) {
if (addrlen >= buflen) {
return kr_error(ENOSPC);
}
memcpy(buf, addr, addrlen); buf[addrlen] = '\0';
}
if (port) {
*port = (uint16_t)p;
}
return kr_ok();
if (!p_start) /* No port specified -> no need to copy anything. */
return addr;
if (p_start[1] == '\0') /* Don't accept empty port string. */
return NULL;
/* Check the port number. */
char *p_end;
long p = strtol(p_start + 1, &p_end, 10);
if (*p_end != '\0' || p <= 0 || p > UINT16_MAX)
return NULL;
*port = p;
/* We need to copy the address. */
const size_t addrlen = p_start - addr;
if (addrlen > INET6_ADDRSTRLEN)
return NULL;
memcpy(buf, addr, addrlen); buf[addrlen] = '\0';
return buf;
}
int kr_straddr_join(const char *addr, uint16_t port, char *buf, size_t *buflen)
......
......@@ -303,16 +303,17 @@ struct sockaddr * kr_straddr_socket(const char *addr, int port);
KR_EXPORT
int kr_straddr_subnet(void *dst, const char *addr);
/** Splits ip address specified as "addr@port" or "addr#port" into addr and port
* and performs validation.
* @note if #port part isn't present, then port will be set to 0.
* buf and\or port can be set to NULL.
* @return kr_error(EINVAL) - addr part doesn't contains valid ip address or
* #port part is out-of-range (either < 0 either > UINT16_MAX)
* kr_error(ENOSP) - buflen is too small
*/
/** Splits ip address specified as "addr@port" or "addr#port" into addr and port.
* \param addr zero-terminated input
* \param buf buffer in case we need to copy the address;
* length > MIN(strlen(addr), INET6_ADDRSTRLEN + 1)
* \param port[out] written in case it's specified in addr
* \return pointer to address without port (zero-terminated string)
* \note Typically you follow this by kr_straddr_socket().
*/
KR_EXPORT
int kr_straddr_split(const char *addr, char *buf, size_t buflen, uint16_t *port);
const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port);
/** Formats ip address and port in "addr#port" format.
* and performs validation.
* @note Port always formatted as five-character string with leading zeros.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment