Source:
<code>private void sendMessage(final RawData message) throws HandshakeException { InetSocketAddress peerAddress = message.getInetSocketAddress(); LOGGER.debug("Sending application layer message to peer [{}]", peerAddress); Connection connection = connectionStore.get(peerAddress); if (connection == null) { connection = new Connection(peerAddress, config.getAutoResumptionTimeoutMillis()); connectionStore.put(connection); } DTLSSession session = connection.getEstablishedSession(); SessionTicket ticket = connection.getSessionTicket(); if (session == null && ticket == null) { if (config.isServerOnly()) { <START> message.onError(new EndpointMismatchException()); <END> } if (!checkOutboundEndpointContext(message, null)) { return; } message.onConnecting(); Handshaker handshaker = connection.getOngoingHandshake(); if (handshaker == null) { handshaker = new ClientHandshaker( DTLSSession.newClientSession(peerAddress, message.getEndpointContext().getVirtualHost()), getRecordLayerForPeer(connection), connection.getSessionListener(), config, maximumTransmissionUnit); initializeHandshaker(handshaker); handshaker.startHandshake(); } handshaker.addSessionListener(newDeferredMessageSender(message)); } else if (connection.isResumptionRequired()){ if (config.isServerOnly()) { message.onError(new EndpointMismatchException()); } message.onConnecting(); SessionId sessionId; if (ticket == null) { ticket = session.getSessionTicket(); sessionId = session.getSessionIdentifier(); } else { sessionId = connection.getSessionIdentity(); } DTLSSession resumableSession = new DTLSSession(sessionId, peerAddress, ticket, 0); Connection newConnection = new Connection(peerAddress, config.getAutoResumptionTimeoutMillis()); terminateConnection(connection, null, null); connectionStore.put(newConnection); Handshaker handshaker = new ResumingClientHandshaker(resumableSession, getRecordLayerForPeer(newConnection), newConnection.getSessionListener(), config, maximumTransmissionUnit); initializeHandshaker(handshaker); handshaker.addSessionListener(newDeferredMessageSender(message)); handshaker.startHandshake(); } else { sendMessage(message, session); } }</code><technical_language>EndpointMismatchException sounds strange me. (If find a more exception, add a String explanation exception)</technical_language>

Target:
private void sendMessage(final RawData message) throws HandshakeException { InetSocketAddress peerAddress = message.getInetSocketAddress(); LOGGER.debug("Sending application layer message to peer [{}]", peerAddress); Connection connection = connectionStore.get(peerAddress); if (connection == null) { connection = new Connection(peerAddress, config.getAutoResumptionTimeoutMillis()); connectionStore.put(connection); } DTLSSession session = connection.getEstablishedSession(); SessionTicket ticket = connection.getSessionTicket(); if (session == null && ticket == null) { if (config.isServerOnly()) { message.onError(new EndpointUnconnectedException()); } if (!checkOutboundEndpointContext(message, null)) { return; } message.onConnecting(); Handshaker handshaker = connection.getOngoingHandshake(); if (handshaker == null) { handshaker = new ClientHandshaker( DTLSSession.newClientSession(peerAddress, message.getEndpointContext().getVirtualHost()), getRecordLayerForPeer(connection), connection.getSessionListener(), config, maximumTransmissionUnit); initializeHandshaker(handshaker); handshaker.startHandshake(); } handshaker.addApplicationDataForDeferredProcessing(message); } else if (connection.isResumptionRequired()) { if (config.isServerOnly()) { message.onError(new EndpointMismatchException()); } message.onConnecting(); SessionId sessionId; if (ticket == null) { ticket = session.getSessionTicket(); sessionId = session.getSessionIdentifier(); } else { sessionId = connection.getSessionIdentity(); } DTLSSession resumableSession = new DTLSSession(sessionId, peerAddress, ticket, 0); Connection newConnection = new Connection(peerAddress, config.getAutoResumptionTimeoutMillis()); connection.cancelPendingFlight(); connectionStore.remove(connection, false); connectionStore.put(newConnection); Handshaker handshaker = new ResumingClientHandshaker(resumableSession, getRecordLayerForPeer(newConnection), newConnection.getSessionListener(), config, maximumTransmissionUnit); initializeHandshaker(handshaker); Handshaker previous = connection.getOngoingHandshake(); if (previous != null) { handshaker.takeDeferredApplicationData(previous); } handshaker.addApplicationDataForDeferredProcessing(message); handshaker.startHandshake(); } else { sendMessage(message, session); } }