dhcp: cleanup ip4_process_dhclient_rfc3442_routes()

- use nm_utils_strsplit_set_full() instead of g_strsplit_set() to avoid allocating
  a full strv array.
- refactor the code to return early and use cleanup attribute for freeing
  memory.
- return TRUE/FALSE from process_dhclient_rfc3442_route(). It's simpler to
  understand than returning the moved pointer and a success output variable.
This commit is contained in:
Thomas Haller
2019-04-04 12:59:21 +02:00
parent 5c1f93943e
commit a15e70889c

View File

@@ -100,67 +100,56 @@ out:
return have_routes; return have_routes;
} }
static const char ** static gboolean
process_dhclient_rfc3442_route (const char **octets, process_dhclient_rfc3442_route (const char *const**p_octets,
NMPlatformIP4Route *route, NMPlatformIP4Route *route)
gboolean *success)
{ {
const char **o = octets; const char *const*o = *p_octets;
int addr_len = 0, i = 0; gs_free char *next_hop = NULL;
long int tmp; int addr_len;
char *next_hop; int v_plen;
guint32 tmp_addr; in_addr_t tmp_addr;
in_addr_t v_network = 0;
*success = FALSE; v_plen = _nm_utils_ascii_str_to_int64 (*o, 10, 0, 32, -1);
if (v_plen == -1)
if (!*o) return FALSE;
return o; /* no prefix */
tmp = strtol (*o, NULL, 10);
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
return o;
memset (route, 0, sizeof (*route));
route->plen = tmp;
o++; o++;
if (tmp > 0) addr_len = v_plen > 0
addr_len = ((tmp - 1) / 8) + 1; ? ((v_plen - 1) / 8) + 1
: 0;
/* ensure there's at least the address + next hop left */ /* ensure there's at least the address + next hop left */
if (g_strv_length ((char **) o) < addr_len + 4) if (NM_PTRARRAY_LEN (o) < addr_len + 4)
goto error; return FALSE;
if (tmp) { if (v_plen > 0) {
const char *addr[4] = { "0", "0", "0", "0" }; const char *addr[4] = { "0", "0", "0", "0" };
char *str_addr; gs_free char *str_addr = NULL;
int i;
for (i = 0; i < addr_len; i++) for (i = 0; i < addr_len; i++)
addr[i] = *o++; addr[i] = *o++;
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL); str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) { if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0)
g_free (str_addr); return FALSE;
goto error; v_network = nm_utils_ip4_address_clear_host_address (tmp_addr, v_plen);
}
g_free (str_addr);
route->network = nm_utils_ip4_address_clear_host_address (tmp_addr, tmp);
} }
/* Handle next hop */
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL); next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) { o += 4;
g_free (next_hop); if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0)
goto error; return FALSE;
}
route->gateway = tmp_addr;
g_free (next_hop);
*success = TRUE; *route = (NMPlatformIP4Route) {
return o + 4; /* advance to past the next hop */ .network = v_network,
.plen = v_plen,
error: .gateway = tmp_addr,
return o; };
*p_octets = o;
return TRUE;
} }
static gboolean static gboolean
@@ -171,23 +160,23 @@ ip4_process_dhclient_rfc3442_routes (const char *iface,
NMIP4Config *ip4_config, NMIP4Config *ip4_config,
guint32 *gwaddr) guint32 *gwaddr)
{ {
char **octets, **o; gs_free const char **octets = NULL;
const char *const*o;
gboolean have_routes = FALSE; gboolean have_routes = FALSE;
NMPlatformIP4Route route;
gboolean success;
o = octets = g_strsplit_set (str, " .", 0); octets = nm_utils_strsplit_set_with_empty (str, " .");
if (g_strv_length (octets) < 5) { if (NM_PTRARRAY_LEN (octets) < 5) {
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str); _LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str);
goto out; return FALSE;
} }
o = octets;
while (*o) { while (*o) {
memset (&route, 0, sizeof (route)); NMPlatformIP4Route route;
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success);
if (!success) { if (!process_dhclient_rfc3442_route (&o, &route)) {
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes"); _LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes");
break; return have_routes;
} }
have_routes = TRUE; have_routes = TRUE;
@@ -211,8 +200,6 @@ ip4_process_dhclient_rfc3442_routes (const char *iface,
} }
} }
out:
g_strfreev (octets);
return have_routes; return have_routes;
} }