예제 #1
0
        static void OnPackageReceived(object sender, NatRequestInfo natRequestInfo)
        {
            Task.Run(() =>
            {
                switch (natRequestInfo.Body.Type)
                {
                case (byte)JsonType.NAT:
                    NatClient.ProcessData(natRequestInfo);
                    break;

                case (byte)JsonType.HTTP:
                    HttpClientProxy.ProcessData(NatClient, natRequestInfo);
                    break;

                case (byte)JsonType.TCP:
                    {
                        int waitTimes = 50;
                        var tcpModel  = natRequestInfo.Body.Data.FromJson <TcpModel>();
                        TcpClientProxy clientProxy = null;
                        mark:
                        clientProxy = TcpClientProxyList.Find(c => c.RemoteSession.SessionId == tcpModel.SessionId);
                        if (natRequestInfo.Body.Action == (int)TcpAction.TransferData)
                        {
                            if ((clientProxy == null || !clientProxy.IsConnected) && waitTimes >= 0)
                            {
                                LogHelper.Warning($"----> {tcpModel.SessionId} 未连接  IsConnected={clientProxy?.IsConnected.ToString() ?? "NULL"} ProxyCount={TcpClientProxyList.Count}");
                                Thread.Sleep(100);
                                waitTimes--;
                                goto mark;
                            }
                        }
                        if (clientProxy == null)
                        {
                            var arr = tcpModel.Local.Split(":");
                            var ip  = arr[0];
                            int.TryParse(arr[1], out int port);
                            clientProxy = new TcpClientProxy(new ClientOption()
                            {
                                Ip           = ip,
                                Port         = port,
                                NoDelay      = true,
                                ProtocolType = ProtocolType.Tcp
                            })
                            {
                                NatClient = NatClient
                            };
                        }
                        clientProxy.ProcessData(NatClient, natRequestInfo);
                        break;
                    }
                }
            });
        }
예제 #2
0
        public void ProcessData(NatClient natClient, NatRequestInfo natRequestInfo)
        {
            try
            {
                var tcpModel = natRequestInfo.Body.Data.FromJson <TcpModel>();
                switch (natRequestInfo.Body.Action)
                {
                case (int)TcpAction.Connect:
                {
                    //tcp注册包  发起连接到内网服务器
                    RemoteSession = tcpModel;
                    Map           = natClient.Client.MapList.Find(c => c.remote_endpoint == tcpModel.Host);
                    if (Map == null)
                    {
                        throw new Exception($"{Map.name} {Map.protocol} {Map.remote_endpoint} --> {Map.local_endpoint} 映射不存在");
                    }
                    ConectLocalServerAsync();
                }
                break;

                case (int)TcpAction.TransferData:
                {
                    if (RemoteSession == null)
                    {
                        return;
                    }
                    //gzip解压
                    var request = DataHelper.Decompress(tcpModel.Content);
                    //发送原始包
                    Send(request);
                    LogHelper.Info($"{Map.name} {Map.protocol} {Map.remote_endpoint} --> {Map.local_endpoint} 发送报文{request.Length}字节");
                }
                break;

                case (int)TcpAction.Close:
                {
                    //tcp连接关闭包
                    ClientManager.TcpClientProxyList.Remove(this);
                    Close();
                }
                break;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"{Map.name} {Map.protocol} {Map.remote_endpoint} --> {Map.local_endpoint} 客户端处理TCP穿透业务异常,{ex}");
            }
        }
예제 #3
0
        public void ProcessData(NatSession session, NatRequestInfo requestInfo, TcpModel tcpModel)
        {
            try
            {
                switch (requestInfo.Body.Action)
                {
                case (int)TcpAction.TransferData:
                {
                    //响应请求
                    int count = 0;
mark:
                    var tcpSession = GetSingleSession(c => c.SessionId == tcpModel.SessionId);
                    if (tcpSession == null)
                    {
                        count++;
                        Thread.Sleep(500);
                        if (count < 5)
                        {
                            goto mark;
                        }
                        LogHelper.Warning($"tcpSession【{tcpModel.SessionId}】不存在");
                        return;
                    }
                    //先讲16进制字符串转为byte数组  再gzip解压
                    var response = DataHelper.Decompress(tcpModel.Content);
                    tcpSession.Send(response);
                    LogHelper.Info($"{tcpSession.Map.name} {tcpSession.Map.protocol} {tcpSession.Map.remote_endpoint} --> {tcpSession.Map.local_endpoint} 发送报文{response.Length}字节");
                }
                break;

                case (int)TcpAction.Close:
                {
                    //关闭请求
                    var tcpSession = GetSingleSession(c => c.SessionId == tcpModel.SessionId);
                    if (tcpSession != null)
                    {
                        tcpSession.Close();
                        LogHelper.Info($"连接【{tcpSession.SessionId},{tcpSession.RemoteEndPoint}】关闭成功");
                    }
                }
                break;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"TcpServer穿透处理异常,{ex}");
            }
        }
예제 #4
0
        private static void Received(NatSession session, NatRequestInfo requestInfo)
        {
            Task.Run(() =>
            {
                try
                {
                    switch (requestInfo.Body.Type)
                    {
                    case (byte)JsonType.NAT:
                        {
                            LogHelper.Info($"NAT收到数据:{requestInfo.Raw.ToHexWithSpace()},正文内容: {requestInfo.Body.ToJson()}", false);
                            NATServer.ProcessData(session, requestInfo);
                            break;
                        }

                    case (byte)JsonType.HTTP:
                        {
                            var httpModel = requestInfo.Body.Data.FromJson <HttpModel>();
                            var server    = HttpServerList.Find(c => c.ServerId == httpModel.ServerId);
                            server?.ProcessData(session, requestInfo, httpModel);
                            break;
                        }

                    case (byte)JsonType.TCP:
                        {
                            var tcpModel = requestInfo.Body.Data.FromJson <TcpModel>();
                            var server   = TcpServerList.Find(c => c.ServerId == tcpModel.ServerId);
                            server?.ProcessData(session, requestInfo, tcpModel);
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"穿透传输连接【{session.RemoteEndPoint},{session.Client?.name}】响应请求异常:{ex}");
                }
            });
        }
예제 #5
0
        public void ProcessData(NatSession session, NatRequestInfo requestInfo, HttpModel httpModel)
        {
            try
            {
                switch (requestInfo.Body.Action)
                {
                case (int)HttpAction.Response:
                {
                    var context = GetSingleSession(c => c.SessionId == httpModel.SessionId);
                    if (context == null)
                    {
                        LogHelper.Error($"未找到上下文context,SessionId={httpModel.SessionId}");
                        return;
                    }
                    HttpResponse httpResponse = new HttpResponse()
                    {
                        HttpVersion   = httpModel.HttpVersion,
                        Headers       = httpModel.Headers,
                        Status        = httpModel.StatusCode,
                        StatusMessage = httpModel.StatusMessage
                    };
                    if (httpModel.Content?.Length > 0)
                    {
                        //解压
                        var byteData = DataHelper.Decompress(httpModel.Content);
                        httpResponse.ContentType = httpModel.ContentType;
                        httpResponse.Body        = byteData;
                    }
                    //把处理信息返回到客户端
                    context.Send(httpResponse.Write());
                    var response_time = DateTime.Now;
                    var timeSpan      = (response_time - httpModel.RequestTime);
                    var totalSize     = (httpResponse.Body?.Length ?? 0) * 1.00 / 1024;
                    var map           = session.MapList.Find(c => c.remote_endpoint == httpModel.Host);
                    LogHelper.Info($"{session.Client.user_name} {session.Client.name} {map?.name} {httpModel.Method} {httpModel.Path} {httpModel.StatusCode} {httpModel.StatusMessage} {Math.Round(totalSize, 1)}KB {timeSpan.TotalMilliseconds}ms");

                    var request = new Request
                    {
                        request_url      = $"{map.protocol}://{map.remote_endpoint}{httpModel.Path}",
                        request_method   = httpModel.Method,
                        client_ip        = session.RemoteEndPoint.ToString(),
                        user_id          = session.Client.user_id,
                        request_time     = httpModel.RequestTime,
                        response_time    = response_time,
                        handle_time      = Convert.ToInt64(timeSpan.TotalMilliseconds),   //ms
                        create_time      = DateTime.Now,
                        requet_content   = context.RequestInfo.Body == null ? null : Encoding.UTF8.GetString(context.RequestInfo.Body),
                        response_content = httpResponse.Body.Length <= 1024 ? Encoding.UTF8.GetString(httpResponse.Body) : "",
                        status_code      = httpModel.StatusCode,
                        status_message   = httpModel.StatusMessage,
                        total_size       = httpResponse.Body?.Length ?? 0,
                        speed            = Math.Round(totalSize / (timeSpan.TotalMilliseconds / 1000), 2),//KB/s
                        map_id           = map.id
                    };
                    lock (RequestQueue)
                        RequestQueue.Enqueue(request);
                }
                break;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"HttpsServer ProcessData穿透处理异常,{ex}");
            }
        }
예제 #6
0
        public static async void ProcessData(NatClient natClient, NatRequestInfo natRequestInfo)
        {
            try
            {
                switch (natRequestInfo.Body.Action)
                {
                case (byte)HttpAction.Request:
                {
                    var httpModel = natRequestInfo.Body.Data.FromJson <HttpModel>();
                    var map       = natClient.Client.MapList.Find(c => c.remote_endpoint == httpModel.Host || (c.remote == httpModel.Host && c.remote_port == 80));
                    if (map == null)
                    {
                        LogHelper.Error($"映射不存在,外网访问地址:{httpModel.Host}");
                        return;
                    }
                    using HttpRequestMessage httpRequest = new HttpRequestMessage()
                          {
                              Method     = new HttpMethod(httpModel.Method),
                              RequestUri = new Uri($"{map.protocol}://{map.local_endpoint}{httpModel.Path}")
                          };
                    LogHelper.Info($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri} {httpModel.Headers.ToJson()}{Environment.NewLine}");
                    string bodyStr = string.Empty;
                    if (httpRequest.Method != HttpMethod.Get && httpModel.Content?.Length > 0)
                    {
                        var body = DataHelper.Decompress(httpModel.Content);        //解压
                        bodyStr             = body.ToUTF8String();
                        httpRequest.Content = httpModel.ContentType == null ? new StringContent(bodyStr, Encoding.UTF8) : new StringContent(bodyStr, Encoding.UTF8, httpModel.ContentType.Split(";")[0]);
                    }
                    LogHelper.Info($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{Environment.NewLine}【Header】{httpModel.Headers.ToJson()}{$"{Environment.NewLine}【Body】{bodyStr}".If(httpModel.Content?.Length < 1024)}{Environment.NewLine}");
                    using HttpClient _httpClient = new HttpClient();
                    //替换Host 不然400 Bad Request
                    httpModel.Headers["Host"] = map.local_endpoint;
                    foreach (var item in httpModel.Headers)
                    {
                        if (!item.Key.EqualsWhithNoCase("Content-Type"))
                        {
                            if (!httpRequest.Content?.Headers.TryAddWithoutValidation(item.Key, item.Value) ?? true)
                            {
                                _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
                            }
                        }
                    }
                    if (map.protocol == "https")
                    {
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                    }
                    var response = await _httpClient.SendAsync(httpRequest);

                    //回传给服务器
                    httpModel.HttpVersion   = $"{map.protocol.ToUpper()}/{response.Version}";
                    httpModel.StatusCode    = (int)response.StatusCode;
                    httpModel.StatusMessage = response.StatusCode.ToString();
                    httpModel.Local         = map.local_endpoint;
                    httpModel.Headers       = response.Headers.ToDictionary();
                    httpModel.ResponseTime  = DateTime.Now;
                    foreach (var item in response.Content.Headers)
                    {
                        if (item.Key.EqualsWhithNoCase("Content-Type"))
                        {
                            httpModel.ContentType = string.Join(";", item.Value);
                        }
                        else
                        {
                            if (item.Key.EqualsWhithNoCase("Content-Length"))
                            {
                                continue;
                            }
                            httpModel.Headers.Add(item.Key, string.Join(";", item.Value));
                        }
                    }
                    httpModel.Headers.Remove("Transfer-Encoding");        //response收到的是完整的 这个响应头要去掉 不然浏览器解析出错
                    var returnContent = DataHelper.StreamToBytes(response.Content.ReadAsStreamAsync().Result);
                    if (returnContent.Length > 0)
                    {
                        httpModel.Content = DataHelper.Compress(returnContent);
                    }
                    var pack = PackHelper.CreatePack(new JsonData()
                        {
                            Type   = (int)JsonType.HTTP,
                            Action = (int)HttpAction.Response,
                            Data   = httpModel.ToJson()
                        });
                    natClient?.Send(pack);
                    LogHelper.Info($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{$"{returnContent.ToUTF8String()}".If(returnContent.Length < 1024)} {httpModel.StatusCode} {httpModel.StatusMessage} {Math.Round(returnContent.Length * 1.00 / 1024, 1)}KB{Environment.NewLine}");
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"处理请求异常:{ex}");

                var pack = PackHelper.CreatePack(new JsonData()
                {
                    Type   = (int)JsonType.HTTP,
                    Action = (int)HttpAction.Response,
                    Data   = new HttpModel()
                    {
                        StatusCode  = (int)HttpStatusCode.BadRequest,
                        ContentType = "text/html",
                        Content     = DataHelper.Compress(Encoding.UTF8.GetBytes($"server error"))
                    }.ToJson()
                });
                natClient?.Send(pack);
            }
        }