Example #1
0
 public void DisconnectAsync(string reason, Exception exception = null)
 {
     if (!IsConnected)
     {
         return;
     }
     if (Interlocked.CompareExchange(ref _Disconnecting, 1, 0) == 1)
     {
         return;
     }
     using (TraceCorrelation.Open())
     {
         NodeServerTrace.Information("Disconnection request " + reason);
         State = NodeState.Disconnecting;
         _Connection.Cancel.Cancel();
         if (DisconnectReason == null)
         {
             DisconnectReason = new NodeDisconnectReason()
             {
                 Reason    = reason,
                 Exception = exception
             }
         }
         ;
     }
 }
Example #2
0
        internal Node(NetworkAddress peer, NetworkInfo network, NodeConnectionParameters parameters)
        {
            parameters = parameters ?? new NodeConnectionParameters();
            var addrman = AddressManagerBehavior.GetAddrman(parameters);

            Inbound    = false;
            _Behaviors = new NodeBehaviorsCollection(this);
            _MyVersion = parameters.CreateVersion(peer.Endpoint, network);
            Network    = network;
            _Peer      = peer;
            LastSeen   = peer.Time;

            var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);

            socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);

            _Connection = new NodeConnection(this, socket);
            socket.ReceiveBufferSize = parameters.ReceiveBufferSize;
            socket.SendBufferSize    = parameters.SendBufferSize;
            using (TraceCorrelation.Open())
            {
                try
                {
                    var completed = new ManualResetEvent(false);
                    var args      = new SocketAsyncEventArgs();
                    args.RemoteEndPoint = peer.Endpoint;
                    args.Completed     += (s, a) =>
                    {
                        Utils.SafeSet(completed);
                    };
                    if (!socket.ConnectAsync(args))
                    {
                        completed.Set();
                    }
                    WaitHandle.WaitAny(new WaitHandle[] { completed, parameters.ConnectCancellation.WaitHandle });
                    parameters.ConnectCancellation.ThrowIfCancellationRequested();
                    if (args.SocketError != SocketError.Success)
                    {
                        throw new SocketException((int)args.SocketError);
                    }
                    var remoteEndpoint = (IPEndPoint)(socket.RemoteEndPoint ?? args.RemoteEndPoint);
                    _RemoteSocketAddress = remoteEndpoint.Address;
                    _RemoteSocketPort    = remoteEndpoint.Port;
                    State       = NodeState.Connected;
                    ConnectedAt = DateTimeOffset.UtcNow;
                    NodeServerTrace.Information("Outbound connection successfull");
                    if (addrman != null)
                    {
                        addrman.Attempt(Peer);
                    }
                }
                catch (OperationCanceledException)
                {
                    Utils.SafeCloseSocket(socket);
                    NodeServerTrace.Information("Connection to node cancelled");
                    State = NodeState.Offline;
                    if (addrman != null)
                    {
                        addrman.Attempt(Peer);
                    }
                    throw;
                }
                catch (Exception ex)
                {
                    Utils.SafeCloseSocket(socket);
                    NodeServerTrace.Error("Error connecting to the remote endpoint ", ex);
                    DisconnectReason = new NodeDisconnectReason()
                    {
                        Reason    = "Unexpected exception while connecting to socket",
                        Exception = ex
                    };
                    State = NodeState.Failed;
                    if (addrman != null)
                    {
                        addrman.Attempt(Peer);
                    }
                    throw;
                }
                InitDefaultBehaviors(parameters);
                _Connection.BeginListen();
            }
        }