diff options
author | Steve Huston <shuston@riverace.com> | 1998-05-08 13:55:57 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 1998-05-08 13:55:57 +0000 |
commit | 0958af1a97bc0485a156f68a38ffd9a54526efff (patch) | |
tree | 0c630806d742ceaf09663c137b1724433622f572 /ace/SOCK_Dgram_Mcast.cpp | |
parent | b977a90a239b7434d8816ba07c2fc25d614e9e40 (diff) | |
download | ATCD-0958af1a97bc0485a156f68a38ffd9a54526efff.tar.gz |
Added code to subscribe() for Win32 to subscribe on each IP interface
if no specific interface is given. This works around a bug in winsock on
NT.
Diffstat (limited to 'ace/SOCK_Dgram_Mcast.cpp')
-rw-r--r-- | ace/SOCK_Dgram_Mcast.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/ace/SOCK_Dgram_Mcast.cpp b/ace/SOCK_Dgram_Mcast.cpp index f4eb5e21b18..3ae21f94220 100644 --- a/ace/SOCK_Dgram_Mcast.cpp +++ b/ace/SOCK_Dgram_Mcast.cpp @@ -68,6 +68,55 @@ ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, else if (ACE_SOCK_Dgram::shared_open (local, protocol_family) == -1) return -1; } +#if defined (ACE_WIN32) + // Windows NT's winsock has trouble with multicast subscribes in the presence + // of multiple network interfaces when the IP address is given as INADDR_ANY. + // It will pick the first interface and only accept mcast there. So, to work + // around this, cycle through all of the interfaces known and subscribe to + // all the non-loopback ones. + // Note that this only needs to be done on NT, but there's no way to tell + // at this point if the code will be running on NT - only if it is compiled + // for NT-only or for NT/95, and that doesn't really help us. It doesn't + // hurt to do this on Win95, it's just a little slower than it normally + // would be. + // + // NOTE - get_ip_interfaces doesn't always get all of the interfaces. In + // particular, it may not get a PPP interface. This is a limitation of the + // way get_ip_interfaces works with MSVC. The reliable way of getting the + // interface list is available only with MSVC 5. + + if (net_if == 0) + { + ACE_INET_Addr *if_addrs; + size_t if_cnt, nr_subscribed; + + if (ACE::get_ip_interfaces(if_cnt, if_addrs) != 0) + return -1; + + for (nr_subscribed = 0; if_cnt > 0; ) + { + --if_cnt; // Convert to 0-based for indexing, and next loop check + if (if_addrs[if_cnt].get_ip_address() == INADDR_LOOPBACK) + continue; + if (this->subscribe(mcast_addr, + reuse_addr, + if_addrs[if_cnt].get_host_addr(), + protocol_family, + protocol) == 0) + ++nr_subscribed; + } + + delete [] if_addrs; + + if (nr_subscribed == 0) + { + errno = ENODEV; + return -1; + } + return 0; + } + // else do it like everyone else... +#endif /* ACE_WIN32 */ // Create multicast request. if (this->make_multicast_address (this->mcast_addr_, net_if) == -1) |