QUIC: Add support for datagram injection
authorHugo Landau <hlandau@openssl.org>
Mon, 6 Mar 2023 17:58:32 +0000 (17:58 +0000)
committerPauli <pauli@openssl.org>
Tue, 21 Mar 2023 23:14:25 +0000 (10:14 +1100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20451)

doc/man3/SSL_inject_net_dgram.pod [new file with mode: 0644]
include/internal/quic_channel.h
include/openssl/ssl.h.in
ssl/quic/quic_channel.c
ssl/quic/quic_impl.c
util/libssl.num

diff --git a/doc/man3/SSL_inject_net_dgram.pod b/doc/man3/SSL_inject_net_dgram.pod
new file mode 100644 (file)
index 0000000..01714ac
--- /dev/null
@@ -0,0 +1,51 @@
+=pod
+
+=head1 NAME
+
+SSL_inject_net_dgram - inject a datagram as though received from the network
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,
+                          size_t buf_len,
+                          const BIO_ADDR *peer,
+                          const BIO_ADDR *local);
+
+=head1 DESCRIPTION
+
+This function can be used to inject a datagram payload to a QUIC connection SSL
+object. The payload is processed as though it was received from the network.
+This function can be used for debugging purposes or to allow datagrams to be fed
+to QUIC from alternative sources.
+
+I<buf> is required and must point to a datagram payload to inject. I<buf_len> is
+the length of the buffer in bytes. The buffer is copied and need not remain
+valid after this function returns.
+
+I<peer> and I<local> are optional values pointing to B<BIO_ADDR> structures
+describing the remote and local UDP endpoint addresses for the packet. Though
+the injected packet was not actually received from the network directly by
+OpenSSL, the packet will be processed as though the received datagram had the
+given addresses.
+
+=head1 RETURN VALUES
+
+Returns 1 on success or 0 on failure. This function always fails if called
+on a SSL object which is not a QUIC connection SSL object.
+
+=head1 SEE ALSO
+
+L<OSSL_QUIC_client_method(3)>, L<SSL_tick(3)>, L<SSL_set_blocking_mode(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 29682ff72f53fff78e7ab0c32e6075eec93eadfa..f08252d1f9ec115f4346b29982967e7b547e8e2c 100644 (file)
@@ -194,6 +194,8 @@ int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch);
 int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch);
 int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch);
 
+QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch);
+
 SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch);
 
 # endif
index b669cec88838241f3306ccce881aa29d9d6d70a3..a50378f27dda0d1e2772efac903801e7d12aee52 100644 (file)
@@ -2257,6 +2257,12 @@ __owur int SSL_net_write_desired(SSL *s);
 __owur int SSL_set_blocking_mode(SSL *s, int blocking);
 __owur int SSL_get_blocking_mode(SSL *s);
 __owur int SSL_set_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr);
+# ifndef OPENSSL_NO_QUIC
+__owur int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,
+                                size_t buf_len,
+                                const BIO_ADDR *peer,
+                                const BIO_ADDR *local);
+# endif
 
 typedef struct ssl_shutdown_ex_args_st {
     uint64_t    quic_error_code;
index 984ee871b2f1c307c90ac59172f7c5727cb9ab37..86eed313ab447a4f1294db80d53e3e7e9255287c 100644 (file)
@@ -438,6 +438,11 @@ int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch)
     return ch->handshake_confirmed;
 }
 
+QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch)
+{
+    return ch->demux;
+}
+
 /*
  * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components
  * ================================================================
index 12099043ff79ceb8923ad6436cd8081997b6e3fa..436d2efc03ab7c000ec03910d4ab6a046a082323 100644 (file)
@@ -1244,6 +1244,29 @@ int ossl_quic_conn_stream_conclude(QUIC_CONNECTION *qc)
     return 1;
 }
 
+/*
+ * SSL_inject_net_dgram
+ * --------------------
+ */
+int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,
+                         size_t buf_len,
+                         const BIO_ADDR *peer,
+                         const BIO_ADDR *local)
+{
+    QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+    QUIC_DEMUX *demux;
+
+    if (!expect_quic_conn(qc))
+        return 0;
+
+    if (qc->ch == NULL)
+        return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
+                                           NULL);
+
+    demux = ossl_quic_channel_get0_demux(qc->ch);
+    return ossl_quic_demux_inject(demux, buf, buf_len, peer, local);
+}
+
 /*
  * QUIC Front-End I/O API: SSL_CTX Management
  * ==========================================
index 0c5e2f5d59a62923f29c4e099ec7e9aece2113ae..f697f31114aaeb64382bbd25526dba8eb0ee7531 100644 (file)
@@ -543,3 +543,4 @@ SSL_net_read_desired                    ?   3_2_0   EXIST::FUNCTION:
 SSL_net_write_desired                   ?      3_2_0   EXIST::FUNCTION:
 SSL_shutdown_ex                         ?      3_2_0   EXIST::FUNCTION:
 SSL_stream_conclude                     ?      3_2_0   EXIST::FUNCTION:
+SSL_inject_net_dgram                    ?      3_2_0   EXIST::FUNCTION:QUIC