summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-08-14 16:32:44 +0100
committerMatt Caswell <matt@openssl.org>2023-08-25 11:42:51 +0100
commitf6225f4f692ab45c0e891f83a7782a7dcd211204 (patch)
tree8b67ee21b8e5644c902c41eb7fd76ac38f4cf684 /util
parent584140fa4b0a037c85b58722a08ba6fd0ee086ce (diff)
Update quicserver to be able to handle multiple streams
We extend quicserver so that it can handle multiple requests with an HTTP request on each one. If a uni-directional stream comes in we create a uni-directional stream for the response Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Hugo Landau <hlandau@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21765)
Diffstat (limited to 'util')
-rw-r--r--util/quicserver.c102
1 files changed, 66 insertions, 36 deletions
diff --git a/util/quicserver.c b/util/quicserver.c
index 25ac21691f..c25128eaf6 100644
--- a/util/quicserver.c
+++ b/util/quicserver.c
@@ -149,9 +149,16 @@ int main(int argc, char *argv[])
const char reqterm[] = {
'\r', '\n', '\r', '\n'
};
- const char *msg = "Hello world\n";
+ const char *response[] = {
+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Hello world</body>\n</html>\n",
+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Hello again</body>\n</html>\n",
+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>Another response</body>\n</html>\n",
+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n<!DOCTYPE html>\n<html>\n<body>A message</body>\n</html>\n",
+ };
unsigned char alpn[] = { 8, 'h', 't', 't', 'p', '/', '1', '.', '0' };
int first = 1;
+ uint64_t streamid;
+ size_t respnum = 0;
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
if (argc == 0 || bio_err == NULL)
@@ -212,49 +219,72 @@ int main(int argc, char *argv[])
if (trace)
ossl_quic_tserver_set_msg_callback(qtserv, SSL_trace, bio_err);
- /* Read the request */
- do {
- if (first)
- first = 0;
- else
- wait_for_activity(qtserv);
-
+ /* Wait for handshake to complete */
+ ossl_quic_tserver_tick(qtserv);
+ while(!ossl_quic_tserver_is_handshake_confirmed(qtserv)) {
+ wait_for_activity(qtserv);
ossl_quic_tserver_tick(qtserv);
+ }
- if (ossl_quic_tserver_read(qtserv, 0, reqbuf + reqbytes,
- sizeof(reqbuf) - reqbytes,
- &numbytes)) {
- if (numbytes > 0)
- fwrite(reqbuf + reqbytes, 1, numbytes, stdout);
- reqbytes += numbytes;
+ for (;; respnum++) {
+ if (respnum >= OSSL_NELEM(response))
+ goto end;
+ /* Wait for an incoming stream */
+ do {
+ streamid = ossl_quic_tserver_pop_incoming_stream(qtserv);
+ if (streamid == UINT64_MAX)
+ wait_for_activity(qtserv);
+ ossl_quic_tserver_tick(qtserv);
+ if (ossl_quic_tserver_is_terminated(qtserv)) {
+ /* Assume we finished everything the clients wants from us */
+ ret = EXIT_SUCCESS;
+ goto end;
+ }
+ } while(streamid == UINT64_MAX);
+
+ /* Read the request */
+ do {
+ if (first)
+ first = 0;
+ else
+ wait_for_activity(qtserv);
+
+ ossl_quic_tserver_tick(qtserv);
+
+ if (ossl_quic_tserver_read(qtserv, streamid, reqbuf + reqbytes,
+ sizeof(reqbuf) - reqbytes,
+ &numbytes)) {
+ if (numbytes > 0)
+ fwrite(reqbuf + reqbytes, 1, numbytes, stdout);
+ reqbytes += numbytes;
+ }
+ } while (reqbytes < sizeof(reqterm)
+ || memcmp(reqbuf + reqbytes - sizeof(reqterm), reqterm,
+ sizeof(reqterm)) != 0);
+
+ if ((streamid & QUIC_STREAM_DIR_UNI) != 0) {
+ /*
+ * Incoming stream was uni-directional. Create a server initiated
+ * uni-directional stream for the response.
+ */
+ if (!ossl_quic_tserver_stream_new(qtserv, 1, &streamid)) {
+ BIO_printf(bio_err, "Failed creating response stream\n");
+ goto end;
+ }
}
- } while (reqbytes < sizeof(reqterm)
- || memcmp(reqbuf + reqbytes - sizeof(reqterm), reqterm,
- sizeof(reqterm)) != 0);
-
- /* Send the response */
- ossl_quic_tserver_tick(qtserv);
- if (!ossl_quic_tserver_write(qtserv, 0, (unsigned char *)msg, strlen(msg),
- &numbytes))
- goto end;
+ /* Send the response */
- if (!ossl_quic_tserver_conclude(qtserv, 0))
- goto end;
-
- /* Wait until all data we have sent has been acked */
- while (!ossl_quic_tserver_is_terminated(qtserv)
- && !ossl_quic_tserver_is_stream_totally_acked(qtserv, 0)) {
ossl_quic_tserver_tick(qtserv);
- wait_for_activity(qtserv);
- }
+ if (!ossl_quic_tserver_write(qtserv, streamid,
+ (unsigned char *)response[respnum],
+ strlen(response[respnum]), &numbytes))
+ goto end;
- while (!ossl_quic_tserver_shutdown(qtserv))
- wait_for_activity(qtserv);
-
- /* Close down here */
+ if (!ossl_quic_tserver_conclude(qtserv, streamid))
+ goto end;
+ }
- ret = EXIT_SUCCESS;
end:
/* Free twice because we did an up-ref */
BIO_free(bio);