package org.jscsi.target.connection.stage.login; import java.io.IOException; import java.security.DigestException; import java.util.List; import java.util.Vector; import org.jscsi.exception.InternetSCSIException; import org.jscsi.parser.BasicHeaderSegment; import org.jscsi.parser.ProtocolDataUnit; import org.jscsi.parser.login.LoginStage; import org.jscsi.parser.login.LoginStatus; import org.jscsi.target.connection.Connection.TargetConnection; import org.jscsi.target.connection.phase.TargetLoginPhase; import org.jscsi.target.settings.SettingsException; import org.jscsi.target.settings.TextParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A {@link TargetLoginStage} sub-class representing Login Operational * (Parameter) Negotiation Stages. * * @author Andreas Ergenzinger */ public final class LoginOperationalParameterNegotiationStage extends TargetLoginStage { private static final Logger LOGGER = LoggerFactory .getLogger(LoginOperationalParameterNegotiationStage.class); /** * The constructor. * * @param targetLoginPhase * the login phase this stage is a part of. */ public LoginOperationalParameterNegotiationStage(TargetLoginPhase targetLoginPhase) { super(targetLoginPhase, LoginStage.LOGIN_OPERATIONAL_NEGOTIATION); } @Override public void execute(ProtocolDataUnit pdu) throws IOException, InterruptedException, InternetSCSIException, DigestException, IllegalArgumentException, SettingsException { LOGGER.debug("Entering LOPN Stage"); BasicHeaderSegment bhs = pdu.getBasicHeaderSegment(); initiatorTaskTag = bhs.getInitiatorTaskTag(); String keyValuePairProposal = receivePduSequence(pdu); // negotiate parameters, leave if unsuccessful final List<String> requestKeyValuePairs = TextParameter.tokenizeKeyValuePairs(keyValuePairProposal); final List<String> responseKeyValuePairs = new Vector<String>(); if (!negotiator.negotiate(session, stageNumber, (TargetConnection) connection, ((TargetLoginPhase)targetPhase).getFirstPduAndSetToFalse(), requestKeyValuePairs, responseKeyValuePairs)) { // negotiation failure, no exception sendRejectPdu(LoginStatus.INITIATOR_ERROR); // nextStageNumber = null;//no change return; } // print request and response key value pairs if debugging if (LOGGER.isDebugEnabled()) { final StringBuilder sb = new StringBuilder(); sb.append("request: "); for (String s : requestKeyValuePairs) { sb.append("\n "); sb.append(s); } sb.append("\nresponse: "); for (String s : responseKeyValuePairs) { sb.append("\n "); sb.append(s); } LOGGER.debug(sb.toString()); } // make sure that initiator wants to proceed to FFP, leave if it does // not if (requestedNextStageNumber != LoginStage.FULL_FEATURE_PHASE) { sendRejectPdu(LoginStatus.INITIATOR_ERROR); throw new InternetSCSIException(); } // concatenate key-value pairs to null char-separated string final String keyValuePairReply = TextParameter.concatenateKeyValuePairs(responseKeyValuePairs); // send reply, finish negotiation, and return successfully sendPduSequence(keyValuePairReply, LoginStage.FULL_FEATURE_PHASE); negotiator.finishNegotiation(true); nextStageNumber = LoginStage.FULL_FEATURE_PHASE; } }