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 override async Task <ConnectResult> ProtectedConnect(ConnectArgument arg) { var dest = arg.Dest; var baseResult = await ConnectHelper.Connect(this, server.WithDefaultPort(80), connect_timeout); if (!baseResult.Ok) { return(baseResult); } try { var dataStream = baseResult.Stream; var asStream = MyStream.ToStream(dataStream); var sw = new StringWriter(new StringBuilder(1024)); var destStr = dest.ToString(); HttpClient.WriteHttpRequestHeader(sw, "CONNECT", destStr, new Dictionary <string, string> { ["Host"] = destStr }); await dataStream.WriteAsync(NaiveUtils.GetUTF8Bytes(sw.ToString())); var responseStr = await NaiveUtils.ReadStringUntil(asStream, NaiveUtils.DoubleCRLFBytes); var sr = new StringReader(responseStr); var response = HttpClient.ReadHttpResponseHeader(sr); if (response.StatusCode != "200") { throw new Exception($"remote server response '{response.StatusCode} {response.ReasonPhrase}'"); } return(CreateConnectResultWithStream(dataStream)); } catch (Exception) { MyStream.CloseWithTimeout(baseResult.Stream); throw; } }
public override async Task <ConnectResult> ProtectedConnect(ConnectArgument arg) { var dest = arg.Dest; var stream = await Socks5Client.Connect(server.Host, server.Port, dest.Host, dest.Port, username, password); return(CreateConnectResultWithStream(stream)); }
private static bool HandleRule(ConnectArgument x, Rule r, out Match regexMatch) { regexMatch = null; if (r.is_dns && x is InConnectionDns) { return(true); } if (x.DestOriginalName != null && HandleRule(r, ref regexMatch, x.DestOriginalName, x.Dest.Port)) { return(true); } if (HandleRule(r, ref regexMatch, x.Dest.Host, x.Dest.Port)) { return(true); } return(false); }
public async Task <ConnectResult> Connect(ConnectArgument arg) { try { var result = await ProtectedConnect(arg); if (!result.IsRedirected && !result.Ok && if_failed != null) { Logging.error(ToString() + $": {arg} failed ({result.FailedReason}), redirecting to {if_failed}."); return(ConnectResult.RedirectTo(this, if_failed)); } return(result); } catch (Exception ex) when(if_failed != null) { Logging.exception(ex, Logging.Level.Error, ToString() + $": {arg} failed, redirecting to {if_failed}."); return(ConnectResult.RedirectTo(this, if_failed)); } catch (Exception) { throw; } }
public override async Task <ConnectResult> ProtectedConnect(ConnectArgument arg) { var dest = arg.Dest; var baseResult = await ConnectHelper.Connect(this, server, connect_timeout); if (!baseResult.Ok) { return(baseResult); } try { var dataStream = getEncryptionStream(baseResult.Stream); var bytes = dest.ToSocks5Bytes(); await dataStream.WriteAsync(bytes); return(CreateConnectResultWithStream(dataStream)); } catch (Exception) { MyStream.CloseWithTimeout(baseResult.Stream); throw; } }
// 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 bool Check(ConnectArgument conn) { return(Check(conn.TryGetDestWithOriginalName(), conn.Url)); }
public override Task <ConnectResult> ProtectedConnect(ConnectArgument arg) { var dest = force_dest.IsDefault ? arg.Dest : force_dest; return(ConnectHelper.Connect(this, arg.Dest, connect_timeout)); }
public Task <ConnectResult> Connect(ConnectArgument arg) { return(Task.FromResult(GetConnectResult())); }
public static Task <ConnectResult> ConnectWrapper(IConnectionHandler handler, ConnectArgument arg) { var tcs = new TaskCompletionSource <ConnectResult>(); var newinc = InConnectionTcp.Create(arg.InAdapter, arg.Dest, async(r) => { if (r.Ok) { var stream = new LoopbackStream(); r.Stream = stream; tcs.SetResult(r); return(stream.Another); } else { tcs.SetResult(r); return(null); } }); newinc.Url = arg.Url; newinc.DestOriginalName = arg.DestOriginalName; NaiveUtils.RunAsyncTask(async() => { try { await handler.HandleTcpConnection(newinc).CAF(); } catch (Exception e) { tcs.SetException(e); return; } if (newinc.IsRedirected && tcs.Task.IsCompleted == false) { tcs.SetResult(ConnectResult.RedirectTo(handler, newinc.Redirected)); } else { tcs.SetException(new Exception("handleConnection() did nothing.")); } }); return(tcs.Task); }
public abstract Task <ConnectResult> ProtectedConnect(ConnectArgument arg);