}
String handle = Association.FAILED_ASSOC_HANDLE;
// build a list of association types, with the preferred one at the end
LinkedHashMap requests = new LinkedHashMap();
if (discovered.isVersion2())
{
requests.put(AssociationSessionType.NO_ENCRYPTION_SHA1MAC, null);
requests.put(AssociationSessionType.NO_ENCRYPTION_SHA256MAC, null);
requests.put(AssociationSessionType.DH_SHA1, null);
requests.put(AssociationSessionType.DH_SHA256, null);
}
else
{
requests.put(AssociationSessionType.NO_ENCRYPTION_COMPAT_SHA1MAC, null);
requests.put(AssociationSessionType.DH_COMPAT_SHA1, null);
}
if (_prefAssocSessEnc.isVersion2() == discovered.isVersion2())
requests.put(_prefAssocSessEnc, null);
// build a stack of Association Request objects
// and keep only the allowed by the configured preferences
// the most-desirable entry is always at the top of the stack
Stack reqStack = new Stack();
Iterator iter = requests.keySet().iterator();
while(iter.hasNext())
{
AssociationSessionType type = (AssociationSessionType) iter.next();
// create the appropriate Association Request
AssociationRequest newReq = createAssociationRequest(type, opUrl);
if (newReq != null) reqStack.push(newReq);
}
// perform the association attempts
int attemptsLeft = maxAttempts;
LinkedHashMap alreadyTried = new LinkedHashMap();
while (attemptsLeft > 0 && ! reqStack.empty())
{
try
{
attemptsLeft--;
AssociationRequest assocReq =
(AssociationRequest) reqStack.pop();
if (DEBUG)
_log.debug("Trying association type: " + assocReq.getType());
// was this association / session type attempted already?
if (alreadyTried.keySet().contains(assocReq.getType()))
{
if (DEBUG) _log.debug("Already tried.");
continue;
}
// mark the current request type as already tried
alreadyTried.put(assocReq.getType(), null);
ParameterList respParams = new ParameterList();
int status = call(opEndpoint, assocReq, respParams);
// process the response
if (status == HttpStatus.SC_OK) // success response
{
AssociationResponse assocResp;
assocResp = AssociationResponse
.createAssociationResponse(respParams);
// valid association response
Association assoc =
assocResp.getAssociation(assocReq.getDHSess());
handle = assoc.getHandle();
AssociationSessionType respType = assocResp.getType();
if ( respType.equals(assocReq.getType()) ||
// v1 OPs may return a success no-encryption resp
( ! discovered.isVersion2() &&
respType.getHAlgorithm() == null &&
createAssociationRequest(respType,opUrl) != null))
{
// store the association and do no try alternatives
_associations.save(opEndpoint, assoc);
_log.info("Associated with " + discovered.getOPEndpoint()
+ " handle: " + assoc.getHandle());
break;
}
else
_log.info("Discarding association response, " +
"not matching consumer criteria");
}
else if (status == HttpStatus.SC_BAD_REQUEST) // error response
{
_log.info("Association attempt failed.");
// retrieve fallback sess/assoc/encryption params set by OP
// and queue a new attempt
AssociationError assocErr =
AssociationError.createAssociationError(respParams);
AssociationSessionType opType =
AssociationSessionType.create(
assocErr.getSessionType(),
assocErr.getAssocType());
if (alreadyTried.keySet().contains(opType))
continue;
// create the appropriate Association Request
AssociationRequest newReq =
createAssociationRequest(opType, opUrl);