From c8f47626e2428449bfb64844e46fe5ad6b8e0f1c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 21 Oct 2010 14:23:18 -0400 Subject: [PATCH] Rx: Fix socket() handling so errors are properly detected socket() returns an osi_socket which on Windows is an unsigned type (HANDLE). Therefore, tests of osi_socket < 0 will never identify when the INVALID_SOCKET value is returned. On Windows, the OSI_NULLSOCKET is assigned to INVALID_SOCKET. Replace all comparisons of (osi_socket < 0) with (osi_socket == OSI_NULLSOCKET) as a means of detecting errors. In addition, do not pass socket() the protocol value 0 when IPPROTO_UDP is what is desired. Finally, perror() on Windows never reports any error from Winsock. perror() is a CRT function. To get the real socket error WSAGetLastError() must be called and its value be written to stderr. Change-Id: Ibc392eeb733851f56dbc7398cb252a4753b95275 Reviewed-on: http://gerrit.openafs.org/3027 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/rx/rx_user.c | 49 +++++++++++++++++++++++++++---------------------- src/rxdebug/rxdebug.c | 14 +++++++++++++- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/rx/rx_user.c b/src/rx/rx_user.c index 32f4c06..8fbeaf4 100644 --- a/src/rx/rx_user.c +++ b/src/rx/rx_user.c @@ -124,10 +124,14 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) goto error; } #endif - socketFd = socket(AF_INET, SOCK_DGRAM, 0); + socketFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (socketFd < 0) { + if (socketFd == OSI_NULLSOCKET) { +#ifdef AFS_NT40_ENV + fprintf(stderr, "socket() failed with error %u\n", WSAGetLastError()); +#else perror("socket"); +#endif goto error; } @@ -146,11 +150,9 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) if (binds) rxi_Delay(10); code = bind(socketFd, (struct sockaddr *)&taddr, sizeof(taddr)); - if (!code) - break; + break; } if (code) { - perror("bind"); (osi_Msg "%sbind failed\n", name); goto error; } @@ -218,10 +220,10 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) error: #ifdef AFS_NT40_ENV - if (socketFd >= 0) + if (socketFd != OSI_NULLSOCKET) closesocket(socketFd); #else - if (socketFd >= 0) + if (socketFd != OSI_NULLSOCKET) close(socketFd); #endif @@ -490,10 +492,9 @@ rx_GetIFInfo(void) memset(myNetMTUs, 0, sizeof(myNetMTUs)); memset(myNetMasks, 0, sizeof(myNetMasks)); UNLOCK_IF; - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s == OSI_NULLSOCKET) return; - #ifdef AFS_AIX41_ENV ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; @@ -734,18 +735,22 @@ rxi_InitPeerParams(struct rx_peer *pp) #endif /* ADAPT_MTU */ #if defined(ADAPT_PMTU) && defined(IP_MTU) sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock >= 0) { - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = pp->host; - addr.sin_port = pp->port; - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { - int mtu=0; - socklen_t s = sizeof(mtu); - if (getsockopt(sock, SOL_IP, IP_MTU, &mtu, &s)== 0) { - pp->ifMTU = MIN(mtu - RX_IPUDP_SIZE, pp->ifMTU); - } - } - close(sock); + if (sock != OSI_NULLSOCKET) { + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = pp->host; + addr.sin_port = pp->port; + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + int mtu=0; + socklen_t s = sizeof(mtu); + if (getsockopt(sock, SOL_IP, IP_MTU, &mtu, &s)== 0) { + pp->ifMTU = MIN(mtu - RX_IPUDP_SIZE, pp->ifMTU); + } + } +#ifdef AFS_NT40_ENV + closesocket(sock); +#else + close(sock); +#endif } #endif pp->ifMTU = rxi_AdjustIfMTU(pp->ifMTU); diff --git a/src/rxdebug/rxdebug.c b/src/rxdebug/rxdebug.c index c3ed6f4..944a2b8 100644 --- a/src/rxdebug/rxdebug.c +++ b/src/rxdebug/rxdebug.c @@ -209,7 +209,15 @@ MainCommand(struct cmd_syndesc *as, void *arock) hostAddr.s_addr = host; afs_inet_ntoa_r(hostAddr.s_addr, hoststr); printf("Trying %s (port %d):\n", hoststr, ntohs(port)); - s = socket(AF_INET, SOCK_DGRAM, 0); + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s == OSI_NULLSOCKET) { +#ifdef AFS_NT40_ENV + fprintf(stderr, "socket() failed with error %u\n", WSAGetLastError()); +#else + perror("socket"); +#endif + exit(1); + } taddr.sin_family = AF_INET; taddr.sin_port = 0; taddr.sin_addr.s_addr = 0; @@ -218,7 +226,11 @@ MainCommand(struct cmd_syndesc *as, void *arock) #endif code = bind(s, (struct sockaddr *)&taddr, sizeof(struct sockaddr_in)); if (code) { +#ifdef AFS_NT40_ENV + fprintf(stderr, "bind() failed with error %u\n", WSAGetLastError()); +#else perror("bind"); +#endif exit(1); } -- 1.9.4