diff options
author | Adam Frisby | 2009-05-23 05:09:10 +0000 |
---|---|---|
committer | Adam Frisby | 2009-05-23 05:09:10 +0000 |
commit | 2d0613516626960de5d7e3ea83b6386ce00dcb74 (patch) | |
tree | e5c2f868532a3b68a12723112f845c735acb6b4d /OpenSim/Framework/NetworkUtil.cs | |
parent | Changing extension of two of the config files to .example because they need t... (diff) | |
download | opensim-SC-2d0613516626960de5d7e3ea83b6386ce00dcb74.zip opensim-SC-2d0613516626960de5d7e3ea83b6386ce00dcb74.tar.gz opensim-SC-2d0613516626960de5d7e3ea83b6386ce00dcb74.tar.bz2 opensim-SC-2d0613516626960de5d7e3ea83b6386ce00dcb74.tar.xz |
* Adds new NetworkUtil class, contains methods for handling IP resolution when located on the same subnet. (Eg, can be used to avoid NAT Loopback requirements if fully utilized.)
* Adds a few new network-related methods to Util.
Diffstat (limited to 'OpenSim/Framework/NetworkUtil.cs')
-rw-r--r-- | OpenSim/Framework/NetworkUtil.cs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs new file mode 100644 index 0000000..1abf0d8 --- /dev/null +++ b/OpenSim/Framework/NetworkUtil.cs | |||
@@ -0,0 +1,122 @@ | |||
1 | using System.Collections.Generic; | ||
2 | using System.Net.Sockets; | ||
3 | using System.Net; | ||
4 | using System.Net.NetworkInformation; | ||
5 | |||
6 | namespace OpenSim.Framework | ||
7 | { | ||
8 | /// <summary> | ||
9 | /// Handles NAT translation in a 'manner of speaking' | ||
10 | /// Allows you to return multiple different external | ||
11 | /// hostnames depending on the requestors network | ||
12 | /// | ||
13 | /// This enables standard port forwarding techniques | ||
14 | /// to work correctly with OpenSim. | ||
15 | /// </summary> | ||
16 | static class NetworkUtil | ||
17 | { | ||
18 | // IPv4Address, Subnet | ||
19 | static readonly Dictionary<IPAddress,IPAddress> m_subnets = new Dictionary<IPAddress, IPAddress>(); | ||
20 | |||
21 | private static IPAddress GetExternalIPFor(IPAddress destination, string defaultHostname) | ||
22 | { | ||
23 | // Adds IPv6 Support (Not that any of the major protocols supports it...) | ||
24 | if (destination.AddressFamily == AddressFamily.InterNetworkV6) | ||
25 | { | ||
26 | foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) | ||
27 | { | ||
28 | if (host.AddressFamily == AddressFamily.InterNetworkV6) | ||
29 | return host; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | if(destination.AddressFamily != AddressFamily.InterNetwork) | ||
34 | return null; | ||
35 | |||
36 | // Check if we're accessing localhost. | ||
37 | foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) | ||
38 | { | ||
39 | if (host.Equals(destination)) | ||
40 | return destination; | ||
41 | } | ||
42 | |||
43 | // Check for same LAN segment | ||
44 | foreach (KeyValuePair<IPAddress, IPAddress> subnet in m_subnets) | ||
45 | { | ||
46 | byte[] subnetBytes = subnet.Value.GetAddressBytes(); | ||
47 | byte[] localBytes = subnet.Key.GetAddressBytes(); | ||
48 | byte[] destBytes = destination.GetAddressBytes(); | ||
49 | |||
50 | if(subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) | ||
51 | return null; | ||
52 | |||
53 | bool valid = true; | ||
54 | |||
55 | for(int i=0;i<subnetBytes.Length;i++) | ||
56 | { | ||
57 | if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) | ||
58 | { | ||
59 | valid = false; | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | if (valid) | ||
65 | return subnet.Key; | ||
66 | } | ||
67 | |||
68 | // None found. Assume outside network. | ||
69 | return null; | ||
70 | } | ||
71 | |||
72 | static NetworkUtil() | ||
73 | { | ||
74 | foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) | ||
75 | { | ||
76 | foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses) | ||
77 | { | ||
78 | if (address.Address.AddressFamily == AddressFamily.InterNetwork) | ||
79 | { | ||
80 | m_subnets.Add(address.Address, address.IPv4Mask); | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | public static IPAddress GetIPFor(IPEndPoint user, string defaultHostname) | ||
87 | { | ||
88 | // Try subnet matching | ||
89 | IPAddress rtn = GetExternalIPFor(user.Address, defaultHostname); | ||
90 | if (rtn != null) | ||
91 | return rtn; | ||
92 | |||
93 | // Otherwise use the old algorithm | ||
94 | IPAddress ia; | ||
95 | |||
96 | if (IPAddress.TryParse(defaultHostname, out ia)) | ||
97 | return ia; | ||
98 | |||
99 | ia = null; | ||
100 | |||
101 | foreach (IPAddress Adr in Dns.GetHostAddresses(defaultHostname)) | ||
102 | { | ||
103 | if (Adr.AddressFamily == AddressFamily.InterNetwork) | ||
104 | { | ||
105 | ia = Adr; | ||
106 | break; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return ia; | ||
111 | } | ||
112 | |||
113 | public static string GetHostFor(IPAddress user, string defaultHostname) | ||
114 | { | ||
115 | IPAddress rtn = GetExternalIPFor(user, defaultHostname); | ||
116 | if(rtn != null) | ||
117 | return rtn.ToString(); | ||
118 | |||
119 | return defaultHostname; | ||
120 | } | ||
121 | } | ||
122 | } | ||