/// <param name="targetName">Set to null for discovery session</param> public bool Login(string targetName) { if (!m_isConnected) { throw new InvalidOperationException("iSCSI client is not connected"); } m_connection.Session = new ISCSISession(); m_connection.Session.ISID = ClientHelper.GetRandomISID(); m_connection.CID = m_connection.Session.GetNextCID(); // p.s. It's possible to perform a single stage login (stage 1 to stage 3, tested against Microsoft iSCSI Target v3.1) LoginRequestPDU request = ClientHelper.GetFirstStageLoginRequest(m_initiatorName, targetName, m_connection); SendPDU(request); LoginResponsePDU response = WaitForPDU(request.InitiatorTaskTag) as LoginResponsePDU; if (response != null && response.Status == LoginResponseStatusName.Success) { m_connection.Session.TSIH = response.TSIH; // Status numbering starts with the Login response to the first Login request of the connection m_connection.StatusNumberingStarted = true; m_connection.ExpStatSN = response.StatSN + 1; request = ClientHelper.GetSecondStageLoginRequest(response, m_connection, targetName == null); SendPDU(request); response = WaitForPDU(request.InitiatorTaskTag) as LoginResponsePDU; if (response != null && response.Status == LoginResponseStatusName.Success) { KeyValuePairList <string, string> loginParameters = KeyValuePairUtils.GetKeyValuePairList(response.LoginParametersText); ClientHelper.UpdateOperationalParameters(loginParameters, m_connection); return(true); } } return(false); }
/// <summary> /// The transform test data values. /// </summary> /// <returns> /// The <see cref="OrderedDictionary"/>. /// </returns> private OrderedDictionary TransformTestDataValues() { //// Transformation Step //// - Results\TestDataValues.transformed.txt(ready to load using KeyValuePairUtils) //// -values evaluated //// - Constants applied(Results\Constants.transformed.txt) ////- Simple functions called var resolvedTestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseTempFilePath("TestDataValues.resolved.txt", false); var resolvedDict = KeyValuePairUtils.ReadKeyValuePairsFromFile(resolvedTestDataValuesFilePath); var transformedDict = new OrderedDictionary(); // TODO: Is this the kind of transformation we require see above foreach (var key in resolvedDict.Keys) { var value = (string)resolvedDict[key]; var evaluatedValue = StringTransformationUtils.Evaluate(value); transformedDict.Add(key, evaluatedValue); } var transformedTestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseResultsFilePath("TestDataValues.transformed.txt", false); KeyValuePairUtils.SaveKeyValuePairsToFile( transformedTestDataValuesFilePath, transformedDict, "Transformed Test Data Values"); return(transformedDict); }
/*static public void PostTweet(string message, RestCallback callback) * { * var credentials = new OAuthCredentials * { * Type = OAuthType.ProtectedResource, * SignatureMethod = OAuthSignatureMethod.HmacSha1, * ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader, * ConsumerKey = AppObject.GameInfo.TwitterConsumerKey, * ConsumerSecret = AppObject.GameInfo.TwitterConsumerSecret, * Token = TwitterClient.AccessToken, * TokenSecret = TwitterClient.AccessTokenSecret, * Version = "1.0" * }; * * var restClient = new RestClient * { * Authority = "https://api.twitter.com", * HasElevatedPermissions = true * }; * * var restRequest = new RestRequest * { * Credentials = credentials, * Path = "/1.1/statuses/update.json", * Method = WebMethod.Post * }; * * restRequest.AddParameter("status", message); * restClient.BeginRequest(restRequest, callback); * } * */ /*static private void PostTweetRequestCallback(RestRequest request, RestResponse response, object obj) * { * Deployment.Current.Dispatcher.BeginInvoke(() => * { * if (response.StatusCode == HttpStatusCode.OK) * { * MessageBox.Show("TWEET_POSTED_SUCCESSFULLY"); * } * else if (response.StatusCode == HttpStatusCode.Forbidden) * { * MessageBox.Show("TWEET_POST_ERR_UPDATE_LIMIT"); * } * else * { * MessageBox.Show("WEET_POST_ERR_FAILED"); * } * * }); * //var requestTokenQuery = OAuthUtil.GetRequestTokenQuery(); * //requestTokenQuery.RequestAsync(AppSettings.RequestTokenUri, null); * //requestTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(requestTokenQuery_QueryResponse); * } * */ static public void Logout() { KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyAcessToken, string.Empty); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyAcessTokenSecret, string.Empty); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyUserName, string.Empty); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyUserID, string.Empty); }
private LoginResponsePDU GetLoginResponsePDU(LoginRequestPDU request, ConnectionParameters connection) { // RFC 3720: The numbering fields (StatSN, ExpCmdSN, MaxCmdSN) are only valid if status-Class is 0. // RFC 3720: Command numbering starts with the first login request on the first connection of a session if (request.Continue) { connection.AddTextToSequence(request.InitiatorTaskTag, request.LoginParametersText); return(GetPartialLoginResponsePDU(request, connection)); } else { string text = connection.AddTextToSequence(request.InitiatorTaskTag, request.LoginParametersText); connection.RemoveTextSequence(request.InitiatorTaskTag); KeyValuePairList <string, string> loginParameters = KeyValuePairUtils.GetKeyValuePairList(text); if (connection.Session == null) { LoginResponseStatusName status = SetUpSession(request, loginParameters, connection); if (status != LoginResponseStatusName.Success) { LoginResponsePDU response = GetLoginResponseTemplate(request); response.Transit = request.Transit; response.Status = status; return(response); } } return(GetFinalLoginResponsePDU(request, loginParameters, connection)); } }
public List <string> ListTargets() { if (!m_isConnected) { throw new InvalidOperationException("iSCSI client is not connected"); } TextRequestPDU request = ClientHelper.GetSendTargetsRequest(m_session, m_connection); SendPDU(request); TextResponsePDU response = WaitForPDU(request.InitiatorTaskTag) as TextResponsePDU; if (response != null && response.Final) { KeyValuePairList <string, string> entries = KeyValuePairUtils.GetKeyValuePairList(response.Text); List <string> result = new List <string>(); foreach (KeyValuePair <string, string> entry in entries) { if (entry.Key == "TargetName") { result.Add(entry.Value); } } return(result); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="TestCaseDirectoryDataUtils"/> class. /// </summary> /// <param name="testCaseId"> /// The test case id. /// </param> /// <param name="testCaseDirectoryRoot"> /// The test case directory root. /// </param> public TestCaseDirectoryDataUtils(int testCaseId, string testCaseDirectoryRoot) { TestCaseDirectoryRoot = testCaseDirectoryRoot; TestCaseId = testCaseId; TestCaseFileAndFolderUtils = new TestCaseFileAndFolderUtils(TestCaseId, TestCaseDirectoryRoot); TestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseRootFilePath("TestDataValues.txt"); ConstantsFilePath = TestCaseFileAndFolderUtils.GetTestCaseRootFilePath("Constants.txt"); KeyValuePairUtils = new KeyValuePairUtils(); StringTransformationUtils = new StringTransformationUtils(); Init(); }
/// <summary> /// Initializes a new instance of the <see cref="TestCaseDirectoryDataUtils"/> class. /// </summary> /// <param name="testCaseFileAndFolderUtils"> /// The test Case File And Folder Utils. /// </param> /// <param name="stringTransformationUtils"> /// The string Transformation Utils. /// </param> public TestCaseDirectoryDataUtils(TestCaseFileAndFolderUtils testCaseFileAndFolderUtils, IStringTransformationUtils stringTransformationUtils) { TestCaseDirectoryRoot = testCaseFileAndFolderUtils.TestCaseDirectory; TestCaseId = testCaseFileAndFolderUtils.TestCaseId; TestCaseFileAndFolderUtils = testCaseFileAndFolderUtils; TestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseRootFilePath("TestDataValues.txt"); ConstantsFilePath = TestCaseFileAndFolderUtils.GetTestCaseRootFilePath("Constants.txt"); KeyValuePairUtils = new KeyValuePairUtils(); StringTransformationUtils = stringTransformationUtils; StringTransformationUtils.RegisterAllStuFunctionsForType(this); Init(); }
void _browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) { try { String uri = e.Uri.ToString(); if (uri.StartsWith("https://www.facebook.com/connect/login_success.html") || uri.StartsWith("http://www.facebook.com/connect/login_success.html") || uri.StartsWith("https://m.facebook.com/connect/login_success.html") || uri.StartsWith("http://m.facebook.com/connect/login_success.html") || uri.StartsWith("https://www.facebook.com/v2.0/connect/login_success.html") || uri.StartsWith("http://www.facebook.com/v2.0/connect/login_success.html") || uri.StartsWith("https://m.facebook.com/v2.0/connect/login_success.html") || uri.StartsWith("http://m.facebook.com/v2.0/connect/login_success.html") || uri.StartsWith("https://www.facebook.com/v1.0/connect/login_success.html") || uri.StartsWith("http://www.facebook.com/v1.0/connect/login_success.html") || uri.StartsWith("https://m.facebook.com/v1.0/connect/login_success.html") || uri.StartsWith("http://m.facebook.com/v1.0/connect/login_success.html") || uri.StartsWith(_app_info.RedirectLink)) { if (uri.EndsWith("#_=_")) { uri = uri.Substring(0, uri.Length - 4); } String queryString = e.Uri.Query.ToString(); try { IEnumerable <KeyValuePair <string, string> > pairs = UriToolKits.ParseQueryString(queryString); string code = KeyValuePairUtils.GetValue(pairs, "code"); string tokenurl = FacebookClient.Instance.getAccessTokenRequestUrl(_app_info, code); WebClient client = new WebClient(); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(AccessTokenDownloadCompleted); client.DownloadStringAsync(new Uri(tokenurl)); } catch (Exception ex) { fail(); } } else if (uri.StartsWith("https://m.facebook.com/dialog/oauth/write") || uri.StartsWith("http://m.facebook.com/dialog/oauth/write") || uri.StartsWith("https://m.facebook.com/v2.0/dialog/oauth/write") || uri.StartsWith("http://m.facebook.com/v2.0/dialog/oauth/write") || uri.StartsWith("https://m.facebook.com/v1.0/dialog/oauth/write") || uri.StartsWith("http://m.facebook.com/v1.0/dialog/oauth/write")) { string url = FacebookClient.Instance.getLoginUrl(_app_info); _browser.Source = new Uri(url); } } catch (Exception ex2) { fail(); Debug.WriteLine(ex2.Message); } }
public void TestSimpleTestDataManagement2() { var testCaseFileAndFolderUtils = new TestCaseFileAndFolderUtils(4002, @".\TestData\EndToEnd"); var testDataValuesFilePath = testCaseFileAndFolderUtils.GetTestCaseRootFilePath("TestDataValues.txt"); var keyValuePairUtils = new KeyValuePairUtils(); var testData = keyValuePairUtils.ReadKeyValuePairsFromFile(testDataValuesFilePath); foreach (var testDataKey in testData.Keys) { var value = testData[testDataKey]; StfLogger.LogInfo($"[{testDataKey}] has the value [{value}]"); } }
internal static TextResponsePDU GetTextResponsePDU(TextRequestPDU request, List <ISCSITarget> targets) { TextResponsePDU response = new TextResponsePDU(); response.Final = true; response.InitiatorTaskTag = request.InitiatorTaskTag; KeyValuePairList <string, string> entries = new KeyValuePairList <string, string>(); foreach (ISCSITarget target in targets) { entries.Add("TargetName", target.TargetName); } response.Text = KeyValuePairUtils.ToNullDelimitedString(entries); return(response); }
/// <summary> /// The get constants values. /// </summary> /// <returns> /// The <see cref="OrderedDictionary"/>. /// </returns> private OrderedDictionary GetConstantsValues() { ////(2) Evaluate Constants.txt //// - Temp\Constants.list.txt(all constant files compiled into one file) //// - include files resolved(marked for debug with comments) //// -Temp\Constants.resolved.txt //// - values overlayed //// - Results\Constants.transformed.txt(ready to load using KeyValuePairUtils) var retVal = KeyValuePairUtils.ReadKeyValuePairsFromFile(ConstantsFilePath); var resolvedConstantFilePath = TestCaseFileAndFolderUtils.GetTestCaseResultsFilePath("Constants.Resolved.txt", false); KeyValuePairUtils.SaveKeyValuePairsToFile(resolvedConstantFilePath, retVal, "Resolved Constants"); return(retVal); }
void ExchangeAccessTokenCompleted(object sender, UploadStringCompletedEventArgs e) { // Acquire access_token and expires timestamp IEnumerable <KeyValuePair <string, string> > pairs = UriToolKits.ParseQueryString(e.Result); string accessToken = KeyValuePairUtils.GetValue(pairs, "access_token"); if (accessToken != null && !accessToken.Equals("")) { MessageBox.Show("Access Token Exchange Failed"); return; } // Save access_token FacebookClient.Instance.AccessToken = accessToken; FacebookClient.Instance.PostMessageOnWall(txtStatus.Text, new UploadStringCompletedEventHandler(PostMessageOnWallCompleted)); }
////static public Transaction CurrentTransaction = null; static public bool isAlreadyLoggedIn() { AccessToken = KeyValuePairUtils.GetKeyValue <string>(KeyAcessToken); AccessTokenSecret = KeyValuePairUtils.GetKeyValue <string>(KeyAcessTokenSecret); UserScreenName = KeyValuePairUtils.GetKeyValue <string>(KeyUserName); UserID = KeyValuePairUtils.GetKeyValue <string>(KeyUserID); if (string.IsNullOrEmpty(AccessToken) || string.IsNullOrEmpty(AccessTokenSecret)) { return(false); } else { return(true); } }
private TextResponsePDU GetTextResponsePDU(TextRequestPDU request, ConnectionParameters connection) { TextResponsePDU response = new TextResponsePDU(); response.Final = request.Final; response.InitiatorTaskTag = request.InitiatorTaskTag; if (request.Continue) { connection.AddTextToSequence(request.InitiatorTaskTag, request.Text); } else { string text = connection.AddTextToSequence(request.InitiatorTaskTag, request.Text); connection.RemoveTextSequence(request.InitiatorTaskTag); KeyValuePairList <string, string> requestParameters = KeyValuePairUtils.GetKeyValuePairList(text); // text keys are case sensitive if (requestParameters.ContainsKey("SendTargets")) { KeyValuePairList <string, string> responseParameters = new KeyValuePairList <string, string>(); lock (m_targets.Lock) { foreach (ISCSITarget target in m_targets.GetList()) { responseParameters.Add("TargetName", target.TargetName); } } response.TextParameters = responseParameters; } else if (connection.Session.IsDiscovery || !IsVendorSpecificRequest(requestParameters)) { KeyValuePairList <string, string> responseParameters = new KeyValuePairList <string, string>(); foreach (KeyValuePair <string, string> entry in requestParameters) { responseParameters.Add(entry.Key, "Reject"); } response.TextParameters = responseParameters; } else { // RFC 3720: Vendor specific keys MUST ONLY be used in normal sessions // Vendor specific text request, let the target handle it: response.TextParameters = connection.Session.Target.GetTextResponse(requestParameters); } } return(response); }
/// <summary> /// The compile test data values. /// </summary> /// <returns> /// The <see cref="OrderedDictionary"/>. /// </returns> private OrderedDictionary CompileTestDataValues() { //// Compilation Step //// -Temp\TestDataValues.txt(all TestDataValue files compiled into one file) //// - include files resolved(marked for debug with comments) //// var originalDict = KeyValuePairUtils.ReadKeyValuePairsFromFile(TestDataValuesFilePath); // TODO: Do some compilation here as per comment above (gathering all TDV's together) var retVal = originalDict; var compiledTestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseTempFilePath("TestDataValues.compiled.txt", false); KeyValuePairUtils.SaveKeyValuePairsToFile(compiledTestDataValuesFilePath, retVal, "Compiled Test Data Values"); return(retVal); }
void _browser_Navigating(object sender, NavigatingEventArgs e) { if (e.Uri.ToString().StartsWith(AppSettings.CallbackUri)) { //MessageBox.Show("uri:" + e.Uri.ToString()); var AuthorizeResult = KeyValuePairUtils.GetQueryParameters(e.Uri.ToString()); try { var VerifyPin = AuthorizeResult["oauth_verifier"]; //MessageBox.Show(VerifyPin); if (AuthorizeResult != null && VerifyPin != null) { var AccessTokenQuery = OAuthUtil.GetAccessTokenQuery(TwitterClient.OAuthTokenKey, TwitterClient.TokenSecret, VerifyPin); AccessTokenQuery.QueryResponse += new EventHandler <WebQueryResponseEventArgs>(AccessTokenQuery_QueryResponse); AccessTokenQuery.RequestAsync(AppSettings.AccessTokenUri, null); } } catch (Exception ex) { } } }
void requestTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) { Deployment.Current.Dispatcher.BeginInvoke(() => { try { StreamReader reader = new StreamReader(e.Response); string strResponse = reader.ReadToEnd(); var parameters = KeyValuePairUtils.GetQueryParameters(strResponse); TwitterClient.OAuthTokenKey = parameters["oauth_token"]; TwitterClient.TokenSecret = parameters["oauth_token_secret"]; var authorizeUrl = AppSettings.AuthorizeUri + "?oauth_token=" + TwitterClient.OAuthTokenKey; Deployment.Current.Dispatcher.BeginInvoke(() => { _browser.Source = new Uri(authorizeUrl, UriKind.RelativeOrAbsolute); CurrentUrl = authorizeUrl; }); } catch (Exception ex) { fail(); } }); }
void AccessTokenDownloadCompleted(object sender, DownloadStringCompletedEventArgs e) { if (!e.Cancelled && e.Error == null) { try { string data = e.Result; data = "?" + data; IEnumerable <KeyValuePair <string, string> > pairs = UriToolKits.ParseQueryString(data); string accessToken = KeyValuePairUtils.GetValue(pairs, "access_token"); string expires = KeyValuePairUtils.GetValue(pairs, "expires"); success(accessToken, expires); } catch (Exception ex) { fail(); } } else { fail(); } }
void AccessTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e) { try { Deployment.Current.Dispatcher.BeginInvoke(() => { StreamReader reader = new StreamReader(e.Response); string strResponse = reader.ReadToEnd(); var parameters = KeyValuePairUtils.GetQueryParameters(strResponse); TwitterClient.AccessToken = parameters["oauth_token"]; TwitterClient.AccessTokenSecret = parameters["oauth_token_secret"]; TwitterClient.UserID = parameters["user_id"]; TwitterClient.UserScreenName = parameters["screen_name"]; KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyAcessToken, TwitterClient.AccessToken); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyAcessTokenSecret, TwitterClient.AccessTokenSecret); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyUserName, TwitterClient.UserScreenName); KeyValuePairUtils.SetKeyValue <string>(TwitterClient.KeyUserID, TwitterClient.UserID); success(parameters["oauth_token"], parameters["oauth_token_secret"]); }); } catch (Exception ex) { fail(); } }
/// <summary> /// The helper read key value pairs from file. /// </summary> /// <param name="testStep"> /// The test step. /// </param> /// <param name="inputFilename"> /// The input filename. /// </param> /// <param name="assignmentOperator"> /// The assignment operator. /// </param> /// <param name="commentIndicator"> /// The comment indicator. /// </param> /// <param name="keyNameIgnoreCase"> /// The key name ignore case. /// </param> private void HelperReadKeyValuePairsFromFile(string testStep, string inputFilename, string assignmentOperator = "=", string commentIndicator = "//", bool keyNameIgnoreCase = true) { StfLogger.LogHeader(testStep); var absolutePathInput = stfTestUtils.GetTestCaseRootFilePath(inputFilename); var absolutePathExpected = stfTestUtils.GetTestCaseRootFilePath($@"Expected\{inputFilename}"); var tempInputPath = stfTestUtils.GetTestCaseTempFilePath(inputFilename, false); var tempActualPath = stfTestUtils.GetTestCaseTempFilePath($@"{inputFilename}-Actual.txt", false); var tempExpectedPath = stfTestUtils.GetTestCaseTempFilePath($@"{inputFilename}-Expected.txt", false); var fileUtils = stfTestUtils.FileUtils; fileUtils.CopyFile(absolutePathInput, tempInputPath); fileUtils.CopyFile(absolutePathExpected, tempExpectedPath); // generate Actual var keyNameValueUtils = new KeyValuePairUtils(assignmentOperator, commentIndicator, keyNameIgnoreCase); var keyValuePairs = keyNameValueUtils.ReadKeyValuePairsFromFile(tempInputPath); keyNameValueUtils.SaveKeyValuePairsToFile(tempActualPath, keyValuePairs); StfAssert.FilesDoNotDiffer(testStep, tempExpectedPath, tempActualPath); }
/// <summary> /// The resolve test data values. /// </summary> /// <returns> /// The <see cref="OrderedDictionary"/>. /// </returns> private OrderedDictionary ResolveTestDataValues() { //// Resolution Step //// -Temp\TestDataValues.resolved.txt //// - values overlayed //// var compiledTestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseTempFilePath("TestDataValues.compiled.txt", false); var compiledDict = KeyValuePairUtils.ReadKeyValuePairsFromFile(compiledTestDataValuesFilePath); // TODO: Do some resolving and overlaying as per comment above on Resolving step var retVal = compiledDict; var resolvedTestDataValuesFilePath = TestCaseFileAndFolderUtils.GetTestCaseTempFilePath("TestDataValues.resolved.txt", false); KeyValuePairUtils.SaveKeyValuePairsToFile( resolvedTestDataValuesFilePath, retVal, "Resolved Test Data Values"); return(retVal); }
public void ProcessPDU(ISCSIPDU pdu, StateObject state) { Socket clientSocket = state.ClientSocket; uint?cmdSN = PDUHelper.GetCmdSN(pdu); Log(LogLevel.Debug, "[{0}][ProcessPDU] Received PDU from initiator, Operation: {1}, Size: {2}, CmdSN: {3}", state.ConnectionIdentifier, (ISCSIOpCodeName)pdu.OpCode, pdu.Length, cmdSN); // RFC 3720: On any connection, the iSCSI initiator MUST send the commands in increasing order of CmdSN, // except for commands that are retransmitted due to digest error recovery and connection recovery. if (cmdSN.HasValue) { if (state.SessionParameters.CommandNumberingStarted) { if (cmdSN != state.SessionParameters.ExpCmdSN) { Log(LogLevel.Warning, "[{0}][ProcessPDU] CmdSN outside of expected range", state.ConnectionIdentifier); // We ignore this PDU return; } } else { state.SessionParameters.ExpCmdSN = cmdSN.Value; state.SessionParameters.CommandNumberingStarted = true; } if (pdu is LogoutRequestPDU || pdu is TextRequestPDU || pdu is SCSICommandPDU || pdu is RejectPDU) { if (!pdu.ImmediateDelivery) { state.SessionParameters.ExpCmdSN++; } } } if (pdu is LoginRequestPDU) { LoginRequestPDU request = (LoginRequestPDU)pdu; Log(LogLevel.Information, "[{0}][ReceiveCallback] Login Request, current stage: {1}, next stage: {2}, parameters: {3}", state.ConnectionIdentifier, request.CurrentStage, request.NextStage, KeyValuePairUtils.ToString(request.LoginParameters)); if (request.TSIH != 0) { // RFC 3720: A Login Request with a non-zero TSIH and a CID equal to that of an existing // connection implies a logout of the connection followed by a Login lock (m_activeConnectionsLock) { int existingConnectionIndex = GetStateObjectIndex(m_activeConnections, request.ISID, request.TSIH, request.CID); if (existingConnectionIndex >= 0) { // Perform implicit logout Log(LogLevel.Information, "[{0}][ProcessPDU] Initiating implicit logout", state.ConnectionIdentifier); SocketUtils.ReleaseSocket(m_activeConnections[existingConnectionIndex].ClientSocket); if (m_activeConnections[existingConnectionIndex].Target != null) { lock (m_activeConnections[existingConnectionIndex].Target.IOLock) { // Wait for pending I/O to complete. } } m_activeConnections.RemoveAt(existingConnectionIndex); Log(LogLevel.Information, "[{0}][ProcessPDU] Implicit logout completed", state.ConnectionIdentifier); } } } LoginResponsePDU response = ServerResponseHelper.GetLoginResponsePDU(request, m_targets, state.SessionParameters, state.ConnectionParameters, ref state.Target, GetNextTSIH); if (state.SessionParameters.IsFullFeaturePhase) { state.SessionParameters.ISID = request.ISID; state.ConnectionParameters.CID = request.CID; lock (m_activeConnectionsLock) { m_activeConnections.Add(state); } } Log(LogLevel.Information, "[{0}][ReceiveCallback] Login Response parameters: {1}", state.ConnectionIdentifier, KeyValuePairUtils.ToString(response.LoginParameters)); TrySendPDU(state, response); } else if (!state.SessionParameters.IsFullFeaturePhase) { // Before the Full Feature Phase is established, only Login Request and Login Response PDUs are allowed. Log(LogLevel.Warning, "[{0}][ProcessPDU] Improper command during login phase, OpCode: 0x{1}", state.ConnectionIdentifier, pdu.OpCode.ToString("x")); // A target receiving any PDU except a Login request before the Login phase is started MUST // immediately terminate the connection on which the PDU was received. // Once the Login phase has started, if the target receives any PDU except a Login request, // it MUST send a Login reject (with Status "invalid during login") and then disconnect. clientSocket.Dispose(); } else // Logged in { if (pdu is TextRequestPDU) { TextRequestPDU request = (TextRequestPDU)pdu; TextResponsePDU response = ServerResponseHelper.GetTextResponsePDU(request, m_targets); TrySendPDU(state, response); } else if (pdu is LogoutRequestPDU) { lock (m_activeConnectionsLock) { int connectionIndex = GetStateObjectIndex(m_activeConnections, state.SessionParameters.ISID, state.SessionParameters.TSIH, state.ConnectionParameters.CID); if (connectionIndex >= 0) { if (m_activeConnections[connectionIndex].Target != null) { lock (m_activeConnections[connectionIndex].Target.IOLock) { // Wait for pending I/O to complete. } } m_activeConnections.RemoveAt(connectionIndex); } } LogoutRequestPDU request = (LogoutRequestPDU)pdu; LogoutResponsePDU response = ServerResponseHelper.GetLogoutResponsePDU(request); TrySendPDU(state, response); clientSocket.Dispose(); // We can close the connection now } else if (state.SessionParameters.IsDiscovery) { // The target MUST ONLY accept text requests with the SendTargets key and a logout // request with the reason "close the session". All other requests MUST be rejected. Log(LogLevel.Warning, "[{0}][ProcessPDU] Improper command during discovery session, OpCode: 0x{1}", state.ConnectionIdentifier, pdu.OpCode.ToString("x")); RejectPDU reject = new RejectPDU(); reject.Reason = RejectReason.ProtocolError; reject.Data = ByteReader.ReadBytes(pdu.GetBytes(), 0, 48); TrySendPDU(state, reject); } else if (pdu is NOPOutPDU) { NOPOutPDU request = (NOPOutPDU)pdu; if (request.InitiatorTaskTag != 0xFFFFFFFF) { NOPInPDU response = ServerResponseHelper.GetNOPResponsePDU(request); TrySendPDU(state, response); } } else if (pdu is SCSIDataOutPDU) { // FIXME: the iSCSI target layer MUST deliver the commands for execution (to the SCSI execution engin) in the order specified by CmdSN // e.g. read requests should not be executed while previous write request data is being received (via R2T) SCSIDataOutPDU request = (SCSIDataOutPDU)pdu; Log(LogLevel.Debug, "[{0}][ProcessPDU] SCSIDataOutPDU: Target transfer tag: {1}, LUN: {2}, Buffer offset: {3}, Data segment length: {4}, DataSN: {5}, Final: {6}", state.ConnectionIdentifier, request.TargetTransferTag, (ushort)request.LUN, request.BufferOffset, request.DataSegmentLength, request.DataSN, request.Final); ISCSIPDU response = TargetResponseHelper.GetSCSIDataOutResponsePDU(request, state.Target, state.SessionParameters, state.ConnectionParameters); TrySendPDU(state, response); } else if (pdu is SCSICommandPDU) { SCSICommandPDU command = (SCSICommandPDU)pdu; Log(LogLevel.Debug, "[{0}][ProcessPDU] SCSICommandPDU: CmdSN: {1}, LUN: {2}, Data segment length: {3}, Expected Data Transfer Length: {4}, Final: {5}", state.ConnectionIdentifier, command.CmdSN, (ushort)command.LUN, command.DataSegmentLength, command.ExpectedDataTransferLength, command.Final); List <ISCSIPDU> scsiResponseList = TargetResponseHelper.GetSCSIResponsePDU(command, state.Target, state.SessionParameters, state.ConnectionParameters); foreach (ISCSIPDU response in scsiResponseList) { TrySendPDU(state, response); if (!clientSocket.Connected) { return; } } } else { Log(LogLevel.Warning, "[{0}][ProcessPDU] Unsupported command, OpCode: 0x{1}", state.ConnectionIdentifier, pdu.OpCode.ToString("x")); } } }