commit - 798e1c954749cdd5b3042212050c8ddae75a9c52
commit + 35a316069c85713fae74d8ddf6c60836c6efe51f
blob - 6d8e0e4e3262ab70488c88ff0cdbc9e1f647b5a8
blob + 3c3ef2b25073fa35c11b4a797d284cca9515cab5
--- net.c
+++ net.c
# include <asr.h>
#endif
+#define DNS_RDATACLASS_IN 1
+#define DNS_RDATATYPE_TXT 16
+
#include "telescope.h"
static struct imsgev *iev_ui;
static void try_to_connect(int, short, void*);
+static void offline_dns_done(struct rrsetinfo *, struct req *);
+static void offline_dns_query(struct req *);
+
#if HAVE_ASR_RUN
static void query_done(struct asr_result*, void*);
static void async_conn_towards(struct req*);
+static void offline_query_done(struct asr_result *, void *);
#else
static void blocking_conn_towards(struct req*);
#endif
err:
freeaddrinfo(req->servinfo);
- close_with_errf(req, "failed to connect to %s",
- req->url.host);
+ offline_dns_query(req);
return;
done:
default:
die();
+ }
+}
+
+static void
+offline_dns_done(struct rrsetinfo *res, struct req *req)
+{
+ size_t i, len;
+ const char *reason = NULL;
+
+ for (i = 0; i < res->rri_nrdatas; ++i) {
+ if (res->rri_rdatas[i].rdi_length <= 1)
+ continue;
+
+ len = *(uint8_t*)res->rri_rdatas[i].rdi_data;
+ reason = res->rri_rdatas[i].rdi_data+1;
+ break;
+ }
+
+ if (reason == NULL)
+ close_with_errf(req, "failed to connect to %s", req->url.host);
+ else
+ close_with_errf(req,
+ "failed to connect to %s\n\nThe site says: %*s\n",
+ req->url.host, (int)len, reason);
+
+ freerrset(res);
+}
+
+static void
+offline_dns_query(struct req *req)
+{
+ char hostname[254];
+
+ strlcpy(hostname, "_offline.", sizeof(hostname));
+ strlcat(hostname, req->url.host, sizeof(hostname));
+
+#if HAVE_ASR_RUN
+ {
+ struct asr_query *q;
+
+ q = getrrsetbyname_async(hostname, DNS_RDATACLASS_IN,
+ DNS_RDATATYPE_TXT, 0, NULL);
+ req->asrev = event_asr_run(q, offline_query_done, req);
}
+#else
+ {
+ struct rrsetinfo *res;
+
+ if (getrrsetbyname(hostname, DNS_RDATACLASS_IN,
+ DNS_RDATATYPE_TXT, 0, &res))
+ close_with_errf(req, "failed to connect to %s",
+ req->url.host);
+ else
+ offline_dns_done(res, req);
+ }
+#endif
}
#if HAVE_ASR_RUN
q = getaddrinfo_async(req->url.host, proto, &req->hints, NULL);
req->asrev = event_asr_run(q, query_done, req);
}
+
+static void
+offline_query_done(struct asr_result *res, void *d)
+{
+ struct req *req = d;
+
+ req->asrev = NULL;
+ if (res->ar_rrset_errno != 0) {
+ close_with_errf(req, "failed to resolve %s", req->url.host);
+ return;
+ }
+
+ offline_dns_done(res->ar_rrsetinfo, req);
+}
+
#else
static void
blocking_conn_towards(struct req *req)