From 38e835983f38ad842315ea734217402f377da80f Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Mon, 11 Jan 2021 13:52:57 -0500 Subject: [PATCH] API: add lsquic_conn_get_sni(), fixes issue #203 --- bin/http_server.c | 5 +++++ docs/apiref.rst | 4 ++++ include/lsquic.h | 4 ++++ src/liblsquic/lsquic_conn.c | 10 ++++++++++ src/liblsquic/lsquic_enc_sess.h | 3 +++ src/liblsquic/lsquic_enc_sess_ietf.c | 17 +++++++++++++++++ src/liblsquic/lsquic_handshake.c | 10 ++++++++++ 7 files changed, 53 insertions(+) diff --git a/bin/http_server.c b/bin/http_server.c index 81ce97d..452e68d 100644 --- a/bin/http_server.c +++ b/bin/http_server.c @@ -321,6 +321,11 @@ static lsquic_conn_ctx_t * http_server_on_new_conn (void *stream_if_ctx, lsquic_conn_t *conn) { struct server_ctx *server_ctx = stream_if_ctx; + const char *sni; + + sni = lsquic_conn_get_sni(conn); + LSQ_DEBUG("new connection, SNI: %s", sni ? sni : ""); + lsquic_conn_ctx_t *conn_h = malloc(sizeof(*conn_h)); conn_h->conn = conn; conn_h->server_ctx = server_ctx; diff --git a/docs/apiref.rst b/docs/apiref.rst index 8059a8c..acebc3d 100644 --- a/docs/apiref.rst +++ b/docs/apiref.rst @@ -1964,6 +1964,10 @@ Miscellaneous Connection Functions Get peer context associated with the connection and local address. +.. function:: const char * lsquic_conn_get_sni (lsquic_conn_t *conn) + + Get SNI sent by the client. + .. function:: enum LSQUIC_CONN_STATUS lsquic_conn_status (lsquic_conn_t *conn, char *errbuf, size_t bufsz) Get connection status. diff --git a/include/lsquic.h b/include/lsquic.h index d9ea9e3..226a179 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -1979,6 +1979,10 @@ lsquic_conn_set_ctx (lsquic_conn_t *, lsquic_conn_ctx_t *); void * lsquic_conn_get_peer_ctx (lsquic_conn_t *, const struct sockaddr *local_sa); +/** Get SNI sent by the client */ +const char * +lsquic_conn_get_sni (lsquic_conn_t *); + /** * Abort connection. */ diff --git a/src/liblsquic/lsquic_conn.c b/src/liblsquic/lsquic_conn.c index fea9421..ca21e93 100644 --- a/src/liblsquic/lsquic_conn.c +++ b/src/liblsquic/lsquic_conn.c @@ -324,3 +324,13 @@ lsquic_conn_stats_diff (const struct conn_stats *cumulative_stats, #endif + + +const char * +lsquic_conn_get_sni (struct lsquic_conn *lconn) +{ + if (lconn->cn_esf_c && lconn->cn_esf_c->esf_get_sni) + return lconn->cn_esf_c->esf_get_sni(lconn->cn_enc_session); + else + return NULL; +} diff --git a/src/liblsquic/lsquic_enc_sess.h b/src/liblsquic/lsquic_enc_sess.h index 7af721a..ce9a626 100644 --- a/src/liblsquic/lsquic_enc_sess.h +++ b/src/liblsquic/lsquic_enc_sess.h @@ -99,6 +99,9 @@ struct enc_session_funcs_common int (*esf_alg_keysize) (enc_session_t *); + const char * + (*esf_get_sni) (enc_session_t *); + /* Need to pass lconn in encrypt and decrypt methods because enc_session * is allowed to be NULL for gQUIC. */ diff --git a/src/liblsquic/lsquic_enc_sess_ietf.c b/src/liblsquic/lsquic_enc_sess_ietf.c index 6dc3c78..562dc5d 100644 --- a/src/liblsquic/lsquic_enc_sess_ietf.c +++ b/src/liblsquic/lsquic_enc_sess_ietf.c @@ -2410,6 +2410,21 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p, } +static const char * +iquic_esf_get_sni (enc_session_t *enc_session_p) +{ + struct enc_sess_iquic *const enc_sess = enc_session_p; + const char *server_name; + + server_name = SSL_get_servername(enc_sess->esi_ssl, TLSEXT_NAMETYPE_host_name); +#ifndef NDEBUG + if (!server_name) + server_name = enc_sess->esi_sni_bypass; +#endif + return server_name; +} + + static int iquic_esf_global_init (int flags) { @@ -2669,6 +2684,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 = .esf_tag_len = IQUIC_TAG_LEN, .esf_get_server_cert_chain = iquic_esf_get_server_cert_chain, + .esf_get_sni = iquic_esf_get_sni, .esf_cipher = iquic_esf_cipher, .esf_keysize = iquic_esf_keysize, .esf_alg_keysize = iquic_esf_alg_keysize, @@ -2687,6 +2703,7 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1_no_flush .esf_tag_len = IQUIC_TAG_LEN, .esf_get_server_cert_chain = iquic_esf_get_server_cert_chain, + .esf_get_sni = iquic_esf_get_sni, .esf_cipher = iquic_esf_cipher, .esf_keysize = iquic_esf_keysize, .esf_alg_keysize = iquic_esf_alg_keysize, diff --git a/src/liblsquic/lsquic_handshake.c b/src/liblsquic/lsquic_handshake.c index c96b90b..6e61762 100644 --- a/src/liblsquic/lsquic_handshake.c +++ b/src/liblsquic/lsquic_handshake.c @@ -3502,6 +3502,14 @@ lsquic_enc_session_get_ua (enc_session_t *enc_session_p) } +static const char * +lsquic_enc_session_get_sni (enc_session_t *enc_session_p) +{ + struct lsquic_enc_session *const enc_session = enc_session_p; + return lsquic_str_cstr(&enc_session->hs_ctx.sni); +} + + #ifndef NDEBUG static uint8_t lsquic_enc_session_have_key (enc_session_t *enc_session_p) @@ -3819,6 +3827,7 @@ struct enc_session_funcs_common lsquic_enc_session_common_gquic_1 = .esf_cipher = lsquic_enc_session_cipher, .esf_keysize = lsquic_enc_session_keysize, .esf_alg_keysize = lsquic_enc_session_alg_keysize, + .esf_get_sni = lsquic_enc_session_get_sni, .esf_encrypt_packet = gquic_encrypt_packet, .esf_decrypt_packet = gquic_decrypt_packet, .esf_tag_len = GQUIC_PACKET_HASH_SZ, @@ -4246,6 +4255,7 @@ const /* Q050 and later */ struct enc_session_funcs_common lsquic_enc_session_common_gquic_2 = { + .esf_get_sni = lsquic_enc_session_get_sni, .esf_global_init = lsquic_handshake_init, .esf_global_cleanup = lsquic_handshake_cleanup, .esf_cipher = lsquic_enc_session_cipher,