/// <summary> /// Browse service names or types /// </summary> static async Task <IEnumerable <DnsServiceEntry> > ResolveServiceAsync(DnsServiceRecord record, int period, bool fromCache) { Console.WriteLine($"Resolving {record} for {period} ms..."); var entries = new HashSet <DnsServiceEntry>(); var cts = new CancellationTokenSource(period); try { using (var browser = await Dns.BrowseAsync(record, fromCache, cts.Token)) { cts.Token.ThrowIfCancellationRequested(); while (await browser.MoveNextAsync(cts.Token)) { cts.Token.ThrowIfCancellationRequested(); Console.WriteLine($"{DateTime.Now}: {browser.Current}"); entries.Add(browser.Current); } } } catch (OperationCanceledException) { } return(entries); }
/// <summary> /// Main program entry point /// </summary> static void Main(string[] args) { Op op = Op.None; bool cache = false; int period = 60 * 1000; DnsServiceRecord record = null; ProxySocketAddress address = null; // Parse command line try { for (int i = 0; i < args.Length; i++) { switch (args[i]) { case "-a": case "--all": if (op != Op.None) { throw new ArgumentException("Operations are mutual exclusive"); } op = Op.All; break; case "-s": case "--services": i++; if (op != Op.None) { throw new ArgumentException("Operations are mutual exclusive"); } op = Op.Browse; if (i < args.Length) { record = DnsServiceRecord.Parse(args[i]); } break; case "-t": case "--timeout": i++; if (i >= args.Length || !int.TryParse(args[i], out period)) { throw new ArgumentException($"Bad -t arg"); } break; case "-r": case "--resolve": i++; if (op != Op.None) { throw new ArgumentException("Operations are mutual exclusive"); } op = Op.Resolve; if (i < args.Length) { address = ProxySocketAddress.Parse(args[i]); } break; case "-d": case "--dir": i++; if (op != Op.None) { throw new ArgumentException("Operations are mutual exclusive"); } op = Op.Dir; if (i < args.Length) { address = ProxySocketAddress.Parse(args[i]); } break; case "--fs": if (op != Op.None) { throw new ArgumentException("Operations are mutual exclusive"); } op = Op.Fs; break; case "--use-cache": cache = true; break; case "-R": case "--relay": Socket.Provider = Provider.RelayProvider.CreateAsync().Result; break; case "-?": case "-h": case "--help": throw new ArgumentException("Help"); default: throw new ArgumentException($"Unknown {args[i]}"); } } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine( @" Browser - Proxy .net browser sample. usage: Browser [options] operation [args] Options: -t --timeout Timeout in ms to use for each browse request. --use-cache Return data from cache only (meaning depends on operation). --relay -R Use relay provider instead of default provider. --help -? -h Prints out this help. Operations (Mutually exclusive): -s --services Without further argument browses all domains. Otherwise browses for service types or service names in a domain. If service name is provided, resolves to host:port and txt. -a --all Browse all services in all domains on all proxies and resolve each one. (default!) -r --resolve Resolve host to address (getaddrbyhost) or address to host (gethostbyaddr) on all proxies. -d --dir Browse a folder on any proxy. --fs Browse entire file system on all proxies recursively. " ); return; } if (op == Op.Browse) { if (record != null) { if (string.IsNullOrEmpty(record.Name)) { var entries = BrowseServicesAsync( record.Type, record.Domain, period, cache).Result; } else { var entries = ResolveServiceAsync( record, period, cache).Result; } } else { var entries = BrowseDomainsAsync(period).Result; Console.WriteLine($"{entries.Count} entries found!!!"); } } else if (op == Op.Resolve) { var entries = ResolveAddressAsync(address, period, cache).Result; } else if (op == Op.Dir) { var files = BrowseFilesAsync(null, address?.Host, period, cache).Result; Console.WriteLine($"{files.Count} files/folders found!!!"); } else if (op == Op.Fs) { BrowseFilesRecursiveAsync(null, null, period, cache).Wait(); } else if (op == Op.All || op == Op.None) { Console.WriteLine("Browse and resolve all services"); var entries = ResolveServiceNamesAsync(period).Result; Console.WriteLine($"{entries.Count} entries resolved!!!"); } Console.WriteLine("Press a key to exit..."); Console.ReadKey(); }