Adding V2ClientHello counter.

Change-Id: I324743e7d1864fbbb9653209ff93e4da872c8d31
Reviewed-on: https://boringssl-review.googlesource.com/13340
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index d272b58..6c9822f 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2968,6 +2968,10 @@
 OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl,
                                              size_t max_send_fragment);
 
+/* SSL_get_v2clienthello_count returns the total number of V2ClientHellos that
+ * are accepted. */
+OPENSSL_EXPORT uint64_t SSL_get_v2clienthello_count(void);
+
 /* ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain
  * callbacks that are called very early on during the server handshake. At this
  * point, much of the SSL* hasn't been filled out and only the ClientHello can
diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c
index 33ffa7e..e3889bb 100644
--- a/ssl/handshake_server.c
+++ b/ssl/handshake_server.c
@@ -185,6 +185,17 @@
 static int ssl3_get_channel_id(SSL_HANDSHAKE *hs);
 static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs);
 
+static struct CRYPTO_STATIC_MUTEX g_v2clienthello_lock =
+    CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_v2clienthello_count = 0;
+
+uint64_t SSL_get_v2clienthello_count(void) {
+  CRYPTO_STATIC_MUTEX_lock_read(&g_v2clienthello_lock);
+  uint64_t ret = g_v2clienthello_count;
+  CRYPTO_STATIC_MUTEX_unlock_read(&g_v2clienthello_lock);
+  return ret;
+}
+
 int ssl3_accept(SSL_HANDSHAKE *hs) {
   SSL *const ssl = hs->ssl;
   uint32_t alg_a;
@@ -474,6 +485,12 @@
           ssl->s3->new_session = NULL;
         }
 
+        if (hs->v2_clienthello) {
+          CRYPTO_STATIC_MUTEX_lock_write(&g_v2clienthello_lock);
+          g_v2clienthello_count++;
+          CRYPTO_STATIC_MUTEX_unlock_write(&g_v2clienthello_lock);
+        }
+
         ssl->s3->initial_handshake_complete = 1;
         ssl_update_cache(hs, SSL_SESS_CACHE_SERVER);
 
diff --git a/ssl/internal.h b/ssl/internal.h
index 66dc37a..13e3605 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1056,6 +1056,9 @@
    * or received. */
   unsigned ticket_expected:1;
 
+  /* v2_clienthello is one if we received a V2ClientHello. */
+  unsigned v2_clienthello:1;
+
   /* client_version is the value sent or received in the ClientHello version. */
   uint16_t client_version;
 } /* SSL_HANDSHAKE */;
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 627ef63..f8f33dc 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -666,6 +666,8 @@
       return ret;
     }
     if (is_v2_client_hello) {
+      /* This is the first message, so hs must be non-NULL. */
+      ssl->s3->hs->v2_clienthello = 1;
       /* V2ClientHello is hashed separately. */
       hash_message = ssl_dont_hash_message;
     }