ISCSIServer.TextRequest.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* Copyright (C) 2012-2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace ISCSI.Server
  12. {
  13. public partial class ISCSIServer
  14. {
  15. private TextResponsePDU GetTextResponsePDU(TextRequestPDU request, ConnectionParameters connection)
  16. {
  17. TextResponsePDU response = new TextResponsePDU();
  18. response.Final = request.Final;
  19. response.InitiatorTaskTag = request.InitiatorTaskTag;
  20. if (request.Continue)
  21. {
  22. connection.AddTextToSequence(request.InitiatorTaskTag, request.Text);
  23. }
  24. else
  25. {
  26. string text = connection.AddTextToSequence(request.InitiatorTaskTag, request.Text);
  27. connection.RemoveTextSequence(request.InitiatorTaskTag);
  28. KeyValuePairList<string, string> requestParameters = KeyValuePairUtils.GetKeyValuePairList(text);
  29. // text keys are case sensitive
  30. if (requestParameters.ContainsKey("SendTargets"))
  31. {
  32. KeyValuePairList<string, string> responseParameters = new KeyValuePairList<string, string>();
  33. lock (m_targets.Lock)
  34. {
  35. foreach (ISCSITarget target in m_targets.GetList())
  36. {
  37. responseParameters.Add("TargetName", target.TargetName);
  38. }
  39. }
  40. response.TextParameters = responseParameters;
  41. }
  42. else if (connection.Session.IsDiscovery || !IsVendorSpecificRequest(requestParameters))
  43. {
  44. KeyValuePairList<string, string> responseParameters = new KeyValuePairList<string, string>();
  45. foreach (KeyValuePair<string, string> entry in requestParameters)
  46. {
  47. responseParameters.Add(entry.Key, "Reject");
  48. }
  49. response.TextParameters = responseParameters;
  50. }
  51. else
  52. {
  53. // RFC 3720: Vendor specific keys MUST ONLY be used in normal sessions
  54. // Vendor specific text request, let the target handle it:
  55. response.TextParameters = connection.Session.Target.GetTextResponse(requestParameters);
  56. }
  57. }
  58. return response;
  59. }
  60. private static bool IsVendorSpecificRequest(KeyValuePairList<string, string> requestParameters)
  61. {
  62. foreach(string key in requestParameters.Keys)
  63. {
  64. // RFC 3720: Implementers may introduce new keys by prefixing them with "X-" [..] or X# if registered with IANA.
  65. if (!(key.StartsWith("X-") || key.StartsWith("X#")))
  66. {
  67. return false;
  68. }
  69. }
  70. return (requestParameters.Count > 0);
  71. }
  72. }
  73. }