86c6c7eca883fb25a857aa089a6cfc938e05c699
[openssl.git] / crypto / bio / b_addr.c
1 /* ====================================================================
2  * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    openssl-core@openssl.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This product includes cryptographic software written by Eric Young
50  * (eay@cryptsoft.com).  This product includes software written by Tim
51  * Hudson (tjh@cryptsoft.com).
52  *
53  */
54
55 #include <string.h>
56
57 #include "bio_lcl.h"
58 #include "internal/threads.h"
59
60 #ifndef OPENSSL_NO_SOCK
61 #include <openssl/err.h>
62 #include <openssl/buffer.h>
63 #include <ctype.h>
64
65 CRYPTO_RWLOCK *bio_lookup_lock;
66 static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
67
68 /*
69  * Throughout this file and bio_lcl.h, the existence of the macro
70  * AI_PASSIVE is used to detect the availability of struct addrinfo,
71  * getnameinfo() and getaddrinfo().  If that macro doesn't exist,
72  * we use our own implementation instead, using gethostbyname,
73  * getservbyname and a few other.
74  */
75
76 /**********************************************************************
77  *
78  * Address structure
79  *
80  */
81
82 BIO_ADDR *BIO_ADDR_new(void)
83 {
84     BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
85
86     if (ret == NULL)
87         return NULL;
88
89     ret->sa.sa_family = AF_UNSPEC;
90     return ret;
91 }
92
93 void BIO_ADDR_free(BIO_ADDR *ap)
94 {
95     OPENSSL_free(ap);
96 }
97
98 void BIO_ADDR_clear(BIO_ADDR *ap)
99 {
100     memset(ap, 0, sizeof(*ap));
101     ap->sa.sa_family = AF_UNSPEC;
102 }
103
104 /*
105  * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
106  * of a struct sockaddr.
107  */
108 int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
109 {
110     if (sa->sa_family == AF_INET) {
111         ap->s_in = *(const struct sockaddr_in *)sa;
112         return 1;
113     }
114 #ifdef AF_INET6
115     if (sa->sa_family == AF_INET6) {
116         ap->s_in6 = *(const struct sockaddr_in6 *)sa;
117         return 1;
118     }
119 #endif
120 #ifdef AF_UNIX
121     if (ap->sa.sa_family == AF_UNIX) {
122         ap->s_un = *(const struct sockaddr_un *)sa;
123         return 1;
124     }
125 #endif
126
127     return 0;
128 }
129
130 int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
131                      const void *where, size_t wherelen,
132                      unsigned short port)
133 {
134 #ifdef AF_UNIX
135     if (family == AF_UNIX) {
136         if (wherelen + 1 > sizeof(ap->s_un.sun_path))
137             return 0;
138         memset(&ap->s_un, 0, sizeof(ap->s_un));
139         ap->s_un.sun_family = family;
140         strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
141         return 1;
142     }
143 #endif
144     if (family == AF_INET) {
145         if (wherelen != sizeof(struct in_addr))
146             return 0;
147         memset(&ap->s_in, 0, sizeof(ap->s_in));
148         ap->s_in.sin_family = family;
149         ap->s_in.sin_port = port;
150         ap->s_in.sin_addr = *(struct in_addr *)where;
151         return 1;
152     }
153 #ifdef AF_INET6
154     if (family == AF_INET6) {
155         if (wherelen != sizeof(struct in6_addr))
156             return 0;
157         memset(&ap->s_in6, 0, sizeof(ap->s_in6));
158         ap->s_in6.sin6_family = family;
159         ap->s_in6.sin6_port = port;
160         ap->s_in6.sin6_addr = *(struct in6_addr *)where;
161         return 1;
162     }
163 #endif
164
165     return 0;
166 }
167
168 int BIO_ADDR_family(const BIO_ADDR *ap)
169 {
170     return ap->sa.sa_family;
171 }
172
173 int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
174 {
175     size_t len = 0;
176     const void *addrptr = NULL;
177
178     if (ap->sa.sa_family == AF_INET) {
179         len = sizeof(ap->s_in.sin_addr);
180         addrptr = &ap->s_in.sin_addr;
181     }
182 #ifdef AF_INET6
183     else if (ap->sa.sa_family == AF_INET6) {
184         len = sizeof(ap->s_in6.sin6_addr);
185         addrptr = &ap->s_in6.sin6_addr;
186     }
187 #endif
188 #ifdef AF_UNIX
189     else if (ap->sa.sa_family == AF_UNIX) {
190         len = strlen(ap->s_un.sun_path);
191         addrptr = &ap->s_un.sun_path;
192     }
193 #endif
194
195     if (addrptr == NULL)
196         return 0;
197
198     if (p != NULL) {
199         memcpy(p, addrptr, len);
200     }
201     if (l != NULL)
202         *l = len;
203
204     return 1;
205 }
206
207 unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
208 {
209     if (ap->sa.sa_family == AF_INET)
210         return ap->s_in.sin_port;
211 #ifdef AF_INET6
212     if (ap->sa.sa_family == AF_INET6)
213         return ap->s_in6.sin6_port;
214 #endif
215     return 0;
216 }
217
218 /*-
219  * addr_strings - helper function to get host and service names
220  * @ap: the BIO_ADDR that has the input info
221  * @numeric: 0 if actual names should be returned, 1 if the numeric
222  * representation should be returned.
223  * @hostname: a pointer to a pointer to a memory area to store the
224  * host name or numeric representation.  Unused if NULL.
225  * @service: a pointer to a pointer to a memory area to store the
226  * service name or numeric representation.  Unused if NULL.
227  *
228  * The return value is 0 on failure, with the error code in the error
229  * stack, and 1 on success.
230  */
231 static int addr_strings(const BIO_ADDR *ap, int numeric,
232                         char **hostname, char **service)
233 {
234     if (BIO_sock_init() != 1)
235         return 0;
236
237     if (1) {
238 #ifdef AI_PASSIVE
239         int ret = 0;
240         char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
241         int flags = 0;
242
243         if (numeric)
244             flags |= NI_NUMERICHOST | NI_NUMERICSERV;
245
246         if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
247                                BIO_ADDR_sockaddr_size(ap),
248                                host, sizeof(host), serv, sizeof(serv),
249                                flags)) != 0) {
250 # ifdef EAI_SYSTEM
251             if (ret == EAI_SYSTEM) {
252                 SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
253                 BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
254             } else
255 # endif
256             {
257                 BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
258                 ERR_add_error_data(1, gai_strerror(ret));
259             }
260             return 0;
261         }
262
263         /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
264          * leaves it with whatever garbage that happens to be there.
265          * However, we initialise serv with the empty string (serv[0]
266          * is therefore NUL), so it gets real easy to detect when things
267          * didn't go the way one might expect.
268          */
269         if (serv[0] == '\0') {
270             BIO_snprintf(serv, sizeof(serv), "%d",
271                          ntohs(BIO_ADDR_rawport(ap)));
272         }
273
274         if (hostname)
275             *hostname = OPENSSL_strdup(host);
276         if (service)
277             *service = OPENSSL_strdup(serv);
278     } else {
279 #endif
280         if (hostname)
281             *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
282         if (service) {
283             char serv[6];        /* port is 16 bits => max 5 decimal digits */
284             BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
285             *service = OPENSSL_strdup(serv);
286         }
287     }
288
289     return 1;
290 }
291
292 char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
293 {
294     char *hostname = NULL;
295
296     if (addr_strings(ap, numeric, &hostname, NULL))
297         return hostname;
298
299     return NULL;
300 }
301
302 char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
303 {
304     char *service = NULL;
305
306     if (addr_strings(ap, numeric, NULL, &service))
307         return service;
308
309     return NULL;
310 }
311
312 char *BIO_ADDR_path_string(const BIO_ADDR *ap)
313 {
314 #ifdef AF_UNIX
315     if (ap->sa.sa_family == AF_UNIX)
316         return OPENSSL_strdup(ap->s_un.sun_path);
317 #endif
318     return NULL;
319 }
320
321 /*
322  * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
323  * for a given BIO_ADDR.  In reality, this is simply a type safe cast.
324  * The returned struct sockaddr is const, so it can't be tampered with.
325  */
326 const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
327 {
328     return &(ap->sa);
329 }
330
331 /*
332  * BIO_ADDR_sockaddr_noconst - non-public function that does the same
333  * as BIO_ADDR_sockaddr, but returns a non-const.  USE WITH CARE, as
334  * it allows you to tamper with the data (and thereby the contents
335  * of the input BIO_ADDR).
336  */
337 struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
338 {
339     return &(ap->sa);
340 }
341
342 /*
343  * BIO_ADDR_sockaddr_size - non-public function that returns the size
344  * of the struct sockaddr the BIO_ADDR is using.  If the protocol family
345  * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
346  * the size of the BIO_ADDR type is returned.
347  */
348 socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
349 {
350     if (ap->sa.sa_family == AF_INET)
351         return sizeof(ap->s_in);
352 #ifdef AF_INET6
353     if (ap->sa.sa_family == AF_INET6)
354         return sizeof(ap->s_in6);
355 #endif
356 #ifdef AF_UNIX
357     if (ap->sa.sa_family == AF_UNIX)
358         return sizeof(ap->s_un);
359 #endif
360     return sizeof(*ap);
361 }
362
363 /**********************************************************************
364  *
365  * Address info database
366  *
367  */
368
369 const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
370 {
371     if (bai != NULL)
372         return bai->bai_next;
373     return NULL;
374 }
375
376 int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
377 {
378     if (bai != NULL)
379         return bai->bai_family;
380     return 0;
381 }
382
383 int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
384 {
385     if (bai != NULL)
386         return bai->bai_socktype;
387     return 0;
388 }
389
390 int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
391 {
392     if (bai != NULL) {
393         if (bai->bai_protocol != 0)
394             return bai->bai_protocol;
395
396 #ifdef AF_UNIX
397         if (bai->bai_family == AF_UNIX)
398             return 0;
399 #endif
400
401         switch (bai->bai_socktype) {
402         case SOCK_STREAM:
403             return IPPROTO_TCP;
404         case SOCK_DGRAM:
405             return IPPROTO_UDP;
406         default:
407             break;
408         }
409     }
410     return 0;
411 }
412
413 /*
414  * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
415  * of the struct sockaddr inside the BIO_ADDRINFO.
416  */
417 socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
418 {
419     if (bai != NULL)
420         return bai->bai_addrlen;
421     return 0;
422 }
423
424 /*
425  * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
426  * as the struct sockaddr it is.
427  */
428 const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
429 {
430     if (bai != NULL)
431         return bai->bai_addr;
432     return NULL;
433 }
434
435 const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
436 {
437     if (bai != NULL)
438         return (BIO_ADDR *)bai->bai_addr;
439     return NULL;
440 }
441
442 void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
443 {
444     if (bai == NULL)
445         return;
446
447 #ifdef AI_PASSIVE
448 # ifdef AF_UNIX
449 #  define _cond bai->bai_family != AF_UNIX
450 # else
451 #  define _cond 1
452 # endif
453     if (_cond) {
454         freeaddrinfo(bai);
455         return;
456     }
457 #endif
458
459     /* Free manually when we know that addrinfo_wrap() was used.
460      * See further comment above addrinfo_wrap()
461      */
462     while (bai != NULL) {
463         BIO_ADDRINFO *next = bai->bai_next;
464         OPENSSL_free(bai->bai_addr);
465         OPENSSL_free(bai);
466         bai = next;
467     }
468 }
469
470 /**********************************************************************
471  *
472  * Service functions
473  *
474  */
475
476 /*-
477  * The specs in hostserv can take these forms:
478  *
479  * host:service         => *host = "host", *service = "service"
480  * host:*               => *host = "host", *service = NULL
481  * host:                => *host = "host", *service = NULL
482  * :service             => *host = NULL, *service = "service"
483  * *:service            => *host = NULL, *service = "service"
484  *
485  * in case no : is present in the string, the result depends on
486  * hostserv_prio, as follows:
487  *
488  * when hostserv_prio == BIO_PARSE_PRIO_HOST
489  * host                 => *host = "host", *service untouched
490  *
491  * when hostserv_prio == BIO_PARSE_PRIO_SERV
492  * service              => *host untouched, *service = "service"
493  *
494  */
495 int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
496                        enum BIO_hostserv_priorities hostserv_prio)
497 {
498     const char *h = NULL; size_t hl = 0;
499     const char *p = NULL; size_t pl = 0;
500
501     if (*hostserv == '[') {
502         if ((p = strchr(hostserv, ']')) == NULL)
503             goto spec_err;
504         h = hostserv + 1;
505         hl = p - h;
506         p++;
507         if (*p == '\0')
508             p = NULL;
509         else if (*p != ':')
510             goto spec_err;
511         else {
512             p++;
513             pl = strlen(p);
514         }
515     } else {
516         const char *p2 = strrchr(hostserv, ':');
517         p = strchr(hostserv, ':');
518
519         /*-
520          * Check for more than one colon.  There are three possible
521          * interpretations:
522          * 1. IPv6 address with port number, last colon being separator.
523          * 2. IPv6 address only.
524          * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
525          *    IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
526          * Because of this ambiguity, we currently choose to make it an
527          * error.
528          */
529         if (p != p2)
530             goto amb_err;
531
532         if (p != NULL) {
533             h = hostserv;
534             hl = p - h;
535             p++;
536             pl = strlen(p);
537         } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
538             h = hostserv;
539             hl = strlen(h);
540         } else {
541             p = hostserv;
542             pl = strlen(p);
543         }
544     }
545
546     if (p != NULL && strchr(p, ':'))
547         goto spec_err;
548
549     if (h != NULL && host != NULL) {
550         if (hl == 0
551             || (hl == 1 && h[0] == '*')) {
552             *host = NULL;
553         } else {
554             *host = OPENSSL_strndup(h, hl);
555             if (*host == NULL)
556                 goto memerr;
557         }
558     }
559     if (p != NULL && service != NULL) {
560         if (pl == 0
561             || (pl == 1 && p[0] == '*')) {
562             *service = NULL;
563         } else {
564             *service = OPENSSL_strndup(p, pl);
565             if (*service == NULL)
566                 goto memerr;
567         }
568     }
569
570     return 1;
571  amb_err:
572     BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
573     return 0;
574  spec_err:
575     BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
576     return 0;
577  memerr:
578     BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
579     return 0;
580 }
581
582 /* addrinfo_wrap is used to build our own addrinfo "chain".
583  * (it has only one entry, so calling it a chain may be a stretch)
584  * It should ONLY be called when getaddrinfo() and friends
585  * aren't available, OR when dealing with a non IP protocol
586  * family, such as AF_UNIX
587  *
588  * the return value is 1 on success, or 0 on failure, which
589  * only happens if a memory allocation error occurred.
590  */
591 static int addrinfo_wrap(int family, int socktype,
592                          const void *where, size_t wherelen,
593                          unsigned short port,
594                          BIO_ADDRINFO **bai)
595 {
596     OPENSSL_assert(bai != NULL);
597
598     *bai = OPENSSL_zalloc(sizeof(**bai));
599     if (*bai == NULL)
600         return 0;
601
602     (*bai)->bai_family = family;
603     (*bai)->bai_socktype = socktype;
604     if (socktype == SOCK_STREAM)
605         (*bai)->bai_protocol = IPPROTO_TCP;
606     if (socktype == SOCK_DGRAM)
607         (*bai)->bai_protocol = IPPROTO_UDP;
608 #ifdef AF_UNIX
609     if (family == AF_UNIX)
610         (*bai)->bai_protocol = 0;
611 #endif
612     {
613         /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
614            just an advanced cast of BIO_ADDR* to struct sockaddr *
615            by the power of union, so while it may seem that we're
616            creating a memory leak here, we are not.  It will be
617            all right. */
618         BIO_ADDR *addr = BIO_ADDR_new();
619         if (addr != NULL) {
620             BIO_ADDR_rawmake(addr, family, where, wherelen, port);
621             (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
622         }
623     }
624     (*bai)->bai_next = NULL;
625     if ((*bai)->bai_addr == NULL) {
626         BIO_ADDRINFO_free(*bai);
627         *bai = NULL;
628         return 0;
629     }
630     return 1;
631 }
632
633 static void do_bio_lookup_init(void)
634 {
635     bio_lookup_lock = CRYPTO_THREAD_lock_new();
636 }
637
638 /*-
639  * BIO_lookup - look up the node and service you want to connect to.
640  * @node: the node you want to connect to.
641  * @service: the service you want to connect to.
642  * @lookup_type: declare intent with the result, client or server.
643  * @family: the address family you want to use.  Use AF_UNSPEC for any, or
644  *  AF_INET, AF_INET6 or AF_UNIX.
645  * @socktype: The socket type you want to use.  Can be SOCK_STREAM, SOCK_DGRAM
646  *  or 0 for all.
647  * @res: Storage place for the resulting list of returned addresses
648  *
649  * This will do a lookup of the node and service that you want to connect to.
650  * It returns a linked list of different addresses you can try to connect to.
651  *
652  * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
653  *
654  * The return value is 1 on success or 0 in case of error.
655  */
656 int BIO_lookup(const char *host, const char *service,
657                enum BIO_lookup_type lookup_type,
658                int family, int socktype, BIO_ADDRINFO **res)
659 {
660     int ret = 0;                 /* Assume failure */
661
662     switch(family) {
663     case AF_INET:
664 #ifdef AF_INET6
665     case AF_INET6:
666 #endif
667 #ifdef AF_UNIX
668     case AF_UNIX:
669 #endif
670 #ifdef AF_UNSPEC
671     case AF_UNSPEC:
672 #endif
673         break;
674     default:
675         BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
676         return 0;
677     }
678
679 #ifdef AF_UNIX
680     if (family == AF_UNIX) {
681         if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
682             return 1;
683         else
684             BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
685         return 0;
686     }
687 #endif
688
689     if (BIO_sock_init() != 1)
690         return 0;
691
692     if (1) {
693         int gai_ret = 0;
694 #ifdef AI_PASSIVE
695         struct addrinfo hints;
696         memset(&hints, 0, sizeof hints);
697
698 # ifdef AI_ADDRCONFIG
699         hints.ai_flags = AI_ADDRCONFIG;
700 # endif
701         hints.ai_family = family;
702         hints.ai_socktype = socktype;
703
704         if (lookup_type == BIO_LOOKUP_SERVER)
705             hints.ai_flags |= AI_PASSIVE;
706
707         /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
708          * macro magic in bio_lcl.h
709          */
710         switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
711 # ifdef EAI_SYSTEM
712         case EAI_SYSTEM:
713             SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
714             BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
715             break;
716 # endif
717         case 0:
718             ret = 1;             /* Success */
719             break;
720         default:
721             BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
722             ERR_add_error_data(1, gai_strerror(gai_ret));
723             break;
724         }
725     } else {
726 #endif
727         const struct hostent *he;
728 /*
729  * Because struct hostent is defined for 32-bit pointers only with
730  * VMS C, we need to make sure that '&he_fallback_address' and
731  * '&he_fallback_addresses' are 32-bit pointers
732  */
733 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
734 # pragma pointer_size save
735 # pragma pointer_size 32
736 #endif
737         /* Windows doesn't seem to have in_addr_t */
738 #ifdef OPENSSL_SYS_WINDOWS
739         static uint32_t he_fallback_address;
740         static const uint32_t *he_fallback_addresses[] =
741             { &he_fallback_address, NULL };
742 #else
743         static in_addr_t he_fallback_address;
744         static const in_addr_t *he_fallback_addresses[] =
745             { &he_fallback_address, NULL };
746 #endif
747         static const struct hostent he_fallback =
748             { NULL, NULL, AF_INET, sizeof(he_fallback_address),
749               (char **)&he_fallback_addresses };
750 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
751 # pragma pointer_size restore
752 #endif
753
754         struct servent *se;
755         /* Apparently, on WIN64, s_proto and s_port have traded places... */
756 #ifdef _WIN64
757         struct servent se_fallback = { NULL, NULL, NULL, 0 };
758 #else
759         struct servent se_fallback = { NULL, NULL, 0, NULL };
760 #endif
761
762         CRYPTO_THREAD_run_once(&bio_lookup_init, do_bio_lookup_init);
763
764         CRYPTO_THREAD_write_lock(bio_lookup_lock);
765         he_fallback_address = INADDR_ANY;
766         if (host == NULL) {
767             he = &he_fallback;
768             switch(lookup_type) {
769             case BIO_LOOKUP_CLIENT:
770                 he_fallback_address = INADDR_LOOPBACK;
771                 break;
772             case BIO_LOOKUP_SERVER:
773                 he_fallback_address = INADDR_ANY;
774                 break;
775             default:
776                 OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
777                 break;
778             }
779         } else {
780             he = gethostbyname(host);
781
782             if (he == NULL) {
783 #ifndef OPENSSL_SYS_WINDOWS
784                 BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
785                 ERR_add_error_data(1, hstrerror(h_errno));
786 #else
787                 SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
788 #endif
789                 ret = 0;
790                 goto err;
791             }
792         }
793
794         if (service == NULL) {
795             se_fallback.s_port = 0;
796             se_fallback.s_proto = NULL;
797             se = &se_fallback;
798         } else {
799             char *endp = NULL;
800             long portnum = strtol(service, &endp, 10);
801
802 /*
803  * Because struct servent is defined for 32-bit pointers only with
804  * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
805  */
806 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
807 # pragma pointer_size save
808 # pragma pointer_size 32
809 #endif
810             char *proto = NULL;
811 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
812 # pragma pointer_size restore
813 #endif
814
815             switch (socktype) {
816             case SOCK_STREAM:
817                 proto = "tcp";
818                 break;
819             case SOCK_DGRAM:
820                 proto = "udp";
821                 break;
822             }
823
824             if (endp != service && *endp == '\0'
825                     && portnum > 0 && portnum < 65536) {
826                 se_fallback.s_port = htons(portnum);
827                 se_fallback.s_proto = proto;
828                 se = &se_fallback;
829             } else if (endp == service) {
830                 se = getservbyname(service, proto);
831
832                 if (se == NULL) {
833 #ifndef OPENSSL_SYS_WINDOWS
834                     BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
835                     ERR_add_error_data(1, hstrerror(h_errno));
836 #else
837                     SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
838 #endif
839                     goto err;
840                 }
841             } else {
842                 BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
843                 goto err;
844             }
845         }
846
847         *res = NULL;
848
849         {
850 /*
851  * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
852  * we must make sure our iterator designates the same element type, hence
853  * the pointer size dance.
854  */
855 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
856 # pragma pointer_size save
857 # pragma pointer_size 32
858 #endif
859             char **addrlistp;
860 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
861 # pragma pointer_size restore
862 #endif
863             size_t addresses;
864             BIO_ADDRINFO *tmp_bai = NULL;
865
866             /* The easiest way to create a linked list from an
867                array is to start from the back */
868             for(addrlistp = he->h_addr_list; *addrlistp != NULL;
869                 addrlistp++)
870                 ;
871
872             for(addresses = addrlistp - he->h_addr_list;
873                 addrlistp--, addresses-- > 0; ) {
874                 if (!addrinfo_wrap(he->h_addrtype, socktype,
875                                    *addrlistp, he->h_length,
876                                    se->s_port, &tmp_bai))
877                     goto addrinfo_malloc_err;
878                 tmp_bai->bai_next = *res;
879                 *res = tmp_bai;
880                 continue;
881              addrinfo_malloc_err:
882                 BIO_ADDRINFO_free(*res);
883                 *res = NULL;
884                 BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
885                 ret = 0;
886                 goto err;
887             }
888
889             ret = 1;
890         }
891      err:
892         CRYPTO_THREAD_unlock(bio_lookup_lock);
893     }
894
895     return ret;
896 }
897
898 #endif /* OPENSSL_NO_SOCK */