merge -r 53370:58178
[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
54                 public static IAsyncResult BeginGetHostByName (string hostName,
55                         AsyncCallback requestCallback, object stateObject)
56                 {
57                         if (hostName == null)
58                                 throw new ArgumentNullException ("hostName");
59
60                         GetHostByNameCallback c = new GetHostByNameCallback (GetHostByName);
61                         return c.BeginInvoke (hostName, requestCallback, stateObject);
62                 }
63
64                 public static IAsyncResult BeginResolve (string hostName,
65                         AsyncCallback requestCallback, object stateObject)
66                 {
67                         if (hostName == null)
68                                 throw new ArgumentNullException ("hostName");
69
70                         ResolveCallback c = new ResolveCallback (Resolve);
71                         return c.BeginInvoke (hostName, requestCallback, stateObject);
72                 }
73
74                 public static IPHostEntry EndGetHostByName (IAsyncResult asyncResult) 
75                 {
76                         if (asyncResult == null)
77                                 throw new ArgumentNullException ("asyncResult");
78
79                         AsyncResult async = (AsyncResult) asyncResult;
80                         GetHostByNameCallback cb = (GetHostByNameCallback) async.AsyncDelegate;
81                         return cb.EndInvoke(asyncResult);
82                 }
83
84                 public static IPHostEntry EndResolve (IAsyncResult asyncResult) 
85                 {
86                         if (asyncResult == null)
87                                 throw new ArgumentNullException ("asyncResult");
88                         AsyncResult async = (AsyncResult) asyncResult;
89                         ResolveCallback cb = (ResolveCallback) async.AsyncDelegate;
90                         return cb.EndInvoke(asyncResult);
91                 }
92
93                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
94                 private extern static bool GetHostByName_internal(string host, out string h_name, out string[] h_aliases, out string[] h_addr_list);
95
96                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
97                 private extern static bool GetHostByAddr_internal(string addr, out string h_name, out string[] h_aliases, out string[] h_addr_list);
98
99                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
100                 private extern static bool GetHostName_internal(out string h_name);
101                 
102                 private static IPHostEntry hostent_to_IPHostEntry(string h_name, string[] h_aliases, string[] h_addrlist) 
103                 {
104                         IPHostEntry he = new IPHostEntry();
105                         ArrayList addrlist = new ArrayList();
106
107                         he.HostName = h_name;
108                         he.Aliases = h_aliases;
109                         for(int i=0; i<h_addrlist.Length; i++) {
110                                 IPAddress newAddress = IPAddress.Parse(h_addrlist[i]);
111
112                                 if( (Socket.SupportsIPv6 && newAddress.AddressFamily == AddressFamily.InterNetworkV6) ||
113                                         (Socket.SupportsIPv4 && newAddress.AddressFamily == AddressFamily.InterNetwork) )
114                                         addrlist.Add(newAddress);
115                         }
116
117                         if(addrlist.Count == 0)
118                                 throw new SocketException(11001);
119
120                         he.AddressList = addrlist.ToArray(typeof(IPAddress)) as IPAddress[];
121                         return he;
122                 }
123
124                 public static IPHostEntry GetHostByAddress(IPAddress address)
125                 {
126                         if (address == null)
127                                 throw new ArgumentNullException ("address");
128
129                         return GetHostByAddressFromString (address.ToString (), false);
130                 }
131
132                 public static IPHostEntry GetHostByAddress(string address)
133                 {
134                         if (address == null)
135                                 throw new ArgumentNullException ("address");
136
137                         return GetHostByAddressFromString (address, true);
138                 }
139
140                 static IPHostEntry GetHostByAddressFromString (string address, bool parse)
141                 {
142                         // Undocumented MS behavior: when called with IF_ANY,
143                         // this should return the local host
144                         if (address.Equals ("0.0.0.0")) {
145                                 address = "127.0.0.1";
146                                 parse = false;
147                         }
148
149                         // Must check the IP format, might send an exception if invalid string.
150                         if (parse)
151                                 IPAddress.Parse(address);
152
153                         string h_name;
154                         string[] h_aliases, h_addrlist;
155
156                         bool ret = GetHostByAddr_internal(address, out h_name, out h_aliases, out h_addrlist);
157                         if (!ret)
158                                 throw new SocketException(11001);
159
160                         return (hostent_to_IPHostEntry (h_name, h_aliases, h_addrlist));
161                 }
162
163 #if NET_2_0
164                 [MonoTODO]
165                 public static IPHostEntry GetHostEntry (string hostNameOrAddress)
166                 {
167                         if (hostNameOrAddress == null)
168                                 throw new ArgumentNullException ("hostNameOrAddress");
169
170                         return Resolve (hostNameOrAddress);
171                 }
172 #endif
173                 public static IPHostEntry GetHostByName(string hostName) 
174                 {
175                         if (hostName == null)
176                                 throw new ArgumentNullException();
177
178                         string h_name;
179                         string[] h_aliases, h_addrlist;
180
181                         bool ret = GetHostByName_internal(hostName, out h_name,
182                                 out h_aliases,
183                                 out h_addrlist);
184                         if (ret == false)
185                                 throw new SocketException(11001);
186
187                         return(hostent_to_IPHostEntry(h_name, h_aliases,
188                                 h_addrlist));
189                 }
190
191                 public static string GetHostName() 
192                 {
193                         string hostName;
194
195                         bool ret = GetHostName_internal(out hostName);
196
197                         if (ret == false)
198                                 throw new SocketException(11001);
199
200                         return hostName;
201                 }
202
203                 public static IPHostEntry Resolve(string hostName) 
204                 {
205                         if (hostName == null)
206                                 throw new ArgumentNullException ("hostName");
207
208                         IPHostEntry ret = null;
209
210                         try {
211                                 ret =  GetHostByAddress(hostName);
212                         }
213                         catch{}
214
215                         if(ret == null)
216                                 ret =  GetHostByName(hostName);
217
218                         return ret;
219                 }
220         }
221 }
222