From 4ff014d2757edb0e2eef8f896f8ff276f2e418cb Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Wed, 13 Apr 2011 18:43:28 +0200 Subject: [PATCH] Add multicast support for sockets --- simgear/io/raw_socket.cxx | 24 ++++++++++++++++++++++-- simgear/io/sg_socket.cxx | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/simgear/io/raw_socket.cxx b/simgear/io/raw_socket.cxx index e2adb7ee..0d9199c1 100644 --- a/simgear/io/raw_socket.cxx +++ b/simgear/io/raw_socket.cxx @@ -196,7 +196,8 @@ bool Socket::open ( bool stream ) // killed. // // Reference: http://www.unixguide.net/network/socketfaq/4.5.shtml - // + // -- + // Also required for joining multicast domains if ( stream ) { int opt_boolean = 1; #if defined(_WIN32) || defined(__CYGWIN__) @@ -256,9 +257,28 @@ void Socket::setBroadcast ( bool broadcast ) int Socket::bind ( const char* host, int port ) { + int result; assert ( handle != -1 ) ; IPAddress addr ( host, port ) ; - return ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress)); + if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) { + SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")"); + return result; + } + + // 224.0.0.0 - 239.255.255.255 are multicast + // Usage of 239.x.x.x is recommended for local scope + // Reference: http://tools.ietf.org/html/rfc5771 + if( ntohl(addr.getIP()) >= 0xe0000000 && ntohl(addr.getIP()) <= 0xefffffff ) { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = addr.getIP(); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if( (result=::setsockopt(getHandle(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq))) != 0 ) { + SG_LOG(SG_IO, SG_ALERT, "setsockopt(IP_ADD_MEMBERSHIP) failed. Errno " << errno << " (" << strerror(errno) << ")"); + return result; + } + } + + return 0; } diff --git a/simgear/io/sg_socket.cxx b/simgear/io/sg_socket.cxx index 770bb51d..4af401de 100644 --- a/simgear/io/sg_socket.cxx +++ b/simgear/io/sg_socket.cxx @@ -84,7 +84,7 @@ SGSocket::make_server_socket() return false; } - if (sock.bind( "", port ) < 0) + if (sock.bind( hostname.c_str(), port ) < 0) { SG_LOG( SG_IO, SG_ALERT, "Error: bind() failed in make_server_socket()" ); -- 2.39.5