diff src/lib/net.c @ 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 cb108f786fb4
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