예제 #1
0
		void GetLocalHost (SimpleResolverEventArgs args)
		{
			//FIXME
			IPHostEntry entry = new IPHostEntry ();
			entry.HostName = "localhost";
			entry.AddressList = new IPAddress [] { IPAddress.Loopback };
			entry.Aliases = EmptyStrings;
			args.ResolverError = 0;
			args.HostEntry = entry;
			return;

/*
			List<IPEndPoint> eps = new List<IPEndPoint> ();
			foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces ()) {
				if (NetworkInterfaceType.Loopback == iface.NetworkInterfaceType)
					continue;

				foreach (IPAddress addr in iface.GetIPProperties ().DnsAddresses) {
					if (AddressFamily.InterNetworkV6 == addr.AddressFamily)
						continue;
					IPEndPoint ep = new IPEndPoint (addr, 53);
					if (eps.Contains (ep))
						continue;

					eps.Add (ep);
				}
			}
			endpoints = eps.ToArray ();
*/
		}
예제 #2
0
        static void Main(string [] args)
        {
            if (args.Length == 0)
            {
                return;
            }
            counter = args.Length;
            Stopwatch watch = new Stopwatch();

            watch.Start();
            SimpleResolver r = new SimpleResolver();

            foreach (string s in args)
            {
                SimpleResolverEventArgs e = new SimpleResolverEventArgs();
                e.Completed += OnCompleted;
                e.HostName   = s;
                if (!r.GetHostEntryAsync(e))
                {
                    OnCompleted(e, e);
                }
            }
            exit_event.WaitOne();
            watch.Stop();
            Console.WriteLine(watch.Elapsed);
        }
예제 #3
0
        void SendQuery(SimpleResolverEventArgs args, DnsQuery query, bool add_it)
        {
            // TODO: not sure about reusing IDs when add_it == false
            int count = 0;

            if (add_it)
            {
                do
                {
                    query.Header.ID = (ushort)new Random().Next(1, 65534);
                    if (count > 500)
                    {
                        throw new InvalidOperationException("Too many pending queries (or really bad luck)");
                    }
                } while (AddQuery(query, args) == false);
                args.QueryID = query.Header.ID;
            }
            else
            {
                query.Header.ID = args.QueryID;
            }
            if (args.Timer == null)
            {
                args.Timer = new Timer(timeout_cb, args, 5000, Timeout.Infinite);
            }
            else
            {
                args.Timer.Change(5000, Timeout.Infinite);
            }
            client.BeginSend(query.Packet, 0, query.Length, SocketFlags.None, null, null);
        }
예제 #4
0
파일: resolver.cs 프로젝트: netngn/Mono.Dns
		static void OnCompleted (object sender, SimpleResolverEventArgs e)
		{
			IPHostEntry entry = e.HostEntry;
			if (entry == null) {
				Console.WriteLine ("HostName: {0} Error: {1} {2}", e.HostName, e.ResolverError, e.ErrorMessage);
				if (Interlocked.Decrement (ref counter) == 0)
					exit_event.Set ();
				return;
			}

			if (e.ResolverError != 0)
				Console.WriteLine ("HostName: {0} {1}", e.HostName, e.ResolverError);
			else
				Console.WriteLine ("HostName: {0}", e.HostName);

			if (entry.HostName != null)
				Console.WriteLine ("\tHostName: {0}", entry.HostName);
			foreach (string alias in entry.Aliases) {
				Console.WriteLine ("\tAlias: {0}", alias);
			}
			foreach (IPAddress addr in entry.AddressList) {
				Console.WriteLine ("\tAddress: {0}", addr);
			}
			if (Interlocked.Decrement (ref counter) == 0)
				exit_event.Set ();
		}
예제 #5
0
        void GetLocalHost(SimpleResolverEventArgs args)
        {
            //FIXME
            IPHostEntry entry = new IPHostEntry();

            entry.HostName     = "localhost";
            entry.AddressList  = new IPAddress [] { IPAddress.Loopback };
            entry.Aliases      = EmptyStrings;
            args.ResolverError = 0;
            args.HostEntry     = entry;
            return;

/*
 *                      List<IPEndPoint> eps = new List<IPEndPoint> ();
 *                      foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces ()) {
 *                              if (NetworkInterfaceType.Loopback == iface.NetworkInterfaceType)
 *                                      continue;
 *
 *                              foreach (IPAddress addr in iface.GetIPProperties ().DnsAddresses) {
 *                                      if (AddressFamily.InterNetworkV6 == addr.AddressFamily)
 *                                              continue;
 *                                      IPEndPoint ep = new IPEndPoint (addr, 53);
 *                                      if (eps.Contains (ep))
 *                                              continue;
 *
 *                                      eps.Add (ep);
 *                              }
 *                      }
 *                      endpoints = eps.ToArray ();
 */
        }
예제 #6
0
        void OnTimeout(object obj)
        {
            SimpleResolverEventArgs args = (SimpleResolverEventArgs)obj;
            SimpleResolverEventArgs args2;

            lock (queries) {
                if (!queries.TryGetValue(args.QueryID, out args2))
                {
                    return;                     // Already processed.
                }
                if (args != args2)
                {
                    throw new Exception("Should not happen: args != args2");
                }
                args.Retries++;
                if (args.Retries > 1)
                {
                    // Error timeout
                    args.ResolverError = ResolverError.Timeout;
                    args.OnCompleted(this);
                }
                else
                {
                    SendAQuery(args, false);
                }
            }
        }
예제 #7
0
파일: Dns.cs 프로젝트: shana/mono
		static void OnCompleted (object sender, SimpleResolverEventArgs e)
		{
			DnsAsyncResult ares = (DnsAsyncResult) e.UserToken;
			IPHostEntry entry = e.HostEntry;
			if (entry == null || e.ResolverError != 0) {
				ares.SetCompleted (false, new Exception ("Error: " + e.ResolverError));
				return;
			}
			ares.SetCompleted (false, entry);
		}
예제 #8
0
 bool AddQuery(DnsQuery query, SimpleResolverEventArgs args)
 {
     lock (queries) {
         if (queries.ContainsKey(query.Header.ID))
         {
             return(false);
         }
         queries [query.Header.ID] = args;
     }
     return(true);
 }
예제 #9
0
        // For names -> type A Query
        // For IP addresses -> PTR + A -> will at least return itself
        //	Careful: for IP addresses with PTR, the hostname might yield different IP addresses!
        public bool GetHostEntryAsync(SimpleResolverEventArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            if (args.HostName == null)
            {
                throw new ArgumentNullException("args.HostName is null");
            }

            if (args.HostName.Length > 255)
            {
                throw new ArgumentException("args.HostName is too long");
            }

            args.Reset(ResolverAsyncOperation.GetHostEntry);
            string host = args.HostName;

            if (host == "")
            {
                GetLocalHost(args);
                return(false);
            }

            IPAddress addr;

            if (IPAddress.TryParse(host, out addr))
            {
                IPHostEntry entry = new IPHostEntry();
                entry.HostName    = host;
                entry.Aliases     = EmptyStrings;
                entry.AddressList = new IPAddress [1] {
                    addr
                };
                args.HostEntry  = entry;
                args.PTRAddress = addr;
                SendPTRQuery(args, true);
                return(true);
            }

            // 3. For IP addresses:
            //	3.1 Parsing IP succeeds
            //	3.2 Reverse lookup of the IP fills in HostName -> fails? HostName = IP
            //	3.3 The hostname resulting from this is used to query DNS again to get the IP addresses
            //
            // Exclude IPv6 addresses if not supported by the system
            // .Aliases is always empty
            // Length > 255
            SendAQuery(args, true);
            return(true);
        }
예제 #10
0
        static void GetLocalHost(SimpleResolverEventArgs args)
        {
            //FIXME
            IPHostEntry entry = new IPHostEntry();

            entry.HostName     = "localhost";
            entry.Aliases      = EmptyStrings;
            args.ResolverError = 0;
            args.HostEntry     = entry;

#if NET_4_0
            bool ipv4 = Socket.OSSupportsIPv4;
#else
            bool ipv4 = Socket.SupportsIPv4;
#endif
            bool             ipv6 = Socket.OSSupportsIPv6;
            List <IPAddress> ips  = new List <IPAddress> ();
            if (ipv4)
            {
                ips.Add(IPAddress.Loopback);
            }
            if (ipv6)
            {
                ips.Add(IPAddress.IPv6Loopback);
            }

            foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (NetworkInterfaceType.Loopback == iface.NetworkInterfaceType)
                {
                    continue;
                }

                foreach (UnicastIPAddressInformation info in iface.GetIPProperties().UnicastAddresses)
                {
                    IPAddress     addr   = info.Address;
                    AddressFamily family = addr.AddressFamily;
                    if ((ipv6 && AddressFamily.InterNetworkV6 == family) ||
                        (ipv4 && AddressFamily.InterNetwork == family))
                    {
                        ips.Add(addr);
                    }
                }
            }
            entry.AddressList = ips.ToArray();
        }
예제 #11
0
파일: resolver.cs 프로젝트: netngn/Mono.Dns
		static void Main (string [] args)
		{
			if (args.Length == 0)
				return;
			counter = args.Length;
			Stopwatch watch = new Stopwatch ();
			watch.Start ();
			SimpleResolver r = new SimpleResolver ();
			foreach (string s in args) {
				SimpleResolverEventArgs e = new SimpleResolverEventArgs ();
				e.Completed += OnCompleted;
				e.HostName = s;
				if (!r.GetHostEntryAsync (e))
					OnCompleted (e, e);
			}
			exit_event.WaitOne ();
			watch.Stop ();
			Console.WriteLine (watch.Elapsed);
		}
예제 #12
0
        // Type A query
        // Might fill in Aliases
        // -IPAddress -> return the same IPAddress
        // -"" -> Local host ip addresses (filter out IPv6 if needed)
        public bool GetHostAddressesAsync(SimpleResolverEventArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            if (args.HostName == null)
            {
                throw new ArgumentNullException("args.HostName is null");
            }

            if (args.HostName.Length > 255)
            {
                throw new ArgumentException("args.HostName is too long");
            }

            args.Reset(ResolverAsyncOperation.GetHostAddresses);
            string host = args.HostName;

            if (host == "")
            {
                GetLocalHost(args);
                return(false);
            }
            IPAddress addr;

            if (IPAddress.TryParse(host, out addr))
            {
                IPHostEntry entry = new IPHostEntry();
                entry.HostName    = host;
                entry.Aliases     = EmptyStrings;
                entry.AddressList = new IPAddress [1] {
                    addr
                };
                args.HostEntry = entry;
                return(false);
            }

            SendAQuery(args, true);
            return(true);
        }
예제 #13
0
        static void OnCompleted(object sender, SimpleResolverEventArgs e)
        {
            IPHostEntry entry = e.HostEntry;

            if (entry == null)
            {
                Console.WriteLine("HostName: {0} Error: {1} {2}", e.HostName, e.ResolverError, e.ErrorMessage);
                if (Interlocked.Decrement(ref counter) == 0)
                {
                    exit_event.Set();
                }
                return;
            }

            if (e.ResolverError != 0)
            {
                Console.WriteLine("HostName: {0} {1}", e.HostName, e.ResolverError);
            }
            else
            {
                Console.WriteLine("HostName: {0}", e.HostName);
            }

            if (entry.HostName != null)
            {
                Console.WriteLine("\tHostName: {0}", entry.HostName);
            }
            foreach (string alias in entry.Aliases)
            {
                Console.WriteLine("\tAlias: {0}", alias);
            }
            foreach (IPAddress addr in entry.AddressList)
            {
                Console.WriteLine("\tAddress: {0}", addr);
            }
            if (Interlocked.Decrement(ref counter) == 0)
            {
                exit_event.Set();
            }
        }
예제 #14
0
		static void GetLocalHost (SimpleResolverEventArgs args)
		{
			//FIXME
			IPHostEntry entry = new IPHostEntry ();
			entry.HostName = "localhost";
			entry.Aliases = EmptyStrings;
			args.ResolverError = 0;
			args.HostEntry = entry;

#if NET_4_0
			bool ipv4 = Socket.OSSupportsIPv4;
#else
			bool ipv4 = Socket.SupportsIPv4;
#endif
			bool ipv6 = Socket.OSSupportsIPv6;
			List<IPAddress> ips = new List<IPAddress> ();
			if (ipv4)
				ips.Add (IPAddress.Loopback);
			if (ipv6)
				ips.Add (IPAddress.IPv6Loopback);

			foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces ()) {
				if (NetworkInterfaceType.Loopback == iface.NetworkInterfaceType)
					continue;

				foreach (UnicastIPAddressInformation info in iface.GetIPProperties ().UnicastAddresses) {
					IPAddress addr = info.Address;
					AddressFamily family = addr.AddressFamily;
					if ((ipv6 && AddressFamily.InterNetworkV6 == family) ||
						(ipv4 && AddressFamily.InterNetwork == family)) {
						ips.Add (addr);
					}
				}
			}
			entry.AddressList = ips.ToArray ();
		}
예제 #15
0
		void SendQuery (SimpleResolverEventArgs args, DnsQuery query, bool add_it)
		{
			// TODO: not sure about reusing IDs when add_it == false
			int count = 0;
			if (add_it) {
				do {
					query.Header.ID = (ushort)new Random().Next(1, 65534);
					if (count > 500)
						throw new InvalidOperationException ("Too many pending queries (or really bad luck)");
				} while (AddQuery (query, args) == false);
				args.QueryID = query.Header.ID;
			} else {
				query.Header.ID = args.QueryID;
			}
			if (args.Timer == null)
				args.Timer = new Timer (timeout_cb, args, 5000, Timeout.Infinite);
			else
				args.Timer.Change (5000, Timeout.Infinite);
			client.BeginSend (query.Packet, 0, query.Length, SocketFlags.None, null, null);
		}
예제 #16
0
		void SendPTRQuery (SimpleResolverEventArgs args, bool add_it)
		{
			DnsQuery query = GetQuery (GetPTRName (args.PTRAddress), DnsQType.PTR, DnsQClass.IN);
			SendQuery (args, query, add_it);
		}
예제 #17
0
		void SendAQuery (SimpleResolverEventArgs args, string host, bool add_it)
		{
			DnsQuery query = GetQuery (host, DnsQType.A, DnsQClass.IN);
			SendQuery (args, query, add_it);
		}
예제 #18
0
		void SendAQuery (SimpleResolverEventArgs args, bool add_it)
		{
			SendAQuery (args, args.HostName, add_it);
		}
예제 #19
0
		bool AddQuery (DnsQuery query, SimpleResolverEventArgs args)
		{
			lock (queries) {
				if (queries.ContainsKey (query.Header.ID))
					return false;
				queries [query.Header.ID] = args;
			}
			return true;
		}
예제 #20
0
		// For names -> type A Query
		// For IP addresses -> PTR + A -> will at least return itself
		//	Careful: for IP addresses with PTR, the hostname might yield different IP addresses!
		public bool GetHostEntryAsync (SimpleResolverEventArgs args)
		{
			if (args == null)
				throw new ArgumentNullException ("args");

			if (args.HostName == null)
				throw new ArgumentNullException ("args.HostName is null");

			if (args.HostName.Length > 255)
				throw new ArgumentException ("args.HostName is too long");

			args.Reset (ResolverAsyncOperation.GetHostEntry);
			string host = args.HostName;
			if (host == "") {
				GetLocalHost (args);
				return false;
			}

			IPAddress addr;
			if (IPAddress.TryParse (host, out addr)) {
				IPHostEntry entry = new IPHostEntry ();
				entry.HostName = host;
				entry.Aliases = EmptyStrings;
				entry.AddressList = new IPAddress [1] { addr };
				args.HostEntry = entry;
				args.PTRAddress = addr;
				SendPTRQuery (args, true);
				return true;
			}

			// 3. For IP addresses:
			//	3.1 Parsing IP succeeds
			//	3.2 Reverse lookup of the IP fills in HostName -> fails? HostName = IP
			//	3.3 The hostname resulting from this is used to query DNS again to get the IP addresses
			//
			// Exclude IPv6 addresses if not supported by the system
			// .Aliases is always empty
			// Length > 255
			SendAQuery (args, true);
			return true;
		}
예제 #21
0
        void ProcessResponse(SimpleResolverEventArgs args, DnsResponse response, EndPoint server_ep)
        {
            DnsRCode status = response.Header.RCode;

            if (status != 0)
            {
                if (args.PTRAddress != null)
                {
                    // PTR query failed -> no error, we have the IP
                    return;
                }
                args.ResolverError = (ResolverError)status;
                return;
            }

            // TODO: verify IP of the server is in our list and the same one that got the query
            IPEndPoint ep = (IPEndPoint)server_ep;

            if (ep.Port != 53)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "Port";
                return;
            }

            DnsHeader header = response.Header;

            if (!header.IsQuery)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "IsQuery";
                return;
            }

            // TODO: handle Truncation. Retry with bigger buffer?

            if (header.QuestionCount > 1)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QuestionCount";
                return;
            }
            ReadOnlyCollection <DnsQuestion> q = response.GetQuestions();

            if (q.Count != 1)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QuestionCount 2";
                return;
            }
            DnsQuestion question = q [0];

            /* The answer might have dot at the end, etc...
             * if (String.Compare (question.Name, args.HostName) != 0) {
             *      args.ResolverError = ResolverError.ResponseHeaderError;
             *      args.ErrorMessage = "HostName - " + question.Name + " != " + args.HostName;
             *      return;
             * }
             */

            DnsQType t = question.Type;

            if (t != DnsQType.A && t != DnsQType.AAAA && t != DnsQType.PTR)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QType " + question.Type;
                return;
            }

            if (question.Class != DnsQClass.IN)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QClass " + question.Class;
                return;
            }

            ReadOnlyCollection <DnsResourceRecord> records = response.GetAnswers();

            if (records.Count == 0)
            {
                if (args.PTRAddress != null)
                {
                    // PTR query failed -> no error
                    return;
                }
                args.ResolverError = ResolverError.NameError;                 // is this ok?
                args.ErrorMessage  = "NoAnswers";
                return;
            }

            List <string>    aliases   = null;
            List <IPAddress> addresses = null;

            foreach (DnsResourceRecord r in records)
            {
                if (r.Class != DnsClass.IN)
                {
                    continue;
                }
                if (r.Type == DnsType.A || r.Type == DnsType.AAAA)
                {
                    if (addresses == null)
                    {
                        addresses = new List <IPAddress> ();
                    }
                    addresses.Add(((DnsResourceRecordIPAddress)r).Address);
                }
                else if (r.Type == DnsType.CNAME)
                {
                    if (aliases == null)
                    {
                        aliases = new List <string> ();
                    }
                    aliases.Add(((DnsResourceRecordCName)r).CName);
                }
                else if (r.Type == DnsType.PTR)
                {
                    args.HostEntry.HostName    = ((DnsResourceRecordPTR)r).DName;
                    args.HostEntry.Aliases     = aliases == null ? EmptyStrings : aliases.ToArray();
                    args.HostEntry.AddressList = EmptyAddresses;
                    return;
                }
            }

            IPHostEntry entry = args.HostEntry ?? new IPHostEntry();

            if (entry.HostName == null && aliases != null && aliases.Count > 0)
            {
                entry.HostName = aliases [0];
                aliases.RemoveAt(0);
            }
            entry.Aliases     = aliases == null ? EmptyStrings : aliases.ToArray();
            entry.AddressList = addresses == null ? EmptyAddresses : addresses.ToArray();
            args.HostEntry    = entry;
            if ((question.Type == DnsQType.A || question.Type == DnsQType.AAAA) && entry.AddressList == EmptyAddresses)
            {
                args.ResolverError = ResolverError.NameError;
                args.ErrorMessage  = "No addresses in response";
            }
            else if (question.Type == DnsQType.PTR && entry.HostName == null)
            {
                args.ResolverError = ResolverError.NameError;
                args.ErrorMessage  = "No PTR in response";
            }
        }
예제 #22
0
파일: Dns.cs 프로젝트: shana/mono
		static IAsyncResult BeginAsyncCallAddresses (string host, AsyncCallback callback, object state)
		{
			SimpleResolverEventArgs e = new SimpleResolverEventArgs ();
			e.Completed += OnCompleted;
			e.HostName = host;
			DnsAsyncResult ares = new DnsAsyncResult (callback, state);
			e.UserToken = ares;
			if (resolver.GetHostAddressesAsync (e) == false)
				ares.SetCompleted (true, e.HostEntry); // Completed synchronously
			return ares;
		}
예제 #23
0
 void SendAQuery(SimpleResolverEventArgs args, bool add_it)
 {
     SendAQuery(args, args.HostName, add_it);
 }
예제 #24
0
        void SendAQuery(SimpleResolverEventArgs args, string host, bool add_it)
        {
            DnsQuery query = GetQuery(host, DnsQType.A, DnsQClass.IN);

            SendQuery(args, query, add_it);
        }
예제 #25
0
        void SendPTRQuery(SimpleResolverEventArgs args, bool add_it)
        {
            DnsQuery query = GetQuery(GetPTRName(args.PTRAddress), DnsQType.PTR, DnsQClass.IN);

            SendQuery(args, query, add_it);
        }
예제 #26
0
		void ProcessResponse (SimpleResolverEventArgs args, DnsResponse response, EndPoint server_ep)
		{
			DnsRCode status = response.Header.RCode;
			if (status != 0) {
				if (args.PTRAddress != null) {
					// PTR query failed -> no error, we have the IP
					return;
				}
				args.ResolverError = (ResolverError) status;
				return;
			}

			// TODO: verify IP of the server is in our list and the same one that got the query
			IPEndPoint ep = (IPEndPoint) server_ep;
			if (ep.Port != 53) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "Port";
				return;
			}

			DnsHeader header = response.Header;
			if (!header.IsQuery) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "IsQuery";
				return;
			}

			// TODO: handle Truncation. Retry with bigger buffer?

			if (header.QuestionCount > 1) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "QuestionCount";
				return;
			}
			ReadOnlyCollection<DnsQuestion> q = response.GetQuestions ();
			if (q.Count != 1) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "QuestionCount 2";
				return;
			}
			DnsQuestion question = q [0];
			/* The answer might have dot at the end, etc...
			if (String.Compare (question.Name, args.HostName) != 0) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "HostName - " + question.Name + " != " + args.HostName;
				return;
			}
			*/

			DnsQType t = question.Type;
			if (t != DnsQType.A && t != DnsQType.AAAA && t != DnsQType.PTR) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "QType " + question.Type;
				return;
			}

			if (question.Class != DnsQClass.IN) {
				args.ResolverError = ResolverError.ResponseHeaderError;
				args.ErrorMessage = "QClass " + question.Class;
				return;
			}

			ReadOnlyCollection<DnsResourceRecord> records = response.GetAnswers ();
			if (records.Count == 0) {
				if (args.PTRAddress != null) {
					// PTR query failed -> no error
					return;
				}
				args.ResolverError = ResolverError.NameError; // is this ok?
				args.ErrorMessage = "NoAnswers";
				return;
			}

			List<string> aliases = null;
			List<IPAddress> addresses = null;
			foreach (DnsResourceRecord r in records) {
				if (r.Class != DnsClass.IN)
					continue;
				if (r.Type == DnsType.A || r.Type == DnsType.AAAA) {
					if (addresses == null)
						addresses = new List<IPAddress> ();
					addresses.Add (((DnsResourceRecordIPAddress) r).Address);
				} else if (r.Type == DnsType.CNAME) {
					if (aliases == null)
						aliases = new List<string> ();
					aliases.Add (((DnsResourceRecordCName) r).CName);
				} else if (r.Type == DnsType.PTR) {
					args.HostEntry.HostName = ((DnsResourceRecordPTR) r).DName;
					args.HostEntry.Aliases = aliases == null ? EmptyStrings : aliases.ToArray ();
					args.HostEntry.AddressList = EmptyAddresses;
					return;
				}
			}

			IPHostEntry entry = args.HostEntry ?? new IPHostEntry ();
			if (entry.HostName == null && aliases != null && aliases.Count > 0) {
				entry.HostName = aliases [0];
				aliases.RemoveAt (0);
			}
			entry.Aliases = aliases == null ? EmptyStrings : aliases.ToArray ();
			entry.AddressList = addresses == null ? EmptyAddresses : addresses.ToArray ();
			args.HostEntry = entry;
			if ((question.Type == DnsQType.A || question.Type == DnsQType.AAAA) && entry.AddressList == EmptyAddresses) {
				args.ResolverError = ResolverError.NameError;
				args.ErrorMessage = "No addresses in response";
			} else if (question.Type == DnsQType.PTR && entry.HostName == null) {
				args.ResolverError = ResolverError.NameError;
				args.ErrorMessage = "No PTR in response";
			}

		}
예제 #27
0
		// Type A query
		// Might fill in Aliases
		// -IPAddress -> return the same IPAddress
		// -"" -> Local host ip addresses (filter out IPv6 if needed)
		public bool GetHostAddressesAsync (SimpleResolverEventArgs args)
		{
			if (args == null)
				throw new ArgumentNullException ("args");

			if (args.HostName == null)
				throw new ArgumentNullException ("args.HostName is null");

			if (args.HostName.Length > 255)
				throw new ArgumentException ("args.HostName is too long");

			args.Reset (ResolverAsyncOperation.GetHostAddresses);
			string host = args.HostName;
			if (host == "") {
				GetLocalHost (args);
				return false;
			}
			IPAddress addr;
			if (IPAddress.TryParse (host, out addr)) {
				IPHostEntry entry = new IPHostEntry ();
				entry.HostName = host;
				entry.Aliases = EmptyStrings;
				entry.AddressList = new IPAddress [1] { addr };
				args.HostEntry = entry;
				return false;
			}

			SendAQuery (args, true);
			return true;
		}
예제 #28
0
        void OnReceive(IAsyncResult ares)
        {
            if (disposed)
            {
                return;
            }

            int      nread     = 0;
            EndPoint remote_ep = client.RemoteEndPoint;

            try {
                nread = client.EndReceive(ares);
            } catch (Exception e) {
                Console.Error.WriteLine(e);
            }

            BeginReceive();

            byte [] buffer = (byte [])ares.AsyncState;
            if (nread > 12)
            {
                DnsResponse             response = new DnsResponse(buffer, nread);
                int                     id       = response.Header.ID;
                SimpleResolverEventArgs args     = null;
                lock (queries) {
                    if (queries.TryGetValue(id, out args))
                    {
                        queries.Remove(id);
                    }
                }

                if (args != null)
                {
                    Timer t = args.Timer;
                    if (t != null)
                    {
                        t.Change(Timeout.Infinite, Timeout.Infinite);
                    }

                    try {
                        ProcessResponse(args, response, remote_ep);
                    } catch (Exception e) {
                        args.ResolverError = (ResolverError)(-1);
                        args.ErrorMessage  = e.Message;
                    }

                    IPHostEntry entry = args.HostEntry;
                    if (args.ResolverError != 0 && args.PTRAddress != null && entry != null && entry.HostName != null)
                    {
                        args.PTRAddress = null;
                        SendAQuery(args, entry.HostName, true);
                        args.Timer.Change(5000, Timeout.Infinite);
                    }
                    else
                    {
                        args.OnCompleted(this);
                    }
                }
            }
            FreeBuffer(buffer);
        }