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