Revert "[SMF] Refactor core address‐resolution to robustly support both IP literals and hostnames (#4008)"

This reverts commit 64bb567aa2.
This commit is contained in:
Sukchan Lee
2025-07-21 16:51:41 +09:00
parent 64bb567aa2
commit a850c4d1d2
4 changed files with 35 additions and 150 deletions

View File

@@ -103,18 +103,11 @@ int ogs_addaddrinfo(ogs_sockaddr_t **sa_list,
int rc;
char service[NI_MAXSERV];
struct addrinfo hints, *ai, *ai_list;
ogs_sockaddr_t *prev = NULL;
/* Last node of original list (for appending) */
ogs_sockaddr_t *tail = NULL;
/* First newly added node (for cleanup on error) */
ogs_sockaddr_t *first_new = NULL;
ogs_sockaddr_t *prev;
char buf[OGS_ADDRSTRLEN];
ogs_assert(sa_list);
/* Prepare hints for getaddrinfo() */
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
@@ -125,41 +118,24 @@ int ogs_addaddrinfo(ogs_sockaddr_t **sa_list,
rc = getaddrinfo(hostname, service, &hints, &ai_list);
if (rc != 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"getaddrinfo(%d:%s:%d:0x%x) failed: %s",
family, hostname ? hostname : "(null)",
port, flags, gai_strerror(rc));
/* Non-fatal: log the error and return */
"getaddrinfo(%d:%s:%d:0x%x) failed",
family, hostname, port, flags);
return OGS_ERROR;
}
/* Find the end of the existing list, so new entries can be appended */
prev = NULL;
if (*sa_list) {
tail = *sa_list;
while (tail->next)
tail = tail->next;
prev = tail;
prev = *sa_list;
while(prev->next) prev = prev->next;
}
/* Iterate over each result from getaddrinfo and add to the linked list */
for (ai = ai_list; ai; ai = ai->ai_next) {
ogs_sockaddr_t *new, tmp;
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue; /* Skip unsupported address families */
continue;
new = ogs_calloc(1, sizeof(ogs_sockaddr_t));
if (!new) {
ogs_error("ogs_calloc() failed");
/* Clean up any partially added entries on memory failure */
if (first_new) {
if (tail) {
/* detach new sub-list from original list */
tail->next = NULL;
} else {
*sa_list = NULL; /* no original list, reset head */
}
ogs_freeaddrinfo(first_new);
}
freeaddrinfo(ai_list);
return OGS_ERROR;
}
memcpy(&new->sa, ai->ai_addr, ai->ai_addrlen);
@@ -167,49 +143,30 @@ int ogs_addaddrinfo(ogs_sockaddr_t **sa_list,
if (hostname) {
if (ogs_inet_pton(ai->ai_family, hostname, &tmp) == OGS_OK) {
/* Input string is a valid numeric IP address */
/* It's a valid IP address */
ogs_debug("addr:%s, port:%d", OGS_ADDR(new, buf), port);
} else {
/* Input string is not a numeric IP; treat it as a hostname */
/* INVALID IP address! We assume it is a hostname */
new->hostname = ogs_strdup(hostname);
if (!new->hostname) {
ogs_error("ogs_strdup() failed");
/* Free the new node and any previously added nodes */
ogs_free(new);
if (first_new) {
if (tail) {
tail->next = NULL;
} else {
*sa_list = NULL;
}
ogs_freeaddrinfo(first_new);
}
freeaddrinfo(ai_list);
return OGS_ERROR;
}
ogs_assert(new->hostname);
ogs_debug("name:%s, port:%d", new->hostname, port);
}
}
/* Link the new node into the list */
if (!prev) {
if (!prev)
*sa_list = new;
} else {
else
prev->next = new;
}
prev = new;
if (!first_new) {
first_new = new; /* mark the first new node added */
}
}
freeaddrinfo(ai_list);
if (first_new == NULL) {
/* No addresses were added (e.g., no AF_INET/AF_INET6 results) */
if (prev == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"ogs_addaddrinfo(%d:%s:%d:0x%x) returned no addresses",
family, hostname ? hostname : "(null)", port, flags);
"ogs_getaddrinfo(%d:%s:%d:%d) failed",
family, hostname, port, flags);
return OGS_ERROR;
}
@@ -843,37 +800,3 @@ char *ogs_sockaddr_to_string_static(ogs_sockaddr_t *sa_list)
/* No address */
return NULL;
}
int ogs_sockaddr_from_ip_or_fqdn(ogs_sockaddr_t **sa_list,
int family, const char *ip_or_fqdn, uint16_t port)
{
int rc;
int flags = 0;
ogs_sockaddr_t tmp;
ogs_assert(sa_list);
ogs_assert(ip_or_fqdn);
/* Determine if the input is an IP literal (numeric address).
* If so, use AI_NUMERICHOST to avoid DNS lookup. */
if (ogs_inet_pton(AF_INET, ip_or_fqdn, &tmp) == OGS_OK ||
ogs_inet_pton(AF_INET6, ip_or_fqdn, &tmp) == OGS_OK) {
flags |= AI_NUMERICHOST;
}
/* Use ogs_addaddrinfo
* to perform resolution and construct the sockaddr list */
*sa_list = NULL;
rc = ogs_addaddrinfo(sa_list, family, ip_or_fqdn, port, flags);
if (rc != OGS_OK) {
ogs_error("Failed to resolve address: %s", ip_or_fqdn);
/* Cleanup: free any nodes that might have been added before failure */
if (*sa_list) {
ogs_freeaddrinfo(*sa_list);
*sa_list = NULL;
}
return OGS_ERROR;
}
return OGS_OK;
}

View File

@@ -123,8 +123,6 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub,
char *ogs_gethostname(ogs_sockaddr_t *addr);
char *ogs_ipstrdup(ogs_sockaddr_t *addr);
char *ogs_sockaddr_to_string_static(ogs_sockaddr_t *sa_list);
int ogs_sockaddr_from_ip_or_fqdn(ogs_sockaddr_t **sa_list,
int family, const char *ip_or_fqdn, uint16_t port);
#ifdef __cplusplus
}

View File

@@ -111,8 +111,6 @@ void smf_context_init(void)
void smf_context_final(void)
{
int i;
ogs_gtp_node_t *gnode = NULL, *next_gnode = NULL;
ogs_assert(context_initialized == 1);
@@ -145,11 +143,6 @@ void smf_context_final(void)
ogs_gtp_node_remove(&self.sgw_s5c_list, gnode);
}
for (i = 0; i < self.num_of_p_cscf; i++)
ogs_free(self.p_cscf[i]);
for (i = 0; i < self.num_of_p_cscf6; i++)
ogs_free(self.p_cscf6[i]);
ogs_pool_final(&smf_gtp_node_pool);
context_initialized = 0;
@@ -560,63 +553,34 @@ int smf_context_parse_config(void)
self.num_of_p_cscf6 = 0;
do {
const char *v = NULL;
ogs_sockaddr_t *resolved_list = NULL;
ogs_sockaddr_t *cur = NULL;
char buf[OGS_ADDRSTRLEN];
int res;
if (ogs_yaml_iter_type(&p_cscf_iter) ==
YAML_SEQUENCE_NODE) {
if (!ogs_yaml_iter_next(&p_cscf_iter))
break;
}
v = ogs_yaml_iter_value(&p_cscf_iter);
if (!v) {
ogs_error("No value for P-CSCF in configuration");
continue;
}
if (v) {
ogs_ipsubnet_t ipsub;
rv = ogs_ipsubnet(&ipsub, v, NULL);
ogs_assert(rv == OGS_OK);
/* Use the new API to resolve IP or FQDN
* into one or more addresses */
res = ogs_sockaddr_from_ip_or_fqdn(
&resolved_list, AF_UNSPEC, v, 0);
if (res != OGS_OK || !resolved_list) {
ogs_error("Failed to resolve P-CSCF address: %s",
v);
continue; /* Skip this entry and move to the next */
if (ipsub.family == AF_INET) {
if (self.num_of_p_cscf >= MAX_NUM_OF_P_CSCF)
ogs_warn("Ignore P-CSCF : %s", v);
else self.p_cscf[self.num_of_p_cscf++] = v;
}
/* Iterate through all resolved addresses
* and store them */
for (cur = resolved_list; cur; cur = cur->next) {
if (cur->ogs_sa_family == AF_INET) {
if (self.num_of_p_cscf < MAX_NUM_OF_P_CSCF) {
self.p_cscf[self.num_of_p_cscf++] =
ogs_ipstrdup(cur);
} else {
ogs_warn("Ignore P-CSCF IPv4 "
"(max %d reached): %s",
MAX_NUM_OF_P_CSCF,
OGS_ADDR(cur, buf));
else if (ipsub.family == AF_INET6) {
if (self.num_of_p_cscf6 >= MAX_NUM_OF_P_CSCF)
ogs_warn("Ignore P-CSCF : %s", v);
else self.p_cscf6[self.num_of_p_cscf6++] = v;
} else
ogs_warn("Ignore P-CSCF : %s", v);
}
} else if (cur->ogs_sa_family == AF_INET6) {
if (self.num_of_p_cscf6 < MAX_NUM_OF_P_CSCF) {
self.p_cscf6[self.num_of_p_cscf6++] =
ogs_ipstrdup(cur);
} else {
ogs_warn("Ignore P-CSCF IPv6 "
"(max %d reached): %s",
MAX_NUM_OF_P_CSCF,
OGS_ADDR(cur, buf));
}
}
}
/* free the linked list */
ogs_freeaddrinfo(resolved_list);
} while (ogs_yaml_iter_type(&p_cscf_iter) ==
YAML_SEQUENCE_NODE);
} else if (!strcmp(smf_key, "info")) {
ogs_sbi_nf_instance_t *nf_instance = NULL;

View File

@@ -129,10 +129,10 @@ typedef struct smf_context_s {
const char *dns6[MAX_NUM_OF_DNS];
#define MAX_NUM_OF_P_CSCF 16
char *p_cscf[MAX_NUM_OF_P_CSCF];
const char *p_cscf[MAX_NUM_OF_P_CSCF];
int num_of_p_cscf;
int p_cscf_index;
char *p_cscf6[MAX_NUM_OF_P_CSCF];
const char *p_cscf6[MAX_NUM_OF_P_CSCF];
int num_of_p_cscf6;
int p_cscf6_index;