Example #1
0
  /**
   * Notifies this <tt>ResponseCollector</tt> that a transaction described by the specified
   * <tt>BaseStunMessageEvent</tt> has failed. The possible reasons for the failure include
   * timeouts, unreachable destination, etc.
   *
   * @param event the <tt>BaseStunMessageEvent</tt> which describes the failed transaction and the
   *     runtime type of which specifies the failure reason
   * @see AbstractResponseCollector#processFailure(BaseStunMessageEvent)
   */
  @Override
  protected void processFailure(BaseStunMessageEvent event) {
    TransactionID transactionID = event.getTransactionID();

    logger.finest("A transaction expired: tranid=" + transactionID);
    logger.finest("localAddr=" + hostCandidate);

    /*
     * Clean up for the purposes of the workaround which determines the STUN
     * Request to which a STUN Response responds.
     */
    Request request;

    synchronized (requests) {
      request = requests.remove(transactionID);
    }
    if (request == null) {
      Message message = event.getMessage();

      if (message instanceof Request) request = (Request) message;
    }

    boolean completedResolvingCandidate = true;
    try {
      if (processErrorOrFailure(null, request, transactionID)) completedResolvingCandidate = false;
    } finally {
      if (completedResolvingCandidate) completedResolvingCandidate(request, null);
    }
  }
Example #2
0
  /**
   * Notifies this <tt>ResponseCollector</tt> that a STUN response described by the specified
   * <tt>StunResponseEvent</tt> has been received.
   *
   * @param event the <tt>StunResponseEvent</tt> which describes the received STUN response
   * @see ResponseCollector#processResponse(StunResponseEvent)
   */
  @Override
  public void processResponse(StunResponseEvent event) {
    TransactionID transactionID = event.getTransactionID();

    logger.finest("Received a message: tranid= " + transactionID);
    logger.finest("localCand= " + hostCandidate);

    /*
     * Clean up for the purposes of the workaround which determines the STUN
     * Request to which a STUN Response responds.
     */
    synchronized (requests) {
      requests.remove(transactionID);
    }

    // At long last, do start handling the received STUN Response.
    Response response = event.getResponse();
    Request request = event.getRequest();
    boolean completedResolvingCandidate = true;

    try {
      if (response.isSuccessResponse()) {
        // Authentication and Message-Integrity Mechanisms
        if (request.containsAttribute(Attribute.MESSAGE_INTEGRITY)) {
          MessageIntegrityAttribute messageIntegrityAttribute =
              (MessageIntegrityAttribute) response.getAttribute(Attribute.MESSAGE_INTEGRITY);

          /*
           * RFC 5389: If MESSAGE-INTEGRITY was absent, the response
           * MUST be discarded, as if it was never received.
           */
          if (messageIntegrityAttribute == null) return;

          UsernameAttribute usernameAttribute =
              (UsernameAttribute) request.getAttribute(Attribute.USERNAME);

          /*
           * For a request or indication message, the agent MUST
           * include the USERNAME and MESSAGE-INTEGRITY attributes in
           * the message.
           */
          if (usernameAttribute == null) return;
          if (!harvester
              .getStunStack()
              .validateMessageIntegrity(
                  messageIntegrityAttribute,
                  LongTermCredential.toString(usernameAttribute.getUsername()),
                  !request.containsAttribute(Attribute.REALM)
                      && !request.containsAttribute(Attribute.NONCE),
                  event.getRawMessage())) return;
        }

        processSuccess(response, request, transactionID);
      } else {
        ErrorCodeAttribute errorCodeAttr =
            (ErrorCodeAttribute) response.getAttribute(Attribute.ERROR_CODE);

        if ((errorCodeAttr != null) && (errorCodeAttr.getErrorClass() == 4)) {
          try {
            switch (errorCodeAttr.getErrorNumber()) {
              case 1: // 401 Unauthorized
                if (processUnauthorized(response, request, transactionID))
                  completedResolvingCandidate = false;
                break;
              case 38: // 438 Stale Nonce
                if (processStaleNonce(response, request, transactionID))
                  completedResolvingCandidate = false;
                break;
            }
          } catch (StunException sex) {
            completedResolvingCandidate = true;
          }
        }
        if (completedResolvingCandidate && processErrorOrFailure(response, request, transactionID))
          completedResolvingCandidate = false;
      }
    } finally {
      if (completedResolvingCandidate) completedResolvingCandidate(request, response);
    }
  }