private void EndAccept(SocketAsyncEventArgs args) { using (_Trace.Open()) { Socket client = null; try { if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } client = args.AcceptSocket; if (_Cancel.IsCancellationRequested) { return; } NodeServerTrace.Information("Client connection accepted : " + client.RemoteEndPoint); var cancel = CancellationTokenSource.CreateLinkedTokenSource(_Cancel.Token); cancel.CancelAfter(TimeSpan.FromSeconds(10)); var stream = new NetworkStream(client, false); while (true) { cancel.Token.ThrowIfCancellationRequested(); PerformanceCounter counter; var message = Message.ReadNext(stream, Network, Version, cancel.Token, out counter); _MessageProducer.PushMessage(new IncomingMessage() { Socket = client, Message = message, Length = counter.ReadenBytes, Node = null, }); if (message.Payload is VersionPayload) { break; } else { NodeServerTrace.Error("The first message of the remote peer did not contained a Version payload", null); } } } catch (OperationCanceledException) { Utils.SafeCloseSocket(client); if (!_Cancel.Token.IsCancellationRequested) { NodeServerTrace.Error("The remote connecting failed to send a message within 10 seconds, dropping connection", null); } } catch (Exception ex) { if (_Cancel.IsCancellationRequested) { return; } if (client == null) { NodeServerTrace.Error("Error while accepting connection ", ex); Thread.Sleep(3000); } else { Utils.SafeCloseSocket(client); NodeServerTrace.Error("Invalid message received from the remote connecting node", ex); } } BeginAccept(); } }
internal void StartConnecting() { if (_Disconnect.IsCancellationRequested) { return; } if (_ConnectedNodes.Count >= MaximumNodeConnection) { return; } if (_Connecting) { return; } Task.Factory.StartNew(() => { if (Monitor.TryEnter(cs)) { _Connecting = true; TraceCorrelationScope scope = null; try { while (!_Disconnect.IsCancellationRequested && _ConnectedNodes.Count < MaximumNodeConnection) { scope = scope ?? _Trace.Open(); NodeServerTrace.Information("Connected nodes : " + _ConnectedNodes.Count + "/" + MaximumNodeConnection); var parameters = _ConnectionParameters.Clone(); parameters.TemplateBehaviors.Add(new NodesGroupBehavior(this)); parameters.ConnectCancellation = _Disconnect.Token; var addrman = AddressManagerBehavior.GetAddrman(parameters); if (addrman == null) { addrman = _DefaultAddressManager; AddressManagerBehavior.SetAddrman(parameters, addrman); } Node node = null; try { node = Node.Connect(_Network, parameters, AllowSameGroup ? null : _ConnectedNodes.Select(n => n.RemoteSocketAddress).ToArray()); var timeout = CancellationTokenSource.CreateLinkedTokenSource(_Disconnect.Token); timeout.CancelAfter(5000); node.VersionHandshake(_Requirements, timeout.Token); NodeServerTrace.Information("Node successfully connected to and handshaked"); } catch (OperationCanceledException ex) { if (_Disconnect.Token.IsCancellationRequested) { throw; } NodeServerTrace.Error("Timeout for picked node", ex); if (node != null) { node.DisconnectAsync("Handshake timeout", ex); } } catch (Exception ex) { NodeServerTrace.Error("Error while connecting to node", ex); if (node != null) { node.DisconnectAsync("Error while connecting", ex); } } } } finally { Monitor.Exit(cs); _Connecting = false; if (scope != null) { scope.Dispose(); } } } }, TaskCreationOptions.LongRunning); }