[MEDIUM] add internal support for IPv6 server addresses

This patch turns internal server addresses to sockaddr_storage to
store IPv6 addresses, and makes the connect() function use it. This
code already works but some caveats with getaddrinfo/gethostbyname
still need to be sorted out while the changes had to be merged at
this stage of internal architecture changes. So for now the config
parser will not emit an IPv6 address yet so that user experience
remains unchanged.

This change should have absolutely zero user-visible effect, otherwise
it's a bug introduced during the merge, that should be reported ASAP.
diff --git a/src/standard.c b/src/standard.c
index 1ab2194..27fa374 100644
--- a/src/standard.c
+++ b/src/standard.c
@@ -219,10 +219,10 @@
  * a host name, or empty or "*" to indicate INADDR_ANY. NULL is returned
  * if the host part cannot be resolved.
  */
-struct sockaddr_in *str2sa(char *str)
+struct sockaddr_storage *str2sa(char *str)
 {
-	static struct sockaddr_in sa;
-	struct sockaddr_in *ret = NULL;
+	static struct sockaddr_storage sa;
+	struct sockaddr_storage *ret = NULL;
 	char *c;
 	int port;
 
@@ -238,17 +238,17 @@
 	else
 		port = 0;
 
+	sa.ss_family = AF_INET;
+	((struct sockaddr_in *)&sa)->sin_port = htons(port);
 	if (*str == '*' || *str == '\0') { /* INADDR_ANY */
-		sa.sin_addr.s_addr = INADDR_ANY;
+		((struct sockaddr_in *)&sa)->sin_addr.s_addr = INADDR_ANY;
 	}
-	else if (!inet_pton(AF_INET, str, &sa.sin_addr)) {
+	else if (!inet_pton(sa.ss_family, str, &((struct sockaddr_in *)&sa)->sin_addr)) {
 		struct hostent *he = gethostbyname(str);
 		if (!he)
 			goto out;
-		sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
+		((struct sockaddr_in *)&sa)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
 	}
-	sa.sin_port   = htons(port);
-	sa.sin_family = AF_INET;
 	ret = &sa;
  out:
 	free(str);
@@ -265,10 +265,10 @@
  * name, or empty or "*" to indicate INADDR_ANY. NULL is returned if the host
  * part cannot be resolved.
  */
-struct sockaddr_in *str2sa_range(char *str, int *low, int *high)
+struct sockaddr_storage *str2sa_range(char *str, int *low, int *high)
 {
-	static struct sockaddr_in sa;
-	struct sockaddr_in *ret = NULL;
+	static struct sockaddr_storage sa;
+	struct sockaddr_storage *ret = NULL;
 	char *c;
 	int portl, porth;
 
@@ -293,17 +293,17 @@
 		porth = 0;
 	}
 
+	sa.ss_family = AF_INET;
+	((struct sockaddr_in *)&sa)->sin_port = htonl(portl);
 	if (*str == '*' || *str == '\0') { /* INADDR_ANY */
-		sa.sin_addr.s_addr = INADDR_ANY;
+		((struct sockaddr_in *)&sa)->sin_addr.s_addr = INADDR_ANY;
 	}
-	else if (!inet_pton(AF_INET, str, &sa.sin_addr)) {
+	else if (!inet_pton(sa.ss_family, str, &((struct sockaddr_in *)&sa)->sin_addr)) {
 		struct hostent *he = gethostbyname(str);
 		if (!he)
 			goto out;
-		sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
+		((struct sockaddr_in *)&sa)->sin_addr = *(struct in_addr *) *(he->h_addr_list);
 	}
-	sa.sin_port   = htons(portl);
-	sa.sin_family = AF_INET;
 	ret = &sa;
 
 	*low = portl;
@@ -387,9 +387,9 @@
 
 
 /*
- * Parse IP address found in url.
+ * Parse IPv4 address found in url.
  */
-int url2ip(const char *addr, struct in_addr *dst)
+int url2ipv4(const char *addr, struct in_addr *dst)
 {
 	int saw_digit, octets, ch;
 	u_char tmp[4], *tp;
@@ -430,18 +430,20 @@
 }
 
 /*
- * Resolve destination server from URL. Convert <str> to a sockaddr_in*.
+ * Resolve destination server from URL. Convert <str> to a sockaddr_storage*.
  */
-int url2sa(const char *url, int ulen, struct sockaddr_in *addr)
+int url2sa(const char *url, int ulen, struct sockaddr_storage *addr)
 {
 	const char *curr = url, *cp = url;
 	int ret, url_code = 0;
 	unsigned int http_code = 0;
 
 	/* Cleanup the room */
-	addr->sin_family = AF_INET;
-	addr->sin_addr.s_addr = 0;
-	addr->sin_port = 0;
+
+	/* FIXME: assume IPv4 only for now */
+	((struct sockaddr_in *)addr)->sin_family = AF_INET;
+	((struct sockaddr_in *)addr)->sin_addr.s_addr = 0;
+	((struct sockaddr_in *)addr)->sin_port = 0;
 
 	/* Firstly, try to find :// pattern */
 	while (curr < url+ulen && url_code != 0x3a2f2f) {
@@ -467,12 +469,12 @@
 			 * be warned this can slow down global daemon performances
 			 * while handling lagging dns responses.
 			 */
-			ret = url2ip(curr, &addr->sin_addr);
+			ret = url2ipv4(curr, &((struct sockaddr_in *)&addr)->sin_addr);
 			if (!ret)
 				return -1;
 			curr += ret;
-			addr->sin_port = (*curr == ':') ? str2uic(++curr) : 80;
-			addr->sin_port = htons(addr->sin_port);
+			((struct sockaddr_in *)addr)->sin_port = (*curr == ':') ? str2uic(++curr) : 80;
+			((struct sockaddr_in *)addr)->sin_port = htons(((struct sockaddr_in *)&addr)->sin_port);
 		}
 		return 0;
 	}