View Javadoc

1   package org.jscsi.target.connection.stage.login;
2   
3   
4   import java.io.IOException;
5   import java.security.DigestException;
6   import java.util.List;
7   import java.util.Vector;
8   
9   import org.jscsi.exception.InternetSCSIException;
10  import org.jscsi.parser.BasicHeaderSegment;
11  import org.jscsi.parser.ProtocolDataUnit;
12  import org.jscsi.parser.login.LoginStage;
13  import org.jscsi.parser.login.LoginStatus;
14  import org.jscsi.target.connection.phase.TargetLoginPhase;
15  import org.jscsi.target.settings.SettingsException;
16  import org.jscsi.target.settings.TextParameter;
17  import org.slf4j.Logger;
18  import org.slf4j.LoggerFactory;
19  
20  
21  /**
22   * A {@link TargetLoginStage} sub-class representing Login Operational (Parameter) Negotiation Stages.
23   * 
24   * @author Andreas Ergenzinger
25   */
26  public final class LoginOperationalParameterNegotiationStage extends TargetLoginStage {
27  
28      private static final Logger LOGGER = LoggerFactory.getLogger(LoginOperationalParameterNegotiationStage.class);
29  
30      /**
31       * The constructor.
32       * 
33       * @param targetLoginPhase the login phase this stage is a part of.
34       */
35      public LoginOperationalParameterNegotiationStage (TargetLoginPhase targetLoginPhase) {
36          super(targetLoginPhase, LoginStage.LOGIN_OPERATIONAL_NEGOTIATION);
37      }
38  
39      @Override
40      public void execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , IllegalArgumentException , SettingsException {
41          LOGGER.debug("Entering LOPN Stage");
42  
43          BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
44          initiatorTaskTag = bhs.getInitiatorTaskTag();
45  
46          String keyValuePairProposal = receivePduSequence(pdu);
47  
48          // negotiate parameters, leave if unsuccessful
49          final List<String> requestKeyValuePairs = TextParameter.tokenizeKeyValuePairs(keyValuePairProposal);
50          final List<String> responseKeyValuePairs = new Vector<String>();
51          if (!negotiator.negotiate(session.getTargetServer(), stageNumber, connection.isLeadingConnection(), ((TargetLoginPhase) targetPhase).getFirstPduAndSetToFalse(), requestKeyValuePairs, responseKeyValuePairs)) {
52              // negotiation failure, no exception
53              sendRejectPdu(LoginStatus.INITIATOR_ERROR);
54              // nextStageNumber = null;//no change
55              return;
56          }
57  
58          // print request and response key value pairs if debugging
59          if (LOGGER.isDebugEnabled()) {
60              final StringBuilder sb = new StringBuilder();
61              sb.append("request: ");
62              for (String s : requestKeyValuePairs) {
63                  sb.append("\n  ");
64                  sb.append(s);
65              }
66              sb.append("\nresponse: ");
67              for (String s : responseKeyValuePairs) {
68                  sb.append("\n  ");
69                  sb.append(s);
70              }
71              LOGGER.debug(sb.toString());
72          }
73  
74          // make sure that initiator wants to proceed to FFP, leave if it does
75          // not
76          if (requestedNextStageNumber != LoginStage.FULL_FEATURE_PHASE) {
77              sendRejectPdu(LoginStatus.INITIATOR_ERROR);
78              throw new InternetSCSIException();
79          }
80  
81          // concatenate key-value pairs to null char-separated string
82          final String keyValuePairReply = TextParameter.concatenateKeyValuePairs(responseKeyValuePairs);
83  
84          // send reply, finish negotiation, and return successfully
85          sendPduSequence(keyValuePairReply, LoginStage.FULL_FEATURE_PHASE);
86          negotiator.finishNegotiation(true);
87          nextStageNumber = LoginStage.FULL_FEATURE_PHASE;
88      }
89  }