git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	Eric Wong <normalperson@yhbt.net>,
	Erik Faye-Lund <kusmabite@gmail.com>,
	Richard Hartmann <richih.mailinglist@gmail.com>
Subject: [PATCH 8/5] srv: tolerate broken DNS replies
Date: Thu, 8 Mar 2012 07:23:39 -0600	[thread overview]
Message-ID: <20120308132339.GH9426@burratino> (raw)
In-Reply-To: <20120308124857.GA7666@burratino>

At a hotel with a very broken Wi-Fi setup, Richard found his copy
of git unable to cope:

	% git clone git://git.kitenet.net/mr
	Cloning into 'mr'...
	error: cannot initialize DNS parser: Message too long
	fatal: Unable to look up git.kitenet.net

Other programs gave some warnings but otherwise worked fine.  From a
packet capture, it seems that the response to a SRV query for
_git._tcp.git.kitenet.net in this setup was a single A resource record
pointing to the link-local address 169.254.1.1, followed by two
trailing bytes: c0 1a.  The trailing bytes cause the underlying parser
to fail.

It would not be good to silently tolerate this and similar kinds of
brokenness, but working around it would help people on affected
systems to recover.  Luckily RFC2782 gives us enough leeway to act as
we please for this particular kind of error, so give a warning and
fall back to an A/AAAA query (which should work).

Similarly, if we receive non-SRV RRs in response to a SRV query,
RFC2782 does not say to error out, so in the spirit of graceful
degradation let's warn and skip those records.

Reported-by: Richard Hartmann <richih.mailinglist@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Thanks for reading.  That's the end of the series.

Good night,
Jonathan

 srv.c |   40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/srv.c b/srv.c
index 2716206e..829ef762 100644
--- a/srv.c
+++ b/srv.c
@@ -83,7 +83,6 @@ static int srv_parse(ns_msg *msg, struct parsed_srv_rr **res)
 {
 	struct parsed_srv_rr *rrs = NULL;
 	int nr_parsed = 0;
-	int cnames = 0;
 	int i, n;
 
 	n = ns_msg_count(*msg, ns_s_an);
@@ -98,30 +97,33 @@ static int srv_parse(ns_msg *msg, struct parsed_srv_rr **res)
 		if (ns_rr_type(rr) != ns_t_cname)
 			break;
 	}
-	cnames = i;
-	n -= cnames;
 
-	rrs = xmalloc(n * sizeof(*rrs));
-	for (i = 0; i < n; i++) {
+	rrs = xmalloc((n - i) * sizeof(*rrs));
+	for (; i < n; i++) {
 		ns_rr rr;
 
-		if (ns_parserr(msg, ns_s_an, cnames + i, &rr)) {
+		if (ns_parserr(msg, ns_s_an, i, &rr)) {
 			error("cannot parse DNS RR: %s", strerror(errno));
 			goto fail;
 		}
 		if (ns_rr_type(rr) != ns_t_srv) {
-			error("expected SRV RR, found RR type %d",
+			/*
+			 * Maybe the server is playing tricks and returned
+			 * an A record.  Let it pass and if we don't get
+			 * any SRV RRs, we can fall back to an A lookup.
+			 */
+			warning("expected SRV RR, found RR type %d",
 						(int) ns_rr_type(rr));
-			goto fail;
+			continue;
 		}
-		if (srv_parse_rr(msg, &rr, rrs + i))
+		if (srv_parse_rr(msg, &rr, rrs + nr_parsed))
 			/* srv_parse_rr writes a message */
 			goto fail;
 		nr_parsed++;
 	}
 
 	*res = rrs;
-	return n;
+	return nr_parsed;
 fail:
 	for (i = 0; i < nr_parsed; i++)
 		free(rrs[i].target);
@@ -274,13 +276,23 @@ int get_srv(const char *host, struct host **hosts)
 	if (len < 0)
 		goto out;
 
+	/*
+	 * If the reply to a SRV query is malformed, fall back to an
+	 * A query.
+	 *
+	 * The RFC2782 usage rules don't say anything about this, but
+	 * in practice, it seems that some firewalls or DNS servers
+	 * (think: captive portal) handle A queries sensibly and
+	 * provide malformed replies in response to SRV queries.
+	 */
+	if (ns_initparse(buf, len, &msg)) {
+		warning("cannot parse SRV response: %s", strerror(errno));
+		goto out;
+	}
+
 	/* If a SRV RR cannot be parsed, give up. */
 	ret = -1;
 
-	if (ns_initparse(buf, len, &msg)) {
-		error("cannot initialize DNS parser: %s", strerror(errno));
-		goto out;
-	}
 	n = srv_parse(&msg, &rrs);
 	if (n < 0)
 		/* srv_parse writes a message */
-- 
1.7.9.2

  parent reply	other threads:[~2012-03-08 13:23 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-08 12:48 [PATCH 0/5] transport: unify ipv4 and ipv6 code paths Jonathan Nieder
2012-03-08 13:03 ` [PATCH 1/5] transport: expose git_tcp_connect() and friends in new tcp.h Jonathan Nieder
2012-03-08 15:28   ` Erik Faye-Lund
2012-03-08 13:05 ` [PATCH 2/5] daemon: make host resolution a separate function Jonathan Nieder
2012-03-08 13:06 ` [PATCH 3/5] daemon: move locate_host() to tcp lib Jonathan Nieder
2012-03-08 13:09 ` [PATCH 4/5] tcp: unify ipv4 and ipv6 code paths Jonathan Nieder
2012-03-08 15:39   ` Erik Faye-Lund
2012-03-08 21:10     ` Jonathan Nieder
2012-03-08 13:11 ` [PATCH 5/5] daemon: check for errors retrieving IP address Jonathan Nieder
2012-03-08 13:16 ` [PATCH 6/5] tcp: make dns_resolve() return an error code Jonathan Nieder
2012-03-08 13:21 ` [PATCH 7/5] transport: optionally honor DNS SRV records Jonathan Nieder
2012-03-08 16:18   ` Erik Faye-Lund
2012-03-08 21:35     ` Jonathan Nieder
2012-03-09  7:07       ` Johannes Sixt
2012-03-09  8:00         ` Jonathan Nieder
2012-03-08 13:23 ` Jonathan Nieder [this message]
2012-03-08 22:28   ` [PATCH 8/5] srv: tolerate broken DNS replies Richard Hartmann
2012-06-11 18:12 ` [PATCH 0/5] transport: unify ipv4 and ipv6 code paths Erik Faye-Lund
2012-06-11 18:59   ` Junio C Hamano
2012-06-14  5:02   ` Jonathan Nieder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120308132339.GH9426@burratino \
    --to=jrnieder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kusmabite@gmail.com \
    --cc=normalperson@yhbt.net \
    --cc=peff@peff.net \
    --cc=richih.mailinglist@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).