| @@ -1250,55 +1250,19 @@ namespace GSF.Communication · 1249 unmodified lines |
| 1250 | 1250 | |
| 1251 | 1251 | private void AddMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, out byte[] multicastMembershipAddresses) |
| 1252 | 1252 | { |
| 1253 | | − if (!Transport.IsMulticastIP(serverAddress)) |
| 1254 | | − throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP."); |
| 1253 | + multicastMembershipAddresses = null; |
| 1255 | 1254 | |
| 1256 | | − if ((object)sourceAddress == null) |
| 1257 | | − { |
| 1258 | | − // Execute multicast subscribe for any source |
| 1259 | | − m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(serverAddress)); |
| 1260 | | − multicastMembershipAddresses = null; |
| 1261 | | − } |
| 1262 | | − else |
| 1255 | + try |
| 1263 | 1256 | { |
| 1264 | | − IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address; |
| 1265 | | − |
| 1266 | | − if (sourceAddress.AddressFamily != serverAddress.AddressFamily) |
| 1267 | | − throw new InvalidOperationException(string.Format("Source address \"{0}\" is not in the same IP format as server address \"{1}\"", sourceAddress, serverAddress)); |
| 1268 | | − |
| 1269 | | − if (localAddress.AddressFamily != serverAddress.AddressFamily) |
| 1270 | | − throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress)); |
| 1271 | | − |
| 1272 | | − MemoryStream membershipAddresses = new MemoryStream(); |
| 1273 | | − |
| 1274 | | − byte[] serverAddressBytes = serverAddress.GetAddressBytes(); |
| 1275 | | − byte[] sourceAddressBytes = sourceAddress.GetAddressBytes(); |
| 1276 | | − byte[] localAddressBytes = localAddress.GetAddressBytes(); |
| 1277 | | − |
| 1278 | | − membershipAddresses.Write(serverAddressBytes, 0, serverAddressBytes.Length); |
| 1279 | | − membershipAddresses.Write(sourceAddressBytes, 0, sourceAddressBytes.Length); |
| 1280 | | − membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length); |
| 1281 | | − |
| 1282 | | − multicastMembershipAddresses = membershipAddresses.ToArray(); |
| 1283 | | − |
| 1284 | | − // Execute multicast subscribe for specific source |
| 1285 | | − m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, multicastMembershipAddresses); |
| 1286 | | − } |
| 1287 | | − } |
| 1257 | + if (!Transport.IsMulticastIP(serverAddress)) |
| 1258 | + throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP."); |
| 1288 | 1259 | |
| 1289 | | − private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses) |
| 1290 | | − { |
| 1291 | | − if (!Transport.IsMulticastIP(serverAddress)) |
| 1292 | | − throw new InvalidOperationException("Cannot drop multicast membership if server address is not a multicast IP."); |
| 1293 | | − |
| 1294 | | − if ((object)sourceAddress == null && (object)multicastMembershipAddresses == null) |
| 1295 | | − { |
| 1296 | | − // Execute multicast unsubscribe for any source |
| 1297 | | − m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropMembership, new MulticastOption(serverAddress)); |
| 1298 | | − } |
| 1299 | | − else |
| 1300 | | − { |
| 1301 | | − if ((object)multicastMembershipAddresses == null) |
| 1260 | + if ((object)sourceAddress == null) |
| 1261 | + { |
| 1262 | + // Execute multicast subscribe for any source |
| 1263 | + m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(serverAddress)); |
| 1264 | + } |
| 1265 | + else |
| 1302 | 1266 | { |
| 1303 | 1267 | IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address; |
| 1304 | 1268 | |
| @@ -1309,6 +1273,7 @@ namespace GSF.Communication · 4 unmodified lines |
| 1309 | 1273 | throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress)); |
| 1310 | 1274 | |
| 1311 | 1275 | MemoryStream membershipAddresses = new MemoryStream(); |
| 1276 | + |
| 1312 | 1277 | byte[] serverAddressBytes = serverAddress.GetAddressBytes(); |
| 1313 | 1278 | byte[] sourceAddressBytes = sourceAddress.GetAddressBytes(); |
| 1314 | 1279 | byte[] localAddressBytes = localAddress.GetAddressBytes(); |
| @@ -1318,10 +1283,62 @@ namespace GSF.Communication · 3 unmodified lines |
| 1318 | 1283 | membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length); |
| 1319 | 1284 | |
| 1320 | 1285 | multicastMembershipAddresses = membershipAddresses.ToArray(); |
| 1286 | + |
| 1287 | + // Execute multicast subscribe for specific source |
| 1288 | + m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, multicastMembershipAddresses); |
| 1321 | 1289 | } |
| 1290 | + } |
| 1291 | + catch (SocketException ex) |
| 1292 | + { |
| 1293 | + if (ex.SocketErrorCode != SocketError.InvalidArgument) |
| 1294 | + throw; |
| 1295 | + } |
| 1296 | + } |
| 1322 | 1297 | |
| 1323 | | − // Execute multicast unsubscribe for specific source |
| 1324 | | − m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropSourceMembership, multicastMembershipAddresses); |
| 1298 | + private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses) |
| 1299 | + { |
| 1300 | + try |
| 1301 | + { |
| 1302 | + if (!Transport.IsMulticastIP(serverAddress)) |
| 1303 | + throw new InvalidOperationException("Cannot drop multicast membership if server address is not a multicast IP."); |
| 1304 | + |
| 1305 | + if ((object)sourceAddress == null && (object)multicastMembershipAddresses == null) |
| 1306 | + { |
| 1307 | + // Execute multicast unsubscribe for any source |
| 1308 | + m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropMembership, new MulticastOption(serverAddress)); |
| 1309 | + } |
| 1310 | + else |
| 1311 | + { |
| 1312 | + if ((object)multicastMembershipAddresses == null) |
| 1313 | + { |
| 1314 | + IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address; |
| 1315 | + |
| 1316 | + if (sourceAddress.AddressFamily != serverAddress.AddressFamily) |
| 1317 | + throw new InvalidOperationException(string.Format("Source address \"{0}\" is not in the same IP format as server address \"{1}\"", sourceAddress, serverAddress)); |
| 1318 | + |
| 1319 | + if (localAddress.AddressFamily != serverAddress.AddressFamily) |
| 1320 | + throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress)); |
| 1321 | + |
| 1322 | + MemoryStream membershipAddresses = new MemoryStream(); |
| 1323 | + byte[] serverAddressBytes = serverAddress.GetAddressBytes(); |
| 1324 | + byte[] sourceAddressBytes = sourceAddress.GetAddressBytes(); |
| 1325 | + byte[] localAddressBytes = localAddress.GetAddressBytes(); |
| 1326 | + |
| 1327 | + membershipAddresses.Write(serverAddressBytes, 0, serverAddressBytes.Length); |
| 1328 | + membershipAddresses.Write(sourceAddressBytes, 0, sourceAddressBytes.Length); |
| 1329 | + membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length); |
| 1330 | + |
| 1331 | + multicastMembershipAddresses = membershipAddresses.ToArray(); |
| 1332 | + } |
| 1333 | + |
| 1334 | + // Execute multicast unsubscribe for specific source |
| 1335 | + m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropSourceMembership, multicastMembershipAddresses); |
| 1336 | + } |
| 1337 | + } |
| 1338 | + catch (SocketException ex) |
| 1339 | + { |
| 1340 | + if (ex.SocketErrorCode != SocketError.InvalidArgument) |
| 1341 | + throw; |
| 1325 | 1342 | } |
| 1326 | 1343 | } |
| 1327 | 1344 | |