use of gov.nist.javax.sip.header.HeaderExt in project load-balancer by RestComm.
the class SIPBalancerForwarder method forwardRequest.
/**
* @param requestEvent
* @param sipProvider
* @param originalRequest
* @param serverTransaction
* @param request
* @throws ParseException
* @throws InvalidArgumentException
* @throws SipException
* @throws TransactionUnavailableException
*/
private void forwardRequest(SipProvider sipProvider, Request request, boolean isIpv6) throws ParseException, InvalidArgumentException, SipException, TransactionUnavailableException {
if (logger.isDebugEnabled()) {
logger.debug("got request:\n" + request);
}
boolean isRequestFromServer = false;
if (!balancerRunner.balancerContext.isTwoEntrypoints()) {
isRequestFromServer = isViaHeaderFromServer(request);
} else {
isRequestFromServer = sipProvider.equals(balancerRunner.balancerContext.internalSipProvider) || sipProvider.equals(balancerRunner.balancerContext.internalIpv6SipProvider);
}
if (isRequestFromServer) {
ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
String host = viaHeader.getHost();
if (host.matches(".*[a-zA-Z]+.*")) {
try {
host = InetAddress.getByName(host).getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
int port = viaHeader.getPort();
String transport = viaHeader.getTransport().toLowerCase();
Node node = getNodeDeadOrAlive(host, port, transport);
if (node != null) {
if (logger.isDebugEnabled())
logger.debug("Updating Timestamp of node: " + node + " because of request from it");
node.updateTimerStamp();
}
}
final boolean isCancel = Request.CANCEL.equals(request.getMethod());
if (!isCancel) {
decreaseMaxForwardsHeader(sipProvider, request);
}
String outerTransport = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport().toLowerCase();
if (isRequestFromServer) {
Boolean hasTransport = false;
if (request.getRequestURI().isSipURI()) {
if (((SipUri) request.getRequestURI()).getTransportParam() != null) {
outerTransport = ((SipUri) request.getRequestURI()).getTransportParam();
hasTransport = true;
}
}
if (!hasTransport) {
outerTransport = getRouteHeadersMeantForLB(request, isIpv6);
if (outerTransport == null)
outerTransport = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport().toLowerCase();
}
}
RouteHeaderHints hints = removeRouteHeadersMeantForLB(request, isIpv6);
String version = hints.version;
if (version == null) {
version = register.getLatestVersion();
hints.version = version;
}
InvocationContext ctx = balancerRunner.getInvocationContext(version);
final String callID = ((CallIdHeader) request.getHeader(CallIdHeader.NAME)).getCallId();
String transport = null;
if (balancerRunner.balancerContext.internalTransport != null) {
if (logger.isDebugEnabled()) {
logger.debug("Set internal transport for NODE looking: " + balancerRunner.balancerContext.internalTransport);
}
transport = balancerRunner.balancerContext.internalTransport.toLowerCase();
} else if (balancerRunner.balancerContext.terminateTLSTraffic) {
switch(((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport()) {
case ListeningPoint.TLS:
transport = ListeningPoint.TCP.toLowerCase();
break;
case ListeningPointExt.WSS:
transport = ListeningPointExt.WS.toLowerCase();
break;
case ListeningPointExt.WS:
case ListeningPointExt.TCP:
case ListeningPointExt.UDP:
transport = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport().toLowerCase();
}
if (logger.isDebugEnabled()) {
logger.debug("Terminate TLS traffic, isRequestFromServer: " + isRequestFromServer + " transport before " + ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport() + ", transport after " + transport);
}
} else {
transport = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport().toLowerCase();
}
if (hints.serverAssignedNode != null) {
String headerKey = null;
if (balancerRunner.balancerContext.sipHeaderAffinityKey.equalsIgnoreCase(ToHeader.NAME)) {
URI currURI = ((HeaderAddress) request.getHeader(balancerRunner.balancerContext.sipHeaderAffinityKey)).getAddress().getURI();
if (currURI.isSipURI())
headerKey = ((SipURI) currURI).getUser();
else
headerKey = ((TelURL) currURI).getPhoneNumber();
if (balancerRunner.balancerContext.sipHeaderAffinityKeyExclusionPattern != null && balancerRunner.balancerContext.sipHeaderAffinityKeyExclusionPattern.matcher(headerKey).matches()) {
headerKey = ((HeaderExt) request.getHeader(balancerRunner.balancerContext.sipHeaderAffinityFallbackKey)).getValue();
}
} else if (balancerRunner.balancerContext.sipHeaderAffinityKey.equalsIgnoreCase(FromHeader.NAME)) {
headerKey = ((HeaderAddress) request.getHeader(balancerRunner.balancerContext.sipHeaderAffinityKey)).getAddress().getURI().toString();
if (balancerRunner.balancerContext.sipHeaderAffinityKeyExclusionPattern != null && balancerRunner.balancerContext.sipHeaderAffinityKeyExclusionPattern.matcher(headerKey).matches()) {
headerKey = ((HeaderExt) request.getHeader(balancerRunner.balancerContext.sipHeaderAffinityFallbackKey)).getValue();
}
} else {
headerKey = ((HeaderExt) request.getHeader(balancerRunner.balancerContext.sipHeaderAffinityKey)).getValue();
}
if (logger.isDebugEnabled()) {
logger.debug("headerKey " + headerKey);
}
if (!request.getMethod().equalsIgnoreCase(Request.ACK))
ctx.balancerAlgorithm.assignToNode(headerKey, hints.serverAssignedNode);
if (logger.isDebugEnabled()) {
logger.debug("Following node information has been found in one of the route Headers " + hints.serverAssignedNode);
}
// SipURI loopbackUri = getLoopbackUri(request);
// if(loopbackUri != null) {
// loopbackUri.setHost(hints.serverAssignedNode.getIp());
// loopbackUri.setPort((Integer) hints.serverAssignedNode.getProperties().get(transport + "Port"));
// }
}
Node nextNode = null;
if (isRequestFromServer) {
if (logger.isDebugEnabled()) {
logger.debug("Request from server");
}
Header initialAddrHeader = request.getHeader("X-Sip-Balancer-InitialRemoteAddr");
Header initialPortHeader = request.getHeader("X-Sip-Balancer-InitialRemotePort");
if (initialAddrHeader != null)
request.removeHeader(initialAddrHeader.getName());
if (initialPortHeader != null)
request.removeHeader(initialPortHeader.getName());
ctx.balancerAlgorithm.processInternalRequest(request);
if (request.getMethod().equalsIgnoreCase(Request.INVITE) && ctx.balancerAlgorithm.blockInternalRequest(request)) {
Response response = balancerRunner.balancerContext.messageFactory.createResponse(Response.FORBIDDEN, request);
response.setReasonPhrase("Destination not allowed");
sipProvider.sendResponse(response);
return;
}
nextNode = hints.serverAssignedNode;
if (logger.isDebugEnabled()) {
logger.debug("nexNode " + nextNode);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Request not from server");
}
if (hints.serverAssignedNode != null) {
SipURI loopbackUri = getLoopbackUri(request, isIpv6);
if (loopbackUri != null) {
loopbackUri.setHost(hints.serverAssignedNode.getIp());
loopbackUri.setPort(Integer.parseInt(hints.serverAssignedNode.getProperties().get(transport + "Port")));
}
}
// Request is NOT from app server, first check if we have hints in Route headers
Node assignedNode = hints.serverAssignedNode;
// If there are no hints see if there is route header pointing existing node
if (assignedNode == null) {
RouteHeader nextNodeHeader = (RouteHeader) request.getHeader(RouteHeader.NAME);
if (nextNodeHeader != null) {
URI uri = nextNodeHeader.getAddress().getURI();
if (uri instanceof SipURI) {
SipURI sipUri = (SipURI) uri;
assignedNode = getAliveNode(sipUri.getHost(), sipUri.getPort(), transport, ctx, isIpv6);
if (logger.isDebugEnabled()) {
logger.debug("Found SIP URI " + uri + " |Next node is " + assignedNode);
}
}
}
}
SipURI assignedUri = null;
// boolean nextNodeInRequestUri = false;
SipURI originalRouteHeaderUri = null;
if (assignedNode == null) {
if (hints.subsequentRequest) {
RouteHeader header = (RouteHeader) request.getHeader(RouteHeader.NAME);
if (header != null) {
assignedUri = (SipURI) header.getAddress().getURI();
originalRouteHeaderUri = (SipURI) assignedUri.clone();
request.removeFirst(RouteHeader.NAME);
} else {
if (request.getRequestURI() instanceof SipURI) {
SipURI sipUri = (SipURI) request.getRequestURI();
// nextNodeInRequestUri = true;
assignedNode = getAliveNode(sipUri.getHost(), sipUri.getPort(), transport, ctx, isIpv6);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Subsequent request -> Found Route Header " + header + " |Next node is " + assignedNode);
}
} else if (request.getRequestURI() instanceof SipURI) {
SipURI sipUri = (SipURI) request.getRequestURI();
// nextNodeInRequestUri = true;
assignedNode = getAliveNode(sipUri.getHost(), sipUri.getPort(), transport, ctx, isIpv6);
if (logger.isDebugEnabled()) {
logger.debug("NOT Subsequent request -> using sipUri " + sipUri + " |Next node is " + assignedNode);
}
}
}
if (assignedNode == null) {
if (logger.isDebugEnabled()) {
logger.debug("assignedNode is null");
}
if (!securityCheck(request)) {
logger.warn("Request failed at the security check:\n" + request);
} else {
nextNode = ctx.balancerAlgorithm.processExternalRequest(request, isIpv6);
}
if (nextNode instanceof NullServerNode) {
if (logger.isDebugEnabled()) {
logger.debug("Algorithm returned a NullServerNode. We will not attempt to forward this request " + request);
}
}
if (nextNode != null) {
if (logger.isDebugEnabled()) {
String nodesString = "";
// Object[] nodes = ctx.nodes.toArray();
Object[] nodes = ctx.sipNodeMap(isIpv6).values().toArray();
for (Object n : nodes) {
nodesString += n + " , ";
}
logger.debug("Next node is not null. Assigned uri is " + assignedUri + "Available nodes: " + nodesString);
}
// Adding Route Header pointing to the node the sip balancer wants to forward to
SipURI routeSipUri;
try {
if (assignedUri == null) {
// If a next node is NOT already assigned in the dialog from previous requests
routeSipUri = balancerRunner.balancerContext.addressFactory.createSipURI(null, nextNode.getIp());
} else {
// OTHERWISE, a node is already assigned and it's alive
routeSipUri = assignedUri;
}
routeSipUri.setHost(nextNode.getIp());
Integer port = Integer.parseInt(nextNode.getProperties().get(transport + "Port"));
if (port == null) {
throw new RuntimeException("Port is null in the node properties for transport=" + transport);
}
routeSipUri.setPort(port);
routeSipUri.setTransportParam(transport);
routeSipUri.setLrParam();
SipURI uri = (SipURI) request.getRequestURI();
RouteHeader header = (RouteHeader) request.getHeader(RouteHeader.NAME);
if (isHeaderExternal(uri.getHost(), uri.getPort(), ((ViaHeader) request.getHeader("Via")).getTransport(), isIpv6) || header != null) {
final RouteHeader route = balancerRunner.balancerContext.headerFactory.createRouteHeader(balancerRunner.balancerContext.addressFactory.createAddress(routeSipUri));
request.addFirst(route);
// For http://code.google.com/p/mobicents/issues/detail?id=2132
if (originalRouteHeaderUri != null && request.getRequestURI().isSipURI()) {
// we will just compare by hostport id
String rurihostid = uri.getHost() + uri.getPort();
String originalhostid = originalRouteHeaderUri.getHost() + originalRouteHeaderUri.getPort();
if (rurihostid.equals(originalhostid)) {
uri.setPort(routeSipUri.getPort());
uri.setHost(routeSipUri.getHost());
}
}
} else {
// should not add any routes , packet is destinated to lb
uri.setPort(routeSipUri.getPort());
uri.setHost(routeSipUri.getHost());
}
} catch (Exception e) {
throw new RuntimeException("Error adding route header", e);
}
}
} else {
nextNode = ctx.balancerAlgorithm.processAssignedExternalRequest(request, assignedNode);
if (logger.isDebugEnabled()) {
logger.debug("Next node " + nextNode + " from assignedNode " + assignedNode);
}
// add Route header for using it for transferring instead of using uri
if (nextNode != null && hints.subsequentRequest && !isRequestFromServer) {
if (request.getRequestURI().isSipURI()) {
SipURI sipUri = (SipURI) request.getRequestURI();
SipURI routeSipUri = balancerRunner.balancerContext.addressFactory.createSipURI(null, nextNode.getIp());
Integer port = Integer.parseInt(nextNode.getProperties().get(transport + "Port"));
// port should not be null since it subsequent request
if (port != null) {
routeSipUri.setPort(port);
routeSipUri.setTransportParam(transport);
routeSipUri.setLrParam();
if (!sipUri.getHost().equals(routeSipUri.getHost()) || sipUri.getPort() != routeSipUri.getPort()) {
Boolean oldHeaderMatch = false;
Header oldHeader = request.getHeader(RouteHeader.NAME);
if (oldHeader != null) {
RouteHeader oldRouteHeader = (RouteHeader) oldHeader;
if (oldRouteHeader.getAddress().getURI().isSipURI()) {
SipURI oldURI = (SipURI) oldRouteHeader.getAddress().getURI();
if (oldURI.getHost().equals(routeSipUri.getHost()) && oldURI.getPort() == routeSipUri.getPort())
oldHeaderMatch = true;
}
}
if (!oldHeaderMatch) {
final RouteHeader route = balancerRunner.balancerContext.headerFactory.createRouteHeader(balancerRunner.balancerContext.addressFactory.createAddress(routeSipUri));
request.addFirst(route);
}
}
}
}
}
}
if (nextNode == null) {
if (logger.isDebugEnabled()) {
logger.debug("No nodes available");
}
if (!Request.ACK.equalsIgnoreCase(request.getMethod())) {
try {
Response response = balancerRunner.balancerContext.messageFactory.createResponse(Response.SERVER_INTERNAL_ERROR, request);
response.setReasonPhrase("No nodes available");
sipProvider.sendResponse(response);
} catch (Exception e) {
logger.error("Unexpected exception while trying to send the error response for this " + request, e);
}
}
return;
} else {
}
if (balancerRunner.balancerContext.maxRequestNumberWithoutResponse != null && balancerRunner.balancerContext.maxResponseTime != null && !Request.ACK.equalsIgnoreCase(request.getMethod()))
nodeHealthcheck(ctx, nextNode);
}
if (logger.isDebugEnabled()) {
logger.debug("Next node " + nextNode);
}
String requestMethod = request.getMethod();
// https://telestax.atlassian.net/browse/LB-25 improve performance by sending back 100 Trying right away to tame retransmissions.
if (balancerRunner.balancerContext.isSendTrying) {
logger.debug("Load balancer sends 100 TRYING");
if (requestMethod.equals(Request.INVITE) || requestMethod.equals(Request.SUBSCRIBE) || requestMethod.equals(Request.NOTIFY) || requestMethod.equals(Request.MESSAGE) || requestMethod.equals(Request.REFER) || requestMethod.equals(Request.PUBLISH) || requestMethod.equals(Request.UPDATE)) {
try {
Response response = balancerRunner.balancerContext.messageFactory.createResponse(Response.TRYING, request);
RouteList routeList = ((SIPMessage) request).getRouteHeaders();
if (routeList != null) {
Route route = (Route) routeList.getFirst();
SipUri sipUri = (SipUri) route.getAddress().getURI();
if (sipUri.toString().contains("node_host") || sipUri.toString().contains("node_port")) {
String nodeHost = sipUri.getParameter("node_host");
int nodePort = Integer.parseInt(sipUri.getParameter("node_port"));
ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
viaHeader.setHost(nodeHost);
viaHeader.setPort(nodePort);
}
}
sipProvider.sendResponse(response);
} catch (SipException e) {
logger.error("Unexpected exception while sending TRYING", e);
} catch (ParseException e) {
logger.error("Unexpected exception while sending TRYING", e);
} catch (NumberFormatException e) {
logger.error("Unexpected exception while sending TRYING", e);
} catch (InvalidArgumentException e) {
logger.error("Unexpected exception while sending TRYING", e);
}
}
} else {
logger.debug("Load balancer do not send 100 TRYING, this option is disabled");
}
hints.serverAssignedNode = nextNode;
if (!hints.subsequentRequest && dialogCreationMethods.contains(request.getMethod())) {
addLBRecordRoute(sipProvider, request, hints, version, isIpv6);
}
// Stateless proxies must not use internal state or ransom values when creating branch because they
// must repeat exactly the same branches for retransmissions
final ViaHeader via = (ViaHeader) request.getHeader(ViaHeader.NAME);
String newBranch = via.getBranch() + callID.substring(0, Math.min(callID.length(), 5));
// Add the via header to the top of the header list.
ViaHeader viaHeaderExternal = null;
ViaHeader viaHeaderInternal = null;
String externalViaHost = null;
String internalViaHost = null;
String meantHost = null;
if (!isRequestFromServer)
meantHost = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getReceived();
else {
Header routeHeader = request.getHeader(RouteHeader.NAME);
if (routeHeader != null)
meantHost = ((SipURI) ((RouteHeader) routeHeader).getAddress().getURI()).getHost();
}
if (!isIpv6) {
if (balancerRunner.balancerContext.routingRulesIpv4 != null && meantHost != null) {
boolean found = false;
for (RoutingRule rule : balancerRunner.balancerContext.routingRulesIpv4) {
if (rule.getIpPattern().matcher(meantHost).matches() && !rule.isPatch) {
found = true;
externalViaHost = balancerRunner.balancerContext.externalHost;
internalViaHost = balancerRunner.balancerContext.internalHost;
break;
}
}
if (!found) {
externalViaHost = balancerRunner.balancerContext.externalViaHost;
internalViaHost = balancerRunner.balancerContext.internalViaHost;
}
} else {
externalViaHost = balancerRunner.balancerContext.externalViaHost;
internalViaHost = balancerRunner.balancerContext.internalViaHost;
}
} else {
if (balancerRunner.balancerContext.routingRulesIpv6 != null && meantHost != null) {
boolean found = false;
for (RoutingRule rule : balancerRunner.balancerContext.routingRulesIpv6) {
if (rule.getIpPattern().matcher(meantHost).matches() && !rule.isPatch) {
found = true;
externalViaHost = balancerRunner.balancerContext.externalIpv6Host;
internalViaHost = balancerRunner.balancerContext.internalIpv6Host;
break;
}
}
if (!found) {
externalViaHost = balancerRunner.balancerContext.externalIpv6ViaHost;
internalViaHost = balancerRunner.balancerContext.internalIpv6ViaHost;
}
} else {
externalViaHost = balancerRunner.balancerContext.externalIpv6ViaHost;
internalViaHost = balancerRunner.balancerContext.internalIpv6ViaHost;
}
}
if (!isRequestFromServer) {
viaHeaderExternal = balancerRunner.balancerContext.headerFactory.createViaHeader(externalViaHost, balancerRunner.balancerContext.getExternalViaPortByTransport(outerTransport, isIpv6), outerTransport, newBranch + "_" + version);
String innerTransport = transport;
if (balancerRunner.balancerContext.internalTransport != null) {
if (logger.isDebugEnabled()) {
logger.debug("Set internal transport for for creating Via header : " + balancerRunner.balancerContext.internalTransport);
}
innerTransport = balancerRunner.balancerContext.internalTransport;
} else if (balancerRunner.balancerContext.terminateTLSTraffic) {
if (logger.isDebugEnabled()) {
logger.debug("Terminate TLS traffic, isRequestFromServer: " + isRequestFromServer + " transport before " + innerTransport);
}
if (innerTransport.equalsIgnoreCase(ListeningPoint.TLS))
innerTransport = ListeningPoint.TCP;
else if (innerTransport.equalsIgnoreCase(ListeningPointExt.WSS))
innerTransport = ListeningPointExt.WS;
if (logger.isDebugEnabled()) {
logger.debug("Terminate TLS traffic, transport after " + innerTransport);
}
}
if (balancerRunner.balancerContext.isTwoEntrypoints())
viaHeaderInternal = balancerRunner.balancerContext.headerFactory.createViaHeader(internalViaHost, balancerRunner.balancerContext.getInternalViaPortByTransport(innerTransport, isIpv6), innerTransport, newBranch + "zsd" + "_" + version);
else
viaHeaderInternal = balancerRunner.balancerContext.headerFactory.createViaHeader(externalViaHost, balancerRunner.balancerContext.getExternalViaPortByTransport(innerTransport, isIpv6), innerTransport, newBranch + "zsd" + "_" + version);
} else {
if (balancerRunner.balancerContext.isTwoEntrypoints())
viaHeaderInternal = balancerRunner.balancerContext.headerFactory.createViaHeader(internalViaHost, balancerRunner.balancerContext.getInternalViaPortByTransport(transport, isIpv6), transport, newBranch + "zsd" + "_" + version);
else
viaHeaderInternal = balancerRunner.balancerContext.headerFactory.createViaHeader(externalViaHost, balancerRunner.balancerContext.getExternalViaPortByTransport(transport, isIpv6), transport, newBranch + "zsd" + "_" + version);
// https://github.com/RestComm/load-balancer/issues/67
// if (balancerRunner.balancerContext.terminateTLSTraffic) {
// if(logger.isDebugEnabled()) {
// logger.debug("Terminate TLS traffic, isRequestFromServer: " + isRequestFromServer +
// " transport before " + outerTransport);
// }
//
// if (outerTransport.equalsIgnoreCase(ListeningPoint.TCP))
// outerTransport = ListeningPoint.TLS;
// else if (outerTransport.equalsIgnoreCase(ListeningPointExt.WS))
// outerTransport = ListeningPointExt.WSS;
//
// if(logger.isDebugEnabled()) {
// logger.debug("Terminate TLS traffic, transport after " + outerTransport);
// }
// }
viaHeaderExternal = balancerRunner.balancerContext.headerFactory.createViaHeader(externalViaHost, balancerRunner.balancerContext.getExternalViaPortByTransport(outerTransport, isIpv6), outerTransport, newBranch + "_" + version);
}
if (logger.isDebugEnabled()) {
logger.debug("ViaHeaders will be added " + viaHeaderExternal + " and " + viaHeaderInternal);
logger.debug("Sending the request:\n" + request + "\n on the other side");
}
if (getLoopbackUri(request, isIpv6) != null) {
logger.warn("Drop. Cannot forward to loopback the following request: " + request);
return;
}
try {
if (!isRequestFromServer) {
request.addHeader(viaHeaderExternal);
if (viaHeaderInternal != null)
request.addHeader(viaHeaderInternal);
if (balancerRunner.balancerContext.terminateTLSTraffic) {
// https://github.com/RestComm/load-balancer/issues/67
// Patching the contact header for incoming requests so that requests coming out of nodes will use the non secure version
ContactHeader contactHeader = (ContactHeader) request.getHeader(ContactHeader.NAME);
if (contactHeader != null) {
final URI contactURI = contactHeader.getAddress().getURI();
if (logger.isDebugEnabled()) {
logger.debug("Patching the contact header " + contactURI + " so that requests coming out of nodes will use the non secure protocol");
}
if (contactURI instanceof SipUri) {
((SipUri) contactURI).setTransportParam(outerTransport);
logger.debug("new transport " + contactURI + " so that requests coming out of nodes will use the non secure protocol");
}
}
} else if (balancerRunner.balancerContext.internalTransport != null) {
// https://github.com/RestComm/load-balancer/issues/67
// Patching the contact header for incoming requests so that requests coming out of nodes will use the non secure version
ContactHeader contactHeader = (ContactHeader) request.getHeader(ContactHeader.NAME);
if (contactHeader != null) {
final URI contactURI = contactHeader.getAddress().getURI();
if (logger.isDebugEnabled()) {
logger.debug("Patching the contact header " + contactURI + " so that requests coming out of nodes will use correct protocol");
}
if (contactURI instanceof SipUri) {
((SipUri) contactURI).setTransportParam(outerTransport);
logger.debug("new transport " + contactURI + " so that requests coming out of nodes will use correct protocol");
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("Sending the request:\n" + request);
}
if (balancerRunner.balancerContext.isTwoEntrypoints()) {
if (!isIpv6)
balancerRunner.balancerContext.internalSipProvider.sendRequest(request);
else {
balancerRunner.balancerContext.internalIpv6SipProvider.sendRequest(request);
}
} else {
if (!isIpv6)
balancerRunner.balancerContext.externalSipProvider.sendRequest(request);
else
balancerRunner.balancerContext.externalIpv6SipProvider.sendRequest(request);
}
} else {
// Check if the next hop is actually the load balancer again
if (viaHeaderInternal != null)
request.addHeader(viaHeaderInternal);
if (viaHeaderExternal != null)
request.addHeader(viaHeaderExternal);
// }
if (logger.isDebugEnabled()) {
logger.debug("Sending the request:\n" + request);
}
if (!isIpv6)
balancerRunner.balancerContext.externalSipProvider.sendRequest(request);
else
balancerRunner.balancerContext.externalIpv6SipProvider.sendRequest(request);
}
} catch (Exception e) {
if ((request.getMethod().equalsIgnoreCase(Request.OPTIONS) || e.getMessage().equals("Operation not permitted (sendto failed)")) && isRequestFromServer)
logger.warn("Problem with sending OPTIONS to external side possibly due to closed window in broweser");
else
logger.error("Unexpected exception while forwarding the request \n" + request, e);
if (balancerRunner.balancerContext.isSend5xxResponse)
try {
Response response = balancerRunner.balancerContext.messageFactory.createResponse(Response.SERVICE_UNAVAILABLE, request);
response.removeFirst(ViaHeader.NAME);
response.removeFirst(ViaHeader.NAME);
if (balancerRunner.balancerContext.isSend5xxResponseReasonHeader != null) {
HeaderFactory hf = SipFactory.getInstance().createHeaderFactory();
ReasonHeader reasonHeader = hf.createReasonHeader(transport, balancerRunner.balancerContext.isSend5xxResponseSatusCode, balancerRunner.balancerContext.isSend5xxResponseReasonHeader);
response.setHeader(reasonHeader);
}
sipProvider.sendResponse(response);
} catch (SipException ex) {
logger.error("Unexpected exception while sending SERVICE_UNAVAILABLE", ex);
} catch (ParseException ex) {
logger.error("Unexpected exception while sending SERVICE_UNAVAILABLE", ex);
} catch (NumberFormatException ex) {
logger.error("Unexpected exception while sending SERVICE_UNAVAILABLE", ex);
} catch (InvalidArgumentException ex) {
logger.error("Unexpected exception while sending SERVICE_UNAVAILABLE", ex);
}
}
}
Aggregations