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 void ServerData(object sender, BytesSegment bs) { if (serverDone || bs.Len == 0) { return; } serverDone = true; if (sBuf != null) { bs.CopyTo(sBuf, 0, bs.Len, sProg); sProg += bs.Len; if (sProg < sBuf.Length) { goto CONTINUE_READ; } else { bs = new BytesSegment(sBuf, 0, sProg); } } if (Tls.Version != 0) { var hello = new TlsStream.ServerHello(); try { TlsStream.ParseServerHelloRecord(bs, ref hello, out var size); if (size > bs.Len) { if (sBuf != null) { throw new Exception("sBuf != null"); } sBuf = new byte[size]; bs.CopyTo(sBuf); sProg = bs.Len; goto CONTINUE_READ; } } catch (Exception e) { if (hello.Version != 0) { TlsError = true; Logging.exception(e, Logging.Level.Warning, "parsing tls server hello from " + sender); } } Tls.Version = Math.Min(Tls.Version, hello.Version); Tls.Alpn = hello.Alpn; } sBuf = null; return; CONTINUE_READ: serverDone = false; return; }
public void ClientData(object sender, BytesSegment _bs) { if (clientDone || _bs.Len == 0) { return; } clientDone = true; try { TlsStream.ParseClientHelloRecord(_bs, ref Tls, out var size); } catch (Exception e) { if (Tls.Version != 0) { TlsError = true; Logging.exception(e, Logging.Level.Warning, "parsing tls client hello from " + sender); } } try { var bs = _bs; var http = false; foreach (var item in httpMethods) { if (Match(bs, item) && bs.GetOrZero(item.Length) == ' ') { bs.SubSelf(item.Length + 1); http = true; break; } } if (http) { Protocol = "HTTP?"; var begin = Find(bs, (byte)' '); if (begin != -1) { begin += 1; bs.SubSelf(begin); if (Match(bs, "HTTP")) { var len = Find(bs.Sub(0, Math.Min(bs.Len, 10)), (byte)'\r'); if (len == -1) { len = Find(bs.Sub(0, Math.Min(bs.Len, 10)), (byte)'\n'); } if (len != -1) { Protocol = Encoding.ASCII.GetString(bs.Bytes, bs.Offset, len); } } } } } catch (Exception) { } if (Protocol != null) { return; } if (Match(_bs, "SSH-")) { Protocol = "SSH"; return; } if (Match(_bs, "\x0013BitTorrent protocol")) { Protocol = "BitTorrent"; return; } if (_bs[0] == '<') { // XML stream? var bs = _bs.Sub(1); if (Match(bs, "?xml version=")) { Protocol = "XML?"; // skip xml declaration var end = Find(bs, (byte)'>'); if (end != -1) { bs.Sub(end + 1); } } while (Match(bs, "\r") || Match(bs, "\n")) { bs.SubSelf(1); } if (Match(bs, "<stream")) { Protocol = "XMPP?"; } } if (_bs.Len >= 2 && _bs[0] == 0x10) { // MQTT CONNECT? var remainingLength = _bs[1]; if (2 + remainingLength <= _bs.Len) { var payload = _bs.Sub(2, remainingLength); if (Match(payload, "\x0000\x0004MQTT")) { Protocol = "MQTT"; if (payload.Len >= 7) { var version = payload[6]; Protocol += version == 5 ? "(v5.0)" : version == 4 ? "(v3.1.1)" : $"(v{version})"; } } } } }