use of gov.nist.javax.sip.header.ViaList in project XobotOS by xamarin.
the class UDPMessageChannel method processIncomingDataPacket.
/**
* Process an incoming datagram
*
* @param packet
* is the incoming datagram packet.
*/
private void processIncomingDataPacket(DatagramPacket packet) throws Exception {
this.peerAddress = packet.getAddress();
int packetLength = packet.getLength();
// Read bytes and put it in a eueue.
byte[] bytes = packet.getData();
byte[] msgBytes = new byte[packetLength];
System.arraycopy(bytes, 0, msgBytes, 0, packetLength);
// Do debug logging.
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("UDPMessageChannel: processIncomingDataPacket : peerAddress = " + peerAddress.getHostAddress() + "/" + packet.getPort() + " Length = " + packetLength);
}
SIPMessage sipMessage = null;
try {
this.receptionTime = System.currentTimeMillis();
sipMessage = myParser.parseSIPMessage(msgBytes);
myParser = null;
} catch (ParseException ex) {
// let go of the parser reference.
myParser = null;
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("Rejecting message ! " + new String(msgBytes));
this.sipStack.getStackLogger().logDebug("error message " + ex.getMessage());
this.sipStack.getStackLogger().logException(ex);
}
// JvB: send a 400 response for requests (except ACK)
// Currently only UDP, @todo also other transports
String msgString = new String(msgBytes, 0, packetLength);
if (!msgString.startsWith("SIP/") && !msgString.startsWith("ACK ")) {
String badReqRes = createBadReqRes(msgString, ex);
if (badReqRes != null) {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Sending automatic 400 Bad Request:");
sipStack.getStackLogger().logDebug(badReqRes);
}
try {
this.sendMessage(badReqRes.getBytes(), peerAddress, packet.getPort(), "UDP", false);
} catch (IOException e) {
this.sipStack.getStackLogger().logException(e);
}
} else {
if (sipStack.isLoggingEnabled()) {
sipStack.getStackLogger().logDebug("Could not formulate automatic 400 Bad Request");
}
}
}
return;
}
if (sipMessage == null) {
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logDebug("Rejecting message ! + Null message parsed.");
}
if (pingBackRecord.get(packet.getAddress().getHostAddress() + ":" + packet.getPort()) == null) {
byte[] retval = "\r\n\r\n".getBytes();
DatagramPacket keepalive = new DatagramPacket(retval, 0, retval.length, packet.getAddress(), packet.getPort());
((UDPMessageProcessor) this.messageProcessor).sock.send(keepalive);
this.sipStack.getTimer().schedule(new PingBackTimerTask(packet.getAddress().getHostAddress(), packet.getPort()), 1000);
}
return;
}
ViaList viaList = sipMessage.getViaHeaders();
// Check for the required headers.
if (sipMessage.getFrom() == null || sipMessage.getTo() == null || sipMessage.getCallId() == null || sipMessage.getCSeq() == null || sipMessage.getViaHeaders() == null) {
String badmsg = new String(msgBytes);
if (sipStack.isLoggingEnabled()) {
this.sipStack.getStackLogger().logError("bad message " + badmsg);
this.sipStack.getStackLogger().logError(">>> Dropped Bad Msg " + "From = " + sipMessage.getFrom() + "To = " + sipMessage.getTo() + "CallId = " + sipMessage.getCallId() + "CSeq = " + sipMessage.getCSeq() + "Via = " + sipMessage.getViaHeaders());
}
return;
}
// For response, just get the port from the packet.
if (sipMessage instanceof SIPRequest) {
Via v = (Via) viaList.getFirst();
Hop hop = sipStack.addressResolver.resolveAddress(v.getHop());
this.peerPort = hop.getPort();
this.peerProtocol = v.getTransport();
this.peerPacketSourceAddress = packet.getAddress();
this.peerPacketSourcePort = packet.getPort();
try {
this.peerAddress = packet.getAddress();
// Check to see if the received parameter matches
// the peer address and tag it appropriately.
boolean hasRPort = v.hasParameter(Via.RPORT);
if (hasRPort || !hop.getHost().equals(this.peerAddress.getHostAddress())) {
v.setParameter(Via.RECEIVED, this.peerAddress.getHostAddress());
}
if (hasRPort) {
v.setParameter(Via.RPORT, Integer.toString(this.peerPacketSourcePort));
}
} catch (java.text.ParseException ex1) {
InternalErrorHandler.handleException(ex1);
}
} else {
this.peerPacketSourceAddress = packet.getAddress();
this.peerPacketSourcePort = packet.getPort();
this.peerAddress = packet.getAddress();
this.peerPort = packet.getPort();
this.peerProtocol = ((Via) viaList.getFirst()).getTransport();
}
this.processMessage(sipMessage);
}
use of gov.nist.javax.sip.header.ViaList in project XobotOS by xamarin.
the class SIPServerTransaction method isMessagePartOfTransaction.
/**
* Determines if the message is a part of this transaction.
*
* @param messageToTest Message to check if it is part of this transaction.
*
* @return True if the message is part of this transaction, false if not.
*/
public boolean isMessagePartOfTransaction(SIPMessage messageToTest) {
// List of Via headers in the message to test
ViaList viaHeaders;
// Topmost Via header in the list
Via topViaHeader;
// Branch code in the topmost Via header
String messageBranch;
// Flags whether the select message is part of this transaction
boolean transactionMatches;
transactionMatches = false;
String method = messageToTest.getCSeq().getMethod();
// http://bugs.sipit.net/show_bug.cgi?id=769
if ((method.equals(Request.INVITE) || !isTerminated())) {
// Get the topmost Via header and its branch parameter
viaHeaders = messageToTest.getViaHeaders();
if (viaHeaders != null) {
topViaHeader = (Via) viaHeaders.getFirst();
messageBranch = topViaHeader.getBranch();
if (messageBranch != null) {
// does not start with the magic cookie,
if (!messageBranch.toLowerCase().startsWith(SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE)) {
// Flags this as old
// (RFC2543-compatible) client
// version
messageBranch = null;
}
}
// If a new branch parameter exists,
if (messageBranch != null && this.getBranch() != null) {
if (method.equals(Request.CANCEL)) {
// Cancel is handled as a special case because it
// shares the same same branch id of the invite
// that it is trying to cancel.
transactionMatches = this.getMethod().equals(Request.CANCEL) && getBranch().equalsIgnoreCase(messageBranch) && topViaHeader.getSentBy().equals(((Via) getOriginalRequest().getViaHeaders().getFirst()).getSentBy());
} else {
// Matching server side transaction with only the
// branch parameter.
transactionMatches = getBranch().equalsIgnoreCase(messageBranch) && topViaHeader.getSentBy().equals(((Via) getOriginalRequest().getViaHeaders().getFirst()).getSentBy());
}
} else {
// This is an RFC2543-compliant message; this code is here
// for backwards compatibility.
// It is a weak check.
// If RequestURI, To tag, From tag, CallID, CSeq number, and
// top Via headers are the same, the
// SIPMessage matches this transaction. An exception is for
// a CANCEL request, which is not deemed
// to be part of an otherwise-matching INVITE transaction.
String originalFromTag = super.fromTag;
String thisFromTag = messageToTest.getFrom().getTag();
boolean skipFrom = (originalFromTag == null || thisFromTag == null);
String originalToTag = super.toTag;
String thisToTag = messageToTest.getTo().getTag();
boolean skipTo = (originalToTag == null || thisToTag == null);
boolean isResponse = (messageToTest instanceof SIPResponse);
// be CANCEL for it to have a chance at matching.
if (messageToTest.getCSeq().getMethod().equalsIgnoreCase(Request.CANCEL) && !getOriginalRequest().getCSeq().getMethod().equalsIgnoreCase(Request.CANCEL)) {
transactionMatches = false;
} else if ((isResponse || getOriginalRequest().getRequestURI().equals(((SIPRequest) messageToTest).getRequestURI())) && (skipFrom || originalFromTag != null && originalFromTag.equalsIgnoreCase(thisFromTag)) && (skipTo || originalToTag != null && originalToTag.equalsIgnoreCase(thisToTag)) && getOriginalRequest().getCallId().getCallId().equalsIgnoreCase(messageToTest.getCallId().getCallId()) && getOriginalRequest().getCSeq().getSeqNumber() == messageToTest.getCSeq().getSeqNumber() && ((!messageToTest.getCSeq().getMethod().equals(Request.CANCEL)) || getOriginalRequest().getMethod().equals(messageToTest.getCSeq().getMethod())) && topViaHeader.equals(getOriginalRequest().getViaHeaders().getFirst())) {
transactionMatches = true;
}
}
}
}
return transactionMatches;
}
use of gov.nist.javax.sip.header.ViaList in project jain-sip.ha by RestComm.
the class SimpleB2BUAHandler method createRequest.
@SuppressWarnings("unchecked")
private Request createRequest(Request origRequest, int peerPort) throws SipException {
final SIPRequest request = (SIPRequest) origRequest.clone();
try {
long l = new AtomicLong().incrementAndGet();
request.getFromHeader().setTag(Long.toString(l));
} catch (ParseException e1) {
throw new SipException("failed to set local tag", e1);
}
final String transport = request.getTopmostViaHeader().getTransport();
final ListeningPointImpl listeningPointImpl = (ListeningPointImpl) sipProvider.getListeningPoint(transport);
final ViaList viaList = new ViaList();
viaList.add((Via) listeningPointImpl.createViaHeader());
request.setVia(viaList);
try {
request.setHeader(headerFactory.createMaxForwardsHeader(70));
} catch (InvalidArgumentException e) {
throw new SipException("Failed to create max forwards header", e);
}
request.setHeader((Header) sipProvider.getNewCallId());
// set contact if the original response had it
if (origRequest.getHeader(ContactHeader.NAME) != null) {
request.setHeader(listeningPointImpl.createContactHeader());
}
/*
* Route header fields of the upstream request MAY be copied in the
* downstream request, except the topmost Route header if it is under
* the responsibility of the B2BUA. Additional Route header fields MAY
* also be added to the downstream request.
*/
if (getOutgoingDialog() == null || getOutgoingDialog().getState() == null) {
// first request, no route available
final RouteList routeList = request.getRouteHeaders();
if (routeList != null) {
final RouteHeader topRoute = routeList.get(0);
final URI topRouteURI = topRoute.getAddress().getURI();
if (topRouteURI.isSipURI()) {
final SipURI topRouteSipURI = (SipURI) topRouteURI;
if (topRouteSipURI.getHost().equals(listeningPointImpl.getIPAddress()) && topRouteSipURI.getPort() == listeningPointImpl.getPort()) {
if (routeList.size() > 1) {
routeList.remove(0);
} else {
request.removeHeader(RouteHeader.NAME);
}
}
}
}
} else {
// replace route in orig request with the one in dialog
request.removeHeader(RouteHeader.NAME);
final RouteList routeList = new RouteList();
for (Iterator<Route> it = getOutgoingDialog().getRouteSet(); it.hasNext(); ) {
Route route = it.next();
routeList.add(route);
}
if (!routeList.isEmpty()) {
request.addHeader(routeList);
}
}
/*
* Record-Route header fields of the upstream request are not copied in
* the new downstream request, as Record-Route is only meaningful for
* the upstream dialog.
*/
request.removeHeader(RecordRouteHeader.NAME);
((SipURI) request.getRequestURI()).setPort(peerPort);
return request;
}
use of gov.nist.javax.sip.header.ViaList in project XobotOS by xamarin.
the class SIPTransaction method doesCancelMatchTransaction.
/**
* A method that can be used to test if an incoming request belongs to this
* transction. This does not take the transaction state into account when
* doing the check otherwise it is identical to isMessagePartOfTransaction.
* This is useful for checking if a CANCEL belongs to this transaction.
*
* @param requestToTest
* is the request to test.
* @return true if the the request belongs to the transaction.
*
*/
public boolean doesCancelMatchTransaction(SIPRequest requestToTest) {
// List of Via headers in the message to test
ViaList viaHeaders;
// Topmost Via header in the list
Via topViaHeader;
// Branch code in the topmost Via header
String messageBranch;
// Flags whether the select message is part of this transaction
boolean transactionMatches;
transactionMatches = false;
if (this.getOriginalRequest() == null || this.getOriginalRequest().getMethod().equals(Request.CANCEL))
return false;
// Get the topmost Via header and its branch parameter
viaHeaders = requestToTest.getViaHeaders();
if (viaHeaders != null) {
topViaHeader = (Via) viaHeaders.getFirst();
messageBranch = topViaHeader.getBranch();
if (messageBranch != null) {
// does not start with the magic cookie,
if (!messageBranch.toLowerCase().startsWith(SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE)) {
// Flags this as old
// (RFC2543-compatible) client
// version
messageBranch = null;
}
}
// If a new branch parameter exists,
if (messageBranch != null && this.getBranch() != null) {
// this message,
if (getBranch().equalsIgnoreCase(messageBranch) && topViaHeader.getSentBy().equals(((Via) getOriginalRequest().getViaHeaders().getFirst()).getSentBy())) {
transactionMatches = true;
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("returning true");
}
} else {
// headers are the same,
if (sipStack.isLoggingEnabled())
sipStack.getStackLogger().logDebug("testing against " + getOriginalRequest());
if (getOriginalRequest().getRequestURI().equals(requestToTest.getRequestURI()) && getOriginalRequest().getTo().equals(requestToTest.getTo()) && getOriginalRequest().getFrom().equals(requestToTest.getFrom()) && getOriginalRequest().getCallId().getCallId().equals(requestToTest.getCallId().getCallId()) && getOriginalRequest().getCSeq().getSeqNumber() == requestToTest.getCSeq().getSeqNumber() && topViaHeader.equals(getOriginalRequest().getViaHeaders().getFirst())) {
transactionMatches = true;
}
}
}
// set it to false
if (transactionMatches) {
this.setPassToListener();
}
return transactionMatches;
}
use of gov.nist.javax.sip.header.ViaList in project XobotOS by xamarin.
the class SIPClientTransaction method isMessagePartOfTransaction.
/**
* Deterines if the message is a part of this transaction.
*
* @param messageToTest Message to check if it is part of this transaction.
*
* @return true if the message is part of this transaction, false if not.
*/
public boolean isMessagePartOfTransaction(SIPMessage messageToTest) {
// List of Via headers in the message to test
ViaList viaHeaders = messageToTest.getViaHeaders();
// Flags whether the select message is part of this transaction
boolean transactionMatches;
String messageBranch = ((Via) viaHeaders.getFirst()).getBranch();
boolean rfc3261Compliant = getBranch() != null && messageBranch != null && getBranch().toLowerCase().startsWith(SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE) && messageBranch.toLowerCase().startsWith(SIPConstants.BRANCH_MAGIC_COOKIE_LOWER_CASE);
transactionMatches = false;
if (TransactionState.COMPLETED == this.getState()) {
if (rfc3261Compliant) {
transactionMatches = getBranch().equalsIgnoreCase(((Via) viaHeaders.getFirst()).getBranch()) && getMethod().equals(messageToTest.getCSeq().getMethod());
} else {
transactionMatches = getBranch().equals(messageToTest.getTransactionId());
}
} else if (!isTerminated()) {
if (rfc3261Compliant) {
if (viaHeaders != null) {
// same as this transaction and the method is the same,
if (getBranch().equalsIgnoreCase(((Via) viaHeaders.getFirst()).getBranch())) {
transactionMatches = getOriginalRequest().getCSeq().getMethod().equals(messageToTest.getCSeq().getMethod());
}
}
} else {
// not RFC 3261 compliant.
if (getBranch() != null) {
transactionMatches = getBranch().equalsIgnoreCase(messageToTest.getTransactionId());
} else {
transactionMatches = getOriginalRequest().getTransactionId().equalsIgnoreCase(messageToTest.getTransactionId());
}
}
}
return transactionMatches;
}
Aggregations