Skip to content

Commit 83f7e92

Browse files
committed
Printing curl library versions and used features
- Moved argument parsing "decisions" into main() - getopt() handling changes, test OPR_PARSING_ERROR with "-j" and "-i" argument strings. - Minimal libcurl version raised to 7.66.0, so no need to check CURL_VERSION_HTTP3 availability. - Raised hardcoded version.
1 parent e6fd23c commit 83f7e92

File tree

6 files changed

+84
-51
lines changed

6 files changed

+84
-51
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ define_file_basename_for_sources("https_dns_proxy")
117117

118118
if(SW_VERSION)
119119
set_source_files_properties(
120-
src/options.c
120+
src/main.c
121121
PROPERTIES COMPILE_FLAGS "-DSW_VERSION='\"${SW_VERSION}\"'")
122122
endif()
123123

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ only makes sense if you trust your DoH provider.
4343

4444
## Build
4545

46-
Depends on `c-ares (>=1.11.0)`, `libcurl (>=7.65.0)`, `libev (>=4.25)`.
46+
Depends on `c-ares (>=1.11.0)`, `libcurl (>=7.66.0)`, `libev (>=4.25)`.
4747

4848
On Debian-derived systems those are libc-ares-dev,
4949
libcurl4-{openssl,nss,gnutls}-dev and libev-dev respectively.
@@ -208,7 +208,7 @@ Usage: ./https_dns_proxy [-a <listen_addr>] [-p <listen_port>]
208208
-F log_limit Flight recorder: storing desired amount of logs from all levels
209209
in memory and dumping them on fatal error or on SIGUSR2 signal.
210210
(Default: 0, Disabled: 0, Min: 100, Max: 100000)
211-
-V Print version and exit.
211+
-V Print versions and exit.
212212
-h Print help and exit.
213213
```
214214

src/https_client.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,8 @@ static const char * http_version_str(const long version) {
235235
case CURL_HTTP_VERSION_2_0: // fallthrough
236236
case CURL_HTTP_VERSION_2TLS:
237237
return "2";
238-
#ifdef CURL_VERSION_HTTP3
239238
case CURL_HTTP_VERSION_3:
240239
return "3";
241-
#endif
242240
default:
243241
FLOG("Unsupported HTTP version: %d", version);
244242
}
@@ -255,9 +253,7 @@ static void https_set_request_version(https_client_t *client,
255253
case 2:
256254
break;
257255
case 3:
258-
#ifdef CURL_VERSION_HTTP3
259256
http_version_int = CURL_HTTP_VERSION_3;
260-
#endif
261257
break;
262258
default:
263259
FLOG_REQ("Invalid HTTP version: %d", client->opt->use_http_version);

src/main.c

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,38 +205,80 @@ static int proxy_supports_name_resolution(const char *proxy)
205205
return 0;
206206
}
207207

208+
static const char * sw_version(void) {
209+
#ifdef SW_VERSION
210+
return SW_VERSION;
211+
#else
212+
return "2025.5.10-atLeast"; // update date sometimes, like 1-2 times a year
213+
#endif
214+
}
215+
208216
int main(int argc, char *argv[]) {
209217
struct Options opt;
210218
options_init(&opt);
211-
if (options_parse_args(&opt, argc, argv)) {
212-
options_show_usage(argc, argv);
213-
exit(1);
219+
switch (options_parse_args(&opt, argc, argv)) {
220+
case OPR_SUCCESS:
221+
break;
222+
case OPR_HELP:
223+
options_show_usage(argc, argv);
224+
exit(0); // asking for help is not a problem
225+
case OPR_VERSION: {
226+
printf("%s\n", sw_version());
227+
CURLcode init_res = curl_global_init(CURL_GLOBAL_DEFAULT);
228+
curl_version_info_data *curl_ver = curl_version_info(CURLVERSION_NOW);
229+
if (init_res == CURLE_OK && curl_ver != NULL) {
230+
printf("Using: ev/%d.%d c-ares/%s %s\n",
231+
ev_version_major(), ev_version_minor(),
232+
ares_version(NULL), curl_version());
233+
printf("Features: %s%s%s%s\n",
234+
curl_ver->features & CURL_VERSION_HTTP2 ? "HTTP2 " : "",
235+
curl_ver->features & CURL_VERSION_HTTP3 ? "HTTP3 " : "",
236+
curl_ver->features & CURL_VERSION_HTTPS_PROXY ? "HTTPS-proxy " : "",
237+
curl_ver->features & CURL_VERSION_IPV6 ? "IPv6" : "");
238+
exit(0);
239+
} else {
240+
printf("\nFailed to get curl version info!\n");
241+
exit(1);
242+
}
243+
}
244+
case OPR_PARSING_ERROR:
245+
printf("Failed to parse options!\n");
246+
// fallthrough
247+
case OPR_OPTION_ERROR:
248+
printf("\n");
249+
options_show_usage(argc, argv);
250+
exit(1);
251+
default:
252+
abort(); // must not happen
214253
}
215254

216255
logging_init(opt.logfd, opt.loglevel, opt.flight_recorder_size);
217256

218-
ILOG("Version: %s", options_sw_version());
257+
ILOG("Version: %s", sw_version());
219258
ILOG("Built: " __DATE__ " " __TIME__);
220-
ILOG("System c-ares: %s", ares_version(NULL));
221-
ILOG("System libcurl: %s", curl_version());
259+
ILOG("System ev library: %d.%d", ev_version_major(), ev_version_minor());
260+
ILOG("System c-ares library: %s", ares_version(NULL));
261+
ILOG("System curl library: %s", curl_version());
222262

223263
// Note: curl intentionally uses uninitialized stack variables and similar
224264
// tricks to increase it's entropy pool. This confuses valgrind and leaks
225265
// through to errors about use of uninitialized values in our code. :(
226-
curl_global_init(CURL_GLOBAL_DEFAULT);
266+
CURLcode code = curl_global_init(CURL_GLOBAL_DEFAULT);
267+
if (code != CURLE_OK) {
268+
FLOG("Failed to initialize curl, error code %d: %s",
269+
code, curl_easy_strerror(code));
270+
}
227271

228272
curl_version_info_data *curl_ver = curl_version_info(CURLVERSION_NOW);
273+
if (curl_ver == NULL) {
274+
FLOG("Failed to get curl version info!");
275+
}
229276
if (!(curl_ver->features & CURL_VERSION_HTTP2)) {
230277
WLOG("HTTP/2 is not supported by current libcurl");
231278
}
232-
#ifdef CURL_VERSION_HTTP3
233-
if (!(curl_ver->features & CURL_VERSION_HTTP3))
234-
{
279+
if (!(curl_ver->features & CURL_VERSION_HTTP3)) {
235280
WLOG("HTTP/3 is not supported by current libcurl");
236281
}
237-
#else
238-
WLOG("HTTP/3 was not available at build time, it will not work at all");
239-
#endif
240282
if (!(curl_ver->features & CURL_VERSION_IPV6)) {
241283
WLOG("IPv6 is not supported by current libcurl");
242284
}

src/options.c

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@ enum {
1919
DEFAULT_HTTP_VERSION = 2
2020
};
2121

22-
23-
const char * options_sw_version(void) {
24-
#ifdef SW_VERSION
25-
return SW_VERSION;
26-
#else
27-
return "2023.10.10-atLeast"; // update date sometimes, like 1-2 times a year
28-
#endif
29-
}
30-
3122
void options_init(struct Options *opt) {
3223
opt->listen_addr = "127.0.0.1";
3324
opt->listen_port = 5053;
@@ -53,7 +44,7 @@ void options_init(struct Options *opt) {
5344
opt->flight_recorder_size = 0;
5445
}
5546

56-
int options_parse_args(struct Options *opt, int argc, char **argv) {
47+
enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char **argv) {
5748
int c = 0;
5849
while ((c = getopt(argc, argv, "a:c:p:du:g:b:i:4r:e:t:l:vxqm:s:C:F:hV")) != -1) {
5950
switch (c) {
@@ -105,7 +96,7 @@ int options_parse_args(struct Options *opt, int argc, char **argv) {
10596
} else {
10697
printf("HTTP version already set to: HTTP/%s\n",
10798
opt->use_http_version == 1 ? "1.1" : "3");
108-
return -1;
99+
return OPR_OPTION_ERROR;
109100
}
110101
break;
111102
case 'm':
@@ -120,38 +111,35 @@ int options_parse_args(struct Options *opt, int argc, char **argv) {
120111
case 'F': // Flight recorder size
121112
opt->flight_recorder_size = atoi(optarg);
122113
break;
123-
case '?':
124-
printf("Unknown option '-%c'\n", c);
125-
// fallthrough
126114
case 'h':
127-
return -1;
115+
return OPR_HELP;
128116
case 'V': // version
129-
printf("%s\n", options_sw_version());
130-
exit(0);
117+
return OPR_VERSION;
118+
case '?':
131119
default:
132-
printf("Unknown state!");
133-
exit(EXIT_FAILURE);
120+
return OPR_PARSING_ERROR;
134121
}
135122
}
123+
136124
if (opt->user) {
137125
struct passwd *p = getpwnam(opt->user);
138126
if (!p || !p->pw_uid) {
139127
printf("Username (%s) invalid.\n", opt->user);
140-
return -1;
128+
return OPR_OPTION_ERROR;
141129
}
142130
opt->uid = p->pw_uid;
143131
}
144132
if (opt->group) {
145133
struct group *g = getgrnam(opt->group);
146134
if (!g || !g->gr_gid) {
147135
printf("Group (%s) invalid.\n", opt->group);
148-
return -1;
136+
return OPR_OPTION_ERROR;
149137
}
150138
opt->gid = g->gr_gid;
151139
}
152140
if (opt->dscp < 0 || opt->dscp >63) {
153141
printf("DSCP code (%d) invalid:[0-63]\n", opt->dscp);
154-
return -1;
142+
return OPR_OPTION_ERROR;
155143
}
156144
opt->dscp <<= 2;
157145
// Get noisy about bad security practices.
@@ -174,28 +162,28 @@ int options_parse_args(struct Options *opt, int argc, char **argv) {
174162
strncmp(opt->resolver_url, "https://", 8) != 0) {
175163
printf("Resolver prefix (%s) must be a https:// address.\n",
176164
opt->resolver_url);
177-
return -1;
165+
return OPR_OPTION_ERROR;
178166
}
179167
if (opt->bootstrap_dns_polling_interval < 5 ||
180168
opt->bootstrap_dns_polling_interval > 3600) {
181169
printf("DNS servers polling interval must be between 5 and 3600.\n");
182-
return -1;
170+
return OPR_OPTION_ERROR;
183171
}
184172
if (opt->max_idle_time < 0 ||
185173
opt->max_idle_time > 3600) {
186174
printf("Maximum idle time must be between 0 and 3600.\n");
187-
return -1;
175+
return OPR_OPTION_ERROR;
188176
}
189177
if (opt->stats_interval < 0 || opt->stats_interval > 3600) {
190178
printf("Statistic interval must be between 0 and 3600.\n");
191-
return -1;
179+
return OPR_OPTION_ERROR;
192180
}
193181
if (opt->flight_recorder_size != 0 &&
194182
(opt->flight_recorder_size < 100 || opt->flight_recorder_size > 100000)) {
195183
printf("Flight recorder limit must be between 100 and 100000.\n");
196-
return -1;
184+
return OPR_OPTION_ERROR;
197185
}
198-
return 0;
186+
return OPR_SUCCESS;
199187
}
200188

201189
void options_show_usage(int __attribute__((unused)) argc, char **argv) {
@@ -254,7 +242,7 @@ void options_show_usage(int __attribute__((unused)) argc, char **argv) {
254242
" in memory and dumping them on fatal error or on SIGUSR2 signal.\n"
255243
" (Default: %u, Disabled: 0, Min: 100, Max: 100000)\n",
256244
defaults.flight_recorder_size);
257-
printf(" -V Print version and exit.\n");
245+
printf(" -V Print versions and exit.\n");
258246
printf(" -h Print help and exit.\n");
259247
options_cleanup(&defaults);
260248
}

src/options.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,19 @@ struct Options {
5959
} __attribute__((aligned(128)));
6060
typedef struct Options options_t;
6161

62+
enum OptionsParseResult {
63+
OPR_SUCCESS,
64+
OPR_HELP,
65+
OPR_VERSION,
66+
OPR_OPTION_ERROR,
67+
OPR_PARSING_ERROR
68+
};
69+
6270
#ifdef __cplusplus
6371
extern "C" {
6472
#endif
65-
const char * options_sw_version(void);
6673
void options_init(struct Options *opt);
67-
int options_parse_args(struct Options *opt, int argc, char **argv);
74+
enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char **argv);
6875
void options_show_usage(int argc, char **argv);
6976
void options_cleanup(struct Options *opt);
7077
#ifdef __cplusplus

0 commit comments

Comments
 (0)