Beispiel #1
0
        private async ValueTask AddConnectionAsync(IConnection connection, OmniAddress address, ConnectionHandshakeType handshakeType, CancellationToken cancellationToken = default)
        {
            var status = new ConnectionStatus(connection, address, handshakeType);

            var myNodeProflie = new NodeProfile(await _connectionController.GetListenEndpointsAsync(cancellationToken));

            var myHelloMessage = new NodeExplorerHelloMessage(_myId, myNodeProflie);
            NodeExplorerHelloMessage?otherHelloMessage = null;

            var enqueueTask = connection.EnqueueAsync((bufferWriter) => myNodeProflie.Export(bufferWriter, _bytesPool), cancellationToken);
            var dequeueTask = connection.DequeueAsync((sequence) => otherHelloMessage = NodeExplorerHelloMessage.Import(sequence, _bytesPool), cancellationToken);

            await ValueTaskHelper.WhenAll(enqueueTask, dequeueTask);

            if (otherHelloMessage == null)
            {
                return;
            }

            status.Id          = otherHelloMessage.Id;
            status.NodeProfile = otherHelloMessage.NodeProfile;

            lock (_lockObject)
            {
                _connections.Add(status);
            }
        }
Beispiel #2
0
            public TcpProxyOptions Deserialize(global::Omnix.Serialization.RocketPack.RocketPackReader r, int rank)
            {
                if (rank > 256)
                {
                    throw new global::System.FormatException();
                }

                uint propertyCount = r.GetUInt32();

                TcpProxyType p_type    = (TcpProxyType)0;
                OmniAddress  p_address = OmniAddress.Empty;

                for (; propertyCount > 0; propertyCount--)
                {
                    uint id = r.GetUInt32();
                    switch (id)
                    {
                    case 0:
                    {
                        p_type = (TcpProxyType)r.GetUInt64();
                        break;
                    }

                    case 1:
                    {
                        p_address = OmniAddress.Formatter.Deserialize(r, rank + 1);
                        break;
                    }
                    }
                }

                return(new TcpProxyOptions(p_type, p_address));
            }
Beispiel #3
0
    public static async ValueTask <ServiceManager> CreateAsync(OmniAddress listenAddress, CancellationToken cancellationToken = default)
    {
        var result = new ServiceManager(listenAddress);
        await result.InitAsync(cancellationToken);

        return(result);
    }
        public static async ValueTask <TcpListenerManager> CreateAsync(OmniAddress listenAddress, bool useUpnp, IUpnpClientFactory upnpClientFactory, CancellationToken cancellationToken = default)
        {
            var tcpListenerManager = new TcpListenerManager(useUpnp, upnpClientFactory);
            await tcpListenerManager.InitAsync(listenAddress, cancellationToken);

            return(tcpListenerManager);
        }
Beispiel #5
0
    public async ValueTask RunAsync([Option("storage", new char[] { 's' })] string storageDirectoryPath, [Option("listen", new char[] { 'l' })] string listenAddress, [Option("verbose", new char[] { 'v' })] bool verbose = false)
    {
        try
        {
            DirectoryHelper.CreateDirectory(storageDirectoryPath);

            SetLogsDirectory(Path.Combine(storageDirectoryPath, "logs"));
            if (verbose)
            {
                ChangeLogLevel(NLog.LogLevel.Trace);
            }

            _lockFileStream = new FileStream(Path.Combine(storageDirectoryPath, "lock"), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1, FileOptions.DeleteOnClose);

            _logger.Info("Starting...");
            _logger.Info("AssemblyInformationalVersion: {0}", Assembly.GetExecutingAssembly().GetCustomAttribute <AssemblyInformationalVersionAttribute>()?.InformationalVersion);

            await Runner.EventLoopAsync(Path.Combine(storageDirectoryPath, "db"), OmniAddress.Parse(listenAddress), this.Context.CancellationToken);
        }
        catch (Exception e)
        {
            _logger.Error(e);
        }
        finally
        {
            _logger.Info("Stopping...");
            NLog.LogManager.Shutdown();

            _lockFileStream?.Dispose();
        }
    }
Beispiel #6
0
    public async Task SimpleParseTest()
    {
        var sample = OmniAddress.CreateTcpEndpoint(IPAddress.Loopback, 32321);

        Assert.True(sample.TryGetTcpEndpoint(out var ipAddress, out var port));
        Assert.Equal(IPAddress.Loopback, ipAddress);
        Assert.Equal(32321, port);
    }
Beispiel #7
0
 public Session(IConnection connection, OmniAddress address, SessionHandshakeType handshakeType, OmniSignature signature, string scheme)
 {
     this.Connection    = connection;
     this.Address       = address;
     this.HandshakeType = handshakeType;
     this.Signature     = signature;
     this.Scheme        = scheme;
 }
        public TcpListenerManager(OmniAddress listenAddress, CancellationToken cancellationToken = default)
        {
            if (!listenAddress.TryGetTcpEndpoint(out var ipAddress, out var port))
            {
                throw new Exception("listenAddress is invalid format.");
            }

            _tcpListener = new TcpListener(ipAddress !, port);
            _tcpListener.Start();
            _registration = cancellationToken.Register(() => _tcpListener.Stop());
        }
        public async ValueTask <IConnection?> ConnectAsync(OmniAddress address, string serviceType, CancellationToken cancellationToken = default)
        {
            var cap = await _tcpConnector.ConnectAsync(address, cancellationToken);

            if (cap != null)
            {
                var connection = await this.InternalConnectAsync(cap, serviceType, cancellationToken);

                return(connection);
            }

            return(null);
        }
    public async ValueTask <IConnection?> ConnectAsync(OmniAddress address, CancellationToken cancellationToken = default)
    {
        var cap = await this.ConnectCapAsync(address, cancellationToken);

        if (cap == null)
        {
            return(null);
        }

        var bridgeConnectionOptions = new BridgeConnectionOptions(MaxReceiveByteCount);
        var bridgeConnection        = new BridgeConnection(cap, _senderBandwidthLimiter, _receiverBandwidthLimiter, _batchActionDispatcher, _bytesPool, bridgeConnectionOptions);

        return(bridgeConnection);
    }
        private async ValueTask InitAsync(OmniAddress listenAddress, CancellationToken cancellationToken = default)
        {
            IUpnpClient?upnpClient = null;

            try
            {
                // TcpListenerの追加処理
                if (!listenAddress.TryGetTcpEndpoint(out var ipAddress, out ushort port, false))
                {
                    return;
                }

                _tcpListener = new TcpListener(ipAddress, port);
                _tcpListener.Start(3);

                if (_useUpnp)
                {
                    // "0.0.0.0"以外はUPnPでのポート開放対象外
                    if (ipAddress.Equals(IPAddress.Any))
                    {
                        if (upnpClient == null)
                        {
                            upnpClient = _upnpClientFactory.Create();
                            await upnpClient.ConnectAsync(cancellationToken);
                        }

                        _externalIpAddress = await upnpClient.GetExternalIpAddressAsync(cancellationToken);

                        _logger.Debug("UPnP ExternalIpAddress: {}", _externalIpAddress);

                        await upnpClient.ClosePortAsync(UpnpProtocolType.Tcp, port, cancellationToken);

                        await upnpClient.OpenPortAsync(UpnpProtocolType.Tcp, port, port, "Axis", cancellationToken);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Error(e);

                throw;
            }
            finally
            {
                if (upnpClient != null)
                {
                    upnpClient.Dispose();
                }
            }
        }
Beispiel #12
0
    public async ValueTask BuildAsync(string databaseDirectoryPath, OmniAddress listenAddress, CancellationToken cancellationToken = default)
    {
        _databaseDirectoryPath = databaseDirectoryPath;
        _listenAddress         = listenAddress;

        ArgumentNullException.ThrowIfNull(_databaseDirectoryPath);
        ArgumentNullException.ThrowIfNull(_listenAddress);

        try
        {
            _uiState = await UiStatus.LoadAsync(Path.Combine(_databaseDirectoryPath, UI_STATE_FILE_NAME));

            _intaractorProvider = new IntaractorProvider(_databaseDirectoryPath, _listenAddress, BytesPool.Shared);

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton(_uiState);
            serviceCollection.AddSingleton <IIntaractorProvider>(_intaractorProvider);
            serviceCollection.AddSingleton <IBytesPool>(BytesPool.Shared);

            serviceCollection.AddSingleton <IApplicationDispatcher, ApplicationDispatcher>();
            serviceCollection.AddSingleton <IMainWindowProvider, MainWindowProvider>();
            serviceCollection.AddSingleton <IClipboardService, ClipboardService>();
            serviceCollection.AddSingleton <IDialogService, DialogService>();
            serviceCollection.AddSingleton <INodesFetcher, NodesFetcher>();

            serviceCollection.AddTransient <MainWindowViewModel>();
            serviceCollection.AddTransient <SettingsWindowViewModel>();
            serviceCollection.AddTransient <MultiLineTextInputWindowViewModel>();
            serviceCollection.AddTransient <StatusControlViewModel>();
            serviceCollection.AddTransient <PeersControlViewModel>();
            serviceCollection.AddTransient <DownloadControlViewModel>();
            serviceCollection.AddTransient <UploadControlViewModel>();
            serviceCollection.AddTransient <SignaturesControlViewModel>();

            _serviceProvider = serviceCollection.BuildServiceProvider();
        }
        catch (OperationCanceledException e)
        {
            _logger.Debug(e);

            throw;
        }
        catch (Exception e)
        {
            _logger.Error(e);

            throw;
        }
    }
Beispiel #13
0
            public TcpAcceptOptions Deserialize(global::Omnix.Serialization.RocketPack.RocketPackReader r, int rank)
            {
                if (rank > 256)
                {
                    throw new global::System.FormatException();
                }

                uint propertyCount = r.GetUInt32();

                bool p_enabled = false;

                OmniAddress[] p_listenAddresses = global::System.Array.Empty <OmniAddress>();
                bool          p_useUpnp         = false;

                for (; propertyCount > 0; propertyCount--)
                {
                    uint id = r.GetUInt32();
                    switch (id)
                    {
                    case 0:
                    {
                        p_enabled = r.GetBoolean();
                        break;
                    }

                    case 1:
                    {
                        var length = r.GetUInt32();
                        p_listenAddresses = new OmniAddress[length];
                        for (int i = 0; i < p_listenAddresses.Length; i++)
                        {
                            p_listenAddresses[i] = OmniAddress.Formatter.Deserialize(r, rank + 1);
                        }
                        break;
                    }

                    case 2:
                    {
                        p_useUpnp = r.GetBoolean();
                        break;
                    }
                    }
                }

                return(new TcpAcceptOptions(p_enabled, p_listenAddresses, p_useUpnp));
            }
Beispiel #14
0
        public async ValueTask <Cap?> ConnectAsync(OmniAddress address, CancellationToken token = default)
        {
            if (this.IsDisposed)
            {
                return(null);
            }

            if (this.StateType != ServiceStateType.Running)
            {
                return(null);
            }

            Cap?result;

            if ((result = await _tcpConnectionCreator.ConnectAsync(address, token)) != null)
            {
                return(result);
            }

            return(null);
        }
Beispiel #15
0
    public static async ValueTask EventLoopAsync(string databaseDirectoryPath, OmniAddress listenAddress, CancellationToken cancellationToken = default)
    {
        await using var service = await AxisService.CreateAsync(databaseDirectoryPath, cancellationToken);

        using var tcpListenerManager = new TcpListenerManager(listenAddress, cancellationToken);

        var tasks = new List <Task>();

        try
        {
            for (; ;)
            {
                var socket = await tcpListenerManager.AcceptSocketAsync();

                var task = InternalEventLoopAsync(service, socket, cancellationToken);
                tasks.Add(task);
            }
        }
        catch (OperationCanceledException e)
        {
            _logger.Debug("OperationCanceledException", e);
        }
    }
Beispiel #16
0
        public TcpProxyOptions(TcpProxyType type, OmniAddress address)
        {
            if (address is null)
            {
                throw new global::System.ArgumentNullException("address");
            }

            this.Type    = type;
            this.Address = address;

            {
                var __h = new global::System.HashCode();
                if (this.Type != default)
                {
                    __h.Add(this.Type.GetHashCode());
                }
                if (this.Address != default)
                {
                    __h.Add(this.Address.GetHashCode());
                }
                __hashCode = __h.ToHashCode();
            }
        }
    public async ValueTask <ICap?> ConnectCapAsync(OmniAddress address, CancellationToken cancellationToken = default)
    {
        this.ThrowIfDisposingRequested();

        if (!address.TryGetTcpEndpoint(out var ipAddress, out ushort port))
        {
            return(null);
        }

#if !DEBUG
        if (!Internal.IpAddressHelper.IsGlobalIpAddress(ipAddress))
        {
            return(null);
        }
#endif

        var disposableList = new List <IDisposable>();

        try
        {
            if (_options.Proxy?.Address is not null && _options.Proxy.Address.TryGetTcpEndpoint(out var proxyAddress, out ushort proxyPort, true))
            {
                if (_socks5ProxyClientFactory is not null && _options.Proxy.Type == TcpProxyType.Socks5Proxy)
                {
                    var socket = await ConnectSocketAsync(new IPEndPoint(proxyAddress, proxyPort), cancellationToken);

                    if (socket == null)
                    {
                        return(null);
                    }

                    disposableList.Add(socket);

                    var proxy = _socks5ProxyClientFactory.Create(ipAddress.ToString(), port);
                    await proxy.ConnectAsync(socket, cancellationToken);

                    var cap = new SocketCap(socket);
                    disposableList.Add(cap);

                    return(cap);
                }
                else if (_httpProxyClientFactory is not null && _options.Proxy.Type == TcpProxyType.HttpProxy)
                {
                    var socket = await ConnectSocketAsync(new IPEndPoint(proxyAddress, proxyPort), cancellationToken);

                    if (socket == null)
                    {
                        return(null);
                    }

                    disposableList.Add(socket);

                    var proxy = _httpProxyClientFactory.Create(ipAddress.ToString(), port);
                    await proxy.ConnectAsync(socket, cancellationToken);

                    var cap = new SocketCap(socket);
                    disposableList.Add(cap);

                    return(cap);
                }
            }
Beispiel #18
0
 private ServiceManager(OmniAddress listenAddress)
 {
     _listenAddress = listenAddress;
 }
Beispiel #19
0
        private static bool TryGetEndpoint(OmniAddress omniAddress, out IPAddress ipAddress, out ushort port, bool nameResolving = false)
        {
            ipAddress = IPAddress.None;
            port      = 0;

            var sections = omniAddress.Decompose();

            // フォーマットのチェック
            if (sections.Length != 4 || !(sections[0] == "ip4" || sections[0] == "ip6") || !(sections[2] == "tcp"))
            {
                return(false);
            }

            // IPアドレスのパース処理
            {
                if (nameResolving)
                {
                    if (!IPAddress.TryParse(sections[1], out ipAddress))
                    {
                        try
                        {
                            var hostEntry = Dns.GetHostEntry(sections[1]);

                            if (hostEntry.AddressList.Length == 0)
                            {
                                return(false);
                            }

                            ipAddress = hostEntry.AddressList[0];
                        }
                        catch (Exception e)
                        {
                            _logger.Error(e);
                            return(false);
                        }
                    }
                }
                else
                {
                    if (!IPAddress.TryParse(sections[1], out ipAddress))
                    {
                        return(false);
                    }
                }

                if (sections[0] == "ip4" && ipAddress.AddressFamily != AddressFamily.InterNetwork)
                {
                    return(false);
                }

                if (sections[0] == "ip6" && ipAddress.AddressFamily != AddressFamily.InterNetworkV6)
                {
                    return(false);
                }
            }

            // ポート番号のパース処理
            if (ushort.TryParse(sections[3], out port))
            {
                return(false);
            }

            return(true);
        }
Beispiel #20
0
 public ConnectionStatus(IConnection connection, OmniAddress address, ConnectionHandshakeType handshakeType)
 {
     this.Connection    = connection;
     this.Address       = address;
     this.HandshakeType = handshakeType;
 }
Beispiel #21
0
        private static bool TryGetEndpoint(OmniAddress rootAddress, [NotNullWhen(true)] out IPAddress?ipAddress, out ushort port, bool nameResolving = false)
        {
            ipAddress = IPAddress.None;
            port      = 0;

            var rootFunction = rootAddress.Parse();

            if (rootFunction == null)
            {
                return(false);
            }

            if (rootFunction.Name == "tcp")
            {
                if (!(rootFunction.Arguments.Count == 2 &&
                      rootFunction.Arguments[0] is OmniAddress.FunctionElement hostFunction &&
                      rootFunction.Arguments[1] is OmniAddress.ConstantElement portConstant))
                {
                    return(false);
                }

                if (hostFunction.Name == "ip4")
                {
                    if (!(hostFunction.Arguments.Count == 1 &&
                          hostFunction.Arguments[0] is OmniAddress.ConstantElement ipAddressConstant))
                    {
                        return(false);
                    }

                    if (!IPAddress.TryParse(ipAddressConstant.Text, out var temp) ||
                        temp.AddressFamily != AddressFamily.InterNetwork)
                    {
                        return(false);
                    }

                    ipAddress = temp;
                }
                else if (hostFunction.Name == "ip6")
                {
                    if (!(hostFunction.Arguments.Count == 1 &&
                          hostFunction.Arguments[0] is OmniAddress.ConstantElement ipAddressConstant))
                    {
                        return(false);
                    }

                    if (!IPAddress.TryParse(ipAddressConstant.Text, out var temp) ||
                        temp.AddressFamily != AddressFamily.InterNetworkV6)
                    {
                        return(false);
                    }

                    ipAddress = temp;
                }
                else if (nameResolving && hostFunction.Name == "dns")
                {
                    if (!(hostFunction.Arguments.Count == 1 &&
                          hostFunction.Arguments[0] is OmniAddress.ConstantElement hostnameConstant))
                    {
                        return(false);
                    }

                    try
                    {
                        var hostEntry = Dns.GetHostEntry(hostnameConstant.Text);

                        if (hostEntry.AddressList.Length == 0)
                        {
                            return(false);
                        }

                        ipAddress = hostEntry.AddressList[0];
                    }
                    catch (Exception e)
                    {
                        _logger.Error(e);
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }

                if (!ushort.TryParse(portConstant.Text, out port))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #22
0
        public async ValueTask <ICap?> ConnectAsync(OmniAddress address, CancellationToken cancellationToken = default)
        {
            using (await _asyncLock.LockAsync())
            {
                this.ThrowIfDisposingRequested();

                var config = _tcpConnectOptions;
                if (config == null || !config.Enabled)
                {
                    return(null);
                }

                if (!TryGetEndpoint(address, out var ipAddress, out ushort port))
                {
                    return(null);
                }

                var disposableList = new List <IDisposable>();

                try
                {
#if !DEBUG
                    if (!IsGlobalIpAddress(ipAddress))
                    {
                        return(null);
                    }
#endif

                    if (config.ProxyOptions != null)
                    {
                        if (!TryGetEndpoint(config.ProxyOptions.Address, out var proxyAddress, out ushort proxyPort, true))
                        {
                            return(null);
                        }

                        if (config.ProxyOptions.Type == TcpProxyType.Socks5Proxy)
                        {
                            var socket = await ConnectAsync(new IPEndPoint(proxyAddress, proxyPort));

                            if (socket == null)
                            {
                                return(null);
                            }

                            disposableList.Add(socket);

                            var proxy = new Socks5ProxyClient(ipAddress.ToString(), port);
                            await proxy.ConnectAsync(socket, cancellationToken);

                            var cap = new SocketCap(socket);
                            disposableList.Add(cap);

                            return(cap);
                        }
                        else if (config.ProxyOptions.Type == TcpProxyType.HttpProxy)
                        {
                            var socket = await ConnectAsync(new IPEndPoint(proxyAddress, proxyPort));

                            if (socket == null)
                            {
                                return(null);
                            }

                            disposableList.Add(socket);

                            var proxy = new HttpProxyClient(ipAddress.ToString(), port);
                            await proxy.ConnectAsync(socket, cancellationToken);

                            var cap = new SocketCap(socket);
                            disposableList.Add(cap);

                            return(cap);
                        }
                    }
                    else
                    {
                        var socket = await ConnectAsync(new IPEndPoint(ipAddress, port));

                        if (socket == null)
                        {
                            return(null);
                        }

                        disposableList.Add(socket);

                        var cap = new SocketCap(socket);
                        disposableList.Add(cap);

                        return(cap);
                    }
                }
                catch (Exception e)
                {
                    _logger.Error(e);

                    foreach (var item in disposableList)
                    {
                        item.Dispose();
                    }
                }

                return(null);
            }
        }
Beispiel #23
0
 public ConnectionControllerAcceptResult(IConnection connection, OmniAddress address)
 {
     this.Connection = connection;
     this.Address    = address;
 }