diff options
author | Richard Levitte <levitte@openssl.org> | 2016-02-03 00:27:44 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2016-02-03 19:40:32 +0100 |
commit | d858c87653257185ead1c5baf3d84cd7276dd912 (patch) | |
tree | 88c6ea3d7634e2cd36e4d4910d5d7f81a32562fc /crypto/bio | |
parent | 75d5bd4e7d61ba3ed845f9e8170eac6a48a26407 (diff) | |
download | openssl-d858c87653257185ead1c5baf3d84cd7276dd912.zip openssl-d858c87653257185ead1c5baf3d84cd7276dd912.tar.gz openssl-d858c87653257185ead1c5baf3d84cd7276dd912.tar.bz2 |
Refactoring BIO: Adapt BIO_s_datagram and all that depends on it
The control commands that previously took a struct sockaddr * have
been changed to take a BIO_ADDR * instead.
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
Diffstat (limited to 'crypto/bio')
-rw-r--r-- | crypto/bio/bss_dgram.c | 173 |
1 files changed, 43 insertions, 130 deletions
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index d8e1b94..a3d8a0c 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -58,10 +58,8 @@ #include <stdio.h> #include <errno.h> -#define USE_SOCKETS -#include "internal/cryptlib.h" -#include <openssl/bio.h> +#include "bio_lcl.h" #ifndef OPENSSL_NO_DGRAM # if !(defined(_WIN32) || defined(OPENSSL_SYS_VMS)) @@ -156,13 +154,7 @@ static BIO_METHOD methods_dgramp_sctp = { # endif typedef struct bio_dgram_data_st { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; + BIO_ADDR peer; unsigned int connected; unsigned int _errno; unsigned int mtu; @@ -179,13 +171,7 @@ typedef struct bio_dgram_sctp_save_message_st { } bio_dgram_sctp_save_message; typedef struct bio_dgram_sctp_data_st { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; + BIO_ADDR peer; unsigned int connected; unsigned int _errno; unsigned int mtu; @@ -369,40 +355,20 @@ static int dgram_read(BIO *b, char *out, int outl) bio_dgram_data *data = (bio_dgram_data *)b->ptr; int flags = 0; - struct { - /* - * See commentary in b_sock.c. <appro> - */ - union { - size_t s; - int i; - } len; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; - } sa; - - sa.len.s = 0; - sa.len.i = sizeof(sa.peer); + BIO_ADDR peer; + socklen_t len = sizeof(peer); if (out != NULL) { clear_socket_error(); - memset(&sa.peer, 0, sizeof(sa.peer)); + memset(&peer, 0, sizeof(peer)); dgram_adjust_rcv_timeout(b); if (data->peekmode) flags = MSG_PEEK; - ret = recvfrom(b->num, out, outl, flags, &sa.peer.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { - OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); - sa.len.i = (int)sa.len.s; - } + ret = recvfrom(b->num, out, outl, flags, + BIO_ADDR_sockaddr_noconst(&peer), &len); if (!data->connected && ret >= 0) - BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); BIO_clear_retry_flags(b); if (ret < 0) { @@ -426,18 +392,14 @@ static int dgram_write(BIO *b, const char *in, int inl) if (data->connected) ret = writesocket(b->num, in, inl); else { - int peerlen = sizeof(data->peer); + int peerlen = BIO_ADDR_sockaddr_size(&data->peer); - if (data->peer.sa.sa_family == AF_INET) - peerlen = sizeof(data->peer.sa_in); -# if OPENSSL_USE_IPV6 - else if (data->peer.sa.sa_family == AF_INET6) - peerlen = sizeof(data->peer.sa_in6); -# endif # if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) - ret = sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); + ret = sendto(b->num, (char *)in, inl, 0, + BIO_ADDR_sockaddr(&data->peer), peerlen); # else - ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); + ret = sendto(b->num, in, inl, 0, + BIO_ADDR_sockaddr(&data->peer), peerlen); # endif } @@ -455,27 +417,31 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data) { long ret; - switch (data->peer.sa.sa_family) { + switch (BIO_ADDR_family(&data->peer)) { case AF_INET: /* * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */ ret = 28; break; -# if OPENSSL_USE_IPV6 +# ifdef AF_INET6 case AF_INET6: + { # ifdef IN6_IS_ADDR_V4MAPPED - if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) - /* - * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP - */ - ret = 28; - else + struct in6_addr tmp_addr; + if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL) + && IN6_IS_ADDR_V4MAPPED(&tmp_addr)) + /* + * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP + */ + ret = 28; + else # endif /* * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */ ret = 48; + } break; # endif default: @@ -490,20 +456,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; - struct sockaddr *to = NULL; bio_dgram_data *data = NULL; int sockopt_val = 0; # if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) socklen_t sockopt_len; /* assume that system supporting IP_MTU is * modern enough to define socklen_t */ socklen_t addr_len; - union { - struct sockaddr sa; - struct sockaddr_in s4; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 s6; -# endif - } addr; + BIO_ADDR addr; # endif data = (bio_dgram_data *)b->ptr; @@ -546,20 +505,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = 1; break; case BIO_CTRL_DGRAM_CONNECT: - to = (struct sockaddr *)ptr; - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } + BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); break; /* (Linux)kernel sets DF bit on outgoing IP packets */ case BIO_CTRL_DGRAM_MTU_DISCOVER: @@ -644,18 +590,22 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: ret = -dgram_get_mtu_overhead(data); - switch (data->peer.sa.sa_family) { + switch (BIO_ADDR_family(&data->peer)) { case AF_INET: ret += 576; break; # if OPENSSL_USE_IPV6 case AF_INET6: + { # ifdef IN6_IS_ADDR_V4MAPPED - if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) - ret += 576; - else + struct in6_addr tmp_addr; + if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL) + && IN6_IS_ADDR_V4MAPPED(&tmp_addr)) + ret += 576; + else # endif - ret += 1280; + ret += 1280; + } break; # endif default: @@ -670,61 +620,24 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = num; break; case BIO_CTRL_DGRAM_SET_CONNECTED: - to = (struct sockaddr *)ptr; - - if (to != NULL) { + if (ptr != NULL) { data->connected = 1; - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } + BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); } else { data->connected = 0; memset(&data->peer, 0, sizeof(data->peer)); } break; case BIO_CTRL_DGRAM_GET_PEER: - switch (data->peer.sa.sa_family) { - case AF_INET: - ret = sizeof(data->peer.sa_in); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - ret = sizeof(data->peer.sa_in6); - break; -# endif - default: - ret = sizeof(data->peer.sa); - break; - } + ret = BIO_ADDR_sockaddr_size(&data->peer); + /* FIXME: if num < ret, we will only return part of an address. + That should bee an error, no? */ if (num == 0 || num > ret) num = ret; memcpy(ptr, &data->peer, (ret = num)); break; case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *)ptr; - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } + BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); break; case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); |