Mercurial > dovecot > core-2.2
changeset 22639:da6cf4b7caf4
lib: net_addr2ip() - Optimize for parsing IPv4 addresses
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 04 Nov 2017 01:43:41 +0200 |
parents | 7d5634889da8 |
children | cf23a90cd2ca |
files | src/lib/net.c src/lib/test-net.c |
diffstat | 2 files changed, 48 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/net.c Sat Nov 04 01:42:37 2017 +0200 +++ b/src/lib/net.c Sat Nov 04 01:43:41 2017 +0200 @@ -952,10 +952,48 @@ #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
--- a/src/lib/test-net.c Sat Nov 04 01:42:37 2017 +0200 +++ b/src/lib/test-net.c Sat Nov 04 01:43:41 2017 +0200 @@ -71,12 +71,22 @@ 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);