Fix application protocol to make it work with utf8

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2021-09-28 16:25:48 +02:00 committed by Simone Bordet
parent 2e98931654
commit b09191d2f8
3 changed files with 42 additions and 19 deletions

View File

@ -17,6 +17,7 @@ import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
@ -45,6 +46,7 @@ public class QuicheConnection
{
private static final Logger LOG = LoggerFactory.getLogger(QuicheConnection.class);
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
private static final Charset APPLICATION_PROTOCOL_CHARSET = StandardCharsets.UTF_8;
static
{
@ -103,9 +105,9 @@ public class QuicheConnection
{
StringBuilder sb = new StringBuilder();
for (String proto : applicationProtos)
sb.append((char)proto.length()).append(proto);
sb.append((char)proto.getBytes(APPLICATION_PROTOCOL_CHARSET).length).append(proto);
String theProtos = sb.toString();
LibQuiche.INSTANCE.quiche_config_set_application_protos(quicheConfig, theProtos, new size_t(theProtos.length()));
LibQuiche.INSTANCE.quiche_config_set_application_protos(quicheConfig, theProtos, new size_t(theProtos.getBytes(APPLICATION_PROTOCOL_CHARSET).length));
}
QuicheConfig.CongestionControl cc = config.getCongestionControl();
@ -473,7 +475,7 @@ public class QuicheConnection
char_pointer out = new char_pointer();
size_t_pointer outLen = new size_t_pointer();
LibQuiche.INSTANCE.quiche_conn_application_proto(quicheConn, out, outLen);
return out.getValueAsString((int)outLen.getValue(), StandardCharsets.UTF_8);
return out.getValueAsString((int)outLen.getValue(), APPLICATION_PROTOCOL_CHARSET);
}
}

View File

@ -1,6 +1,6 @@
git clone --recursive https://github.com/cloudflare/quiche
cd quiche
git checkout -b tag-0.9.0 tags/0.9.0
git checkout -b tag-0.10.0 tags/0.10.0
cargo build --features ffi
ls ./target/debug/libquiche.so

View File

@ -17,6 +17,7 @@ import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.AbstractMap;
import java.util.ArrayList;
@ -41,7 +42,7 @@ public class LowLevelQuicheTest
private InetSocketAddress clientSocketAddress;
private InetSocketAddress serverSocketAddress;
private QuicheConfig quicheClientConfig;
private QuicheConfig clientQuicheConfig;
private QuicheConfig serverQuicheConfig;
private QuicheConnection.TokenMinter tokenMinter;
private QuicheConnection.TokenValidator tokenValidator;
@ -52,18 +53,18 @@ public class LowLevelQuicheTest
clientSocketAddress = new InetSocketAddress("localhost", 9999);
serverSocketAddress = new InetSocketAddress("localhost", 8888);
quicheClientConfig = new QuicheConfig();
quicheClientConfig.setApplicationProtos("http/0.9");
quicheClientConfig.setDisableActiveMigration(true);
quicheClientConfig.setVerifyPeer(false);
quicheClientConfig.setMaxIdleTimeout(1_000L);
quicheClientConfig.setInitialMaxData(10_000_000L);
quicheClientConfig.setInitialMaxStreamDataBidiLocal(10_000_000L);
quicheClientConfig.setInitialMaxStreamDataBidiRemote(10_000_000L);
quicheClientConfig.setInitialMaxStreamDataUni(10_000_000L);
quicheClientConfig.setInitialMaxStreamsUni(100L);
quicheClientConfig.setInitialMaxStreamsBidi(100L);
quicheClientConfig.setCongestionControl(QuicheConfig.CongestionControl.RENO);
clientQuicheConfig = new QuicheConfig();
clientQuicheConfig.setApplicationProtos("http/0.9");
clientQuicheConfig.setDisableActiveMigration(true);
clientQuicheConfig.setVerifyPeer(false);
clientQuicheConfig.setMaxIdleTimeout(1_000L);
clientQuicheConfig.setInitialMaxData(10_000_000L);
clientQuicheConfig.setInitialMaxStreamDataBidiLocal(10_000_000L);
clientQuicheConfig.setInitialMaxStreamDataBidiRemote(10_000_000L);
clientQuicheConfig.setInitialMaxStreamDataUni(10_000_000L);
clientQuicheConfig.setInitialMaxStreamsUni(100L);
clientQuicheConfig.setInitialMaxStreamsBidi(100L);
clientQuicheConfig.setCongestionControl(QuicheConfig.CongestionControl.RENO);
SSLKeyPair serverKeyPair = new SSLKeyPair(Paths.get(Objects.requireNonNull(getClass().getResource("/keystore.p12")).toURI()).toFile(), "PKCS12", "storepwd".toCharArray(), "mykey", "storepwd".toCharArray());
File[] pemFiles = serverKeyPair.export(new File(System.getProperty("java.io.tmpdir")));
@ -165,6 +166,21 @@ public class LowLevelQuicheTest
assertThat(serverQuicheConnection.isStreamFinished(0), is(true));
}
@Test
public void testApplicationProtocol() throws Exception
{
serverQuicheConfig.setApplicationProtos("");
clientQuicheConfig.setApplicationProtos("");
// establish connection
Map.Entry<QuicheConnection, QuicheConnection> entry = connectClientToServer();
QuicheConnection clientQuicheConnection = entry.getKey();
QuicheConnection serverQuicheConnection = entry.getValue();
assertThat(clientQuicheConnection.getNegotiatedProtocol(), is(""));
assertThat(serverQuicheConnection.getNegotiatedProtocol(), is(""));
}
private void drainServerToFeedClient(Map.Entry<QuicheConnection, QuicheConnection> entry, int expectedSize) throws IOException
{
QuicheConnection clientQuicheConnection = entry.getKey();
@ -196,7 +212,7 @@ public class LowLevelQuicheTest
ByteBuffer buffer = ByteBuffer.allocate(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN);
ByteBuffer buffer2 = ByteBuffer.allocate(LibQuiche.QUICHE_MIN_CLIENT_INITIAL_LEN);
QuicheConnection clientQuicheConnection = QuicheConnection.connect(quicheClientConfig, serverSocketAddress);
QuicheConnection clientQuicheConnection = QuicheConnection.connect(clientQuicheConfig, serverSocketAddress);
connectionsToDisposeOf.add(clientQuicheConnection);
int drained = clientQuicheConnection.drainCipherText(buffer);
@ -234,7 +250,12 @@ public class LowLevelQuicheTest
AbstractMap.SimpleImmutableEntry<QuicheConnection, QuicheConnection> entry = new AbstractMap.SimpleImmutableEntry<>(clientQuicheConnection, serverQuicheConnection);
drainServerToFeedClient(entry, 309);
StringBuilder sb = new StringBuilder();
for (String proto : clientQuicheConfig.getApplicationProtos())
sb.append((char)proto.getBytes(StandardCharsets.UTF_8).length).append(proto);
int protosLen = sb.toString().getBytes(StandardCharsets.UTF_8).length;
drainServerToFeedClient(entry, 300 + protosLen);
assertThat(serverQuicheConnection.isConnectionEstablished(), is(false));
assertThat(clientQuicheConnection.isConnectionEstablished(), is(true));