public override async void OnNewConnection(TcpClient client) { var stream = GetMyStreamFromSocket(client.Client); try { var bs = BufferPool.GlobalGetBs(8 * 1024, false); var r = await stream.ReadAsyncR(bs); if (r <= 0) { return; } bs.Len = r; var ch = new TlsStream.ClientHello(); TlsStream.ParseClientHelloRecord(bs, ref ch, out _); if (ch.Sni == null) { return; } var conn = InConnectionTcp.Create(this, new AddrPort(ch.Sni, dest_port), new MyStreamWrapper(stream) { Queue = bs }); await HandleIncommingConnection(conn); } catch (Exception e) { Logger.exception(e, Logging.Level.Error, "OnNewConnection"); } finally { MyStream.CloseWithTimeout(stream).Forget(); } }
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 HandleTcpConnection(InConnectionTcp connection) { Exception e = null; ConnectResult connectResult = null; try { connectResult = await Connect(connection); } catch (Exception ex) when(if_failed != null) { Logging.exception(ex, Logging.Level.Error, $"{this}: {connection} failed ({connectResult.FailedReason}), redirecting to {if_failed}."); connection.RedirectTo(if_failed); return; } if (!connectResult.Ok && if_failed != null) { Logging.warning($": {connection} failed ({connectResult.FailedReason}), redirecting to {if_failed}."); connection.RedirectTo(if_failed); return; } try { if (connectResult.Ok) { await connection.HandleAndPutStream(this, connectResult.Stream, connectResult.WhenCanRead); } else { await connection.HandleAndGetStream(connectResult); } } finally { if (connectResult.Ok) { MyStream.CloseWithTimeout(connectResult.Stream); } } }
protected override Task OnFinish() { var dataStream = DataStream; if (dataStream != null) { MyStream.CloseWithTimeout(dataStream).Forget(); } return(base.OnFinish()); }
public async Task Run() { var left = Left; var right = Right; int halfCloseTimeout = (10 * 1000) + NaiveUtils.Random.Next(-1000, 1000); const int forceCloseTimeout = 10 * 1000; try { var readFromRight = CopierFromRight.CopyAndShutdown(); var readFromLeft = CopierFromLeft.CopyAndShutdown(); var tasks = new Task[] { readFromRight, readFromLeft }; string stringFromTask(Task t) => t == readFromRight ? $"{right} -> {left}" : $"{left} -> {right}"; // waiting for half closing. var compeletedTask = await Task.WhenAny(tasks).CAF(); if (compeletedTask.IsFaulted) { var exception = compeletedTask.Exception.InnerException; Logger?.exception(exception, Logging.Level.Warning, $"stream copying exception, force closing. ({stringFromTask(compeletedTask)})"); return; } var anotherTask = compeletedTask == readFromRight ? readFromLeft : readFromRight; // waiting for full closing with timeout. if (await anotherTask.WithTimeout(halfCloseTimeout)) { Logger?.warning($"keeping half closed for {halfCloseTimeout} ms, force closing. ({stringFromTask(anotherTask)})"); } else { if (anotherTask.IsFaulted) { Logger?.exception(anotherTask.Exception.InnerException, Logging.Level.Warning, $"half closed waiting exception. {stringFromTask(anotherTask)}"); } } } catch (Exception e) { Logger?.exception(e, Logging.Level.Error, $"Relay task ({left.SafeToStr()} <-> {right.SafeToStr()})"); } finally { var t1 = MyStream.CloseWithTimeout(left, forceCloseTimeout); var t2 = MyStream.CloseWithTimeout(right, forceCloseTimeout); //await t1; await t2; } }
public override void Stop() { base.Stop(); var stream = DataStream; if (stream == null) { stream = ConnectResult.Stream; } if (stream == null) { Controller.Logger.warning(this + ": Can not get the stream, failed to stop."); } else { Controller.Logger.info("Closing stream " + stream + " to stop connection " + this); MyStream.CloseWithTimeout(stream); } }
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; } }
public async void Start() { try { if (!await socks5svr.ProcessAsync()) { return; } this.Dest.Host = socks5svr.TargetAddr; this.Dest.Port = socks5svr.TargetPort; this.DataStream = _stream; if (_adapter.fastreply) { await OnConnectionResult(new ConnectResult(null, ConnectResultEnum.OK)).CAF(); } await _adapter.HandleIncommingConnection(this, outRef); } catch (Exception e) { _adapter.Logger.exception(e, Logging.Level.Warning, "listener"); } finally { MyStream.CloseWithTimeout(_stream).Forget(); } }