bss_dgram.c: fix bugs [from HEAD].

PR: 2833
This commit is contained in:
Andy Polyakov 2012-06-19 12:36:00 +00:00
parent 58fdd30664
commit 7655044dd3

View File

@ -77,11 +77,11 @@
#define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
#endif #endif
#ifdef OPENSSL_SYS_LINUX #if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
#define IP_MTU 14 /* linux is lame */ #define IP_MTU 14 /* linux is lame */
#endif #endif
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
/* Standard definition causes type-punning problems. */ /* Standard definition causes type-punning problems. */
#undef IN6_IS_ADDR_V4MAPPED #undef IN6_IS_ADDR_V4MAPPED
#define s6_addr32 __u6_addr.__u6_addr32 #define s6_addr32 __u6_addr.__u6_addr32
@ -265,7 +265,7 @@ static void dgram_adjust_rcv_timeout(BIO *b)
{ {
#if defined(SO_RCVTIMEO) #if defined(SO_RCVTIMEO)
bio_dgram_data *data = (bio_dgram_data *)b->ptr; bio_dgram_data *data = (bio_dgram_data *)b->ptr;
int sz = sizeof(int); union { size_t s; int i; } sz = {0};
/* Is a timer active? */ /* Is a timer active? */
if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
@ -275,6 +275,8 @@ static void dgram_adjust_rcv_timeout(BIO *b)
/* Read current socket timeout */ /* Read current socket timeout */
#ifdef OPENSSL_SYS_WINDOWS #ifdef OPENSSL_SYS_WINDOWS
int timeout; int timeout;
sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
(void*)&timeout, &sz) < 0) (void*)&timeout, &sz) < 0)
{ perror("getsockopt"); } { perror("getsockopt"); }
@ -284,9 +286,12 @@ static void dgram_adjust_rcv_timeout(BIO *b)
data->socket_timeout.tv_usec = (timeout % 1000) * 1000; data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
} }
#else #else
sz.i = sizeof(data->socket_timeout);
if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
&(data->socket_timeout), (void *)&sz) < 0) &(data->socket_timeout), (void *)&sz) < 0)
{ perror("getsockopt"); } { perror("getsockopt"); }
else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
OPENSSL_assert(sz.s<=sizeof(data->socket_timeout));
#endif #endif
/* Get current time */ /* Get current time */
@ -455,11 +460,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
int *ip; int *ip;
struct sockaddr *to = NULL; struct sockaddr *to = NULL;
bio_dgram_data *data = NULL; bio_dgram_data *data = NULL;
#if defined(IP_MTU_DISCOVER) || defined(IP_MTU) int sockopt_val = 0;
long sockopt_val = 0; #if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
unsigned int sockopt_len = 0; socklen_t sockopt_len; /* assume that system supporting IP_MTU is
#endif * modern enough to define socklen_t */
#ifdef OPENSSL_SYS_LINUX
socklen_t addr_len; socklen_t addr_len;
union { union {
struct sockaddr sa; struct sockaddr sa;
@ -541,7 +545,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break; break;
/* (Linux)kernel sets DF bit on outgoing IP packets */ /* (Linux)kernel sets DF bit on outgoing IP packets */
case BIO_CTRL_DGRAM_MTU_DISCOVER: case BIO_CTRL_DGRAM_MTU_DISCOVER:
#ifdef OPENSSL_SYS_LINUX #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
addr_len = (socklen_t)sizeof(addr); addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr)); memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0) if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@ -549,7 +553,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0; ret = 0;
break; break;
} }
sockopt_len = sizeof(sockopt_val);
switch (addr.sa.sa_family) switch (addr.sa.sa_family)
{ {
case AF_INET: case AF_INET:
@ -558,7 +561,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
&sockopt_val, sizeof(sockopt_val))) < 0) &sockopt_val, sizeof(sockopt_val))) < 0)
perror("setsockopt"); perror("setsockopt");
break; break;
#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) #if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
case AF_INET6: case AF_INET6:
sockopt_val = IPV6_PMTUDISC_DO; sockopt_val = IPV6_PMTUDISC_DO;
if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
@ -575,7 +578,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
break; break;
#endif #endif
case BIO_CTRL_DGRAM_QUERY_MTU: case BIO_CTRL_DGRAM_QUERY_MTU:
#ifdef OPENSSL_SYS_LINUX #if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
addr_len = (socklen_t)sizeof(addr); addr_len = (socklen_t)sizeof(addr);
memset((void *)&addr, 0, sizeof(addr)); memset((void *)&addr, 0, sizeof(addr));
if (getsockname(b->num, &addr.sa, &addr_len) < 0) if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@ -737,10 +740,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif #endif
break; break;
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
#ifdef OPENSSL_SYS_WINDOWS
{ {
int timeout, sz = sizeof(timeout); union { size_t s; int i; } sz = {0};
#ifdef OPENSSL_SYS_WINDOWS
int timeout;
struct timeval *tv = (struct timeval *)ptr; struct timeval *tv = (struct timeval *)ptr;
sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
(void*)&timeout, &sz) < 0) (void*)&timeout, &sz) < 0)
{ perror("getsockopt"); ret = -1; } { perror("getsockopt"); ret = -1; }
@ -750,12 +756,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
tv->tv_usec = (timeout % 1000) * 1000; tv->tv_usec = (timeout % 1000) * 1000;
ret = sizeof(*tv); ret = sizeof(*tv);
} }
}
#else #else
sz.i = sizeof(struct timeval);
if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
ptr, (void *)&ret) < 0) ptr, (void *)&sz) < 0)
{ perror("getsockopt"); ret = -1; } { perror("getsockopt"); ret = -1; }
else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
{
OPENSSL_assert(sz.s<=sizeof(struct timeval));
ret = (int)sz.s;
}
else
ret = sz.i;
#endif #endif
}
break; break;
#endif #endif
#if defined(SO_SNDTIMEO) #if defined(SO_SNDTIMEO)
@ -775,10 +789,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif #endif
break; break;
case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
#ifdef OPENSSL_SYS_WINDOWS
{ {
int timeout, sz = sizeof(timeout); union { size_t s; int i; } sz = {0};
#ifdef OPENSSL_SYS_WINDOWS
int timeout;
struct timeval *tv = (struct timeval *)ptr; struct timeval *tv = (struct timeval *)ptr;
sz.i = sizeof(timeout);
if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
(void*)&timeout, &sz) < 0) (void*)&timeout, &sz) < 0)
{ perror("getsockopt"); ret = -1; } { perror("getsockopt"); ret = -1; }
@ -790,10 +807,19 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
} }
} }
#else #else
sz.i = sizeof(struct timeval);
if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
ptr, (void *)&ret) < 0) ptr, (void *)&sz) < 0)
{ perror("getsockopt"); ret = -1; } { perror("getsockopt"); ret = -1; }
else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
{
OPENSSL_assert(sz.s<=sizeof(struct timeval));
ret = (int)sz.s;
}
else
ret = sz.i;
#endif #endif
}
break; break;
#endif #endif
case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
@ -965,7 +991,6 @@ static int dgram_sctp_free(BIO *a)
#ifdef SCTP_AUTHENTICATION_EVENT #ifdef SCTP_AUTHENTICATION_EVENT
void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
{ {
unsigned int sockopt_len = 0;
int ret; int ret;
struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event; struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
@ -975,9 +1000,8 @@ void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
/* delete key */ /* delete key */
authkeyid.scact_keynumber = authkeyevent->auth_keynumber; authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
sockopt_len = sizeof(struct sctp_authkeyid);
ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
&authkeyid, sockopt_len); &authkeyid, sizeof(struct sctp_authkeyid));
} }
} }
#endif #endif
@ -1308,7 +1332,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
{ {
long ret=1; long ret=1;
bio_dgram_sctp_data *data = NULL; bio_dgram_sctp_data *data = NULL;
unsigned int sockopt_len = 0; socklen_t sockopt_len = 0;
struct sctp_authkeyid authkeyid; struct sctp_authkeyid authkeyid;
struct sctp_authkey *authkey; struct sctp_authkey *authkey;