The latest changes of bss_dgram.c affected the behavior of 
BIO_CTRL_DGRAM_GET_PEER, which now requires to preset the expected IP type 
before requesting the current peer. This was done to prevent that the user 
always has to use sockaddr_storage, even if he doesn't use IPv6 at all. The 
default is to return the length of a sockaddr structure which is always wrong, 
therefore existing DTLS applications which rely on this function for cookie 
generation, such as s_server/s_client, don't work anymore. Additionally, this 
requires that the user has to guess which IP type the peer has. This can be 
difficult, e.g. if the client uses IPv4 to connect to an IPv6 socket and a 
system returns AF_INET then.

A better solution is to use the num parameter of BIO_ctrl() to limit the length 
if desired. When num is 0, the function returns either sockaddr_in or 
sockaddr_in6, depending on what's necessary, so the user should use 
sockaddr_storage. If the user knows that he only uses IPv4 and doesn't want to 
use sockaddr_storage, he can limit the copied length by setting the num 
parameter to sizeof(struct sockaddr_in). He can then check if the family 
variable of the passed structure is really AF_INET and try again with 
sockaddr_storage or handle it as an error in case it's not.



Index: crypto/bio/bss_dgram.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/bio/bss_dgram.c,v
retrieving revision 1.7.2.20
diff -u -r1.7.2.20 bss_dgram.c
--- crypto/bio/bss_dgram.c      22 Nov 2009 12:24:43 -0000      1.7.2.20
+++ crypto/bio/bss_dgram.c      26 Nov 2009 10:20:24 -0000
@@ -566,18 +970,24 @@
                break;
        case BIO_CTRL_DGRAM_GET_PEER:
                to = (struct sockaddr *) ptr;
-               switch (to->sa_family)
+               switch (data->peer.sa.sa_family)
                        {
                        case AF_INET:
-                               
memcpy(to,&data->peer,(ret=sizeof(data->peer.sa_in)));
+                               if (num == 0 || num > sizeof(data->peer.sa_in))
+                                       num = sizeof(data->peer.sa_in);
+                               memcpy(to,&data->peer,(ret=num));
                                break;
 #if OPENSSL_USE_IPV6
                        case AF_INET6:
-                               
memcpy(to,&data->peer,(ret=sizeof(data->peer.sa_in6)));
+                               if (num == 0 || num > sizeof(data->peer.sa_in6))
+                                       num = sizeof(data->peer.sa_in6);
+                               memcpy(to,&data->peer,(ret=num));
                                break;
 #endif
                        default:
-                               
memcpy(to,&data->peer,(ret=sizeof(data->peer.sa)));
+                               if (num == 0 || num > sizeof(data->peer.sa))
+                                       num = sizeof(data->peer.sa);
+                               memcpy(to,&data->peer,(ret=num));
                                break;
                        }
                break;



Attachment: get_peer.patch
Description: Binary data

Reply via email to