Beispiel #1
0
 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);
 }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
 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);
 }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
        // 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);
        }
Beispiel #8
0
 public bool Check(ConnectArgument conn)
 {
     return(Check(conn.TryGetDestWithOriginalName(), conn.Url));
 }
Beispiel #9
0
        public override Task <ConnectResult> ProtectedConnect(ConnectArgument arg)
        {
            var dest = force_dest.IsDefault ? arg.Dest : force_dest;

            return(ConnectHelper.Connect(this, arg.Dest, connect_timeout));
        }
Beispiel #10
0
 public Task <ConnectResult> Connect(ConnectArgument arg)
 {
     return(Task.FromResult(GetConnectResult()));
 }
Beispiel #11
0
        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);
        }
Beispiel #12
0
 public abstract Task <ConnectResult> ProtectedConnect(ConnectArgument arg);