From: Torsten Dreyer <Torsten@t3r.de>
Date: Wed, 13 Apr 2011 16:43:28 +0000 (+0200)
Subject: Add multicast support for sockets
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=4ff014d2757edb0e2eef8f896f8ff276f2e418cb;p=simgear.git

Add multicast support for sockets
---

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()" );