On Jul 19, 2011, at 9:22 PM, Yogesh Chopra wrote: > 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. Hi,
as you said this is a Windows specific socket layer issue, not a bug in the OpenSSL code. We might come up with a way to handle unconnected UDP sockets. Having a way to demultiplex incoming packets would also to allow 1-to-many style SCTP sockets. However, I'm not sure if this would find its way into 1.0.0. Best regards Michael > > 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 > ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org