* NetworkAccess.cs: Only mark as flags enum on 2.0.
[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 #if NET_2_0
39         public static class Dns {
40 #else
41         public sealed class Dns {
42
43                 private Dns () {}
44 #endif
45
46                 static Dns ()
47                 {
48                         System.Net.Sockets.Socket.CheckProtocolSupport();
49                 }
50
51                 private delegate IPHostEntry GetHostByNameCallback (string hostName);
52                 private delegate IPHostEntry ResolveCallback (string hostName);
53 #if NET_2_0
54                 private delegate IPHostEntry GetHostEntryNameCallback (string hostName);
55                 private delegate IPHostEntry GetHostEntryIPCallback (IPAddress hostAddress);
56                 private delegate IPAddress [] GetHostAddressesCallback (string hostName);
57 #endif
58
59 #if NET_2_0
60                 [Obsolete ("Use BeginGetHostEntry instead")]
61 #endif
62                 public static IAsyncResult BeginGetHostByName (string hostName,
63                         AsyncCallback requestCallback, object stateObject)
64                 {
65                         if (hostName == null)
66                                 throw new ArgumentNullException ("hostName");
67
68                         GetHostByNameCallback c = new GetHostByNameCallback (GetHostByName);
69                         return c.BeginInvoke (hostName, requestCallback, stateObject);
70                 }
71
72 #if NET_2_0
73                 [Obsolete ("Use BeginGetHostEntry instead")]
74 #endif
75                 public static IAsyncResult BeginResolve (string hostName,
76                         AsyncCallback requestCallback, object stateObject)
77                 {
78                         if (hostName == null)
79                                 throw new ArgumentNullException ("hostName");
80
81                         ResolveCallback c = new ResolveCallback (Resolve);
82                         return c.BeginInvoke (hostName, requestCallback, stateObject);
83                 }
84
85 #if NET_2_0
86                 public static IAsyncResult BeginGetHostAddresses (string hostName,
87                         AsyncCallback requestCallback, object stateObject)
88                 {
89                         if (hostName == null)
90                                 throw new ArgumentNullException ("hostName");
91
92                         GetHostAddressesCallback c = new GetHostAddressesCallback (GetHostAddresses);
93                         return c.BeginInvoke (hostName, requestCallback, stateObject);
94                 }
95
96                 public static IAsyncResult BeginGetHostEntry (string hostNameOrAddress,
97                         AsyncCallback requestCallback, object stateObject)
98                 {
99                         if (hostNameOrAddress == null)
100                                 throw new ArgumentNullException ("hostNameOrAddress");
101
102                         GetHostEntryNameCallback c = new GetHostEntryNameCallback (GetHostEntry);
103                         return c.BeginInvoke (hostNameOrAddress, requestCallback, stateObject);
104                 }
105
106                 public static IAsyncResult BeginGetHostEntry (IPAddress hostAddress,
107                         AsyncCallback requestCallback, object stateObject)
108                 {
109                         if (hostAddress == null)
110                                 throw new ArgumentNullException ("hostAddress");
111
112                         GetHostEntryIPCallback c = new GetHostEntryIPCallback (GetHostEntry);
113                         return c.BeginInvoke (hostAddress, requestCallback, stateObject);
114                 }
115 #endif
116
117 #if NET_2_0
118                 [Obsolete ("Use EndGetHostEntry instead")]
119 #endif
120                 public static IPHostEntry EndGetHostByName (IAsyncResult asyncResult) 
121                 {
122                         if (asyncResult == null)
123                                 throw new ArgumentNullException ("asyncResult");
124
125                         AsyncResult async = (AsyncResult) asyncResult;
126                         GetHostByNameCallback cb = (GetHostByNameCallback) async.AsyncDelegate;
127                         return cb.EndInvoke(asyncResult);
128                 }
129
130 #if NET_2_0
131                 [Obsolete ("Use EndGetHostEntry instead")]
132 #endif
133                 public static IPHostEntry EndResolve (IAsyncResult asyncResult) 
134                 {
135                         if (asyncResult == null)
136                                 throw new ArgumentNullException ("asyncResult");
137                         AsyncResult async = (AsyncResult) asyncResult;
138                         ResolveCallback cb = (ResolveCallback) async.AsyncDelegate;
139                         return cb.EndInvoke(asyncResult);
140                 }
141
142 #if NET_2_0
143
144                 public static IPAddress [] EndGetHostAddresses (IAsyncResult asyncResult) 
145                 {
146                         if (asyncResult == null)
147                                 throw new ArgumentNullException ("asyncResult");
148
149                         AsyncResult async = (AsyncResult) asyncResult;
150                         GetHostAddressesCallback cb = (GetHostAddressesCallback) async.AsyncDelegate;
151                         return cb.EndInvoke(asyncResult);
152                 }
153
154                 public static IPHostEntry EndGetHostEntry (IAsyncResult asyncResult) 
155                 {
156                         if (asyncResult == null)
157                                 throw new ArgumentNullException ("asyncResult");
158                         AsyncResult async = (AsyncResult) asyncResult;
159 #if NET_2_0
160                         if (async.AsyncDelegate is GetHostEntryIPCallback)
161                                 return ((GetHostEntryIPCallback) async.AsyncDelegate).EndInvoke (asyncResult);
162 #endif
163                         GetHostEntryNameCallback cb = (GetHostEntryNameCallback) async.AsyncDelegate;
164                         return cb.EndInvoke(asyncResult);
165                 }
166 #endif
167
168 #if !TARGET_JVM
169                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
170                 private extern static bool GetHostByName_internal(string host, out string h_name, out string[] h_aliases, out string[] h_addr_list);
171
172                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
173                 private extern static bool GetHostByAddr_internal(string addr, out string h_name, out string[] h_aliases, out string[] h_addr_list);
174
175                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
176                 private extern static bool GetHostName_internal(out string h_name);
177 #endif  
178
179                 private static IPHostEntry hostent_to_IPHostEntry(string h_name, string[] h_aliases, string[] h_addrlist) 
180                 {
181                         IPHostEntry he = new IPHostEntry();
182                         ArrayList addrlist = new ArrayList();
183
184                         he.HostName = h_name;
185                         he.Aliases = h_aliases;
186                         for(int i=0; i<h_addrlist.Length; i++) {
187                                 try {
188                                         IPAddress newAddress = IPAddress.Parse(h_addrlist[i]);
189
190                                         if( (Socket.SupportsIPv6 && newAddress.AddressFamily == AddressFamily.InterNetworkV6) ||
191                                             (Socket.SupportsIPv4 && newAddress.AddressFamily == AddressFamily.InterNetwork) )
192                                                 addrlist.Add(newAddress);
193                                 } catch (ArgumentNullException) {
194                                         /* Ignore this, as the
195                                          * internal call might have
196                                          * left some blank entries at
197                                          * the end of the array
198                                          */
199                                 }
200                         }
201
202                         if(addrlist.Count == 0)
203                                 throw new SocketException(11001);
204
205                         he.AddressList = addrlist.ToArray(typeof(IPAddress)) as IPAddress[];
206                         return he;
207                 }
208
209 #if NET_2_0
210                 [Obsolete ("Use GetHostEntry instead")]
211 #endif
212                 public static IPHostEntry GetHostByAddress(IPAddress address)
213                 {
214                         if (address == null)
215                                 throw new ArgumentNullException ("address");
216
217                         return GetHostByAddressFromString (address.ToString (), false);
218                 }
219
220 #if NET_2_0
221                 [Obsolete ("Use GetHostEntry instead")]
222 #endif
223                 public static IPHostEntry GetHostByAddress(string address)
224                 {
225                         if (address == null)
226                                 throw new ArgumentNullException ("address");
227
228                         return GetHostByAddressFromString (address, true);
229                 }
230
231                 static IPHostEntry GetHostByAddressFromString (string address, bool parse)
232                 {
233                         // Undocumented MS behavior: when called with IF_ANY,
234                         // this should return the local host
235                         if (address.Equals ("0.0.0.0")) {
236                                 address = "127.0.0.1";
237                                 parse = false;
238                         }
239
240                         // Must check the IP format, might send an exception if invalid string.
241                         if (parse)
242                                 IPAddress.Parse (address);
243
244                         string h_name;
245                         string[] h_aliases, h_addrlist;
246 #if TARGET_JVM
247                         h_name = null;
248                         h_aliases = null;
249                         h_addrlist = null;
250                         try {
251                                 java.net.InetAddress[] iaArr = 
252                                         java.net.InetAddress.getAllByName(address);
253                                 if (iaArr != null && iaArr.Length > 0)
254                                     h_name = iaArr[0].getHostName();
255                                 if (iaArr != null && iaArr.Length > 0)
256                                 {
257                                     h_addrlist = new String[iaArr.Length];
258                                     for (int i = 0; i < h_addrlist.Length; i++)
259                                         h_addrlist[i] = iaArr[i].getHostAddress();
260                                 }
261                         } catch (java.net.UnknownHostException jUHE) {
262                                 throw new SocketException((int)SocketError.HostNotFound, jUHE.Message);
263                         }
264 #else
265                         bool ret = GetHostByAddr_internal(address, out h_name, out h_aliases, out h_addrlist);
266                         if (!ret)
267                                 throw new SocketException(11001);
268 #endif
269                         return (hostent_to_IPHostEntry (h_name, h_aliases, h_addrlist));
270                         
271                 }
272
273 #if NET_2_0
274                 public static IPHostEntry GetHostEntry (string hostNameOrAddress)
275                 {
276                         if (hostNameOrAddress == null)
277                                 throw new ArgumentNullException ("hostNameOrAddress");
278
279                         if (hostNameOrAddress == "0.0.0.0" || hostNameOrAddress == "")
280                                 hostNameOrAddress = "127.0.0.1";
281                         IPAddress addr;
282                         if (IPAddress.TryParse (hostNameOrAddress, out addr))
283                                 return GetHostEntry (addr);
284                         else
285                                 return GetHostByName (hostNameOrAddress);
286                 }
287
288                 public static IPHostEntry GetHostEntry (IPAddress address)
289                 {
290                         if (address == null)
291                                 throw new ArgumentNullException ("address");
292
293                         return GetHostByAddressFromString (address.ToString (), false);
294                 }
295
296                 public static IPAddress [] GetHostAddresses (string hostNameOrAddress)
297                 {
298                         if (hostNameOrAddress == null)
299                                 throw new ArgumentNullException ("hostNameOrAddress");
300
301                         if (hostNameOrAddress == "0.0.0.0" || hostNameOrAddress == "")
302                                 hostNameOrAddress = "127.0.0.1";
303
304                         IPAddress addr;
305                         if (IPAddress.TryParse (hostNameOrAddress, out addr))
306                         {
307                                 return new IPAddress[1] { addr };
308                         }
309                         else
310                         {
311                           
312                                 return GetHostEntry (hostNameOrAddress).AddressList;
313                         }
314                 }
315 #endif
316
317 #if NET_2_0
318                 [Obsolete ("Use GetHostEntry instead")]
319 #endif
320                 public static IPHostEntry GetHostByName (string hostName)
321                 {
322                         if (hostName == null)
323                                 throw new ArgumentNullException ();
324 #if TARGET_JVM
325                         if (hostName.Length == 0)
326                                 hostName = "localhost";
327                         try {
328                                 java.net.InetAddress[] iaArr = java.net.InetAddress.getAllByName(hostName);
329                                 IPHostEntry host = new IPHostEntry();
330                                 if (iaArr != null && iaArr.Length > 0)
331                                 {
332                                         host.HostName = iaArr[0].getHostName();
333                                         IPAddress[] ipArr = new IPAddress[iaArr.Length];
334                                         for (int i = 0; i < iaArr.Length; i++)
335                                                 ipArr[i] = IPAddress.Parse(iaArr[i].getHostAddress());
336
337                                         host.AddressList = ipArr;
338                                 }
339                                 return host;
340                         } catch (java.net.UnknownHostException jUHE) {
341                                 throw new SocketException((int)SocketError.HostNotFound, jUHE.Message);
342                         }
343 #else
344                         string h_name;
345                         string[] h_aliases, h_addrlist;
346
347                         bool ret = GetHostByName_internal(hostName, out h_name,
348                                 out h_aliases,
349                                 out h_addrlist);
350                         if (ret == false)
351                                 throw new SocketException(11001);
352
353                         return(hostent_to_IPHostEntry(h_name, h_aliases,
354                                 h_addrlist));
355 #endif
356                 }
357
358                 public static string GetHostName ()
359                 {
360 #if TARGET_JVM
361                         return java.net.InetAddress.getLocalHost ().getHostName ();
362 #else
363                         string hostName;
364
365                         bool ret = GetHostName_internal(out hostName);
366
367                         if (ret == false)
368                                 throw new SocketException(11001);
369
370                         return hostName;
371 #endif
372                 }
373
374 #if NET_2_0
375                 [Obsolete ("Use GetHostEntry instead")]
376 #endif
377                 public static IPHostEntry Resolve(string hostName) 
378                 {
379                         if (hostName == null)
380                                 throw new ArgumentNullException ("hostName");
381
382                         IPHostEntry ret = null;
383
384                         try {
385                                 ret =  GetHostByAddress(hostName);
386                         }
387                         catch{}
388
389                         if(ret == null)
390                                 ret =  GetHostByName(hostName);
391
392                         return ret;
393                 }
394         }
395 }
396