2016-05-18 02:52:22 +08:00
|
|
|
/*
|
|
|
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*
|
2016-05-18 02:52:22 +08:00
|
|
|
* Licensed under the OpenSSL license (the "License"). You may not use
|
|
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
|
|
* in the file LICENSE in the source distribution or at
|
|
|
|
* https://www.openssl.org/source/license.html
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "bio_lcl.h"
|
2016-05-16 01:02:17 +08:00
|
|
|
#include <openssl/crypto.h>
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
|
2016-02-18 02:33:51 +08:00
|
|
|
#ifndef OPENSSL_NO_SOCK
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/buffer.h>
|
2016-07-20 01:42:11 +08:00
|
|
|
#include <internal/thread_once.h>
|
2016-02-10 12:12:52 +08:00
|
|
|
#include <ctype.h>
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
|
2016-03-12 05:53:18 +08:00
|
|
|
CRYPTO_RWLOCK *bio_lookup_lock;
|
2016-03-04 23:24:26 +08:00
|
|
|
static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
/*
|
|
|
|
* Throughout this file and bio_lcl.h, the existence of the macro
|
|
|
|
* AI_PASSIVE is used to detect the availability of struct addrinfo,
|
|
|
|
* getnameinfo() and getaddrinfo(). If that macro doesn't exist,
|
|
|
|
* we use our own implementation instead, using gethostbyname,
|
|
|
|
* getservbyname and a few other.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
*
|
|
|
|
* Address structure
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
BIO_ADDR *BIO_ADDR_new(void)
|
|
|
|
{
|
2016-02-08 23:11:56 +08:00
|
|
|
BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
|
|
|
|
|
2016-05-06 02:13:32 +08:00
|
|
|
if (ret == NULL) {
|
|
|
|
BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
|
2016-04-29 18:27:09 +08:00
|
|
|
return NULL;
|
2016-05-06 02:13:32 +08:00
|
|
|
}
|
2016-04-29 18:27:09 +08:00
|
|
|
|
2016-02-06 03:40:44 +08:00
|
|
|
ret->sa.sa_family = AF_UNSPEC;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BIO_ADDR_free(BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
OPENSSL_free(ap);
|
|
|
|
}
|
|
|
|
|
2016-02-06 03:40:44 +08:00
|
|
|
void BIO_ADDR_clear(BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
memset(ap, 0, sizeof(*ap));
|
|
|
|
ap->sa.sa_family = AF_UNSPEC;
|
|
|
|
}
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
/*
|
|
|
|
* BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
|
|
|
|
* of a struct sockaddr.
|
|
|
|
*/
|
|
|
|
int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
|
|
|
|
{
|
|
|
|
if (sa->sa_family == AF_INET) {
|
2016-02-16 17:27:16 +08:00
|
|
|
ap->s_in = *(const struct sockaddr_in *)sa;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#ifdef AF_INET6
|
|
|
|
if (sa->sa_family == AF_INET6) {
|
2016-02-16 17:27:16 +08:00
|
|
|
ap->s_in6 = *(const struct sockaddr_in6 *)sa;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (ap->sa.sa_family == AF_UNIX) {
|
2016-02-16 17:27:16 +08:00
|
|
|
ap->s_un = *(const struct sockaddr_un *)sa;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
|
|
|
|
const void *where, size_t wherelen,
|
|
|
|
unsigned short port)
|
|
|
|
{
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (family == AF_UNIX) {
|
2016-02-16 17:27:16 +08:00
|
|
|
if (wherelen + 1 > sizeof(ap->s_un.sun_path))
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 0;
|
2016-02-16 17:27:16 +08:00
|
|
|
memset(&ap->s_un, 0, sizeof(ap->s_un));
|
|
|
|
ap->s_un.sun_family = family;
|
|
|
|
strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (family == AF_INET) {
|
|
|
|
if (wherelen != sizeof(struct in_addr))
|
|
|
|
return 0;
|
2016-02-16 17:27:16 +08:00
|
|
|
memset(&ap->s_in, 0, sizeof(ap->s_in));
|
|
|
|
ap->s_in.sin_family = family;
|
|
|
|
ap->s_in.sin_port = port;
|
|
|
|
ap->s_in.sin_addr = *(struct in_addr *)where;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#ifdef AF_INET6
|
|
|
|
if (family == AF_INET6) {
|
|
|
|
if (wherelen != sizeof(struct in6_addr))
|
|
|
|
return 0;
|
2016-02-16 17:27:16 +08:00
|
|
|
memset(&ap->s_in6, 0, sizeof(ap->s_in6));
|
|
|
|
ap->s_in6.sin6_family = family;
|
|
|
|
ap->s_in6.sin6_port = port;
|
|
|
|
ap->s_in6.sin6_addr = *(struct in6_addr *)where;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDR_family(const BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
return ap->sa.sa_family;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
|
|
|
|
{
|
|
|
|
size_t len = 0;
|
|
|
|
const void *addrptr = NULL;
|
|
|
|
|
|
|
|
if (ap->sa.sa_family == AF_INET) {
|
2016-02-16 17:27:16 +08:00
|
|
|
len = sizeof(ap->s_in.sin_addr);
|
|
|
|
addrptr = &ap->s_in.sin_addr;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
}
|
|
|
|
#ifdef AF_INET6
|
|
|
|
else if (ap->sa.sa_family == AF_INET6) {
|
2016-02-16 17:27:16 +08:00
|
|
|
len = sizeof(ap->s_in6.sin6_addr);
|
|
|
|
addrptr = &ap->s_in6.sin6_addr;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
else if (ap->sa.sa_family == AF_UNIX) {
|
2016-02-16 17:27:16 +08:00
|
|
|
len = strlen(ap->s_un.sun_path);
|
|
|
|
addrptr = &ap->s_un.sun_path;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (addrptr == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (p != NULL) {
|
|
|
|
memcpy(p, addrptr, len);
|
|
|
|
}
|
|
|
|
if (l != NULL)
|
|
|
|
*l = len;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
if (ap->sa.sa_family == AF_INET)
|
2016-02-16 17:27:16 +08:00
|
|
|
return ap->s_in.sin_port;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#ifdef AF_INET6
|
|
|
|
if (ap->sa.sa_family == AF_INET6)
|
2016-02-16 17:27:16 +08:00
|
|
|
return ap->s_in6.sin6_port;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-
|
|
|
|
* addr_strings - helper function to get host and service names
|
|
|
|
* @ap: the BIO_ADDR that has the input info
|
|
|
|
* @numeric: 0 if actual names should be returned, 1 if the numeric
|
|
|
|
* representation should be returned.
|
|
|
|
* @hostname: a pointer to a pointer to a memory area to store the
|
|
|
|
* host name or numeric representation. Unused if NULL.
|
|
|
|
* @service: a pointer to a pointer to a memory area to store the
|
|
|
|
* service name or numeric representation. Unused if NULL.
|
|
|
|
*
|
|
|
|
* The return value is 0 on failure, with the error code in the error
|
|
|
|
* stack, and 1 on success.
|
|
|
|
*/
|
|
|
|
static int addr_strings(const BIO_ADDR *ap, int numeric,
|
|
|
|
char **hostname, char **service)
|
|
|
|
{
|
2016-02-05 00:17:36 +08:00
|
|
|
if (BIO_sock_init() != 1)
|
|
|
|
return 0;
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
if (1) {
|
|
|
|
#ifdef AI_PASSIVE
|
|
|
|
int ret = 0;
|
2016-02-13 02:44:55 +08:00
|
|
|
char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
int flags = 0;
|
|
|
|
|
|
|
|
if (numeric)
|
|
|
|
flags |= NI_NUMERICHOST | NI_NUMERICSERV;
|
|
|
|
|
|
|
|
if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
|
|
|
|
BIO_ADDR_sockaddr_size(ap),
|
|
|
|
host, sizeof(host), serv, sizeof(serv),
|
|
|
|
flags)) != 0) {
|
|
|
|
# ifdef EAI_SYSTEM
|
|
|
|
if (ret == EAI_SYSTEM) {
|
|
|
|
SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
|
|
|
|
BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
|
|
|
|
} else
|
|
|
|
# endif
|
|
|
|
{
|
|
|
|
BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
|
|
|
|
ERR_add_error_data(1, gai_strerror(ret));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2016-02-10 12:12:52 +08:00
|
|
|
|
2016-02-13 02:44:55 +08:00
|
|
|
/* VMS getnameinfo() has a bug, it doesn't fill in serv, which
|
|
|
|
* leaves it with whatever garbage that happens to be there.
|
|
|
|
* However, we initialise serv with the empty string (serv[0]
|
|
|
|
* is therefore NUL), so it gets real easy to detect when things
|
|
|
|
* didn't go the way one might expect.
|
2016-02-10 12:12:52 +08:00
|
|
|
*/
|
2016-02-13 02:44:55 +08:00
|
|
|
if (serv[0] == '\0') {
|
2016-02-10 12:12:52 +08:00
|
|
|
BIO_snprintf(serv, sizeof(serv), "%d",
|
|
|
|
ntohs(BIO_ADDR_rawport(ap)));
|
|
|
|
}
|
|
|
|
|
2016-05-04 18:14:48 +08:00
|
|
|
if (hostname != NULL)
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*hostname = OPENSSL_strdup(host);
|
2016-05-04 18:14:48 +08:00
|
|
|
if (service != NULL)
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*service = OPENSSL_strdup(serv);
|
|
|
|
} else {
|
|
|
|
#endif
|
2016-05-04 18:14:48 +08:00
|
|
|
if (hostname != NULL)
|
2016-02-16 17:27:16 +08:00
|
|
|
*hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
|
2016-05-04 18:14:48 +08:00
|
|
|
if (service != NULL) {
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
char serv[6]; /* port is 16 bits => max 5 decimal digits */
|
2016-02-16 17:27:16 +08:00
|
|
|
BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*service = OPENSSL_strdup(serv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-04 18:14:48 +08:00
|
|
|
if ((hostname != NULL && *hostname == NULL)
|
|
|
|
|| (service != NULL && *service == NULL)) {
|
|
|
|
if (hostname != NULL) {
|
|
|
|
OPENSSL_free(*hostname);
|
|
|
|
*hostname = NULL;
|
|
|
|
}
|
|
|
|
if (service != NULL) {
|
|
|
|
OPENSSL_free(*service);
|
|
|
|
*service = NULL;
|
|
|
|
}
|
|
|
|
BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
|
|
|
|
{
|
|
|
|
char *hostname = NULL;
|
|
|
|
|
|
|
|
if (addr_strings(ap, numeric, &hostname, NULL))
|
|
|
|
return hostname;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
|
|
|
|
{
|
|
|
|
char *service = NULL;
|
|
|
|
|
|
|
|
if (addr_strings(ap, numeric, NULL, &service))
|
|
|
|
return service;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *BIO_ADDR_path_string(const BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (ap->sa.sa_family == AF_UNIX)
|
2016-02-16 17:27:16 +08:00
|
|
|
return OPENSSL_strdup(ap->s_un.sun_path);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#endif
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
|
|
|
|
* for a given BIO_ADDR. In reality, this is simply a type safe cast.
|
|
|
|
* The returned struct sockaddr is const, so it can't be tampered with.
|
|
|
|
*/
|
|
|
|
const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
return &(ap->sa);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BIO_ADDR_sockaddr_noconst - non-public function that does the same
|
|
|
|
* as BIO_ADDR_sockaddr, but returns a non-const. USE WITH CARE, as
|
|
|
|
* it allows you to tamper with the data (and thereby the contents
|
|
|
|
* of the input BIO_ADDR).
|
|
|
|
*/
|
|
|
|
struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
return &(ap->sa);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BIO_ADDR_sockaddr_size - non-public function that returns the size
|
|
|
|
* of the struct sockaddr the BIO_ADDR is using. If the protocol family
|
|
|
|
* isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
|
|
|
|
* the size of the BIO_ADDR type is returned.
|
|
|
|
*/
|
|
|
|
socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
|
|
|
|
{
|
|
|
|
if (ap->sa.sa_family == AF_INET)
|
2016-02-16 17:27:16 +08:00
|
|
|
return sizeof(ap->s_in);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#ifdef AF_INET6
|
|
|
|
if (ap->sa.sa_family == AF_INET6)
|
2016-02-16 17:27:16 +08:00
|
|
|
return sizeof(ap->s_in6);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#endif
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (ap->sa.sa_family == AF_UNIX)
|
2016-02-16 17:27:16 +08:00
|
|
|
return sizeof(ap->s_un);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#endif
|
|
|
|
return sizeof(*ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
*
|
2016-02-09 04:42:00 +08:00
|
|
|
* Address info database
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return bai->bai_next;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return bai->bai_family;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return bai->bai_socktype;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
2016-02-11 05:33:44 +08:00
|
|
|
if (bai != NULL) {
|
|
|
|
if (bai->bai_protocol != 0)
|
|
|
|
return bai->bai_protocol;
|
|
|
|
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (bai->bai_family == AF_UNIX)
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (bai->bai_socktype) {
|
|
|
|
case SOCK_STREAM:
|
|
|
|
return IPPROTO_TCP;
|
|
|
|
case SOCK_DGRAM:
|
|
|
|
return IPPROTO_UDP;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
|
|
|
|
* of the struct sockaddr inside the BIO_ADDRINFO.
|
|
|
|
*/
|
|
|
|
socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return bai->bai_addrlen;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
|
|
|
|
* as the struct sockaddr it is.
|
|
|
|
*/
|
|
|
|
const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return bai->bai_addr;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai != NULL)
|
|
|
|
return (BIO_ADDR *)bai->bai_addr;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
|
|
|
|
{
|
|
|
|
if (bai == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef AI_PASSIVE
|
|
|
|
# ifdef AF_UNIX
|
|
|
|
# define _cond bai->bai_family != AF_UNIX
|
|
|
|
# else
|
|
|
|
# define _cond 1
|
|
|
|
# endif
|
|
|
|
if (_cond) {
|
|
|
|
freeaddrinfo(bai);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Free manually when we know that addrinfo_wrap() was used.
|
|
|
|
* See further comment above addrinfo_wrap()
|
|
|
|
*/
|
|
|
|
while (bai != NULL) {
|
|
|
|
BIO_ADDRINFO *next = bai->bai_next;
|
|
|
|
OPENSSL_free(bai->bai_addr);
|
|
|
|
OPENSSL_free(bai);
|
|
|
|
bai = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
*
|
|
|
|
* Service functions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*-
|
|
|
|
* The specs in hostserv can take these forms:
|
|
|
|
*
|
|
|
|
* host:service => *host = "host", *service = "service"
|
|
|
|
* host:* => *host = "host", *service = NULL
|
|
|
|
* host: => *host = "host", *service = NULL
|
|
|
|
* :service => *host = NULL, *service = "service"
|
|
|
|
* *:service => *host = NULL, *service = "service"
|
|
|
|
*
|
|
|
|
* in case no : is present in the string, the result depends on
|
|
|
|
* hostserv_prio, as follows:
|
|
|
|
*
|
|
|
|
* when hostserv_prio == BIO_PARSE_PRIO_HOST
|
|
|
|
* host => *host = "host", *service untouched
|
|
|
|
*
|
|
|
|
* when hostserv_prio == BIO_PARSE_PRIO_SERV
|
|
|
|
* service => *host untouched, *service = "service"
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
|
|
|
|
enum BIO_hostserv_priorities hostserv_prio)
|
|
|
|
{
|
|
|
|
const char *h = NULL; size_t hl = 0;
|
|
|
|
const char *p = NULL; size_t pl = 0;
|
|
|
|
|
|
|
|
if (*hostserv == '[') {
|
|
|
|
if ((p = strchr(hostserv, ']')) == NULL)
|
|
|
|
goto spec_err;
|
|
|
|
h = hostserv + 1;
|
|
|
|
hl = p - h;
|
|
|
|
p++;
|
|
|
|
if (*p == '\0')
|
|
|
|
p = NULL;
|
|
|
|
else if (*p != ':')
|
|
|
|
goto spec_err;
|
|
|
|
else {
|
|
|
|
p++;
|
|
|
|
pl = strlen(p);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const char *p2 = strrchr(hostserv, ':');
|
|
|
|
p = strchr(hostserv, ':');
|
|
|
|
|
|
|
|
/*-
|
|
|
|
* Check for more than one colon. There are three possible
|
|
|
|
* interpretations:
|
|
|
|
* 1. IPv6 address with port number, last colon being separator.
|
|
|
|
* 2. IPv6 address only.
|
|
|
|
* 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
|
|
|
|
* IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
|
|
|
|
* Because of this ambiguity, we currently choose to make it an
|
|
|
|
* error.
|
|
|
|
*/
|
|
|
|
if (p != p2)
|
|
|
|
goto amb_err;
|
|
|
|
|
|
|
|
if (p != NULL) {
|
|
|
|
h = hostserv;
|
|
|
|
hl = p - h;
|
|
|
|
p++;
|
|
|
|
pl = strlen(p);
|
|
|
|
} else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
|
|
|
|
h = hostserv;
|
|
|
|
hl = strlen(h);
|
|
|
|
} else {
|
|
|
|
p = hostserv;
|
|
|
|
pl = strlen(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-06 20:07:39 +08:00
|
|
|
if (p != NULL && strchr(p, ':'))
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
goto spec_err;
|
|
|
|
|
|
|
|
if (h != NULL && host != NULL) {
|
|
|
|
if (hl == 0
|
|
|
|
|| (hl == 1 && h[0] == '*')) {
|
|
|
|
*host = NULL;
|
|
|
|
} else {
|
|
|
|
*host = OPENSSL_strndup(h, hl);
|
|
|
|
if (*host == NULL)
|
|
|
|
goto memerr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (p != NULL && service != NULL) {
|
|
|
|
if (pl == 0
|
|
|
|
|| (pl == 1 && p[0] == '*')) {
|
|
|
|
*service = NULL;
|
|
|
|
} else {
|
|
|
|
*service = OPENSSL_strndup(p, pl);
|
|
|
|
if (*service == NULL)
|
|
|
|
goto memerr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
amb_err:
|
|
|
|
BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
|
|
|
|
return 0;
|
|
|
|
spec_err:
|
|
|
|
BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
|
|
|
|
return 0;
|
|
|
|
memerr:
|
|
|
|
BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* addrinfo_wrap is used to build our own addrinfo "chain".
|
|
|
|
* (it has only one entry, so calling it a chain may be a stretch)
|
|
|
|
* It should ONLY be called when getaddrinfo() and friends
|
|
|
|
* aren't available, OR when dealing with a non IP protocol
|
|
|
|
* family, such as AF_UNIX
|
|
|
|
*
|
|
|
|
* the return value is 1 on success, or 0 on failure, which
|
2016-03-11 04:34:48 +08:00
|
|
|
* only happens if a memory allocation error occurred.
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
*/
|
|
|
|
static int addrinfo_wrap(int family, int socktype,
|
|
|
|
const void *where, size_t wherelen,
|
|
|
|
unsigned short port,
|
|
|
|
BIO_ADDRINFO **bai)
|
|
|
|
{
|
|
|
|
OPENSSL_assert(bai != NULL);
|
|
|
|
|
2016-02-08 23:11:56 +08:00
|
|
|
*bai = OPENSSL_zalloc(sizeof(**bai));
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
if (*bai == NULL)
|
|
|
|
return 0;
|
2016-02-08 23:11:56 +08:00
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
(*bai)->bai_family = family;
|
|
|
|
(*bai)->bai_socktype = socktype;
|
|
|
|
if (socktype == SOCK_STREAM)
|
|
|
|
(*bai)->bai_protocol = IPPROTO_TCP;
|
|
|
|
if (socktype == SOCK_DGRAM)
|
|
|
|
(*bai)->bai_protocol = IPPROTO_UDP;
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (family == AF_UNIX)
|
|
|
|
(*bai)->bai_protocol = 0;
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
/* Magic: We know that BIO_ADDR_sockaddr_noconst is really
|
|
|
|
just an advanced cast of BIO_ADDR* to struct sockaddr *
|
|
|
|
by the power of union, so while it may seem that we're
|
|
|
|
creating a memory leak here, we are not. It will be
|
|
|
|
all right. */
|
|
|
|
BIO_ADDR *addr = BIO_ADDR_new();
|
|
|
|
if (addr != NULL) {
|
|
|
|
BIO_ADDR_rawmake(addr, family, where, wherelen, port);
|
|
|
|
(*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*bai)->bai_next = NULL;
|
|
|
|
if ((*bai)->bai_addr == NULL) {
|
|
|
|
BIO_ADDRINFO_free(*bai);
|
|
|
|
*bai = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-07-20 01:42:11 +08:00
|
|
|
DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
|
2016-03-04 23:24:26 +08:00
|
|
|
{
|
2016-09-05 21:12:58 +08:00
|
|
|
OPENSSL_init_crypto(0, NULL);
|
2016-03-04 23:24:26 +08:00
|
|
|
bio_lookup_lock = CRYPTO_THREAD_lock_new();
|
2016-08-21 07:06:43 +08:00
|
|
|
return bio_lookup_lock != NULL;
|
2016-03-04 23:24:26 +08:00
|
|
|
}
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
/*-
|
|
|
|
* BIO_lookup - look up the node and service you want to connect to.
|
|
|
|
* @node: the node you want to connect to.
|
|
|
|
* @service: the service you want to connect to.
|
|
|
|
* @lookup_type: declare intent with the result, client or server.
|
|
|
|
* @family: the address family you want to use. Use AF_UNSPEC for any, or
|
|
|
|
* AF_INET, AF_INET6 or AF_UNIX.
|
|
|
|
* @socktype: The socket type you want to use. Can be SOCK_STREAM, SOCK_DGRAM
|
|
|
|
* or 0 for all.
|
|
|
|
* @res: Storage place for the resulting list of returned addresses
|
|
|
|
*
|
|
|
|
* This will do a lookup of the node and service that you want to connect to.
|
|
|
|
* It returns a linked list of different addresses you can try to connect to.
|
|
|
|
*
|
|
|
|
* When no longer needed you should call BIO_ADDRINFO_free() to free the result.
|
|
|
|
*
|
|
|
|
* The return value is 1 on success or 0 in case of error.
|
|
|
|
*/
|
|
|
|
int BIO_lookup(const char *host, const char *service,
|
|
|
|
enum BIO_lookup_type lookup_type,
|
|
|
|
int family, int socktype, BIO_ADDRINFO **res)
|
|
|
|
{
|
|
|
|
int ret = 0; /* Assume failure */
|
|
|
|
|
|
|
|
switch(family) {
|
|
|
|
case AF_INET:
|
|
|
|
#ifdef AF_INET6
|
|
|
|
case AF_INET6:
|
|
|
|
#endif
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
case AF_UNIX:
|
|
|
|
#endif
|
|
|
|
#ifdef AF_UNSPEC
|
|
|
|
case AF_UNSPEC:
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef AF_UNIX
|
|
|
|
if (family == AF_UNIX) {
|
|
|
|
if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-02-05 00:17:36 +08:00
|
|
|
if (BIO_sock_init() != 1)
|
|
|
|
return 0;
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
if (1) {
|
|
|
|
#ifdef AI_PASSIVE
|
2017-03-02 04:28:05 +08:00
|
|
|
int gai_ret = 0;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
struct addrinfo hints;
|
2017-03-02 04:28:05 +08:00
|
|
|
|
2016-02-19 23:23:08 +08:00
|
|
|
memset(&hints, 0, sizeof hints);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
|
|
|
|
hints.ai_family = family;
|
|
|
|
hints.ai_socktype = socktype;
|
|
|
|
|
|
|
|
if (lookup_type == BIO_LOOKUP_SERVER)
|
|
|
|
hints.ai_flags |= AI_PASSIVE;
|
|
|
|
|
|
|
|
/* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
|
|
|
|
* macro magic in bio_lcl.h
|
|
|
|
*/
|
2016-02-05 00:17:36 +08:00
|
|
|
switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
# ifdef EAI_SYSTEM
|
|
|
|
case EAI_SYSTEM:
|
|
|
|
SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
|
|
|
|
break;
|
|
|
|
# endif
|
|
|
|
case 0:
|
|
|
|
ret = 1; /* Success */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
|
2016-02-05 00:17:36 +08:00
|
|
|
ERR_add_error_data(1, gai_strerror(gai_ret));
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#endif
|
2016-02-04 08:59:20 +08:00
|
|
|
const struct hostent *he;
|
2016-03-30 12:40:37 +08:00
|
|
|
/*
|
|
|
|
* Because struct hostent is defined for 32-bit pointers only with
|
|
|
|
* VMS C, we need to make sure that '&he_fallback_address' and
|
|
|
|
* '&he_fallback_addresses' are 32-bit pointers
|
|
|
|
*/
|
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size save
|
|
|
|
# pragma pointer_size 32
|
|
|
|
#endif
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
/* Windows doesn't seem to have in_addr_t */
|
|
|
|
#ifdef OPENSSL_SYS_WINDOWS
|
2016-02-04 08:59:20 +08:00
|
|
|
static uint32_t he_fallback_address;
|
2016-06-15 18:50:09 +08:00
|
|
|
static const char *he_fallback_addresses[] =
|
|
|
|
{ (char *)&he_fallback_address, NULL };
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#else
|
2016-02-04 08:59:20 +08:00
|
|
|
static in_addr_t he_fallback_address;
|
2016-06-15 18:50:09 +08:00
|
|
|
static const char *he_fallback_addresses[] =
|
|
|
|
{ (char *)&he_fallback_address, NULL };
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#endif
|
2016-02-04 08:59:20 +08:00
|
|
|
static const struct hostent he_fallback =
|
|
|
|
{ NULL, NULL, AF_INET, sizeof(he_fallback_address),
|
|
|
|
(char **)&he_fallback_addresses };
|
2016-03-30 12:40:37 +08:00
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size restore
|
|
|
|
#endif
|
|
|
|
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
struct servent *se;
|
2016-03-11 04:34:48 +08:00
|
|
|
/* Apparently, on WIN64, s_proto and s_port have traded places... */
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
#ifdef _WIN64
|
|
|
|
struct servent se_fallback = { NULL, NULL, NULL, 0 };
|
|
|
|
#else
|
|
|
|
struct servent se_fallback = { NULL, NULL, 0, NULL };
|
|
|
|
#endif
|
|
|
|
|
2016-07-20 01:42:11 +08:00
|
|
|
if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
|
|
|
|
ret = 0;
|
|
|
|
goto err;
|
|
|
|
}
|
2016-03-04 23:24:26 +08:00
|
|
|
|
|
|
|
CRYPTO_THREAD_write_lock(bio_lookup_lock);
|
2016-02-04 08:59:20 +08:00
|
|
|
he_fallback_address = INADDR_ANY;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
if (host == NULL) {
|
|
|
|
he = &he_fallback;
|
|
|
|
switch(lookup_type) {
|
|
|
|
case BIO_LOOKUP_CLIENT:
|
|
|
|
he_fallback_address = INADDR_LOOPBACK;
|
|
|
|
break;
|
|
|
|
case BIO_LOOKUP_SERVER:
|
|
|
|
he_fallback_address = INADDR_ANY;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
he = gethostbyname(host);
|
|
|
|
|
|
|
|
if (he == NULL) {
|
2016-02-04 22:20:26 +08:00
|
|
|
#ifndef OPENSSL_SYS_WINDOWS
|
2017-03-02 04:28:05 +08:00
|
|
|
/*
|
|
|
|
* This might be misleading, because h_errno is used as if
|
|
|
|
* it was errno. To minimize mixup add 1000. Underlying
|
|
|
|
* reason for this is that hstrerror is declared obsolete,
|
|
|
|
* not to mention that a) h_errno is not always guaranteed
|
|
|
|
* to be meanigless; b) hstrerror can reside in yet another
|
|
|
|
* library, linking for sake of hstrerror is an overkill;
|
|
|
|
* c) this path is not executed on contemporary systems
|
|
|
|
* anyway [above getaddrinfo/gai_strerror is]. We just let
|
|
|
|
* system administrator figure this out...
|
|
|
|
*/
|
|
|
|
SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno);
|
2016-02-04 22:20:26 +08:00
|
|
|
#else
|
|
|
|
SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
|
|
|
|
#endif
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
ret = 0;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (service == NULL) {
|
|
|
|
se_fallback.s_port = 0;
|
2016-03-31 00:18:24 +08:00
|
|
|
se_fallback.s_proto = NULL;
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
se = &se_fallback;
|
|
|
|
} else {
|
|
|
|
char *endp = NULL;
|
|
|
|
long portnum = strtol(service, &endp, 10);
|
2016-03-30 12:40:37 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Because struct servent is defined for 32-bit pointers only with
|
|
|
|
* VMS C, we need to make sure that 'proto' is a 32-bit pointer.
|
|
|
|
*/
|
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size save
|
|
|
|
# pragma pointer_size 32
|
|
|
|
#endif
|
2016-03-31 00:18:24 +08:00
|
|
|
char *proto = NULL;
|
2016-03-30 12:40:37 +08:00
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size restore
|
|
|
|
#endif
|
2016-03-31 00:18:24 +08:00
|
|
|
|
|
|
|
switch (socktype) {
|
|
|
|
case SOCK_STREAM:
|
|
|
|
proto = "tcp";
|
|
|
|
break;
|
|
|
|
case SOCK_DGRAM:
|
|
|
|
proto = "udp";
|
|
|
|
break;
|
|
|
|
}
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
|
|
|
|
if (endp != service && *endp == '\0'
|
|
|
|
&& portnum > 0 && portnum < 65536) {
|
|
|
|
se_fallback.s_port = htons(portnum);
|
|
|
|
se_fallback.s_proto = proto;
|
|
|
|
se = &se_fallback;
|
|
|
|
} else if (endp == service) {
|
|
|
|
se = getservbyname(service, proto);
|
|
|
|
|
|
|
|
if (se == NULL) {
|
2016-02-04 22:20:26 +08:00
|
|
|
#ifndef OPENSSL_SYS_WINDOWS
|
2017-03-02 04:28:05 +08:00
|
|
|
SYSerr(SYS_F_GETSERVBYNAME, errno);
|
2016-02-04 22:20:26 +08:00
|
|
|
#else
|
|
|
|
SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
|
|
|
|
#endif
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*res = NULL;
|
|
|
|
|
|
|
|
{
|
2016-03-30 12:40:37 +08:00
|
|
|
/*
|
|
|
|
* Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
|
|
|
|
* we must make sure our iterator designates the same element type, hence
|
|
|
|
* the pointer size dance.
|
|
|
|
*/
|
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size save
|
|
|
|
# pragma pointer_size 32
|
|
|
|
#endif
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
char **addrlistp;
|
2016-03-30 12:40:37 +08:00
|
|
|
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
|
|
|
|
# pragma pointer_size restore
|
|
|
|
#endif
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
size_t addresses;
|
|
|
|
BIO_ADDRINFO *tmp_bai = NULL;
|
|
|
|
|
|
|
|
/* The easiest way to create a linked list from an
|
|
|
|
array is to start from the back */
|
|
|
|
for(addrlistp = he->h_addr_list; *addrlistp != NULL;
|
|
|
|
addrlistp++)
|
|
|
|
;
|
|
|
|
|
|
|
|
for(addresses = addrlistp - he->h_addr_list;
|
|
|
|
addrlistp--, addresses-- > 0; ) {
|
|
|
|
if (!addrinfo_wrap(he->h_addrtype, socktype,
|
|
|
|
*addrlistp, he->h_length,
|
|
|
|
se->s_port, &tmp_bai))
|
|
|
|
goto addrinfo_malloc_err;
|
|
|
|
tmp_bai->bai_next = *res;
|
|
|
|
*res = tmp_bai;
|
|
|
|
continue;
|
|
|
|
addrinfo_malloc_err:
|
|
|
|
BIO_ADDRINFO_free(*res);
|
|
|
|
*res = NULL;
|
|
|
|
BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
|
|
|
|
ret = 0;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
err:
|
2016-03-04 23:24:26 +08:00
|
|
|
CRYPTO_THREAD_unlock(bio_lookup_lock);
|
Refactoring BIO: add wrappers around sockaddr et al
Because different platforms have different levels of support for IPv6,
different kinds of sockaddr variants, and some have getaddrinfo et al
while others don't, we could end up with a mess if ifdefs, duplicate
code and other maintainance nightmares.
Instead, we're introducing wrappers around the common form for socket
communication:
BIO_ADDR, closely related to struct sockaddr and some of its variants.
BIO_ADDRINFO, closely related to struct addrinfo.
With that comes support routines, both convenient creators and
accessors, plus a few utility functions:
BIO_parse_hostserv, takes a string of the form host:service and
splits it into host and service. It checks for * in both parts, and
converts any [ipv6-address] syntax to ust the IPv6 address.
BIO_lookup, looks up information on a host.
All routines handle IPv4 (AF_INET) and IPv6 (AF_INET6) addresses, and
there is support for local sockets (AF_UNIX) as well.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
2016-02-02 22:54:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2016-03-12 05:53:18 +08:00
|
|
|
|
2016-02-18 02:33:51 +08:00
|
|
|
#endif /* OPENSSL_NO_SOCK */
|