Skip to content

Commit 489c57e

Browse files
authored
Merge pull request #164 from baranyaib90/master
Rewritten hostname extraction from resolver URL
2 parents 977341a + 983e343 commit 489c57e

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

src/logging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ enum LogSeverity {
4444
#define ELOG(...) _log(__FILENAME__, __LINE__, LOG_ERROR, __VA_ARGS__)
4545
#define SLOG(...) _log(__FILENAME__, __LINE__, LOG_STATS, __VA_ARGS__)
4646
#define FLOG(...) do { \
47-
_log(__FILE__, __LINE__, LOG_FATAL, __VA_ARGS__); \
47+
_log(__FILENAME__, __LINE__, LOG_FATAL, __VA_ARGS__); \
4848
exit(1); /* for clang-tidy! */ \
4949
} while(0)
5050

src/main.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,34 +36,33 @@ typedef struct {
3636
struct sockaddr_storage raddr;
3737
} request_t;
3838

39-
// Very very basic hostname parsing.
40-
// Note: Performs basic checks to see if last digit is non-alpha.
41-
// Non-alpha hostnames are assumed to be IP addresses. e.g. foo.1
42-
// Returns non-zero on success, zero on failure.
43-
static int hostname_from_uri(const char* uri,
44-
char* hostname, int hostname_len) {
45-
if (strncmp(uri, "https://", 8) != 0) { return 0; } // not https://
46-
uri += 8;
47-
const char *end = uri;
48-
while (*end && *end != '/') { end++; }
49-
if (end - uri >= hostname_len) {
50-
return 0;
51-
}
52-
if (end == uri) { return 0; } // empty string.
53-
if (!isalpha(*(end - 1))) { return 0; } // last digit non-alpha.
54-
55-
// If using basic authentication in URL, chop off prefix.
56-
char *tmp = strchr(uri, '@');
57-
if (tmp) {
58-
tmp++;
59-
if (tmp < end) {
60-
uri = tmp;
39+
static int is_ipv4_address(char *str) {
40+
struct in6_addr addr;
41+
return inet_pton(AF_INET, str, &addr) == 1;
42+
}
43+
44+
static int hostname_from_url(const char* url_in,
45+
char* hostname, const size_t hostname_len) {
46+
int res = 0;
47+
CURLU *url = curl_url();
48+
if (url != NULL) {
49+
CURLUcode rc = curl_url_set(url, CURLUPART_URL, url_in, 0);
50+
if (rc == CURLUE_OK) {
51+
char *host = NULL;
52+
rc = curl_url_get(url, CURLUPART_HOST, &host, 0);
53+
const size_t host_len = strlen(host);
54+
if (rc == CURLUE_OK && host_len < hostname_len &&
55+
host[0] != '[' && host[host_len-1] != ']' && // skip IPv6 address
56+
!is_ipv4_address(host)) {
57+
strncpy(hostname, host, hostname_len-1); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
58+
hostname[hostname_len-1] = '\0';
59+
res = 1; // success
60+
}
61+
curl_free(host);
6162
}
63+
curl_url_cleanup(url);
6264
}
63-
64-
strncpy(hostname, uri, end - uri); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
65-
hostname[end - uri] = 0;
66-
return 1;
65+
return res;
6766
}
6867

6968
static void signal_shutdown_cb(struct ev_loop *loop,
@@ -298,9 +297,9 @@ int main(int argc, char *argv[]) {
298297
logging_flush_init(loop);
299298

300299
dns_poller_t dns_poller;
301-
char hostname[255]; // Domain names shouldn't exceed 253 chars.
300+
char hostname[255] = {0}; // Domain names shouldn't exceed 253 chars.
302301
if (!proxy_supports_name_resolution(opt.curl_proxy)) {
303-
if (hostname_from_uri(opt.resolver_url, hostname, 254)) {
302+
if (hostname_from_url(opt.resolver_url, hostname, sizeof(hostname))) {
304303
app.using_dns_poller = 1;
305304
dns_poller_init(&dns_poller, loop, opt.bootstrap_dns,
306305
opt.bootstrap_dns_polling_interval, hostname,

0 commit comments

Comments
 (0)