* Instead of creating a new IPEndPoint on every udp packet receive, reuse the existing one

* This requires copying details into a new endpoint when it needs to be stored in client/circuit code hashes
0.6.0-stable
Justin Clarke Casey 2008-10-17 17:57:18 +00:00
parent e4b8912296
commit 7891f821e2
2 changed files with 41 additions and 23 deletions

View File

@ -58,7 +58,7 @@ namespace OpenSim.Framework
numBytes = x; numBytes = x;
} }
public static EndPoint DecodeProxyMessage(byte[] bytes, ref int numBytes) public static IPEndPoint DecodeProxyMessage(byte[] bytes, ref int numBytes)
{ {
// IPv4 Only // IPv4 Only
byte[] addr = new byte[4]; byte[] addr = new byte[4];
@ -71,7 +71,7 @@ namespace OpenSim.Framework
ushort port = (ushort) (bytes[--numBytes] * 256); ushort port = (ushort) (bytes[--numBytes] * 256);
port += (ushort) bytes[--numBytes]; port += (ushort) bytes[--numBytes];
return (EndPoint) new IPEndPoint(new IPAddress(addr), (int) port); return new IPEndPoint(new IPAddress(addr), (int) port);
} }
} }
} }

View File

@ -60,10 +60,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <value> /// <value>
/// The endpoint of a sender of a particular packet. The port is changed by the various socket receive methods /// The endpoint of a sender of a particular packet. The port is changed by the various socket receive methods
/// </value> /// </value>
protected EndPoint epSender; protected EndPoint reusedEpSender = new IPEndPoint(IPAddress.Any, 0);
protected EndPoint reusedEpProxy;
protected EndPoint epProxy;
protected int proxyPortOffset; protected int proxyPortOffset;
protected AsyncCallback ReceivedData; protected AsyncCallback ReceivedData;
protected LLPacketServer m_packetServer; protected LLPacketServer m_packetServer;
protected Location m_location; protected Location m_location;
@ -175,7 +175,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="result"></param> /// <param name="result"></param>
protected virtual void OnReceivedData(IAsyncResult result) protected virtual void OnReceivedData(IAsyncResult result)
{ {
epSender = new IPEndPoint(listenIP, 0);
Packet packet = null; Packet packet = null;
int numBytes = 1; int numBytes = 1;
@ -184,7 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try try
{ {
numBytes = m_socket.EndReceiveFrom(result, ref epSender); numBytes = m_socket.EndReceiveFrom(result, ref reusedEpSender);
ok = true; ok = true;
} }
catch (SocketException e) catch (SocketException e)
@ -220,10 +219,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (z = numBytes ; z < RecvBuffer.Length ; z++) for (z = numBytes ; z < RecvBuffer.Length ; z++)
RecvBuffer[z] = 0; RecvBuffer[z] = 0;
epProxy = epSender; reusedEpProxy = reusedEpSender;
if (proxyPortOffset != 0) if (proxyPortOffset != 0)
{ {
epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); reusedEpSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes);
} }
int packetEnd = numBytes - 1; int packetEnd = numBytes - 1;
@ -267,7 +266,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bool ret; bool ret;
lock (clientCircuits) lock (clientCircuits)
{ {
ret = clientCircuits.TryGetValue(epSender, out circuit); ret = clientCircuits.TryGetValue(reusedEpSender, out circuit);
} }
if (ret) if (ret)
@ -303,7 +302,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
try try
{ {
m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); m_socket.BeginReceiveFrom(
RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null);
} }
catch (SocketException e) catch (SocketException e)
{ {
@ -316,7 +316,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
try try
{ {
CloseEndPoint(epSender); CloseEndPoint(reusedEpSender);
} }
catch (Exception a) catch (Exception a)
{ {
@ -324,10 +324,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
try try
{ {
m_socket.BeginReceiveFrom(
m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null);
ReceivedData, null);
// Ter: For some stupid reason ConnectionReset basically kills our async event structure.. // Ter: For some stupid reason ConnectionReset basically kills our async event structure..
// so therefore.. we've got to tell the server to BeginReceiveFrom again. // so therefore.. we've got to tell the server to BeginReceiveFrom again.
@ -363,29 +362,48 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Slave regions don't accept new clients //Slave regions don't accept new clients
if (m_localScene.Region_Status != RegionStatus.SlaveScene) if (m_localScene.Region_Status != RegionStatus.SlaveScene)
{ {
m_log.DebugFormat("[CLIENT]: Adding new circuit for agent {0}, circuit code {1}", useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code); m_log.DebugFormat(
"[CLIENT]: Adding new circuit for agent {0}, circuit code {1}",
useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code);
// Copy the current reusedEpSender and reusedEpProxy to store in the maps and hashes,
// since the reused ones will change on the next packet receipt.
IPEndPoint reusedIpEpSender = (IPEndPoint)reusedEpSender;
EndPoint epSender = new IPEndPoint(reusedIpEpSender.Address, reusedIpEpSender.Port);
IPEndPoint reusedIpEpPorxy = (IPEndPoint)reusedEpProxy;
EndPoint epProxy = new IPEndPoint(reusedIpEpPorxy.Address, reusedIpEpPorxy.Port);
lock (clientCircuits) lock (clientCircuits)
{ {
if (!clientCircuits.ContainsKey(epSender)) if (!clientCircuits.ContainsKey(epSender))
{
clientCircuits.Add(epSender, useCircuit.CircuitCode.Code); clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
}
else else
m_log.Error("[CLIENT]: clientCircuits already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding."); {
m_log.Error(
"[CLIENT]: clientCircuits already contains entry for user "
+ useCircuit.CircuitCode.Code + ". NOT adding.");
}
} }
// This doesn't need locking as it's synchronized data // This doesn't need locking as it's synchronized data
if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender); clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender);
else else
m_log.Error("[CLIENT]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding."); m_log.Error(
"[CLIENT]: clientCurcuits_reverse already contains entry for user "
+ useCircuit.CircuitCode.Code + ". NOT adding.");
lock (proxyCircuits) lock (proxyCircuits)
{ {
if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code)) if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy); proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy);
else else
m_log.Error("[CLIENT]: proxyCircuits already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding."); m_log.Error(
"[CLIENT]: proxyCircuits already contains entry for user "
+ useCircuit.CircuitCode.Code + ". NOT adding.");
} }
if (!PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_circuitManager, epProxy)) if (!PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_circuitManager, epProxy))
@ -416,9 +434,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.Info("[UDPSERVER]: UDP socket bound, getting ready to listen"); m_log.Info("[UDPSERVER]: UDP socket bound, getting ready to listen");
epSender = new IPEndPoint(listenIP, 0);
ReceivedData = OnReceivedData; ReceivedData = OnReceivedData;
m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); m_socket.BeginReceiveFrom(
RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null);
m_log.Info("[UDPSERVER]: Listening on port " + newPort); m_log.Info("[UDPSERVER]: Listening on port " + newPort);
} }