2005-06-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System / System.Net / Dns.cs
1 // System.Net.Dns.cs
2 //
3 // Author: Mads Pultz (mpultz@diku.dk)
4 // Author: Lawrence Pit (loz@cable.a2000.nl)
5 //
6 // (C) Mads Pultz, 2001
7
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Net.Sockets;
31 using System.Text;
32 using System.Collections;
33 using System.Threading;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.Remoting.Messaging;
36
37 namespace System.Net {
38         public sealed class Dns {
39
40                 private Dns () {}
41                 static Dns ()
42                 {
43                         System.Net.Sockets.Socket.CheckProtocolSupport();
44                 }
45
46                 private delegate IPHostEntry GetHostByNameCallback (string hostName);
47                 private delegate IPHostEntry ResolveCallback (string hostName);
48
49                 public static IAsyncResult BeginGetHostByName (string hostName,
50                         AsyncCallback requestCallback, object stateObject)
51                 {
52                         if (hostName == null)
53                                 throw new ArgumentNullException ("hostName");
54
55                         GetHostByNameCallback c = new GetHostByNameCallback (GetHostByName);
56                         return c.BeginInvoke (hostName, requestCallback, stateObject);
57                 }
58
59                 public static IAsyncResult BeginResolve (string hostName,
60                         AsyncCallback requestCallback, object stateObject)
61                 {
62                         if (hostName == null)
63                                 throw new ArgumentNullException ("hostName");
64
65                         ResolveCallback c = new ResolveCallback (Resolve);
66                         return c.BeginInvoke (hostName, requestCallback, stateObject);
67                 }
68
69                 public static IPHostEntry EndGetHostByName (IAsyncResult asyncResult) 
70                 {
71                         if (asyncResult == null)
72                                 throw new ArgumentNullException ("asyncResult");
73
74                         AsyncResult async = (AsyncResult) asyncResult;
75                         GetHostByNameCallback cb = (GetHostByNameCallback) async.AsyncDelegate;
76                         return cb.EndInvoke(asyncResult);
77                 }
78
79                 public static IPHostEntry EndResolve (IAsyncResult asyncResult) 
80                 {
81                         if (asyncResult == null)
82                                 throw new ArgumentNullException ("asyncResult");
83                         AsyncResult async = (AsyncResult) asyncResult;
84                         ResolveCallback cb = (ResolveCallback) async.AsyncDelegate;
85                         return cb.EndInvoke(asyncResult);
86                 }
87
88                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
89                 private extern static bool GetHostByName_internal(string host, out string h_name, out string[] h_aliases, out string[] h_addr_list);
90
91                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
92                 private extern static bool GetHostByAddr_internal(string addr, out string h_name, out string[] h_aliases, out string[] h_addr_list);
93
94                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
95                 private extern static bool GetHostName_internal(out string h_name);
96                 
97                 private static IPHostEntry hostent_to_IPHostEntry(string h_name, string[] h_aliases, string[] h_addrlist) 
98                 {
99                         IPHostEntry he = new IPHostEntry();
100                         ArrayList addrlist = new ArrayList();
101
102                         he.HostName = h_name;
103                         he.Aliases = h_aliases;
104                         for(int i=0; i<h_addrlist.Length; i++) {
105                                 IPAddress newAddress = IPAddress.Parse(h_addrlist[i]);
106
107                                 if( (Socket.SupportsIPv6 && newAddress.AddressFamily == AddressFamily.InterNetworkV6) ||
108                                         (Socket.SupportsIPv4 && newAddress.AddressFamily == AddressFamily.InterNetwork) )
109                                         addrlist.Add(newAddress);
110                         }
111
112                         if(addrlist.Count == 0)
113                                 throw new SocketException(11001);
114
115                         he.AddressList = addrlist.ToArray(typeof(IPAddress)) as IPAddress[];
116                         return he;
117                 }
118
119                 public static IPHostEntry GetHostByAddress(IPAddress address)
120                 {
121                         if (address == null)
122                                 throw new ArgumentNullException ("address");
123
124                         return GetHostByAddressFromString (address.ToString (), false);
125                 }
126
127                 public static IPHostEntry GetHostByAddress(string address)
128                 {
129                         if (address == null)
130                                 throw new ArgumentNullException ("address");
131
132                         return GetHostByAddressFromString (address, true);
133                 }
134
135                 static IPHostEntry GetHostByAddressFromString (string address, bool parse)
136                 {
137                         // Undocumented MS behavior: when called with IF_ANY,
138                         // this should return the local host
139                         if (address.Equals ("0.0.0.0")) {
140                                 address = "127.0.0.1";
141                                 parse = false;
142                         }
143
144                         // Must check the IP format, might send an exception if invalid string.
145                         if (parse)
146                                 IPAddress.Parse(address);
147
148                         string h_name;
149                         string[] h_aliases, h_addrlist;
150
151                         bool ret = GetHostByAddr_internal(address, out h_name, out h_aliases, out h_addrlist);
152                         if (!ret)
153                                 throw new SocketException(11001);
154
155                         return (hostent_to_IPHostEntry (h_name, h_aliases, h_addrlist));
156                 }
157
158                 public static IPHostEntry GetHostByName(string hostName) 
159                 {
160                         if (hostName == null)
161                                 throw new ArgumentNullException();
162
163                         string h_name;
164                         string[] h_aliases, h_addrlist;
165
166                         bool ret = GetHostByName_internal(hostName, out h_name,
167                                 out h_aliases,
168                                 out h_addrlist);
169                         if (ret == false)
170                                 throw new SocketException(11001);
171
172                         return(hostent_to_IPHostEntry(h_name, h_aliases,
173                                 h_addrlist));
174                 }
175
176                 public static string GetHostName() 
177                 {
178                         string hostName;
179
180                         bool ret = GetHostName_internal(out hostName);
181
182                         if (ret == false)
183                                 throw new SocketException(11001);
184
185                         return hostName;
186                 }
187
188                 public static IPHostEntry Resolve(string hostName) 
189                 {
190                         if (hostName == null)
191                                 throw new ArgumentNullException ("hostName");
192
193                         IPHostEntry ret = null;
194
195                         try {
196                                 ret =  GetHostByAddress(hostName);
197                         }
198                         catch{}
199
200                         if(ret == null)
201                                 ret =  GetHostByName(hostName);
202
203                         return ret;
204                 }
205         }
206 }
207