aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs95
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(