This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

SO_REUSEADDR and windows enhanced socket security


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]