PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Framework/Current Version/Source/Libraries/TVA.Communication/Transport.cs

#
C# | 454 lines | 127 code | 16 blank | 311 comment | 17 complexity | 9b9f10acb8022684590bcb28bd546bea MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0
  1. //*******************************************************************************************************
  2. // Transport.cs - Gbtc
  3. //
  4. // Tennessee Valley Authority, 2009
  5. // No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
  6. //
  7. // This software is made freely available under the TVA Open Source Agreement (see below).
  8. //
  9. // Code Modification History:
  10. // -----------------------------------------------------------------------------------------------------
  11. // 06/01/2006 - Pinal C. Patel
  12. // Original version of source created.
  13. // 09/29/2008 - J. Ritchie Carroll
  14. // Converted to C#.
  15. // 08/22/2009 - Pinal C. Patel
  16. // Modified CreateEndPoint() to try parsing IP address first before doing a DNS lookup.
  17. // 09/08/2009 - Pinal C. Patel
  18. // Modified CreateSocket() to create a socket for the AddressFamily of the endpoint.
  19. // Modified CreateEndPoint() to use IPv6 if supported when no IP address is specified.
  20. // 09/14/2009 - Stephen C. Wills
  21. // Added new header and license agreement.
  22. // 10/30/2009 - Pinal C. Patel
  23. // Added IsIPv6IP() and IsMulticastIP() methods.
  24. // Fixed bug in CreateSocket() that was breaking one-way communication support in UDP components.
  25. // 04/29/2010 - Pinal C. Patel
  26. // Added EndpointFormatRegex constant to be used for parsing endpoint strings.
  27. //
  28. //*******************************************************************************************************
  29. #region [ TVA Open Source Agreement ]
  30. /*
  31. THIS OPEN SOURCE AGREEMENT ("AGREEMENT") DEFINES THE RIGHTS OF USE,REPRODUCTION, DISTRIBUTION,
  32. MODIFICATION AND REDISTRIBUTION OF CERTAIN COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE
  33. TENNESSEE VALLEY AUTHORITY, A CORPORATE AGENCY AND INSTRUMENTALITY OF THE UNITED STATES GOVERNMENT
  34. ("GOVERNMENT AGENCY"). GOVERNMENT AGENCY IS AN INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT
  35. DISTRIBUTIONS OR REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, DISTRIBUTES,
  36. MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED HEREIN, OR ANY PART THEREOF, IS, BY THAT
  37. ACTION, ACCEPTING IN FULL THE RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT.
  38. Original Software Designation: openPDC
  39. Original Software Title: The TVA Open Source Phasor Data Concentrator
  40. User Registration Requested. Please Visit https://naspi.tva.com/Registration/
  41. Point of Contact for Original Software: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>
  42. 1. DEFINITIONS
  43. A. "Contributor" means Government Agency, as the developer of the Original Software, and any entity
  44. that makes a Modification.
  45. B. "Covered Patents" mean patent claims licensable by a Contributor that are necessarily infringed by
  46. the use or sale of its Modification alone or when combined with the Subject Software.
  47. C. "Display" means the showing of a copy of the Subject Software, either directly or by means of an
  48. image, or any other device.
  49. D. "Distribution" means conveyance or transfer of the Subject Software, regardless of means, to
  50. another.
  51. E. "Larger Work" means computer software that combines Subject Software, or portions thereof, with
  52. software separate from the Subject Software that is not governed by the terms of this Agreement.
  53. F. "Modification" means any alteration of, including addition to or deletion from, the substance or
  54. structure of either the Original Software or Subject Software, and includes derivative works, as that
  55. term is defined in the Copyright Statute, 17 USC § 101. However, the act of including Subject Software
  56. as part of a Larger Work does not in and of itself constitute a Modification.
  57. G. "Original Software" means the computer software first released under this Agreement by Government
  58. Agency entitled openPDC, including source code, object code and accompanying documentation, if any.
  59. H. "Recipient" means anyone who acquires the Subject Software under this Agreement, including all
  60. Contributors.
  61. I. "Redistribution" means Distribution of the Subject Software after a Modification has been made.
  62. J. "Reproduction" means the making of a counterpart, image or copy of the Subject Software.
  63. K. "Sale" means the exchange of the Subject Software for money or equivalent value.
  64. L. "Subject Software" means the Original Software, Modifications, or any respective parts thereof.
  65. M. "Use" means the application or employment of the Subject Software for any purpose.
  66. 2. GRANT OF RIGHTS
  67. A. Under Non-Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor,
  68. with respect to its own contribution to the Subject Software, hereby grants to each Recipient a
  69. non-exclusive, world-wide, royalty-free license to engage in the following activities pertaining to
  70. the Subject Software:
  71. 1. Use
  72. 2. Distribution
  73. 3. Reproduction
  74. 4. Modification
  75. 5. Redistribution
  76. 6. Display
  77. B. Under Patent Rights: Subject to the terms and conditions of this Agreement, each Contributor, with
  78. respect to its own contribution to the Subject Software, hereby grants to each Recipient under Covered
  79. Patents a non-exclusive, world-wide, royalty-free license to engage in the following activities
  80. pertaining to the Subject Software:
  81. 1. Use
  82. 2. Distribution
  83. 3. Reproduction
  84. 4. Sale
  85. 5. Offer for Sale
  86. C. The rights granted under Paragraph B. also apply to the combination of a Contributor's Modification
  87. and the Subject Software if, at the time the Modification is added by the Contributor, the addition of
  88. such Modification causes the combination to be covered by the Covered Patents. It does not apply to
  89. any other combinations that include a Modification.
  90. D. The rights granted in Paragraphs A. and B. allow the Recipient to sublicense those same rights.
  91. Such sublicense must be under the same terms and conditions of this Agreement.
  92. 3. OBLIGATIONS OF RECIPIENT
  93. A. Distribution or Redistribution of the Subject Software must be made under this Agreement except for
  94. additions covered under paragraph 3H.
  95. 1. Whenever a Recipient distributes or redistributes the Subject Software, a copy of this Agreement
  96. must be included with each copy of the Subject Software; and
  97. 2. If Recipient distributes or redistributes the Subject Software in any form other than source code,
  98. Recipient must also make the source code freely available, and must provide with each copy of the
  99. Subject Software information on how to obtain the source code in a reasonable manner on or through a
  100. medium customarily used for software exchange.
  101. B. Each Recipient must ensure that the following copyright notice appears prominently in the Subject
  102. Software:
  103. No copyright is claimed pursuant to 17 USC § 105. All Other Rights Reserved.
  104. C. Each Contributor must characterize its alteration of the Subject Software as a Modification and
  105. must identify itself as the originator of its Modification in a manner that reasonably allows
  106. subsequent Recipients to identify the originator of the Modification. In fulfillment of these
  107. requirements, Contributor must include a file (e.g., a change log file) that describes the alterations
  108. made and the date of the alterations, identifies Contributor as originator of the alterations, and
  109. consents to characterization of the alterations as a Modification, for example, by including a
  110. statement that the Modification is derived, directly or indirectly, from Original Software provided by
  111. Government Agency. Once consent is granted, it may not thereafter be revoked.
  112. D. A Contributor may add its own copyright notice to the Subject Software. Once a copyright notice has
  113. been added to the Subject Software, a Recipient may not remove it without the express permission of
  114. the Contributor who added the notice.
  115. E. A Recipient may not make any representation in the Subject Software or in any promotional,
  116. advertising or other material that may be construed as an endorsement by Government Agency or by any
  117. prior Recipient of any product or service provided by Recipient, or that may seek to obtain commercial
  118. advantage by the fact of Government Agency's or a prior Recipient's participation in this Agreement.
  119. F. In an effort to track usage and maintain accurate records of the Subject Software, each Recipient,
  120. upon receipt of the Subject Software, is requested to register with Government Agency by visiting the
  121. following website: https://naspi.tva.com/Registration/. Recipient's name and personal information
  122. shall be used for statistical purposes only. Once a Recipient makes a Modification available, it is
  123. requested that the Recipient inform Government Agency at the web site provided above how to access the
  124. Modification.
  125. G. Each Contributor represents that that its Modification does not violate any existing agreements,
  126. regulations, statutes or rules, and further that Contributor has sufficient rights to grant the rights
  127. conveyed by this Agreement.
  128. H. A Recipient may choose to offer, and to charge a fee for, warranty, support, indemnity and/or
  129. liability obligations to one or more other Recipients of the Subject Software. A Recipient may do so,
  130. however, only on its own behalf and not on behalf of Government Agency or any other Recipient. Such a
  131. Recipient must make it absolutely clear that any such warranty, support, indemnity and/or liability
  132. obligation is offered by that Recipient alone. Further, such Recipient agrees to indemnify Government
  133. Agency and every other Recipient for any liability incurred by them as a result of warranty, support,
  134. indemnity and/or liability offered by such Recipient.
  135. I. A Recipient may create a Larger Work by combining Subject Software with separate software not
  136. governed by the terms of this agreement and distribute the Larger Work as a single product. In such
  137. case, the Recipient must make sure Subject Software, or portions thereof, included in the Larger Work
  138. is subject to this Agreement.
  139. J. Notwithstanding any provisions contained herein, Recipient is hereby put on notice that export of
  140. any goods or technical data from the United States may require some form of export license from the
  141. U.S. Government. Failure to obtain necessary export licenses may result in criminal liability under
  142. U.S. laws. Government Agency neither represents that a license shall not be required nor that, if
  143. required, it shall be issued. Nothing granted herein provides any such export license.
  144. 4. DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION
  145. A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, EITHER
  146. EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT
  147. SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  148. PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR
  149. FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS
  150. AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR
  151. RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS
  152. RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND
  153. LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT
  154. "AS IS."
  155. B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST GOVERNMENT AGENCY, ITS
  156. AGENTS, EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE
  157. OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM
  158. SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S USE OF THE
  159. SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS GOVERNMENT AGENCY, ITS AGENTS,
  160. EMPLOYEES, CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY
  161. LAW. THE FOREGOING RELEASE AND INDEMNIFICATION SHALL APPLY EVEN IF THE LIABILITIES, DEMANDS, DAMAGES,
  162. EXPENSES OR LOSSES ARE CAUSED, OCCASIONED, OR CONTRIBUTED TO BY THE NEGLIGENCE, SOLE OR CONCURRENT, OF
  163. GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER SHALL BE THE
  164. IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
  165. 5. GENERAL TERMS
  166. A. Termination: This Agreement and the rights granted hereunder will terminate automatically if a
  167. Recipient fails to comply with these terms and conditions, and fails to cure such noncompliance within
  168. thirty (30) days of becoming aware of such noncompliance. Upon termination, a Recipient agrees to
  169. immediately cease use and distribution of the Subject Software. All sublicenses to the Subject
  170. Software properly granted by the breaching Recipient shall survive any such termination of this
  171. Agreement.
  172. B. Severability: If any provision of this Agreement is invalid or unenforceable under applicable law,
  173. it shall not affect the validity or enforceability of the remainder of the terms of this Agreement.
  174. C. Applicable Law: This Agreement shall be subject to United States federal law only for all purposes,
  175. including, but not limited to, determining the validity of this Agreement, the meaning of its
  176. provisions and the rights, obligations and remedies of the parties.
  177. D. Entire Understanding: This Agreement constitutes the entire understanding and agreement of the
  178. parties relating to release of the Subject Software and may not be superseded, modified or amended
  179. except by further written agreement duly executed by the parties.
  180. E. Binding Authority: By accepting and using the Subject Software under this Agreement, a Recipient
  181. affirms its authority to bind the Recipient to all terms and conditions of this Agreement and that
  182. Recipient hereby agrees to all terms and conditions herein.
  183. F. Point of Contact: Any Recipient contact with Government Agency is to be directed to the designated
  184. representative as follows: J. Ritchie Carroll <mailto:jrcarrol@tva.gov>.
  185. */
  186. #endregion
  187. using System;
  188. using System.Net;
  189. using System.Net.Sockets;
  190. namespace TVA.Communication
  191. {
  192. /// <summary>
  193. /// A helper class containing methods related to server-client communication.
  194. /// </summary>
  195. public static class Transport
  196. {
  197. /// <summary>
  198. /// Specifies the lowest valid port number for a <see cref="Socket"/>.
  199. /// </summary>
  200. public const int PortRangeLow = 0;
  201. /// <summary>
  202. /// Specifies the highest valid port number for a <see cref="Socket"/>.
  203. /// </summary>
  204. public const int PortRangeHigh = 65535;
  205. /// <summary>
  206. /// Regular expression used to validate the format for an endpoint.
  207. /// </summary>
  208. /// <remarks>
  209. /// <para>
  210. /// Matches the following valid input:<br/>
  211. /// - localhost:80<br/>
  212. /// - 127.0.0.1:80<br/>
  213. /// - [::1]:80<br/>
  214. /// - [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80
  215. /// </para>
  216. /// </remarks>
  217. public const string EndpointFormatRegex = @"(?<host>.+)\:(?<port>\d+$)";
  218. /// <summary>
  219. /// Creates an <see cref="IPEndPoint"/> for the specified host name and port number.
  220. /// </summary>
  221. /// <param name="hostNameOrAddress">The host name or IP address to resolve.</param>
  222. /// <param name="port">The port number to be associated with the address.</param>
  223. /// <returns>An <see cref="IPEndPoint"/> object.</returns>
  224. public static IPEndPoint CreateEndPoint(string hostNameOrAddress, int port)
  225. {
  226. if (string.IsNullOrEmpty(hostNameOrAddress))
  227. {
  228. // Use all of the local IPs.
  229. if (Socket.OSSupportsIPv6)
  230. return new IPEndPoint(IPAddress.IPv6Any, port);
  231. else
  232. return new IPEndPoint(IPAddress.Any, port);
  233. }
  234. else
  235. {
  236. IPAddress address;
  237. if (IPAddress.TryParse(hostNameOrAddress, out address))
  238. // Use the provided IP address.
  239. return new IPEndPoint(address, port);
  240. else
  241. // Exception will occur if DNS lookup fails.
  242. return new IPEndPoint(Dns.GetHostEntry(hostNameOrAddress).AddressList[0], port);
  243. }
  244. }
  245. /// <summary>
  246. /// Creates a <see cref="Socket"/> for the specified <paramref name="port"/> and <paramref name="protocol"/>.
  247. /// </summary>
  248. /// <param name="address">The local address where the <see cref="Socket"/> will be bound.</param>
  249. /// <param name="port">The port number at which the <see cref="Socket"/> will be bound.</param>
  250. /// <param name="protocol">One of the <see cref="ProtocolType"/> values.</param>
  251. /// <returns>An <see cref="Socket"/> object.</returns>
  252. public static Socket CreateSocket(string address, int port, ProtocolType protocol)
  253. {
  254. Socket socket = null;
  255. IPEndPoint endpoint = null;
  256. switch (protocol)
  257. {
  258. case ProtocolType.Tcp:
  259. endpoint = Transport.CreateEndPoint(address, port);
  260. socket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  261. socket.Bind(endpoint);
  262. break;
  263. case ProtocolType.Udp:
  264. // Allow negative port number to be specified for unbound socket.
  265. if (port >= 0)
  266. {
  267. endpoint = Transport.CreateEndPoint(address, port);
  268. socket = new Socket(endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
  269. socket.Bind(endpoint);
  270. }
  271. else
  272. {
  273. endpoint = Transport.CreateEndPoint(address, 0);
  274. socket = new Socket(endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
  275. }
  276. break;
  277. default:
  278. throw new NotSupportedException(string.Format("{0} is not supported", protocol));
  279. }
  280. return socket;
  281. }
  282. /// <summary>
  283. /// Determines if the specified <paramref name="ipAddress"/> is an IPv6 IP.
  284. /// </summary>
  285. /// <param name="ipAddress">IP address to check.</param>
  286. /// <returns>true if the <paramref name="ipAddress"/> is IPv6 IP; otherwise false.</returns>
  287. public static bool IsIPv6IP(IPAddress ipAddress)
  288. {
  289. if (ipAddress == null)
  290. throw new ArgumentNullException("ipAddress");
  291. if (ipAddress.ToString().Contains(":"))
  292. // IP is a IPV6 IP.
  293. return true;
  294. else
  295. // IP is a IPV4 IP.
  296. return false;
  297. }
  298. /// <summary>
  299. /// Determines if the specified <paramref name="ipAddress"/> is a multicast IP.
  300. /// </summary>
  301. /// <param name="ipAddress">IP address to check.</param>
  302. /// <returns>true if the <paramref name="ipAddress"/> is multicast IP; otherwise false.</returns>
  303. public static bool IsMulticastIP(IPAddress ipAddress)
  304. {
  305. if (ipAddress == null)
  306. throw new ArgumentNullException("ipAddress");
  307. if (Transport.IsIPv6IP(ipAddress))
  308. {
  309. // IP is a IPV6 IP.
  310. return ipAddress.IsIPv6Multicast;
  311. }
  312. else
  313. {
  314. // IP is a IPV4 IP.
  315. int firstOctet = int.Parse(ipAddress.ToString().Split('.')[0]);
  316. if (firstOctet >= 224 && firstOctet <= 247)
  317. // IP is a Class D multicast IP.
  318. return true;
  319. else
  320. // IP is not a multicast IP.
  321. return false;
  322. }
  323. }
  324. /// <summary>
  325. /// Determines whether the specified port is valid.
  326. /// </summary>
  327. /// <param name="port">The port number to be validated.</param>
  328. /// <returns>True if the port number is valid.</returns>
  329. public static bool IsPortNumberValid(string port)
  330. {
  331. int portNumber;
  332. if (int.TryParse(port, out portNumber))
  333. {
  334. // The specified port is a valid integer value.
  335. if (portNumber >= PortRangeLow && portNumber <= PortRangeHigh)
  336. // The port number is within the valid range.
  337. return true;
  338. else
  339. return false;
  340. }
  341. else
  342. {
  343. throw new ArgumentException("Port number is not a valid number");
  344. }
  345. }
  346. /// <summary>
  347. /// Determines if the specified UDP destination is listening for data.
  348. /// </summary>
  349. /// <param name="targetIPEndPoint">The <see cref="IPEndPoint"/> for the UDP destination to be checked.</param>
  350. /// <returns>true if the UDP destination is listening for data; otherwise false.</returns>
  351. public static bool IsDestinationReachable(IPEndPoint targetIPEndPoint)
  352. {
  353. try
  354. {
  355. // We'll check if the target endpoint exist by sending empty data to it and then wait for data from it.
  356. // If the endpoint doesn't exist then we'll receive a ConnectionReset socket exception.
  357. EndPoint targetEndPoint = (EndPoint)targetIPEndPoint;
  358. using (Socket targetChecker = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
  359. {
  360. targetChecker.ReceiveTimeout = 1;
  361. targetChecker.SendTo(new byte[] { }, targetEndPoint);
  362. targetChecker.ReceiveFrom(new byte[] { }, ref targetEndPoint);
  363. }
  364. }
  365. catch (SocketException ex)
  366. {
  367. switch (ex.SocketErrorCode)
  368. {
  369. case SocketError.ConnectionReset:
  370. // This means that the target endpoint is unreachable.
  371. return false;
  372. }
  373. }
  374. catch
  375. {
  376. // We'll ignore any other exceptions we might encounter.
  377. }
  378. return true;
  379. }
  380. }
  381. }