Index: trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 22257)
+++ trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 22258)
@@ -456,4 +456,5 @@
 static int iscsiTextGetKeyValue(const uint8_t *pbBuf, size_t cbBuf, const char *pcszKey, const char **ppcszValue);
 static int iscsiStrToBinary(const char *pcszValue, uint8_t *pbValue, size_t *pcbValue);
+static int iscsiUpdateParameters(PISCSIIMAGE pImage, const uint8_t *pbBuf, size_t cbBuf);
 
 /* Serial number arithmetic comparison. */
@@ -838,10 +839,6 @@
     pImage->cbRecvDataLength = ISCSI_DATA_LENGTH_MAX;
     pImage->cbSendDataLength = ISCSI_DATA_LENGTH_MAX;
-    char szMaxRecvDataSegmentLength[16];
-    RTStrPrintf(szMaxRecvDataSegmentLength, sizeof(szMaxRecvDataSegmentLength), "%u", ISCSI_DATA_LENGTH_MAX);
-    char szMaxBurstLength[16];
-    RTStrPrintf(szMaxBurstLength, sizeof(szMaxBurstLength), "%u", ISCSI_DATA_LENGTH_MAX);
-    char szFirstBurstLength[16];
-    RTStrPrintf(szFirstBurstLength, sizeof(szFirstBurstLength), "%u", ISCSI_DATA_LENGTH_MAX);
+    char szMaxDataLength[16];
+    RTStrPrintf(szMaxDataLength, sizeof(szMaxDataLength), "%u", ISCSI_DATA_LENGTH_MAX);
     ISCSIPARAMETER aParameterNeg[] =
     {
@@ -851,7 +848,7 @@
         { "InitialR2T", "No", 0 },
         { "ImmediateData", "Yes", 0 },
-        { "MaxRecvDataSegmentLength", szMaxRecvDataSegmentLength, 0 },
-        { "MaxBurstLength", szMaxBurstLength, 0 },
-        { "FirstBurstLength", szFirstBurstLength, 0 },
+        { "MaxRecvDataSegmentLength", szMaxDataLength, 0 },
+        { "MaxBurstLength", szMaxDataLength, 0 },
+        { "FirstBurstLength", szMaxDataLength, 0 },
         { "DefaultTime2Wait", "0", 0 },
         { "DefaultTime2Retain", "60", 0 },
@@ -1044,4 +1041,8 @@
                         {
                             case 0x0000:    /* security negotiation, step 0: receive final authentication. */
+                                rc = iscsiUpdateParameters(pImage, bBuf, aISCSIRes[1].cbSeg);
+                                if (RT_FAILURE(rc))
+                                    break;
+
                                 const char *pcszAuthMethod;
 
@@ -1072,4 +1073,8 @@
                                 break;
                             case 0x0001:    /* security negotiation, step 1: receive final CHAP variant and challenge. */
+                                rc = iscsiUpdateParameters(pImage, bBuf, aISCSIRes[1].cbSeg);
+                                if (RT_FAILURE(rc))
+                                    break;
+
                                 const char *pcszChapAuthMethod;
                                 const char *pcszChapIdxTarget;
@@ -1113,4 +1118,8 @@
                                 break;
                             case 0x0002:    /* security negotiation, step 2: check authentication success. */
+                                rc = iscsiUpdateParameters(pImage, bBuf, aISCSIRes[1].cbSeg);
+                                if (RT_FAILURE(rc))
+                                    break;
+
                                 if (targetCSG == 0 && targetNSG == 1 && targetTransit)
                                 {
@@ -1124,68 +1133,7 @@
                                 break;
                             case 0x0100:    /* login operational negotiation, step 0: check results. */
-                            {
-                                const char *pcszMaxRecvDataSegmentLength = NULL;
-                                const char *pcszMaxBurstLength = NULL;
-                                const char *pcszFirstBurstLength = NULL;
-                                rc = iscsiTextGetKeyValue(bBuf, aISCSIRes[1].cbSeg, "MaxRecvDataSegmentLength", &pcszMaxRecvDataSegmentLength);
-                                if (rc == VERR_INVALID_NAME)
-                                    rc = VINF_SUCCESS;
+                                rc = iscsiUpdateParameters(pImage, bBuf, aISCSIRes[1].cbSeg);
                                 if (RT_FAILURE(rc))
-                                {
-                                    rc = VERR_PARSE_ERROR;
                                     break;
-                                }
-                                if (pcszMaxRecvDataSegmentLength && strlen(pcszMaxRecvDataSegmentLength) >= sizeof(szMaxRecvDataSegmentLength))
-                                {
-                                    rc = VERR_BUFFER_OVERFLOW;
-                                    break;
-                                }
-                                rc = iscsiTextGetKeyValue(bBuf, aISCSIRes[1].cbSeg, "MaxBurstLength", &pcszMaxBurstLength);
-                                if (rc == VERR_INVALID_NAME)
-                                    rc = VINF_SUCCESS;
-                                if (RT_FAILURE(rc))
-                                {
-                                    rc = VERR_PARSE_ERROR;
-                                    break;
-                                }
-                                if (pcszMaxBurstLength && strlen(pcszMaxBurstLength) >= sizeof(szMaxBurstLength))
-                                {
-                                    rc = VERR_BUFFER_OVERFLOW;
-                                    break;
-                                }
-                                rc = iscsiTextGetKeyValue(bBuf, aISCSIRes[1].cbSeg, "FirstBurstLength", &pcszFirstBurstLength);
-                                if (rc == VERR_INVALID_NAME)
-                                    rc = VINF_SUCCESS;
-                                if (RT_FAILURE(rc))
-                                {
-                                    rc = VERR_PARSE_ERROR;
-                                    break;
-                                }
-                                if (pcszFirstBurstLength && strlen(pcszFirstBurstLength) >= sizeof(szFirstBurstLength))
-                                {
-                                    rc = VERR_BUFFER_OVERFLOW;
-                                    break;
-                                }
-                                if (pcszMaxRecvDataSegmentLength)
-                                {
-                                    uint32_t cb = pImage->cbSendDataLength;
-                                    rc = RTStrToUInt32Full(pcszMaxRecvDataSegmentLength, 0, &cb);
-                                    AssertRC(rc);
-                                    pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
-                                }
-                                if (pcszMaxBurstLength)
-                                {
-                                    uint32_t cb = pImage->cbSendDataLength;
-                                    rc = RTStrToUInt32Full(pcszMaxBurstLength, 0, &cb);
-                                    AssertRC(rc);
-                                    pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
-                                }
-                                if (pcszFirstBurstLength)
-                                {
-                                    uint32_t cb = pImage->cbSendDataLength;
-                                    rc = RTStrToUInt32Full(pcszFirstBurstLength, 0, &cb);
-                                    AssertRC(rc);
-                                    pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
-                                }
 
                                 if (targetCSG == 1 && targetNSG == 3 && targetTransit)
@@ -1207,5 +1155,4 @@
                                 rc = VERR_PARSE_ERROR;
                                 break;
-                            }
                             case 0x0300:    /* full feature phase. */
                             default:
@@ -2116,4 +2063,58 @@
         default:
             return VERR_PARSE_ERROR;
+    }
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Retrieve the relevant parameter values and update the initiator state.
+ *
+ * @returns VBOX status.
+ * @param   pImage     Current iSCSI initiator state.
+ * @param   pbBuf      Buffer containing key=value pairs.
+ * @param   cbBuf      Length of buffer with key=value pairs.
+ */
+static int iscsiUpdateParameters(PISCSIIMAGE pImage, const uint8_t *pbBuf, size_t cbBuf)
+{
+    int rc;
+    const char *pcszMaxRecvDataSegmentLength = NULL;
+    const char *pcszMaxBurstLength = NULL;
+    const char *pcszFirstBurstLength = NULL;
+    rc = iscsiTextGetKeyValue(pbBuf, cbBuf, "MaxRecvDataSegmentLength", &pcszMaxRecvDataSegmentLength);
+    if (rc == VERR_INVALID_NAME)
+        rc = VINF_SUCCESS;
+    if (RT_FAILURE(rc))
+        return VERR_PARSE_ERROR;
+    rc = iscsiTextGetKeyValue(pbBuf, cbBuf, "MaxBurstLength", &pcszMaxBurstLength);
+    if (rc == VERR_INVALID_NAME)
+        rc = VINF_SUCCESS;
+    if (RT_FAILURE(rc))
+        return VERR_PARSE_ERROR;
+    rc = iscsiTextGetKeyValue(pbBuf, cbBuf, "FirstBurstLength", &pcszFirstBurstLength);
+    if (rc == VERR_INVALID_NAME)
+        rc = VINF_SUCCESS;
+    if (RT_FAILURE(rc))
+        return VERR_PARSE_ERROR;
+    if (pcszMaxRecvDataSegmentLength)
+    {
+        uint32_t cb = pImage->cbSendDataLength;
+        rc = RTStrToUInt32Full(pcszMaxRecvDataSegmentLength, 0, &cb);
+        AssertRC(rc);
+        pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
+    }
+    if (pcszMaxBurstLength)
+    {
+        uint32_t cb = pImage->cbSendDataLength;
+        rc = RTStrToUInt32Full(pcszMaxBurstLength, 0, &cb);
+        AssertRC(rc);
+        pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
+    }
+    if (pcszFirstBurstLength)
+    {
+        uint32_t cb = pImage->cbSendDataLength;
+        rc = RTStrToUInt32Full(pcszFirstBurstLength, 0, &cb);
+        AssertRC(rc);
+        pImage->cbSendDataLength = RT_MIN(pImage->cbSendDataLength, cb);
     }
     return VINF_SUCCESS;
