eclipse-vertx / vertx-sql-client

High performance reactive SQL Client written in Java
Apache License 2.0
894 stars 200 forks source link

SQL Server has closed connection unexpectedly if sql request size more then package size and it is chunked (probably only together with ssl) #1433

Closed temaleva closed 6 months ago

temaleva commented 7 months ago

Version

At least version 4.x and actual snapshot 5.0.0-SNAPSHOT

Context

By trying to send sql request (especially insert) which exceeds in size current package size

Reproducer

Reproducer quarkus project could be found here https://github.com/eagely/vertx-closed-connection/tree/master

Steps to reproduce

  1. set tds driver package size small enough to be as small as you request size ( for example using quarkus.datasource.reactive.mssql.packet-size property in quarkus based project). The minimal package size is 512 , so you request size must be at least 512 bytes.
  2. Try to execute insert statement
  3. Receive ClosedConnectionException instead of answer from sql server.

Extra

It looks like the problem is connected with tls package size, which must be synchronized with request package size. The same error was detected (and fixed) in several other mssql clients/libraries, such as .NET and Node.js At least this one looks very similar https://github.com/tediousjs/tedious/issues/923

It could be, that the problem only appeares on linux, but this is also mean in docker env reproducible as well.. Reproducer use sql docker and was started on linux only. (Not know if on windows host the same exception appears).

tsegismont commented 7 months ago

Thanks for the report. I will look into it

temaleva commented 6 months ago

@tsegismont Could I help somehow? I was trying to understand how one can synchronize ssl package size with tds package size, but was no able to cope it. I believe, based on the fixes in another projects, this should be the solution. Maybe if you can give me some insides on this, so I can try it once again?

tsegismont commented 6 months ago

I was able to reproduce with this test in MSSQLEncryptionTest:

  @Test
  public void testSmallerPacketSize(TestContext ctx) {
    setOptions(rule.options()
      .setSsl(true)
      .setSslOptions(new ClientSSLOptions().setTrustAll(true))
      .setPacketSize(512));

    char[] chars = new char[200];
    Arrays.fill(chars, 'a');
    String str = new String(chars);

    connect(ctx.asyncAssertSuccess(conn -> {
      conn.query("CREATE TABLE #TestX (text NVARCHAR(MAX))").execute().onComplete(ctx.asyncAssertSuccess(v -> {
        conn.preparedQuery("INSERT INTO Test2 (text) VALUES (@p1)").execute(Tuple.of(str)).onComplete(ctx.asyncAssertSuccess());
      }));
    }));
  }

Working on the fix

tsegismont commented 6 months ago

Fixed by df39408b