The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f61f75771f95b59fdbc6ebd71b8da9407374ad44

commit f61f75771f95b59fdbc6ebd71b8da9407374ad44
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2025-08-04 19:38:07 +0000
Commit:     John Baldwin <j...@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);
 }
 

Reply via email to