aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/quic/CMakeLists.txt5
-rw-r--r--src/plugins/quic/certs.c212
-rw-r--r--src/plugins/quic/certs.h48
-rw-r--r--src/plugins/quic/error.c260
-rw-r--r--src/plugins/quic/error.h33
-rw-r--r--src/plugins/quic/quic.c559
-rw-r--r--src/plugins/quic/quic.h42
7 files changed, 634 insertions, 525 deletions
diff --git a/src/plugins/quic/CMakeLists.txt b/src/plugins/quic/CMakeLists.txt
index 70a1243b3b3..5652bdb313e 100644
--- a/src/plugins/quic/CMakeLists.txt
+++ b/src/plugins/quic/CMakeLists.txt
@@ -30,12 +30,11 @@ if(QUICLY_INCLUDE_DIR AND QUIC_LINK_LIBRARIES)
include_directories (${QUICLY_INCLUDE_DIR})
add_vpp_plugin(quic
SOURCES
+ certs.c
+ error.c
quic.c
quic_crypto.c
- INSTALL_HEADERS
- quic.h
-
LINK_LIBRARIES ${QUIC_LINK_LIBRARIES}
)
message(STATUS "Found quicly in ${QUICLY_INCLUDE_DIR}")
diff --git a/src/plugins/quic/certs.c b/src/plugins/quic/certs.c
new file mode 100644
index 00000000000..20d9881d22c
--- /dev/null
+++ b/src/plugins/quic/certs.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <openssl/pem.h>
+
+#include <vppinfra/error.h>
+
+#include <quic/certs.h>
+
+
+int
+ptls_compare_separator_line (const char *line, const char *begin_or_end,
+ const char *label)
+{
+ int ret = strncmp (line, "-----", 5);
+ size_t text_index = 5;
+
+ if (ret == 0)
+ {
+ size_t begin_or_end_length = strlen (begin_or_end);
+ ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
+ text_index += begin_or_end_length;
+ }
+
+ if (ret == 0)
+ {
+ ret = line[text_index] - ' ';
+ text_index++;
+ }
+
+ if (ret == 0)
+ {
+ size_t label_length = strlen (label);
+ ret = strncmp (line + text_index, label, label_length);
+ text_index += label_length;
+ }
+
+ if (ret == 0)
+ {
+ ret = strncmp (line + text_index, "-----", 5);
+ }
+
+ return ret;
+}
+
+int
+ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
+{
+ int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
+ char line[256];
+ ptls_base64_decode_state_t state;
+
+ /* Get the label on a line by itself */
+ while (BIO_gets (bio, line, 256))
+ {
+ if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
+ {
+ ret = 0;
+ ptls_base64_decode_init (&state);
+ break;
+ }
+ }
+ /* Get the data in the buffer */
+ while (ret == 0 && BIO_gets (bio, line, 256))
+ {
+ if (ptls_compare_separator_line (line, "END", label) == 0)
+ {
+ if (state.status == PTLS_BASE64_DECODE_DONE
+ || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
+ && state.nbc == 0))
+ {
+ ret = 0;
+ }
+ else
+ {
+ ret = PTLS_ERROR_INCORRECT_BASE64;
+ }
+ break;
+ }
+ else
+ {
+ ret = ptls_base64_decode (line, &state, buf);
+ }
+ }
+
+ return ret;
+}
+
+int
+ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
+ size_t list_max, size_t * nb_objects)
+{
+ int ret = 0;
+ size_t count = 0;
+
+ *nb_objects = 0;
+
+ if (ret == 0)
+ {
+ while (count < list_max)
+ {
+ ptls_buffer_t buf;
+
+ ptls_buffer_init (&buf, "", 0);
+
+ ret = ptls_get_bio_pem_object (bio, label, &buf);
+
+ if (ret == 0)
+ {
+ if (buf.off > 0 && buf.is_allocated)
+ {
+ list[count].base = buf.base;
+ list[count].len = buf.off;
+ count++;
+ }
+ else
+ {
+ ptls_buffer_dispose (&buf);
+ }
+ }
+ else
+ {
+ ptls_buffer_dispose (&buf);
+ break;
+ }
+ }
+ }
+
+ if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
+ {
+ ret = 0;
+ }
+
+ *nb_objects = count;
+
+ return ret;
+}
+
+#define PTLS_MAX_CERTS_IN_CONTEXT 16
+
+int
+ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
+{
+ int ret = 0;
+
+ ctx->certificates.list =
+ (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
+ sizeof (ptls_iovec_t));
+
+ if (ctx->certificates.list == NULL)
+ {
+ ret = PTLS_ERROR_NO_MEMORY;
+ }
+ else
+ {
+ ret =
+ ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
+ PTLS_MAX_CERTS_IN_CONTEXT,
+ &ctx->certificates.count);
+ }
+
+ return ret;
+}
+
+void
+load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
+{
+ BIO *cert_bio;
+ cert_bio = BIO_new_mem_buf (cert_data, -1);
+ if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
+ {
+ BIO_free (cert_bio);
+ clib_warning ("failed to load certificate:%s\n", strerror (errno));
+ exit (1);
+ }
+ BIO_free (cert_bio);
+}
+
+void
+load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
+{
+ static ptls_openssl_sign_certificate_t sc;
+ EVP_PKEY *pkey;
+ BIO *key_bio;
+
+ key_bio = BIO_new_mem_buf (pk_data, -1);
+ pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
+ BIO_free (key_bio);
+
+ if (pkey == NULL)
+ {
+ clib_warning ("failed to read private key from app configuration\n");
+ exit (1);
+ }
+
+ ptls_openssl_init_sign_certificate (&sc, pkey);
+ EVP_PKEY_free (pkey);
+
+ ctx->sign_certificate = &sc.super;
+}
diff --git a/src/plugins/quic/certs.h b/src/plugins/quic/certs.h
new file mode 100644
index 00000000000..e60f96d55d2
--- /dev/null
+++ b/src/plugins/quic/certs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __included_quic_certs_h__
+#define __included_quic_certs_h__
+
+
+#include <picotls/openssl.h>
+#include <picotls/pembase64.h>
+
+int ptls_compare_separator_line (const char *line, const char *begin_or_end,
+ const char *label);
+
+int ptls_get_bio_pem_object (BIO * bio, const char *label,
+ ptls_buffer_t * buf);
+
+int ptls_load_bio_pem_objects (BIO * bio, const char *label,
+ ptls_iovec_t * list, size_t list_max,
+ size_t * nb_objects);
+
+int ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio);
+
+void load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data);
+
+void load_bio_private_key (ptls_context_t * ctx, const char *pk_data);
+
+
+#endif /* __included_quic_certs_h__ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/quic/error.c b/src/plugins/quic/error.c
new file mode 100644
index 00000000000..72aa99909f6
--- /dev/null
+++ b/src/plugins/quic/error.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <quic/quic.h>
+
+#include <quicly.h>
+
+u8 *
+quic_format_err (u8 * s, va_list * args)
+{
+ u64 code = va_arg (*args, u64);
+ switch (code)
+ {
+ case 0:
+ s = format (s, "no error");
+ break;
+ /* app errors */
+ case QUIC_ERROR_FULL_FIFO:
+ s = format (s, "full fifo");
+ break;
+ case QUIC_APP_ERROR_CLOSE_NOTIFY:
+ s = format (s, "QUIC_APP_ERROR_CLOSE_NOTIFY");
+ break;
+ case QUIC_APP_ALLOCATION_ERROR:
+ s = format (s, "QUIC_APP_ALLOCATION_ERROR");
+ break;
+ case QUIC_APP_ACCEPT_NOTIFY_ERROR:
+ s = format (s, "QUIC_APP_ACCEPT_NOTIFY_ERROR");
+ break;
+ case QUIC_APP_CONNECT_NOTIFY_ERROR:
+ s = format (s, "QUIC_APP_CONNECT_NOTIFY_ERROR");
+ break;
+ /* quicly errors */
+ case QUICLY_ERROR_PACKET_IGNORED:
+ s = format (s, "QUICLY_ERROR_PACKET_IGNORED");
+ break;
+ case QUICLY_ERROR_SENDBUF_FULL:
+ s = format (s, "QUICLY_ERROR_SENDBUF_FULL");
+ break;
+ case QUICLY_ERROR_FREE_CONNECTION:
+ s = format (s, "QUICLY_ERROR_FREE_CONNECTION");
+ break;
+ case QUICLY_ERROR_RECEIVED_STATELESS_RESET:
+ s = format (s, "QUICLY_ERROR_RECEIVED_STATELESS_RESET");
+ break;
+ case QUICLY_TRANSPORT_ERROR_NONE:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_NONE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_INTERNAL:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_INTERNAL");
+ break;
+ case QUICLY_TRANSPORT_ERROR_SERVER_BUSY:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_SERVER_BUSY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_FLOW_CONTROL:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_FLOW_CONTROL");
+ break;
+ case QUICLY_TRANSPORT_ERROR_STREAM_LIMIT:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_STREAM_LIMIT");
+ break;
+ case QUICLY_TRANSPORT_ERROR_STREAM_STATE:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_STREAM_STATE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_FINAL_OFFSET:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_FINAL_OFFSET");
+ break;
+ case QUICLY_TRANSPORT_ERROR_FRAME_ENCODING:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_FRAME_ENCODING");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER");
+ break;
+ case QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION:
+ s = format (s, "QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION");
+ break;
+ /* picotls errors */
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CLOSE_NOTIFY):
+ s =
+ format (s, "PTLS_ALERT_CLOSE_NOTIFY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNEXPECTED_MESSAGE):
+ s =
+ format (s, "PTLS_ALERT_UNEXPECTED_MESSAGE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_BAD_RECORD_MAC):
+ s =
+ format (s, "PTLS_ALERT_BAD_RECORD_MAC");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_HANDSHAKE_FAILURE):
+ s =
+ format (s, "PTLS_ALERT_HANDSHAKE_FAILURE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_BAD_CERTIFICATE):
+ s =
+ format (s, "PTLS_ALERT_BAD_CERTIFICATE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_REVOKED):
+ s =
+ format (s, "PTLS_ALERT_CERTIFICATE_REVOKED");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_EXPIRED):
+ s =
+ format (s, "PTLS_ALERT_CERTIFICATE_EXPIRED");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_UNKNOWN):
+ s =
+ format (s, "PTLS_ALERT_CERTIFICATE_UNKNOWN");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_ILLEGAL_PARAMETER):
+ s =
+ format (s, "PTLS_ALERT_ILLEGAL_PARAMETER");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNKNOWN_CA):
+ s =
+ format (s, "PTLS_ALERT_UNKNOWN_CA");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_DECODE_ERROR):
+ s =
+ format (s, "PTLS_ALERT_DECODE_ERROR");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_DECRYPT_ERROR):
+ s =
+ format (s, "PTLS_ALERT_DECRYPT_ERROR");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_PROTOCOL_VERSION):
+ s =
+ format (s, "PTLS_ALERT_PROTOCOL_VERSION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_INTERNAL_ERROR):
+ s =
+ format (s, "PTLS_ALERT_INTERNAL_ERROR");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_USER_CANCELED):
+ s =
+ format (s, "PTLS_ALERT_USER_CANCELED");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_MISSING_EXTENSION):
+ s =
+ format (s, "PTLS_ALERT_MISSING_EXTENSION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNRECOGNIZED_NAME):
+ s =
+ format (s, "PTLS_ALERT_UNRECOGNIZED_NAME");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_REQUIRED):
+ s =
+ format (s, "PTLS_ALERT_CERTIFICATE_REQUIRED");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_NO_APPLICATION_PROTOCOL):
+ s =
+ format (s, "PTLS_ALERT_NO_APPLICATION_PROTOCOL");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_NO_MEMORY):
+ s =
+ format (s, "PTLS_ERROR_NO_MEMORY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_IN_PROGRESS):
+ s =
+ format (s, "PTLS_ERROR_IN_PROGRESS");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_LIBRARY):
+ s =
+ format (s, "PTLS_ERROR_LIBRARY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCOMPATIBLE_KEY):
+ s =
+ format (s, "PTLS_ERROR_INCOMPATIBLE_KEY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_SESSION_NOT_FOUND):
+ s =
+ format (s, "PTLS_ERROR_SESSION_NOT_FOUND");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_STATELESS_RETRY):
+ s =
+ format (s, "PTLS_ERROR_STATELESS_RETRY");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_NOT_AVAILABLE):
+ s =
+ format (s, "PTLS_ERROR_NOT_AVAILABLE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_COMPRESSION_FAILURE):
+ s =
+ format (s, "PTLS_ERROR_COMPRESSION_FAILURE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_INCORRECT_ENCODING):
+ s =
+ format (s, "PTLS_ERROR_BER_INCORRECT_ENCODING");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_MALFORMED_TYPE):
+ s =
+ format (s, "PTLS_ERROR_BER_MALFORMED_TYPE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_MALFORMED_LENGTH):
+ s =
+ format (s, "PTLS_ERROR_BER_MALFORMED_LENGTH");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_EXCESSIVE_LENGTH):
+ s =
+ format (s, "PTLS_ERROR_BER_EXCESSIVE_LENGTH");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_ELEMENT_TOO_SHORT):
+ s =
+ format (s, "PTLS_ERROR_BER_ELEMENT_TOO_SHORT");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_UNEXPECTED_EOC):
+ s =
+ format (s, "PTLS_ERROR_BER_UNEXPECTED_EOC");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_DER_INDEFINITE_LENGTH):
+ s =
+ format (s, "PTLS_ERROR_DER_INDEFINITE_LENGTH");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_ASN1_SYNTAX):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_ASN1_SYNTAX");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_KEY_VERSION):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_PEM_KEY_VERSION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE");
+ break;
+ case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX):
+ s =
+ format (s, "PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX");
+ break;
+ default:
+ s = format (s, "unknown error 0x%lx", code);
+ break;
+ }
+ return s;
+}
diff --git a/src/plugins/quic/error.h b/src/plugins/quic/error.h
new file mode 100644
index 00000000000..4dce2459a49
--- /dev/null
+++ b/src/plugins/quic/error.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __included_quic_error_h__
+#define __included_quic_error_h__
+
+#include <stdarg.h>
+
+#include <vppinfra/format.h>
+
+u8 *quic_format_err (u8 * s, va_list * args);
+
+#endif /* __included_quic_error_h__ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c
index 435113a8cd2..9ec7fd869d5 100644
--- a/src/plugins/quic/quic.c
+++ b/src/plugins/quic/quic.c
@@ -20,263 +20,20 @@
#include <vnet/session/session.h>
#include <vlib/unix/plugin.h>
#include <vpp/app/version.h>
-#include <openssl/pem.h>
#include <vppinfra/lock.h>
#include <quic/quic.h>
+#include <quic/certs.h>
+#include <quic/error.h>
+#include <quic/quic_crypto.h>
#include <quicly/defaults.h>
-#include <picotls/openssl.h>
-#include <picotls/pembase64.h>
-#include <quic/quic_crypto.h>
static quic_main_t quic_main;
static void quic_update_timer (quic_ctx_t * ctx);
-static u8 *
-quic_format_err (u8 * s, va_list * args)
-{
- u64 code = va_arg (*args, u64);
- switch (code)
- {
- case 0:
- s = format (s, "no error");
- break;
- /* app errors */
- case QUIC_ERROR_FULL_FIFO:
- s = format (s, "full fifo");
- break;
- case QUIC_APP_ERROR_CLOSE_NOTIFY:
- s = format (s, "QUIC_APP_ERROR_CLOSE_NOTIFY");
- break;
- case QUIC_APP_ALLOCATION_ERROR:
- s = format (s, "QUIC_APP_ALLOCATION_ERROR");
- break;
- case QUIC_APP_ACCEPT_NOTIFY_ERROR:
- s = format (s, "QUIC_APP_ACCEPT_NOTIFY_ERROR");
- break;
- case QUIC_APP_CONNECT_NOTIFY_ERROR:
- s = format (s, "QUIC_APP_CONNECT_NOTIFY_ERROR");
- break;
- /* quicly errors */
- case QUICLY_ERROR_PACKET_IGNORED:
- s = format (s, "QUICLY_ERROR_PACKET_IGNORED");
- break;
- case QUICLY_ERROR_SENDBUF_FULL:
- s = format (s, "QUICLY_ERROR_SENDBUF_FULL");
- break;
- case QUICLY_ERROR_FREE_CONNECTION:
- s = format (s, "QUICLY_ERROR_FREE_CONNECTION");
- break;
- case QUICLY_ERROR_RECEIVED_STATELESS_RESET:
- s = format (s, "QUICLY_ERROR_RECEIVED_STATELESS_RESET");
- break;
- case QUICLY_TRANSPORT_ERROR_NONE:
- s = format (s, "QUICLY_TRANSPORT_ERROR_NONE");
- break;
- case QUICLY_TRANSPORT_ERROR_INTERNAL:
- s = format (s, "QUICLY_TRANSPORT_ERROR_INTERNAL");
- break;
- case QUICLY_TRANSPORT_ERROR_SERVER_BUSY:
- s = format (s, "QUICLY_TRANSPORT_ERROR_SERVER_BUSY");
- break;
- case QUICLY_TRANSPORT_ERROR_FLOW_CONTROL:
- s = format (s, "QUICLY_TRANSPORT_ERROR_FLOW_CONTROL");
- break;
- case QUICLY_TRANSPORT_ERROR_STREAM_LIMIT:
- s = format (s, "QUICLY_TRANSPORT_ERROR_STREAM_LIMIT");
- break;
- case QUICLY_TRANSPORT_ERROR_STREAM_STATE:
- s = format (s, "QUICLY_TRANSPORT_ERROR_STREAM_STATE");
- break;
- case QUICLY_TRANSPORT_ERROR_FINAL_OFFSET:
- s = format (s, "QUICLY_TRANSPORT_ERROR_FINAL_OFFSET");
- break;
- case QUICLY_TRANSPORT_ERROR_FRAME_ENCODING:
- s = format (s, "QUICLY_TRANSPORT_ERROR_FRAME_ENCODING");
- break;
- case QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER:
- s = format (s, "QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER");
- break;
- case QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION:
- s = format (s, "QUICLY_TRANSPORT_ERROR_VERSION_NEGOTIATION");
- break;
- case QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION:
- s = format (s, "QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION");
- break;
- case QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION:
- s = format (s, "QUICLY_TRANSPORT_ERROR_INVALID_MIGRATION");
- break;
- /* picotls errors */
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CLOSE_NOTIFY):
- s =
- format (s, "PTLS_ALERT_CLOSE_NOTIFY");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNEXPECTED_MESSAGE):
- s =
- format (s, "PTLS_ALERT_UNEXPECTED_MESSAGE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_BAD_RECORD_MAC):
- s =
- format (s, "PTLS_ALERT_BAD_RECORD_MAC");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_HANDSHAKE_FAILURE):
- s =
- format (s, "PTLS_ALERT_HANDSHAKE_FAILURE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_BAD_CERTIFICATE):
- s =
- format (s, "PTLS_ALERT_BAD_CERTIFICATE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_REVOKED):
- s =
- format (s, "PTLS_ALERT_CERTIFICATE_REVOKED");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_EXPIRED):
- s =
- format (s, "PTLS_ALERT_CERTIFICATE_EXPIRED");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_UNKNOWN):
- s =
- format (s, "PTLS_ALERT_CERTIFICATE_UNKNOWN");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_ILLEGAL_PARAMETER):
- s =
- format (s, "PTLS_ALERT_ILLEGAL_PARAMETER");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNKNOWN_CA):
- s =
- format (s, "PTLS_ALERT_UNKNOWN_CA");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_DECODE_ERROR):
- s =
- format (s, "PTLS_ALERT_DECODE_ERROR");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_DECRYPT_ERROR):
- s =
- format (s, "PTLS_ALERT_DECRYPT_ERROR");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_PROTOCOL_VERSION):
- s =
- format (s, "PTLS_ALERT_PROTOCOL_VERSION");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_INTERNAL_ERROR):
- s =
- format (s, "PTLS_ALERT_INTERNAL_ERROR");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_USER_CANCELED):
- s =
- format (s, "PTLS_ALERT_USER_CANCELED");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_MISSING_EXTENSION):
- s =
- format (s, "PTLS_ALERT_MISSING_EXTENSION");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_UNRECOGNIZED_NAME):
- s =
- format (s, "PTLS_ALERT_UNRECOGNIZED_NAME");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_CERTIFICATE_REQUIRED):
- s =
- format (s, "PTLS_ALERT_CERTIFICATE_REQUIRED");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ALERT_NO_APPLICATION_PROTOCOL):
- s =
- format (s, "PTLS_ALERT_NO_APPLICATION_PROTOCOL");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_NO_MEMORY):
- s =
- format (s, "PTLS_ERROR_NO_MEMORY");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_IN_PROGRESS):
- s =
- format (s, "PTLS_ERROR_IN_PROGRESS");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_LIBRARY):
- s =
- format (s, "PTLS_ERROR_LIBRARY");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCOMPATIBLE_KEY):
- s =
- format (s, "PTLS_ERROR_INCOMPATIBLE_KEY");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_SESSION_NOT_FOUND):
- s =
- format (s, "PTLS_ERROR_SESSION_NOT_FOUND");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_STATELESS_RETRY):
- s =
- format (s, "PTLS_ERROR_STATELESS_RETRY");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_NOT_AVAILABLE):
- s =
- format (s, "PTLS_ERROR_NOT_AVAILABLE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_COMPRESSION_FAILURE):
- s =
- format (s, "PTLS_ERROR_COMPRESSION_FAILURE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_INCORRECT_ENCODING):
- s =
- format (s, "PTLS_ERROR_BER_INCORRECT_ENCODING");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_MALFORMED_TYPE):
- s =
- format (s, "PTLS_ERROR_BER_MALFORMED_TYPE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_MALFORMED_LENGTH):
- s =
- format (s, "PTLS_ERROR_BER_MALFORMED_LENGTH");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_EXCESSIVE_LENGTH):
- s =
- format (s, "PTLS_ERROR_BER_EXCESSIVE_LENGTH");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_ELEMENT_TOO_SHORT):
- s =
- format (s, "PTLS_ERROR_BER_ELEMENT_TOO_SHORT");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_BER_UNEXPECTED_EOC):
- s =
- format (s, "PTLS_ERROR_BER_UNEXPECTED_EOC");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_DER_INDEFINITE_LENGTH):
- s =
- format (s, "PTLS_ERROR_DER_INDEFINITE_LENGTH");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_ASN1_SYNTAX):
- s =
- format (s, "PTLS_ERROR_INCORRECT_ASN1_SYNTAX");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_KEY_VERSION):
- s =
- format (s, "PTLS_ERROR_INCORRECT_PEM_KEY_VERSION");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION):
- s =
- format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_KEY_VERSION");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE):
- s =
- format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_CURVE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE):
- s =
- format (s, "PTLS_ERROR_INCORRECT_PEM_ECDSA_KEYSIZE");
- break;
- case QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT (PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX):
- s =
- format (s, "PTLS_ERROR_INCORRECT_ASN1_ECDSA_KEY_SYNTAX");
- break;
- default:
- s = format (s, "unknown error 0x%lx", code);
- break;
- }
- return s;
-}
-
static u32
quic_ctx_alloc (u32 thread_index)
{
@@ -385,7 +142,7 @@ quic_ack_rx_data (session_t * stream_session)
quic_ctx_get (stream_session->connection_index,
stream_session->thread_index);
ASSERT (quic_ctx_is_stream (sctx));
- stream = sctx->c_quic_ctx_id.stream;
+ stream = sctx->stream;
stream_data = (quic_stream_data_t *) stream->data;
f = stream_session->rx_fifo;
@@ -430,7 +187,7 @@ quic_connection_delete (quic_ctx_t * ctx)
}
/* Delete the connection from the connection map */
- conn = ctx->c_quic_ctx_id.conn;
+ conn = ctx->conn;
quic_make_connection_key (&kv, quicly_get_master_id (conn));
QUIC_DBG (2, "Deleting conn with id %lu %lu from map", kv.key[0],
kv.key[1]);
@@ -438,9 +195,9 @@ quic_connection_delete (quic_ctx_t * ctx)
quic_disconnect_transport (ctx);
- if (ctx->c_quic_ctx_id.conn)
- quicly_free (ctx->c_quic_ctx_id.conn);
- ctx->c_quic_ctx_id.conn = NULL;
+ if (ctx->conn)
+ quicly_free (ctx->conn);
+ ctx->conn = NULL;
session_transport_delete_notify (&ctx->connection);
quic_ctx_free (ctx);
@@ -459,7 +216,7 @@ quic_connection_closed (quic_ctx_t * ctx)
/* TODO if connection is not established, just delete the session? */
/* Actually should send connect or accept error */
- switch (ctx->c_quic_ctx_id.conn_state)
+ switch (ctx->conn_state)
{
case QUIC_CONN_STATE_READY:
/* Error on an opened connection (timeout...)
@@ -467,12 +224,10 @@ quic_connection_closed (quic_ctx_t * ctx)
when the app has closed its session */
session_transport_reset_notify (&ctx->connection);
/* This ensures we delete the connection when the app confirms the close */
- ctx->c_quic_ctx_id.conn_state =
- QUIC_CONN_STATE_PASSIVE_CLOSING_QUIC_CLOSED;
+ ctx->conn_state = QUIC_CONN_STATE_PASSIVE_CLOSING_QUIC_CLOSED;
break;
case QUIC_CONN_STATE_PASSIVE_CLOSING:
- ctx->c_quic_ctx_id.conn_state =
- QUIC_CONN_STATE_PASSIVE_CLOSING_QUIC_CLOSED;
+ ctx->conn_state = QUIC_CONN_STATE_PASSIVE_CLOSING_QUIC_CLOSED;
/* quic_proto_on_close will eventually be called when the app confirms the close
, we delete the connection at that point */
break;
@@ -566,9 +321,7 @@ quic_send_packets (quic_ctx_t * ctx)
/* We have sctx, get qctx */
if (quic_ctx_is_stream (ctx))
- ctx =
- quic_ctx_get (ctx->c_quic_ctx_id.quic_connection_ctx_id,
- ctx->c_thread_index);
+ ctx = quic_ctx_get (ctx->quic_connection_ctx_id, ctx->c_thread_index);
ASSERT (!quic_ctx_is_stream (ctx));
@@ -576,7 +329,7 @@ quic_send_packets (quic_ctx_t * ctx)
if (!udp_session)
goto quicly_error;
- conn = ctx->c_quic_ctx_id.conn;
+ conn = ctx->conn;
if (!conn)
return 0;
@@ -831,10 +584,10 @@ quic_accept_stream (void *s)
sctx = quic_ctx_get (sctx_id, qctx->c_thread_index);
sctx->parent_app_wrk_id = qctx->parent_app_wrk_id;
sctx->parent_app_id = qctx->parent_app_id;
- sctx->c_quic_ctx_id.quic_connection_ctx_id = qctx->c_c_index;
+ sctx->quic_connection_ctx_id = qctx->c_c_index;
sctx->c_c_index = sctx_id;
sctx->c_s_index = stream_session->session_index;
- sctx->c_quic_ctx_id.stream = stream;
+ sctx->stream = stream;
sctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
sctx->flags |= QUIC_F_IS_STREAM;
@@ -848,8 +601,7 @@ quic_accept_stream (void *s)
stream_session->app_wrk_index = sctx->parent_app_wrk_id;
stream_session->connection_index = sctx->c_c_index;
stream_session->session_type =
- session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC,
- qctx->c_quic_ctx_id.udp_is_ip4);
+ session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC, qctx->udp_is_ip4);
quic_session = session_get (qctx->c_s_index, qctx->c_thread_index);
stream_session->listener_handle = listen_session_get_handle (quic_session);
@@ -902,7 +654,7 @@ quic_on_closed_by_peer (quicly_closed_by_peer_t * self, quicly_conn_t * conn,
session_handle (quic_session), quic_format_err, code,
reason_len, reason);
#endif
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_PASSIVE_CLOSING;
+ ctx->conn_state = QUIC_CONN_STATE_PASSIVE_CLOSING;
session_transport_closing_notify (&ctx->connection);
}
@@ -977,7 +729,7 @@ quic_update_timer (quic_ctx_t * ctx)
session_t *quic_session;
/* This timeout is in ms which is the unit of our timer */
- next_timeout = quicly_get_first_timeout (ctx->c_quic_ctx_id.conn);
+ next_timeout = quicly_get_first_timeout (ctx->conn);
next_interval = next_timeout - quic_get_time (NULL);
if (next_timeout == 0 || next_interval <= 0)
@@ -1126,197 +878,6 @@ static ptls_context_t quic_tlsctx = {
};
/* *INDENT-ON* */
-static int
-ptls_compare_separator_line (const char *line, const char *begin_or_end,
- const char *label)
-{
- int ret = strncmp (line, "-----", 5);
- size_t text_index = 5;
-
- if (ret == 0)
- {
- size_t begin_or_end_length = strlen (begin_or_end);
- ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
- text_index += begin_or_end_length;
- }
-
- if (ret == 0)
- {
- ret = line[text_index] - ' ';
- text_index++;
- }
-
- if (ret == 0)
- {
- size_t label_length = strlen (label);
- ret = strncmp (line + text_index, label, label_length);
- text_index += label_length;
- }
-
- if (ret == 0)
- {
- ret = strncmp (line + text_index, "-----", 5);
- }
-
- return ret;
-}
-
-static int
-ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
-{
- int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
- char line[256];
- ptls_base64_decode_state_t state;
-
- /* Get the label on a line by itself */
- while (BIO_gets (bio, line, 256))
- {
- if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
- {
- ret = 0;
- ptls_base64_decode_init (&state);
- break;
- }
- }
- /* Get the data in the buffer */
- while (ret == 0 && BIO_gets (bio, line, 256))
- {
- if (ptls_compare_separator_line (line, "END", label) == 0)
- {
- if (state.status == PTLS_BASE64_DECODE_DONE
- || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
- && state.nbc == 0))
- {
- ret = 0;
- }
- else
- {
- ret = PTLS_ERROR_INCORRECT_BASE64;
- }
- break;
- }
- else
- {
- ret = ptls_base64_decode (line, &state, buf);
- }
- }
-
- return ret;
-}
-
-static int
-ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
- size_t list_max, size_t * nb_objects)
-{
- int ret = 0;
- size_t count = 0;
-
- *nb_objects = 0;
-
- if (ret == 0)
- {
- while (count < list_max)
- {
- ptls_buffer_t buf;
-
- ptls_buffer_init (&buf, "", 0);
-
- ret = ptls_get_bio_pem_object (bio, label, &buf);
-
- if (ret == 0)
- {
- if (buf.off > 0 && buf.is_allocated)
- {
- list[count].base = buf.base;
- list[count].len = buf.off;
- count++;
- }
- else
- {
- ptls_buffer_dispose (&buf);
- }
- }
- else
- {
- ptls_buffer_dispose (&buf);
- break;
- }
- }
- }
-
- if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
- {
- ret = 0;
- }
-
- *nb_objects = count;
-
- return ret;
-}
-
-#define PTLS_MAX_CERTS_IN_CONTEXT 16
-
-static int
-ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
-{
- int ret = 0;
-
- ctx->certificates.list =
- (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
- sizeof (ptls_iovec_t));
-
- if (ctx->certificates.list == NULL)
- {
- ret = PTLS_ERROR_NO_MEMORY;
- }
- else
- {
- ret =
- ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
- PTLS_MAX_CERTS_IN_CONTEXT,
- &ctx->certificates.count);
- }
-
- return ret;
-}
-
-static inline void
-load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
-{
- BIO *cert_bio;
- cert_bio = BIO_new_mem_buf (cert_data, -1);
- if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
- {
- BIO_free (cert_bio);
- fprintf (stderr, "failed to load certificate:%s\n", strerror (errno));
- exit (1);
- }
- BIO_free (cert_bio);
-}
-
-static inline void
-load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
-{
- static ptls_openssl_sign_certificate_t sc;
- EVP_PKEY *pkey;
- BIO *key_bio;
-
- key_bio = BIO_new_mem_buf (pk_data, -1);
- pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
- BIO_free (key_bio);
-
- if (pkey == NULL)
- {
- fprintf (stderr, "failed to read private key from app configuration\n");
- exit (1);
- }
-
- ptls_openssl_init_sign_certificate (&sc, pkey);
- EVP_PKEY_free (pkey);
-
- ctx->sign_certificate = &sc.super;
-}
-
static void
allocate_quicly_ctx (application_t * app, u8 is_client)
{
@@ -1421,12 +982,12 @@ quic_connect_new_stream (session_t * quic_session, u32 opaque)
sctx->parent_app_wrk_id = qctx->parent_app_wrk_id;
sctx->parent_app_id = qctx->parent_app_id;
- sctx->c_quic_ctx_id.quic_connection_ctx_id = qctx->c_c_index;
+ sctx->quic_connection_ctx_id = qctx->c_c_index;
sctx->c_c_index = sctx_index;
sctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
sctx->flags |= QUIC_F_IS_STREAM;
- conn = qctx->c_quic_ctx_id.conn;
+ conn = qctx->conn;
if (!conn || !quicly_connection_is_ready (conn))
return -1;
@@ -1436,7 +997,7 @@ quic_connect_new_stream (session_t * quic_session, u32 opaque)
QUIC_DBG (2, "Stream open failed with %d", rv);
return -1;
}
- sctx->c_quic_ctx_id.stream = stream;
+ sctx->stream = stream;
QUIC_DBG (2, "Opened stream %d, creating session", stream->stream_id);
@@ -1447,8 +1008,7 @@ quic_connect_new_stream (session_t * quic_session, u32 opaque)
stream_session->connection_index = sctx_index;
stream_session->listener_handle = quic_session_handle;
stream_session->session_type =
- session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC,
- qctx->c_quic_ctx_id.udp_is_ip4);
+ session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC, qctx->udp_is_ip4);
sctx->c_s_index = stream_session->session_index;
@@ -1497,20 +1057,20 @@ quic_connect_new_connection (session_endpoint_cfg_t * sep)
ctx->parent_app_wrk_id = sep->app_wrk_index;
ctx->c_s_index = QUIC_SESSION_INVALID;
ctx->c_c_index = ctx_index;
- ctx->c_quic_ctx_id.udp_is_ip4 = sep->is_ip4;
+ ctx->udp_is_ip4 = sep->is_ip4;
ctx->timer_handle = QUIC_TIMER_HANDLE_INVALID;
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_HANDSHAKE;
- ctx->c_quic_ctx_id.client_opaque = sep->opaque;
+ ctx->conn_state = QUIC_CONN_STATE_HANDSHAKE;
+ ctx->client_opaque = sep->opaque;
ctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
if (sep->hostname)
{
- ctx->c_quic_ctx_id.srv_hostname = format (0, "%v", sep->hostname);
- vec_terminate_c_string (ctx->c_quic_ctx_id.srv_hostname);
+ ctx->srv_hostname = format (0, "%v", sep->hostname);
+ vec_terminate_c_string (ctx->srv_hostname);
}
else
{
/* needed by quic for crypto + determining client / server */
- ctx->c_quic_ctx_id.srv_hostname =
+ ctx->srv_hostname =
format (0, "%U", format_ip46_address, &sep->ip, sep->is_ip4);
}
@@ -1560,16 +1120,16 @@ quic_proto_on_close (u32 ctx_index, u32 thread_index)
#endif
if (quic_ctx_is_stream (ctx))
{
- quicly_stream_t *stream = ctx->c_quic_ctx_id.stream;
+ quicly_stream_t *stream = ctx->stream;
quicly_reset_stream (stream, QUIC_APP_ERROR_CLOSE_NOTIFY);
quic_send_packets (ctx);
}
- switch (ctx->c_quic_ctx_id.conn_state)
+ switch (ctx->conn_state)
{
case QUIC_CONN_STATE_READY:
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_ACTIVE_CLOSING;
- quicly_conn_t *conn = ctx->c_quic_ctx_id.conn;
+ ctx->conn_state = QUIC_CONN_STATE_ACTIVE_CLOSING;
+ quicly_conn_t *conn = ctx->conn;
/* Start connection closing. Keep sending packets until quicly_send
returns QUICLY_ERROR_FREE_CONNECTION */
quicly_close (conn, QUIC_APP_ERROR_CLOSE_NOTIFY, "Closed by peer");
@@ -1577,8 +1137,7 @@ quic_proto_on_close (u32 ctx_index, u32 thread_index)
quic_send_packets (ctx);
break;
case QUIC_CONN_STATE_PASSIVE_CLOSING:
- ctx->c_quic_ctx_id.conn_state =
- QUIC_CONN_STATE_PASSIVE_CLOSING_APP_CLOSED;
+ ctx->conn_state = QUIC_CONN_STATE_PASSIVE_CLOSING_APP_CLOSED;
/* send_packets will eventually return an error, we delete the conn at
that point */
break;
@@ -1703,8 +1262,7 @@ format_quic_ctx (u8 * s, va_list * args)
str = format (str, "Listener, UDP %ld", ctx->udp_session_handle);
else if (quic_ctx_is_stream (ctx))
str = format (str, "Stream %ld conn %d",
- ctx->c_quic_ctx_id.stream->stream_id,
- ctx->c_quic_ctx_id.quic_connection_ctx_id);
+ ctx->stream->stream_id, ctx->quic_connection_ctx_id);
else /* connection */
str = format (str, "Conn %d UDP %d", ctx->c_c_index,
ctx->udp_session_handle);
@@ -1713,7 +1271,7 @@ format_quic_ctx (u8 * s, va_list * args)
ctx->parent_app_wrk_id);
if (verbose == 1)
- s = format (s, "%-50s%-15d", str, ctx->c_quic_ctx_id.conn_state);
+ s = format (s, "%-50s%-15d", str, ctx->conn_state);
else
s = format (s, "%s\n", str);
vec_free (str);
@@ -1806,20 +1364,17 @@ quic_on_client_connected (quic_ctx_t * ctx)
quic_session->connection_index = ctx->c_c_index;
quic_session->listener_handle = SESSION_INVALID_HANDLE;
quic_session->session_type =
- session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC,
- ctx->c_quic_ctx_id.udp_is_ip4);
+ session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC, ctx->udp_is_ip4);
if (app_worker_init_connected (app_wrk, quic_session))
{
QUIC_DBG (1, "failed to app_worker_init_connected");
quic_proto_on_close (ctx_id, thread_index);
- return app_worker_connect_notify (app_wrk, NULL,
- ctx->c_quic_ctx_id.client_opaque);
+ return app_worker_connect_notify (app_wrk, NULL, ctx->client_opaque);
}
quic_session->session_state = SESSION_STATE_CONNECTING;
- if (app_worker_connect_notify
- (app_wrk, quic_session, ctx->c_quic_ctx_id.client_opaque))
+ if (app_worker_connect_notify (app_wrk, quic_session, ctx->client_opaque))
{
QUIC_DBG (1, "failed to notify app");
quic_proto_on_close (ctx_id, thread_index);
@@ -1855,7 +1410,7 @@ quic_receive_connection (void *arg)
new_ctx->c_thread_index = thread_index;
new_ctx->c_c_index = new_ctx_id;
- conn = new_ctx->c_quic_ctx_id.conn;
+ conn = new_ctx->conn;
quic_store_conn_ctx (conn, new_ctx);
quic_make_connection_key (&kv, quicly_get_master_id (conn));
kv.value = ((u64) thread_index) << 32 | (u64) new_ctx_id;
@@ -1885,7 +1440,7 @@ quic_transfer_connection (u32 ctx_index, u32 dest_thread)
memcpy (temp_ctx, ctx, sizeof (quic_ctx_t));
/* Remove from lookup hash, timer wheel and thread-local pool */
- conn = ctx->c_quic_ctx_id.conn;
+ conn = ctx->conn;
quic_make_connection_key (&kv, quicly_get_master_id (conn));
clib_bihash_add_del_16_8 (&quic_main.connection_hash, &kv, 0 /* is_add */ );
if (ctx->timer_handle != QUIC_TIMER_HANDLE_INVALID)
@@ -1986,17 +1541,17 @@ quic_session_connected_callback (u32 quic_app_index, u32 ctx_index,
quic_build_sockaddr (sa, &salen, &tc->rmt_ip, tc->rmt_port, tc->is_ip4);
ret =
- quicly_connect (&ctx->c_quic_ctx_id.conn,
+ quicly_connect (&ctx->conn,
(quicly_context_t *) app->quicly_ctx,
- (char *) ctx->c_quic_ctx_id.srv_hostname, sa, salen,
+ (char *) ctx->srv_hostname, sa, salen,
&quic_main.next_cid, &quic_main.hs_properties, NULL);
++quic_main.next_cid.master_id;
/* Save context handle in quicly connection */
- quic_store_conn_ctx (ctx->c_quic_ctx_id.conn, ctx);
+ quic_store_conn_ctx (ctx->conn, ctx);
assert (ret == 0);
/* Register connection in connections map */
- conn = ctx->c_quic_ctx_id.conn;
+ conn = ctx->conn;
quic_make_connection_key (&kv, quicly_get_master_id (conn));
kv.value = ((u64) thread_index) << 32 | (u64) ctx_index;
QUIC_DBG (2, "Registering conn with id %lu %lu", kv.key[0], kv.key[1]);
@@ -2043,14 +1598,14 @@ quic_session_accepted_callback (session_t * udp_session)
ctx->c_s_index = QUIC_SESSION_INVALID;
ctx->udp_session_handle = session_handle (udp_session);
QUIC_DBG (2, "ACCEPTED UDP 0x%lx", ctx->udp_session_handle);
- ctx->c_quic_ctx_id.listener_ctx_id = udp_listen_session->opaque;
+ ctx->listener_ctx_id = udp_listen_session->opaque;
lctx = quic_ctx_get (udp_listen_session->opaque,
udp_listen_session->thread_index);
- ctx->c_quic_ctx_id.udp_is_ip4 = lctx->c_is_ip4;
+ ctx->udp_is_ip4 = lctx->c_is_ip4;
ctx->parent_app_id = lctx->parent_app_id;
ctx->parent_app_wrk_id = lctx->parent_app_wrk_id;
ctx->timer_handle = QUIC_TIMER_HANDLE_INVALID;
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_OPENED;
+ ctx->conn_state = QUIC_CONN_STATE_OPENED;
ctx->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
udp_session->opaque = ctx->parent_app_id;
@@ -2123,7 +1678,7 @@ quic_custom_tx_callback (void *s, u32 max_burst_size)
if (!svm_fifo_max_dequeue (stream_session->tx_fifo))
return 0;
- stream = ctx->c_quic_ctx_id.stream;
+ stream = ctx->stream;
if (!quicly_sendstate_is_open (&stream->sendstate))
{
QUIC_DBG (1, "Warning: tried to send on closed stream");
@@ -2174,7 +1729,7 @@ quic_find_packet_ctx (u32 * ctx_thread, u32 * ctx_index,
return -1;
}
ctx_ = quic_ctx_get (index, vlib_get_thread_index ());
- conn_ = ctx_->c_quic_ctx_id.conn;
+ conn_ = ctx_->conn;
if (conn_ && quicly_is_destination (conn_, sa, salen, packet))
{
QUIC_DBG (3, "Connection found");
@@ -2204,12 +1759,11 @@ quic_receive (quic_ctx_t * ctx, quicly_conn_t * conn,
/* ctx pointer may change if a new stream is opened */
ctx = quic_ctx_get (ctx_id, thread_index);
/* Conn may be set to null if the connection is terminated */
- if (ctx->c_quic_ctx_id.conn
- && ctx->c_quic_ctx_id.conn_state == QUIC_CONN_STATE_HANDSHAKE)
+ if (ctx->conn && ctx->conn_state == QUIC_CONN_STATE_HANDSHAKE)
{
if (quicly_connection_is_ready (conn))
{
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_READY;
+ ctx->conn_state = QUIC_CONN_STATE_READY;
if (quicly_is_client (conn))
{
quic_on_client_connected (ctx);
@@ -2234,13 +1788,12 @@ quic_create_quic_session (quic_ctx_t * ctx)
quic_session->session_state = SESSION_STATE_LISTENING;
ctx->c_s_index = quic_session->session_index;
- lctx = quic_ctx_get (ctx->c_quic_ctx_id.listener_ctx_id, 0);
+ lctx = quic_ctx_get (ctx->listener_ctx_id, 0);
quic_session->app_wrk_index = lctx->parent_app_wrk_id;
quic_session->connection_index = ctx->c_c_index;
quic_session->session_type =
- session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC,
- ctx->c_quic_ctx_id.udp_is_ip4);
+ session_type_from_proto_and_ip (TRANSPORT_PROTO_QUIC, ctx->udp_is_ip4);
quic_session->listener_handle = lctx->c_s_index;
/* TODO: don't alloc fifos when we don't transfer data on this session
@@ -2290,8 +1843,8 @@ quic_create_connection (quicly_context_t * quicly_ctx,
ctx = quic_ctx_get (ctx_index, thread_index);
/* Save ctx handle in quicly connection */
quic_store_conn_ctx (conn, ctx);
- ctx->c_quic_ctx_id.conn = conn;
- ctx->c_quic_ctx_id.conn_state = QUIC_CONN_STATE_HANDSHAKE;
+ ctx->conn = conn;
+ ctx->conn_state = QUIC_CONN_STATE_HANDSHAKE;
quic_create_quic_session (ctx);
@@ -2415,7 +1968,7 @@ quic_app_rx_callback (session_t * udp_session)
if (err == 0)
{
ctx = quic_ctx_get (ctx_index, thread_index);
- quic_receive (ctx, ctx->c_quic_ctx_id.conn, packet);
+ quic_receive (ctx, ctx->conn, packet);
}
else if (ctx_thread != UINT32_MAX)
{
diff --git a/src/plugins/quic/quic.h b/src/plugins/quic/quic.h
index de27f2ac7d5..a7ce4dd57ad 100644
--- a/src/plugins/quic/quic.h
+++ b/src/plugins/quic/quic.h
@@ -83,37 +83,30 @@ typedef enum quic_ctx_flags_
QUIC_F_IS_LISTENER = (1 << 1),
} quic_ctx_flags_t;
-/* *INDENT-OFF* */
-typedef struct quic_ctx_id_
+/* This structure is used to implement the concept of VPP connection for QUIC.
+ * We create one per connection and one per stream. */
+typedef struct quic_ctx_
{
- union { /** QUIC ctx case */
- struct {
+ union
+ {
+ transport_connection_t connection;
+ struct
+ { /** QUIC ctx case */
quicly_conn_t *conn;
u32 listener_ctx_id;
u32 client_opaque;
u8 *srv_hostname;
u8 conn_state;
u8 udp_is_ip4;
+ u8 _qctx_end_marker; /* Leave this at the end */
};
- struct { /** STREAM ctx case */
+ struct
+ { /** STREAM ctx case */
quicly_stream_t *stream;
u32 quic_connection_ctx_id;
+ u8 _sctx_end_marker; /* Leave this at the end */
};
};
-} quic_ctx_id_t;
-/* *INDENT-ON* */
-
-STATIC_ASSERT (sizeof (quic_ctx_id_t) <= 42, "ctx id must be less than 42");
-
-/* This structure is used to implement the concept of VPP connection for QUIC.
- * We create one per connection and one per stream. */
-typedef struct quic_ctx_
-{
- union
- {
- transport_connection_t connection;
- quic_ctx_id_t c_quic_ctx_id;
- };
session_handle_t udp_session_handle;
u32 timer_handle;
u32 parent_app_wrk_id;
@@ -121,6 +114,17 @@ typedef struct quic_ctx_
u8 flags;
} quic_ctx_t;
+/* Make sure our custom fields don't overlap with the fields we use in
+ .connection
+*/
+STATIC_ASSERT (offsetof (quic_ctx_t, _qctx_end_marker) <=
+ TRANSPORT_CONN_ID_LEN,
+ "connection data must be less than TRANSPORT_CONN_ID_LEN bytes");
+STATIC_ASSERT (offsetof (quic_ctx_t, _sctx_end_marker) <=
+ TRANSPORT_CONN_ID_LEN,
+ "connection data must be less than TRANSPORT_CONN_ID_LEN bytes");
+
+
typedef struct quic_stream_data_
{
u32 ctx_id;