History

GSF.Communication: Added try-catch to AddMulticastMembership and DropMulticastMembership in UdpClient.cs to avoid errors when calling SetSocketOption. GSF.PhasorProtocols: In MultiProtocolFrameParser, added user-unhandled exception handlers for the command channel and the data channel.

StephenCWills committed 13 years ago

Commit 635b5301 parent 84014222 files · +104 −48Browse files

Unified · Split

2 files
  1. Source/Libraries/GSF.Communication/UdpClient.cs +65 −48
  2. Source/Libraries/GSF.PhasorProtocols/MultiProtocolFrameParser.cs +39 −0
Source/Libraries/GSF.Communication/UdpClient.cs+65−48
@@ -1250,55 +1250,19 @@ namespace GSF.Communication · 1249 unmodified lines
1250 1250
1251 private void AddMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, out byte[] multicastMembershipAddresses)1251 private void AddMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, out byte[] multicastMembershipAddresses)
1252 {1252 {
1253 if (!Transport.IsMulticastIP(serverAddress))1253 multicastMembershipAddresses = null;
1254 throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP.");
1255 1254
1256 if ((object)sourceAddress == null)1255 try
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
1263 {1256 {
1264 IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;1257 if (!Transport.IsMulticastIP(serverAddress))
1265 1258 throw new InvalidOperationException("Cannot add multicast membership if server address is not a multicast IP.");
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 }
1288 1259
1289 private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses)1260 if ((object)sourceAddress == null)
1290 {1261 {
1291 if (!Transport.IsMulticastIP(serverAddress))1262 // Execute multicast subscribe for any source
1292 throw new InvalidOperationException("Cannot drop multicast membership if server address is not a multicast IP.");1263 m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(serverAddress));
1293 1264 }
1294 if ((object)sourceAddress == null && (object)multicastMembershipAddresses == null)1265 else
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)
1302 {1266 {
1303 IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;1267 IPAddress localAddress = ((IPEndPoint)m_udpClient.Provider.LocalEndPoint).Address;
1304 1268
@@ -1309,6 +1273,7 @@ namespace GSF.Communication · 4 unmodified lines
1309 throw new InvalidOperationException(string.Format("Local address \"{0}\" is not in the same IP format as server address \"{1}\"", localAddress, serverAddress));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 MemoryStream membershipAddresses = new MemoryStream();1275 MemoryStream membershipAddresses = new MemoryStream();
1276
1312 byte[] serverAddressBytes = serverAddress.GetAddressBytes();1277 byte[] serverAddressBytes = serverAddress.GetAddressBytes();
1313 byte[] sourceAddressBytes = sourceAddress.GetAddressBytes();1278 byte[] sourceAddressBytes = sourceAddress.GetAddressBytes();
1314 byte[] localAddressBytes = localAddress.GetAddressBytes();1279 byte[] localAddressBytes = localAddress.GetAddressBytes();
@@ -1318,10 +1283,62 @@ namespace GSF.Communication · 3 unmodified lines
1318 membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length);1283 membershipAddresses.Write(localAddressBytes, 0, localAddressBytes.Length);
1319 1284
1320 multicastMembershipAddresses = membershipAddresses.ToArray();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 source1298 private void DropMulticastMembership(IPAddress serverAddress, IPAddress sourceAddress, byte[] multicastMembershipAddresses)
1324 m_udpClient.Provider.SetSocketOption(serverAddress.AddressFamily == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.DropSourceMembership, 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
Source/Libraries/GSF.PhasorProtocols/MultiProtocolFrameParser.cs+39−0
@@ -937,6 +937,7 @@ namespace GSF.PhasorProtocols · 936 unmodified lines
937 sharedClient.ReceiveDataException += SharedClient_ReceiveDataException;937 sharedClient.ReceiveDataException += SharedClient_ReceiveDataException;
938 sharedClient.ReceiveDataFrom += SharedClient_ReceiveDataFrom;938 sharedClient.ReceiveDataFrom += SharedClient_ReceiveDataFrom;
939 sharedClient.SendDataException += SharedClient_SendDataException;939 sharedClient.SendDataException += SharedClient_SendDataException;
940 sharedClient.UnhandledUserException += SharedClient_UnhandledUserException;
940 941
941 if (!sharing)942 if (!sharing)
942 {943 {
@@ -1139,6 +1140,14 @@ namespace GSF.PhasorProtocols · 196 unmodified lines
1139 SendDataException(this, e);1140 SendDataException(this, e);
1140 }1141 }
1141 1142
1143 // Shared client unhandled user exception handler.
1144 // Forwards event to users attached to this client.
1145 private void SharedClient_UnhandledUserException(object sender, EventArgs<Exception> e)
1146 {
1147 if ((object)UnhandledUserException != null)
1148 UnhandledUserException(this, e);
1149 }
1150
1142 #endregion1151 #endregion
1143 1152
1144 #region [ Static ]1153 #region [ Static ]
@@ -2527,6 +2536,7 @@ namespace GSF.PhasorProtocols · 1382 unmodified lines
2527 m_commandChannel.ReceiveData += m_commandChannel_ReceiveData;2536 m_commandChannel.ReceiveData += m_commandChannel_ReceiveData;
2528 m_commandChannel.ReceiveDataException += m_commandChannel_ReceiveDataException;2537 m_commandChannel.ReceiveDataException += m_commandChannel_ReceiveDataException;
2529 m_commandChannel.SendDataException += m_commandChannel_SendDataException;2538 m_commandChannel.SendDataException += m_commandChannel_SendDataException;
2539 m_commandChannel.UnhandledUserException += m_commandChannel_UnhandledUserException;
2530 2540
2531 // Attempt connection to device over command channel2541 // Attempt connection to device over command channel
2532 m_commandChannel.ReceiveBufferSize = m_bufferSize;2542 m_commandChannel.ReceiveBufferSize = m_bufferSize;
@@ -2595,6 +2605,7 @@ namespace GSF.PhasorProtocols · 62 unmodified lines
2595 m_dataChannel.ReceiveData += m_dataChannel_ReceiveData;2605 m_dataChannel.ReceiveData += m_dataChannel_ReceiveData;
2596 m_dataChannel.ReceiveDataException += m_dataChannel_ReceiveDataException;2606 m_dataChannel.ReceiveDataException += m_dataChannel_ReceiveDataException;
2597 m_dataChannel.SendDataException += m_dataChannel_SendDataException;2607 m_dataChannel.SendDataException += m_dataChannel_SendDataException;
2608 m_dataChannel.UnhandledUserException += m_dataChannel_UnhandledUserException;
2598 2609
2599 // Attempt connection to device2610 // Attempt connection to device
2600 m_dataChannel.ReceiveBufferSize = m_bufferSize;2611 m_dataChannel.ReceiveBufferSize = m_bufferSize;
@@ -2612,6 +2623,7 @@ namespace GSF.PhasorProtocols · 11 unmodified lines
2612 m_serverBasedDataChannel.ReceiveClientData += m_serverBasedDataChannel_ReceiveClientData;2623 m_serverBasedDataChannel.ReceiveClientData += m_serverBasedDataChannel_ReceiveClientData;
2613 m_serverBasedDataChannel.ReceiveClientDataException += m_serverBasedDataChannel_ReceiveClientDataException;2624 m_serverBasedDataChannel.ReceiveClientDataException += m_serverBasedDataChannel_ReceiveClientDataException;
2614 m_serverBasedDataChannel.SendClientDataException += m_serverBasedDataChannel_SendClientDataException;2625 m_serverBasedDataChannel.SendClientDataException += m_serverBasedDataChannel_SendClientDataException;
2626 m_serverBasedDataChannel.UnhandledUserException += m_serverBasedDataChannel_UnhandledUserException;
2615 2627
2616 // Listen for device connection2628 // Listen for device connection
2617 m_serverBasedDataChannel.ReceiveBufferSize = m_bufferSize;2629 m_serverBasedDataChannel.ReceiveBufferSize = m_bufferSize;
@@ -2702,6 +2714,7 @@ namespace GSF.PhasorProtocols · 84 unmodified lines
2702 m_dataChannel.ReceiveData -= m_dataChannel_ReceiveData;2714 m_dataChannel.ReceiveData -= m_dataChannel_ReceiveData;
2703 m_dataChannel.ReceiveDataException -= m_dataChannel_ReceiveDataException;2715 m_dataChannel.ReceiveDataException -= m_dataChannel_ReceiveDataException;
2704 m_dataChannel.SendDataException -= m_dataChannel_SendDataException;2716 m_dataChannel.SendDataException -= m_dataChannel_SendDataException;
2717 m_dataChannel.UnhandledUserException -= m_dataChannel_UnhandledUserException;
2705 m_dataChannel.Dispose();2718 m_dataChannel.Dispose();
2706 }2719 }
2707 }2720 }
@@ -2726,6 +2739,7 @@ namespace GSF.PhasorProtocols · 18 unmodified lines
2726 m_serverBasedDataChannel.ReceiveClientData -= m_serverBasedDataChannel_ReceiveClientData;2739 m_serverBasedDataChannel.ReceiveClientData -= m_serverBasedDataChannel_ReceiveClientData;
2727 m_serverBasedDataChannel.ReceiveClientDataException -= m_serverBasedDataChannel_ReceiveClientDataException;2740 m_serverBasedDataChannel.ReceiveClientDataException -= m_serverBasedDataChannel_ReceiveClientDataException;
2728 m_serverBasedDataChannel.SendClientDataException -= m_serverBasedDataChannel_SendClientDataException;2741 m_serverBasedDataChannel.SendClientDataException -= m_serverBasedDataChannel_SendClientDataException;
2742 m_serverBasedDataChannel.UnhandledUserException -= m_serverBasedDataChannel_UnhandledUserException;
2729 m_serverBasedDataChannel.Dispose();2743 m_serverBasedDataChannel.Dispose();
2730 }2744 }
2731 }2745 }
@@ -2750,6 +2764,7 @@ namespace GSF.PhasorProtocols · 18 unmodified lines
2750 m_commandChannel.ReceiveData -= m_commandChannel_ReceiveData;2764 m_commandChannel.ReceiveData -= m_commandChannel_ReceiveData;
2751 m_commandChannel.ReceiveDataException -= m_commandChannel_ReceiveDataException;2765 m_commandChannel.ReceiveDataException -= m_commandChannel_ReceiveDataException;
2752 m_commandChannel.SendDataException -= m_commandChannel_SendDataException;2766 m_commandChannel.SendDataException -= m_commandChannel_SendDataException;
2767 m_commandChannel.UnhandledUserException -= m_commandChannel_UnhandledUserException;
2753 m_commandChannel.Dispose();2768 m_commandChannel.Dispose();
2754 }2769 }
2755 }2770 }
@@ -3415,6 +3430,14 @@ namespace GSF.PhasorProtocols · 659 unmodified lines
3415 OnParsingException(e.Argument, "Data channel receive exception: {0}", ex.Message);3430 OnParsingException(e.Argument, "Data channel receive exception: {0}", ex.Message);
3416 }3431 }
3417 3432
3433 private void m_dataChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3434 {
3435 Exception ex = e.Argument;
3436
3437 if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3438 OnParsingException(e.Argument, "Data channel user unhandled exception: {0}", ex.Message);
3439 }
3440
3418 #endregion3441 #endregion
3419 3442
3420 #region [ Server Based Data Channel Event Handlers ]3443 #region [ Server Based Data Channel Event Handlers ]
@@ -3477,6 +3500,14 @@ namespace GSF.PhasorProtocols · 56 unmodified lines
3477 OnParsingException(e.Argument2, "Server based data channel receive exception: {0}", ex.Message);3500 OnParsingException(e.Argument2, "Server based data channel receive exception: {0}", ex.Message);
3478 }3501 }
3479 3502
3503 private void m_serverBasedDataChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3504 {
3505 Exception ex = e.Argument;
3506
3507 if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3508 OnParsingException(e.Argument, "Server based data channel user unhandled exception: {0}", ex.Message);
3509 }
3510
3480 #endregion3511 #endregion
3481 3512
3482 #region [ Command Channel Event Handlers ]3513 #region [ Command Channel Event Handlers ]
@@ -3553,6 +3584,14 @@ namespace GSF.PhasorProtocols · 70 unmodified lines
3553 OnParsingException(e.Argument, "Command channel send exception: {0}", ex.Message);3584 OnParsingException(e.Argument, "Command channel send exception: {0}", ex.Message);
3554 }3585 }
3555 3586
3587 private void m_commandChannel_UnhandledUserException(object sender, EventArgs<Exception> e)
3588 {
3589 Exception ex = e.Argument;
3590
3591 if (!(ex is NullReferenceException) && !(ex is ObjectDisposedException))
3592 OnParsingException(e.Argument, "Command channel user unhandled exception: {0}", ex.Message);
3593 }
3594
3556 #endregion3595 #endregion
3557 3596
3558 #region [ Frame Parser Event Handlers ]3597 #region [ Frame Parser Event Handlers ]

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t