Commit 6ded779194 for openssl.org

commit 6ded7791946e8670cd16a30a5593aa6eebd81ade
Author: Bob Beck <beck@openssl.org>
Date:   Tue Sep 1 10:38:23 2026 -0600

    Let TLSProxy tests set the expected NewSessionTicket count

    The DTLS 1.3 handshake-complete check waited for two ticket acks, but
    a server sends at most one ticket after a resumption, so the resuming
    connection in 70-test_dtls13sessionid.t stalled until the proxy killed
    s_server. Add a per-connection expected_tickets setting (default two)
    and set it to one there.

    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Merge-date: Tue Sep  1 17:04:41 2026
    Merged-from: https://github.com/openssl/openssl/pull/32629

diff --git a/test/recipes/70-test_dtls13sessionid.t b/test/recipes/70-test_dtls13sessionid.t
index 471982b4a4..2ee53489de 100644
--- a/test/recipes/70-test_dtls13sessionid.t
+++ b/test/recipes/70-test_dtls13sessionid.t
@@ -76,6 +76,9 @@ $proxy->clientflags("$clientflags -sess_in $session");
 $proxy->serverflags($serverflags);
 $proxy->sessionfile($session);
 $proxy->filter(\&inject_session_id_filter);
+# The server sends at most one NewSessionTicket after a resumption, so the
+# proxy must not wait for the default two to be acked.
+$proxy->expected_tickets(1);
 TLSProxy::Message->successondata(1);
 $proxy->start();
 ok(TLSProxy::Message->success() && !server_sent_certificate(),
diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm
index 5225d073e5..783794e25d 100644
--- a/util/perl/TLSProxy/Proxy.pm
+++ b/util/perl/TLSProxy/Proxy.pm
@@ -117,6 +117,7 @@ sub init
         serverconnects => 1,
         reneg => 0,
         sessionfile => undef,
+        expected_tickets => 2,

         #Public read
         isdtls => $isdtls,
@@ -164,6 +165,7 @@ sub clearClient
     $self->{seen_msgseq} = {};
     $self->{clientflags} = "";
     $self->{sessionfile} = undef;
+    $self->{expected_tickets} = 2;
     $self->{clientpid} = 0;
     $self->{clientexit} = 0;
     $is_tls13 = 0;
@@ -773,7 +775,7 @@ sub process_packet
                 foreach my $record (@{$message->{records}}) {
                     if (@{$self->{session_ticket_seq}} == 0) {
                         push @{$self->{session_ticket_seq}}, TLSProxy::RecordNumber->new($record->epoch, $record->seq);
-                    } elsif (scalar(@{$self->{session_ticket_seq}}) != 2) {
+                    } elsif (scalar(@{$self->{session_ticket_seq}}) != $self->{expected_tickets}) {
                         my $match = $self->find_session_ticket_ack($record->epoch, $record->seq);
                         if ($match == -1) {
                             push @{$self->{session_ticket_seq}}, TLSProxy::RecordNumber->new($record->epoch, $record->seq);
@@ -820,7 +822,8 @@ sub seen_session_ticket_ack
     my $record = shift;

     my $ack_hash = $self->{saw_session_ticket_ack};
-    return if !$self->{saw_session_ticket} || scalar(keys %{$ack_hash}) == 2;
+    return if !$self->{saw_session_ticket}
+              || scalar(keys %{$ack_hash}) == $self->{expected_tickets};
     return if $record->content_type() != TLSProxy::Record::RT_ACK;

     my @record_numbers = ();
@@ -838,7 +841,7 @@ sub seen_session_ticket_ack
         if ($match != -1) {
             my $session_ticket = splice(@{$ticket_seq}, $match, 1);
             $ack_hash->{$key} = $session_ticket;
-            last if scalar(keys %{$ack_hash}) == 2;
+            last if scalar(keys %{$ack_hash}) == $self->{expected_tickets};
         }
     }
 }
@@ -867,8 +870,9 @@ sub handshake_complete
     my $res = 0;

     if ($self->{isdtls} && $self->is_tls13() && defined($self->{sessionfile})) {
-        # We need to wait for the second ack message for the handshake to be complete
-        if (scalar(keys %{$self->{saw_session_ticket_ack}}) == 2) {
+        # The handshake is complete once every expected NewSessionTicket
+        # (2 by default, but only 1 follows a resumption) has been acked
+        if (scalar(keys %{$self->{saw_session_ticket_ack}}) == $self->{expected_tickets}) {
             $res = 1;
         }
     } else {
@@ -1078,6 +1082,14 @@ sub sessionfile
     }
     return $self->{sessionfile};
 }
+sub expected_tickets
+{
+    my $self = shift;
+    if (@_) {
+        $self->{expected_tickets} = shift;
+    }
+    return $self->{expected_tickets};
+}

 sub ciphersuite
 {