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); } }
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)); }
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); }
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(); } }
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); }
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(); } } }
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; } }
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)); }
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); }
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); } }
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); } }
private ServiceManager(OmniAddress listenAddress) { _listenAddress = listenAddress; }
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); }
public ConnectionStatus(IConnection connection, OmniAddress address, ConnectionHandshakeType handshakeType) { this.Connection = connection; this.Address = address; this.HandshakeType = handshakeType; }
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); }
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); } }
public ConnectionControllerAcceptResult(IConnection connection, OmniAddress address) { this.Connection = connection; this.Address = address; }