BUG/MEDIUM: dns: Consider the fact that dns answers are case-insensitive

We can't expect the DNS answer to always match the case we used for the
request, so we can't just use memcmp() to compare the DNS answer with what
we are expected.
Instead, introduce dns_hostname_cmp(), which compares each string in a
case-insensitive way.
This should fix github issue #566.

This should be backported to 2.1, 2.0, 1.9 and 1.8.
diff --git a/src/dns.c b/src/dns.c
index 953f941..38f73c1 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -77,6 +77,19 @@
 	return NULL;
 }
 
+/* Compare hostnames in a case-insensitive way .
+ * Returns 0 if they are the same, non-zero otherwise
+ */
+static __inline int dns_hostname_cmp(const char *name1, const char *name2, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		if (tolower(name1[i]) != tolower(name2[i]))
+			return -1;
+	return 0;
+}
+
 /* Returns a pointer on the SRV request matching the name <name> for the proxy
  * <px>. NULL is returned if no match is found.
  */
@@ -540,7 +553,7 @@
 					HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
 					if (srv->srvrq == srvrq && srv->svc_port == item->port &&
 					    item->data_len == srv->hostname_dn_len &&
-					    !memcmp(srv->hostname_dn, item->target, item->data_len)) {
+					    !dns_hostname_cmp(srv->hostname_dn, item->target, item->data_len)) {
 						snr_update_srv_status(srv, 1);
 						free(srv->hostname);
 						free(srv->hostname_dn);
@@ -572,7 +585,7 @@
 				HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
 				if (srv->srvrq == srvrq && srv->svc_port == item->port &&
 				    item->data_len == srv->hostname_dn_len &&
-				    !memcmp(srv->hostname_dn, item->target, item->data_len) &&
+				    !dns_hostname_cmp(srv->hostname_dn, item->target, item->data_len) &&
 				    !srv->dns_opts.ignore_weight) {
 					int ha_weight;
 
@@ -820,7 +833,7 @@
 
 		/* Check if the current record dname is valid.  previous_dname
 		 * points either to queried dname or last CNAME target */
-		if (dns_query->type != DNS_RTYPE_SRV && memcmp(previous_dname, tmpname, len) != 0) {
+		if (dns_query->type != DNS_RTYPE_SRV && dns_hostname_cmp(previous_dname, tmpname, len) != 0) {
 			pool_free(dns_answer_item_pool, dns_answer_record);
 			if (i == 0) {
 				/* First record, means a mismatch issue between
@@ -999,7 +1012,7 @@
 
 			case DNS_RTYPE_SRV:
                                 if (dns_answer_record->data_len == tmp_record->data_len &&
-				    !memcmp(dns_answer_record->target, tmp_record->target, dns_answer_record->data_len) &&
+				    !dns_hostname_cmp(dns_answer_record->target, tmp_record->target, dns_answer_record->data_len) &&
 				    dns_answer_record->port == tmp_record->port) {
 					tmp_record->weight = dns_answer_record->weight;
                                         found = 1;
@@ -1179,7 +1192,7 @@
 				if ( !(
 					(tmp_record->type == DNS_RTYPE_SRV) &&
 					(tmp_record->ar_item == NULL) &&
-					(memcmp(tmp_record->target, dns_answer_record->name, tmp_record->data_len) == 0)
+					(dns_hostname_cmp(tmp_record->target, dns_answer_record->name, tmp_record->data_len) == 0)
 				      )
 				   )
 					continue;
@@ -1520,7 +1533,7 @@
 			continue;
 		if ((query_type == res->prefered_query_type) &&
 		    hostname_dn_len == res->hostname_dn_len  &&
-		    !memcmp(*hostname_dn, res->hostname_dn, hostname_dn_len))
+		    !dns_hostname_cmp(*hostname_dn, res->hostname_dn, hostname_dn_len))
 			return res;
 	}
 
@@ -1530,7 +1543,7 @@
 			continue;
 		if ((query_type == res->prefered_query_type) &&
 		    hostname_dn_len == res->hostname_dn_len  &&
-		    !memcmp(*hostname_dn, res->hostname_dn, hostname_dn_len))
+		    !dns_hostname_cmp(*hostname_dn, res->hostname_dn, hostname_dn_len))
 			return res;
 	}
 
@@ -1897,7 +1910,7 @@
 		 * sent. We can check only the first query of the list. We send
 		 * one query at a time so we get one query in the response */
 		query = LIST_NEXT(&res->response.query_list, struct dns_query_item *, list);
-		if (query && memcmp(query->name, res->hostname_dn, res->hostname_dn_len) != 0) {
+		if (query && dns_hostname_cmp(query->name, res->hostname_dn, res->hostname_dn_len) != 0) {
 			dns_resp = DNS_RESP_WRONG_NAME;
 			ns->counters.other++;
 			goto report_res_error;