提交 636b6b45 编写于 作者: D Dr. Stephen Henson

PR: 2069

Submitted by: Michael Tuexen <tuexen@fh-muenster.de>
Approved by: steve@openssl.org

IPv6 support for DTLS.
上级 2c55c0d3
...@@ -692,7 +692,15 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign ...@@ -692,7 +692,15 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
{ {
unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length, resultlength; unsigned int length, resultlength;
#if OPENSSL_USE_IPV6
union {
struct sockaddr_storage ss;
struct sockaddr_in6 s6;
struct sockaddr_in s4;
} peer;
#else
struct sockaddr_in peer; struct sockaddr_in peer;
#endif
/* Initialize a random secret */ /* Initialize a random secret */
if (!cookie_initialized) if (!cookie_initialized)
...@@ -709,8 +717,25 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign ...@@ -709,8 +717,25 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */ /* Create buffer with peer's address and port */
#if OPENSSL_USE_IPV6
length = 0;
switch (peer.ss.ss_family)
{
case AF_INET:
length += sizeof(struct in_addr);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
break;
default:
OPENSSL_assert(0);
break;
}
length += sizeof(in_port_t);
#else
length = sizeof(peer.sin_addr); length = sizeof(peer.sin_addr);
length += sizeof(peer.sin_port); length += sizeof(peer.sin_port);
#endif
buffer = OPENSSL_malloc(length); buffer = OPENSSL_malloc(length);
if (buffer == NULL) if (buffer == NULL)
...@@ -719,8 +744,33 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign ...@@ -719,8 +744,33 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
return 0; return 0;
} }
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); #if OPENSSL_USE_IPV6
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); switch (peer.ss.ss_family)
{
case AF_INET:
memcpy(buffer,
&peer.s4.sin_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s4.sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer,
&peer.s6.sin6_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s6.sin6_addr,
sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
#else
memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port));
memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr));
#endif
/* Calculate HMAC of buffer using the secret */ /* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
...@@ -737,7 +787,15 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned ...@@ -737,7 +787,15 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
{ {
unsigned char *buffer, result[EVP_MAX_MD_SIZE]; unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length, resultlength; unsigned int length, resultlength;
#if OPENSSL_USE_IPV6
union {
struct sockaddr_storage ss;
struct sockaddr_in6 s6;
struct sockaddr_in s4;
} peer;
#else
struct sockaddr_in peer; struct sockaddr_in peer;
#endif
/* If secret isn't initialized yet, the cookie can't be valid */ /* If secret isn't initialized yet, the cookie can't be valid */
if (!cookie_initialized) if (!cookie_initialized)
...@@ -747,8 +805,25 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned ...@@ -747,8 +805,25 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */ /* Create buffer with peer's address and port */
#if OPENSSL_USE_IPV6
length = 0;
switch (peer.ss.ss_family)
{
case AF_INET:
length += sizeof(struct in_addr);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
break;
default:
OPENSSL_assert(0);
break;
}
length += sizeof(in_port_t);
#else
length = sizeof(peer.sin_addr); length = sizeof(peer.sin_addr);
length += sizeof(peer.sin_port); length += sizeof(peer.sin_port);
#endif
buffer = OPENSSL_malloc(length); buffer = OPENSSL_malloc(length);
if (buffer == NULL) if (buffer == NULL)
...@@ -757,8 +832,33 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned ...@@ -757,8 +832,33 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
return 0; return 0;
} }
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr)); #if OPENSSL_USE_IPV6
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port)); switch (peer.ss.ss_family)
{
case AF_INET:
memcpy(buffer,
&peer.s4.sin_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s4.sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer,
&peer.s6.sin6_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s6.sin6_addr,
sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
#else
memcpy(buffer, &peer.sin_port, sizeof(peer.sin_port));
memcpy(buffer + sizeof(peer.sin_port), &peer.sin_addr, sizeof(peer.sin_addr));
#endif
/* Calculate HMAC of buffer using the secret */ /* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
......
...@@ -108,7 +108,11 @@ static BIO_METHOD methods_dgramp= ...@@ -108,7 +108,11 @@ static BIO_METHOD methods_dgramp=
typedef struct bio_dgram_data_st typedef struct bio_dgram_data_st
{ {
struct sockaddr peer; #if OPENSSL_USE_IPV6
struct sockaddr_storage peer;
#else
struct sockaddr_in peer;
#endif
unsigned int connected; unsigned int connected;
unsigned int _errno; unsigned int _errno;
unsigned int mtu; unsigned int mtu;
...@@ -274,7 +278,11 @@ static int dgram_read(BIO *b, char *out, int outl) ...@@ -274,7 +278,11 @@ static int dgram_read(BIO *b, char *out, int outl)
int ret=0; int ret=0;
bio_dgram_data *data = (bio_dgram_data *)b->ptr; bio_dgram_data *data = (bio_dgram_data *)b->ptr;
struct sockaddr peer; #if OPENSSL_USE_IPV6
struct sockaddr_storage peer;
#else
struct sockaddr_in peer;
#endif
int peerlen = sizeof(peer); int peerlen = sizeof(peer);
if (out != NULL) if (out != NULL)
...@@ -287,7 +295,7 @@ static int dgram_read(BIO *b, char *out, int outl) ...@@ -287,7 +295,7 @@ static int dgram_read(BIO *b, char *out, int outl)
* compiler warnings. * compiler warnings.
*/ */
dgram_adjust_rcv_timeout(b); dgram_adjust_rcv_timeout(b);
ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); ret=recvfrom(b->num,out,outl,0,(struct sockaddr *)&peer,(void *)&peerlen);
dgram_reset_rcv_timeout(b); dgram_reset_rcv_timeout(b);
if ( ! data->connected && ret >= 0) if ( ! data->connected && ret >= 0)
...@@ -315,10 +323,25 @@ static int dgram_write(BIO *b, const char *in, int inl) ...@@ -315,10 +323,25 @@ static int dgram_write(BIO *b, const char *in, int inl)
if ( data->connected ) if ( data->connected )
ret=writesocket(b->num,in,inl); ret=writesocket(b->num,in,inl);
else else
#if OPENSSL_USE_IPV6
if (data->peer.ss_family == AF_INET)
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
#else
ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
#endif
else
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6));
#else
ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in6));
#endif
#else
#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); ret=sendto(b->num, (char *)in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
#else #else
ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); ret=sendto(b->num, in, inl, 0, (const struct sockaddr *)&data->peer, sizeof(struct sockaddr_in));
#endif
#endif #endif
BIO_clear_retry_flags(b); BIO_clear_retry_flags(b);
...@@ -405,7 +428,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -405,7 +428,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
else else
{ {
#endif #endif
memcpy(&(data->peer),to, sizeof(struct sockaddr)); #if OPENSSL_USE_IPV6
memcpy(&(data->peer),to, sizeof(struct sockaddr_storage));
#else
memcpy(&(data->peer),to, sizeof(struct sockaddr_in));
#endif
#if 0 #if 0
} }
#endif #endif
...@@ -510,24 +537,41 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -510,24 +537,41 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
if ( to != NULL) if ( to != NULL)
{ {
data->connected = 1; data->connected = 1;
memcpy(&(data->peer),to, sizeof(struct sockaddr)); #if OPENSSL_USE_IPV6
memcpy(&(data->peer),to, sizeof(struct sockaddr_storage));
#else
memcpy(&(data->peer),to, sizeof(struct sockaddr_in));
#endif
} }
else else
{ {
data->connected = 0; data->connected = 0;
memset(&(data->peer), 0x00, sizeof(struct sockaddr)); #if OPENSSL_USE_IPV6
memset(&(data->peer), 0x00, sizeof(struct sockaddr_storage));
#else
memset(&(data->peer), 0x00, sizeof(struct sockaddr_in));
#endif
} }
break; break;
case BIO_CTRL_DGRAM_GET_PEER: case BIO_CTRL_DGRAM_GET_PEER:
to = (struct sockaddr *) ptr; to = (struct sockaddr *) ptr;
memcpy(to, &(data->peer), sizeof(struct sockaddr)); #if OPENSSL_USE_IPV6
ret = sizeof(struct sockaddr); memcpy(to, &(data->peer), sizeof(struct sockaddr_storage));
ret = sizeof(struct sockaddr_storage);
#else
memcpy(to, &(data->peer), sizeof(struct sockaddr_in));
ret = sizeof(struct sockaddr_in);
#endif
break; break;
case BIO_CTRL_DGRAM_SET_PEER: case BIO_CTRL_DGRAM_SET_PEER:
to = (struct sockaddr *) ptr; to = (struct sockaddr *) ptr;
memcpy(&(data->peer), to, sizeof(struct sockaddr)); #if OPENSSL_USE_IPV6
memcpy(&(data->peer), to, sizeof(struct sockaddr_storage));
#else
memcpy(&(data->peer), to, sizeof(struct sockaddr_in));
#endif
break; break;
case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册