1 #include "dnscrypt.h"
2 #include "block.h"
3
4 typedef struct SendtoWithRetryCtx_ {
5 void (*cb) (UDPRequest *udp_request);
6 const void *buffer;
7 UDPRequest *udp_request;
8 const struct sockaddr *dest_addr;
9 evutil_socket_t handle;
10 size_t length;
11 ev_socklen_t dest_len;
12 int flags;
13 } SendtoWithRetryCtx;
14
15 /* Forward declarations. */
16 static int sendto_with_retry(SendtoWithRetryCtx *const ctx);
17
18 #ifndef UDP_BUFFER_SIZE
19 # define UDP_BUFFER_SIZE 2097152
20 #endif
21 #ifndef UDP_DELAY_BETWEEN_RETRIES
22 # define UDP_DELAY_BETWEEN_RETRIES 1
23 #endif
24
25 #ifndef SO_RCVBUFFORCE
26 # define SO_RCVBUFFORCE SO_RCVBUF
27 #endif
28 #ifndef SO_SNDBUFFORCE
29 # define SO_SNDBUFFORCE SO_SNDBUF
30 #endif
31
32 #ifndef EVUTIL_ERR_RW_RETRIABLE
33 # ifndef _WIN32
34 # define EVUTIL_ERR_RW_RETRIABLE(e) ((e) == EINTR || (e) == EAGAIN)
35 # else
36 # define EVUTIL_ERR_RW_RETRIABLE(e) ((e) == WSAEWOULDBLOCK || (e) == WSAEINTR)
37 # endif
38 #endif
39
udp_request_cmp(const UDPRequest * r1,const UDPRequest * r2)40 static int udp_request_cmp(const UDPRequest *r1, const UDPRequest *r2) {
41 if (r1->hash < r2->hash) {
42 return -1;
43 } else if (r1->hash > r2->hash) {
44 return 1;
45 } else if (r1->id < r2->id) {
46 return -1;
47 } else if (r1->id > r2->id) {
48 return 1;
49 } else if (r1->gen < r2->gen) {
50 return -1;
51 } else if (r1->gen > r2->gen) {
52 return 1;
53 }
54 return 0;
55 }
56
RB_GENERATE_STATIC(UDPRequestQueue_,UDPRequest_,queue,udp_request_cmp)57 RB_GENERATE_STATIC(UDPRequestQueue_, UDPRequest_, queue, udp_request_cmp)
58
59 static void
60 udp_tune(evutil_socket_t const handle)
61 {
62 if (handle == -1) {
63 return;
64 }
65 setsockopt(handle, IPPROTO_IP, IP_TOS, (void *) (int []) {
66 0x70}, sizeof(int));
67 setsockopt(handle, SOL_SOCKET, SO_RCVBUFFORCE, (void *)(int[]) {
68 UDP_BUFFER_SIZE}, sizeof(int));
69 setsockopt(handle, SOL_SOCKET, SO_SNDBUFFORCE, (void *)(int[]) {
70 UDP_BUFFER_SIZE}, sizeof(int));
71 #if defined(IP_PMTUDISC_OMIT)
72 setsockopt(handle, IPPROTO_IP, IP_MTU_DISCOVER,
73 (void *) (int []) { IP_PMTUDISC_OMIT }, sizeof (int));
74 #elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
75 setsockopt(handle, IPPROTO_IP, IP_MTU_DISCOVER, (void *)(int[]) {
76 IP_PMTUDISC_DONT}, sizeof(int));
77 #elif defined(IP_DONTFRAG)
78 setsockopt(handle, IPPROTO_IP, IP_DONTFRAG, (void *)(int[]) {
79 0}, sizeof(int));
80 #endif
81 #if defined(__linux__) && defined(SO_REUSEPORT)
82 setsockopt(handle, SOL_SOCKET, SO_REUSEPORT, (void *)(int[]) {
83 1}, sizeof(int));
84 #endif
85 }
86
87 static void
client_to_proxy_cb_sendto_cb(UDPRequest * const udp_request)88 client_to_proxy_cb_sendto_cb(UDPRequest *const udp_request)
89 {
90 (void)udp_request;
91 }
92
93 static void
udp_request_kill(UDPRequest * const udp_request)94 udp_request_kill(UDPRequest *const udp_request)
95 {
96 if (udp_request == NULL || udp_request->status.is_dying)
97 return;
98
99 udp_request->status.is_dying = 1;
100
101 // free
102 struct context *c;
103 if (udp_request->sendto_retry_timer != NULL) {
104 free(event_get_callback_arg(udp_request->sendto_retry_timer));
105 event_free(udp_request->sendto_retry_timer);
106 udp_request->sendto_retry_timer = NULL;
107 }
108 if (udp_request->timeout_timer != NULL) {
109 event_free(udp_request->timeout_timer);
110 udp_request->timeout_timer = NULL;
111 }
112
113 c = udp_request->context;
114 if (udp_request->status.is_in_queue != 0) {
115 assert(!RB_EMPTY(&c->udp_request_queue));
116 RB_REMOVE(UDPRequestQueue_, &c->udp_request_queue, udp_request);
117 assert(c->connections > 0);
118 c->connections--;
119 }
120
121 udp_request->context = NULL;
122 free(udp_request);
123 }
124
125 int
udp_listener_kill_oldest_request(struct context * c)126 udp_listener_kill_oldest_request(struct context *c)
127 {
128 if (RB_EMPTY(&c->udp_request_queue))
129 return -1;
130
131 udp_request_kill(RB_MIN(UDPRequestQueue_, &c->udp_request_queue));
132
133 return 0;
134 }
135
136 static void
sendto_with_retry_timer_cb(evutil_socket_t retry_timer_handle,short ev_flags,void * const ctx_)137 sendto_with_retry_timer_cb(evutil_socket_t retry_timer_handle, short ev_flags,
138 void *const ctx_)
139 {
140 SendtoWithRetryCtx *const ctx = ctx_;
141
142 (void)ev_flags;
143 assert(retry_timer_handle ==
144 event_get_fd(ctx->udp_request->sendto_retry_timer));
145
146 sendto_with_retry(ctx);
147 }
148
149 static int
sendto_with_retry(SendtoWithRetryCtx * const ctx)150 sendto_with_retry(SendtoWithRetryCtx *const ctx)
151 {
152 void (*cb) (UDPRequest *udp_request);
153 SendtoWithRetryCtx *ctx_cb;
154 UDPRequest *udp_request = ctx->udp_request;
155 int err;
156 bool retriable;
157
158 if (sendto(ctx->handle, ctx->buffer, ctx->length, ctx->flags,
159 ctx->dest_addr, ctx->dest_len) == (ssize_t) ctx->length) {
160 cb = ctx->cb;
161 if (udp_request->sendto_retry_timer != NULL) {
162 ctx_cb = event_get_callback_arg(udp_request->sendto_retry_timer);
163 assert(ctx_cb != NULL);
164 assert(ctx_cb->udp_request == ctx->udp_request);
165 assert(ctx_cb->buffer == ctx->buffer);
166 free(ctx_cb);
167 event_free(udp_request->sendto_retry_timer);
168 udp_request->sendto_retry_timer = NULL;
169 }
170 if (cb) {
171 cb(udp_request);
172 }
173 return 0;
174 }
175
176 err = evutil_socket_geterror(udp_request->client_proxy_handle);
177 logger(LOG_WARNING, "sendto: [%s]", evutil_socket_error_to_string(err));
178
179 retriable = (err == ENOBUFS || err == ENOMEM ||
180 err == EAGAIN || err == EINTR);
181
182 if (retriable == 0) {
183 udp_request_kill(udp_request);
184 return -1;
185 }
186 assert(DNS_QUERY_TIMEOUT < UCHAR_MAX);
187 if (++(udp_request->retries) > DNS_QUERY_TIMEOUT) {
188 udp_request_kill(udp_request);
189 return -1;
190 }
191 if (udp_request->sendto_retry_timer != NULL) {
192 ctx_cb = event_get_callback_arg(udp_request->sendto_retry_timer);
193 assert(ctx_cb != NULL);
194 assert(ctx_cb->udp_request == ctx->udp_request);
195 assert(ctx_cb->buffer == ctx->buffer);
196 } else {
197 if ((ctx_cb = malloc(sizeof *ctx_cb)) == NULL) {
198 udp_request_kill(udp_request);
199 return -1;
200 }
201 assert(ctx_cb ==
202 event_get_callback_arg(udp_request->sendto_retry_timer));
203 *ctx_cb = *ctx;
204 if ((udp_request->sendto_retry_timer =
205 evtimer_new(udp_request->context->event_loop,
206 sendto_with_retry_timer_cb, ctx_cb)) == NULL) {
207 free(ctx_cb);
208 udp_request_kill(udp_request);
209 return -1;
210 }
211 }
212 const struct timeval tv = {
213 .tv_sec = (time_t) UDP_DELAY_BETWEEN_RETRIES,.tv_usec = 0
214 };
215 evtimer_add(udp_request->sendto_retry_timer, &tv);
216 return -1;
217
218 }
219
220 static void
timeout_timer_cb(evutil_socket_t timeout_timer_handle,short ev_flags,void * const udp_request_)221 timeout_timer_cb(evutil_socket_t timeout_timer_handle, short ev_flags,
222 void *const udp_request_)
223 {
224 UDPRequest *const udp_request = udp_request_;
225
226 (void)ev_flags;
227 (void)timeout_timer_handle;
228 logger(LOG_DEBUG, "resolver timeout (UDP)");
229 udp_request_kill(udp_request);
230 }
231
232 /**
233 * Return 0 if served.
234 */
235 static int
self_serve_cert_file(struct context * c,struct dns_header * header,size_t dns_query_len,size_t max_len,UDPRequest * udp_request)236 self_serve_cert_file(struct context *c, struct dns_header *header,
237 size_t dns_query_len, size_t max_len, UDPRequest *udp_request)
238 {
239 int ret = dnscrypt_self_serve_cert_file(c, header, &dns_query_len, max_len);
240 if (ret == 0) {
241 SendtoWithRetryCtx retry_ctx = {
242 .udp_request = udp_request,
243 .handle = udp_request->client_proxy_handle,
244 .buffer = header,
245 .length = dns_query_len,
246 .flags = 0,
247 .dest_addr = (struct sockaddr *)&udp_request->client_sockaddr,
248 .dest_len = udp_request->client_sockaddr_len,
249 .cb = udp_request_kill
250 };
251 sendto_with_retry(&retry_ctx);
252 return 0;
253 }
254 logger(LOG_DEBUG, "failed to serve cert file, err: %d", ret);
255 return ret;
256 }
257
258 static void
client_to_proxy_cb(evutil_socket_t client_proxy_handle,short ev_flags,void * const context)259 client_to_proxy_cb(evutil_socket_t client_proxy_handle, short ev_flags,
260 void *const context)
261 {
262 logger(LOG_DEBUG, "client to proxy cb");
263 const size_t sizeof_dns_query = DNS_MAX_PACKET_SIZE_UDP;
264 static uint8_t *dns_query = NULL;
265 struct context *c = context;
266 UDPRequest *udp_request;
267 ssize_t nread;
268 size_t dns_query_len = 0;
269
270 if (dns_query == NULL && (dns_query = sodium_malloc(sizeof_dns_query)) == NULL) {
271 return;
272 }
273 (void)ev_flags;
274 assert(client_proxy_handle == c->udp_listener_handle);
275
276 udp_request = calloc(1, sizeof(*udp_request));
277 if (udp_request == NULL)
278 return;
279
280 udp_request->context = c;
281 udp_request->sendto_retry_timer = NULL;
282 udp_request->timeout_timer = NULL;
283 udp_request->client_proxy_handle = client_proxy_handle;
284 udp_request->client_sockaddr_len = sizeof(udp_request->client_sockaddr);
285 memset(&udp_request->status, 0, sizeof(udp_request->status));
286 nread = recvfrom(client_proxy_handle,
287 (void *)dns_query,
288 sizeof_dns_query,
289 0,
290 (struct sockaddr *)&udp_request->client_sockaddr,
291 &udp_request->client_sockaddr_len);
292 if (nread < 0) {
293 const int err = evutil_socket_geterror(client_proxy_handle);
294 if (!EVUTIL_ERR_RW_RETRIABLE(err)) {
295 logger(LOG_WARNING, "recvfrom(client): [%s]",
296 evutil_socket_error_to_string(err));
297 }
298 udp_request_kill(udp_request);
299 return;
300 }
301
302 if (nread < (ssize_t) DNS_HEADER_SIZE || nread > sizeof_dns_query) {
303 logger(LOG_WARNING, "Short query received");
304 udp_request_kill(udp_request);
305 return;
306 }
307
308 dns_query_len = (size_t) nread;
309 assert(dns_query_len <= sizeof_dns_query);
310
311 assert(SIZE_MAX - DNSCRYPT_MAX_PADDING - DNSCRYPT_QUERY_HEADER_SIZE >
312 dns_query_len);
313
314 udp_request->len = (uint16_t) dns_query_len;
315 // decrypt if encrypted
316 struct dnscrypt_query_header *dnscrypt_header =
317 (struct dnscrypt_query_header *)dns_query;
318 debug_assert(sizeof c->keypairs[0].crypt_publickey >= DNSCRYPT_MAGIC_HEADER_LEN);
319 if ((udp_request->cert =
320 find_cert(c, dnscrypt_header->magic_query, dns_query_len)) == NULL) {
321 udp_request->is_dnscrypted = false;
322 } else {
323 if (dnscrypt_server_uncurve(c, udp_request->cert,
324 udp_request->client_nonce,
325 udp_request->nmkey, dns_query,
326 &dns_query_len) != 0 || dns_query_len < DNS_HEADER_SIZE) {
327 logger(LOG_DEBUG, "Received a suspicious query from the client");
328 udp_request_kill(udp_request);
329 return;
330 }
331 udp_request->is_dnscrypted = true;
332 }
333
334 struct dns_header *header = (struct dns_header *)dns_query;
335
336 // self serve signed certificate for provider name?
337 if (!udp_request->is_dnscrypted) {
338 if (self_serve_cert_file(c, header, dns_query_len, sizeof_dns_query, udp_request) == 0)
339 return;
340 if (!c->allow_not_dnscrypted) {
341 logger(LOG_DEBUG, "Unauthenticated query received over UDP");
342 udp_request_kill(udp_request);
343 return;
344 }
345 }
346
347 udp_request->is_blocked = is_blocked(c, header, dns_query_len);
348
349 udp_request->id = ntohs(header->id);
350 if (questions_hash(&udp_request->hash, header, dns_query_len, c->namebuff, c->hash_key) != 0) {
351 logger(LOG_DEBUG, "Received a suspicious query from the client");
352 udp_request_kill(udp_request);
353 return;
354 }
355
356 static uint16_t gen;
357 udp_request->gen = gen++;
358 udp_request->status.is_in_queue = 1;
359 c->connections++;
360 RB_INSERT(UDPRequestQueue_, &c->udp_request_queue, udp_request);
361
362 udp_request->timeout_timer =
363 evtimer_new(udp_request->context->event_loop, timeout_timer_cb,
364 udp_request);
365 if (udp_request->timeout_timer) {
366 const struct timeval tv = {
367 .tv_sec = (time_t) DNS_QUERY_TIMEOUT,.tv_usec = 0
368 };
369 evtimer_add(udp_request->timeout_timer, &tv);
370 }
371
372 SendtoWithRetryCtx retry_ctx = {
373 .udp_request = udp_request,.handle =
374 c->udp_resolver_handle,.buffer = dns_query,.length =
375 dns_query_len,.flags = 0,.dest_addr =
376 (struct sockaddr *)&c->resolver_sockaddr,.dest_len =
377 c->resolver_sockaddr_len,.cb = client_to_proxy_cb_sendto_cb
378 };
379 sendto_with_retry(&retry_ctx);
380 }
381
382 /*
383 * Find corresponding request by DNS id and hash of questions.
384 */
385 static UDPRequest *
lookup_request(struct context * c,uint16_t id,uint64_t hash)386 lookup_request(struct context *c, uint16_t id, uint64_t hash)
387 {
388 UDPRequest *found_udp_request;
389 UDPRequest scanned_udp_request;
390
391 scanned_udp_request.hash = hash;
392 scanned_udp_request.id = id;
393 scanned_udp_request.gen = (uint16_t) 0U;
394 found_udp_request = RB_NFIND(UDPRequestQueue_, &c->udp_request_queue,
395 &scanned_udp_request);
396 if (found_udp_request == NULL ||
397 found_udp_request->hash != hash || found_udp_request->id != id) {
398 return NULL;
399 }
400 return found_udp_request;
401 }
402
403 static int
maybe_truncate(uint8_t * const dns_reply,size_t * const dns_reply_len_p,size_t query_len)404 maybe_truncate(uint8_t *const dns_reply, size_t *const dns_reply_len_p, size_t query_len)
405 {
406 struct dns_header *header = (struct dns_header *)dns_reply;
407 uint8_t *ansp;
408
409 if (*dns_reply_len_p <= sizeof(struct dns_header)) {
410 *dns_reply_len_p = 0;
411 return -1;
412 }
413 if (query_len >= *dns_reply_len_p) {
414 return 0;
415 }
416 if (!(ansp = skip_questions(header, *dns_reply_len_p))) {
417 *dns_reply_len_p = sizeof(struct dns_header);
418 return -1;
419 }
420 *dns_reply_len_p = (size_t) (ansp - dns_reply);
421 header->hb3 |= HB3_TC;
422 header->ancount = htons(0);
423 header->nscount = htons(0);
424 header->arcount = htons(0);
425
426 return 0;
427 }
428
429 static void
resolver_to_proxy_cb(evutil_socket_t proxy_resolver_handle,short ev_flags,void * const context)430 resolver_to_proxy_cb(evutil_socket_t proxy_resolver_handle, short ev_flags,
431 void *const context)
432 {
433 logger(LOG_DEBUG, "resolver to proxy cb");
434 const size_t sizeof_dns_reply = DNS_MAX_PACKET_SIZE_UDP;
435 static uint8_t *dns_reply = NULL;
436 struct context *c = context;
437 UDPRequest *udp_request = NULL;
438 struct sockaddr_storage resolver_sockaddr;
439 ev_socklen_t resolver_sockaddr_len = sizeof(struct sockaddr_storage);
440 ssize_t nread;
441 size_t dns_reply_len = (size_t) 0U;
442
443 (void)ev_flags;
444 if (dns_reply == NULL && (dns_reply = sodium_malloc(sizeof_dns_reply)) == NULL) {
445 return;
446 }
447 nread = recvfrom(proxy_resolver_handle,
448 (void *)dns_reply, sizeof_dns_reply, 0,
449 (struct sockaddr *)&resolver_sockaddr,
450 &resolver_sockaddr_len);
451 if (nread < 0) {
452 const int err = evutil_socket_geterror(proxy_resolver_handle);
453 if (!EVUTIL_ERR_RW_RETRIABLE(err)) {
454 logger(LOG_WARNING, "recvfrom(resolver): [%s]",
455 evutil_socket_error_to_string(err));
456 }
457 return;
458 }
459 if (evutil_sockaddr_cmp((const struct sockaddr *)&resolver_sockaddr,
460 (const struct sockaddr *)
461 &c->resolver_sockaddr, 1) != 0) {
462 logger(LOG_WARNING,
463 "Received a resolver reply from a different resolver");
464 return;
465 }
466 dns_reply_len = nread;
467
468 struct dns_header *header = (struct dns_header *)dns_reply;
469 uint16_t id = ntohs(header->id);
470 uint64_t hash;
471 if (questions_hash(&hash, header, dns_reply_len, c->namebuff, c->hash_key) != 0) {
472 logger(LOG_ERR, "Received an invalid response from the server");
473 return;
474 }
475 udp_request = lookup_request(c, id, hash);
476 if (udp_request == NULL) {
477 logger(LOG_DEBUG, "Received a reply that doesn't match any active query");
478 return;
479 }
480 size_t max_reply_size = DNS_MAX_PACKET_SIZE_UDP;
481 size_t max_len =
482 dns_reply_len + DNSCRYPT_MAX_PADDING + DNSCRYPT_REPLY_HEADER_SIZE;
483 if (max_len > max_reply_size)
484 max_len = max_reply_size;
485
486 if (udp_request->is_blocked) {
487 struct dns_header *p = (struct dns_header *) dns_reply;
488 SET_RCODE(p, REFUSED);
489 }
490 maybe_truncate(dns_reply, &dns_reply_len, udp_request->len);
491
492 if (udp_request->is_dnscrypted) {
493 if (dnscrypt_server_curve
494 (c, udp_request->cert, udp_request->client_nonce, udp_request->nmkey, dns_reply,
495 &dns_reply_len, max_len) != 0) {
496 logger(LOG_ERR, "Curving reply failed.");
497 return;
498 }
499 }
500
501 SendtoWithRetryCtx retry_ctx = {
502 .udp_request = udp_request,.handle =
503 udp_request->client_proxy_handle,.buffer =
504 dns_reply,.length = dns_reply_len,.flags = 0,.dest_addr =
505 (struct sockaddr *)&udp_request->client_sockaddr,.dest_len =
506 udp_request->client_sockaddr_len,.cb = udp_request_kill
507 };
508 sendto_with_retry(&retry_ctx);
509 }
510
511 int
udp_listener_bind(struct context * c)512 udp_listener_bind(struct context *c)
513 {
514 // listen socket & bind
515 assert(c->udp_listener_handle == -1);
516
517 if ((c->udp_listener_handle =
518 socket(c->local_sockaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
519 logger(LOG_ERR, "Unable to create a socket (UDP)");
520 return -1;
521 }
522
523 udp_tune(c->udp_listener_handle);
524
525 evutil_make_socket_closeonexec(c->udp_listener_handle);
526 evutil_make_socket_nonblocking(c->udp_listener_handle);
527 if (bind
528 (c->udp_listener_handle, (struct sockaddr *)&c->local_sockaddr,
529 c->local_sockaddr_len) != 0) {
530 logger(LOG_ERR, "Unable to bind (UDP) [%s]",
531 evutil_socket_error_to_string(evutil_socket_geterror
532 (c->udp_listener_handle)));
533 evutil_closesocket(c->udp_listener_handle);
534 c->udp_listener_handle = -1;
535 return -1;
536 }
537
538 // resolver socket
539 assert(c->udp_resolver_handle == -1);
540 if ((c->udp_resolver_handle =
541 socket(c->resolver_sockaddr.ss_family, SOCK_DGRAM,
542 IPPROTO_UDP)) == -1) {
543 logger(LOG_ERR, "Unable to create a socket to the resolver");
544 evutil_closesocket(c->udp_resolver_handle);
545 c->udp_listener_handle = -1;
546 }
547 evutil_make_socket_closeonexec(c->udp_resolver_handle);
548 evutil_make_socket_nonblocking(c->udp_resolver_handle);
549 udp_tune(c->udp_resolver_handle);
550
551 /* Bind source IP:port if --outgoing-address is provided */
552 if(c->outgoing_address &&
553 bind(c->udp_resolver_handle, (struct sockaddr *)&c->outgoing_sockaddr,
554 c->outgoing_sockaddr_len) != 0) {
555 logger(LOG_ERR, "Unable to bind (UDP) [%s]",
556 evutil_socket_error_to_string(evutil_socket_geterror
557 (c->udp_resolver_handle)));
558 evutil_closesocket(c->udp_resolver_handle);
559 c->udp_resolver_handle = -1;
560 return -1;
561 }
562
563 RB_INIT(&c->udp_request_queue);
564
565 return 0;
566 }
567
568 void
udp_listener_stop(struct context * c)569 udp_listener_stop(struct context *c)
570 {
571 event_free(c->udp_resolver_event);
572 c->udp_resolver_event = NULL;
573
574 while (udp_listener_kill_oldest_request(c) == 0);
575 logger(LOG_INFO, "UDP listener shut down");
576 }
577
578 int
udp_listener_start(struct context * c)579 udp_listener_start(struct context *c)
580 {
581 assert(c->udp_listener_handle != -1);
582 if ((c->udp_listener_event =
583 event_new(c->event_loop, c->udp_listener_handle, EV_READ | EV_PERSIST,
584 client_to_proxy_cb, c)) == NULL) {
585 return -1;
586 }
587 if (event_add(c->udp_listener_event, NULL) != 0) {
588 udp_listener_stop(c);
589 return -1;
590 }
591
592 assert(c->udp_resolver_handle != -1);
593 if ((c->udp_resolver_event =
594 event_new(c->event_loop, c->udp_resolver_handle, EV_READ | EV_PERSIST,
595 resolver_to_proxy_cb, c)) == NULL) {
596 udp_listener_stop(c);
597 return -1;
598 }
599 if (event_add(c->udp_resolver_event, NULL) != 0) {
600 udp_listener_stop(c);
601 return -1;
602 }
603 return 0;
604 }
605