Bruce Wayne 5 年之前
父節點
當前提交
93295485c2
共有 2 個文件被更改,包括 362 次插入399 次删除
  1. 362 361
      STUN/Client/StunClient.cs
  2. 0 38
      STUN/Message/StunMessageType.cs

+ 362 - 361
STUN/Client/StunClient.cs

@@ -1,91 +1,92 @@
-using System;
+using STUN.Message;
+using STUN.Message.Enums;
+using STUN.Utils;
+using System;
 using System.IO;
 using System.IO;
 using System.Net;
 using System.Net;
 using System.Net.Sockets;
 using System.Net.Sockets;
-using STUN.Message;
-using STUN.Utils;
 
 
 namespace STUN.Client
 namespace STUN.Client
 {
 {
-	/// <summary>
-	/// This class implements STUN client. Defined in RFC 3489.
-	/// </summary>
-	/// <example>
-	/// <code>
-	/// // Create new socket for STUN client.
-	/// Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
-	/// socket.Bind(new IPEndPoint(IPAddress.Any,0));
-	/// 
-	/// // Query STUN server
-	/// STUN_Result result = STUN_Client.Query("stun.ekiga.net",3478,socket);
-	/// if(result.NetType != STUN_NetType.UdpBlocked){
-	///     // UDP blocked or !!!! bad STUN server
-	/// }
-	/// else{
-	///     IPEndPoint publicEP = result.PublicEndPoint;
-	///     // Do your stuff
-	/// }
-	/// </code>
-	/// </example>
-	public static class StunClient
-	{
-		#region static method Query
-
-		/// <summary>
-		/// Gets NAT info from STUN server.
-		/// </summary>
-		/// <param name="host">STUN server name or IP.</param>
-		/// <param name="port">STUN server port. Default port is 3478.</param>
-		/// <param name="localEP">Local IP end point.</param>
-		/// <returns>Returns UDP network info.</returns>
-		/// <exception cref="Exception">Is raised when <b>host</b> or <b>localEP</b> is null reference.</exception>
-		/// <exception cref="ArgumentNullException">Throws exception if unexpected error happens.</exception>
-		public static StunResult Query(string host, int port, IPEndPoint localEP)
-		{
-			if (host == null)
-			{
-				throw new ArgumentNullException(nameof(host));
-			}
-			if (localEP == null)
-			{
-				throw new ArgumentNullException(nameof(localEP));
-			}
-
-			using var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
-			s.Bind(localEP);
-			return Query(host, port, s);
-		}
-
-		/// <summary>
-		/// Gets NAT info from STUN server.
-		/// </summary>
-		/// <param name="host">STUN server name or IP.</param>
-		/// <param name="port">STUN server port. Default port is 3478.</param>
-		/// <param name="socket">UDP socket to use.</param>
-		/// <returns>Returns UDP network info.</returns>
-		/// <exception cref="Exception">Throws exception if unexpected error happens.</exception>
-		public static StunResult Query(string host, int port, Socket socket)
-		{
-			if (host == null)
-			{
-				throw new ArgumentNullException(nameof(host));
-			}
-			if (socket == null)
-			{
-				throw new ArgumentNullException(nameof(socket));
-			}
-			if (port < 1)
-			{
-				throw new ArgumentException(@"Port value must be >= 1 !");
-			}
-			if (socket.ProtocolType != ProtocolType.Udp)
-			{
-				throw new ArgumentException(@"Socket must be UDP socket !");
-			}
-
-			var remoteEndPoint = new IPEndPoint(Dns.GetHostAddresses(host)[0], port);
-
-			/*
+    /// <summary>
+    /// This class implements STUN client. Defined in RFC 3489.
+    /// </summary>
+    /// <example>
+    /// <code>
+    /// // Create new socket for STUN client.
+    /// Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
+    /// socket.Bind(new IPEndPoint(IPAddress.Any,0));
+    /// 
+    /// // Query STUN server
+    /// STUN_Result result = STUN_Client.Query("stun.ekiga.net",3478,socket);
+    /// if(result.NetType != STUN_NetType.UdpBlocked){
+    ///     // UDP blocked or !!!! bad STUN server
+    /// }
+    /// else{
+    ///     IPEndPoint publicEP = result.PublicEndPoint;
+    ///     // Do your stuff
+    /// }
+    /// </code>
+    /// </example>
+    public static class StunClient
+    {
+        #region static method Query
+
+        /// <summary>
+        /// Gets NAT info from STUN server.
+        /// </summary>
+        /// <param name="host">STUN server name or IP.</param>
+        /// <param name="port">STUN server port. Default port is 3478.</param>
+        /// <param name="localEP">Local IP end point.</param>
+        /// <returns>Returns UDP network info.</returns>
+        /// <exception cref="Exception">Is raised when <b>host</b> or <b>localEP</b> is null reference.</exception>
+        /// <exception cref="ArgumentNullException">Throws exception if unexpected error happens.</exception>
+        public static StunResult Query(string host, int port, IPEndPoint localEP)
+        {
+            if (host == null)
+            {
+                throw new ArgumentNullException(nameof(host));
+            }
+            if (localEP == null)
+            {
+                throw new ArgumentNullException(nameof(localEP));
+            }
+
+            using var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+            s.Bind(localEP);
+            return Query(host, port, s);
+        }
+
+        /// <summary>
+        /// Gets NAT info from STUN server.
+        /// </summary>
+        /// <param name="host">STUN server name or IP.</param>
+        /// <param name="port">STUN server port. Default port is 3478.</param>
+        /// <param name="socket">UDP socket to use.</param>
+        /// <returns>Returns UDP network info.</returns>
+        /// <exception cref="Exception">Throws exception if unexpected error happens.</exception>
+        public static StunResult Query(string host, int port, Socket socket)
+        {
+            if (host == null)
+            {
+                throw new ArgumentNullException(nameof(host));
+            }
+            if (socket == null)
+            {
+                throw new ArgumentNullException(nameof(socket));
+            }
+            if (port < 1)
+            {
+                throw new ArgumentException(@"Port value must be >= 1 !");
+            }
+            if (socket.ProtocolType != ProtocolType.Udp)
+            {
+                throw new ArgumentException(@"Socket must be UDP socket !");
+            }
+
+            var remoteEndPoint = new IPEndPoint(Dns.GetHostAddresses(host)[0], port);
+
+            /*
                 In test I, the client sends a STUN Binding Request to a server, without any flags set in the
                 In test I, the client sends a STUN Binding Request to a server, without any flags set in the
                 CHANGE-REQUEST attribute, and without the RESPONSE-ADDRESS attribute. This causes the server 
                 CHANGE-REQUEST attribute, and without the RESPONSE-ADDRESS attribute. This causes the server 
                 to send the response back to the address and port that the request came from.
                 to send the response back to the address and port that the request came from.
@@ -140,287 +141,287 @@ namespace STUN.Client
 
 
             */
             */
 
 
-			try
-			{
-				// Test I
-				var test1 = new StunMessage { Type = StunMessageType.BindingRequest };
-				var test1Response = DoTransaction(test1, socket, remoteEndPoint, 1600);
-
-				// UDP blocked.
-				if (test1Response == null)
-				{
-					return new StunResult(NatType.UdpBlocked, null);
-				}
-				else
-				{
-					// Test II
-					var test2 = new StunMessage
-					{
-						Type = StunMessageType.BindingRequest,
-						ChangeRequest = new StunChangeRequest(true, true)
-					};
-
-					// No NAT.
-					if (socket.LocalEndPoint.Equals(test1Response.MappedAddress))
-					{
-						var test2Response = DoTransaction(test2, socket, remoteEndPoint, 1600);
-						// Open Internet.
-						if (test2Response != null)
-						{
-							return new StunResult(NatType.OpenInternet, test1Response.MappedAddress);
-						}
-						// Symmetric UDP firewall.
-						else
-						{
-							return new StunResult(NatType.SymmetricUdpFirewall, test1Response.MappedAddress);
-						}
-					}
-					// NAT
-					else
-					{
-						var test2Response = DoTransaction(test2, socket, remoteEndPoint, 1600);
-
-						// Full cone NAT.
-						if (test2Response != null)
-						{
-							return new StunResult(NatType.FullCone, test1Response.MappedAddress);
-						}
-						else
-						{
-							/*
+            try
+            {
+                // Test I
+                var test1 = new StunMessage { Type = StunMessageType.BindingRequest };
+                var test1Response = DoTransaction(test1, socket, remoteEndPoint, 1600);
+
+                // UDP blocked.
+                if (test1Response == null)
+                {
+                    return new StunResult(NatType.UdpBlocked, null);
+                }
+                else
+                {
+                    // Test II
+                    var test2 = new StunMessage
+                    {
+                        Type = StunMessageType.BindingRequest,
+                        ChangeRequest = new StunChangeRequest(true, true)
+                    };
+
+                    // No NAT.
+                    if (socket.LocalEndPoint.Equals(test1Response.MappedAddress))
+                    {
+                        var test2Response = DoTransaction(test2, socket, remoteEndPoint, 1600);
+                        // Open Internet.
+                        if (test2Response != null)
+                        {
+                            return new StunResult(NatType.OpenInternet, test1Response.MappedAddress);
+                        }
+                        // Symmetric UDP firewall.
+                        else
+                        {
+                            return new StunResult(NatType.SymmetricUdpFirewall, test1Response.MappedAddress);
+                        }
+                    }
+                    // NAT
+                    else
+                    {
+                        var test2Response = DoTransaction(test2, socket, remoteEndPoint, 1600);
+
+                        // Full cone NAT.
+                        if (test2Response != null)
+                        {
+                            return new StunResult(NatType.FullCone, test1Response.MappedAddress);
+                        }
+                        else
+                        {
+                            /*
                                 If no response is received, it performs test I again, but this time, does so to 
                                 If no response is received, it performs test I again, but this time, does so to 
                                 the address and port from the CHANGED-ADDRESS attribute from the response to test I.
                                 the address and port from the CHANGED-ADDRESS attribute from the response to test I.
                             */
                             */
 
 
-							// Test I(II)
-							var test12 = new StunMessage { Type = StunMessageType.BindingRequest };
-
-							var test12Response = DoTransaction(test12, socket, test1Response.ChangedAddress, 1600);
-							if (test12Response == null)
-							{
-								throw new Exception(@"STUN Test I(II) didn't get response !");
-							}
-							else
-							{
-								// Symmetric NAT
-								if (!test12Response.MappedAddress.Equals(test1Response.MappedAddress))
-								{
-									return new StunResult(NatType.Symmetric, test1Response.MappedAddress);
-								}
-								else
-								{
-									// Test III
-									var test3 = new StunMessage
-									{
-										Type = StunMessageType.BindingRequest,
-										ChangeRequest = new StunChangeRequest(false, true)
-									};
-
-									var test3Response = DoTransaction(test3, socket, test1Response.ChangedAddress, 1600);
-									// Restricted
-									if (test3Response != null)
-									{
-										return new StunResult(NatType.RestrictedCone, test1Response.MappedAddress);
-									}
-									// Port restricted
-									else
-									{
-										return new StunResult(NatType.PortRestrictedCone, test1Response.MappedAddress);
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-			finally
-			{
-				// Junk all late responses.
-				var startTime = DateTime.Now;
-				while (startTime.AddMilliseconds(200) > DateTime.Now)
-				{
-					// We got response.
-					if (socket.Poll(1, SelectMode.SelectRead))
-					{
-						var receiveBuffer = new byte[512];
-						socket.Receive(receiveBuffer);
-					}
-				}
-			}
-		}
-
-		#endregion
-
-		#region method GetPublicIP
-
-		/// <summary>
-		/// Resolves local IP to public IP using STUN.
-		/// </summary>
-		/// <param name="stunServer">STUN server.</param>
-		/// <param name="port">STUN server port. Default port is 3478.</param>
-		/// <param name="localIP">Local IP address.</param>
-		/// <returns>Returns public IP address.</returns>
-		/// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>localIP</b> is null reference.</exception>
-		/// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
-		/// <exception cref="IOException">Is raised when no connection to STUN server.</exception>
-		public static IPAddress GetPublicIP(string stunServer, int port, IPAddress localIP)
-		{
-			if (stunServer == null)
-			{
-				throw new ArgumentNullException(nameof(stunServer));
-			}
-			if (stunServer == string.Empty)
-			{
-				throw new ArgumentException(@"Argument 'stunServer' value must be specified.");
-			}
-			if (port < 1)
-			{
-				throw new ArgumentException(@"Invalid argument 'port' value.");
-			}
-			if (localIP == null)
-			{
-				throw new ArgumentNullException(nameof(localIP));
-			}
-
-			if (!NetUtils.IsPrivateIP(localIP))
-			{
-				return localIP;
-			}
-
-			var result = Query(stunServer, port, NetUtils.CreateSocket(new IPEndPoint(localIP, 0), ProtocolType.Udp));
-			if (result.PublicEndPoint != null)
-			{
-				return result.PublicEndPoint.Address;
-			}
-
-			throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
-		}
-
-		#endregion
-
-		#region method GetPublicEP
-
-		/// <summary>
-		/// Resolves socket local end point to public end point.
-		/// </summary>
-		/// <param name="stunServer">STUN server.</param>
-		/// <param name="port">STUN server port. Default port is 3478.</param>
-		/// <param name="socket">UDP socket to use.</param>
-		/// <returns>Returns public IP end point.</returns>
-		/// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>socket</b> is null reference.</exception>
-		/// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
-		/// <exception cref="IOException">Is raised when no connection to STUN server.</exception>
-		public static IPEndPoint GetPublicEP(string stunServer, int port, Socket socket)
-		{
-			if (stunServer == null)
-			{
-				throw new ArgumentNullException(nameof(stunServer));
-			}
-			if (stunServer == string.Empty)
-			{
-				throw new ArgumentException(@"Argument 'stunServer' value must be specified.");
-			}
-			if (port < 1)
-			{
-				throw new ArgumentException(@"Invalid argument 'port' value.");
-			}
-			if (socket == null)
-			{
-				throw new ArgumentNullException(nameof(socket));
-			}
-			if (socket.ProtocolType != ProtocolType.Udp)
-			{
-				throw new ArgumentException(@"Socket must be UDP socket !");
-			}
-
-			var remoteEndPoint = new IPEndPoint(Dns.GetHostAddresses(stunServer)[0], port);
-
-			try
-			{
-				// Test I
-				var test1 = new StunMessage { Type = StunMessageType.BindingRequest };
-				var test1response = DoTransaction(test1, socket, remoteEndPoint, 1000);
-
-				// UDP blocked.
-				if (test1response == null)
-				{
-					throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
-				}
-
-				return test1response.SourceAddress;
-			}
-			catch
-			{
-				throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
-			}
-			finally
-			{
-				// Junk all late responses.
-				var startTime = DateTime.Now;
-				while (startTime.AddMilliseconds(200) > DateTime.Now)
-				{
-					// We got response.
-					if (socket.Poll(1, SelectMode.SelectRead))
-					{
-						var receiveBuffer = new byte[512];
-						socket.Receive(receiveBuffer);
-					}
-				}
-			}
-		}
-
-		#endregion
-
-		#region method DoTransaction
-
-		/// <summary>
-		/// Does STUN transaction. Returns transaction response or null if transaction failed.
-		/// </summary>
-		/// <param name="request">STUN message.</param>
-		/// <param name="socket">Socket to use for send/receive.</param>
-		/// <param name="remoteEndPoint">Remote end point.</param>
-		/// <param name="timeout">Timeout in milliseconds.</param>
-		/// <returns>Returns transaction response or null if transaction failed.</returns>
-		private static StunMessage DoTransaction(StunMessage request, Socket socket, IPEndPoint remoteEndPoint, int timeout)
-		{
-			var requestBytes = request.ToByteData();
-			var startTime = DateTime.Now;
-			// Retransmit with 500 ms.
-			while (startTime.AddMilliseconds(timeout) > DateTime.Now)
-			{
-				try
-				{
-					socket.SendTo(requestBytes, remoteEndPoint);
-
-					// We got response.
-					if (socket.Poll(500 * 1000, SelectMode.SelectRead))
-					{
-						var receiveBuffer = new byte[512];
-						socket.Receive(receiveBuffer);
-
-						// Parse message
-						var response = new StunMessage();
-						response.Parse(receiveBuffer);
-
-						// Check that transaction ID matches or not response what we want.
-						if (NetUtils.CompareArray(request.TransactionId, response.TransactionId))
-						{
-							return response;
-						}
-					}
-				}
-				catch
-				{
-					// ignored
-				}
-			}
-
-			return null;
-		}
-
-		#endregion
-
-		// TODO: Update to RFC 5389
-
-	}
+                            // Test I(II)
+                            var test12 = new StunMessage { Type = StunMessageType.BindingRequest };
+
+                            var test12Response = DoTransaction(test12, socket, test1Response.ChangedAddress, 1600);
+                            if (test12Response == null)
+                            {
+                                throw new Exception(@"STUN Test I(II) didn't get response !");
+                            }
+                            else
+                            {
+                                // Symmetric NAT
+                                if (!test12Response.MappedAddress.Equals(test1Response.MappedAddress))
+                                {
+                                    return new StunResult(NatType.Symmetric, test1Response.MappedAddress);
+                                }
+                                else
+                                {
+                                    // Test III
+                                    var test3 = new StunMessage
+                                    {
+                                        Type = StunMessageType.BindingRequest,
+                                        ChangeRequest = new StunChangeRequest(false, true)
+                                    };
+
+                                    var test3Response = DoTransaction(test3, socket, test1Response.ChangedAddress, 1600);
+                                    // Restricted
+                                    if (test3Response != null)
+                                    {
+                                        return new StunResult(NatType.RestrictedCone, test1Response.MappedAddress);
+                                    }
+                                    // Port restricted
+                                    else
+                                    {
+                                        return new StunResult(NatType.PortRestrictedCone, test1Response.MappedAddress);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                // Junk all late responses.
+                var startTime = DateTime.Now;
+                while (startTime.AddMilliseconds(200) > DateTime.Now)
+                {
+                    // We got response.
+                    if (socket.Poll(1, SelectMode.SelectRead))
+                    {
+                        var receiveBuffer = new byte[512];
+                        socket.Receive(receiveBuffer);
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        #region method GetPublicIP
+
+        /// <summary>
+        /// Resolves local IP to public IP using STUN.
+        /// </summary>
+        /// <param name="stunServer">STUN server.</param>
+        /// <param name="port">STUN server port. Default port is 3478.</param>
+        /// <param name="localIP">Local IP address.</param>
+        /// <returns>Returns public IP address.</returns>
+        /// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>localIP</b> is null reference.</exception>
+        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
+        /// <exception cref="IOException">Is raised when no connection to STUN server.</exception>
+        public static IPAddress GetPublicIP(string stunServer, int port, IPAddress localIP)
+        {
+            if (stunServer == null)
+            {
+                throw new ArgumentNullException(nameof(stunServer));
+            }
+            if (stunServer == string.Empty)
+            {
+                throw new ArgumentException(@"Argument 'stunServer' value must be specified.");
+            }
+            if (port < 1)
+            {
+                throw new ArgumentException(@"Invalid argument 'port' value.");
+            }
+            if (localIP == null)
+            {
+                throw new ArgumentNullException(nameof(localIP));
+            }
+
+            if (!NetUtils.IsPrivateIP(localIP))
+            {
+                return localIP;
+            }
+
+            var result = Query(stunServer, port, NetUtils.CreateSocket(new IPEndPoint(localIP, 0), ProtocolType.Udp));
+            if (result.PublicEndPoint != null)
+            {
+                return result.PublicEndPoint.Address;
+            }
+
+            throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
+        }
+
+        #endregion
+
+        #region method GetPublicEP
+
+        /// <summary>
+        /// Resolves socket local end point to public end point.
+        /// </summary>
+        /// <param name="stunServer">STUN server.</param>
+        /// <param name="port">STUN server port. Default port is 3478.</param>
+        /// <param name="socket">UDP socket to use.</param>
+        /// <returns>Returns public IP end point.</returns>
+        /// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>socket</b> is null reference.</exception>
+        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
+        /// <exception cref="IOException">Is raised when no connection to STUN server.</exception>
+        public static IPEndPoint GetPublicEP(string stunServer, int port, Socket socket)
+        {
+            if (stunServer == null)
+            {
+                throw new ArgumentNullException(nameof(stunServer));
+            }
+            if (stunServer == string.Empty)
+            {
+                throw new ArgumentException(@"Argument 'stunServer' value must be specified.");
+            }
+            if (port < 1)
+            {
+                throw new ArgumentException(@"Invalid argument 'port' value.");
+            }
+            if (socket == null)
+            {
+                throw new ArgumentNullException(nameof(socket));
+            }
+            if (socket.ProtocolType != ProtocolType.Udp)
+            {
+                throw new ArgumentException(@"Socket must be UDP socket !");
+            }
+
+            var remoteEndPoint = new IPEndPoint(Dns.GetHostAddresses(stunServer)[0], port);
+
+            try
+            {
+                // Test I
+                var test1 = new StunMessage { Type = StunMessageType.BindingRequest };
+                var test1response = DoTransaction(test1, socket, remoteEndPoint, 1000);
+
+                // UDP blocked.
+                if (test1response == null)
+                {
+                    throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
+                }
+
+                return test1response.SourceAddress;
+            }
+            catch
+            {
+                throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN.");
+            }
+            finally
+            {
+                // Junk all late responses.
+                var startTime = DateTime.Now;
+                while (startTime.AddMilliseconds(200) > DateTime.Now)
+                {
+                    // We got response.
+                    if (socket.Poll(1, SelectMode.SelectRead))
+                    {
+                        var receiveBuffer = new byte[512];
+                        socket.Receive(receiveBuffer);
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        #region method DoTransaction
+
+        /// <summary>
+        /// Does STUN transaction. Returns transaction response or null if transaction failed.
+        /// </summary>
+        /// <param name="request">STUN message.</param>
+        /// <param name="socket">Socket to use for send/receive.</param>
+        /// <param name="remoteEndPoint">Remote end point.</param>
+        /// <param name="timeout">Timeout in milliseconds.</param>
+        /// <returns>Returns transaction response or null if transaction failed.</returns>
+        private static StunMessage DoTransaction(StunMessage request, Socket socket, IPEndPoint remoteEndPoint, int timeout)
+        {
+            var requestBytes = request.ToByteData();
+            var startTime = DateTime.Now;
+            // Retransmit with 500 ms.
+            while (startTime.AddMilliseconds(timeout) > DateTime.Now)
+            {
+                try
+                {
+                    socket.SendTo(requestBytes, remoteEndPoint);
+
+                    // We got response.
+                    if (socket.Poll(500 * 1000, SelectMode.SelectRead))
+                    {
+                        var receiveBuffer = new byte[512];
+                        socket.Receive(receiveBuffer);
+
+                        // Parse message
+                        var response = new StunMessage();
+                        response.Parse(receiveBuffer);
+
+                        // Check that transaction ID matches or not response what we want.
+                        if (NetUtils.CompareArray(request.TransactionId, response.TransactionId))
+                        {
+                            return response;
+                        }
+                    }
+                }
+                catch
+                {
+                    // ignored
+                }
+            }
+
+            return null;
+        }
+
+        #endregion
+
+        // TODO: Update to RFC 5389
+
+    }
 }
 }

+ 0 - 38
STUN/Message/StunMessageType.cs

@@ -1,38 +0,0 @@
-namespace STUN.Message
-{
-	/// <summary>
-	/// This enum specifies STUN message type.
-	/// </summary>
-	public enum StunMessageType
-	{
-		/// <summary>
-		/// STUN message is binding request.
-		/// </summary>
-		BindingRequest = 0x0001,
-
-		/// <summary>
-		/// STUN message is binding request response.
-		/// </summary>
-		BindingResponse = 0x0101,
-
-		/// <summary>
-		/// STUN message is binding request error response.
-		/// </summary>
-		BindingErrorResponse = 0x0111,
-
-		/// <summary>
-		/// STUN message is "shared secret" request.
-		/// </summary>
-		SharedSecretRequest = 0x0002,
-
-		/// <summary>
-		/// STUN message is "shared secret" request response.
-		/// </summary>
-		SharedSecretResponse = 0x0102,
-
-		/// <summary>
-		/// STUN message is "shared secret" request error response.
-		/// </summary>
-		SharedSecretErrorResponse = 0x0112
-	}
-}