Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewritten hostname extraction from resolver URL #164

Merged
merged 1 commit into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ enum LogSeverity {
#define ELOG(...) _log(__FILENAME__, __LINE__, LOG_ERROR, __VA_ARGS__)
#define SLOG(...) _log(__FILENAME__, __LINE__, LOG_STATS, __VA_ARGS__)
#define FLOG(...) do { \
_log(__FILE__, __LINE__, LOG_FATAL, __VA_ARGS__); \
_log(__FILENAME__, __LINE__, LOG_FATAL, __VA_ARGS__); \
exit(1); /* for clang-tidy! */ \
} while(0)

Expand Down
55 changes: 27 additions & 28 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,33 @@ typedef struct {
struct sockaddr_storage raddr;
} request_t;

// Very very basic hostname parsing.
// Note: Performs basic checks to see if last digit is non-alpha.
// Non-alpha hostnames are assumed to be IP addresses. e.g. foo.1
// Returns non-zero on success, zero on failure.
static int hostname_from_uri(const char* uri,
char* hostname, int hostname_len) {
if (strncmp(uri, "https://", 8) != 0) { return 0; } // not https://
uri += 8;
const char *end = uri;
while (*end && *end != '/') { end++; }
if (end - uri >= hostname_len) {
return 0;
}
if (end == uri) { return 0; } // empty string.
if (!isalpha(*(end - 1))) { return 0; } // last digit non-alpha.

// If using basic authentication in URL, chop off prefix.
char *tmp = strchr(uri, '@');
if (tmp) {
tmp++;
if (tmp < end) {
uri = tmp;
static int is_ipv4_address(char *str) {
struct in6_addr addr;
return inet_pton(AF_INET, str, &addr) == 1;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much nicer. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hoped so. You are welcome!

}

static int hostname_from_url(const char* url_in,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: May be worth keeping the return code comment (non-zero == success, zero = failure).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I have left a very minimal trace of that comment by indicating which value means success. I thought it is enough.
res = 1; // success

char* hostname, const size_t hostname_len) {
int res = 0;
CURLU *url = curl_url();
if (url != NULL) {
CURLUcode rc = curl_url_set(url, CURLUPART_URL, url_in, 0);
if (rc == CURLUE_OK) {
char *host = NULL;
rc = curl_url_get(url, CURLUPART_HOST, &host, 0);
const size_t host_len = strlen(host);
if (rc == CURLUE_OK && host_len < hostname_len &&
host[0] != '[' && host[host_len-1] != ']' && // skip IPv6 address
!is_ipv4_address(host)) {
strncpy(hostname, host, hostname_len-1); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
hostname[hostname_len-1] = '\0';
res = 1; // success
}
curl_free(host);
}
curl_url_cleanup(url);
}

strncpy(hostname, uri, end - uri); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
hostname[end - uri] = 0;
return 1;
return res;
}

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

dns_poller_t dns_poller;
char hostname[255]; // Domain names shouldn't exceed 253 chars.
char hostname[255] = {0}; // Domain names shouldn't exceed 253 chars.
if (!proxy_supports_name_resolution(opt.curl_proxy)) {
if (hostname_from_uri(opt.resolver_url, hostname, 254)) {
if (hostname_from_url(opt.resolver_url, hostname, sizeof(hostname))) {
app.using_dns_poller = 1;
dns_poller_init(&dns_poller, loop, opt.bootstrap_dns,
opt.bootstrap_dns_polling_interval, hostname,
Expand Down