On Tue, Sep 8, 2015 at 7:58 AM, Baptiste <[email protected]> wrote:
>>> Hi,
>>>
>>> I wonder why the code send the TCP port in the DNS query...
>>> I'm currently installing an opnsense and I'll try to reproduce the
>>> problem.
>>>
>>> I've not used FreeBSD since 5.4 version :)
>>>
>>> Baptiste
>>
>> Hi Baptiste,
>>
>> it seems ipv4 and ipv6 are handled differently regarding the removal of the
>> port in server.c and this is apparently done after the initial dns check has
>> already been performed.?. as it knows to treat 'google.com' differently from
>> 'nu.nl'
>>
>>             /* save hostname and create associated name resolution */
>>             switch (sk->ss_family) {
>>             case AF_INET: {
>>                 /* remove the port if any */
>> Alert("\n AF_INET remove the port if any: %s", args[2]);
>>                 char *c;
>>                 if ((c = rindex(args[2], ':')) != NULL) {
>>                     newsrv->hostname = my_strndup(args[2], c - args[2]);
>>                 }
>>                 else {
>>                     newsrv->hostname = strdup(args[2]);
>>                 }
>>             }
>>                 break;
>>             case AF_INET6:
>> Alert("\n AF_INET6   args 2              : %s", args[2]);
>>                 newsrv->hostname = strdup(args[2]);
>>                 break;
>>             default:
>>                 goto skip_name_resolution;
>>             }
>> Alert("\nparse_server newsrv->hostname: %s", newsrv->hostname);
>>
>> Result:
>>  AF_INET6   args 2              : www.google.com:80[ALERT] 249/231349
>> (38431) :
>> parse_server newsrv->hostname: www.google.com:80[ALERT] 249/231349 (38431) :
>>  AF_INET remove the port if any: nu.nl:80[ALERT] 249/231349 (38431) :
>> parse_server newsrv->hostname: nu.nl[ALERT] 249/231349 (38431) :
>>
>> Though the tricky part i guess is that ipv6 can contain ':' in a address to
>> but not in a hostname i would think.. Maybe the question should be why have
>> the different treatment at all?
>>
>> I would expect this to not occur on FreeBSD systems.?
>>
>> Hope it helps investigate the issue.
>>
>> PiBa-NL
>
>
> Hi Piba,
>
> You're right and I think this bug is not linked to FreeBSD at all :)
> I think checking port1 and port2 variables at this moment of the code
> is the best way to go instead of relying on ss_family.
> I'll send you a patch later today for testing purpose.
>
> Baptiste


Hi Piba,

I was able to reproduce the bug on my linux machine (that said, I now
have a nice Freebsd 10.2 running in a virtualbox).
Please apply the patch in attachment and tell me whether it fixes the
issue on your side.

Here is new behavior:
09:28:18.097616 IP 10.0.3.20.40165 > 10.0.1.2.53: 20646+ AAAA?
www.google.com. (32)
09:28:18.098140 IP 10.0.1.2.53 > 10.0.3.20.40165: 20646 1/0/0 AAAA
2a00:1450:4007:805::1014 (60)
09:28:18.098852 IP 10.0.3.20.38413 > 8.8.8.8.53: 61174+ ANY?
www.google.com. (32)
09:28:18.108185 IP 8.8.8.8.53 > 10.0.3.20.38413: 61174 15/0/0 A
159.180.253.42, A 159.180.253.49, A 159.180.253.30, A 159.180.253.53,
A 159.180.253.38, A 159.180.253.57, A 159.180.253.59, A
159.180.253.34, A 159.180.253.27, A 159.180.253.45, A 159.180.253.23,
A 159.180.253.15, A 159.180.253.19, A 159.180.253.29, A 159.180.253.44
(272)

Baptiste
From c5eb4a02ecd6392d727ad7a08dbe483358e52643 Mon Sep 17 00:00:00 2001
From: Baptiste Assmann <[email protected]>
Date: Tue, 8 Sep 2015 09:28:39 +0200
Subject: [PATCH 11/11] MINOR: FIX: hostname parsing error lead TCP port to be
 part of hostname sent in DNS resolution

A corner case could lead configuration parsing of server's hostname to
use the TCP port as part of the hostname. This happens when the first
resolution from libc points to an IPv6 address.

The patch in attachement fix this by relying of the existence of TCP
port instead of IP address family before saving server's hostname.
---
 src/server.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/src/server.c b/src/server.c
index fed180b..d364b5b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -936,23 +936,16 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
 			}
 
 			/* save hostname and create associated name resolution */
-			switch (sk->ss_family) {
-			case AF_INET: {
-				/* remove the port if any */
+			if (!port1 && !port2) {
+				/* no ports set, means no ':' are used to split IP from PORT */
+				newsrv->hostname = strdup(args[2]);
+			}
+			else {
+				/* port set, means ':' is used to split IP from PORT
+				 * We want to copy hostname part only */
 				char *c;
-				if ((c = rindex(args[2], ':')) != NULL) {
+				if ((c = rindex(args[2], ':')) != NULL)
 					newsrv->hostname = my_strndup(args[2], c - args[2]);
-				}
-				else {
-					newsrv->hostname = strdup(args[2]);
-				}
-			}
-				break;
-			case AF_INET6:
-				newsrv->hostname = strdup(args[2]);
-				break;
-			default:
-				goto skip_name_resolution;
 			}
 
 			/* no name resolution if an IP has been provided */
-- 
2.5.0

Reply via email to