protected Cmd ReadCommand() { lock (input) { Cmd c = ReadCommand0(); if (c.Type != TorControl.Commands.Fragment && c.Type != TorControl.Commands.FragmentHeader) return c; if (c.Type == TorControl.Commands.Fragment) throw new TorControlSyntaxException("Fragment without header"); int realType = Bytes.GetU16(c.Body, 0); int realLen = Bytes.GetU32(c.Body, 2); Cmd outCmd = new Cmd((TorControl.Commands)realType, realLen); Array.Copy(c.Body, 6, outCmd.Body, 0, c.Body.Length - 6); int pos = c.Body.Length-6; while (pos < realLen) { c = ReadCommand0(); if (c.Type != TorControl.Commands.Fragment) throw new TorControlSyntaxException("Incomplete fragmented message"); Array.Copy(c.Body, 0, outCmd.Body, pos, c.Body.Length); pos += c.Body.Length; } return outCmd; } }
protected void HandleEvent(Cmd c) { TorControl.Event type = (TorControl.Event)Bytes.GetU16(c.Body, 0); switch (type) { case TorControl.Event.CircSatus: if (this.CircuitStatus != null) { CircuitStatusEventArgs args; args = new CircuitStatusEventArgs(TorControl.StreamStatusNames[c.Body[2]], Bytes.GetU32S(c.Body, 3), Bytes.GetNulTerminatedStr(c.Body, 7)); CircuitStatus(this, args); } break; case TorControl.Event.StreamStatus: if (this.StreamStatus != null) { StreamStatusEventArgs args; args = new StreamStatusEventArgs(TorControl.StreamStatusNames[c.Body[2]], Bytes.GetU32S(c.Body, 3).ToString(), Bytes.GetNulTerminatedStr(c.Body, 7)); StreamStatus(this, args); } break; case TorControl.Event.OrConnStatus: if (this.OrConnStatus != null) { OrConnStatusEventArgs args; args = new OrConnStatusEventArgs(TorControl.ORConnStatusNames[c.Body[2]], Bytes.GetNulTerminatedStr(c.Body, 3)); OrConnStatus(this, args); } break; case TorControl.Event.Bandwidth: if (this.BandwidthUsed != null) { BandwidthUsedEventArgs args; args = new BandwidthUsedEventArgs(Bytes.GetU32(c.Body, 2), Bytes.GetU32(c.Body, 6)); BandwidthUsed(this, args); } break; case TorControl.Event.NewDescriptor: if (this.NewDescriptors != null) { IList lst = new ArrayList(); Bytes.SplitStr(lst, c.Body, 2, (byte)','); NewDescriptorsEventArgs args; args = new NewDescriptorsEventArgs(lst); NewDescriptors(this, args); } break; case TorControl.Event.MsgDebug: if (this.Message != null) { MessageEventArgs args; args = new MessageEventArgs("DEBUG", Bytes.GetNulTerminatedStr(c.Body, 2)); Message(this, args); } break; case TorControl.Event.MsgInfo: if (this.Message != null) { MessageEventArgs args; args = new MessageEventArgs("INFO", Bytes.GetNulTerminatedStr(c.Body, 2)); Message(this, args); } break; case TorControl.Event.MsgNotice: if (this.Message != null) { MessageEventArgs args; args = new MessageEventArgs("NOTICE", Bytes.GetNulTerminatedStr(c.Body, 2)); Message(this, args); } break; case TorControl.Event.MsgWarn: if (this.Message != null) { MessageEventArgs args; args = new MessageEventArgs("WARN", Bytes.GetNulTerminatedStr(c.Body, 2)); Message(this, args); } break; case TorControl.Event.MsgError: if (this.Message != null) { MessageEventArgs args; args = new MessageEventArgs("ERR", Bytes.GetNulTerminatedStr(c.Body, 2)); Message(this, args); } break; default: if (this.Unrecognized != null) { // TODO: Check if this is practicable UnrecognizedEventArgs args; args = new UnrecognizedEventArgs("UNKNOWN", Bytes.GetNulTerminatedStr(c.Body, 3)); Unrecognized(this, args); } break; } }