From nobody Mon Aug 4 19:46:44 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bwnBF2lwfz63RcM; Mon, 04 Aug 2025 19:46:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bwnBD6w0Dz4KVr; Mon, 04 Aug 2025 19:46:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754336805; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=etkLKq3t8rwmne/RSZHufAkgPqPZhJaeGUdFWXL20n0=; b=FdMUQAtWdscIvGXlg3T+B8P9FE87fbGHAlwL5a/3gjgU4NKZO6tGuJQ23UUV++oaR4ZFL5 gSaBL9TvMXfPpmCZcB2i04I7v0d6Qb8o6e9/n33poWTHxubqIb1gb6Wuc1G+hOLcitCBbf P5CmJlQrPiAjpbC7GdODnJYnGscwQwjzoa13pyDBD63uyDN3obly+b8VabQh57lo29pNdp NRJJcEWOYfr/aSLJjfPlESGDGeJDP3cDIG8GDgF0ZrJBEjF3sg2vV1sS4Y4BN8bI7bamnU rwL3MxwyULhjCBVE8V9yC++8ys203nb5QwL8WgxkoFDra4PyitZqdvmHvE9pTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754336805; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=etkLKq3t8rwmne/RSZHufAkgPqPZhJaeGUdFWXL20n0=; b=AEay9POY1KM47LXMdDG3WYks7VmbBnwyxAW9lAf/ZvOlNBOtVuXJ8HlCsqLkSjbfJCnZSR PdQQ+K22dyR7aWpM4h6haKKvqC4WGQWodP40RKHpdNURYYZUnXJVJFm+jhjWYCzcytruAf 9WsX0ZEuZGVJExFY2c3T48NIOXwbJoSrCkb17Ve9droXFaOmQpDSYkWjLpWOkKSpFAZGqp xZdlVQHO4E/VSikjEIFZwQIIfdAHfNQuyGktJ2KAR1xwikkSQYcAfW/1IsVFPAOti9zGOR q2Bi3GMdfy0fsMzpZoDyZcezyYazDEqc1w3Adst1iS0y2qPscKyOCcVPm4MUcQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1754336805; a=rsa-sha256; cv=none; b=LPhZBhcVRmPmvKkQMIvHikbja7SZqlIwp/YndniKxlv2E8BNhwdaOqde+4Uxq+MWpJs3Zd iA/HrdV2VFLvwCcWLlIG50ngsx3l+1pKMoBd/2yE+/B6o/AuOpCeahdEPMs0BCHTIkBnVP G59KMLn79BxehvocYdF10Rz81r7no6nSWNRpEHgLwKALIIW5ZlrA32vDV/3E38ZmF5ZA2Y P6gTrdHUPPLt91/bWpcTA8rhdE1WEVMjZa9gtFzvJD/aNkMEc3G7R8GJOkt7Bct+sFDjC4 /gftEBMQF68HxTxWUOG96hOSLeaGP/WyF1ua1VQr6wOW4fOb4VOvsjxquNZgWA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bwnBD60KFz12nK; Mon, 04 Aug 2025 19:46:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 574Jki7i098959; Mon, 4 Aug 2025 19:46:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 574JkiNj098956; Mon, 4 Aug 2025 19:46:44 GMT (envelope-from git) Date: Mon, 4 Aug 2025 19:46:44 GMT Message-Id: <202508041946.574JkiNj098956@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: ccb188268565 - main - ctld: Convert struct auth_portal to a C++ class List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ccb188268565a89c7f3649eccfd80e0fe7279e31 Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=ccb188268565a89c7f3649eccfd80e0fe7279e31 commit ccb188268565a89c7f3649eccfd80e0fe7279e31 Author: John Baldwin AuthorDate: 2025-08-04 19:38:06 +0000 Commit: John Baldwin CommitDate: 2025-08-04 19:38:06 +0000 ctld: Convert struct auth_portal to a C++ class Pull logic to parse a portal address string into a sockaddr and mask into a parse() method. Reimplement the logic using operations on C++ std::string's instead of C string parsing. Pull logic from inside the loop in auth_portal_find() to compare a candidate socket address against a portal into a matches() method. Use a std::list of auth_portal objects instead of a TAILQ in struct auth_group. Sponsored by: Chelsio Communications Pull Request: https://github.com/freebsd/freebsd-src/pull/1794 --- usr.sbin/ctld/ctld.cc | 190 +++++++++++++++++++++++--------------------------- usr.sbin/ctld/ctld.hh | 23 +++--- 2 files changed, 100 insertions(+), 113 deletions(-) diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc index 3ddccbfdb20e..396b8db13323 100644 --- a/usr.sbin/ctld/ctld.cc +++ b/usr.sbin/ctld/ctld.cc @@ -51,6 +51,8 @@ #include #include +#include + #include "conf.h" #include "ctld.hh" #include "isns.hh" @@ -241,135 +243,127 @@ auth_name_check(const struct auth_group *ag, const char *initiator_name) } bool -auth_portal_new(struct auth_group *ag, const char *portal) +auth_portal::parse(const char *portal) { - struct auth_portal *ap; - char *net, *mask, *str, *tmp; - int len, dm, m; + std::string net(portal); + std::string mask; - ap = reinterpret_cast(calloc(1, sizeof(*ap))); - if (ap == NULL) - log_err(1, "calloc"); - ap->ap_auth_group = ag; - ap->ap_initiator_portal = checked_strdup(portal); - mask = str = checked_strdup(portal); - net = strsep(&mask, "/"); - if (net[0] == '[') { - net++; - len = strlen(net); + /* Split into 'net' (address) and 'mask'. */ + size_t pos = net.find('/'); + if (pos != net.npos) { + mask = net.substr(pos + 1); + if (mask.empty()) + return false; + net.resize(pos); + } + if (net.empty()) + return false; + + /* + * If 'net' starts with a '[', ensure it ends with a ']' and + * force interpreting the address as IPv6. + */ + bool brackets = net[0] == '['; + if (brackets) { + net.erase(0, 1); + + size_t len = net.length(); if (len < 2) - goto error; + return false; if (net[len - 1] != ']') - goto error; - net[len - 1] = 0; - } else if (net[0] == '\0') - goto error; - if (str[0] == '[' || strchr(net, ':') != NULL) { + return false; + net.resize(len - 1); + } + + /* Parse address from 'net' and set default mask. */ + if (brackets || net.find(':') != net.npos) { struct sockaddr_in6 *sin6 = - (struct sockaddr_in6 *)&ap->ap_sa; + (struct sockaddr_in6 *)&ap_sa; sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; - if (inet_pton(AF_INET6, net, &sin6->sin6_addr) <= 0) - goto error; - dm = 128; + if (inet_pton(AF_INET6, net.c_str(), &sin6->sin6_addr) <= 0) + return false; + ap_mask = sizeof(sin6->sin6_addr) * 8; } else { struct sockaddr_in *sin = - (struct sockaddr_in *)&ap->ap_sa; + (struct sockaddr_in *)&ap_sa; sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; - if (inet_pton(AF_INET, net, &sin->sin_addr) <= 0) - goto error; - dm = 32; - } - if (mask != NULL) { - if (mask[0] == '\0') - goto error; - m = strtol(mask, &tmp, 0); - if (m < 0 || m > dm || tmp[0] != 0) - goto error; - } else - m = dm; - ap->ap_mask = m; - free(str); - TAILQ_INSERT_TAIL(&ag->ag_portals, ap, ap_next); - return (true); - -error: - free(str); - free(ap); - log_warnx("incorrect initiator portal \"%s\"", portal); - return (false); -} + if (inet_pton(AF_INET, net.c_str(), &sin->sin_addr) <= 0) + return false; + ap_mask = sizeof(sin->sin_addr) * 8; + } -static void -auth_portal_delete(struct auth_portal *ap) -{ - TAILQ_REMOVE(&ap->ap_auth_group->ag_portals, ap, ap_next); + /* Parse explicit mask if present. */ + if (!mask.empty()) { + char *tmp; + long m = strtol(mask.c_str(), &tmp, 0); + if (m < 0 || m > ap_mask || tmp[0] != 0) + return false; + ap_mask = m; + } - free(ap->ap_initiator_portal); - free(ap); + return true; } bool -auth_portal_defined(const struct auth_group *ag) +auth_portal_new(struct auth_group *ag, const char *portal) { - if (TAILQ_EMPTY(&ag->ag_portals)) + auth_portal ap; + if (!ap.parse(portal)) { + log_warnx("invalid initiator portal \"%s\"", portal); return (false); + } + + ag->ag_portals.emplace_back(ap); return (true); } -const struct auth_portal * -auth_portal_find(const struct auth_group *ag, const struct sockaddr_storage *ss) +bool +auth_portal::matches(const struct sockaddr *sa) const { - const struct auth_portal *ap; const uint8_t *a, *b; int i; - uint8_t bmask; - TAILQ_FOREACH(ap, &ag->ag_portals, ap_next) { - if (ap->ap_sa.ss_family != ss->ss_family) - continue; - if (ss->ss_family == AF_INET) { - a = (const uint8_t *) - &((const struct sockaddr_in *)ss)->sin_addr; - b = (const uint8_t *) - &((const struct sockaddr_in *)&ap->ap_sa)->sin_addr; - } else { - a = (const uint8_t *) - &((const struct sockaddr_in6 *)ss)->sin6_addr; - b = (const uint8_t *) - &((const struct sockaddr_in6 *)&ap->ap_sa)->sin6_addr; - } - for (i = 0; i < ap->ap_mask / 8; i++) { - if (a[i] != b[i]) - goto next; - } - if (ap->ap_mask % 8) { - bmask = 0xff << (8 - (ap->ap_mask % 8)); - if ((a[i] & bmask) != (b[i] & bmask)) - goto next; - } - return (ap); -next: - ; - } + if (ap_sa.ss_family != sa->sa_family) + return (false); - return (NULL); + if (sa->sa_family == AF_INET) { + a = (const uint8_t *) + &((const struct sockaddr_in *)sa)->sin_addr; + b = (const uint8_t *) + &((const struct sockaddr_in *)&ap_sa)->sin_addr; + } else { + a = (const uint8_t *) + &((const struct sockaddr_in6 *)sa)->sin6_addr; + b = (const uint8_t *) + &((const struct sockaddr_in6 *)&ap_sa)->sin6_addr; + } + for (i = 0; i < ap_mask / 8; i++) { + if (a[i] != b[i]) + return (false); + } + if ((ap_mask % 8) != 0) { + uint8_t bmask = 0xff << (8 - (ap_mask % 8)); + if ((a[i] & bmask) != (b[i] & bmask)) + return (false); + } + return (true); } bool -auth_portal_check(const struct auth_group *ag, const struct sockaddr_storage *sa) +auth_portal_check(const struct auth_group *ag, + const struct sockaddr_storage *sa) { - - if (!auth_portal_defined(ag)) + if (ag->ag_portals.empty()) return (true); - if (auth_portal_find(ag, sa) == NULL) - return (false); - - return (true); + for (const auth_portal &ap : ag->ag_portals) + if (ap.matches((const struct sockaddr *)sa)) + return (true); + return (false); } static struct auth_group * @@ -381,7 +375,6 @@ auth_group_create(struct conf *conf, const char *name, char *label) if (name != NULL) ag->ag_name = checked_strdup(name); ag->ag_label = label; - TAILQ_INIT(&ag->ag_portals); ag->ag_conf = conf; TAILQ_INSERT_TAIL(&conf->conf_auth_groups, ag, ag_next); @@ -416,13 +409,8 @@ auth_group_new(struct conf *conf, struct target *target) void auth_group_delete(struct auth_group *ag) { - struct auth_portal *auth_portal, *auth_portal_tmp; - TAILQ_REMOVE(&ag->ag_conf->conf_auth_groups, ag, ag_next); - TAILQ_FOREACH_SAFE(auth_portal, &ag->ag_portals, ap_next, - auth_portal_tmp) - auth_portal_delete(auth_portal); free(ag->ag_label); free(ag->ag_name); delete ag; diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh index 339793e90bf1..06b932a65453 100644 --- a/usr.sbin/ctld/ctld.hh +++ b/usr.sbin/ctld/ctld.hh @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -74,11 +75,12 @@ private: }; struct auth_portal { - TAILQ_ENTRY(auth_portal) ap_next; - struct auth_group *ap_auth_group; - char *ap_initiator_portal; + bool matches(const struct sockaddr *sa) const; + bool parse(const char *portal); + +private: struct sockaddr_storage ap_sa; - int ap_mask; + int ap_mask = 0; }; #define AG_TYPE_UNKNOWN 0 @@ -95,7 +97,7 @@ struct auth_group { int ag_type; std::unordered_map ag_auths; std::unordered_set ag_names; - TAILQ_HEAD(, auth_portal) ag_portals; + std::list ag_portals; }; struct portal { @@ -286,13 +288,10 @@ bool auth_name_new(struct auth_group *ag, bool auth_name_check(const struct auth_group *ag, const char *initiator_name); -bool auth_portal_new(struct auth_group *ag, - const char *initiator_portal); -bool auth_portal_defined(const struct auth_group *ag); -const struct auth_portal *auth_portal_find(const struct auth_group *ag, - const struct sockaddr_storage *sa); -bool auth_portal_check(const struct auth_group *ag, - const struct sockaddr_storage *sa); +bool auth_portal_new(struct auth_group *ag, + const char *initiator_portal); +bool auth_portal_check(const struct auth_group *ag, + const struct sockaddr_storage *sa); struct portal_group *portal_group_new(struct conf *conf, const char *name); void portal_group_delete(struct portal_group *pg);