/** * Notifies this <tt>StunCandidateHarvest</tt> that a specific STUN <tt>Response</tt> has been * received and it challenges a specific STUN <tt>Request</tt> for a long-term credential (as the * short-term credential mechanism does not utilize challenging). * * @param response the STUN <tt>Response</tt> which has been received * @param request the STUN <tt>Request</tt> to which <tt>response</tt> responds and which it * challenges for a long-term credential * @return <tt>true</tt> if the challenge has been processed and this * <tt>StunCandidateHarvest</tt> is to continue processing STUN <tt>Response</tt>s; otherwise, * <tt>false</tt> * @param transactionID the <tt>TransactionID</tt> of <tt>response</tt> and <tt>request</tt> * because <tt>response</tt> and <tt>request</tt> only have it as a <tt>byte</tt> array and * <tt>TransactionID</tt> is required for the <tt>applicationData</tt> property value * @throws StunException if anything goes wrong while processing the challenge */ private boolean processChallenge(Response response, Request request, TransactionID transactionID) throws StunException { boolean retried = false; if (response.getAttributeCount() > 0) { /* * The response SHOULD NOT contain a USERNAME or * MESSAGE-INTEGRITY attribute. */ char[] excludedResponseAttributeTypes = new char[] {Attribute.USERNAME, Attribute.MESSAGE_INTEGRITY}; boolean challenge = true; for (char excludedResponseAttributeType : excludedResponseAttributeTypes) { if (response.containsAttribute(excludedResponseAttributeType)) { challenge = false; break; } } if (challenge) { // This response MUST include a REALM value. RealmAttribute realmAttribute = (RealmAttribute) response.getAttribute(Attribute.REALM); if (realmAttribute == null) challenge = false; else { // The response MUST include a NONCE. NonceAttribute nonceAttribute = (NonceAttribute) response.getAttribute(Attribute.NONCE); if (nonceAttribute == null) challenge = false; else { retried = processChallenge( realmAttribute.getRealm(), nonceAttribute.getNonce(), request, transactionID); } } } } return retried; }