1
1
/*
2
- * Copyright (c) 2015, 2021 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2015, 2022 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
33
33
* @run main/othervm DTLSOverDatagram
34
34
*/
35
35
36
+ import java .io .IOException ;
36
37
import java .nio .*;
37
38
import java .net .*;
38
39
import java .util .*;
42
43
import jdk .test .lib .security .SSLContextBuilder ;
43
44
44
45
import java .util .concurrent .*;
46
+ import java .util .concurrent .atomic .AtomicBoolean ;
45
47
46
48
import jdk .test .lib .hexdump .HexPrinter ;
47
49
50
52
*/
51
53
public class DTLSOverDatagram {
52
54
53
- private static final int MAX_HANDSHAKE_LOOPS = 200 ;
54
- private static final int MAX_APP_READ_LOOPS = 60 ;
55
55
private static final int SOCKET_TIMEOUT = 10 * 1000 ; // in millis
56
56
private static final int BUFFER_SIZE = 1024 ;
57
57
private static final int MAXIMUM_PACKET_SIZE = 1024 ;
@@ -75,8 +75,9 @@ public class DTLSOverDatagram {
75
75
private static final ByteBuffer CLIENT_APP =
76
76
ByteBuffer .wrap ("Hi Server, I'm Client" .getBytes ());
77
77
78
- private static Exception clientException = null ;
79
- private static Exception serverException = null ;
78
+ private final AtomicBoolean exceptionOccurred = new AtomicBoolean (false );
79
+
80
+ private final CountDownLatch serverStarted = new CountDownLatch (1 );
80
81
/*
81
82
* =============================================================
82
83
* The test case
@@ -148,18 +149,12 @@ void handshake(SSLEngine engine, DatagramSocket socket,
148
149
SocketAddress peerAddr , String side ) throws Exception {
149
150
150
151
boolean endLoops = false ;
151
- int loops = MAX_HANDSHAKE_LOOPS ;
152
+ int loops = 0 ;
152
153
engine .beginHandshake ();
153
- while (!endLoops &&
154
- (serverException == null ) && (clientException == null )) {
155
-
156
- if (--loops < 0 ) {
157
- throw new RuntimeException (
158
- "Too many loops to produce handshake packets" );
159
- }
154
+ while (!endLoops && !exceptionOccurred .get ()) {
160
155
161
156
SSLEngineResult .HandshakeStatus hs = engine .getHandshakeStatus ();
162
- log (side , "=======handshake(" + loops + ", " + hs + ")=======" );
157
+ log (side , "=======handshake(" + ++ loops + ", " + hs + ")=======" );
163
158
164
159
switch (hs ) {
165
160
case NEED_UNWRAP , NEED_UNWRAP_AGAIN -> {
@@ -313,16 +308,10 @@ void deliverAppData(SSLEngine engine, DatagramSocket socket,
313
308
void receiveAppData (SSLEngine engine ,
314
309
DatagramSocket socket , ByteBuffer expectedApp ) throws Exception {
315
310
316
- int loops = MAX_APP_READ_LOOPS ;
317
- while ((serverException == null ) && (clientException == null )) {
318
- if (--loops < 0 ) {
319
- throw new RuntimeException (
320
- "Too much loops to receive application data" );
321
- }
322
-
311
+ while (!exceptionOccurred .get ()) {
323
312
byte [] buf = new byte [BUFFER_SIZE ];
324
- DatagramPacket packet = new DatagramPacket ( buf , buf . length );
325
- socket . receive ( packet );
313
+ DatagramPacket packet = readFromSocket ( socket , buf );
314
+
326
315
ByteBuffer netBuffer = ByteBuffer .wrap (buf , 0 , packet .getLength ());
327
316
ByteBuffer recBuffer = ByteBuffer .allocate (BUFFER_SIZE );
328
317
SSLEngineResult rs = engine .unwrap (netBuffer , recBuffer );
@@ -338,19 +327,31 @@ void receiveAppData(SSLEngine engine,
338
327
}
339
328
}
340
329
330
+ /*
331
+ Some tests failed with receive time-out errors when the client tried to read
332
+ from the server. The server thread had exited normally so the read _should_
333
+ succeed. So let's try to read a couple of times before giving up.
334
+ */
335
+ DatagramPacket readFromSocket (DatagramSocket socket , byte [] buffer ) throws IOException {
336
+ for (int i = 1 ; i <= 2 ; ++i ) {
337
+ try {
338
+ DatagramPacket packet = new DatagramPacket (buffer , buffer .length );
339
+ socket .receive (packet );
340
+ return packet ;
341
+ } catch (SocketTimeoutException exc ) {
342
+ System .out .println ("Attempt " + i + ": Timeout occurred reading from socket." );
343
+ }
344
+ }
345
+ throw new IOException ("Did not receive data after 2 attempts." );
346
+ }
347
+
341
348
// produce handshake packets
342
349
boolean produceHandshakePackets (SSLEngine engine , SocketAddress socketAddr ,
343
350
String side , List <DatagramPacket > packets ) throws Exception {
344
351
345
352
boolean endLoops = false ;
346
- int loops = MAX_HANDSHAKE_LOOPS / 2 ;
347
- while (!endLoops &&
348
- (serverException == null ) && (clientException == null )) {
349
-
350
- if (--loops < 0 ) {
351
- throw new RuntimeException (
352
- "Too many loops to produce handshake packets" );
353
- }
353
+ int loops = 0 ;
354
+ while (!endLoops && !exceptionOccurred .get ()) {
354
355
355
356
ByteBuffer oNet = ByteBuffer .allocate (32768 );
356
357
ByteBuffer oApp = ByteBuffer .allocate (0 );
@@ -360,7 +361,7 @@ boolean produceHandshakePackets(SSLEngine engine, SocketAddress socketAddr,
360
361
SSLEngineResult .Status rs = r .getStatus ();
361
362
SSLEngineResult .HandshakeStatus hs = r .getHandshakeStatus ();
362
363
log (side , "----produce handshake packet(" +
363
- loops + ", " + rs + ", " + hs + ")----" );
364
+ ++ loops + ", " + rs + ", " + hs + ")----" );
364
365
365
366
verifySSLEngineResultStatus (r , side );
366
367
@@ -518,10 +519,6 @@ SSLContext getDTLSContext() throws Exception {
518
519
* The remainder is support stuff to kickstart the testing.
519
520
*/
520
521
521
- // Will the handshaking and application data exchange succeed?
522
- public boolean isGoodJob () {
523
- return true ;
524
- }
525
522
526
523
public final void runTest (DTLSOverDatagram testCase ) throws Exception {
527
524
InetSocketAddress serverSocketAddress = new InetSocketAddress
@@ -541,97 +538,51 @@ public final void runTest(DTLSOverDatagram testCase) throws Exception {
541
538
InetSocketAddress clientSocketAddr = new InetSocketAddress (
542
539
InetAddress .getLoopbackAddress (), clientSocket .getLocalPort ());
543
540
544
- ExecutorService pool = Executors .newFixedThreadPool (2 );
545
- Future <String > server , client ;
541
+ ExecutorService pool = Executors .newFixedThreadPool (1 );
542
+ Future <Void > server ;
546
543
547
- try {
548
- server = pool .submit (new ServerCallable (
544
+ server = pool .submit (() -> runServer (
549
545
testCase , serverSocket , clientSocketAddr ));
550
- client = pool .submit (new ClientCallable (
551
- testCase , clientSocket , serverSocketAddr ));
552
- } finally {
553
- pool .shutdown ();
554
- }
555
-
556
- boolean failed = false ;
546
+ pool .shutdown ();
557
547
558
- // wait for client to finish
559
- try {
560
- System .out .println ("Client finished: " + client .get ());
561
- } catch (CancellationException | InterruptedException
562
- | ExecutionException e ) {
563
- System .out .println ("Exception on client side: " );
564
- e .printStackTrace (System .out );
565
- failed = true ;
566
- }
567
-
568
- // wait for server to finish
569
- try {
570
- System .out .println ("Client finished: " + server .get ());
571
- } catch (CancellationException | InterruptedException
572
- | ExecutionException e ) {
573
- System .out .println ("Exception on server side: " );
574
- e .printStackTrace (System .out );
575
- failed = true ;
576
- }
577
-
578
- if (failed ) {
579
- throw new RuntimeException ("Test failed" );
580
- }
548
+ runClient (testCase , clientSocket , serverSocketAddr );
549
+ server .get ();
581
550
}
582
551
}
583
552
584
- record ServerCallable (DTLSOverDatagram testCase , DatagramSocket socket ,
585
- InetSocketAddress clientSocketAddr ) implements Callable <String > {
553
+ Void runServer (DTLSOverDatagram testCase , DatagramSocket socket ,
554
+ InetSocketAddress clientSocketAddr ) throws Exception {
555
+ try {
556
+ serverStarted .countDown ();
557
+ testCase .doServerSide (socket , clientSocketAddr );
586
558
587
- @ Override
588
- public String call () throws Exception {
589
- try {
590
- testCase .doServerSide (socket , clientSocketAddr );
591
- } catch (Exception e ) {
592
- System .out .println ("Exception in ServerCallable.call():" );
593
- e .printStackTrace (System .out );
594
- serverException = e ;
595
-
596
- if (testCase .isGoodJob ()) {
597
- throw e ;
598
- } else {
599
- return "Well done, server!" ;
600
- }
601
- }
559
+ } catch (Exception exc ) {
560
+ exceptionOccurred .set (true );
602
561
603
- if (testCase .isGoodJob ()) {
604
- return "Well done, server!" ;
605
- } else {
606
- throw new Exception ("No expected exception" );
607
- }
562
+ // log for debugging clarity
563
+ System .out .println ("Unexpected exception in server" );
564
+ exc .printStackTrace (System .err );
565
+ throw exc ;
608
566
}
567
+
568
+ return null ;
609
569
}
610
570
611
- record ClientCallable (DTLSOverDatagram testCase , DatagramSocket socket ,
612
- InetSocketAddress serverSocketAddr ) implements Callable <String > {
571
+ private void runClient (DTLSOverDatagram testCase , DatagramSocket socket ,
572
+ InetSocketAddress serverSocketAddr ) throws Exception {
573
+ if (!serverStarted .await (5 , TimeUnit .SECONDS )) {
574
+ throw new Exception ("Server did not start within 5 seconds." );
575
+ }
613
576
614
- @ Override
615
- public String call () throws Exception {
616
- try {
617
- testCase .doClientSide (socket , serverSocketAddr );
618
- } catch (Exception e ) {
619
- System .out .println ("Exception in ClientCallable.call():" );
620
- e .printStackTrace (System .out );
621
- clientException = e ;
622
-
623
- if (testCase .isGoodJob ()) {
624
- throw e ;
625
- } else {
626
- return "Well done, client!" ;
627
- }
628
- }
577
+ try {
578
+ testCase .doClientSide (socket , serverSocketAddr );
579
+ } catch (Exception exc ) {
580
+ exceptionOccurred .set (true );
629
581
630
- if (testCase .isGoodJob ()) {
631
- return "Well done, client!" ;
632
- } else {
633
- throw new Exception ("No expected exception" );
634
- }
582
+ // log for debugging clarity
583
+ System .out .println ("Unexpected exception in client." );
584
+ exc .printStackTrace (System .err );
585
+ throw exc ;
635
586
}
636
587
}
637
588
0 commit comments