@@ -682,6 +682,89 @@ func TestPSKHintFail(t *testing.T) {
682682 assert .ErrorIs (t , <- clientErr , pskRejected , "TestPSK: Client should fail with pskRejected error" )
683683}
684684
685+ func TestPSKMismatchNoRetransmitLoop (t * testing.T ) {
686+ lim := test .TimeOut (time .Second * 20 )
687+ defer lim .Stop ()
688+
689+ report := test .CheckRoutines (t )
690+ defer report ()
691+
692+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
693+ defer cancel ()
694+
695+ var serverWrites atomic.Int32
696+ var clientWrites atomic.Int32
697+
698+ ca , cb := dpipe .Pipe ()
699+ defer func () {
700+ _ = ca .Close ()
701+ }()
702+ defer func () {
703+ _ = cb .Close ()
704+ }()
705+
706+ caCount := & connWithCallback {Conn : ca }
707+ caCount .onWrite = func ([]byte ) {
708+ clientWrites .Add (1 )
709+ }
710+ cbCount := & connWithCallback {Conn : cb }
711+ cbCount .onWrite = func ([]byte ) {
712+ serverWrites .Add (1 )
713+ }
714+
715+ clientErr := make (chan error , 1 )
716+ serverErr := make (chan error , 1 )
717+
718+ go func () {
719+ conf := & Config {
720+ PSK : func ([]byte ) ([]byte , error ) {
721+ return []byte ("client-psk" ), nil
722+ },
723+ PSKIdentityHint : []byte ("Client Identity" ),
724+ CipherSuites : []CipherSuiteID {TLS_PSK_WITH_AES_128_CCM_8 },
725+ }
726+
727+ c , err := testClient (ctx , dtlsnet .PacketConnFromConn (caCount ), caCount .RemoteAddr (), conf , false )
728+ if c != nil {
729+ _ = c .Close () //nolint:contextcheck
730+ }
731+ clientErr <- err
732+ }()
733+
734+ go func () {
735+ conf := & Config {
736+ PSK : func ([]byte ) ([]byte , error ) {
737+ return []byte ("server-psk" ), nil
738+ },
739+ CipherSuites : []CipherSuiteID {TLS_PSK_WITH_AES_128_CCM_8 },
740+ }
741+
742+ s , err := testServer (ctx , dtlsnet .PacketConnFromConn (cbCount ), cbCount .RemoteAddr (), conf , false )
743+ if s != nil {
744+ _ = s .Close () //nolint:contextcheck
745+ }
746+ serverErr <- err
747+ }()
748+
749+ serverErrRes := <- serverErr
750+ clientErrRes := <- clientErr
751+
752+ var serverHandshakeErr * HandshakeError
753+ var clientHandshakeErr * HandshakeError
754+ assert .ErrorAs (t , serverErrRes , & serverHandshakeErr )
755+ assert .ErrorAs (t , clientErrRes , & clientHandshakeErr )
756+
757+ serverCount := serverWrites .Load ()
758+ clientCount := clientWrites .Load ()
759+
760+ time .Sleep (2 * time .Second )
761+
762+ assert .Equal (t , serverCount , serverWrites .Load (), "Server should not retransmit after handshake failure" )
763+ assert .Equal (t , clientCount , clientWrites .Load (), "Client should not retransmit after handshake failure" )
764+ assert .LessOrEqual (t , serverCount , int32 (20 ), "Server retransmit count too high for backoff" )
765+ assert .LessOrEqual (t , clientCount , int32 (20 ), "Client retransmit count too high for backoff" )
766+ }
767+
685768// Assert that ServerKeyExchange is only sent if Identity is set on server side.
686769func TestPSKServerKeyExchange (t * testing.T ) {
687770 // Limit runtime in case of deadlocks
0 commit comments