Skip to content

Commit

Permalink
lib: net_addr2ip() - Optimize for parsing IPv4 addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
sirainen committed Nov 7, 2017
1 parent fade87f commit 3f0c3d5
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/lib/net.c
Expand Up @@ -952,10 +952,48 @@ const char *net_ip2addr(const struct ip_addr *ip)
#endif
}

static bool net_addr2ip_inet4_fast(const char *addr, struct ip_addr *ip)
{
uint8_t *s_addr = (void *)&ip->u.ip4.s_addr;
unsigned int i, num;

if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
if (*addr == '\0' && num <= 0xffffffff) {
/* single-number IPv4 address */
ip->u.ip4.s_addr = htonl(num);
ip->family = AF_INET;
return TRUE;
}

/* try to parse as a.b.c.d */
i = 0;
for (;;) {
if (num >= 256)
return FALSE;
s_addr[i] = num;
if (i == 3)
break;
i++;
if (*addr != '.')
return FALSE;
addr++;
if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
}
if (*addr != '\0')
return FALSE;
ip->family = AF_INET;
return TRUE;
}

int net_addr2ip(const char *addr, struct ip_addr *ip)
{
int ret;

if (net_addr2ip_inet4_fast(addr, ip))
return 0;

if (strchr(addr, ':') != NULL) {
/* IPv6 */
#ifdef HAVE_IPV6
Expand Down
10 changes: 10 additions & 0 deletions src/lib/test-net.c
Expand Up @@ -71,12 +71,22 @@ static void test_net_ip2addr(void)
ip.family == AF_INET &&
ntohl(ip.u.ip4.s_addr) == (0x7f000001));
#ifdef HAVE_IPV6
test_assert(net_addr2ip("2130706433", &ip) == 0 &&
ip.family == AF_INET &&
ntohl(ip.u.ip4.s_addr) == (0x7f000001));
test_assert(strcmp(net_ip2addr(&ip), "127.0.0.1") == 0);
test_assert(net_addr2ip("255.254.253.252", &ip) == 0 &&
ip.family == AF_INET &&
ntohl(ip.u.ip4.s_addr) == (0xfffefdfc));
test_assert(strcmp(net_ip2addr(&ip), "255.254.253.252") == 0);
test_assert(net_addr2ip("::5", &ip) == 0 &&
ip.family == AF_INET6 &&
ip.u.ip6.s6_addr[15] == 5);
test_assert(strcmp(net_ip2addr(&ip), "::5") == 0);
test_assert(net_addr2ip("[::5]", &ip) == 0 &&
ip.family == AF_INET6 &&
ip.u.ip6.s6_addr[15] == 5);
test_assert(strcmp(net_ip2addr(&ip), "::5") == 0);
ip.family = 123;
test_assert(net_addr2ip("abc", &ip) < 0 &&
ip.family == 123);
Expand Down

0 comments on commit 3f0c3d5

Please sign in to comment.