use of javax.sip.TransactionUnavailableException in project Spark by igniterealtime.
the class SipManager method processRequest.
// error occurred
// ============================= SIP LISTENER METHODS ==============================
public void processRequest(RequestEvent requestReceivedEvent) {
Log.debug(requestReceivedEvent.getRequest().toString());
ServerTransaction serverTransaction = requestReceivedEvent.getServerTransaction();
Request request = requestReceivedEvent.getRequest();
if (serverTransaction == null) {
try {
serverTransaction = sipProvider.getNewServerTransaction(request);
} catch (TransactionAlreadyExistsException ex) {
return;
} catch (TransactionUnavailableException ex) {
return;
}
}
Dialog dialog = serverTransaction.getDialog();
if (request.getMethod().equals(Request.NOTIFY)) {
Response ok = null;
try {
ok = messageFactory.createResponse(Response.OK, request);
} catch (ParseException ex) {
ex.printStackTrace();
}
ContactHeader contactHeader = null;
try {
contactHeader = getContactHeader();
ok.addHeader(contactHeader);
attachToTag(ok, dialog);
System.err.println(ok.toString());
serverTransaction.sendResponse(ok);
} catch (CommunicationsException e) {
e.printStackTrace();
} catch (InvalidArgumentException e) {
e.printStackTrace();
} catch (SipException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
fireMessageReceived(request);
return;
}
// TODO REMOVE
@SuppressWarnings("unused") Request requestClone = (Request) request.clone();
// INVITE
if (request.getMethod().equals(Request.INVITE)) {
if (serverTransaction.getDialog().getState() == null) {
callProcessing.processInvite(serverTransaction, request);
} else {
callProcessing.processReInvite(serverTransaction, request);
}
} else // ACK
if (request.getMethod().equals(Request.ACK)) {
if (serverTransaction != null && serverTransaction.getDialog().getFirstTransaction().getRequest().getMethod().equals(Request.INVITE)) {
callProcessing.processAck(serverTransaction, request);
} else {
// just ignore
}
} else // BYE
if (request.getMethod().equals(Request.BYE)) {
if (dialog.getFirstTransaction().getRequest().getMethod().equals(Request.INVITE) || dialog.getFirstTransaction().getRequest().getMethod().equals(Request.REFER)) {
callProcessing.processBye(serverTransaction, request);
}
} else // CANCEL
if (request.getMethod().equals(Request.CANCEL)) {
if (dialog.getFirstTransaction().getRequest().getMethod().equals(Request.INVITE)) {
callProcessing.processCancel(serverTransaction, request);
} else {
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
}
} else // REFER
if (request.getMethod().equals(Request.REFER)) {
transferProcessing.processRefer(serverTransaction, request);
} else if (request.getMethod().equals(Request.INFO)) {
/**
* @todo add proper request handling
*/
fireMessageReceived(request);
} else if (request.getMethod().equals(Request.MESSAGE)) {
messageProcessing.processMessageRequest(serverTransaction, request);
fireMessageReceived(request);
} else if (request.getMethod().equals(Request.OPTIONS)) {
/**
* @todo add proper request handling
*/
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
} else if (request.getMethod().equals(Request.PRACK)) {
/**
* @todo add proper request handling
*/
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
} else if (request.getMethod().equals(Request.REGISTER)) {
/**
* @todo add proper request handling
*/
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
} else if (request.getMethod().equals(Request.SUBSCRIBE)) {
} else if (request.getMethod().equals(Request.UPDATE)) {
/**
* @todo add proper request handling
*/
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
} else if (request.getMethod().equals(Request.INFO)) {
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
} else {
// We couldn't recognise the message
sendNotImplemented(serverTransaction, request);
fireUnknownMessageReceived(requestReceivedEvent.getRequest());
}
}
use of javax.sip.TransactionUnavailableException in project Spark by igniterealtime.
the class CallProcessing method sendNumDTMF.
// end call
// send dtmf
private void sendNumDTMF(Dialog dialog, String digit) throws CommunicationsException {
Request info = null;
String body = "Signal=" + digit + "\nDuration=160";
String contentType = "application/dtmf-relay";
String[] contentTypeTab = contentType.split("/");
ContentTypeHeader contentTypeHeader = null;
try {
info = dialog.createRequest(Request.INFO);
try {
contentTypeHeader = sipManCallback.headerFactory.createContentTypeHeader(contentTypeTab[0], contentTypeTab[1]);
info.setContent(body, contentTypeHeader);
} catch (ParseException ex) {
throw new CommunicationsException("ContentType Header must look like type/subtype!", ex);
}
} catch (SipException ex) {
throw new CommunicationsException("Failed to create bye request!", ex);
}
ClientTransaction clientTransaction = null;
try {
clientTransaction = sipManCallback.sipProvider.getNewClientTransaction(info);
} catch (TransactionUnavailableException ex) {
throw new CommunicationsException("Failed to construct a client transaction from the INFO request", ex);
}
try {
dialog.sendRequest(clientTransaction);
} catch (SipException ex1) {
throw new CommunicationsException("Failed to send the INFO request");
}
}
use of javax.sip.TransactionUnavailableException in project load-balancer by RestComm.
the class SIPBalancerForwarder method processResponse.
/**
* @param originalRequest
* @param serverTransaction
* @throws ParseException
* @throws SipException
* @throws InvalidArgumentException
* @throws TransactionUnavailableException
*/
/*
* (non-Javadoc)
* @see javax.sip.SipListener#processResponse(javax.sip.ResponseEvent)
*/
public void processResponse(ResponseEvent responseEvent) {
BalancerAppContent content = (BalancerAppContent) responseEvent.getSource();
boolean isIpv6 = content.isIpv6();
SipProvider sipProvider = content.getProvider();
Response originalResponse = responseEvent.getResponse();
if (logger.isDebugEnabled()) {
logger.debug("got response :\n" + originalResponse);
}
updateStats(originalResponse);
final Response response = (Response) originalResponse;
Node senderNode = getSenderNode(response);
if (senderNode != null) {
if (logger.isDebugEnabled()) {
logger.debug("Updating Timestamp of sendernode: " + senderNode);
}
senderNode.updateTimerStamp();
}
// Topmost via headers is me. As it is response to external request
ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
String branch = viaHeader.getBranch();
int versionDelimiter = branch.lastIndexOf('_');
String version = branch.substring(versionDelimiter + 1);
InvocationContext ctx = balancerRunner.getInvocationContext(version);
if (viaHeader != null && !isHeaderExternal(viaHeader.getHost(), viaHeader.getPort(), viaHeader.getTransport(), isIpv6)) {
response.removeFirst(ViaHeader.NAME);
}
viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
String transport = viaHeader.getTransport();
if (viaHeader != null && !isHeaderExternal(viaHeader.getHost(), viaHeader.getPort(), viaHeader.getTransport(), isIpv6)) {
response.removeFirst(ViaHeader.NAME);
}
boolean fromServer = false;
if (balancerRunner.balancerContext.isTwoEntrypoints()) {
if (!isIpv6)
fromServer = sipProvider.equals(balancerRunner.balancerContext.internalSipProvider);
else
fromServer = sipProvider.equals(balancerRunner.balancerContext.internalIpv6SipProvider);
if (logger.isDebugEnabled()) {
if (!isIpv6)
logger.debug("fromServer : " + fromServer + ", sipProvider " + sipProvider + ", internalSipProvider " + balancerRunner.balancerContext.internalSipProvider);
else
logger.debug("fromServer : " + fromServer + ", sipProvider " + sipProvider + ", internalIpv6SipProvider " + balancerRunner.balancerContext.internalIpv6SipProvider);
}
} else {
fromServer = senderNode == null;
if (logger.isDebugEnabled()) {
logger.debug("fromServer : " + fromServer + ", senderNode " + senderNode);
}
}
// only for external responses
if (balancerRunner.balancerContext.isUseWithNexmo && !fromServer) {
viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
if (viaHeader != null) {
if (logger.isDebugEnabled())
logger.debug("We are going to remove rport and received parametres from :" + viaHeader + " from external response");
response.removeFirst(ViaHeader.NAME);
viaHeader.removeParameter("rport");
viaHeader.removeParameter("received");
try {
response.addFirst(viaHeader);
} catch (NullPointerException | SipException e) {
e.printStackTrace();
}
if (logger.isDebugEnabled())
logger.debug("After removing :" + response);
}
}
if (fromServer) {
if (senderNode != null && senderNode.getIp() != null) {
if (balancerRunner.balancerContext.maxRequestNumberWithoutResponse != null && balancerRunner.balancerContext.maxResponseTime != null) {
KeySip keySip = new KeySip(senderNode, isIpv6);
// adding null check for https://github.com/RestComm/load-balancer/issues/83
Node currNode = ctx.sipNodeMap(isIpv6).get(keySip);
if (currNode != null) {
if (logger.isDebugEnabled())
logger.debug("We are going to reset counters of health check" + currNode.getRequestNumberWithoutResponse() + " : " + currNode.getLastTimeResponse());
currNode.setLastTimeResponse(System.currentTimeMillis());
currNode.setRequestNumberWithoutResponse(0);
if (logger.isDebugEnabled())
logger.debug("Counter of request without responses is : " + currNode.getRequestNumberWithoutResponse() + " : " + currNode.getLastTimeResponse());
} else {
logger.warn("Node is null, we will not reset counters");
}
}
mediaFailureDetection(response, ctx, senderNode);
}
/*
if("true".equals(balancerRunner.balancerContext.properties.getProperty("removeNodesOn500Response")) && response.getStatusCode() == 500) {
// If the server is broken remove it from the list and try another one with the next retransmission
if(!(sourceNode instanceof ExtraServerNode)) {
if(balancerRunner.balancerContext.nodes.size()>1) {
balancerRunner.balancerContext.nodes.remove(sourceNode);
balancerRunner.balancerContext.balancerAlgorithm.nodeRemoved(sourceNode);
}
}
}
*/
String publicIp = null;
if (!isIpv6)
publicIp = balancerRunner.balancerContext.publicIP;
else
publicIp = balancerRunner.balancerContext.publicIPv6;
if (publicIp != null && publicIp.trim().length() > 0) {
if (logger.isDebugEnabled()) {
logger.debug("Will add Record-Route header to response with public IP Address: " + publicIp);
}
patchSipMessageForNAT(response, isIpv6);
}
// https://github.com/RestComm/load-balancer/issues/45 Adding sender node for the algorithm to be available
((ResponseExt) response).setApplicationData(senderNode);
ctx.balancerAlgorithm.processInternalResponse(response, isIpv6);
try {
if (logger.isDebugEnabled()) {
logger.debug("from server sending response externally " + response);
}
if (!isIpv6)
balancerRunner.balancerContext.externalSipProvider.sendResponse(response);
else
balancerRunner.balancerContext.externalIpv6SipProvider.sendResponse(response);
} catch (Exception ex) {
logger.error("Unexpected exception while forwarding the response \n" + response, ex);
}
} else {
try {
SIPMessage message = (SIPMessage) response;
String initialRemoteAddr = message.getPeerPacketSourceAddress().getHostAddress();
String initialRemotePort = String.valueOf(message.getPeerPacketSourcePort());
Header remoteAddrHeader = null;
Header remotePortHeader = null;
try {
HeaderFactory hf = SipFactory.getInstance().createHeaderFactory();
remoteAddrHeader = hf.createHeader("X-Sip-Balancer-InitialRemoteAddr", initialRemoteAddr);
remotePortHeader = hf.createHeader("X-Sip-Balancer-InitialRemotePort", initialRemotePort);
} catch (PeerUnavailableException e) {
logger.error("Unexpected exception while creating custom headers for REGISTER message ", e);
} catch (ParseException e) {
logger.error("Unexpected exception while creating custom headers for REGISTER message ", e);
}
if (remoteAddrHeader != null)
response.addHeader(remoteAddrHeader);
if (remotePortHeader != null)
response.addHeader(remotePortHeader);
if (balancerRunner.balancerContext.isTwoEntrypoints()) {
ctx.balancerAlgorithm.processExternalResponse(response, isIpv6);
if (logger.isDebugEnabled()) {
logger.debug("two entry points: from external sending response " + response);
}
if (!isIpv6)
balancerRunner.balancerContext.internalSipProvider.sendResponse(response);
else
balancerRunner.balancerContext.internalIpv6SipProvider.sendResponse(response);
} else {
if (!comesFromInternalNode(response, ctx, initialRemoteAddr, message.getPeerPacketSourcePort(), transport, isIpv6))
ctx.balancerAlgorithm.processExternalResponse(response, isIpv6);
else
ctx.balancerAlgorithm.processInternalResponse(response, isIpv6);
if (logger.isDebugEnabled()) {
logger.debug("one entry point: from external sending response " + response);
}
if (!isIpv6)
balancerRunner.balancerContext.externalSipProvider.sendResponse(response);
else
balancerRunner.balancerContext.externalIpv6SipProvider.sendResponse(response);
}
} catch (Exception ex) {
logger.error("Unexpected exception while forwarding the response \n" + response, ex);
}
}
}
use of javax.sip.TransactionUnavailableException 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);
}
}
}
use of javax.sip.TransactionUnavailableException in project load-balancer by RestComm.
the class Shootist method processRequest.
public void processRequest(RequestEvent requestReceivedEvent) {
Request request = requestReceivedEvent.getRequest();
requests.add(request);
ServerTransaction serverTransactionId = requestReceivedEvent.getServerTransaction();
if (serverTransactionId == null) {
try {
serverTransactionId = sipProvider.getNewServerTransaction(request);
} catch (TransactionAlreadyExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransactionUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\n\nRequest " + request.getMethod() + " received at " + sipStack.getStackName() + " with server transaction id " + serverTransactionId);
if (request.getMethod().equals(Request.INVITE)) {
processInvite(request, serverTransactionId);
} else if (request.getMethod().equals(Request.BYE)) {
processBye(request, serverTransactionId);
} else if (request.getMethod().equals(Request.ACK)) {
processAck(request, serverTransactionId);
} else {
try {
serverTransactionId.sendResponse(messageFactory.createResponse(200, request));
} catch (Exception e) {
e.printStackTrace();
fail("Unxepcted exception ");
}
}
}
Aggregations