SO_REUSEADDR and windows enhanced socket security

yesin v.yesin@gmail.com
Tue Dec 15 15:49:00 GMT 2009


looks like a problem with SO_REUSEADDR exists in CYGWIN for all windows 
with support for "Enhanced socket security" (see 
http://msdn.microsoft.com/en-us/library/ms740621(VS.85).aspx 
<http://www.google.com/url?sa=D&q=http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx&usg=AFQjCNF9bXOmPTwYjiP37Xdq2xRAYNXfWg>) 
i'am trying to start multimple simultaneous UDP listeners for a 
multicast packets on a single machine (reuse same address and port with 
SO_REUSEADDR)
i've done such tests with cygwin 1.7 beta in windows vista, server 2008, 
7 environment - all with no success, i.e. i can't start more than one 
listener (i see an error message Address already in use in bind())!
in windows xp all works as expected!
i'll show some samples to demonstrate this:
=================listener.c========================
#include <sys/types.h>
#ifndef __MINGW32__
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
#else
 #include <winsock2.h>
 #include <ws2tcpip.h>
#endif
#include <stdio.h>
#include <stdlib.h>
struct sockaddr_in localSock;
struct ip_mreq group;
int sd;
int datalen;
char databuf[1024];
int main(int argc, char *argv[])
{
 struct sockaddr_in sender_addr;
 int sender_addr_size = sizeof(sender_addr);
#ifdef __MINGW32__
 WSADATA wsadata;
 if (WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) {
 printf("can't WSAStartup\n");
 exit(1);
 }
#endif
 /* Create a datagram socket on which to receive. */
 sd = socket(AF_INET, SOCK_DGRAM, 0);
 if(sd < 0)
 {
 printf("Opening datagram socket error %d\n", sd);
 exit(1);
 }
 printf("Opening datagram socket....OK.\n");
 /* Enable SO_REUSEADDR to allow multiple instances of this */
 /* application to receive copies of the multicast datagrams. */
 {
 int reuse = 1;
 if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char 
*)&reuse, sizeof
(reuse)) < 0)
 {
 perror("Setting SO_REUSEADDR error");
 close(sd);
 exit(1);
 }
 printf("Setting SO_REUSEADDR...OK.\n");
 }
 /* Bind to the proper port number with the IP address */
 /* specified as INADDR_ANY. */
 memset((char *) &localSock, 0, sizeof(localSock));
 localSock.sin_family = AF_INET;
 localSock.sin_port = htons(4321);
 localSock.sin_addr.s_addr = INADDR_ANY;
 if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
 {
 perror("Binding datagram socket error");
 close(sd);
 exit(1);
 }
 printf("Binding datagram socket...OK.\n");
 /* Join the multicast group 226.1.1.1 on the local 203.106.93.94 */
 /* interface. Note that this IP_ADD_MEMBERSHIP option must be */
 /* called for each local interface over which the multicast */
 /* datagrams are to be received. */
 group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
 group.imr_interface.s_addr = 
INADDR_ANY;//inet_addr("203.106.93.94");
 if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group,
sizeof(group)) < 0)
 {
 perror("Adding multicast group error");
 close(sd);
 exit(1);
 }
 printf("Adding multicast group...OK.\n");
 /* Read from the socket. */
 datalen = sizeof(databuf);
 while(1)
 {
 printf("Receiving...\n");
 if(recvfrom(sd, databuf, datalen, 0, (struct sockaddr *)
&sender_addr, &sender_addr_size) < 0)
 {
 perror("Reading datagram message error");
 close(sd);
 exit(1);
 }
 else
 {
 printf("Reading datagram message...OK.\n");
 printf("The message from multicast server is: 
\"%s\"\n", databuf);
 }
 }
 return 0;
}
===============================================================
============send.c==============================================
/* Send Multicast Datagram code example. */
#include <sys/types.h>
#ifndef __MINGW32__
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
#else
 #include <winsock2.h>
 #include <ws2tcpip.h>
#endif
#include <stdio.h>
#include <stdlib.h>
struct in_addr localInterface;
struct sockaddr_in groupSock;
int sd;
char databuf[1024] = "Multicast test message!";
int datalen = sizeof(databuf);
int main (int argc, char *argv[ ])
{
#ifdef __MINGW32__
 WSADATA wsadata;
 if (WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) {
 printf("can't WSAStartup\n");
 exit(1);
 }
#endif
 /* Create a datagram socket on which to send. */
 sd = socket(AF_INET, SOCK_DGRAM, 0);
 if(sd < 0)
 {
 perror("Opening datagram socket error");
 exit(1);
 }
 printf("Opening the datagram socket...OK.\n");
 /* Initialize the group sockaddr structure with a */
 /* group address of 225.1.1.1 and port 5555. */
 memset((char *) &groupSock, 0, sizeof(groupSock));
 groupSock.sin_family = AF_INET;
 groupSock.sin_addr.s_addr = inet_addr("226.1.1.1");
 groupSock.sin_port = htons(4321);
 /* Disable loopback so you do not receive your own datagrams.
 {
 char loopch = 0;
 if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char 
*)&loopch,
sizeof(loopch)) < 0)
 {
 perror("Setting IP_MULTICAST_LOOP error");
 close(sd);
 exit(1);
 }
 printf("Disabling the loopback...OK.\n");
 }
 */
 /* Set local interface for outbound multicast datagrams. */
 /* The IP address specified must be associated with a local, */
 /* multicast capable interface. */
 localInterface.s_addr = INADDR_ANY;
 if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)
&localInterface, sizeof(localInterface)) < 0)
 {
 perror("Setting local interface error");
 exit(1);
 }
 printf("Setting the local interface...OK\n");
 /* Send a message to the multicast group specified by the*/
 /* groupSock sockaddr structure. */
 /*int datalen = 1024;*/
 if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock,
sizeof(groupSock)) < 0)
 {
 perror("Sending datagram message error");
 exit(1);
 }
 printf("Sending datagram message...OK\n");
#ifdef __MINGW32__
 closesocket(sd);
 WSACleanup();
#endif
 return 0;
}
===============================================================
with cygwin environment i can't run multiple listerers... bind error:
Address already in use!
(
building with cygwin:
gcc -o listener.cygwin.exe listener.c
gcc -o send.cygwin.exe send.c
)
but with mingw all works as expected!
(
building with mingw:
gcc -o listener.mingw.exe listener.c -lws2_32
gcc -o send.mingw.exe send.c -lws2_32
or in mingw environment:
gcc -mno-cygwin -o listener.mingw.exe listener.c -lws2_32
gcc -mno-cygwin -o send.mingw.exe send.c -lws2_32
)
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple


More information about the Cygwin mailing list

AltStyle によって変換されたページ (->オリジナル) /