private void ReceivedMessage(IAsyncResult result)
{
try {
if (connectionState == ConnectionState.Disconnected) {
// Connection has been closed. Ignore the message.
LoggingService.LogWarning("LocalNodeConnection: Ignored message received after connection was closed.");
return;
}
byte[] messageData = transport.EndReceiveMessage(result);
if (messageData == null)
return;
// Get the next one!
ReceiveMessage();
Message message = null;
string messageFrom = null;
try {
message = Message.Parse(transport.Network, messageData, out messageFrom);
} catch (InvalidSignatureException ex) {
if (String.IsNullOrEmpty(messageFrom) || messageFrom == remoteNodeInfo.NodeID) {
throw ex;
} else {
LoggingService.LogWarning("Ignored message with invalid signature from {0}", messageFrom);
return;
}
}
ReceivedMessageInfo info = new ReceivedMessageInfo ();
info.Connection = this;
info.Message = message;
Core.RaiseMessageReceived(info);
if (remoteNodeInfo == null) {
KeyInfo key = (KeyInfo) message.Content;
RSACryptoServiceProvider provider = new RSACryptoServiceProvider ();
provider.FromXmlString (key.Key);
string nodeID = FileFind.Common.SHA512Str(provider.ToXmlString (false));
if (nodeID.ToLower () == transport.Network.LocalNode.NodeID.ToLower ()) {
throw new Exception ("You cannot connect to yourself!");
}
if (!transport.Network.TrustedNodes.ContainsKey(nodeID)) {
bool acceptKey = transport.Network.RaiseReceivedKey (this, key);
if (acceptKey) {
TrustedNodeInfo trustedNode = new TrustedNodeInfo();
trustedNode.Identifier = String.Format("[{0}]", nodeID);
trustedNode.PublicKey = new PublicKey(key.Key);
transport.Network.AddTrustedNode(trustedNode);
Core.Settings.SyncNetworkInfoAndSave();
} else {
throw new ConnectNotTrustedException ();
}
}
if (transport.Network.TrustedNodes[nodeID].AllowConnect == false)
throw new ConnectNotAllowedException(nodeID);
foreach (LocalNodeConnection connection in transport.Network.LocalConnections) {
if (connection != this && connection.NodeRemote != null && connection.NodeRemote.NodeID == nodeID)
throw new Exception ("Already connected!");
}
remoteNodeInfo = transport.Network.TrustedNodes[nodeID];
if (!transport.Network.Nodes.ContainsKey(RemoteNodeInfo.NodeID)) {
Node node = new Node (transport.Network, RemoteNodeInfo.NodeID);
node.NickName = RemoteNodeInfo.Identifier;
node.Verified = true;
transport.Network.AddNode(node);
}
this.NodeRemote = transport.Network.Nodes[RemoteNodeInfo.NodeID];
if (transport.Incoming == true) {
this.SendMessage(transport.Network.MessageBuilder.CreateMyKeyMessage (null));
} else {
ConnectionState = ConnectionState.Authenticating;
RaiseConnectionInfoChanged ();
Message m = transport.Network.MessageBuilder.CreateAuthMessage (this, RemoteNodeInfo);
SendMessage(m);
}
} else {
ThreadPool.QueueUserWorkItem(new WaitCallback(transport.Network.ProcessMessage), info);
}
} catch (Exception ex) {
Disconnect(ex);
}
}