bool Handle(ConnectArgument x, out AdapterRef redir) { redir = null; if (parsedRules == null) { return(false); } foreach (var r in parsedRules) { var abpFilter = r._abp_current_filter; bool hit = false; if (abpFilter != null) { hit = abpFilter(x); } Match regexMatch = null; if (!hit) { hit = HandleRule(x, r, out regexMatch); } if (hit && onConnectionHit(r, x, regexMatch, out redir)) { return(true); } } return(false); }
public static ConnectResult RedirectTo(IAdapter adapter, AdapterRef redirectTo) { return(new ConnectResult(adapter, ConnectResultEnum.Failed) { Redirected = redirectTo }); }
protected Task HandleIncommingConnection(InConnection inConnection, AdapterRef outRef) { if (rdns?.Adapter is DnsInAdapter dnsIn) { try { dnsIn.HandleRdns(inConnection); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, "rdns handling"); } } return(Controller.HandleInConnection(inConnection, outRef.Adapter as IConnectionHandler)); }
private Task <DnsResponse> StartResolve(DnsRequestType type, string strName, out bool newTask) { if (dnsProvider == null) { throw new Exception("no dns resolver"); } lock (resolvingNames) { newTask = false; if (resolvingNames.TryGetValue(strName, out var rt)) { // try to return a running task if (type == DnsRequestType.A && rt.A != null) { return(rt.A); } if (type == DnsRequestType.AAAA || rt.AAAA != null) { return(rt.AAAA); } if (type == DnsRequestType.AnAAAA) { if (rt.A == rt.AAAA) { return(rt.A); } if (rt.A != null && rt.AAAA != null) { return(UnionWarpper(rt)); } } } else { rt = new ResolveTask(); resolvingNames[strName] = rt; } var task = Controller.ResolveName(this, AdapterRef.FromAdapter(dnsProvider), new DnsRequest(strName, type)); if ((type & DnsRequestType.A) != 0 && rt.A == null) { rt.A = task; } if ((type & DnsRequestType.AAAA) != 0 && rt.AAAA == null) { rt.AAAA = task; } newTask = true; return(task); } }
public Task HandleInConnection(InConnection inc, AdapterRef outAdapterRef) { if (outAdapterRef == null) { throw new ArgumentNullException(nameof(outAdapterRef)); } IConnectionHandler adapter = outAdapterRef.Adapter as IConnectionHandler; if (adapter == null) { if (LoggingLevel <= Logging.Level.Warning) { warning($"null out adapter reference ({outAdapterRef})"); } } return(HandleInConnection(inc, adapter)); }
private bool Auth(Socks5Server s) { if (s.Username.IsNullOrEmpty() && s.Password.IsNullOrEmpty() && _adapter._allowNoAuth) { return(true); } foreach (var x in _adapter.users) { if ((x.name ?? "") == s.Username && (x.passwd ?? "") == s.Password) { outRef = x.@out ?? _adapter.@out; return(true); } } _adapter.Logger.warning("Auth failed: " + _eppair.RemoteEP); return(false); }
public async Task <DnsResponse> ResolveName(IAdapter creator, AdapterRef handler, DnsRequest request) { var cxn = InConnectionDns.Create(creator, request); await HandleInConnection(cxn, handler); var result = cxn.ConnectResult; if (result?.Ok == false) { if (result.FailedReason != null) { throw new Exception(result.FailedReason); } throw new Exception("name resolving failed."); } return(result as DnsResponse ?? DnsResponse.Empty(this)); }
public override void SetConfig(TomlTable toml) { base.SetConfig(toml); _noAuthOut = @out; if (users == null) { _allowNoAuth = true; } else { foreach (var x in users) { if (x.name.IsNullOrEmpty() && x.passwd.IsNullOrEmpty()) { _allowNoAuth = true; _noAuthOut = x.@out ?? @out; break; } } } }
public SocksInConnection(TcpClient tcp, SocksInAdapter adapter) : base(adapter) { _eppair = EPPair.FromSocket(tcp.Client); _adapter = adapter; _stream = adapter.GetMyStreamFromSocket(tcp.Client); socks5svr = new Socks5Server(_stream); Socks5Server.Methods methods = Socks5Server.Methods.None; if (adapter._allowNoAuth) { methods |= Socks5Server.Methods.NoAuth; } if (adapter.users != null) { methods |= Socks5Server.Methods.UsernamePassword; } socks5svr.AcceptMethods = methods; outRef = adapter._noAuthOut; socks5svr.Auth = Auth; }
// returns true if redirected private static bool onConnectionHit(Rule rule, ConnectArgument connection, Match regexMatch, out AdapterRef redirect) { AddrPort dest = connection.Dest; redirect = null; var destChanged = false; if (!rule.new_dest.IsDefault) { dest = rule.new_dest; destChanged = true; } if (rule.new_host != null) { dest.Host = rule.new_host; destChanged = true; } if (destChanged) { if (regexMatch != null) { for (int i = regexMatch.Groups.Count - 1; i >= 0; i--) { dest.Host = dest.Host.Replace("$" + i, regexMatch.Groups[i].Value); } } connection.Dest = dest; connection.DestOriginalName = null; } if (rule.to != null) { redirect = rule.to; return(true); } return(false); }
public LoadedConfig LoadConfig(ConfigFile cf, LoadedConfig newcfg) { var toml = cf.Content; newcfg = newcfg ?? new LoadedConfig(); if (cf.Path != null) { newcfg.FilePath = cf.Path; newcfg.WorkingDirectory = Path.GetDirectoryName(cf.Path); } Config t; TomlTable tomlTable; var refs = new List <AdapterRef>(); try { var tomlSettings = CreateTomlSettings(refs); tomlTable = Toml.ReadString(toml, tomlSettings); t = tomlTable.Get <Config>(); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, "TOML Error"); return(null); } newcfg.TomlTable = tomlTable; newcfg.SocketImpl = t.socket_impl; newcfg.LoggingLevel = t.log_level; newcfg.Aliases = t.aliases; newcfg.DebugFlags = t?.debug?.flags ?? new string[0]; int failedCount = 0; if (tomlTable.TryGetValue <TomlTable>("a", out var tableA)) { foreach (var pair in tableA) { var typeName = pair.Key; if (!(pair.Value is TomlTable table)) { Logger.error($"TOML path 'a.{typeName}' is not a TOML table."); continue; } foreach (var innerPair in table) { var name = innerPair.Key; try { var tt = (TomlTable)innerPair.Value; var adapter = NewRegisteredType(tt, name, typeName); newcfg.Adapters.Add(adapter); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, $"TOML table 'a.{typeName}.{name}':"); failedCount++; } } } } if (t.@in != null) { foreach (var item in t.@in) { try { var tt = item.Value; var name = "in." + item.Key; var adapter = NewRegisteredInType(tt, name); newcfg.Adapters.Add(adapter); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, $"TOML table 'in.{item.Key}':"); failedCount++; } } } if (t.@out != null) { foreach (var item in t.@out) { try { var tt = item.Value; var name = "out." + item.Key; var adapter = NewRegisteredOutType(tt, name); newcfg.Adapters.Add(adapter); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, $"TOML table 'out.{item.Key}':"); failedCount++; } } } for (int rIdx = 0; rIdx < refs.Count; rIdx++) { AdapterRef r = refs[rIdx]; if (r.IsTable == false) { continue; } var tt = r.Ref as TomlTable; try { string name = null; if (tt.TryGetValue("name", out string n)) { name = n; } if (name == null) { int i = 0; do { name = $"_{tt["type"].Get<string>()}_" + ((i++ == 0) ? "" : i.ToString()); } while (newcfg.Adapters.Any(x => x.Name == name)); } var adapter = NewRegisteredOutType(tt, name); r.Adapter = adapter; newcfg.Adapters.Add(adapter); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, $"TOML inline table:"); failedCount++; } } bool notExistAndNeed(string name) => newcfg.Adapters.Any(x => x.Name == name) == false /* && refs.Any(x => x.IsName && x.Ref as string == name) */; if (notExistAndNeed("direct")) { newcfg.Adapters.Add(new DirectOutAdapter() { Name = "direct" }); } if (notExistAndNeed("fail")) { newcfg.Adapters.Add(new FailAdapter() { Name = "fail" }); } foreach (var r in refs) { if (r.IsName) { r.Adapter = FindAdapter <IAdapter>(newcfg, r.Ref as string, -1); } } newcfg.Adapters.Sort((a, b) => a.Name.CompareTo(b.Name)); newcfg.FailedCount = failedCount; return(newcfg); }
private static TomlSettings CreateTomlSettings(List <AdapterRef> refs) { return(TomlSettings.Create(cfg => cfg .AllowNonstandard(true) .ConfigureType <IPEndPoint>(type => type .WithConversionFor <TomlString>(convert => convert .ToToml(custom => custom.ToString()) .FromToml(tmlString => Utils.CreateIPEndPoint(tmlString.Value)))) .ConfigureType <AddrPort>(type => type .WithConversionFor <TomlString>(convert => convert .ToToml(custom => custom.ToString()) .FromToml(tmlString => AddrPort.Parse(tmlString.Value)))) .ConfigureType <AdapterRef>(type => type .WithConversionFor <TomlString>(convert => convert .ToToml(custom => custom.Ref.ToString()) .FromToml(tmlString => { var a = new AdapterRef { IsName = true, Ref = tmlString.Value }; refs.Add(a); return a; })) .WithConversionFor <TomlTable>(convert => convert .FromToml(tml => { var a = new AdapterRef { IsTable = true, Ref = tml }; refs.Add(a); return a; }))) .ConfigureType <AdapterRefOrArray>(type => type .WithConversionFor <TomlString>(convert => convert .FromToml(tmlString => { var str = tmlString.Value; if (str.Contains('|')) { var splits = str.Split('|'); var aarr = new AdapterRef[splits.Length]; for (int i = 0; i < splits.Length; i++) { var a = new AdapterRef { IsName = true, Ref = splits[i] }; refs.Add(a); aarr[i] = a; } return new AdapterRefOrArray { obj = aarr }; } else { return new AdapterRefOrArray { obj = tmlString.Get <AdapterRef>() }; } })) .WithConversionFor <TomlTable>(convert => convert .FromToml(tmlTable => { var a = new AdapterRefOrArray { obj = tmlTable.Get <AdapterRef>() }; return a; })) .WithConversionFor <TomlArray>(convert => convert .FromToml(tmlTable => { var a = new AdapterRefOrArray { obj = tmlTable.Get <AdapterRef[]>() }; return a; })) .WithConversionFor <TomlTableArray>(convert => convert .FromToml(tmlTable => { var a = new AdapterRefOrArray { obj = tmlTable.Get <AdapterRef[]>() }; return a; }))) .ConfigureType <StringOrArray>(type => type .WithConversionFor <TomlString>(convert => convert .FromToml(tmlString => { return new StringOrArray { obj = tmlString.Get <string>() }; })) .WithConversionFor <TomlTable>(convert => convert .FromToml(tmlTable => { return new StringOrArray { obj = tmlTable.Get <string>() }; })) .WithConversionFor <TomlArray>(convert => convert .FromToml(tmlArray => { return new StringOrArray { obj = tmlArray.Get <string[]>() }; }))) )); }
public void RedirectTo(AdapterRef redirectedName) { Redirected = redirectedName; }