Commit 5ed0b3a5 authored by Vladimír Čunát's avatar Vladimír Čunát

lib/utils kr_straddr_split(): simplify the API

After 83539eb7 it was a bit complicated.  It allowed to save a memcpy
of the address in case no port was specified, but we only need to do the
split when changing configuration, so it was overzealous optimization.
parent c1496370
......@@ -535,9 +535,10 @@ static int net_tls_client(lua_State *L)
lua_error_p(L, "address is not a string");
char buf[INET6_ADDRSTRLEN + 1];
uint16_t port = 853;
addr_str = kr_straddr_split(addr_str, buf, &port);
const struct sockaddr *addr = NULL;
if (kr_straddr_split(addr_str, buf, &port) == kr_ok())
addr = kr_straddr_socket(buf, port);
/* Add newcfg into the C map, saving the original into oldcfg. */
const struct sockaddr *addr = kr_straddr_socket(addr_str, port);
if (!addr)
lua_error_p(L, "address '%s' could not be converted", addr_str);
tls_client_param_t **oldcfgp = tls_client_param_getptr(
......@@ -578,8 +579,9 @@ int net_tls_client_clear(lua_State *L)
const char *addr_str = lua_tostring(L, 1);
char buf[INET6_ADDRSTRLEN + 1];
uint16_t port = 853;
addr_str = kr_straddr_split(addr_str, buf, &port);
const struct sockaddr *addr = kr_straddr_socket(addr_str, port);
const struct sockaddr *addr = NULL;
if (kr_straddr_split(addr_str, buf, &port) == kr_ok())
addr = kr_straddr_socket(buf, port);
if (!addr)
lua_error_p(L, "invalid IP address");
/* Do the actual removal. */
......
......@@ -632,13 +632,13 @@ 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;
for (size_t i = 0; i < addr_set->len; ++i) {
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, port, flags);
char addr_str[INET6_ADDRSTRLEN + 1];
int ret = kr_straddr_split(addr_set->at[i], addr_str, &port);
if (ret == 0)
ret = network_listen(net, addr_str, port, flags);
if (ret != 0) {
kr_log_error("[system] bind to '%s@%d' %s%s\n",
addr, port, tls ? "(TLS) " : "", kr_strerror(ret));
kr_log_error("[system] bind to '%s' %s%s\n",
addr_set->at[i], tls ? "(TLS) " : "", kr_strerror(ret));
return ret;
}
}
......
......@@ -500,29 +500,30 @@ int kr_straddr_subnet(void *dst, const char *addr)
return bit_len;
}
const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port)
int kr_straddr_split(const char *instr, char ipaddr[static restrict (INET6_ADDRSTRLEN + 1)],
uint16_t *port)
{
assert(addr && buf && port);
assert(instr && ipaddr && port);
/* Find where port number starts. */
const char *p_start = strchr(addr, '@');
const char *p_start = strchr(instr, '@');
if (!p_start)
p_start = strchr(addr, '#');
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;
p_start = strchr(instr, '#');
if (p_start) { /* Get and check the port number. */
if (p_start[1] == '\0') /* Don't accept empty port string. */
return kr_error(EILSEQ);
char *p_end;
long p = strtol(p_start + 1, &p_end, 10);
if (*p_end != '\0' || p <= 0 || p > UINT16_MAX)
return kr_error(EILSEQ);
*port = p;
}
/* Copy the address. */
const size_t addrlen = p_start ? p_start - instr : strlen(instr);
if (addrlen > INET6_ADDRSTRLEN)
return NULL;
memcpy(buf, addr, addrlen); buf[addrlen] = '\0';
return buf;
return kr_error(EILSEQ);
memcpy(ipaddr, instr, addrlen);
ipaddr[addrlen] = '\0';
return kr_ok();
}
int kr_straddr_join(const char *addr, uint16_t port, char *buf, size_t *buflen)
......
......@@ -337,15 +337,16 @@ 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.
* \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)
* \param instr[in] zero-terminated input, e.g. "192.0.2.1#12345\0"
* \param ipaddr[out] working buffer for the port-less prefix of instr;
* length >= INET6_ADDRSTRLEN + 1.
* \param port[out] written in case it's specified in instr
* \return error code
* \note Typically you follow this by kr_straddr_socket().
*/
KR_EXPORT
const char * kr_straddr_split(const char *addr, char *buf, uint16_t *port);
int kr_straddr_split(const char *instr, char ipaddr[static restrict (INET6_ADDRSTRLEN + 1)],
uint16_t *port);
/** Formats ip address and port in "addr#port" format.
* and performs validation.
......
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