Package org.jscsi.target.connection.phase

Source Code of org.jscsi.target.connection.phase.TargetLoginPhase

package org.jscsi.target.connection.phase;


import java.io.IOException;
import java.security.DigestException;

import javax.naming.OperationNotSupportedException;

import org.jscsi.exception.InternetSCSIException;
import org.jscsi.parser.BasicHeaderSegment;
import org.jscsi.parser.ProtocolDataUnit;
import org.jscsi.parser.login.LoginRequestParser;
import org.jscsi.parser.login.LoginStage;
import org.jscsi.target.connection.Connection;
import org.jscsi.target.connection.stage.login.LoginOperationalParameterNegotiationStage;
import org.jscsi.target.connection.stage.login.SecurityNegotiationStage;
import org.jscsi.target.connection.stage.login.TargetLoginStage;
import org.jscsi.target.settings.ConnectionSettingsNegotiator;
import org.jscsi.target.settings.SettingsException;


/**
* Objects of this class represent the Target Login Phase of a connection.
*
* @see TargetPhase
* @author Andreas Ergenzinger
*/
public final class TargetLoginPhase extends TargetPhase {

    /**
     * The current stage of this phase
     */
    private TargetLoginStage stage;

    /**
     * This variable indicates if the initiator is to be considered as authenticated, i.e. if it has given sufficient
     * proof of its identity to proceed to the next (Target Full Feature) phase.
     * <p>
     * Currently the jSCSI Target does not support any authentication methods and this value is initialized to
     * <code>true</code> for all initiators.
     */
    private boolean authenticated = true;// TODO false if authentication
                                         // required

    /**
     * This variable will be <code>true</code> until the first call of {@link #getFirstPduAndSetToFalse()} has happened.
     * <p>
     * This value will be <code>true</code> if the currently processed PDU is the first PDU sent by the initiator over
     * this phase's connection. This means that it must contain all text parameters necessary for either starting a
     * discovery session or a normal session.
     */
    private boolean firstPdu = true;

    /**
     * The constructor.
     *
     * @param connection {@inheritDoc}
     */
    public TargetLoginPhase (Connection connection) {
        super(connection);
    }

    /**
     * Starts the login phase.
     *
     * @param pdu {@inheritDoc}
     * @return {@inheritDoc}
     * @throws OperationNotSupportedException {@inheritDoc}
     * @throws IOException {@inheritDoc}
     * @throws InterruptedException {@inheritDoc}
     * @throws InternetSCSIException {@inheritDoc}
     * @throws DigestException {@inheritDoc}
     * @throws SettingsException {@inheritDoc}
     */
    @Override
    public boolean execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {

        // begin login negotiation
        final ConnectionSettingsNegotiator negotiator = connection.getConnectionSettingsNegotiator();
        while (!negotiator.beginNegotiation()) {
            // do nothing, just wait for permission to begin, method is blocking
        }

        boolean loginSuccessful = true;// will determine if settings are
                                       // committed

        try {
            // if possible, enter LOPN Stage
            BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
            LoginRequestParser parser = (LoginRequestParser) bhs.getParser();

            LoginStage nextStageNumber;// will store return value from the last
                                       // login stage

            // Security Negotiation Stage (optional)
            if (parser.getCurrentStageNumber() == LoginStage.SECURITY_NEGOTIATION) {
                // complete SNS
                stage = new SecurityNegotiationStage(this);
                stage.execute(pdu);
                nextStageNumber = stage.getNextStageNumber();

                if (nextStageNumber != null)
                    authenticated = true;
                else {
                    loginSuccessful = false;
                    return false;
                }

                if (nextStageNumber == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) {
                    // receive first PDU from LOPNS
                    pdu = connection.receivePdu();
                    bhs = pdu.getBasicHeaderSegment();
                    parser = (LoginRequestParser) bhs.getParser();
                } else if (nextStageNumber == LoginStage.FULL_FEATURE_PHASE) {
                    // we are done here
                    return true;
                } else {
                    // should be unreachable, since SNS may not return NSG==SNS
                    loginSuccessful = false;
                    return false;
                }
            }

            // Login Operational Parameter Negotiation Stage (also optional, but
            // either SNS or LOPNS must be passed before proceeding to FFP)
            if (parser != null && authenticated && parser.getCurrentStageNumber() == LoginStage.LOGIN_OPERATIONAL_NEGOTIATION) {
                stage = new LoginOperationalParameterNegotiationStage(this);
                stage.execute(pdu);
                nextStageNumber = stage.getNextStageNumber();
                if (nextStageNumber == LoginStage.FULL_FEATURE_PHASE) return true;
            }
            // else
            loginSuccessful = false;
            return false;
        } catch (DigestException e) {
            loginSuccessful = false;
            throw e;
        } catch (IOException e) {
            loginSuccessful = false;
            throw e;
        } catch (InterruptedException e) {
            loginSuccessful = false;
            throw e;
        } catch (InternetSCSIException e) {
            loginSuccessful = false;
            throw e;
        } catch (SettingsException e) {
            loginSuccessful = false;
            throw e;
        } finally {
            // commit or roll back changes and release exclusive negotiator lock
            negotiator.finishNegotiation(loginSuccessful);
        }
    }

    /**
     * This method will return <code>true</code> if currently processed PDU is the first PDU sent by the initiator over
     * this phase's connection. Subsequent calls will always return <code>false</code>.
     *
     * @return <code>true</code> if and only if this method is called for the first time
     */
    public boolean getFirstPduAndSetToFalse () {
        if (!firstPdu) return false;
        firstPdu = false;
        return true;
    }

    public final boolean getAuthenticated () {
        return authenticated;
    }
}
TOP

Related Classes of org.jscsi.target.connection.phase.TargetLoginPhase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.