[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / System / System.Net / EndpointPermission.cs
blob80b0fb465365e075a7180de2d3467b30299ee54a
1 //
2 // System.Net.EndpointPermission.cs
3 //
4 // Author:
5 // Lawrence Pit (loz@cable.a2000.nl)
6 //
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.
29 using System;
30 using System.Collections;
31 using System.Security;
32 using System.Security.Permissions;
34 namespace System.Net
36 [Serializable]
37 public class EndpointPermission // too bad about the lowercase p, not consistent with IPEndPoint ;)
39 private static char [] dot_char = new char [] { '.' };
41 // Fields
42 private string hostname;
43 private int port;
44 private TransportType transport;
46 private bool resolved;
47 private bool hasWildcard;
48 private IPAddress [] addresses;
50 // Constructors
51 internal EndpointPermission (string hostname,
52 int port,
53 TransportType transport) : base ()
55 if (hostname == null)
56 throw new ArgumentNullException ("hostname");
57 this.hostname = hostname;
58 this.port = port;
59 this.transport = transport;
60 this.resolved = false;
61 this.hasWildcard = false;
62 this.addresses = null;
65 // Properties
67 public string Hostname {
68 get { return hostname; }
71 public int Port {
72 get { return port; }
75 public TransportType Transport {
76 get { return transport; }
79 // Methods
81 public override bool Equals (object obj)
83 EndpointPermission epp = obj as EndpointPermission;
84 return ((epp != null) &&
85 (this.port == epp.port) &&
86 (this.transport == epp.transport) &&
87 (String.Compare (this.hostname, epp.hostname, true) == 0));
90 public override int GetHashCode ()
92 return ToString ().GetHashCode ();
95 public override string ToString ()
97 return hostname + "#" + port + "#" + (int) transport;
100 // Internal & Private Methods
102 internal bool IsSubsetOf (EndpointPermission perm)
104 if (perm == null)
105 return false;
107 if (perm.port != SocketPermission.AllPorts &&
108 this.port != perm.port)
109 return false;
111 if (perm.transport != TransportType.All &&
112 this.transport != perm.transport)
113 return false;
115 this.Resolve ();
116 perm.Resolve ();
118 if (this.hasWildcard) {
119 if (perm.hasWildcard)
120 return IsSubsetOf (this.hostname, perm.hostname);
121 else
122 return false;
125 if (this.addresses == null)
126 return false;
128 if (perm.hasWildcard)
129 // a bit dubious... should they all be a subset or is one
130 // enough in this case?
131 foreach (IPAddress addr in this.addresses)
132 if (IsSubsetOf (addr.ToString (), perm.hostname))
133 return true;
135 if (perm.addresses == null)
136 return false;
138 // a bit dubious... should they all be a subset or is one
139 // enough in this case?
140 foreach (IPAddress addr in perm.addresses)
141 if (IsSubsetOf (this.hostname, addr.ToString ()))
142 return true;
144 return false;
147 private bool IsSubsetOf (string addr1, string addr2)
149 string [] h1 = addr1.Split (dot_char);
150 string [] h2 = addr2.Split (dot_char);
152 for (int i = 0; i < 4; i++) {
153 int part1 = ToNumber (h1 [i]);
154 if (part1 == -1)
155 return false;
157 int part2 = ToNumber (h2 [i]);
158 if (part2 == -1)
159 return false;
160 if (part1 == 256)
161 continue;
162 if (part1 != part2 && part2 != 256)
163 return false;
165 return true;
168 internal EndpointPermission Intersect (EndpointPermission perm)
170 if (perm == null)
171 return null;
173 int _port;
174 if (this.port == perm.port)
175 _port = this.port;
176 else if (this.port == SocketPermission.AllPorts)
177 _port = perm.port;
178 else if (perm.port == SocketPermission.AllPorts)
179 _port = this.port;
180 else
181 return null;
183 TransportType _transport;
184 if (this.transport == perm.transport)
185 _transport = this.transport;
186 else if (this.transport == TransportType.All)
187 _transport = perm.transport;
188 else if (perm.transport == TransportType.All)
189 _transport = this.transport;
190 else
191 return null;
193 string _hostname = IntersectHostname (perm);
195 if (_hostname == null)
196 return null;
198 if (!this.hasWildcard)
199 return this;
201 if (!perm.hasWildcard)
202 return perm;
204 EndpointPermission newperm = new EndpointPermission (_hostname, _port, _transport);
205 newperm.hasWildcard = true;
206 newperm.resolved = true;
207 return newperm;
210 private string IntersectHostname (EndpointPermission perm)
212 if (this.hostname == perm.hostname)
213 return this.hostname;
215 this.Resolve ();
216 perm.Resolve ();
218 string _hostname = null;
220 if (this.hasWildcard) {
221 if (perm.hasWildcard) {
222 _hostname = Intersect (this.hostname, perm.hostname);
223 } else if (perm.addresses != null) {
224 for (int j = 0; j < perm.addresses.Length; j++) {
225 _hostname = Intersect (this.hostname, perm.addresses [j].ToString ());
226 if (_hostname != null)
227 break;
230 } else if (this.addresses != null) {
231 for (int i = 0; i < this.addresses.Length; i++) {
232 string thisaddr = this.addresses [i].ToString ();
233 if (perm.hasWildcard) {
234 _hostname = Intersect (thisaddr, perm.hostname);
235 } else if (perm.addresses != null) {
236 for (int j = 0; j < perm.addresses.Length; j++) {
237 _hostname = Intersect (thisaddr, perm.addresses [j].ToString ());
238 if (_hostname != null)
239 break;
245 return _hostname;
248 // alas, currently we'll only support IPv4 as that's MS.Net behaviour
249 // returns null when both host strings do not intersect
250 private string Intersect (string addr1, string addr2)
252 string [] h1 = addr1.Split (dot_char);
253 string [] h2 = addr2.Split (dot_char);
255 string [] s = new string [7];
256 for (int i = 0; i < 4; i++) {
257 int part1 = ToNumber (h1 [i]);
258 if (part1 == -1)
259 return null;
261 int part2 = ToNumber (h2 [i]);
262 if (part2 == -1)
263 return null;
265 if (part1 == 256)
266 s [i << 1] = (part2 == 256) ? "*" : String.Empty + part2;
267 else if (part2 == 256)
268 s [i << 1] = (part1 == 256) ? "*" : String.Empty + part1;
269 else if (part1 == part2)
270 s [i << 1] = String.Empty + part1;
271 else
272 return null;
275 s [1] = s [3] = s [5] = ".";
276 return String.Concat (s);
279 // returns 256 if value is a '*' character
280 // returns -1 if value isn't a number between 0 and 255
281 private int ToNumber (string value)
283 if (value == "*")
284 return 256;
286 int len = value.Length;
287 if (len < 1 || len > 3)
288 return -1;
290 int val = 0;
291 for (int i = 0; i < len; i++) {
292 char c = value [i];
293 if ('0' <= c && c <= '9')
294 val = checked (val * 10 + (c - '0'));
295 else
296 return -1;
299 return val <= 255 ? val : -1;
302 internal void Resolve ()
304 if (resolved)
305 return;
307 bool isHostname = false;
308 bool hasWildcard = false;
309 this.addresses = null;
311 string [] s = hostname.Split (dot_char);
313 if (s.Length != 4) {
314 isHostname = true;
315 } else {
316 for (int i = 0; i < 4; i++) {
317 int quad = ToNumber (s [i]);
318 if (quad == -1) {
319 isHostname = true;
320 break;
322 if (quad == 256)
323 hasWildcard = true;
327 if (isHostname) {
328 this.hasWildcard = false;
329 try {
330 this.addresses = Dns.GetHostAddresses (hostname);
331 } catch (System.Net.Sockets.SocketException) {
333 } else {
334 this.hasWildcard = hasWildcard;
335 if (!hasWildcard) {
336 addresses = new IPAddress [1];
337 addresses [0] = IPAddress.Parse (hostname);
341 this.resolved = true;
344 internal void UndoResolve ()
346 resolved = false;