Applied patch #1759 - SLProxy bugfixes / improvements

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@771 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
otakup0pe
2006-12-28 21:36:10 +00:00
parent 1f037a1287
commit 0db5d7d2a0
2 changed files with 94 additions and 96 deletions

View File

@@ -70,7 +70,6 @@ public class Analyst
proxy.SetLoginResponseDelegate(new XmlRpcResponseDelegate(LoginResponse));
// add a delegate for outgoing chat
proxy.AddDelegate(PacketType.ChatFromViewer, Direction.Incoming, new PacketDelegate(ChatFromViewerIn));
proxy.AddDelegate(PacketType.ChatFromViewer, Direction.Outgoing, new PacketDelegate(ChatFromViewerOut));
// handle command line arguments
@@ -110,17 +109,6 @@ public class Analyst
}
}
// ChatFromViewerIn: incoming ChatFromViewer delegate; shouldn't be possible, but just in case...
private static Packet ChatFromViewerIn(Packet packet, IPEndPoint sim)
{
if (loggedPackets.Contains(PacketType.ChatFromViewer) || modifiedPackets.Contains(PacketType.ChatFromViewer))
// user has asked to log or modify this packet
return Analyze(packet, sim, Direction.Incoming);
else
// return the packet unmodified
return packet;
}
// ChatFromViewerOut: outgoing ChatFromViewer delegate; check for Analyst commands
private static Packet ChatFromViewerOut(Packet packet, IPEndPoint sim)
{
@@ -138,13 +126,8 @@ public class Analyst
return null;
}
}
if (loggedPackets.Contains(PacketType.ChatFromViewer) || modifiedPackets.Contains(PacketType.ChatFromViewer))
// user has asked to log or modify this packet
return Analyze(packet, sim, Direction.Outgoing);
else
// return the packet unmodified
return packet;
return packet;
}
// CommandDelegate: specifies a callback delegate for a /command
@@ -193,11 +176,8 @@ public class Analyst
return;
}
loggedPackets[pType] = null;
if (words[1] != "ChatFromViewer")
{
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(AnalyzeIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(AnalyzeOut));
}
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
SayToUser("logging " + words[1]);
}
}
@@ -217,15 +197,8 @@ public class Analyst
PacketType pType = packetTypeFromName(words[1]);
loggedPackets.Remove(pType);
if (!modifiedPackets.Contains(words[1]))
{
if (words[1] != "ChatFromViewer")
{
proxy.RemoveDelegate(pType, Direction.Incoming);
proxy.RemoveDelegate(pType, Direction.Outgoing);
}
}
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
SayToUser("stopped logging " + words[1]);
}
}
@@ -284,11 +257,8 @@ public class Analyst
fields[new BlockField(words[2], words[3])] = value;
modifiedPackets[pType] = fields;
if (words[1] != "ChatFromViewer")
{
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(AnalyzeIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(AnalyzeOut));
}
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
SayToUser("setting " + words[1] + "." + words[2] + "." + words[3] + " = " + valueString);
}
@@ -300,10 +270,9 @@ public class Analyst
if (words.Length == 2 && words[1] == "*")
{
foreach (PacketType pType in modifiedPackets.Keys)
if (!loggedPackets.Contains(pType) && pType != PacketType.ChatFromViewer)
{
proxy.RemoveDelegate(pType, Direction.Incoming);
proxy.RemoveDelegate(pType, Direction.Outgoing);
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
}
modifiedPackets = new Hashtable();
@@ -332,14 +301,8 @@ public class Analyst
{
modifiedPackets.Remove(pType);
if (!loggedPackets.Contains(pType))
{
if (words[1] != "ChatFromViewer")
{
proxy.RemoveDelegate(pType, Direction.Incoming);
proxy.RemoveDelegate(pType, Direction.Outgoing);
}
}
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
}
}
@@ -410,21 +373,36 @@ public class Analyst
ConstructorInfo ctr = packetClass.GetConstructor(new Type[] { });
if (ctr == null) throw new Exception("Couldn't get suitable constructor for " + name + "Packet");
packet = (Packet)ctr.Invoke(new object[] { });
Console.WriteLine("Created new " + name + "Packet");
//Console.WriteLine("Created new " + name + "Packet");
}
else
{
match = (new Regex(@"^\s*\[(\w+)\]\s*$")).Match(line);
if (match.Success)
{
//FIXME: support variable blocks
block = match.Groups[1].Captures[0].ToString();
FieldInfo blockField = packetClass.GetField(block);
if (blockField == null) throw new Exception("Couldn't get " + name + "Packet." + block);
blockObj = blockField.GetValue(packet);
Type blockClass = blockField.FieldType;
if (blockClass.IsArray)
{
blockClass = blockClass.GetElementType();
ConstructorInfo ctr = blockClass.GetConstructor(new Type[] { });
if (ctr == null) throw new Exception("Couldn't get suitable constructor for " + blockClass.Name);
blockObj = ctr.Invoke(new object[] { });
object[] arr = (object[])blockField.GetValue(packet);
object[] narr = (object[])Array.CreateInstance(blockClass, arr.Length + 1);
Array.Copy(arr,narr,arr.Length);
narr[arr.Length] = blockObj;
blockField.SetValue(packet,narr);
//Console.WriteLine("Added block "+block);
}
else
{
blockObj = blockField.GetValue(packet);
}
if (blockObj == null) throw new Exception("Got " + name + "Packet." + block + " == null");
Console.WriteLine("Got block " + name + "Packet." + block);
//Console.WriteLine("Got block " + name + "Packet." + block);
continue;
}
@@ -543,20 +521,12 @@ public class Analyst
{
Type packetClass = libslAssembly.GetType("libsecondlife.Packets." + name + "Packet");
if (packetClass == null) throw new Exception("Couldn't get class " + name + "Packet");
/* try {
packetMap = protocolManager.Command(name);
} catch {
throw new Exception("unkown packet " + name);
} */
//FIXME: support variable blocks
FieldInfo blockField = packetClass.GetField(block);
if (blockField == null) throw new Exception("Couldn't get " + name + "Packet." + block);
Type blockClass = blockField.FieldType;
if (blockClass.IsArray) blockClass = blockClass.GetElementType();
Console.WriteLine("DEBUG: " + blockClass.Name);
// Console.WriteLine("DEBUG: " + blockClass.Name);
FieldInfo fieldField = blockClass.GetField(field); PropertyInfo fieldProp = null;
Type fieldClass = null;
@@ -719,20 +689,20 @@ public class Analyst
throw new Exception("unknown block " + name + "." + block); */
}
// AnalyzeIn: analyze an incoming packet
private static Packet AnalyzeIn(Packet packet, IPEndPoint endPoint)
// ModifyIn: modify an incoming packet
private static Packet ModifyIn(Packet packet, IPEndPoint endPoint)
{
return Analyze(packet, endPoint, Direction.Incoming);
return Modify(packet, endPoint, Direction.Incoming);
}
// AnalyzeOut: analyze an outgoing packet
private static Packet AnalyzeOut(Packet packet, IPEndPoint endPoint)
// ModifyOut: modify an outgoing packet
private static Packet ModifyOut(Packet packet, IPEndPoint endPoint)
{
return Analyze(packet, endPoint, Direction.Outgoing);
return Modify(packet, endPoint, Direction.Outgoing);
}
// Analyze: modify and/or log a packet
private static Packet Analyze(Packet packet, IPEndPoint endPoint, Direction direction)
// Modify: modify a packet
private static Packet Modify(Packet packet, IPEndPoint endPoint, Direction direction)
{
if (modifiedPackets.Contains(packet.Type))
{
@@ -758,9 +728,20 @@ public class Analyst
}
}
if (loggedPackets.Contains(packet.Type))
LogPacket(packet, endPoint, direction);
return packet;
}
// LogPacketIn: log an incoming packet
private static Packet LogPacketIn(Packet packet, IPEndPoint endPoint)
{
LogPacket(packet, endPoint, Direction.Incoming);
return packet;
}
// LogPacketOut: log an outgoing packet
private static Packet LogPacketOut(Packet packet, IPEndPoint endPoint)
{
LogPacket(packet, endPoint, Direction.Outgoing);
return packet;
}
@@ -788,11 +769,8 @@ public class Analyst
loggedPackets[pType] = null;
if (pType != PacketType.ChatFromViewer)
{
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(AnalyzeIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(AnalyzeOut));
}
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
}
}
}
@@ -821,11 +799,8 @@ public class Analyst
loggedPackets.Remove(pType);
if (pType != PacketType.ChatFromViewer)
{
proxy.RemoveDelegate(pType, Direction.Incoming);
proxy.RemoveDelegate(pType, Direction.Outgoing);
}
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
}
}
}

View File

@@ -208,14 +208,39 @@ namespace SLProxy {
// AddDelegate: add callback packetDelegate for packets of type packetName going direction
public void AddDelegate(PacketType packetType, Direction direction, PacketDelegate packetDelegate) { lock(this) {
(direction == Direction.Incoming ? incomingDelegates : outgoingDelegates)[packetType] = packetDelegate;
Dictionary<PacketType, List<PacketDelegate>> delegates = (direction == Direction.Incoming ? incomingDelegates : outgoingDelegates);
if (!delegates.ContainsKey(packetType)) {
delegates[packetType] = new List<PacketDelegate>();
}
List<PacketDelegate> delegateArray = delegates[packetType];
if(!delegateArray.Contains(packetDelegate)) {
delegateArray.Add(packetDelegate);
}
}}
// RemoveDelegate: remove callback for packets of type packetName going direction
public void RemoveDelegate(PacketType packetType, Direction direction) { lock(this) {
(direction == Direction.Incoming ? incomingDelegates : outgoingDelegates).Remove(packetType);
public void RemoveDelegate(PacketType packetType, Direction direction, PacketDelegate packetDelegate) { lock(this) {
Dictionary<PacketType, List<PacketDelegate>> delegates = (direction == Direction.Incoming ? incomingDelegates : outgoingDelegates);
if (!delegates.ContainsKey(packetType)) {
return;
}
List<PacketDelegate> delegateArray = delegates[packetType];
if(delegateArray.Contains(packetDelegate)) {
delegateArray.Remove(packetDelegate);
}
}}
private Packet callDelegates(Dictionary<PacketType, List<PacketDelegate>> delegates, Packet packet, IPEndPoint remoteEndPoint) {
PacketType origType = packet.Type;
foreach (PacketDelegate del in delegates[origType]) {
packet = del(packet, remoteEndPoint);
// FIXME: how should we handle the packet type changing?
if(packet == null || packet.Type != origType) break;
}
return packet;
}
// InjectPacket: send packet to the client or server when direction is Incoming or Outgoing, respectively
public void InjectPacket(Packet packet, Direction direction) { lock(this) {
if (activeCircuit == null) {
@@ -376,8 +401,8 @@ namespace SLProxy {
private Hashtable proxyHandlers = new Hashtable();
private XmlRpcRequestDelegate loginRequestDelegate = null;
private XmlRpcResponseDelegate loginResponseDelegate = null;
private Hashtable incomingDelegates = new Hashtable();
private Hashtable outgoingDelegates = new Hashtable();
private Dictionary<PacketType, List<PacketDelegate>> incomingDelegates = new Dictionary<PacketType, List<PacketDelegate>>();
private Dictionary<PacketType, List<PacketDelegate>> outgoingDelegates = new Dictionary<PacketType, List<PacketDelegate>>();
private ArrayList queuedIncomingInjections = new ArrayList();
private ArrayList queuedOutgoingInjections = new ArrayList();
@@ -452,7 +477,7 @@ namespace SLProxy {
}
// pass the packet to any callback delegates
if (incomingDelegates.Contains(packet.Type)) {
if (incomingDelegates.ContainsKey(packet.Type)) {
/* if (needsZero) {
length = Helpers.ZeroDecode(packet.Header.Data, length, zeroBuffer);
packet.Header.Data = zeroBuffer;
@@ -466,7 +491,7 @@ namespace SLProxy {
}
try {
Packet newPacket = ((PacketDelegate)incomingDelegates[packet.Type])(packet, (IPEndPoint)remoteEndPoint);
Packet newPacket = callDelegates(incomingDelegates, packet, (IPEndPoint)remoteEndPoint);
if (newPacket == null) {
if ((packet.Header.Flags & Helpers.MSG_RELIABLE) != 0)
simProxy.Inject(SpoofAck(oldSequence), Direction.Outgoing);
@@ -766,7 +791,7 @@ namespace SLProxy {
}
// pass the packet to any callback delegates
if (proxy.outgoingDelegates.Contains(packet.Type)) {
if (proxy.outgoingDelegates.ContainsKey(packet.Type)) {
/* if (packet.Header.Zerocoded) {
length = Helpers.ZeroDecode(packet.Header.Data, length, zeroBuffer);
packet.Header.Data = zeroBuffer;
@@ -780,7 +805,7 @@ namespace SLProxy {
}
try {
Packet newPacket = ((PacketDelegate)proxy.outgoingDelegates[packet.Type])(packet, remoteEndPoint);
Packet newPacket = proxy.callDelegates(proxy.outgoingDelegates, packet, remoteEndPoint);
if (newPacket == null) {
if ((packet.Header.Flags & Helpers.MSG_RELIABLE) != 0)
Inject(proxy.SpoofAck(oldSequence), Direction.Incoming);
@@ -952,10 +977,8 @@ namespace SLProxy {
#endif
}
if (ackCount == 0) {
byte[] newData = new byte[length -= 1];
Array.Copy(packet.Header.Data, 0, newData, 0, length);
newData[0] ^= Helpers.MSG_APPENDED_ACKS;
packet.Header.Data = newData;
packet.Header.Flags ^= Helpers.MSG_APPENDED_ACKS;
packet.Header.AckList = new uint[0];
}
}