1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 * 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, 2019,
4 * 2020
5 * Inferno Nettverk A/S, Norway. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. The above copyright notice, this list of conditions and the following
11 * disclaimer must appear in all copies of the software, derivative works
12 * or modified versions, and any portions thereof, aswell as in all
13 * supporting documentation.
14 * 2. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by
17 * Inferno Nettverk A/S, Norway.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Inferno Nettverk A/S requests users of this software to return to
33 *
34 * Software Distribution Coordinator or sdc@inet.no
35 * Inferno Nettverk A/S
36 * Oslo Research Park
37 * Gaustadall�en 21
38 * NO-0349 Oslo
39 * Norway
40 *
41 * any improvements or extensions that they make and grant Inferno Nettverk A/S
42 * the rights to redistribute these changes.
43 *
44 */
45
46 #include "common.h"
47 #include "config_parse.h"
48
49 static const char rcsid[] =
50 "$Id: dante_udp.c,v 1.93.4.3.2.3.4.3 2020/11/11 16:11:58 karls Exp $";
51
52
53 udpheader_t *
54 getudptarget(const char *buf, const size_t buflen, udpheader_t *header,
55 size_t *headerlen, char *emsg, const size_t emsglen);
56 /*
57 * Gets the target address for the SOCKS UDP packet stored in "buf".
58 * "buflen" gives the length of the received UDP packet.
59 *
60 * On success "header" is returned, filled in appropriately.
61 * "headerlen" gives the length of the SOCKS UDP header. Payload will
62 * start at the first byte following it.
63 *
64 * On failure NULL is returned. "emsg" of "emsglen" will then contain an
65 * error string describing the reason for failure.
66 */
67
68
69 static int
70 fromaddr_as_expected(struct sockaddr_storage *expected,
71 const struct sockaddr_storage *from,
72 char *emsg, size_t emsglen);
73
74 /*
75 * Checks that the packet received on socket "s", from "from", matches the
76 * expected address as given in "expected".
77 * If so, the socket is connected to "from" and "expected" is updated to
78 * contain the address of "from".
79 *
80 * Returns if the from address is as expected, or false otherwise. If false,
81 * "emsg" may be filled with more information as to what went wrong or did
82 * not match.
83 */
84
85 extern int rawsocket;
86
87 iostatus_t
io_udp_client2target(control,client,twotargets,cauth,state,clog,dlog,badfd,packetrule,bwused)88 io_udp_client2target(control, client, twotargets, cauth, state,
89 clog, dlog, badfd, packetrule, bwused)
90 sockd_io_direction_t *control;
91 sockd_io_direction_t *client;
92 sockd_io_direction_t *twotargets;
93 const authmethod_t *cauth;
94 connectionstate_t *state;
95 int *badfd;
96 iologaddr_t *clog;
97 iologaddr_t *dlog;
98 rule_t *packetrule;
99 size_t *bwused;
100 {
101 /*
102 * Dante has only one client per i/o session, but each UDP-based i/o
103 * session can have up to two targets (ipv4 and ipv6). When transferring
104 * data from the client we thus want to bill it to the correct target
105 * target address.
106 */
107 const char *function = "io_udp_client2target()";
108 iostatus_t iostatus = IO_NOERROR;
109 udptarget_t *target = NULL;
110 recvfrom_info_t recvflags;
111 sendto_info_t sendtoflags;
112 udpheader_t header;
113 struct sockaddr_storage from, targetaddr;
114 socklen_t len;
115 ssize_t w, r;
116 size_t headerlen, payloadlen, emsglen;
117 char hosta[MAXSOCKSHOSTSTRING], hostb[MAXSOCKSHOSTSTRING], emsg[2048],
118 buf[SOCKD_BUFSIZE + sizeof(udpheader_t)], *payload;
119 int sametarget, gaierr,
120 doconnect = 0,
121 permit = 0,
122 icmp_type = ICMP_TYPE_UNREACHABLE,
123 icmp_code = ICMP_CODE_UNREACHABLE_PORT;
124
125 recvflags.side = INTERNALIF;
126 recvflags.peer = client->raddr;
127 recvflags.type = SOCK_DGRAM;
128
129 len = sizeof(from);
130 if ((r = socks_recvfrom(client->s,
131 buf,
132 sizeof(buf),
133 0,
134 &from,
135 &len,
136 &recvflags,
137 &client->auth)) == -1) {
138 if (ERRNOISPREVIOUSPACKET(errno)) {
139 /*
140 * error is from a previous packet sent by us out on this socket,
141 * i.e., /from target/ to client.
142 * Note that Linux apparently can return this error even if the
143 * socket is not connected.
144 *
145 * Don't treat this as fatal; more packets could come
146 * and they may be accepted by the client. As long
147 * as we still have the control connection, assume
148 * the client is alive. When we no longer have the
149 * control connection, we delete this io.
150 */
151 struct sockaddr_storage *packetsrc;
152 struct sockaddr_storage *receivedonaddr;
153 const int oldcommand = state->command;
154 state->command = SOCKS_UDPREPLY;
155
156 if (twotargets->dstc <= 1) {
157 *badfd = twotargets->dstv[0].s;
158 SASSERTX(*badfd != -1);
159
160 receivedonaddr = &twotargets->dstv[0].laddr;
161 packetsrc = &twotargets->dstv[0].raddr;
162 }
163 else {
164 /*
165 * don't know which target socket was used.
166 */
167 *badfd = -1;
168 receivedonaddr = NULL;
169 packetsrc = NULL;
170 }
171
172 emsglen = snprintf(emsg, sizeof(emsg),
173 "%s (delayed error)", strerror(errno));
174
175 iolog(packetrule,
176 state,
177 OPERATION_TMPERROR,
178 dlog,
179 clog,
180 NULL,
181 NULL,
182 emsg,
183 emsglen);
184
185 state->command = oldcommand;
186
187 send_icmperror(rawsocket,
188 receivedonaddr,
189 packetsrc,
190 &client->raddr,
191 -1,
192 -1,
193 icmp_type,
194 icmp_code);
195
196
197 return IO_TMPERROR;
198 }
199
200 *badfd = client->s;
201
202 if (ERRNOISTMP(errno))
203 return IO_EAGAIN;
204 else {
205 log_unexpected_udprecv_error(function, client->s, errno, INTERNALIF);
206 return IO_IOERROR;
207 }
208 }
209
210 iostatus = io_packet_received(&recvflags, r, &from, &client->laddr);
211
212 if (iostatus != IO_NOERROR) {
213 *badfd = client->s;
214 return iostatus;
215 }
216
217 sockaddr2sockshost(&from, &clog->peer);
218 clog->peer_isset = 1;
219
220 slog(LOG_DEBUG, "%s: received udp packet from %s, length: %ld",
221 function, sockaddr2string(&from, NULL, 0), (long)r);
222
223 /*
224 * Read udp packet. Now figure out if it should be forwarded, where it
225 * should be forwarded, and from what address we should forward it.
226 */
227
228 *emsg = NUL;
229
230 if (!client->state.isconnected) {
231 /*
232 * Have not yet connected to the client, so need to check whether
233 * the packet is really from our expected client. After the connect,
234 * the kernel takes care of this for us.
235 *
236 * XXX or, what happens if somebody else also sends packets that ends
237 * up in client the socket buffer before we connect to the real client?
238 * Do we get those packet too from recvfrom(), even after we connect to
239 * a different address? Should check this out.
240 */
241 const int blocked
242 = !fromaddr_as_expected(&client->raddr, &from, emsg, sizeof(emsg));
243
244 if (!blocked) {
245 sockaddr2sockshost(&client->raddr, &client->host);
246
247 /* More efficient to be connected. */
248 if (socks_connecthost(client->s,
249 INTERNALIF,
250 &client->host,
251 NULL,
252 NULL,
253 (long)-1,
254 emsg,
255 sizeof(emsg)) != 0 ) {
256 swarnx("%s: strange ... could not connect(2) back to new UDP "
257 "client that sent us its first packet from %s: %s",
258 function, sockaddr2string(&client->raddr, NULL, 0), emsg);
259
260 *badfd = client->s;
261 iostatus = IO_ERROR;
262 }
263 else
264 client->state.isconnected = 1;
265 }
266
267 SASSERTX(!((iostatus != IO_NOERROR) && blocked));
268
269 if (iostatus != IO_NOERROR || blocked) {
270 iolog(packetrule,
271 state,
272 IOOP(blocked, iostatus),
273 clog,
274 dlog,
275 NULL,
276 NULL,
277 emsg,
278 strlen(emsg));
279
280 return blocked ? IO_TMPERROR : iostatus;
281 }
282
283 SASSERTX(client->state.isconnected);
284 }
285 else
286 /*
287 * already connected to client. Kernel should make sure address is
288 * correct.
289 */
290
291 SASSERTX(iostatus == IO_NOERROR);
292
293 if (getudptarget(buf, (size_t)r, &header, &headerlen, emsg, sizeof(emsg))
294 == NULL) {
295 slog(LOG_DEBUG,
296 "%s: getudptarget() failed for packet of length %lu from client %s, "
297 "received on local address %s for target %s: %s",
298 function,
299 (unsigned long)r,
300 sockaddr2string(&client->raddr, hosta, sizeof(hosta)),
301 sockaddr2string(&client->laddr, hostb, sizeof(hostb)),
302 header.host.atype == SOCKS_ADDR_NOTSET ?
303 "N/A" : sockshost2string(&header.host, NULL, 0),
304 emsg);
305
306 icmp_code = ICMP_CODE_UNREACHABLE_DESTHOSTUNKNOWN;
307 iostatus = IO_TMPERROR;
308 }
309
310 if (header.host.atype != SOCKS_ADDR_NOTSET) {
311 /*
312 * Whether getudptarget() failed or not, we did get a hostname at
313 * least, so update for logging.
314 */
315 dlog->peer = header.host;
316 dlog->peer_isset = 1;
317 }
318 else
319 dlog->peer_isset = 0;
320
321 if (iostatus == IO_NOERROR) {
322 SASSERTX(header.host.atype != SOCKS_ADDR_NOTSET);
323
324 SASSERTX(headerlen > 0);
325 payload = buf + headerlen;
326 payloadlen = r - headerlen;
327
328 sockshost2sockaddr2(&header.host,
329 &targetaddr,
330 &gaierr,
331 emsg,
332 sizeof(emsg));
333
334 if (IPADDRISBOUND(&targetaddr)) {
335 /*
336 * we want to log ipaddress used, not (a possible) hostname sent
337 * by the client.
338 */
339 sockaddr2sockshost(&targetaddr, &dlog->peer);
340 SASSERTX(dlog->peer_isset);
341 }
342 else {
343 if (gaierr != 0) { /* dns-error. */
344 SASSERTX(header.host.atype == SOCKS_ADDR_DOMAIN);
345 log_resolvefailed(header.host.addr.domain, EXTERNALIF, gaierr);
346
347 snprintf(emsg, sizeof(emsg),
348 "could not resolve target address %s: %s ",
349 sockshost2string(&header.host, NULL, 0),
350 gai_strerror(gaierr));
351 }
352 else { /* some other, non-dns error. */
353 snprintf(emsg, sizeof(emsg),
354 "could not resolve target address %s. Non-DNS error: %s ",
355 sockshost2string(&header.host, NULL, 0),
356 strerror(errno));
357 }
358
359 iostatus = IO_TMPERROR;
360 icmp_code = ICMP_CODE_UNREACHABLE_DESTHOSTUNKNOWN;
361 }
362 }
363 else {
364 bzero(&targetaddr, sizeof(targetaddr));
365 SET_SOCKADDR(&targetaddr, AF_INET);
366 }
367
368 if (iostatus != IO_NOERROR) {
369 iolog(packetrule,
370 state,
371 IOOP(packetrule->verdict == VERDICT_BLOCK, iostatus),
372 clog,
373 dlog,
374 NULL,
375 NULL,
376 emsg,
377 strlen(emsg));
378
379 /*
380 * This may be considered a violation of rfc 1928, which says UDP
381 * packets should be forwarded or dropped "silently", but what does
382 * silently mean? Just not closing the control connection (obviously),
383 * or not providing any ICMP errors either?
384 * Allowing the latter seems useful, so keep it until we have reason to
385 * think it breaks things for someone.
386 */
387 send_icmperror(rawsocket,
388 &client->laddr,
389 &client->raddr,
390 IPADDRISBOUND(&targetaddr) ? &targetaddr : NULL,
391 -1,
392 -1,
393 icmp_type,
394 iostatus == IO_NOERROR ?
395 ICMP_CODE_UNREACHABLE_HOSTPROHIBITED : icmp_code);
396
397 return IO_TMPERROR;
398 }
399
400 /*
401 * Ok, received a packet and things look ok so far. Now check the rules
402 * for whether the packet is to be allowed through or not.
403 */
404
405 slog(LOG_DEBUG,
406 "%s: packet of length %lu (payload length %lu) from client %s "
407 "received on local address, %s for target %s",
408 function,
409 (unsigned long)r,
410 (unsigned long)payloadlen,
411 sockaddr2string(&client->raddr, hosta, sizeof(hosta)),
412 sockaddr2string(&client->laddr, hostb, sizeof(hostb)),
413 sockshost2string(&header.host, NULL, 0));
414
415 /*
416 * Do we have a saved rule from before? If so, see if we can reuse it
417 * and avoid having to do a new rule-lookup.
418 */
419 if (client->state.use_saved_srule) {
420 int addtarget;
421
422 SASSERTX(twotargets->dstc > 0);
423
424 /*
425 * Can reuse, but only if target is the same as last time.
426 * First figure out what target object is the correct one to use,
427 * so we know what the target was the last time.
428 */
429
430 switch (twotargets->dstc) {
431 case 1:
432 /*
433 * Have one target socket created already. Is it of the
434 * same addressfamily as the packet we now received?
435 */
436 if (twotargets->dstv[0].raddr.ss_family == targetaddr.ss_family) {
437 target = &twotargets->dstv[0]; /* yes. */
438 addtarget = 0;
439 }
440 else /* nope, must create a new socket for this target. */
441 addtarget = 1;
442
443 break;
444
445 case 2:
446 /*
447 * Have two target sockets created already. One of them
448 * must be of the correct addressfamily.
449 */
450 if (twotargets->dstv[0].raddr.ss_family == targetaddr.ss_family)
451 target = &twotargets->dstv[0]; /* this is the one. */
452 else {
453 SASSERTX(twotargets->dstv[1].raddr.ss_family
454 == targetaddr.ss_family);
455
456 target = &twotargets->dstv[1]; /* this is the one. */
457 }
458
459 addtarget = 0;
460 break;
461
462 default:
463 SERRX(twotargets->dstc);
464 }
465
466 if (addtarget) {
467 SASSERTX(twotargets->dstc == 1);
468 SASSERTX(twotargets->dstv[0].raddr.ss_family != targetaddr.ss_family);
469
470 slog(LOG_DEBUG,
471 "%s: new to add a new targetsocket due to change of af. "
472 "Have %s, need %s",
473 function,
474 safamily2string(twotargets->dstv[0].raddr.ss_family),
475 safamily2string(targetaddr.ss_family));
476
477 SASSERTX(twotargets->dstv[twotargets->dstc].s == 0);
478
479 if (initclient(control->s,
480 &client->laddr,
481 &client->raddr,
482 &header.host,
483 &targetaddr,
484 packetrule,
485 emsg,
486 sizeof(emsg),
487 &twotargets->dstv[twotargets->dstc]) != NULL) {
488 target = addclient(&client->laddr,
489 &twotargets->dstv[twotargets->dstc],
490 &twotargets->dstc,
491 &twotargets->dstcmax,
492 &twotargets->dstv,
493 state,
494 packetrule);
495
496 SASSERTX(target != NULL);
497 SASSERTX(twotargets->dstc == 2);
498
499 doconnect = sockscf.udpconnectdst;
500 }
501 else {
502 /*
503 * still have the other (first) target socket, so don't consider
504 * this a fatal error.
505 */
506 iostatus = IO_TMPERROR;
507
508 iolog(packetrule,
509 state,
510 IOOP(packetrule->verdict == VERDICT_BLOCK, iostatus),
511 clog,
512 dlog,
513 NULL,
514 NULL,
515 emsg,
516 strlen(emsg));
517
518 send_icmperror(rawsocket,
519 &client->laddr,
520 &client->raddr,
521 &targetaddr,
522 -1,
523 -1,
524 icmp_type,
525 icmp_code);
526
527 return iostatus;
528 }
529
530 sametarget = 0;
531 }
532 else
533 sametarget = addrmatch(sockshost2ruleaddr(&target->raddrhost, NULL),
534 &header.host,
535 NULL,
536 SOCKS_UDP,
537 0);
538
539 twotargets->s = target->s; /* update as soon as known. */
540
541 sockaddr2sockshost(&target->laddr, &dlog->local);
542 dlog->local_isset = 1;
543
544 slog(LOG_DEBUG,
545 "%s: use_saved_srule set. UDP packet #%"PRIu64" from %s. "
546 "Destination %s. Already set up with socks-rule #%lu (%s) "
547 "for previous destination %s (%ssame as now)",
548 function,
549 client->read.packets + 1,
550 sockaddr2string(&client->raddr, NULL, 0),
551 sockshost2string(&header.host, NULL, 0),
552 (unsigned long)packetrule->number,
553 verdict2string(packetrule->verdict),
554 sockshost2string(&target->raddrhost, hosta, sizeof(hosta)),
555 sametarget ? "" : "not ");
556
557 if (sametarget)
558 permit = (packetrule->verdict == VERDICT_PASS);
559 else {
560 sockshost_t targethost;
561 char clientstr[MAXSOCKADDRSTRING], dstbefore[MAXSOCKSHOSTSTRING],
562 dstnow[MAXSOCKSHOSTSTRING];
563
564 SASSERTX(iostatus == IO_NOERROR);
565
566 permit = rulespermit(control->s,
567 &control->raddr,
568 &control->laddr,
569 cauth,
570 &control->auth,
571 packetrule,
572 state,
573 &client->host,
574 &header.host,
575 &targethost,
576 emsg,
577 sizeof(emsg));
578
579 if (permit)
580 header.host = targethost;
581
582 if (!addtarget)
583 slog(LOG_DEBUG,
584 "%s: destination host for packet from client %s changed "
585 "from %s to %s%s",
586 function,
587 sockaddr2string(&control->raddr, clientstr, sizeof(clientstr)),
588 sockshost2string(&target->raddrhost,
589 dstbefore,
590 sizeof(dstbefore)),
591 sockshost2string(&header.host,
592 dstnow,
593 sizeof(dstnow)),
594 permit ?
595 "" : ". Packets to this address are not permitted however");
596
597 /*
598 * Target destination changed.
599 * Unconnect the socket if it's connected and keep it unconnected,
600 * so we can receive replies from the previous destination too.
601 *
602 * We do this regardless of whether the new destination is
603 * permitted or not, as we have no reason to assume the previous
604 * (permitted) target is any more likely to be the next target
605 * than this (possibly, not permitted) target. I.e., we want to
606 * cache the negative rulespermit() verdict also.
607 */
608
609 if (target->isconnected) {
610 sockd_unconnect(target->s, &target->raddr);
611 target->isconnected = 0;
612 }
613
614 target->raddrhost = header.host;
615 target->raddr = targetaddr;
616
617 if (permit) {
618 /* possibly the socket options differ in this rule. */
619 setconfsockoptions(target->s,
620 client->s,
621 SOCKS_UDP,
622 0,
623 packetrule->socketoptionc,
624 packetrule->socketoptionv,
625 SOCKETOPT_PRE | SOCKETOPT_ANYTIME,
626 0);
627 }
628 }
629
630 if (permit) {
631 if (redirect(target->s,
632 &target->laddr,
633 &target->raddrhost,
634 state->command,
635 &packetrule->rdr_from,
636 &packetrule->rdr_to) == 0)
637 sockaddr2sockshost(&target->laddr, &dlog->local);
638 else {
639 snprintf(emsg, sizeof(emsg),
640 "redirect failed: %s", strerror(errno));
641
642 if (errno != 0)
643 swarnx("%s: %s", function, emsg);
644
645 iostatus = IO_TMPERROR;
646 }
647 }
648 }
649 else {
650 /*
651 * No saved rule we can reuse. Must do a new rule-lookup.
652 */
653 sockshost_t targethost;
654 int addtarget;
655
656 permit = rulespermit(control->s,
657 &control->raddr,
658 &control->laddr,
659 cauth,
660 &control->auth,
661 packetrule,
662 state,
663 &client->host,
664 &header.host,
665 &targethost,
666 emsg,
667 sizeof(emsg));
668
669 if (permit) {
670 /*
671 * Ok, packet is permitted. Now figure out what target struct to
672 * use for forwarding this packet.
673 */
674
675 header.host = targethost;
676
677 switch (twotargets->dstc) {
678 case 0:
679 /*
680 * No target sockets created yet, so create the first now.
681 */
682 addtarget = 1;
683 break;
684
685 case 1:
686 /*
687 * Have one target socket created already. Is it of the
688 * same addressfamily as the target?
689 */
690 if (twotargets->dstv[0].raddr.ss_family
691 == targetaddr.ss_family) {
692 target = &twotargets->dstv[0]; /* yes. */
693 addtarget = 0;
694 }
695 else
696 addtarget = 1;
697
698 break;
699
700 case 2:
701 /*
702 * Have two target sockets created already. One of them must
703 * be of the correct addressfamily.
704 */
705 if (twotargets->dstv[0].raddr.ss_family == targetaddr.ss_family)
706 target = &twotargets->dstv[0]; /* this is the one. */
707 else {
708 SASSERTX(twotargets->dstv[1].raddr.ss_family
709 == targetaddr.ss_family);
710
711 target = &twotargets->dstv[1]; /* this is the one. */
712 }
713
714 addtarget = 0;
715 break;
716
717 default:
718 SERRX(twotargets->dstc);
719 }
720
721 if (addtarget) {
722 SASSERTX(twotargets->dstc < 2);
723
724 if (initclient(control->s,
725 &client->laddr,
726 &client->raddr,
727 &header.host,
728 &targetaddr,
729 packetrule,
730 emsg,
731 sizeof(emsg),
732 &twotargets->dstv[twotargets->dstc]) != NULL) {
733 target = addclient(&client->laddr,
734 &twotargets->dstv[twotargets->dstc],
735 &twotargets->dstc,
736 &twotargets->dstcmax,
737 &twotargets->dstv,
738 state,
739 packetrule);
740
741 SASSERTX(target != NULL);
742 SASSERTX(twotargets->dstc > 0);
743
744 doconnect = sockscf.udpconnectdst;
745 }
746 else
747 iostatus = IO_TMPERROR;
748 }
749
750 if (target != NULL) {
751 sockaddr2sockshost(&target->laddr, &dlog->local);
752 dlog->local_isset = 1;
753 twotargets->s = target->s; /* update as soon as known. */
754 }
755 }
756 else {
757 /*
758 * This packet was not permitted.
759 */
760
761 if (twotargets->dstc == 0) {
762 /*
763 * No targets sockets added yet and this packet from the client
764 * was not permitted. Is it possible other packets from this
765 * client will be permitted? Try. If not, we can close this
766 * session as there's no point in having the client keep
767 * sending us packets if all of them will be blocked.
768 * A bit unfortunate since we already told the client that
769 * the udpassociate was ok, but that was only because it did
770 * not tell us what address it would be sending us packets from.
771 */
772 rule_t tryrule;
773 const int try_permits = rulespermit(control->s,
774 &control->raddr,
775 &control->laddr,
776 cauth,
777 &control->auth,
778 &tryrule,
779 state,
780 &client->host,
781 NULL, /* try any dst. */
782 NULL,
783 NULL,
784 0);
785
786 if (!try_permits) {
787 slog(LOG_DEBUG,
788 "%s: only now we have the complete UDP client address (%s) "
789 "for the client that connected to us from %s. "
790 "Packets from that client address are not permitted "
791 "according to current rules however, regardless of their "
792 "target destination. We thus close this session now, "
793 "though we are unfortunately unable to tell the client why",
794 function,
795 sockaddr2string(&client->raddr, hosta, sizeof(hosta)),
796 sockaddr2string(&control->raddr, hostb, sizeof(hostb)));
797
798 iostatus = IO_BLOCK;
799 }
800 }
801 }
802
803 if (iostatus != IO_NOERROR || !permit) {
804 iolog(packetrule,
805 state,
806 IOOP(!permit, iostatus),
807 clog,
808 dlog,
809 NULL,
810 NULL,
811 emsg,
812 strlen(emsg));
813
814 send_icmperror(rawsocket,
815 &client->laddr,
816 &client->raddr,
817 &targetaddr,
818 -1,
819 -1,
820 icmp_type,
821 iostatus == IO_NOERROR ?
822 ICMP_CODE_UNREACHABLE_HOSTPROHIBITED : icmp_code);
823
824 if (iostatus != IO_NOERROR)
825 return iostatus;
826 else
827 return IO_TMPBLOCK;
828 }
829
830 if (addtarget) {
831 sametarget = 0;
832
833 slog(LOG_DEBUG, "%s: new target: %s",
834 function, sockshost2string(&header.host, hostb, sizeof(hostb)));
835 }
836 else {
837 sametarget = addrmatch(sockshost2ruleaddr(&target->raddrhost, NULL),
838 &header.host,
839 NULL,
840 SOCKS_UDP,
841 0);
842
843 slog(LOG_DEBUG,
844 "%s: previous target: %s, current: %s (%s before)",
845 function,
846 sockshost2string(&target->raddrhost, hosta, sizeof(hosta)),
847 sockshost2string(&header.host, hostb, sizeof(hostb)),
848 sametarget ? "same as" : "different from");
849 }
850
851 if (target->isconnected && !sametarget) {
852 /*
853 * need to unconnect the socket so we can continue to receive
854 * packets from the old destination.
855 */
856 sockd_unconnect(target->s, &target->raddr);
857 target->isconnected = 0;
858 }
859
860 target->raddr = targetaddr;
861 }
862
863 SASSERTX(target != NULL);
864
865 target->client_read.bytes += recvflags.fromsocket;
866 target->client_read.packets += 1;
867
868 client->state.use_saved_srule = 0; /* XXX temporarily disabled. Bug. */
869
870 if (permit && iostatus == IO_NOERROR) {
871 /*
872 * Should we connect to the destination?
873 * If the client will only be sending udp packets to one address, it
874 * is more efficient to connect the socket to that address.
875 * If we do that we must however be sure to unconnect the socket before
876 * sending target on it again if the client wants to send to a new
877 * address, and from that point on, leave the socket unconnected,
878 * so that possible future packets from the address we first
879 * sent/connected to will also be received.
880 */
881
882 if (doconnect) {
883 slog(LOG_DEBUG, "%s: connecting fd %d to %s, for client %s",
884 function,
885 target->s,
886 sockshost2string(&header.host, hosta, sizeof(hosta)),
887 sockshost2string(&client->host, hostb, sizeof(hostb)));
888
889 if (socks_connecthost(target->s,
890 EXTERNALIF,
891 &header.host,
892 NULL,
893 NULL,
894 (long)-1,
895 emsg,
896 sizeof(emsg)) == -1) {
897 iolog(packetrule,
898 state,
899 OPERATION_TMPERROR,
900 clog,
901 dlog,
902 NULL,
903 NULL,
904 emsg,
905 strlen(emsg));
906
907 iostatus = IO_TMPERROR;
908 return iostatus;
909 }
910
911 target->isconnected = 1;
912 }
913
914 sendtoflags.side = EXTERNALIF;
915 w = socks_sendto(target->s,
916 payload,
917 payloadlen,
918 0,
919 target->isconnected ? NULL : &target->raddr,
920 target->isconnected ?
921 (socklen_t)0 : (socklen_t)sizeof(target->raddr),
922 &sendtoflags,
923 NULL);
924
925 if (w >= 0) {
926 iostatus = io_packet_sent(payloadlen,
927 w,
928 &recvflags.ts,
929 &client->raddr,
930 &target->raddr,
931 emsg,
932 sizeof(emsg));
933
934 *bwused = w;
935
936 target->target_written.bytes += sendtoflags.tosocket;
937 target->target_written.packets += 1;
938
939 gettimeofday_monotonic(&target->lastio);
940
941 /*
942 * Also update twotargets so caller can know how much i/o was done
943 * on this call, as otherwise he would have no way of knowing this
944 * because he could not beforehand know what our target socket would
945 * be (could even be a new target).
946 */
947 twotargets->written.bytes += sendtoflags.tosocket;
948 twotargets->written.packets += 1;
949 }
950 else {
951 snprintf(emsg, sizeof(emsg), "sendto of %lu bytes failed: %s",
952 (unsigned long)payloadlen, strerror(errno));
953
954 iostatus = IOSTATUS_UDP_SEND_FAILED(errno);
955 *badfd = target->s;
956 }
957 }
958 else
959 w = -1;
960
961 if (iostatus != IO_NOERROR || !permit) {
962 iolog(packetrule,
963 state,
964 IOOP(!permit, iostatus),
965 clog,
966 dlog,
967 NULL,
968 NULL,
969 emsg,
970 strlen(emsg));
971
972 send_icmperror(rawsocket,
973 &client->laddr,
974 &client->raddr,
975 &targetaddr,
976 -1,
977 -1,
978 icmp_type,
979 iostatus == IO_NOERROR ?
980 ICMP_CODE_UNREACHABLE_HOSTPROHIBITED : icmp_code);
981
982 if (iostatus != IO_NOERROR)
983 return iostatus;
984 else
985 return IO_TMPBLOCK;
986 }
987
988 SASSERTX(w == (ssize_t)payloadlen);
989
990 iolog(packetrule,
991 state,
992 OPERATION_IO,
993 clog,
994 dlog,
995 NULL,
996 NULL,
997 payload,
998 payloadlen);
999
1000 return IO_NOERROR;
1001 }
1002
1003 iostatus_t
io_udp_target2client(control,client,twotargets,state,clog,dlog,badfd,packetrule,bwused)1004 io_udp_target2client(control, client, twotargets, state,
1005 clog, dlog, badfd, packetrule, bwused)
1006 sockd_io_direction_t *control;
1007 sockd_io_direction_t *client;
1008 sockd_io_direction_t *twotargets;
1009 connectionstate_t *state;
1010 iologaddr_t *clog;
1011 iologaddr_t *dlog;
1012 int *badfd;
1013 rule_t *packetrule;
1014 size_t *bwused;
1015 {
1016 /*
1017 * Received a reply from one of the up to two twotargets sockets (one for
1018 * ipv4 and one for ipv6).
1019 * When called we already know what the twotargets socket is and things
1020 * should be set up correctly.
1021 */
1022 const char *function = "io_udp_target2client()";
1023 iostatus_t iostatus = IO_NOERROR;
1024 udptarget_t *target = NULL;
1025 sendto_info_t sendtoflags;
1026 recvfrom_info_t recvflags;
1027 struct sockaddr_storage from, hostaddr;
1028 socklen_t len;
1029 ssize_t w, r;
1030 size_t headerlen, payloadlen, emsglen, originallen;
1031 char hosta[MAXSOCKSHOSTSTRING], hostb[MAXSOCKSHOSTSTRING], emsg[1024],
1032 buf[SOCKD_BUFSIZE + sizeof(udpheader_t)], *payload;
1033 int samesrc, permit = 0,
1034 icmp_type = ICMP_TYPE_UNREACHABLE,
1035 icmp_code = ICMP_CODE_UNREACHABLE_PORT;
1036
1037 target = clientofsocket(twotargets->s, twotargets->dstc, twotargets->dstv);
1038 SASSERTX(target != NULL);
1039
1040 *emsg = NUL;
1041
1042 recvflags.side = EXTERNALIF;
1043 recvflags.peer = twotargets->raddr;
1044 recvflags.type = SOCK_DGRAM;
1045
1046 len = sizeof(from);
1047 if ((r = socks_recvfrom(twotargets->s,
1048 buf,
1049 sizeof(buf),
1050 0,
1051 &from,
1052 &len,
1053 &recvflags,
1054 &twotargets->auth)) == -1) {
1055 if (ERRNOISPREVIOUSPACKET(errno)) {
1056 /*
1057 * error is from the target of an earlier packet from client,
1058 * sent by us /out/ on this socket, i.e. from client to target.
1059 * Note that Linux apparently can return this error even if
1060 * the socket is not connected.
1061 *
1062 * Don't treat it as fatal, more packets could come, and they
1063 * may be accepted by the twotargets.
1064 */
1065 const int oldcommand = state->command;
1066 state->command = SOCKS_UDPASSOCIATE;
1067
1068 *badfd = client->s;
1069
1070 emsglen = snprintf(emsg, sizeof(emsg),
1071 "%s (delayed error)", strerror(errno));
1072
1073 iolog(packetrule,
1074 state,
1075 OPERATION_TMPERROR,
1076 clog,
1077 dlog,
1078 NULL,
1079 NULL,
1080 emsg,
1081 emsglen);
1082
1083 state->command = oldcommand;
1084
1085 send_icmperror(rawsocket,
1086 &client->laddr,
1087 &client->raddr,
1088 &twotargets->raddr,
1089 -1,
1090 -1,
1091 icmp_type,
1092 icmp_code);
1093
1094 /* tmp error; using control connection do detect fatal errors. */
1095 return IO_TMPERROR;
1096 }
1097
1098 *badfd = twotargets->s;
1099
1100 if (ERRNOISTMP(errno))
1101 return IO_EAGAIN;
1102 else {
1103 log_unexpected_udprecv_error(function,
1104 twotargets->s,
1105 errno,
1106 EXTERNALIF);
1107 return IO_IOERROR;
1108 }
1109 }
1110
1111 iostatus = io_packet_received(&recvflags, r, &from, &twotargets->laddr);
1112
1113 gettimeofday_monotonic(&target->lastio);
1114
1115 if (iostatus != IO_NOERROR) {
1116 *badfd = twotargets->s;
1117 return iostatus;
1118 }
1119
1120 /*
1121 * Read a packet. Now check whether it should be forwarded.
1122 */
1123
1124 payloadlen = r;
1125
1126 target->target_read.bytes += recvflags.fromsocket;
1127 target->target_read.packets += 1;
1128
1129 slog(LOG_DEBUG,
1130 "%s: udp packet #%"PRIu64" from twotargets %s received for client %s "
1131 "on fd %d, packet length is %ld, use_saved_srule is %d",
1132 function,
1133 twotargets->read.packets,
1134 sockaddr2string(&from, hosta, sizeof(hosta)),
1135 sockaddr2string(&client->raddr, hostb, sizeof(hostb)),
1136 twotargets->s,
1137 (long)r,
1138 twotargets->state.use_saved_srule);
1139
1140 if (twotargets->written.packets == 0) {
1141 slog(LOG_DEBUG,
1142 "%s: unusual ... the client at %s has not sent any packets "
1143 "yet, but is receiving a %ld byte reply on address %s from %s",
1144 function,
1145 sockaddr2string(&client->raddr, NULL, 0),
1146 (long)r,
1147 sockaddr2string(&twotargets->laddr, hosta, sizeof(hosta)),
1148 sockaddr2string(&from, hostb, sizeof(hostb)));
1149 }
1150
1151 /*
1152 * Can we reuse the saved rule, if any, from the last time we received a
1153 * packet on this socket, or must we do a new rule-lookup now?
1154 */
1155 if (twotargets->state.use_saved_srule) {
1156 /*
1157 * Yes, previous rule lookup is valid, but if the packet is received
1158 * from the same address as previously.
1159 */
1160 if (twotargets->state.isconnected) {
1161 slog(LOG_DEBUG, "%s: socket is connected. Kernel should take care "
1162 "of making sure the source address %s is the same "
1163 "as last, so that we can reuse previous rule-lookup "
1164 "(rule #%lu, verdict: %s)",
1165 function,
1166 sockaddr2string(&from, NULL, 0),
1167 (unsigned long)packetrule->number,
1168 verdict2string(packetrule->verdict));
1169 samesrc = 1;
1170 }
1171 else {
1172 if (IPADDRISBOUND(&twotargets->raddr)) {
1173 if (! (samesrc = sockaddrareeq(&twotargets->raddr, &from, 0))) {
1174 /*
1175 * ack, not reply from previous twotargets.
1176 */
1177 slog(LOG_DEBUG,
1178 "%s: use_saved_srule set. UDP packet #%"PRIu64" from %s. "
1179 "Destination %s. Previously set up with "
1180 "%s #%lu (%s) for packets from twotargets %s. "
1181 "Not the same as now, so have to do a new rule-lookup",
1182 function,
1183 twotargets->read.packets,
1184 sockaddr2string(&from, hosta, sizeof(hosta)),
1185 sockshost2string(&client->host, hostb, sizeof(hostb)),
1186 objecttype2string(packetrule->type),
1187 (unsigned long)packetrule->number,
1188 verdict2string(packetrule->verdict),
1189 sockaddr2string(&twotargets->raddr, NULL, 0));
1190 }
1191 }
1192 else
1193 samesrc = 0; /* have nothing we should compare with. */
1194 }
1195 }
1196 else
1197 samesrc = 0; /* have nothing we should compare with. */
1198
1199 if (samesrc)
1200 permit = (packetrule->verdict == VERDICT_PASS);
1201 else {
1202 /*
1203 * Nope, can not reuse the last rule lookup. Have to do a new one.
1204 */
1205
1206 twotargets->raddr = from;
1207
1208 sockaddr2sockshost(&twotargets->raddr, &twotargets->host);
1209 dlog->peer = twotargets->host;
1210
1211 slog(LOG_DEBUG,
1212 "%s: received packet from %s to %s on fd %d, "
1213 "use_saved_srule is %d, samesrc is %d",
1214 function,
1215 sockaddr2string(&twotargets->raddr, hosta, sizeof(hosta)),
1216 sockaddr2string(&client->raddr, hostb, sizeof(hostb)),
1217 twotargets->s,
1218 twotargets->state.use_saved_srule,
1219 samesrc);
1220
1221 if (!twotargets->state.use_saved_srule) {
1222 if (client->written.packets > 0)
1223 slog(LOG_DEBUG, "%s: not first packet and use_saved_srule not set "
1224 "... should only happen after SIGHUP",
1225 function);
1226 }
1227
1228 SASSERTX(iostatus == IO_NOERROR);
1229
1230 permit = rulespermit(control->s,
1231 &control->raddr,
1232 &control->laddr,
1233 NULL,
1234 &twotargets->auth,
1235 packetrule,
1236 state,
1237 &twotargets->host,
1238 &client->host,
1239 NULL,
1240 NULL,
1241 0);
1242
1243 if (permit) {
1244 /* use redirected addresses, if applicable. */
1245 /*
1246 * XXX make sure this does not change the address of s, as
1247 * we need to continue receiving packets on that socket.
1248 */
1249 struct sockaddr_storage p;
1250
1251 if (redirect(client->s,
1252 &client->laddr,
1253 &client->host,
1254 state->command,
1255 &packetrule->rdr_from,
1256 &packetrule->rdr_to) == 0) {
1257
1258 /*
1259 * Use ipaddresses when logging.
1260 */
1261
1262 sockaddr2sockshost(&client->laddr, &clog->local);
1263 sockaddr2sockshost(sockshost2sockaddr(&client->host, &p),
1264 &clog->peer);
1265 }
1266 else {
1267 snprintf(emsg, sizeof(emsg),
1268 "redirect failed: %s", strerror(errno));
1269
1270 iostatus = IO_TMPERROR;
1271 }
1272 }
1273 }
1274
1275 if (iostatus != IO_NOERROR || !permit) {
1276 iolog(packetrule,
1277 state,
1278 IOOP(!permit, iostatus),
1279 dlog,
1280 clog,
1281 NULL,
1282 NULL,
1283 emsg,
1284 strlen(emsg));
1285
1286 send_icmperror(rawsocket,
1287 &twotargets->laddr,
1288 &twotargets->raddr,
1289 sockshost2sockaddr(&client->host, &hostaddr),
1290 -1,
1291 -1,
1292 icmp_type,
1293 iostatus == IO_NOERROR ?
1294 ICMP_CODE_UNREACHABLE_HOSTPROHIBITED : icmp_code);
1295
1296 if (iostatus != IO_NOERROR)
1297 return iostatus;
1298 else
1299 return IO_TMPBLOCK;
1300 }
1301
1302 twotargets->state.use_saved_srule = 0; /* XXX temporarily disabled. Bug. */
1303
1304 sendtoflags.side = INTERNALIF;
1305
1306 originallen = payloadlen;
1307 payload = udpheader_add(sockaddr2sockshost(&twotargets->raddr, NULL),
1308 buf,
1309 &payloadlen,
1310 sizeof(buf));
1311
1312 SASSERTX(payload == buf);
1313 SASSERTX(payloadlen > (size_t)r);
1314 SASSERTX(payloadlen - originallen >= MINSOCKSUDPHLEN);
1315
1316 headerlen = payloadlen - originallen;
1317
1318 w = socks_sendto(client->s,
1319 payload,
1320 payloadlen,
1321 0,
1322 client->state.isconnected ? NULL : &client->raddr,
1323 client->state.isconnected ?
1324 (socklen_t)0 : (socklen_t)sizeof(client->raddr),
1325 &sendtoflags,
1326 &client->auth);
1327
1328 if (w >= 0) {
1329 iostatus = io_packet_sent(payloadlen,
1330 w,
1331 &recvflags.ts,
1332 &twotargets->raddr,
1333 &client->raddr,
1334 emsg,
1335 sizeof(emsg));
1336
1337 *bwused = w;
1338
1339 target->client_written.bytes += sendtoflags.tosocket;
1340 target->client_written.packets += 1;
1341 }
1342 else {
1343 snprintf(emsg, sizeof(emsg), "sendto of %lu bytes failed: %s",
1344 (unsigned long)payloadlen, strerror(errno));
1345
1346 iostatus = IOSTATUS_UDP_SEND_FAILED(errno);
1347 *badfd = client->s;
1348 }
1349
1350 if (iostatus != IO_NOERROR) {
1351 iolog(packetrule,
1352 state,
1353 IOOP(!permit, iostatus),
1354 dlog,
1355 clog,
1356 NULL,
1357 NULL,
1358 emsg,
1359 strlen(emsg));
1360
1361 send_icmperror(rawsocket,
1362 &twotargets->laddr,
1363 &twotargets->raddr,
1364 sockshost2sockaddr(&client->host, &hostaddr),
1365 -1,
1366 -1,
1367 icmp_type,
1368 icmp_code);
1369
1370 return iostatus;
1371 }
1372
1373 SASSERTX(w == (ssize_t)payloadlen);
1374
1375 iolog(packetrule,
1376 state,
1377 OPERATION_IO,
1378 dlog,
1379 clog,
1380 NULL,
1381 NULL,
1382 payload + headerlen,
1383 payloadlen - headerlen);
1384
1385 return IO_NOERROR;
1386 }
1387
1388
1389 static int
fromaddr_as_expected(expected,from,emsg,emsglen)1390 fromaddr_as_expected(expected, from, emsg, emsglen)
1391 struct sockaddr_storage *expected;
1392 const struct sockaddr_storage *from;
1393 char *emsg;
1394 size_t emsglen;
1395 {
1396 const char *function = "fromaddr_as_expected()";
1397 char expectedstr[MAXSOCKADDRSTRING], fromstr[MAXSOCKADDRSTRING],
1398 buf[sizeof(expectedstr) + sizeof(fromstr) + 256];
1399 int matches;
1400
1401 snprintf(buf, sizeof(buf),
1402 "expected udp packet from clientaddress %s, got it from %s",
1403 sockaddr2string(expected, expectedstr, sizeof(expectedstr)),
1404 sockaddr2string(from, fromstr, sizeof(fromstr)));
1405
1406 if (!ADDRISBOUND(expected)) {
1407 /*
1408 * Client hasn't sent us it's complete address yet, but if
1409 * the parts of the address it has sent (if any) matches
1410 * the source of this packet, we have to assume this packet
1411 * is from it. We can then update the expected address with
1412 * complete info, based on this packet.
1413 *
1414 * We also connect the socket to the client, for better performance,
1415 * for receiving errors from sendto(2), for getpeername(2) by libwrap
1416 * in rulespermit(), for ... well, that's reasons enough already.
1417 */
1418 struct sockaddr_storage test;
1419
1420 sockaddrcpy(&test, expected, sizeof(test));
1421
1422 if (!IPADDRISBOUND(expected))
1423 SET_SOCKADDRADDR(&test, GET_SOCKADDRADDR(from));
1424
1425 if (!PORTISBOUND(expected))
1426 SET_SOCKADDRPORT((&test), GET_SOCKADDRPORT(from));
1427
1428 matches = sockaddrareeq(&test, from, 0);
1429
1430 if (matches) {
1431 /*
1432 * from-address matches the parts the client told us, so
1433 * assume this packet is from the client and update expected
1434 * address to contain the complete address, both ip and port.
1435 */
1436 sockaddrcpy(expected, &test, sizeof(test));
1437 }
1438 /* else; no match, presumably not from client. */
1439 }
1440 else /* clients complete address is known to us. Matches this packet? */
1441 matches = sockaddrareeq(expected, from, 0);
1442
1443 if (!matches && emsglen > 0) {
1444 strncpy(emsg, buf, emsglen - 1);
1445 emsg[emsglen - 1] = NUL;
1446 }
1447
1448 slog(LOG_DEBUG, "%s: %s: %s",
1449 function, buf, matches ? "matches" : "no match");
1450
1451 return matches;
1452 }
1453
1454 udpheader_t *
getudptarget(buf,buflen,header,headerlen,emsg,emsglen)1455 getudptarget(buf, buflen, header, headerlen, emsg, emsglen)
1456 const char *buf;
1457 const size_t buflen;
1458 udpheader_t *header;
1459 size_t *headerlen;
1460 char *emsg;
1461 const size_t emsglen;
1462 {
1463 const char *function = "getudptarget()";
1464
1465 if (string2udpheader(buf, buflen, header) == NULL) {
1466 snprintf(emsg, emsglen,
1467 "SOCKS protocol error in socks udp packet of length %lu. "
1468 "Could not extract valid address from SOCKS UDP header",
1469 (unsigned long)buflen);
1470
1471 header->host.atype = SOCKS_ADDR_NOTSET;
1472 return NULL;
1473 }
1474
1475 if (header->frag != 0) {
1476 snprintf(emsg, emsglen, "fragmented socks udp packets are not supported");
1477 return NULL;
1478 }
1479
1480 *headerlen = HEADERSIZE_UDP(header);
1481
1482 switch (header->host.atype) {
1483 case SOCKS_ADDR_IPV6:
1484 if (IN6_IS_ADDR_V4MAPPED(&header->host.addr.ipv6.ip)) {
1485 /*
1486 * We never use that; either we have IPv4 available on the
1487 * external interface, or we do not. Convert it to an ordinary
1488 * IPv4 address and proceed as usual.
1489 */
1490 sockshost_t convertedhost;
1491
1492 convertedhost = header->host;
1493 ipv4_mapped_to_regular(&header->host.addr.ipv6.ip,
1494 &convertedhost.addr.ipv4);
1495
1496 header->host.atype = SOCKS_ADDR_IPV4;
1497 header->host.addr.ipv4 = convertedhost.addr.ipv4;
1498 }
1499
1500 /* FALLTHROUGH */
1501
1502 case SOCKS_ADDR_IPV4:
1503 if (!external_has_safamily(atype2safamily(header->host.atype))) {
1504 snprintf(emsg, emsglen,
1505 "packet for %s target, but no %s configured for "
1506 "our usage on the external interface ",
1507 atype2string(header->host.atype),
1508 atype2string(header->host.atype));
1509
1510 return NULL;
1511 }
1512
1513 break;
1514
1515 case SOCKS_ADDR_DOMAIN:
1516 break;
1517
1518 default:
1519 SERRX(header->host.atype);
1520 }
1521
1522 return header;
1523 }
1524