/** * Return a formatted message to the client. We try to re-connect with the peer on the other end * if possible. * * @param sipMessage Message to send. * @throws IOException If there is an error sending the message */ public void sendMessage(final SIPMessage sipMessage) throws IOException { if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG) && !sipMessage.isNullRequest()) { logger.logDebug( "sendMessage:: " + sipMessage.getFirstLine() + " cseq method = " + sipMessage.getCSeq().getMethod()); } for (MessageProcessor messageProcessor : getSIPStack().getMessageProcessors()) { if (messageProcessor.getIpAddress().getHostAddress().equals(this.getPeerAddress()) && messageProcessor.getPort() == this.getPeerPort() && messageProcessor.getTransport().equalsIgnoreCase(this.getPeerProtocol())) { Runnable processMessageTask = new Runnable() { public void run() { try { processMessage((SIPMessage) sipMessage.clone()); } catch (Exception ex) { if (logger.isLoggingEnabled(ServerLogger.TRACE_ERROR)) { logger.logError("Error self routing message cause by: ", ex); } } } }; getSIPStack().getSelfRoutingThreadpoolExecutor().execute(processMessageTask); if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) logger.logDebug("Self routing message"); return; } } byte[] msg = sipMessage.encodeAsBytes(this.getTransport()); long time = System.currentTimeMillis(); // need to store the peerPortAdvertisedInHeaders in case the response has an rport (ephemeral) // that failed to retry on the regular via port // for responses, no need to store anything for subsequent requests. if (peerPortAdvertisedInHeaders <= 0) { if (sipMessage instanceof SIPResponse) { SIPResponse sipResponse = (SIPResponse) sipMessage; Via via = sipResponse.getTopmostVia(); if (via.getRPort() > 0) { if (via.getPort() <= 0) { // if port is 0 we assume the default port for TCP this.peerPortAdvertisedInHeaders = 5060; } else { this.peerPortAdvertisedInHeaders = via.getPort(); } if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) { logger.logDebug( "1.Storing peerPortAdvertisedInHeaders = " + peerPortAdvertisedInHeaders + " for via port = " + via.getPort() + " via rport = " + via.getRPort() + " and peer port = " + peerPort + " for this channel " + this + " key " + key); } } } } // JvB: also retry for responses, if the connection is gone we should // try to reconnect this.sendMessage(msg, sipMessage instanceof SIPRequest); // message was sent without any exception so let's set set port and // address before we feed it to the logger sipMessage.setRemoteAddress(this.peerAddress); sipMessage.setRemotePort(this.peerPort); sipMessage.setLocalAddress(this.getMessageProcessor().getIpAddress()); sipMessage.setLocalPort(this.getPort()); if (logger.isLoggingEnabled(ServerLogger.TRACE_MESSAGES)) logMessage(sipMessage, peerAddress, peerPort, time); }