/// <summary>Create a local peer and start connecting to an active remote host.</summary> /// <param name="remote">Remote address to connect to.</param> /// <param name="config">Peer configuration values. If null, default is used.</param> /// <param name="listener">Peer listener to use. If null, <see cref="PeerEvents"/> is used.</param> /// <param name="message">Connect message to use.</param> /// <returns>Local peer that attempts to connect.</returns> public Peer Connect(IPEndPoint remote, PeerConfig config, IPeerListener listener, IWritable message = null) { // Validate if (Disposed) { throw new ObjectDisposedException(GetType().FullName); } else if (remote == null) { throw new ArgumentNullException(nameof(remote), "Remote connect address is null"); } // Map address if (remote.AddressFamily != Socket.AddressFamily) { if (remote.AddressFamily == AddressFamily.InterNetwork) { remote = new IPEndPoint(remote.Address.MapToIPv6(), remote.Port); } else if (remote.Address.IsIPv4MappedToIPv6) { remote = new IPEndPoint(remote.Address.MapToIPv4(), remote.Port); } else { throw new ArgumentException(string.Format("Bad peer address {0}", remote), nameof(remote)); } } // Create peer Peer peer = null; try { PeersLock.EnterWriteLock(); Peers.TryGetValue(remote, out peer); if (peer == null || peer.Disposed) { peer = new Peer(this, remote, config, listener); Peers[remote] = peer; } else { // Peer already exists } } finally { PeersLock.ExitWriteLock(); } // Start connecting peer.Connect(message); // Return peer return(peer); }
/// <summary>Accept a connection request and return a connected local peer.</summary> /// <param name="request">Connection request to accept.</param> /// <param name="config">Peer configuration values. If null, default is used.</param> /// <param name="listener">Peer listener to use. If null, event based listener is created.</param> /// <returns>Connected local peer.</returns> public Peer Accept(ConnectionRequest request, PeerConfig config, IPeerListener listener) { // Validate request if (Disposed) { throw new ObjectDisposedException(GetType().FullName); } else if (request == null) { throw new ArgumentNullException(nameof(request), "Connection request is null"); } else if (request.Host != this) { throw new ArgumentException("Connection request host mismatch", nameof(request)); } else if (request.Disposed) { throw new InvalidOperationException(string.Format( "Connection request from {0} is disposed", request.Remote )); } else if (config.RemotePublicKey != null) { throw new ArgumentException(string.Format( "Connection request from {0} cannot be authenticated", request.Remote ), nameof(config)); } else if (request.Key.Count > 0 && request.Key.Count != ExchangerKeyLength) { throw new InvalidOperationException(string.Format( "Connection request from {0} has {1} exchanger bytes", request.Remote, request.Key.Count )); } else if (request.Random.Count > 0 && request.Random.Count != Authenticator.SignatureLength) { throw new InvalidOperationException(string.Format( "Connection request from {0} has {1} random bytes", request.Remote, request.Random.Count )); } else if (request.Random.Count > 0 && Config.PrivateKey == null) { throw new InvalidOperationException(string.Format( "Connection request from {0} has authentication", request.Remote )); } // Create peer Peer peer = null; try { PeersLock.EnterWriteLock(); Peers.TryGetValue(request.Remote, out peer); if (peer == null || peer.Disposed) { peer = new Peer(this, request.Remote, config, listener); Peers[request.Remote] = peer; } else { // Peer already exists } } finally { PeersLock.ExitWriteLock(); } // Accept the request peer.Accept(request); // Return peer return(peer); }
/// <summary>Accept the request, create a new peer and establish a connection.</summary> /// <param name="config">Peer configuration values. If null, default is used.</param> /// <param name="listener">Peer listener. If null, event based listener is created.</param> /// <returns>The created peer.</returns> public Peer Accept(PeerConfig config, IPeerListener listener) { return(Host.Accept(this, config, listener)); }