diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/NetworkUtil.cs | 442 |
1 files changed, 221 insertions, 221 deletions
diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs index e3fb009..351020b 100644 --- a/OpenSim/Framework/NetworkUtil.cs +++ b/OpenSim/Framework/NetworkUtil.cs | |||
@@ -1,221 +1,221 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Net.Sockets; | 3 | using System.Net.Sockets; |
4 | using System.Net; | 4 | using System.Net; |
5 | using System.Net.NetworkInformation; | 5 | using System.Net.NetworkInformation; |
6 | using System.Reflection; | 6 | using System.Reflection; |
7 | using log4net; | 7 | using log4net; |
8 | 8 | ||
9 | namespace OpenSim.Framework | 9 | namespace OpenSim.Framework |
10 | { | 10 | { |
11 | /// <summary> | 11 | /// <summary> |
12 | /// Handles NAT translation in a 'manner of speaking' | 12 | /// Handles NAT translation in a 'manner of speaking' |
13 | /// Allows you to return multiple different external | 13 | /// Allows you to return multiple different external |
14 | /// hostnames depending on the requestors network | 14 | /// hostnames depending on the requestors network |
15 | /// | 15 | /// |
16 | /// This enables standard port forwarding techniques | 16 | /// This enables standard port forwarding techniques |
17 | /// to work correctly with OpenSim. | 17 | /// to work correctly with OpenSim. |
18 | /// </summary> | 18 | /// </summary> |
19 | public static class NetworkUtil | 19 | public static class NetworkUtil |
20 | { | 20 | { |
21 | // Logger | 21 | // Logger |
22 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 22 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
23 | 23 | ||
24 | private static bool m_disabled = true; | 24 | private static bool m_disabled = true; |
25 | 25 | ||
26 | public static bool Enabled | 26 | public static bool Enabled |
27 | { | 27 | { |
28 | set { m_disabled = value; } | 28 | set { m_disabled = value; } |
29 | get { return m_disabled; } | 29 | get { return m_disabled; } |
30 | } | 30 | } |
31 | 31 | ||
32 | // IPv4Address, Subnet | 32 | // IPv4Address, Subnet |
33 | static readonly Dictionary<IPAddress,IPAddress> m_subnets = new Dictionary<IPAddress, IPAddress>(); | 33 | static readonly Dictionary<IPAddress,IPAddress> m_subnets = new Dictionary<IPAddress, IPAddress>(); |
34 | 34 | ||
35 | public static IPAddress GetIPFor(IPAddress user, IPAddress simulator) | 35 | public static IPAddress GetIPFor(IPAddress user, IPAddress simulator) |
36 | { | 36 | { |
37 | if(m_disabled) | 37 | if(m_disabled) |
38 | return simulator; | 38 | return simulator; |
39 | 39 | ||
40 | // Check if we're accessing localhost. | 40 | // Check if we're accessing localhost. |
41 | foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) | 41 | foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) |
42 | { | 42 | { |
43 | if (host.Equals(user) && host.AddressFamily == AddressFamily.InterNetwork) | 43 | if (host.Equals(user) && host.AddressFamily == AddressFamily.InterNetwork) |
44 | { | 44 | { |
45 | m_log.Info("[NetworkUtil] Localhost user detected, sending them '" + host + "' instead of '" + simulator + "'"); | 45 | m_log.Info("[NetworkUtil] Localhost user detected, sending them '" + host + "' instead of '" + simulator + "'"); |
46 | return host; | 46 | return host; |
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
50 | // Check for same LAN segment | 50 | // Check for same LAN segment |
51 | foreach (KeyValuePair<IPAddress, IPAddress> subnet in m_subnets) | 51 | foreach (KeyValuePair<IPAddress, IPAddress> subnet in m_subnets) |
52 | { | 52 | { |
53 | byte[] subnetBytes = subnet.Value.GetAddressBytes(); | 53 | byte[] subnetBytes = subnet.Value.GetAddressBytes(); |
54 | byte[] localBytes = subnet.Key.GetAddressBytes(); | 54 | byte[] localBytes = subnet.Key.GetAddressBytes(); |
55 | byte[] destBytes = user.GetAddressBytes(); | 55 | byte[] destBytes = user.GetAddressBytes(); |
56 | 56 | ||
57 | if (subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) | 57 | if (subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) |
58 | return null; | 58 | return null; |
59 | 59 | ||
60 | bool valid = true; | 60 | bool valid = true; |
61 | 61 | ||
62 | for (int i = 0; i < subnetBytes.Length; i++) | 62 | for (int i = 0; i < subnetBytes.Length; i++) |
63 | { | 63 | { |
64 | if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) | 64 | if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) |
65 | { | 65 | { |
66 | valid = false; | 66 | valid = false; |
67 | break; | 67 | break; |
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) | 71 | if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) |
72 | valid = false; | 72 | valid = false; |
73 | 73 | ||
74 | if (valid) | 74 | if (valid) |
75 | { | 75 | { |
76 | m_log.Info("[NetworkUtil] Local LAN user detected, sending them '" + subnet.Key + "' instead of '" + simulator + "'"); | 76 | m_log.Info("[NetworkUtil] Local LAN user detected, sending them '" + subnet.Key + "' instead of '" + simulator + "'"); |
77 | return subnet.Key; | 77 | return subnet.Key; |
78 | } | 78 | } |
79 | } | 79 | } |
80 | 80 | ||
81 | // Otherwise, return outside address | 81 | // Otherwise, return outside address |
82 | return simulator; | 82 | return simulator; |
83 | } | 83 | } |
84 | 84 | ||
85 | private static IPAddress GetExternalIPFor(IPAddress destination, string defaultHostname) | 85 | private static IPAddress GetExternalIPFor(IPAddress destination, string defaultHostname) |
86 | { | 86 | { |
87 | // Adds IPv6 Support (Not that any of the major protocols supports it...) | 87 | // Adds IPv6 Support (Not that any of the major protocols supports it...) |
88 | if (destination.AddressFamily == AddressFamily.InterNetworkV6) | 88 | if (destination.AddressFamily == AddressFamily.InterNetworkV6) |
89 | { | 89 | { |
90 | foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) | 90 | foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) |
91 | { | 91 | { |
92 | if (host.AddressFamily == AddressFamily.InterNetworkV6) | 92 | if (host.AddressFamily == AddressFamily.InterNetworkV6) |
93 | { | 93 | { |
94 | m_log.Info("[NetworkUtil] Localhost user detected, sending them '" + host + "' instead of '" + defaultHostname + "'"); | 94 | m_log.Info("[NetworkUtil] Localhost user detected, sending them '" + host + "' instead of '" + defaultHostname + "'"); |
95 | return host; | 95 | return host; |
96 | } | 96 | } |
97 | } | 97 | } |
98 | } | 98 | } |
99 | 99 | ||
100 | if(destination.AddressFamily != AddressFamily.InterNetwork) | 100 | if(destination.AddressFamily != AddressFamily.InterNetwork) |
101 | return null; | 101 | return null; |
102 | 102 | ||
103 | // Check if we're accessing localhost. | 103 | // Check if we're accessing localhost. |
104 | foreach (KeyValuePair<IPAddress, IPAddress> pair in m_subnets) | 104 | foreach (KeyValuePair<IPAddress, IPAddress> pair in m_subnets) |
105 | { | 105 | { |
106 | IPAddress host = pair.Value; | 106 | IPAddress host = pair.Value; |
107 | if (host.Equals(destination) && host.AddressFamily == AddressFamily.InterNetwork) | 107 | if (host.Equals(destination) && host.AddressFamily == AddressFamily.InterNetwork) |
108 | { | 108 | { |
109 | m_log.Info("[NATROUTING] Localhost user detected, sending them '" + host + "' instead of '" + defaultHostname + "'"); | 109 | m_log.Info("[NATROUTING] Localhost user detected, sending them '" + host + "' instead of '" + defaultHostname + "'"); |
110 | return destination; | 110 | return destination; |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | // Check for same LAN segment | 114 | // Check for same LAN segment |
115 | foreach (KeyValuePair<IPAddress, IPAddress> subnet in m_subnets) | 115 | foreach (KeyValuePair<IPAddress, IPAddress> subnet in m_subnets) |
116 | { | 116 | { |
117 | byte[] subnetBytes = subnet.Value.GetAddressBytes(); | 117 | byte[] subnetBytes = subnet.Value.GetAddressBytes(); |
118 | byte[] localBytes = subnet.Key.GetAddressBytes(); | 118 | byte[] localBytes = subnet.Key.GetAddressBytes(); |
119 | byte[] destBytes = destination.GetAddressBytes(); | 119 | byte[] destBytes = destination.GetAddressBytes(); |
120 | 120 | ||
121 | if(subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) | 121 | if(subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) |
122 | return null; | 122 | return null; |
123 | 123 | ||
124 | bool valid = true; | 124 | bool valid = true; |
125 | 125 | ||
126 | for(int i=0;i<subnetBytes.Length;i++) | 126 | for(int i=0;i<subnetBytes.Length;i++) |
127 | { | 127 | { |
128 | if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) | 128 | if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) |
129 | { | 129 | { |
130 | valid = false; | 130 | valid = false; |
131 | break; | 131 | break; |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) | 135 | if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) |
136 | valid = false; | 136 | valid = false; |
137 | 137 | ||
138 | if (valid) | 138 | if (valid) |
139 | { | 139 | { |
140 | m_log.Info("[NetworkUtil] Local LAN user detected, sending them '" + subnet.Key + "' instead of '" + defaultHostname + "'"); | 140 | m_log.Info("[NetworkUtil] Local LAN user detected, sending them '" + subnet.Key + "' instead of '" + defaultHostname + "'"); |
141 | return subnet.Key; | 141 | return subnet.Key; |
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | // Check to see if we can find a IPv4 address. | 145 | // Check to see if we can find a IPv4 address. |
146 | foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) | 146 | foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) |
147 | { | 147 | { |
148 | if (host.AddressFamily == AddressFamily.InterNetwork) | 148 | if (host.AddressFamily == AddressFamily.InterNetwork) |
149 | return host; | 149 | return host; |
150 | } | 150 | } |
151 | 151 | ||
152 | // Unable to find anything. | 152 | // Unable to find anything. |
153 | throw new ArgumentException("[NetworkUtil] Unable to resolve defaultHostname to an IPv4 address for an IPv4 client"); | 153 | throw new ArgumentException("[NetworkUtil] Unable to resolve defaultHostname to an IPv4 address for an IPv4 client"); |
154 | } | 154 | } |
155 | 155 | ||
156 | static NetworkUtil() | 156 | static NetworkUtil() |
157 | { | 157 | { |
158 | try | 158 | try |
159 | { | 159 | { |
160 | foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) | 160 | foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) |
161 | { | 161 | { |
162 | foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses) | 162 | foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses) |
163 | { | 163 | { |
164 | if (address.Address.AddressFamily == AddressFamily.InterNetwork) | 164 | if (address.Address.AddressFamily == AddressFamily.InterNetwork) |
165 | { | 165 | { |
166 | if (address.IPv4Mask != null) | 166 | if (address.IPv4Mask != null) |
167 | { | 167 | { |
168 | m_subnets.Add(address.Address, address.IPv4Mask); | 168 | m_subnets.Add(address.Address, address.IPv4Mask); |
169 | } | 169 | } |
170 | } | 170 | } |
171 | } | 171 | } |
172 | } | 172 | } |
173 | } | 173 | } |
174 | catch (NotImplementedException) | 174 | catch (NotImplementedException) |
175 | { | 175 | { |
176 | // Mono Sucks. | 176 | // Mono Sucks. |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | public static IPAddress GetIPFor(IPEndPoint user, string defaultHostname) | 180 | public static IPAddress GetIPFor(IPEndPoint user, string defaultHostname) |
181 | { | 181 | { |
182 | if (!m_disabled) | 182 | if (!m_disabled) |
183 | { | 183 | { |
184 | // Try subnet matching | 184 | // Try subnet matching |
185 | IPAddress rtn = GetExternalIPFor(user.Address, defaultHostname); | 185 | IPAddress rtn = GetExternalIPFor(user.Address, defaultHostname); |
186 | if (rtn != null) | 186 | if (rtn != null) |
187 | return rtn; | 187 | return rtn; |
188 | } | 188 | } |
189 | 189 | ||
190 | // Otherwise use the old algorithm | 190 | // Otherwise use the old algorithm |
191 | IPAddress ia; | 191 | IPAddress ia; |
192 | 192 | ||
193 | if (IPAddress.TryParse(defaultHostname, out ia)) | 193 | if (IPAddress.TryParse(defaultHostname, out ia)) |
194 | return ia; | 194 | return ia; |
195 | 195 | ||
196 | ia = null; | 196 | ia = null; |
197 | 197 | ||
198 | foreach (IPAddress Adr in Dns.GetHostAddresses(defaultHostname)) | 198 | foreach (IPAddress Adr in Dns.GetHostAddresses(defaultHostname)) |
199 | { | 199 | { |
200 | if (Adr.AddressFamily == AddressFamily.InterNetwork) | 200 | if (Adr.AddressFamily == AddressFamily.InterNetwork) |
201 | { | 201 | { |
202 | ia = Adr; | 202 | ia = Adr; |
203 | break; | 203 | break; |
204 | } | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
207 | return ia; | 207 | return ia; |
208 | } | 208 | } |
209 | 209 | ||
210 | public static string GetHostFor(IPAddress user, string defaultHostname) | 210 | public static string GetHostFor(IPAddress user, string defaultHostname) |
211 | { | 211 | { |
212 | if (!m_disabled) | 212 | if (!m_disabled) |
213 | { | 213 | { |
214 | IPAddress rtn = GetExternalIPFor(user, defaultHostname); | 214 | IPAddress rtn = GetExternalIPFor(user, defaultHostname); |
215 | if (rtn != null) | 215 | if (rtn != null) |
216 | return rtn.ToString(); | 216 | return rtn.ToString(); |
217 | } | 217 | } |
218 | return defaultHostname; | 218 | return defaultHostname; |
219 | } | 219 | } |
220 | } | 220 | } |
221 | } | 221 | } |