1 #include "dnscrypt.h"
2 #include "block.h"
3
4 static void
tcp_request_kill(TCPRequest * const tcp_request)5 tcp_request_kill(TCPRequest *const tcp_request)
6 {
7 if (tcp_request == NULL || tcp_request->status.is_dying) {
8 return;
9 }
10 tcp_request->status.is_dying = 1;
11 struct context *c;
12
13 if (tcp_request->timeout_timer != NULL) {
14 event_free(tcp_request->timeout_timer);
15 tcp_request->timeout_timer = NULL;
16 }
17 if (tcp_request->client_proxy_bev != NULL) {
18 bufferevent_free(tcp_request->client_proxy_bev);
19 tcp_request->client_proxy_bev = NULL;
20 }
21 if (tcp_request->proxy_resolver_bev != NULL) {
22 bufferevent_free(tcp_request->proxy_resolver_bev);
23 tcp_request->proxy_resolver_bev = NULL;
24 }
25 if (tcp_request->proxy_resolver_query_evbuf != NULL) {
26 evbuffer_free(tcp_request->proxy_resolver_query_evbuf);
27 tcp_request->proxy_resolver_query_evbuf = NULL;
28 }
29 c = tcp_request->context;
30 if (tcp_request->status.is_in_queue != 0) {
31 debug_assert(!TAILQ_EMPTY(&c->tcp_request_queue));
32 TAILQ_REMOVE(&c->tcp_request_queue, tcp_request, queue);
33 debug_assert(c->connections > 0U);
34 c->connections--;
35 }
36 tcp_request->context = NULL;
37 free(tcp_request);
38 }
39
40 static void
tcp_tune(evutil_socket_t handle)41 tcp_tune(evutil_socket_t handle)
42 {
43 if (handle == -1) {
44 return;
45 }
46
47 setsockopt(handle, IPPROTO_IP, IP_TOS, (void *) (int []) {
48 0x70}, sizeof(int));
49 #ifdef TCP_QUICKACK
50 setsockopt(handle, IPPROTO_TCP, TCP_QUICKACK, (void *)(int[]) {
51 1}, sizeof(int));
52 #else
53 setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (void *)(int[]) {
54 1}, sizeof(int));
55 #endif
56 #if defined(__linux__) && defined(SO_REUSEPORT)
57 setsockopt(handle, SOL_SOCKET, SO_REUSEPORT, (void *)(int[]) {
58 1}, sizeof(int));
59 #endif
60 }
61
62 static void
timeout_timer_cb(evutil_socket_t timeout_timer_handle,short ev_flags,void * const tcp_request_)63 timeout_timer_cb(evutil_socket_t timeout_timer_handle, short ev_flags,
64 void *const tcp_request_)
65 {
66 TCPRequest *const tcp_request = tcp_request_;
67
68 (void)ev_flags;
69 (void)timeout_timer_handle;
70 logger(LOG_DEBUG, "resolver timeout (TCP)");
71 tcp_request_kill(tcp_request);
72 }
73
74 int
tcp_listener_kill_oldest_request(struct context * c)75 tcp_listener_kill_oldest_request(struct context *c)
76 {
77 if (TAILQ_EMPTY(&c->tcp_request_queue)) {
78 return -1;
79 }
80 tcp_request_kill(TAILQ_FIRST(&c->tcp_request_queue));
81
82 return 0;
83 }
84
85
86 /**
87 * Return 0 if served.
88 */
89 static int
self_serve_cert_file(struct context * c,struct dns_header * header,size_t dns_query_len,size_t max_len,TCPRequest * tcp_request)90 self_serve_cert_file(struct context *c, struct dns_header *header,
91 size_t dns_query_len, size_t max_len, TCPRequest *tcp_request)
92 {
93 uint8_t dns_query_len_buf[2];
94 if (dnscrypt_self_serve_cert_file(c, header, &dns_query_len, max_len) == 0) {
95 dns_query_len_buf[0] = (dns_query_len >> 8) & 0xff;
96 dns_query_len_buf[1] = dns_query_len & 0xff;
97 if (bufferevent_write(tcp_request->client_proxy_bev,
98 dns_query_len_buf, (size_t) 2U) != 0 ||
99 bufferevent_write(tcp_request->client_proxy_bev, (void *)header,
100 (size_t)dns_query_len) != 0) {
101 tcp_request_kill(tcp_request);
102 return -1;
103 }
104 bufferevent_enable(tcp_request->client_proxy_bev, EV_WRITE);
105 bufferevent_free(tcp_request->proxy_resolver_bev);
106 tcp_request->proxy_resolver_bev = NULL;
107 return 0;
108 }
109 return -1;
110 }
111
112 static void
client_proxy_read_cb(struct bufferevent * const client_proxy_bev,void * const tcp_request_)113 client_proxy_read_cb(struct bufferevent *const client_proxy_bev,
114 void *const tcp_request_)
115 {
116 const size_t sizeof_dns_query = DNS_MAX_PACKET_SIZE_TCP - 2U;
117 static uint8_t *dns_query = NULL;
118 uint8_t dns_query_len_buf[2];
119 uint8_t dns_curved_query_len_buf[2];
120 TCPRequest *tcp_request = tcp_request_;
121 struct context *c = tcp_request->context;
122 struct evbuffer *input = bufferevent_get_input(client_proxy_bev);
123 size_t available_size;
124 size_t dns_query_len;
125 size_t max_query_size;
126
127 if (dns_query == NULL && (dns_query = sodium_malloc(sizeof_dns_query)) == NULL) {
128 return;
129 }
130 if (tcp_request->status.has_dns_query_len == 0) {
131 debug_assert(evbuffer_get_length(input) >= (size_t) 2U);
132 evbuffer_remove(input, dns_query_len_buf, sizeof dns_query_len_buf);
133 tcp_request->dns_query_len = (size_t)
134 ((dns_query_len_buf[0] << 8) | dns_query_len_buf[1]);
135 tcp_request->status.has_dns_query_len = 1;
136 }
137 debug_assert(tcp_request->status.has_dns_query_len != 0);
138 dns_query_len = tcp_request->dns_query_len;
139 if (dns_query_len < (size_t) DNS_HEADER_SIZE) {
140 logger(LOG_WARNING, "Short query received");
141 tcp_request_kill(tcp_request);
142 return;
143 }
144 available_size = evbuffer_get_length(input);
145 if (available_size < dns_query_len) {
146 bufferevent_setwatermark(tcp_request->client_proxy_bev,
147 EV_READ, dns_query_len, dns_query_len);
148 return;
149 }
150 debug_assert(available_size >= dns_query_len);
151 bufferevent_disable(tcp_request->client_proxy_bev, EV_READ);
152 debug_assert(tcp_request->proxy_resolver_query_evbuf == NULL);
153 if ((tcp_request->proxy_resolver_query_evbuf = evbuffer_new()) == NULL) {
154 tcp_request_kill(tcp_request);
155 return;
156 }
157 if ((ssize_t)
158 evbuffer_remove_buffer(input, tcp_request->proxy_resolver_query_evbuf,
159 dns_query_len) != (ssize_t) dns_query_len) {
160 tcp_request_kill(tcp_request);
161 return;
162 }
163 debug_assert(dns_query_len <= sizeof_dns_query);
164 if ((ssize_t) evbuffer_remove(tcp_request->proxy_resolver_query_evbuf,
165 dns_query, dns_query_len)
166 != (ssize_t) dns_query_len) {
167 tcp_request_kill(tcp_request);
168 return;
169 }
170 max_query_size = sizeof_dns_query;
171 debug_assert(max_query_size < DNS_MAX_PACKET_SIZE_TCP);
172 debug_assert(SIZE_MAX - DNSCRYPT_MAX_PADDING - DNSCRYPT_QUERY_HEADER_SIZE
173 > dns_query_len);
174 size_t max_len =
175 dns_query_len + DNSCRYPT_MAX_PADDING + DNSCRYPT_QUERY_HEADER_SIZE;
176 if (max_len > max_query_size) {
177 max_len = max_query_size;
178 }
179 if (dns_query_len + DNSCRYPT_QUERY_HEADER_SIZE > max_len) {
180 tcp_request_kill(tcp_request);
181 return;
182 }
183 debug_assert(max_len <= DNS_MAX_PACKET_SIZE_TCP - 2U);
184 debug_assert(max_len <= sizeof_dns_query);
185 debug_assert(dns_query_len <= max_len);
186
187 // decrypt if encrypted
188 struct dnscrypt_query_header *dnscrypt_header =
189 (struct dnscrypt_query_header *)dns_query;
190 debug_assert(sizeof c->keypairs[0].crypt_publickey >= DNSCRYPT_MAGIC_HEADER_LEN);
191 if ((tcp_request->cert =
192 find_cert(c, dnscrypt_header->magic_query, dns_query_len)) == NULL) {
193 tcp_request->is_dnscrypted = false;
194 } else {
195 if (dnscrypt_server_uncurve(c, tcp_request->cert,
196 tcp_request->client_nonce,
197 tcp_request->nmkey, dns_query,
198 &dns_query_len) != 0 || dns_query_len < DNS_HEADER_SIZE) {
199 logger(LOG_DEBUG, "Received a suspicious query from the client");
200 tcp_request_kill(tcp_request);
201 return;
202 }
203 tcp_request->is_dnscrypted = true;
204 }
205
206 struct dns_header *header = (struct dns_header *)dns_query;
207 // self serve signed certificate for provider name?
208 if (!tcp_request->is_dnscrypted) {
209 if (self_serve_cert_file(c, header, dns_query_len, sizeof_dns_query, tcp_request) == 0)
210 return;
211 if (!c->allow_not_dnscrypted) {
212 logger(LOG_DEBUG, "Unauthenticated query received over TCP");
213 tcp_request_kill(tcp_request);
214 return;
215 }
216 }
217
218 tcp_request->is_blocked = is_blocked(c, header, dns_query_len);
219
220 dns_curved_query_len_buf[0] = (dns_query_len >> 8) & 0xff;
221 dns_curved_query_len_buf[1] = dns_query_len & 0xff;
222 if (bufferevent_write(tcp_request->proxy_resolver_bev,
223 dns_curved_query_len_buf, (size_t) 2U) != 0 ||
224 bufferevent_write(tcp_request->proxy_resolver_bev, dns_query,
225 (size_t) dns_query_len) != 0) {
226 tcp_request_kill(tcp_request);
227 return;
228 }
229
230 bufferevent_enable(tcp_request->proxy_resolver_bev, EV_READ);
231 }
232
233 static void
client_proxy_event_cb(struct bufferevent * const client_proxy_bev,const short events,void * const tcp_request_)234 client_proxy_event_cb(struct bufferevent *const client_proxy_bev,
235 const short events, void *const tcp_request_)
236 {
237 TCPRequest *const tcp_request = tcp_request_;
238
239 (void)client_proxy_bev;
240 (void)events;
241 tcp_request_kill(tcp_request);
242 }
243
244 static void
client_proxy_write_cb(struct bufferevent * const client_proxy_bev,void * const tcp_request_)245 client_proxy_write_cb(struct bufferevent *const client_proxy_bev,
246 void *const tcp_request_)
247 {
248 TCPRequest *const tcp_request = tcp_request_;
249
250 (void)client_proxy_bev;
251 tcp_request_kill(tcp_request);
252 }
253
254 static void
proxy_resolver_event_cb(struct bufferevent * const proxy_resolver_bev,const short events,void * const tcp_request_)255 proxy_resolver_event_cb(struct bufferevent *const proxy_resolver_bev,
256 const short events, void *const tcp_request_)
257 {
258 TCPRequest *const tcp_request = tcp_request_;
259
260 (void)proxy_resolver_bev;
261 if ((events & BEV_EVENT_ERROR) != 0) {
262 tcp_request_kill(tcp_request);
263 return;
264 }
265 if ((events & BEV_EVENT_CONNECTED) == 0) {
266 tcp_tune(bufferevent_getfd(proxy_resolver_bev));
267 return;
268 }
269 }
270
271 static void
resolver_proxy_read_cb(struct bufferevent * const proxy_resolver_bev,void * const tcp_request_)272 resolver_proxy_read_cb(struct bufferevent *const proxy_resolver_bev,
273 void *const tcp_request_)
274 {
275 uint8_t dns_reply_len_buf[2];
276 uint8_t dns_curved_reply_len_buf[2];
277 uint8_t *dns_reply_bev;
278 TCPRequest *tcp_request = tcp_request_;
279 struct context *c = tcp_request->context;
280 struct evbuffer *input = bufferevent_get_input(proxy_resolver_bev);
281 size_t available_size;
282 const size_t sizeof_dns_reply = DNS_MAX_PACKET_SIZE_TCP - 2U;
283 static uint8_t *dns_reply = NULL;
284 size_t dns_reply_len;
285
286 if (dns_reply == NULL && (dns_reply = sodium_malloc(sizeof_dns_reply)) == NULL) {
287 tcp_request_kill(tcp_request);
288 return;
289 }
290 logger(LOG_DEBUG, "Resolver read callback.");
291 if (tcp_request->status.has_dns_reply_len == 0) {
292 debug_assert(evbuffer_get_length(input) >= (size_t) 2U);
293 evbuffer_remove(input, dns_reply_len_buf, sizeof dns_reply_len_buf);
294 tcp_request->dns_reply_len = (size_t)
295 ((dns_reply_len_buf[0] << 8) | dns_reply_len_buf[1]);
296 tcp_request->status.has_dns_reply_len = 1;
297 }
298 debug_assert(tcp_request->status.has_dns_reply_len != 0);
299 dns_reply_len = tcp_request->dns_reply_len;
300 if (dns_reply_len < (size_t) DNS_HEADER_SIZE) {
301 logger(LOG_WARNING, "Short reply received");
302 tcp_request_kill(tcp_request);
303 return;
304 }
305 available_size = evbuffer_get_length(input);
306 if (available_size < dns_reply_len) {
307 bufferevent_setwatermark(tcp_request->proxy_resolver_bev,
308 EV_READ, dns_reply_len, dns_reply_len);
309 return;
310 }
311 debug_assert(available_size >= dns_reply_len);
312 dns_reply_bev = evbuffer_pullup(input, (ssize_t) dns_reply_len);
313 if (dns_reply_bev == NULL) {
314 tcp_request_kill(tcp_request);
315 return;
316 }
317
318 memcpy(dns_reply, dns_reply_bev, dns_reply_len);
319
320 size_t max_len =
321 dns_reply_len + DNSCRYPT_MAX_PADDING + DNSCRYPT_REPLY_HEADER_SIZE;
322
323 if (tcp_request->is_blocked) {
324 struct dns_header *p = (struct dns_header *) dns_reply;
325 SET_RCODE(p, REFUSED);
326 }
327 if (tcp_request->is_dnscrypted) {
328 if (dnscrypt_server_curve(c, tcp_request->cert,
329 tcp_request->client_nonce, tcp_request->nmkey,
330 dns_reply, &dns_reply_len, max_len) != 0) {
331 logger(LOG_ERR, "Curving reply failed.");
332 return;
333 }
334 }
335
336 dns_curved_reply_len_buf[0] = (dns_reply_len >> 8) & 0xff;
337 dns_curved_reply_len_buf[1] = dns_reply_len & 0xff;
338 if (bufferevent_write(tcp_request->client_proxy_bev,
339 dns_curved_reply_len_buf, (size_t) 2U) != 0 ||
340 bufferevent_write(tcp_request->client_proxy_bev, dns_reply,
341 dns_reply_len) != 0) {
342 tcp_request_kill(tcp_request);
343 return;
344 }
345 bufferevent_enable(tcp_request->client_proxy_bev, EV_WRITE);
346 bufferevent_free(tcp_request->proxy_resolver_bev);
347 tcp_request->proxy_resolver_bev = NULL;
348 }
349
350 static void
tcp_connection_cb(struct evconnlistener * const tcp_conn_listener,evutil_socket_t handle,struct sockaddr * const client_sockaddr,const int client_sockaddr_len_int,void * const context)351 tcp_connection_cb(struct evconnlistener *const tcp_conn_listener,
352 evutil_socket_t handle,
353 struct sockaddr *const client_sockaddr,
354 const int client_sockaddr_len_int, void *const context)
355 {
356 logger(LOG_DEBUG, "Accepted a tcp connection.");
357 evutil_socket_t fd;
358 struct context *c = context;
359 TCPRequest *tcp_request;
360
361 (void)tcp_conn_listener;
362 (void)client_sockaddr;
363 (void)client_sockaddr_len_int;
364 if ((tcp_request = calloc((size_t) 1U, sizeof *tcp_request)) == NULL) {
365 return;
366 }
367 tcp_request->context = c;
368 tcp_request->timeout_timer = NULL;
369 tcp_request->proxy_resolver_query_evbuf = NULL;
370 tcp_request->client_proxy_bev = bufferevent_socket_new(c->event_loop,
371 handle,
372 BEV_OPT_CLOSE_ON_FREE);
373 if (tcp_request->client_proxy_bev == NULL) {
374 evutil_closesocket(handle);
375 free(tcp_request);
376 return;
377 }
378
379 fd = socket(c->resolver_sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
380 tcp_tune(fd);
381 if (evutil_make_socket_nonblocking(fd)) {
382 logger(LOG_WARNING, "Could not make socket %d non-blocking", fd);
383 }
384 tcp_request->proxy_resolver_bev = bufferevent_socket_new(c->event_loop, fd,
385 BEV_OPT_CLOSE_ON_FREE);
386
387 if (tcp_request->proxy_resolver_bev == NULL) {
388 bufferevent_free(tcp_request->client_proxy_bev);
389 tcp_request->client_proxy_bev = NULL;
390 free(tcp_request);
391 return;
392 }
393
394 /* Bind source IP:port if --outgoing-address is provided */
395 if(c->outgoing_address &&
396 bind(fd,
397 (struct sockaddr *)&c->outgoing_sockaddr,
398 c->outgoing_sockaddr_len) != 0) {
399 logger(LOG_ERR, "Unable to bind (TCP) [%s]",
400 evutil_socket_error_to_string(evutil_socket_geterror
401 (tcp_request->proxy_resolver_bev)));
402 tcp_request_kill(tcp_request);
403 return;
404 }
405
406 c->connections++;
407 TAILQ_INSERT_TAIL(&c->tcp_request_queue, tcp_request, queue);
408 memset(&tcp_request->status, 0, sizeof tcp_request->status);
409 tcp_request->status.is_in_queue = 1;
410 if ((tcp_request->timeout_timer =
411 evtimer_new(tcp_request->context->event_loop,
412 timeout_timer_cb, tcp_request)) == NULL) {
413 tcp_request_kill(tcp_request);
414 return;
415 }
416 const struct timeval tv = {
417 .tv_sec = (time_t) DNS_QUERY_TIMEOUT,.tv_usec = 0
418 };
419 evtimer_add(tcp_request->timeout_timer, &tv);
420 bufferevent_setwatermark(tcp_request->client_proxy_bev,
421 EV_READ, (size_t) 2U,
422 (size_t) DNS_MAX_PACKET_SIZE_TCP);
423 bufferevent_setcb(tcp_request->client_proxy_bev,
424 client_proxy_read_cb, client_proxy_write_cb,
425 client_proxy_event_cb, tcp_request);
426 if (bufferevent_socket_connect
427 (tcp_request->proxy_resolver_bev,
428 (struct sockaddr *)&c->resolver_sockaddr,
429 (int)c->resolver_sockaddr_len) != 0) {
430 tcp_request_kill(tcp_request);
431 return;
432 }
433 bufferevent_setwatermark(tcp_request->proxy_resolver_bev,
434 EV_READ, (size_t) 2U,
435 (size_t) DNS_MAX_PACKET_SIZE_TCP);
436 bufferevent_setcb(tcp_request->proxy_resolver_bev,
437 resolver_proxy_read_cb, NULL, proxy_resolver_event_cb,
438 tcp_request);
439 bufferevent_enable(tcp_request->client_proxy_bev, EV_READ);
440 }
441
442 static void
tcp_accept_timer_cb(evutil_socket_t handle,const short event,void * const context)443 tcp_accept_timer_cb(evutil_socket_t handle, const short event,
444 void *const context)
445 {
446 struct context *c = context;
447
448 (void)handle;
449 (void)event;
450 event_free(c->tcp_accept_timer);
451 c->tcp_accept_timer = NULL;
452 evconnlistener_enable(c->tcp_conn_listener);
453 }
454
455 static void
tcp_accept_error_cb(struct evconnlistener * const tcp_conn_listener,void * const context)456 tcp_accept_error_cb(struct evconnlistener *const tcp_conn_listener,
457 void *const context)
458 {
459 struct context *c = context;
460
461 (void)tcp_conn_listener;
462 if (c->tcp_accept_timer == NULL) {
463 c->tcp_accept_timer = evtimer_new
464 (c->event_loop, tcp_accept_timer_cb, c);
465 if (c->tcp_accept_timer == NULL) {
466 return;
467 }
468 }
469 if (evtimer_pending(c->tcp_accept_timer, NULL)) {
470 return;
471 }
472 evconnlistener_disable(c->tcp_conn_listener);
473
474 const struct timeval tv = {
475 .tv_sec = (time_t) 1,
476 .tv_usec = 0
477 };
478 evtimer_add(c->tcp_accept_timer, &tv);
479 }
480
481 int
tcp_listener_bind(struct context * c)482 tcp_listener_bind(struct context *c)
483 {
484 debug_assert(c->tcp_conn_listener == NULL);
485 #ifndef LEV_OPT_DEFERRED_ACCEPT
486 # define LEV_OPT_DEFERRED_ACCEPT 0
487 #endif
488
489 /* Until libevent gets support for SO_REUSEPORT we have to break
490 * evconnlistener_new_bind() into a series of:
491 * socket(), tcp_tune(), bind(), evconnlistener_new() */
492 evutil_socket_t fd;
493 fd = socket(c->local_sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
494
495 tcp_tune(fd);
496 evutil_make_socket_nonblocking(fd);
497
498 if (bind(fd, (struct sockaddr *) &c->local_sockaddr, c->local_sockaddr_len) < 0) {
499 logger(LOG_ERR, "Unable to bind (TCP): %s", c->listen_address);
500 return -1;
501 }
502
503 c->tcp_conn_listener =
504 evconnlistener_new(c->event_loop,
505 tcp_connection_cb, c,
506 LEV_OPT_CLOSE_ON_FREE |
507 LEV_OPT_CLOSE_ON_EXEC |
508 LEV_OPT_REUSEABLE |
509 LEV_OPT_DEFERRED_ACCEPT,
510 TCP_REQUEST_BACKLOG,
511 fd);
512 if (c->tcp_conn_listener == NULL) {
513 logger(LOG_ERR, "Unable to create listener (TCP)");
514 return -1;
515 }
516 if (evconnlistener_disable(c->tcp_conn_listener) != 0) {
517 evconnlistener_free(c->tcp_conn_listener);
518 c->tcp_conn_listener = NULL;
519 return -1;
520 }
521 evconnlistener_set_error_cb(c->tcp_conn_listener, tcp_accept_error_cb);
522 TAILQ_INIT(&c->tcp_request_queue);
523
524 return 0;
525 }
526
527 int
tcp_listener_start(struct context * c)528 tcp_listener_start(struct context *c)
529 {
530 debug_assert(c->tcp_conn_listener != NULL);
531 if (evconnlistener_enable(c->tcp_conn_listener) != 0) {
532 return -1;
533 }
534 return 0;
535 }
536
537 void
tcp_listener_stop(struct context * c)538 tcp_listener_stop(struct context *c)
539 {
540 evconnlistener_free(c->tcp_conn_listener);
541 c->tcp_conn_listener = NULL;
542 while (tcp_listener_kill_oldest_request(c) != 0) {
543 }
544 logger(LOG_INFO, "TCP listener shut down");
545 }
546