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); } }
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()); }
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); }
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; } }