Пример #1
0
        public async Task <string> StartAsync(string address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            var entries = AddressEntry.ParseEntries(address);

            if (entries.Length != 1)
            {
                throw new ArgumentException("Address must contain a single entry.", nameof(address));
            }
            var entry     = entries[0];
            var endpoints = await entry.ResolveAsync(listen : true);

            if (endpoints.Length == 0)
            {
                throw new ArgumentException("Address does not resolve to an endpoint.", nameof(address));
            }

            lock (_gate)
            {
                if (IsDisposed)
                {
                    throw new ObjectDisposedException(typeof(LocalServer).FullName);
                }
                if (_started)
                {
                    throw new InvalidOperationException("Server is already started.");
                }
                _started = true;

                var endpoint = endpoints[0];
                if (endpoint is IPEndPoint ipEndPoint)
                {
                    _serverSocket = new Socket(ipEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                }
                else if (endpoint is UnixDomainSocketEndPoint unixEndPoint)
                {
                    _serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
                    address       = (unixEndPoint.Path[0] == '\0') ? $"unix:abstract={unixEndPoint.Path.Substring(1)}" :
                                    $"unix:path={unixEndPoint.Path}";
                }
                _serverSocket.Bind(endpoint);
                _serverSocket.Listen(10);
                AcceptConnections();

                if (endpoint is IPEndPoint)
                {
                    var boundEndPoint = _serverSocket.LocalEndPoint as IPEndPoint;
                    address = $"tcp:host={boundEndPoint.Address},port={boundEndPoint.Port}";
                }
                return(address);
            }
        }
Пример #2
0
        public static AddressEntry[] ParseEntries(string addresses)
        {
            if (addresses == null)
            {
                throw new ArgumentNullException(nameof(addresses));
            }

            List <AddressEntry> entries = new List <AddressEntry>();

            foreach (string entryStr in addresses.Split(';'))
            {
                entries.Add(AddressEntry.Parse(entryStr));
            }

            return(entries.ToArray());
        }
Пример #3
0
        public static AddressEntry Parse(string s)
        {
            AddressEntry entry = new AddressEntry();

            string[] parts = s.Split(new[] { ':' }, 2);

            if (parts.Length < 2)
            {
                throw new FormatException("No colon found");
            }

            entry.Method = parts[0];

            if (parts[1].Length > 0)
            {
                foreach (string propStr in parts[1].Split(','))
                {
                    parts = propStr.Split('=');

                    if (parts.Length < 2)
                    {
                        throw new FormatException("No equals sign found");
                    }
                    if (parts.Length > 2)
                    {
                        throw new FormatException("Too many equals signs found");
                    }

                    if (parts[0] == "guid")
                    {
                        try
                        {
                            entry.Guid = Guid.ParseExact(parts[1], "N");
                        }
                        catch
                        {
                            throw new FormatException("Invalid guid specified");
                        }
                        continue;
                    }

                    entry.Properties[parts[0]] = Unescape(parts[1]);
                }
            }

            return(entry);
        }
Пример #4
0
        public static async Task <IMessageStream> ConnectAsync(AddressEntry entry, ClientSetupResult connectionContext, CancellationToken cancellationToken)
        {
            TransportSocket socket = await TransportSocket.ConnectAsync(entry, cancellationToken, connectionContext.SupportsFdPassing).ConfigureAwait(false);

            try
            {
                Transport transport = new Transport(socket);
                await transport.DoClientAuth(entry.Guid, connectionContext.UserId).ConfigureAwait(false);

                return(transport);
            }
            catch
            {
                socket.Dispose();
                throw;
            }
        }