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