Socket permission stuff, not yet used by Socket itself.
[mono.git] / mcs / class / System / System.Net / Dns.cs
1 // System.Net.Dns.cs
2 //
3 // Author: Mads Pultz (mpultz@diku.dk)
4 //
5 // (C) Mads Pultz, 2001
6
7 using System;
8 using System.Net.Sockets;
9 using System.Text;
10 using System.Collections;
11 using System.Threading;
12 using System.Runtime.CompilerServices;
13
14 namespace System.Net {
15         public sealed class Dns {
16
17                 private Dns () {}
18                 
19                 /// <summary>
20                 /// Helper class
21                 /// </summary>
22                 private sealed class DnsAsyncResult: IAsyncResult {
23                         private object state;
24                         private WaitHandle waitHandle;
25                         private bool completedSync, completed;
26                         private Worker worker;
27                 
28                         public DnsAsyncResult(object state) {
29                                 this.state = state;
30                                 waitHandle = new ManualResetEvent(false);
31                                 completedSync = completed = false;
32                         }       
33                         public object AsyncState {
34                                 get { return state; }
35                         }
36                         public WaitHandle AsyncWaitHandle {
37                                 set { waitHandle = value; }
38                                 get { return waitHandle; }
39                         }
40                         public bool CompletedSynchronously {
41                                 get { return completedSync; }
42                         }
43                         public bool IsCompleted {
44                                 set { completed = value; }
45                                 get { return completed; }
46                         }
47                         public Worker Worker {
48                                 set { worker = value; }
49                                 get { return worker; }
50                         }
51                 }
52
53                 /// <summary>
54                 /// Helper class for asynchronous calls to DNS server
55                 /// </summary>
56                 private sealed class Worker {
57                         private AsyncCallback reqCallback;
58                         private DnsAsyncResult reqRes;
59                         private string req;
60                         private IPHostEntry result;
61                         
62                         public Worker(string req, AsyncCallback reqCallback, DnsAsyncResult reqRes) {
63                                 this.req = req;
64                                 this.reqCallback = reqCallback;
65                                 this.reqRes = reqRes;
66                         }
67                         private void End() {
68                                 reqCallback(reqRes);
69                                 ((ManualResetEvent)reqRes.AsyncWaitHandle).Set();
70                                 reqRes.IsCompleted = true;
71                         }
72                         public void GetHostByName() {
73                                 lock(reqRes) {
74                                         result = Dns.GetHostByName(req);
75                                         End();
76                                 }
77                         }
78                         public void Resolve() {
79                                 lock(reqRes) {
80                                         result = Dns.Resolve(req);
81                                         End();
82                                 }
83                         }
84                         public IPHostEntry Result {
85                                 get { return result; }
86                         }
87                 }
88                 
89                 public static IAsyncResult BeginGetHostByName(string hostName,
90                         AsyncCallback requestCallback, object stateObject)
91                 {
92                         DnsAsyncResult requestResult = new DnsAsyncResult(stateObject);
93                         Worker worker = new Worker(hostName, requestCallback, requestResult);
94                         Thread child = new Thread(new ThreadStart(worker.GetHostByName));
95                         child.Start();
96                         return requestResult;
97                 }
98
99                 public static IAsyncResult BeginResolve(string hostName,
100                         AsyncCallback requestCallback, object stateObject)
101                 {
102                         DnsAsyncResult requestResult = new DnsAsyncResult(stateObject);
103                         Worker worker = new Worker(hostName, requestCallback, requestResult);
104                         Thread child = new Thread(new ThreadStart(worker.Resolve));
105                         child.Start();
106                         return requestResult;
107                 }
108                 
109                 public static IPHostEntry EndGetHostByName(IAsyncResult asyncResult) {
110                         return ((DnsAsyncResult)asyncResult).Worker.Result;
111                 }
112
113                 public static IPHostEntry EndResolve(IAsyncResult asyncResult) {
114                         return ((DnsAsyncResult)asyncResult).Worker.Result;
115                 }
116                 
117                 
118                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
119                 private extern static bool GetHostByName_internal(string host, out string h_name, out string[] h_aliases, out string[] h_addr_list);
120                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
121                 private extern static bool GetHostByAddr_internal(string addr, out string h_name, out string[] h_aliases, out string[] h_addr_list);
122                 
123                 private static IPHostEntry hostent_to_IPHostEntry(string h_name, string[] h_aliases, string[] h_addrlist) {
124                         IPHostEntry he = new IPHostEntry();
125                         IPAddress[] addrlist = new IPAddress[h_addrlist.Length];
126                         
127                         he.HostName=h_name;
128                         he.Aliases=h_aliases;
129                         for(int i=0; i<h_addrlist.Length; i++) {
130                                 addrlist[i]=IPAddress.Parse(h_addrlist[i]);
131                         }
132                         he.AddressList=addrlist;
133
134                         return(he);
135                 }
136
137                 public static IPHostEntry GetHostByAddress(IPAddress address) {
138                         if (address == null)
139                                 throw new ArgumentNullException();
140                         return GetHostByAddress(address.ToString());
141                 }
142                 
143                 public static IPHostEntry GetHostByAddress(string address) {
144                         if (address == null) {
145                                 throw new ArgumentNullException();
146                         }
147                         
148                         string h_name;
149                         string[] h_aliases, h_addrlist;
150                         
151                         bool ret = GetHostByAddr_internal(address, out h_name,
152                                                           out h_aliases,
153                                                           out h_addrlist);
154                         if (ret == false) {
155                                 throw new SocketException(11001);
156                         }
157                         
158                         return(hostent_to_IPHostEntry(h_name, h_aliases,
159                                                       h_addrlist));
160                 }
161
162                 public static IPHostEntry GetHostByName(string hostName) {
163                         if (hostName == null) {
164                                 throw new ArgumentNullException();
165                         }
166                         
167                         string h_name;
168                         string[] h_aliases, h_addrlist;
169                         
170                         bool ret = GetHostByName_internal(hostName, out h_name,
171                                                           out h_aliases,
172                                                           out h_addrlist);
173                         if (ret == false) {
174                                 throw new SocketException(11001);
175                         }
176
177                         return(hostent_to_IPHostEntry(h_name, h_aliases,
178                                                       h_addrlist));
179                 }
180                 
181                 /// <summary>
182                 /// This method returns the host name associated with the local host.
183                 /// </summary>
184                 public static string GetHostName() {
185                         IPHostEntry h = GetHostByAddress("127.0.0.1");
186                         return h.HostName;
187                 }
188                 
189                 /// <summary>
190                 /// This method resolves a DNS-style host name or IP
191                 /// address.
192                 /// </summary>
193                 /// <param name=hostName>
194                 /// A string containing either a DNS-style host name (e.g.
195                 /// www.go-mono.com) or IP address (e.g. 129.250.184.233).
196                 /// </param>
197                 public static IPHostEntry Resolve(string hostName) {
198                         if (hostName == null)
199                                 throw new ArgumentNullException();
200
201                         return GetHostByName (hostName);
202                 }
203         }
204 }
205