protected void OnConnected() { if (!IsListener && DCState == DirectConnectionState.Closed) { // Send foo DCState = DirectConnectionState.Foo; Processor.Send(new byte[] { 0x04, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x00 }); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "foo0 sent", GetType().Name); // Send NONCE DCState = DirectConnectionState.Handshake; P2PDCHandshakeMessage hm = new P2PDCHandshakeMessage(Version); hm.Guid = reply; if (Version == P2PVersion.P2PV1) { // AckSessionId is set by NONCE startupSession.IncreaseLocalIdentifier(); hm.Header.Identifier = startupSession.LocalIdentifier; } Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Sending handshake message:\r\n " + hm.ToDebugString(), GetType().Name); Processor.Send(hm.GetBytes()); DCState = DirectConnectionState.HandshakeReply; } }
private P2PDCHandshakeMessage VerifyHandshake(byte[] data) { P2PVersion authVersion = P2PVersion.P2PV1; P2PDCHandshakeMessage ret = null; if (data.Length == 48) { authVersion = P2PVersion.P2PV1; } else if (data.Length == 16) { authVersion = P2PVersion.P2PV2; } else { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Invalid handshake length, the data was: " + Encoding.ASCII.GetString(data), GetType().Name); return null; } if (authVersion != this.version) { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, String.Format("Received version is {0}, expected {1}", authVersion, this.version), GetType().Name); return null; } P2PDCHandshakeMessage incomingHandshake = new P2PDCHandshakeMessage(version); incomingHandshake.ParseBytes(data); Guid incomingGuid = incomingHandshake.Guid; if (incomingHandshake.Version == P2PVersion.P2PV1 && (P2PFlag.DirectHandshake != (incomingHandshake.V1Header.Flags & P2PFlag.DirectHandshake))) { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Handshake flag not set for v1, the flag was: " + incomingHandshake.V1Header.Flags, GetType().Name); return null; } Guid compareGuid = incomingGuid; if (needHash) { compareGuid = HashedNonceGenerator.HashNonce(compareGuid); } if (this.nonce == compareGuid) { ret = new P2PDCHandshakeMessage(version); ret.ParseBytes(data); // copy identifiers ret.Guid = compareGuid; // set new guid (hashed) ret.Header.Identifier = 0; // our id return ret; // OK this is our handshake message } return null; }
protected void OnConnected() { if (!IsListener && DCState == DirectConnectionState.Closed) { // Send foo DCState = DirectConnectionState.Foo; Processor.Send(new byte[] { 0x04, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x00 }); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "foo0 sent", GetType().Name); // Send NONCE DCState = DirectConnectionState.Handshake; P2PDCHandshakeMessage hm = new P2PDCHandshakeMessage(Version); hm.Guid = reply; if (Version == P2PVersion.P2PV1) { // AckSessionId is set by NONCE startupSession.IncreaseLocalIdentifier(); hm.Header.Identifier = startupSession.LocalIdentifier; } Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Sending handshake message:\r\n " + hm.ToDebugString(), GetType().Name); Processor.Send(hm.GetBytes()); DCState = DirectConnectionState.HandshakeReply; } }
/// <summary> /// Discards the foo message and sends the message to all handlers as a P2PDCMessage object. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void OnMessageReceived(object sender, ByteEventArgs e) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Analyzing message in DC state <" + dcState + ">", GetType().Name); byte[] data = e.Bytes; switch (dcState) { case DirectConnectionState.Established: { // Convert to a p2pdc message P2PDCMessage dcMessage = new P2PDCMessage(version); dcMessage.ParseBytes(data); OnP2PMessageReceived(new P2PMessageEventArgs(dcMessage)); } break; case DirectConnectionState.HandshakeReply: { P2PDCHandshakeMessage match = VerifyHandshake(data); if (match == null) { Dispose(); return; } Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Nonce accepted: " + match.Guid + "; My Nonce: " + this.nonce + "; Need Hash: " + needHash, GetType().Name); DCState = DirectConnectionState.Established; } break; case DirectConnectionState.Handshake: { P2PDCHandshakeMessage match = VerifyHandshake(data); if (match == null) { Dispose(); return; } Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Nonce MATCH: " + match.Guid, GetType().Name); match.Guid = reply; if (version == P2PVersion.P2PV1) { startupSession.IncreaseLocalIdentifier(); match.Header.Identifier = startupSession.LocalIdentifier; } // Send Nonce Reply SendMessage(match); DCState = DirectConnectionState.Established; } break; case DirectConnectionState.Foo: { string initialData = Encoding.ASCII.GetString(data); if (data.Length == 4 && initialData == "foo\0") { DCState = DirectConnectionState.Handshake; Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "foo0 handled", GetType().Name); } else { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "foo0 expected, but it was: " + initialData, GetType().Name); Dispose(); return; } } break; case DirectConnectionState.Closed: break; } }
private P2PDCHandshakeMessage VerifyHandshake(byte[] data) { P2PVersion authVersion = P2PVersion.P2PV1; P2PDCHandshakeMessage ret = null; if (data.Length == 48) { authVersion = P2PVersion.P2PV1; } else if (data.Length == 16) { authVersion = P2PVersion.P2PV2; } else { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Invalid handshake length, the data was: " + Encoding.ASCII.GetString(data), GetType().Name); return(null); } if (authVersion != this.version) { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, String.Format("Received version is {0}, expected {1}", authVersion, this.version), GetType().Name); return(null); } P2PDCHandshakeMessage incomingHandshake = new P2PDCHandshakeMessage(version); incomingHandshake.ParseBytes(data); Guid incomingGuid = incomingHandshake.Guid; if (incomingHandshake.Version == P2PVersion.P2PV1 && (P2PFlag.DirectHandshake != (incomingHandshake.V1Header.Flags & P2PFlag.DirectHandshake))) { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Handshake flag not set for v1, the flag was: " + incomingHandshake.V1Header.Flags, GetType().Name); return(null); } Guid compareGuid = incomingGuid; if (needHash) { compareGuid = HashedNonceGenerator.HashNonce(compareGuid); } if (this.nonce == compareGuid) { ret = new P2PDCHandshakeMessage(version); ret.ParseBytes(data); // copy identifiers ret.Guid = compareGuid; // set new guid (hashed) ret.Header.Identifier = 0; // our id return(ret); // OK this is our handshake message } return(null); }