diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 0030dee..7171974 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -107,6 +107,62 @@ namespace OpenMetaverse | |||
107 | /// </summary> | 107 | /// </summary> |
108 | public float AverageReceiveTicksForLastSamplePeriod { get; private set; } | 108 | public float AverageReceiveTicksForLastSamplePeriod { get; private set; } |
109 | 109 | ||
110 | #region PacketDropDebugging | ||
111 | /// <summary> | ||
112 | /// For debugging purposes only... random number generator for dropping | ||
113 | /// outbound packets. | ||
114 | /// </summary> | ||
115 | private Random m_dropRandomGenerator = new Random(); | ||
116 | |||
117 | /// <summary> | ||
118 | /// For debugging purposes only... parameters for a simplified | ||
119 | /// model of packet loss with bursts, overall drop rate should | ||
120 | /// be roughly 1 - m_dropLengthProbability / (m_dropProbabiliy + m_dropLengthProbability) | ||
121 | /// which is about 1% for parameters 0.0015 and 0.15 | ||
122 | /// </summary> | ||
123 | private double m_dropProbability = 0.0030; | ||
124 | private double m_dropLengthProbability = 0.15; | ||
125 | private bool m_dropState = false; | ||
126 | |||
127 | /// <summary> | ||
128 | /// For debugging purposes only... parameters to control the time | ||
129 | /// duration over which packet loss bursts can occur, if no packets | ||
130 | /// have been sent for m_dropResetTicks milliseconds, then reset the | ||
131 | /// state of the packet dropper to its default. | ||
132 | /// </summary> | ||
133 | private int m_dropLastTick = 0; | ||
134 | private int m_dropResetTicks = 500; | ||
135 | |||
136 | /// <summary> | ||
137 | /// Debugging code used to simulate dropped packets with bursts | ||
138 | /// </summary> | ||
139 | private bool DropOutgoingPacket() | ||
140 | { | ||
141 | double rnum = m_dropRandomGenerator.NextDouble(); | ||
142 | |||
143 | // if the connection has been idle for awhile (more than m_dropResetTicks) then | ||
144 | // reset the state to the default state, don't continue a burst | ||
145 | int curtick = Util.EnvironmentTickCount(); | ||
146 | if (Util.EnvironmentTickCountSubtract(curtick, m_dropLastTick) > m_dropResetTicks) | ||
147 | m_dropState = false; | ||
148 | |||
149 | m_dropLastTick = curtick; | ||
150 | |||
151 | // if we are dropping packets, then the probability of dropping | ||
152 | // this packet is the probability that we stay in the burst | ||
153 | if (m_dropState) | ||
154 | { | ||
155 | m_dropState = (rnum < (1.0 - m_dropLengthProbability)) ? true : false; | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | m_dropState = (rnum < m_dropProbability) ? true : false; | ||
160 | } | ||
161 | |||
162 | return m_dropState; | ||
163 | } | ||
164 | #endregion PacketDropDebugging | ||
165 | |||
110 | /// <summary> | 166 | /// <summary> |
111 | /// Default constructor | 167 | /// Default constructor |
112 | /// </summary> | 168 | /// </summary> |
@@ -117,6 +173,10 @@ namespace OpenMetaverse | |||
117 | { | 173 | { |
118 | m_localBindAddress = bindAddress; | 174 | m_localBindAddress = bindAddress; |
119 | m_udpPort = port; | 175 | m_udpPort = port; |
176 | |||
177 | // for debugging purposes only, initializes the random number generator | ||
178 | // used for simulating packet loss | ||
179 | // m_dropRandomGenerator = new Random(); | ||
120 | } | 180 | } |
121 | 181 | ||
122 | /// <summary> | 182 | /// <summary> |
@@ -135,7 +195,7 @@ namespace OpenMetaverse | |||
135 | /// manner (not throwing an exception when the remote side resets the | 195 | /// manner (not throwing an exception when the remote side resets the |
136 | /// connection). This call is ignored on Mono where the flag is not | 196 | /// connection). This call is ignored on Mono where the flag is not |
137 | /// necessary</remarks> | 197 | /// necessary</remarks> |
138 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 198 | public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
139 | { | 199 | { |
140 | m_asyncPacketHandling = asyncPacketHandling; | 200 | m_asyncPacketHandling = asyncPacketHandling; |
141 | 201 | ||
@@ -158,6 +218,17 @@ namespace OpenMetaverse | |||
158 | 218 | ||
159 | try | 219 | try |
160 | { | 220 | { |
221 | if (m_udpSocket.Ttl < 128) | ||
222 | { | ||
223 | m_udpSocket.Ttl = 128; | ||
224 | } | ||
225 | } | ||
226 | catch (SocketException) | ||
227 | { | ||
228 | m_log.Debug("[UDPBASE]: Failed to increase default TTL"); | ||
229 | } | ||
230 | try | ||
231 | { | ||
161 | // This udp socket flag is not supported under mono, | 232 | // This udp socket flag is not supported under mono, |
162 | // so we'll catch the exception and continue | 233 | // so we'll catch the exception and continue |
163 | m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null); | 234 | m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null); |
@@ -168,6 +239,12 @@ namespace OpenMetaverse | |||
168 | m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); | 239 | m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); |
169 | } | 240 | } |
170 | 241 | ||
242 | // On at least Mono 3.2.8, multiple UDP sockets can bind to the same port by default. At the moment | ||
243 | // we never want two regions to listen on the same port as they cannot demultiplex each other's messages, | ||
244 | // leading to a confusing bug. | ||
245 | // By default, Windows does not allow two sockets to bind to the same port. | ||
246 | m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); | ||
247 | |||
171 | if (recvBufferSize != 0) | 248 | if (recvBufferSize != 0) |
172 | m_udpSocket.ReceiveBufferSize = recvBufferSize; | 249 | m_udpSocket.ReceiveBufferSize = recvBufferSize; |
173 | 250 | ||
@@ -185,14 +262,14 @@ namespace OpenMetaverse | |||
185 | /// <summary> | 262 | /// <summary> |
186 | /// Start outbound UDP packet handling. | 263 | /// Start outbound UDP packet handling. |
187 | /// </summary> | 264 | /// </summary> |
188 | public void StartOutbound() | 265 | public virtual void StartOutbound() |
189 | { | 266 | { |
190 | m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); | 267 | m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); |
191 | 268 | ||
192 | IsRunningOutbound = true; | 269 | IsRunningOutbound = true; |
193 | } | 270 | } |
194 | 271 | ||
195 | public void StopInbound() | 272 | public virtual void StopInbound() |
196 | { | 273 | { |
197 | if (IsRunningInbound) | 274 | if (IsRunningInbound) |
198 | { | 275 | { |
@@ -203,14 +280,14 @@ namespace OpenMetaverse | |||
203 | } | 280 | } |
204 | } | 281 | } |
205 | 282 | ||
206 | public void StopOutbound() | 283 | public virtual void StopOutbound() |
207 | { | 284 | { |
208 | m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); | 285 | m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); |
209 | 286 | ||
210 | IsRunningOutbound = false; | 287 | IsRunningOutbound = false; |
211 | } | 288 | } |
212 | 289 | ||
213 | protected virtual bool EnablePools() | 290 | public virtual bool EnablePools() |
214 | { | 291 | { |
215 | if (!UsePools) | 292 | if (!UsePools) |
216 | { | 293 | { |
@@ -224,7 +301,7 @@ namespace OpenMetaverse | |||
224 | return false; | 301 | return false; |
225 | } | 302 | } |
226 | 303 | ||
227 | protected virtual bool DisablePools() | 304 | public virtual bool DisablePools() |
228 | { | 305 | { |
229 | if (UsePools) | 306 | if (UsePools) |
230 | { | 307 | { |
@@ -389,6 +466,12 @@ namespace OpenMetaverse | |||
389 | { | 466 | { |
390 | // if (IsRunningOutbound) | 467 | // if (IsRunningOutbound) |
391 | // { | 468 | // { |
469 | |||
470 | // This is strictly for debugging purposes to simulate dropped | ||
471 | // packets when testing throttles & retransmission code | ||
472 | // if (DropOutgoingPacket()) | ||
473 | // return; | ||
474 | |||
392 | try | 475 | try |
393 | { | 476 | { |
394 | m_udpSocket.BeginSendTo( | 477 | m_udpSocket.BeginSendTo( |