b_addr.c 25 KB

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