185 lines
3.8 KiB
C
185 lines
3.8 KiB
C
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0 OR ISC
|
|
|
|
#include <openssl/bio.h>
|
|
|
|
#if !defined(OPENSSL_NO_SOCK)
|
|
|
|
#include <openssl/mem.h>
|
|
|
|
#include "../internal.h"
|
|
#include "./internal.h"
|
|
|
|
BIO_ADDR *BIO_ADDR_new(void) {
|
|
BIO_ADDR *ret = OPENSSL_zalloc(sizeof(BIO_ADDR));
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
ret->sa.sa_family = AF_UNSPEC;
|
|
return ret;
|
|
}
|
|
|
|
void BIO_ADDR_free(BIO_ADDR *ap) { OPENSSL_free(ap); }
|
|
|
|
int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src) {
|
|
GUARD_PTR(dst);
|
|
GUARD_PTR(src);
|
|
|
|
if (src->sa.sa_family == AF_UNSPEC) {
|
|
BIO_ADDR_clear(dst);
|
|
return 1;
|
|
}
|
|
|
|
if (src->sa.sa_family == AF_INET) {
|
|
OPENSSL_memcpy(&dst->s_in, &src->sa, sizeof(dst->s_in));
|
|
return 1;
|
|
}
|
|
#ifdef AF_INET6
|
|
if (src->sa.sa_family == AF_INET6) {
|
|
OPENSSL_memcpy(&dst->s_in6, &src->sa, sizeof(dst->s_in6));
|
|
return 1;
|
|
}
|
|
#endif
|
|
#ifdef AWS_LC_HAS_AF_UNIX
|
|
if (src->sa.sa_family == AF_UNIX) {
|
|
OPENSSL_memcpy(&dst->s_un, &src->sa, sizeof(dst->s_un));
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap) {
|
|
GUARD_PTR(ap);
|
|
|
|
BIO_ADDR *ret = BIO_ADDR_new();
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (1 != BIO_ADDR_copy(ret, ap)) {
|
|
BIO_ADDR_free(ret);
|
|
ret = NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void BIO_ADDR_clear(BIO_ADDR *ap) {
|
|
if (ap == NULL) {
|
|
return;
|
|
}
|
|
OPENSSL_cleanse(ap, sizeof(BIO_ADDR));
|
|
ap->sa.sa_family = AF_UNSPEC;
|
|
}
|
|
|
|
int BIO_ADDR_family(const BIO_ADDR *ap) {
|
|
GUARD_PTR(ap);
|
|
|
|
return ap->sa.sa_family;
|
|
}
|
|
|
|
int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, const void *where,
|
|
size_t wherelen, unsigned short port) {
|
|
GUARD_PTR(ap);
|
|
if (family == AF_INET) {
|
|
if (wherelen != sizeof(struct in_addr)) {
|
|
return 0;
|
|
}
|
|
OPENSSL_cleanse(&ap->s_in, 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;
|
|
return 1;
|
|
}
|
|
#ifdef AF_INET6
|
|
if (family == AF_INET6) {
|
|
if (wherelen != sizeof(struct in6_addr)) {
|
|
return 0;
|
|
}
|
|
OPENSSL_cleanse(&ap->s_in6, 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;
|
|
return 1;
|
|
}
|
|
#endif
|
|
#ifdef AWS_LC_HAS_AF_UNIX
|
|
if (family == AF_UNIX) {
|
|
GUARD_PTR(where);
|
|
// wherelen is expected to be the length of the path string
|
|
// not including the terminating NUL.
|
|
if (wherelen + 1 > sizeof(ap->s_un.sun_path)) {
|
|
return 0;
|
|
}
|
|
OPENSSL_cleanse(&ap->s_un, sizeof(ap->s_un));
|
|
ap->s_un.sun_family = family;
|
|
OPENSSL_strlcpy(ap->s_un.sun_path, where, wherelen);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l) {
|
|
size_t len = 0;
|
|
const void *addrptr = NULL;
|
|
|
|
GUARD_PTR(ap);
|
|
|
|
if (ap->sa.sa_family == AF_INET) {
|
|
len = sizeof(ap->s_in.sin_addr);
|
|
addrptr = &ap->s_in.sin_addr;
|
|
}
|
|
#ifdef AF_INET6
|
|
else if (ap->sa.sa_family == AF_INET6) {
|
|
len = sizeof(ap->s_in6.sin6_addr);
|
|
addrptr = &ap->s_in6.sin6_addr;
|
|
}
|
|
#endif
|
|
#ifdef AWS_LC_HAS_AF_UNIX
|
|
else if (ap->sa.sa_family == AF_UNIX) {
|
|
// len does not include the null
|
|
len = OPENSSL_strnlen(ap->s_un.sun_path, sizeof(ap->s_un.sun_path));
|
|
addrptr = &ap->s_un.sun_path;
|
|
}
|
|
#endif
|
|
|
|
if (addrptr == NULL) {
|
|
return 0;
|
|
}
|
|
if (l != NULL) {
|
|
*l = len;
|
|
}
|
|
|
|
if (p != NULL) {
|
|
OPENSSL_memcpy(p, addrptr, len);
|
|
if (ap->sa.sa_family == AF_UNIX) {
|
|
// OpenSSL does not write the terminating NUL
|
|
((char *)p)[len] = '\0';
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
|
|
{
|
|
GUARD_PTR(ap);
|
|
|
|
if (ap->sa.sa_family == AF_INET) {
|
|
return ap->s_in.sin_port;
|
|
}
|
|
#ifdef AF_INET6
|
|
if (ap->sa.sa_family == AF_INET6) {
|
|
return ap->s_in6.sin6_port;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
#endif // !defined(OPENSSL_NO_SOCK)
|