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