git: f61f75771f95 - main - ctld: Cleanups to parse_addr_port
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 04 Aug 2025 19:46:50 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=f61f75771f95b59fdbc6ebd71b8da9407374ad44
commit f61f75771f95b59fdbc6ebd71b8da9407374ad44
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-08-04 19:38:07 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-08-04 19:38:07 +0000
ctld: Cleanups to parse_addr_port
- Reimplement the address parsing logic using std::string operations
instead of C string parsing.
- Return a freebsd::addrinfo_up instance holding the allocated
struct addrinfo chain.
Sponsored by: Chelsio Communications
Pull Request: https://github.com/freebsd/freebsd-src/pull/1794
---
usr.sbin/ctld/ctld.cc | 73 ++++++++++++++++++++++++---------------------------
1 file changed, 34 insertions(+), 39 deletions(-)
diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc
index b2cf31fff18f..bf700d5b4051 100644
--- a/usr.sbin/ctld/ctld.cc
+++ b/usr.sbin/ctld/ctld.cc
@@ -506,51 +506,41 @@ portal_group_find(const struct conf *conf, const char *name)
return (NULL);
}
-static int
-parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai)
+static freebsd::addrinfo_up
+parse_addr_port(const char *address, const char *def_port)
{
- struct addrinfo hints;
- char *str, *addr, *ch;
- const char *port;
- int error, colons = 0;
+ struct addrinfo hints, *ai;
+ int error;
- str = arg = strdup(arg);
- if (arg[0] == '[') {
+ std::string addr(address);
+ std::string port(def_port);
+ if (addr[0] == '[') {
/*
* IPv6 address in square brackets, perhaps with port.
*/
- arg++;
- addr = strsep(&arg, "]");
- if (arg == NULL) {
- free(str);
- return (1);
- }
- if (arg[0] == '\0') {
- port = def_port;
- } else if (arg[0] == ':') {
- port = arg + 1;
- } else {
- free(str);
- return (1);
+ addr.erase(0, 1);
+ size_t pos = addr.find(']');
+ if (pos == 0 || pos == addr.npos)
+ return {};
+ if (pos < addr.length() - 1) {
+ port = addr.substr(pos + 1);
+ if (port[0] != ':' || port.length() < 2)
+ return {};
+ port.erase(0, 1);
}
+ addr.resize(pos);
} else {
/*
* Either IPv6 address without brackets - and without
* a port - or IPv4 address. Just count the colons.
*/
- for (ch = arg; *ch != '\0'; ch++) {
- if (*ch == ':')
- colons++;
- }
- if (colons > 1) {
- addr = arg;
- port = def_port;
- } else {
- addr = strsep(&arg, ":");
- if (arg == NULL)
- port = def_port;
- else
- port = arg;
+ size_t pos = addr.find(':');
+ if (pos != addr.npos && addr.find(':', pos + 1) == addr.npos) {
+ /* Only a single colon at `pos`. */
+ if (pos == addr.length() - 1)
+ return {};
+ port = addr.substr(pos + 1);
+ addr.resize(pos);
}
}
@@ -558,9 +548,10 @@ parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai)
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
- error = getaddrinfo(addr, port, &hints, ai);
- free(str);
- return ((error != 0) ? 1 : 0);
+ error = getaddrinfo(addr.c_str(), port.c_str(), &hints, &ai);
+ if (error != 0)
+ return {};
+ return freebsd::addrinfo_up(ai);
}
bool
@@ -572,7 +563,8 @@ portal_group_add_portal(struct portal_group *pg, const char *value, bool iser)
portal->p_listen = checked_strdup(value);
portal->p_iser = iser;
- if (parse_addr_port(portal->p_listen, "3260", &portal->p_ai)) {
+ freebsd::addrinfo_up ai = parse_addr_port(portal->p_listen, "3260");
+ if (!ai) {
log_warnx("invalid listen address %s", portal->p_listen);
portal_delete(portal);
return (false);
@@ -583,6 +575,7 @@ portal_group_add_portal(struct portal_group *pg, const char *value, bool iser)
* those into multiple portals.
*/
+ portal->p_ai = ai.release();
return (true);
}
@@ -598,7 +591,8 @@ isns_new(struct conf *conf, const char *addr)
TAILQ_INSERT_TAIL(&conf->conf_isns, isns, i_next);
isns->i_addr = checked_strdup(addr);
- if (parse_addr_port(isns->i_addr, "3205", &isns->i_ai)) {
+ freebsd::addrinfo_up ai = parse_addr_port(isns->i_addr, "3205");
+ if (!ai) {
log_warnx("invalid iSNS address %s", isns->i_addr);
isns_delete(isns);
return (false);
@@ -609,6 +603,7 @@ isns_new(struct conf *conf, const char *addr)
* those into multiple servers.
*/
+ isns->i_ai = ai.release();
return (true);
}