Hi,
   The problem with SO_REUSEADDR impacts the regular DTLS handshake as
well at times. We run into a situation where a DTLS handshake does not
complete for a single client (windows only). Even after a connected
socket is established select gets triggered on the "listen socket" and
DTLSv1Listen gets called and the handshake never completes.
A network trace reveals the following messages successfully get exchanged
CLIENT HELLO
                         HELLOVERIFY REQUEST
CLIENTHELLO+COOKIE
                          SEVERHELLO+SERVCERT+SERVERKEY EXCHANGE
CLIENT CERT + CLIENT KEY EXCHANGE + CERT VERIFY

and the connection does not complete beyond this point as the client
messages end up going to the listen socket as opposed to the connected
socket and thus the handshake never completes (The server  never ends
up sending the CHANGE CIPHER SPEC + FINISH)

This has been  noticed  in our tests and does not happen on every
client handshake but we have seen it happen occasionally and is a
different manifestation of the underlying socket issue on windows.

Thanks,
-Yogi

On Mon, Jul 18, 2011 at 11:42 PM, Michael Tüxen
<michael.tue...@lurchi.franken.de> wrote:
> Hi Nilesh,
>
> thank you very much for isolating the problem in the socket handling
> and providing a small test program.
> Let us have a look (it might take some time).
>
> Best regards
> Michael
> On Jul 19, 2011, at 2:56 AM, Nilesh Vaghela wrote:
>
>> Hi Michael and Robin,
>>
>> I verified the same problem WITHOUT using SSL library and the problem is the 
>> same so it seems like Windows ISSUE.
>> Earlier Yogi and myself sent you guys sample program with SSL library.
>>
>> See program below which illustrates the problem.
>>
>> I think DTLS library relies heavily in connected socket and it seems like 
>> LINUX and WINDOWS behavior looks different.
>>
>> /* Tested on linux and windows
>>  * On windows use mingw-gcc:
>>  *    gcc -Wall -g -o udplisten test.c -lws2_32
>>  * On Linux
>>  *    gcc -Wall -g -o udplisten test.c
>>  * Test server
>>  * ./udplisten
>>  * Test client with in Linux:
>>  *    echo hello | netcat -u machinename -p 5555 9898 (this goes to listen 
>> socket sockl)
>>  *    echo hello | netcat -u machinename -p 5555 9898 (this goes to new 
>> connected socket 1)
>>  *    echo hello | netcat -u machinename -p 5556 9898  (this goes to listen 
>> socket sockl)
>>  *    echo hello | netcat -u machinename -p 5556 9898  (this goes to new 
>> connected socket 2)
>>  */
>> #ifdef WIN32
>> #include <winsock2.h>
>> #include <ws2tcpip.h>
>> #else
>> #include <sys/select.h>
>> #include <sys/socket.h>
>> #include <netinet/in.h>
>> #define SOCKET int
>> #define INVALID_SOCKET -1
>> #endif
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <errno.h>
>>
>> #undef max
>> #define max(x,y) ((x) > (y) ? (x) : (y))
>>
>> #define MAX_CLIENTS 256
>>     fd_set read_set, temp_set;
>>     SOCKET client_fds[256];
>>
>>
>>     //SOCKET socka = INVALID_SOCKET, sockb = INVALID_SOCKET;
>>     SOCKET sockl;
>>      SOCKET max;
>> int num_clients = 0;
>>     struct sockaddr_in addr;
>>
>> static void
>> die(const char *str)
>> {
>>     perror(str);
>>     exit(1);
>> }
>>
>> static SOCKET
>> mksocket(struct sockaddr_in *addr)
>> {
>>     SOCKET sock = INVALID_SOCKET;
>>     int opt = 1;
>>     if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
>>         die("socket");
>>     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, 
>> sizeof(opt)) < 0)
>>         die("setsockopt");
>>     if (bind(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0)
>>         die("bind");
>>     return sock;
>> }
>>
>> static void
>> process_listen(SOCKET sock, const char *label)
>> {
>>     char buffer[8192];
>>     struct sockaddr_in caddr;
>>     int count;
>>     int ret;
>>     SOCKET conn_sock;
>>
>>     socklen_t caddr_size = sizeof(caddr);
>>     memset(&caddr, 0, caddr_size);
>>     count = recvfrom(sock, buffer, sizeof(buffer), 0,
>>                          (struct sockaddr *)&caddr, &caddr_size);
>>     if (count < 0) die(label);
>>     printf("%s %d\n", label, count);
>>
>>     conn_sock = mksocket(&addr);
>>     max = max(conn_sock, max);
>>     FD_SET(conn_sock, &read_set);
>>
>>     client_fds[num_clients++] = conn_sock;
>>
>>     ret = connect(conn_sock, (const struct sockaddr *)&caddr, caddr_size);
>>     if (ret == 0)
>>       printf("connected to address = %s and port = %d\n", 
>> inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
>>     else
>>       printf("connetc failed address = %s and port = %d\n", 
>> inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
>>
>> }
>>
>>
>> static void
>> process(SOCKET sock, const char *label)
>> {
>>     char buffer[8192];
>>     struct sockaddr_in caddr;
>>     int count;
>>     socklen_t caddr_size = sizeof(caddr);
>>     memset(&caddr, 0, caddr_size);
>>     count = recvfrom(sock, buffer, sizeof(buffer), 0,
>>                          (struct sockaddr *)&caddr, &caddr_size);
>>     if (count < 0) die(label);
>>     printf("%s : bytes %d\n", label, count);
>> }
>>
>> int
>> main(int argc, char *argv[])
>> {
>>     int i;
>>
>> #ifdef WIN32
>>     WSADATA wsaData;
>>     if (WSAStartup(MAKEWORD(2,2), &wsaData))
>>         return -1;
>> #endif
>>     for (i = 0; i < MAX_CLIENTS; i++)
>>         client_fds[i] = INVALID_SOCKET;
>>
>>     addr.sin_family = AF_INET;
>>     addr.sin_port = htons(9898);
>>     addr.sin_addr.s_addr = INADDR_ANY;
>>
>>     sockl = mksocket(&addr);
>>
>>     max = sockl;
>>     FD_ZERO(&read_set);
>>     FD_SET(sockl, &read_set);
>>
>>     for (;;) {
>>         char buf[256];
>>
>>
>>
>>         memcpy(&temp_set, &read_set, sizeof(fd_set));
>>         if (select(max+1, &temp_set, NULL, NULL, NULL) < 0)
>>             die("select");
>>
>>         if (FD_ISSET(sockl, &temp_set))
>>             process_listen(sockl, "LISTEN");
>>
>>         for (i = 0; i < num_clients; i++)
>>         {
>>             if (FD_ISSET(client_fds[i], &temp_set))
>>             {
>>                 sprintf(buf, "%s %d", "RECEIVED FROM CLIENT ", i);
>>
>>                 process(client_fds[i], buf);
>>             }
>>
>>         }
>>
>>     }
>>     return 0;
>> }
>>
>> --Nilesh.
>>
>>
>> Stratacache Inc.(Santa Clara Office)
>> Systems Architect
>> O: 408-844-9810(2110)
>> M: 408-202-5401
>>
>>
>> ----- Original Message -----
>> From: "Michael Tüxen" <michael.tue...@lurchi.franken.de>
>> To: openssl-dev@openssl.org
>> Cc: "Robin Seggelmann" <seggelm...@fh-muenster.de>
>> Sent: Monday, July 18, 2011 9:42:03 AM GMT -08:00 US/Canada Pacific
>> Subject: Re: DTLSv1_listen unable to accept second client on windows (This 
>> works on Linux)
>>
>> On Jul 18, 2011, at 5:18 PM, Yogesh Chopra wrote:
>>
>> > Hi,
>> >   I am using a separate (second socket) for client connect and
>> > leaving the listening socket unconnected to receive everything else.
>> > (The server program is same as provided for linux earlier). The server
>> > program is same as provided earlier. (This will need modifications for
>> > windows and I will try uploading a new server program for windows
>> > compilation but this program is essentially what is used).
>> ... it would be very helpful to have a program which shows the issue
>> you are experiencing, since it might be a bug in OpenSSL or in the
>> application.
>>
>> Best regards
>> Michael
>> >
>> > http://groups.google.com/group/mailing.openssl.dev/browse_thread/thread/91f7fa90ab401759?pli=1
>> >
>> >
>> > Thanks,
>> > -Yogi
>> >
>> > On Sun, Jul 17, 2011 at 11:57 PM, Robin Seggelmann
>> > <seggelm...@fh-muenster.de> wrote:
>> >> Hi Yogesh,
>> >> are you connecting the listening socket? That shouldn't work on Linux 
>> >> either. The DTLSv1_listen call returns the sock_addr structure of the 
>> >> connecting client, so you can create a new socket dedicated for that 
>> >> client and connect it, while leaving the listening socket unconnected to 
>> >> receive everything else.
>> >>
>> >> Best regards
>> >> Robin
>> >>
>> >>
>> >> On Jul 16, 2011, at 1:53 AM, Yogesh Chopra wrote:
>> >>
>> >>> Hi,
>> >>>    I am using OpenSSL-1.0.0d (release) + all cumulative bug fixes +
>> >>> DTLS Heartbeat feature patch on Windows.
>> >>>
>> >>> A DTLS server (non-blocking) using DTLSv1_Listen having a UDP socket
>> >>> with SO_REUSEADDR is unable to accept a second client connection when
>> >>> it is already accepted a client connection and serving it.
>> >>>
>> >>> Details:
>> >>>
>> >>> Server                                    Client 1
>> >>>       State
>> >>>
>> >>> DTLSv1_Listen                       Handshake complete          
>> >>> Established
>> >>>                                             Client 2
>> >>>           State
>> >>>                                             Keeps sending CLIENT
>> >>> HELLO  but Server never responds with HelloVerify request
>> >>>                                             and select never gets
>> >>> triggered on the listen fd (used by DTLSv1_listen)
>> >>>
>> >>> As per some of the windows documents for connect, see excerpt below:
>> >>>
>> >>> http://msdn.microsoft.com/en-us/library/ms737625%28v=vs.85%29.aspx
>> >>>
>> >>> "For a connectionless socket (for example, type SOCK_DGRAM), the
>> >>> operation performed by connect is merely to establish a default
>> >>> destination address that can be used on subsequent send/ WSASend and
>> >>> recv/ WSARecv calls. Any datagrams received from an address other than
>> >>> the destination address specified will be discarded."
>> >>>
>> >>> So it appears that once a socket is connected to a client, it will no
>> >>> longer be used for accepting second client.
>> >>>
>> >>> It has been observed, that when the first client connection is
>> >>> released (terminated) a new client connection is accepted.
>> >>>
>> >>> This is not a problem on Linux.
>> >>>
>> >>> Is there any workarounds or special handling for windows ?
>> >>>
>> >>> Thanks,
>> >>> -Yogi
>> >>> ______________________________________________________________________
>> >>> OpenSSL Project                                 http://www.openssl.org
>> >>> Development Mailing List                       openssl-dev@openssl.org
>> >>> Automated List Manager                           majord...@openssl.org
>> >>
>> >>
>> >>
>> > ______________________________________________________________________
>> > OpenSSL Project                                 http://www.openssl.org
>> > Development Mailing List                       openssl-dev@openssl.org
>> > Automated List Manager                           majord...@openssl.org
>> >
>>
>> ______________________________________________________________________
>> OpenSSL Project                                 http://www.openssl.org
>> Development Mailing List                       openssl-dev@openssl.org
>> Automated List Manager                           majord...@openssl.org
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       openssl-dev@openssl.org
> Automated List Manager                           majord...@openssl.org
>
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to