提交 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
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
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;
#endif
/* Initialize a random secret */
if (!cookie_initialized)
......@@ -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);
/* 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_port);
#endif
buffer = OPENSSL_malloc(length);
if (buffer == NULL)
......@@ -719,8 +744,33 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
return 0;
}
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
#if OPENSSL_USE_IPV6
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 */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
......@@ -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 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;
#endif
/* If secret isn't initialized yet, the cookie can't be valid */
if (!cookie_initialized)
......@@ -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);
/* 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_port);
#endif
buffer = OPENSSL_malloc(length);
if (buffer == NULL)
......@@ -757,8 +832,33 @@ int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
return 0;
}
memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
#if OPENSSL_USE_IPV6
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 */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
......
......@@ -108,7 +108,11 @@ static BIO_METHOD methods_dgramp=
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 _errno;
unsigned int mtu;
......@@ -274,7 +278,11 @@ static int dgram_read(BIO *b, char *out, int outl)
int ret=0;
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);
if (out != NULL)
......@@ -287,7 +295,7 @@ static int dgram_read(BIO *b, char *out, int outl)
* compiler warnings.
*/
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);
if ( ! data->connected && ret >= 0)
......@@ -315,10 +323,25 @@ static int dgram_write(BIO *b, const char *in, int inl)
if ( data->connected )
ret=writesocket(b->num,in,inl);
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)
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
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
BIO_clear_retry_flags(b);
......@@ -405,7 +428,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
else
{
#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
}
#endif
......@@ -510,24 +537,41 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
if ( to != NULL)
{
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
{
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;
case BIO_CTRL_DGRAM_GET_PEER:
to = (struct sockaddr *) ptr;
memcpy(to, &(data->peer), sizeof(struct sockaddr));
ret = sizeof(struct sockaddr);
#if OPENSSL_USE_IPV6
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;
case BIO_CTRL_DGRAM_SET_PEER:
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;
case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
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.
先完成此消息的编辑!
想要评论请 注册