예제 #1
0
 /**
  * Add a new server transaction to the set of existing transactions. Add it to the top of the list
  * so an incoming ack has less work to do in order to find the transaction.
  *
  * @param serverTransaction -- server transaction to add to the set.
  */
 public void addTransaction(SIPServerTransaction serverTransaction) throws IOException {
   if (LogWriter.needsLogging) logWriter.logMessage("added transaction " + serverTransaction);
   synchronized (serverTransactions) {
     this.serverTransactions.add(0, serverTransaction);
     serverTransaction.map();
   }
   addTransactionHash(serverTransaction);
   serverTransaction.startTransactionTimer();
 }
예제 #2
0
  /**
   * Find the transaction corresponding to a given request.
   *
   * @param sipMessage request for which to retrieve the transaction.
   * @param isServer search the server transaction table if true.
   * @return the transaction object corresponding to the request or null if no such mapping exists.
   */
  public SIPTransaction findTransaction(SIPMessage sipMessage, boolean isServer) {
    SIPTransaction retval = null;

    if (isServer) {
      Via via = sipMessage.getTopmostVia();
      if (via.getBranch() != null) {
        String key = sipMessage.getTransactionId();

        synchronized (this.serverTransactionTable) {
          retval = (SIPTransaction) serverTransactionTable.get(key);
          if (LogWriter.needsLogging) logMessage("looking for key " + key);
          if (retval != null && retval.isMessagePartOfTransaction(sipMessage)) return retval;
        }
      }
      // Need to scan the table for old style transactions (RFC 2543
      // style)
      synchronized (this.serverTransactions) {
        Iterator<SIPServerTransaction> it = serverTransactions.iterator();
        while (it.hasNext()) {
          SIPServerTransaction sipServerTransaction = (SIPServerTransaction) it.next();
          if (sipServerTransaction.isMessagePartOfTransaction(sipMessage))
            return sipServerTransaction;
        }
      }
    } else {
      Via via = sipMessage.getTopmostVia();
      if (via.getBranch() != null) {
        String key = sipMessage.getTransactionId();
        synchronized (this.clientTransactionTable) {
          retval = (SIPTransaction) clientTransactionTable.get(key);
          if (retval != null && retval.isMessagePartOfTransaction(sipMessage)) return retval;
        }
      }
      // Need to scan the table for old style transactions (RFC 2543
      // style)
      synchronized (this.clientTransactions) {
        Iterator<SIPClientTransaction> it = clientTransactions.iterator();
        while (it.hasNext()) {
          SIPClientTransaction clientTransaction = (SIPClientTransaction) it.next();
          if (clientTransaction.isMessagePartOfTransaction(sipMessage)) return clientTransaction;
        }
      }
    }
    return null;
  }
예제 #3
0
  public SIPServerTransaction findPendingTransaction(SIPRequest requestReceived) {
    SIPServerTransaction currentTransaction;
    Iterator<SIPServerTransaction> transactionIterator;
    synchronized (pendingTransactions) {
      transactionIterator = pendingTransactions.iterator();
      currentTransaction = null;
      while (transactionIterator.hasNext() && currentTransaction == null) {

        SIPServerTransaction nextTransaction = (SIPServerTransaction) transactionIterator.next();

        // If this transaction should handle this request,
        if (nextTransaction.isMessagePartOfTransaction(requestReceived)) {
          // Mark this transaction as the one
          // to handle this message
          currentTransaction = nextTransaction;
        }
      }
    }
    return currentTransaction;
  }
예제 #4
0
  /**
   * Get the transaction to cancel. Search the server transaction table for a transaction that
   * matches the given transaction.
   */
  public SIPTransaction findCancelTransaction(SIPRequest cancelRequest, boolean isServer) {

    if (LogWriter.needsLogging) {
      logWriter.logMessage(
          "findCancelTransaction request= \n"
              + cancelRequest
              + "\nfindCancelRequest isServer="
              + isServer);
    }

    if (isServer) {
      synchronized (this.serverTransactions) {
        Iterator<SIPServerTransaction> li = this.serverTransactions.iterator();
        while (li.hasNext()) {
          SIPTransaction transaction = (SIPTransaction) li.next();
          // SIPRequest sipRequest = (SIPRequest) (transaction
          //		.getRequest());

          SIPServerTransaction sipServerTransaction = (SIPServerTransaction) transaction;
          if (sipServerTransaction.doesCancelMatchTransaction(cancelRequest))
            return sipServerTransaction;
        }
      }
    } else {
      synchronized (this.clientTransactions) {
        Iterator<SIPClientTransaction> li = this.clientTransactions.iterator();
        while (li.hasNext()) {
          SIPTransaction transaction = (SIPTransaction) li.next();
          //					SIPRequest sipRequest = (SIPRequest) (transaction
          //							.getRequest());

          SIPClientTransaction sipClientTransaction = (SIPClientTransaction) transaction;
          if (sipClientTransaction.doesCancelMatchTransaction(cancelRequest))
            return sipClientTransaction;
        }
      }
    }
    if (LogWriter.needsLogging)
      logWriter.logMessage("Could not find transaction for cancel request");
    return null;
  }
예제 #5
0
  /**
   * Handles a new SIP request. It finds a server transaction to handle this message. If none
   * exists, it creates a new transaction.
   *
   * @param requestReceived Request to handle.
   * @param requestMessageChannel Channel that received message.
   * @return A server transaction.
   */
  protected ServerRequestInterface newSIPServerRequest(
      SIPRequest requestReceived, MessageChannel requestMessageChannel) {

    // Iterator through all server transactions
    Iterator<SIPServerTransaction> transactionIterator;
    // Next transaction in the set
    SIPServerTransaction nextTransaction;
    // Transaction to handle this request
    SIPServerTransaction currentTransaction;

    String key = requestReceived.getTransactionId();

    currentTransaction = (SIPServerTransaction) serverTransactionTable.get(key);
    if (currentTransaction == null
        || !currentTransaction.isMessagePartOfTransaction(requestReceived)) {

      // Loop through all server transactions
      synchronized (serverTransactions) {
        transactionIterator = serverTransactions.iterator();
        currentTransaction = null;
        while (transactionIterator.hasNext() && currentTransaction == null) {

          nextTransaction = (SIPServerTransaction) transactionIterator.next();

          // If this transaction should handle this request,
          if (nextTransaction.isMessagePartOfTransaction(requestReceived)) {
            // Mark this transaction as the one
            // to handle this message
            currentTransaction = nextTransaction;
          }
        }

        // If no transaction exists to handle this message
        if (currentTransaction == null) {
          currentTransaction = findPendingTransaction(requestReceived);
          if (currentTransaction != null) return currentTransaction;
          currentTransaction = createServerTransaction(requestMessageChannel);
          currentTransaction.setOriginalRequest(requestReceived);
          if (!isDialogCreated(requestReceived.getMethod())) {
            // Dialog is not created - can we find the state?
            // If so, then create a transaction and add it.
            String dialogId = requestReceived.getDialogId(true);
            SIPDialog dialog = getDialog(dialogId);
            // Sequence numbers are supposed to increment.
            // avoid processing old sequence numbers and
            // delivering the same request up to the
            // application if the request has already been seen.
            // Special handling applies to ACK processing.
            if (dialog != null
                && (requestReceived.getMethod().equals(Request.ACK)
                    || requestReceived.getCSeq().getSequenceNumber()
                        > dialog.getRemoteSequenceNumber())) {
              // Found a dialog.
              if (LogWriter.needsLogging)
                logWriter.logMessage("adding server transaction " + currentTransaction);
              serverTransactions.add(0, currentTransaction);
              addTransactionHash(currentTransaction);
              currentTransaction.startTransactionTimer();
              currentTransaction.isMapped = true;
            }
          } else {
            // Create the transaction but dont map it.
            String dialogId = requestReceived.getDialogId(true);
            SIPDialog dialog = getDialog(dialogId);
            // This is a dialog creating request that is part of an
            // existing dialog (eg. re-Invite). Re-invites get a non
            // null server transaction Id (unlike the original
            // invite).
            if (dialog != null
                && requestReceived.getCSeq().getSequenceNumber()
                    > dialog.getRemoteSequenceNumber()) {
              currentTransaction.map();
              if (LogWriter.needsLogging)
                logWriter.logMessage("adding server transaction " + currentTransaction);
              serverTransactions.add(0, currentTransaction);
              addTransactionHash(currentTransaction);
              currentTransaction.startTransactionTimer();
              currentTransaction.toListener = true;
            }
          }
        }
      }
    }

    // Set ths transaction's encapsulated request
    // interface from the superclass
    currentTransaction.setRequestInterface(
        super.newSIPServerRequest(requestReceived, currentTransaction));
    return currentTransaction;
  }
예제 #6
0
  /**
   * Actually proces the parsed message.
   *
   * @param sipMessage
   */
  public void processMessage(SIPMessage sipMessage) {

    if (sipMessage instanceof SIPRequest) {
      SIPRequest sipRequest = (SIPRequest) sipMessage;

      // This is a request - process it.
      // So far so good -- we will commit this message if
      // all processing is OK.
      if (sipStack.logWriter.isLoggingEnabled(ServerLog.TRACE_MESSAGES)) {

        this.sipStack.serverLog.logMessage(
            sipMessage,
            this.getPeerHostPort().toString(),
            this.getHost() + ":" + this.myPort,
            false,
            receptionTime);
      }
      ServerRequestInterface sipServerRequest = sipStack.newSIPServerRequest(sipRequest, this);
      // Drop it if there is no request returned
      if (sipServerRequest == null) {
        if (sipStack.isLoggingEnabled()) {
          this.sipStack.logWriter.logWarning("Null request interface returned -- dropping request");
        }

        return;
      }
      if (sipStack.isLoggingEnabled())
        this.sipStack.logWriter.logDebug(
            "About to process " + sipRequest.getFirstLine() + "/" + sipServerRequest);
      try {
        sipServerRequest.processRequest(sipRequest, this);
      } finally {
        if (sipServerRequest instanceof SIPTransaction) {
          SIPServerTransaction sipServerTx = (SIPServerTransaction) sipServerRequest;
          if (!sipServerTx.passToListener()) {
            ((SIPTransaction) sipServerRequest).releaseSem();
          }
        }
      }
      if (sipStack.isLoggingEnabled())
        this.sipStack.logWriter.logDebug(
            "Done processing " + sipRequest.getFirstLine() + "/" + sipServerRequest);

      // So far so good -- we will commit this message if
      // all processing is OK.

    } else {
      // Handle a SIP Reply message.
      SIPResponse sipResponse = (SIPResponse) sipMessage;
      try {
        sipResponse.checkHeaders();
      } catch (ParseException ex) {
        if (sipStack.isLoggingEnabled())
          sipStack.logWriter.logError(
              "Dropping Badly formatted response message >>> " + sipResponse);
        return;
      }
      ServerResponseInterface sipServerResponse = sipStack.newSIPServerResponse(sipResponse, this);
      if (sipServerResponse != null) {
        try {
          if (sipServerResponse instanceof SIPClientTransaction
              && !((SIPClientTransaction) sipServerResponse).checkFromTag(sipResponse)) {
            if (sipStack.isLoggingEnabled())
              sipStack.logWriter.logError(
                  "Dropping response message with invalid tag >>> " + sipResponse);
            return;
          }

          sipServerResponse.processResponse(sipResponse, this);
        } finally {
          if (sipServerResponse instanceof SIPTransaction
              && !((SIPTransaction) sipServerResponse).passToListener())
            ((SIPTransaction) sipServerResponse).releaseSem();
        }

        // Normal processing of message.
      } else {
        if (sipStack.isLoggingEnabled()) {
          this.sipStack.logWriter.logDebug("null sipServerResponse!");
        }
      }
    }
  }