/** * Handles a specific <tt>IOException</tt> which was thrown during the execution of {@link * #runInConnectThread(DTLSProtocol, TlsPeer, DatagramTransport)} while trying to establish a DTLS * connection * * @param ioe the <tt>IOException</tt> to handle * @param msg the human-readable message to log about the specified <tt>ioe</tt> * @param i the number of tries remaining after the current one * @return <tt>true</tt> if the specified <tt>ioe</tt> was successfully handled; <tt>false</tt>, * otherwise */ private boolean handleRunInConnectThreadException(IOException ioe, String msg, int i) { // SrtpControl.start(MediaType) starts its associated TransformEngine. // We will use that mediaType to signal the normal stop then as well // i.e. we will ignore exception after the procedure to stop this // PacketTransformer has begun. if (mediaType == null) return false; if (ioe instanceof TlsFatalAlert) { TlsFatalAlert tfa = (TlsFatalAlert) ioe; short alertDescription = tfa.getAlertDescription(); if (alertDescription == AlertDescription.unexpected_message) { msg += " Received fatal unexpected message."; if (i == 0 || !Thread.currentThread().equals(connectThread) || connector == null || mediaType == null) { msg += " Giving up after " + (CONNECT_TRIES - i) + " retries."; } else { msg += " Will retry."; logger.error(msg, ioe); return true; } } else { msg += " Received fatal alert " + alertDescription + "."; } } logger.error(msg, ioe); return false; }
public DTLSTransport accept(TlsServer server, DatagramTransport transport) throws IOException { if (server == null) { throw new IllegalArgumentException("'server' cannot be null"); } if (transport == null) { throw new IllegalArgumentException("'transport' cannot be null"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.server; securityParameters.serverRandom = TlsProtocol.createRandomBlock(secureRandom); ServerHandshakeState state = new ServerHandshakeState(); state.server = server; state.serverContext = new TlsServerContextImpl(secureRandom, securityParameters); server.init(state.serverContext); DTLSRecordLayer recordLayer = new DTLSRecordLayer(transport, state.serverContext, server, ContentType.handshake); // TODO Need to handle sending of HelloVerifyRequest without entering a full connection try { return serverHandshake(state, recordLayer); } catch (TlsFatalAlert fatalAlert) { recordLayer.fail(fatalAlert.getAlertDescription()); throw fatalAlert; } catch (IOException e) { recordLayer.fail(AlertDescription.internal_error); throw e; } catch (RuntimeException e) { recordLayer.fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error); } }
private void safeWriteMessage(short type, byte[] buf, int offset, int len) throws IOException { try { rs.writeMessage(type, buf, offset, len); } catch (TlsFatalAlert e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; } catch (IOException e) { if (!closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } catch (RuntimeException e) { if (!closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } }
private void safeReadData() throws IOException { try { rs.readData(); } catch (TlsFatalAlert e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, e.getAlertDescription()); } throw e; } catch (IOException e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } catch (RuntimeException e) { if (!this.closed) { this.failWithError(AlertLevel.fatal, AlertDescription.internal_error); } throw e; } }