summaryrefslogtreecommitdiffstats
path: root/src/Settings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Settings.cpp')
-rw-r--r--src/Settings.cpp429
1 files changed, 350 insertions, 79 deletions
diff --git a/src/Settings.cpp b/src/Settings.cpp
index 39229f5..246eddd 100644
--- a/src/Settings.cpp
+++ b/src/Settings.cpp
@@ -90,10 +90,13 @@ static int txstarttime = 0;
static int noconnectsync = 0;
static int txholdback = 0;
static int fqrate = 0;
+static int fqratestep = 0;
+static int fqratestepinterval = 0;
static int triptime = 0;
static int infinitetime = 0;
static int connectonly = 0;
-static int connectretry = 0;
+static int connectretrytime = 0;
+static int connectretryinterval = 0;
static int burstipg = 0;
static int burstsize = 0;
static int burstperiodic = 0;
@@ -113,7 +116,10 @@ static int hideips = 0;
static int bounceback = 0;
static int bouncebackhold = 0;
static int bouncebackperiod = 0;
+static int bouncebackrequest = 0;
+static int bouncebackreply = 0;
static int overridetos = 0;
+static int dscp = 0;
static int notcpbbquickack = 0;
static int tcpquickack = 0;
static int notcpbbquickack_cliset = 0;
@@ -121,6 +127,12 @@ static int workingload = 0;
static int utctimes = 0;
static int bouncebackdelaystart = 0;
static int tcpwritetimes = 0;
+static int primarycca = 0;
+static int loadcca = 0;
+static int tcptxdelay = 0;
+static int testxchangetimeout = 0;
+static int synctransferid = 0;
+static int ignoreshutdown = 0;
void Settings_Interpret(char option, const char *optarg, struct thread_Settings *mExtSettings);
// apply compound settings after the command line has been fully parsed
@@ -173,8 +185,11 @@ const struct option long_options[] =
{"bounceback-hold", required_argument, &bouncebackhold, 1},
{"bounceback-no-quickack", no_argument, &notcpbbquickack, 1},
{"bounceback-period", required_argument, &bouncebackperiod, 1},
+{"bounceback-request", required_argument, &bouncebackrequest, 1},
+{"bounceback-reply", required_argument, &bouncebackreply, 1},
{"compatibility", no_argument, NULL, 'C'},
{"daemon", no_argument, NULL, 'D'},
+{"dscp", required_argument, &dscp, 1},
{"file_input", required_argument, NULL, 'F'},
{"ssm-host", required_argument, NULL, 'H'},
{"stdin_input", no_argument, NULL, 'I'},
@@ -187,6 +202,7 @@ const struct option long_options[] =
#else
{"reverse", no_argument, NULL, 'R'},
#endif
+{"sync-transfer-id", no_argument, &synctransferid, 1},
{"tos", required_argument, NULL, 'S'},
{"ttl", required_argument, NULL, 'T'},
{"single_udp", no_argument, NULL, 'U'},
@@ -199,6 +215,7 @@ const struct option long_options[] =
{"jitter-histograms", optional_argument, &jitter_histogram, 1},
{"udp-histograms", optional_argument, &histogram, 1}, // keep support per 2.0.13 usage
{"l2checks", no_argument, &l2checks, 1},
+{"ignore-shutdown", no_argument, &ignoreshutdown, 1},
{"incr-dstip", no_argument, &incrdstip, 1},
{"incr-srcip", no_argument, &incrsrcip, 1},
{"incr-dstport", no_argument, &incrdstport, 1},
@@ -207,10 +224,13 @@ const struct option long_options[] =
{"txstart-time", required_argument, &txstarttime, 1},
{"txdelay-time", required_argument, &txholdback, 1},
{"fq-rate", required_argument, &fqrate, 1},
+{"fq-rate-step", required_argument, &fqratestep, 1},
+{"fq-rate-step-interval", required_argument, &fqratestepinterval, 1},
{"trip-times", no_argument, &triptime, 1},
{"no-udp-fin", no_argument, &noudpfin, 1},
{"connect-only", optional_argument, &connectonly, 1},
-{"connect-retries", required_argument, &connectretry, 1},
+{"connect-retry-time", required_argument, &connectretrytime, 1},
+{"connect-retry-timer", required_argument, &connectretryinterval, 1},
{"no-connect-sync", no_argument, &noconnectsync, 1},
{"full-duplex", no_argument, &fullduplextest, 1},
{"ipg", required_argument, &burstipg, 1},
@@ -225,11 +245,15 @@ const struct option long_options[] =
{"tos-override", required_argument, &overridetos, 1},
{"tcp-rx-window-clamp", required_argument, &rxwinclamp, 1},
{"tcp-quickack", no_argument, &tcpquickack, 1},
+{"tcp-tx-delay", required_argument, &tcptxdelay, 1},
{"tcp-write-prefetch", required_argument, &txnotsentlowwater, 1}, // see doc/DESIGN_NOTES
{"tcp-write-times", no_argument, &tcpwritetimes, 1},
+{"test-exchange-timeout", required_argument, &testxchangetimeout, 1},
{"tap-dev", optional_argument, &tapif, 1},
{"tun-dev", optional_argument, &tunif, 1},
{"working-load", optional_argument, &workingload, 1},
+{"working-load-cca", required_argument, &loadcca, 1},
+{"tcp-cca", required_argument, &primarycca, 1},
{"utc", no_argument, &utctimes, 1},
{"NUM_REPORT_STRUCTS", required_argument, &numreportstructs, 1},
#ifdef WIN32
@@ -294,8 +318,7 @@ const char short_options[] = "146b:c:def:hi:l:mn:o:p:rst:uvw:x:y:zAB:CDF:H:IL:M:
const long kDefault_UDPRate = 1024 * 1024; // -u if set, 1 Mbit/sec
const int kDefault_TCPBufLen = 128 * 1024; // TCP default read/write size
-const int kDefault_BBTCPBufLen = 100; // default bounce-back size in bytes
-
+const int kDefault_BBTCPReqLen = 100; // default bounce-back size in bytes
/* -------------------------------------------------------------------
* Initialize all settings to defaults.
@@ -414,6 +437,10 @@ void Settings_Copy (struct thread_Settings *from, struct thread_Settings **into,
(*into)->mCongestion = new char[strlen(from->mCongestion) + 1];
strcpy((*into)->mCongestion, from->mCongestion);
}
+ if (from->mLoadCCA != NULL) {
+ (*into)->mLoadCCA = new char[strlen(from->mLoadCCA) + 1];
+ strcpy((*into)->mLoadCCA, from->mLoadCCA);
+ }
} else {
(*into)->mHost = NULL;
(*into)->mOutputFileName = NULL;
@@ -458,6 +485,15 @@ void Settings_Copy (struct thread_Settings *from, struct thread_Settings **into,
unsetReport((*into));
}
+void Settings_Grow_mBuf (struct thread_Settings *mSettings, int newsize) {
+ char *tmp = new char[newsize];
+ pattern(tmp, newsize);
+ memcpy(tmp, mSettings->mBuf, mSettings->mBufLen);
+ DELETE_ARRAY(mSettings->mBuf);
+ mSettings->mBuf = tmp;
+ mSettings->mBufLen = newsize;
+}
+
/* -------------------------------------------------------------------
* Delete memory: Does not clean up open file pointers or ptr_parents
* ------------------------------------------------------------------- */
@@ -477,6 +513,7 @@ void Settings_Destroy (struct thread_Settings *mSettings) {
DELETE_ARRAY(mSettings->mHistogramStr);
DELETE_ARRAY(mSettings->mSSMMulticastStr);
DELETE_ARRAY(mSettings->mCongestion);
+ DELETE_ARRAY(mSettings->mLoadCCA);
FREE_ARRAY(mSettings->mIfrname);
FREE_ARRAY(mSettings->mIfrnametx);
FREE_ARRAY(mSettings->mTransferIDStr);
@@ -729,7 +766,10 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
break;
case 'v': // print version and exit
- fprintf(stdout, "%s", version);
+ if (strlen(IPERF_BRANCH))
+ fprintf(stdout, "%s", branch_version);
+ else
+ fprintf(stdout, "%s", version);
exit(0);
break;
@@ -888,9 +928,12 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
// TODO use a function that understands base-2
// the zero base here allows the user to specify
// "0x#" hex, "0#" octal, and "#" decimal numbers
- if ((mExtSettings->mTOS = parse_ipqos(optarg)) == -1) {
- fprintf(stderr, "Invalid --tos value of %s\n", optarg);
+ mExtSettings->mTOS = parse_ipqos(optarg);
+ if (mExtSettings->mTOS == -1) {
+ fprintf(stderr, "WARN: Invalid --tos value of %s ignored\n", optarg);
mExtSettings->mTOS = 0;
+ } else {
+ setSetTOS(mExtSettings);
}
break;
@@ -923,10 +966,14 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
break;
case 'Z':
-#ifdef TCP_CONGESTION
- setCongestionControl(mExtSettings);
- mExtSettings->mCongestion = new char[strlen(optarg)+1];
- strcpy(mExtSettings->mCongestion, optarg);
+#if HAVE_DECL_TCP_CONGESTION
+ if (isCongestionControl(mExtSettings)) {
+ fprintf(stderr, "Option --tcp-congestion or -Z ignored because --tcp-cca set\n");
+ } else {
+ setCongestionControl(mExtSettings);
+ mExtSettings->mCongestion = new char[strlen(optarg)+1];
+ strcpy(mExtSettings->mCongestion, optarg);
+ }
#else
fprintf(stderr, "The -Z option is not available on this operating system\n");
#endif
@@ -949,10 +996,18 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
incrsrcport = 0;
setIncrSrcPort(mExtSettings);
}
+ if (ignoreshutdown) {
+ ignoreshutdown = 0;
+ setIgnoreShutdown(mExtSettings);
+ }
if (sumdstip) {
sumdstip = 0;
setSumServerDstIP(mExtSettings);
}
+ if (synctransferid) {
+ synctransferid = 0;
+ setSyncTransferID(mExtSettings);
+ }
if (txstarttime) {
long seconds;
long usecs;
@@ -1013,9 +1068,36 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
mExtSettings->connectonly_count = -1;
}
}
- if (connectretry) {
- connectretry = 0;
- mExtSettings->mConnectRetries = atoi(optarg);
+ if (connectretryinterval) {
+ connectretryinterval = 0;
+ char *end;
+ double period = strtof(optarg, &end);
+ if ((*end != '\0') || (period < 0 )) {
+ fprintf (stderr, "Invalid value of '%s' for --connect-retry-timer\n", optarg);
+ exit(1);
+ }
+ if (period > (UINT_MAX / 1e6)) {
+ fprintf (stderr, "Too large value of '%s' for --connect-retry-timer, max is %f\n", optarg, (UINT_MAX / 1e6));
+ exit(1);
+ }
+ mExtSettings->connect_retry_timer = static_cast<unsigned int>(ceil(period * 1e6));
+ if (mExtSettings->connect_retry_timer == 0) {
+ mExtSettings->connect_retry_timer = 10000;
+ }
+ }
+ if (connectretrytime) {
+ connectretrytime = 0;
+ char *end;
+ double timer = strtof(optarg, &end);
+ if (*end != '\0') {
+ fprintf (stderr, "Invalid value of '%s' for --connect-retry-time\n", optarg);
+ exit(1);
+ }
+ if (timer > (UINT_MAX / 1e6)) {
+ fprintf (stderr, "Too large value of '%s' for --connect-retry-time, max is %f\n", optarg, (UINT_MAX / 1e6));
+ exit(1);
+ }
+ mExtSettings->connect_retry_time = timer;
}
if (sumonly) {
sumonly = 0;
@@ -1048,7 +1130,7 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
permitkey = 0;
if (optarg) {
strncpy(mExtSettings->mPermitKey, optarg, MAX_PERMITKEY_LEN);
- mExtSettings->mPermitKey[MAX_PERMITKEY_LEN] = '\0';
+ mExtSettings->mPermitKey[MAX_PERMITKEY_LEN-1] = '\0';
} else {
mExtSettings->mPermitKey[0] = '\0';
}
@@ -1056,7 +1138,12 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
}
if (permitkeytimeout) {
permitkeytimeout = 0;
- if (atof(optarg) >= 0.0)
+ if (atof(optarg) > mExtSettings->mListenerTimeout)
+ mExtSettings->mListenerTimeout = static_cast<size_t>(atof(optarg));
+ }
+ if (testxchangetimeout) {
+ testxchangetimeout = 0;
+ if (atof(optarg) > mExtSettings->mListenerTimeout)
mExtSettings->mListenerTimeout = static_cast<size_t>(atof(optarg));
}
if (histogram) {
@@ -1096,8 +1183,13 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
setOverrideTOS(mExtSettings);
}
}
+ if (dscp) {
+ dscp = 0;
+ // dscp needs to shifted by 2 and the ECN bits masked off to map to a TOS byte
+ mExtSettings->mTOS = (atoi(optarg) << DSCP_SHIFT) & DSCP_BITMASK; //2 & 0xFC
+ }
if (fqrate) {
-#if defined(HAVE_DECL_SO_MAX_PACING_RATE)
+#if (HAVE_DECL_SO_MAX_PACING_RATE)
fqrate=0;
setFQPacing(mExtSettings);
mExtSettings->mFQPacingRate = static_cast<uintmax_t>(bitorbyte_atoi(optarg) / 8);
@@ -1105,6 +1197,34 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
fprintf(stderr, "WARNING: The --fq-rate option is not supported\n");
#endif
}
+#if (HAVE_DECL_SO_MAX_PACING_RATE)
+ if (fqratestep) {
+ fqratestep=0;
+ setFQPacingStep(mExtSettings);
+ mExtSettings->mFQPacingRateStep = static_cast<uintmax_t>(bitorbyte_atoi(optarg) / 8);
+ setEnhanced(mExtSettings);
+ }
+ if (fqratestepinterval) {
+ fqratestepinterval=0;
+ double val;
+#if HAVE_STRTOD
+ char *end;
+ errno = 0;
+ val = strtod(optarg, &end);
+ if (errno || (*end != '\0')) {
+ fprintf(stderr, "ERROR: --fq-rate-step-interval value of '%s' not recognized\n", optarg);
+ exit(1);
+ }
+#else
+ val = atof(optarg);
+#endif
+ if (val > 0.0) {
+ mExtSettings->mFQPacingRateStepInterval = val;
+ setFQPacingStepInterval(mExtSettings);
+ setEnhanced(mExtSettings);
+ }
+ }
+#endif
if (isochronous) {
isochronous = 0;
setEnhanced(mExtSettings);
@@ -1153,14 +1273,59 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
setTcpQuickAck(mExtSettings);
#endif
}
+ if (tcptxdelay) {
+ tcptxdelay = 0;
+#if HAVE_DECL_TCP_TX_DELAY
+ char *tmp= new char [strlen(optarg) + 1];
+ char *results;
+ strcpy(tmp, optarg);
+ mExtSettings->mTcpTxDelayProb = 1.0;
+ if (((results = strtok(tmp, ",")) != NULL) && !strcmp(results,tmp)) {
+ mExtSettings->mTcpTxDelayMean = atof(results);
+ if ((results = strtok(NULL, ",")) != NULL) {
+ mExtSettings->mTcpTxDelayProb = atof(results);
+ }
+ }
+ if (mExtSettings->mTcpTxDelayMean > 0) {
+ setTcpTxDelay(mExtSettings);
+ }
+#else
+ fprintf(stderr, "The --tcp-tx-delay option is not available on this operating system\n");
+#endif
+ }
if (utctimes) {
setUTC(mExtSettings);
}
+ if (loadcca) {
+ loadcca = 0;
+#if HAVE_DECL_TCP_CONGESTION
+ setLoadCCA(mExtSettings);
+ mExtSettings->mLoadCCA = new char[strlen(optarg)+1];
+ strcpy(mExtSettings->mLoadCCA, optarg);
+#else
+ fprintf(stderr, "The --working-load-cca option is not available on this operating system\n");
+#endif
+ }
+ if (primarycca) {
+ primarycca = 0;
+#if HAVE_DECL_TCP_CONGESTION
+ if (isCongestionControl(mExtSettings)) {
+ fprintf(stderr, "Option --tcp-cca ignored because --tcp-congestion or -Z set\n");
+ } else {
+ setCongestionControl(mExtSettings);
+ mExtSettings->mCongestion = new char[strlen(optarg)+1];
+ strcpy(mExtSettings->mCongestion, optarg);
+ }
+#else
+ fprintf(stderr, "The --tcp-cca option is not available on this operating system\n");
+#endif
+ }
if (workingload) {
workingload = 0;
#ifdef HAVE_THREAD
setWorkingLoadUp(mExtSettings);
setWorkingLoadDown(mExtSettings);
+ setEnhanced(mExtSettings);
if (optarg) {
char *tmp= new char [strlen(optarg) + 1];
if (tmp) {
@@ -1224,7 +1389,7 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
}
if (burstsize) {
burstsize = 0;
- setPeriodicBurst(mExtSettings);
+ setBurstSize(mExtSettings);
if (optarg) {
mExtSettings->mBurstSize = byte_atoi(optarg);
}
@@ -1300,6 +1465,20 @@ void Settings_Interpret (char option, const char *optarg, struct thread_Settings
}
}
}
+ if (bouncebackrequest) {
+ bouncebackrequest = 0;
+ if (optarg)
+ mExtSettings->mBounceBackBytes = byte_atoi(optarg);
+ else
+ mExtSettings->mBounceBackBytes = 0;
+ }
+ if (bouncebackreply) {
+ bouncebackreply = 0;
+ if (optarg)
+ mExtSettings->mBounceBackReplyBytes = byte_atoi(optarg);
+ else
+ mExtSettings->mBounceBackReplyBytes = 0;
+ }
break;
default: // ignore unknown
break;
@@ -1383,7 +1562,7 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
}
} else {
if (isBounceBack(mExtSettings))
- mExtSettings->mBufLen = kDefault_BBTCPBufLen;
+ mExtSettings->mBufLen = kDefault_TCPBufLen;
else
mExtSettings->mBufLen = kDefault_TCPBufLen;
}
@@ -1428,12 +1607,6 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "ERROR: compatibility mode not supported with the requested with options\n");
bail = true;
}
-#if !(HAVE_DECL_IP_TOS)
- if (isOverrideTOS(mExtSettings) || mExtSettings->mTOS) {
- unsetOverrideTOS(mExtSettings);
- fprintf(stderr, "WARN: IP_TOS not supported\n");
- }
-#endif
if (isPermitKey(mExtSettings)) {
if (isUDP(mExtSettings)) {
fprintf(stderr, "ERROR: Option of --permit-key not supported with UDP\n");
@@ -1486,10 +1659,6 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "WARN: option of --jitter-histogram not supported on the client\n");
unsetJitterHistogram(mExtSettings);
}
- if (isIncrSrcPort(mExtSettings) && !mExtSettings->mBindPort) {
- fprintf(stderr, "WARN: option of --incr-srcport requires -B bind option w/port to be set\n");
- unsetIncrSrcPort(mExtSettings);
- }
if (isPeriodicBurst(mExtSettings)) {
setEnhanced(mExtSettings);
setFrameInterval(mExtSettings);
@@ -1502,6 +1671,17 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "ERROR: option of --permit-key requires a value on the client\n");
bail = true;
}
+#if (HAVE_DECL_SO_MAX_PACING_RATE)
+ if (isFQPacingStep(mExtSettings)) {
+ if (!isFQPacing(mExtSettings)) {
+ setFQPacing(mExtSettings);
+ mExtSettings->mFQPacingRate = mExtSettings->mFQPacingRateStep;
+ }
+ if (!isFQPacingStepInterval(mExtSettings)) {
+ mExtSettings->mFQPacingRateStepInterval = 1.0;
+ }
+ }
+#endif
if (!isUDP(mExtSettings) && isTxHoldback(mExtSettings) && isTxStartTime(mExtSettings)) {
fprintf(stderr,"ERROR: options of --txstart-time and --txdelay-time are mutually exclusive\n");
bail = true;
@@ -1527,11 +1707,40 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
bail = true;
}
}
+ if (isTripTime(mExtSettings) && (mExtSettings->mBufLen < static_cast<int> (sizeof(struct TCP_burst_payload)))) {
+ fprintf(stderr, "ERROR: payload (-l) size of %d too small for --trip-times, must be %d or greater\n",\
+ mExtSettings->mBufLen, static_cast<int> (sizeof(struct TCP_burst_payload)));
+ bail = true;
+ }
if (isBounceBack(mExtSettings)) {
if (static_cast<int> (mExtSettings->mBurstSize) > 0) {
fprintf(stderr, "WARN: options of --burst-size for bounce-back ignored, use -l sets size\n");
}
- mExtSettings->mBounceBackBytes = mExtSettings->mBufLen;
+ if (mExtSettings->mBounceBackBytes <= 0) {
+ if (isBuflenSet(mExtSettings)) {
+ // Backward compatibility with older versions
+ mExtSettings->mBounceBackBytes = mExtSettings->mBufLen;
+ } else {
+ mExtSettings->mBounceBackBytes = kDefault_BBTCPReqLen;
+ }
+ } else if (mExtSettings->mBounceBackBytes > mExtSettings->mBufLen) {
+ if (isBuflenSet(mExtSettings)) {
+ mExtSettings->mBounceBackBytes = mExtSettings->mBufLen;
+ fprintf(stderr, "WARN: bounceback request will use -l length and not --bounceback-request value\n");
+ } else {
+ mExtSettings->mBufLen = mExtSettings->mBounceBackBytes;
+ }
+ }
+ if (mExtSettings->mBounceBackReplyBytes <= 0) {
+ mExtSettings->mBounceBackReplyBytes = mExtSettings->mBounceBackBytes;
+ } else if (mExtSettings->mBounceBackReplyBytes > mExtSettings->mBufLen) {
+ if (isBuflenSet(mExtSettings)) {
+ mExtSettings->mBounceBackReplyBytes = mExtSettings->mBufLen;
+ fprintf(stderr, "WARN: bounceback reply will use -l length and not --bounceback-reply value\n");
+ } else {
+ mExtSettings->mBufLen = mExtSettings->mBounceBackReplyBytes;
+ }
+ }
mExtSettings->mBurstSize = mExtSettings->mBufLen;
#if HAVE_DECL_TCP_QUICKACK
if (notcpbbquickack_cliset && isTcpQuickAck(mExtSettings)) {
@@ -1559,15 +1768,17 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
}
}
#if HAVE_DECL_TCP_NOTSENT_LOWAT
- if (isTripTime(mExtSettings) && !isUDP(mExtSettings)) {
- if (isWritePrefetch(mExtSettings)) {
- if (mExtSettings->mWritePrefetch <= 0) {
- unsetWritePrefetch(mExtSettings);
+ if (!isUDP(mExtSettings)) {
+ if (isTcpWriteTimes(mExtSettings) || isTripTime(mExtSettings)) {
+ if (isWritePrefetch(mExtSettings)) {
+ if (mExtSettings->mWritePrefetch <= 0) {
+ unsetWritePrefetch(mExtSettings);
+ }
+ } else {
+ mExtSettings->mWritePrefetch = SMALL_WRITE_PREFETCH;
+ setWritePrefetch(mExtSettings);
+ setEnhanced(mExtSettings);
}
- } else {
- mExtSettings->mWritePrefetch = SMALL_WRITE_PREFETCH;
- setWritePrefetch(mExtSettings);
- setEnhanced(mExtSettings);
}
}
#endif
@@ -1585,10 +1796,14 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "ERROR: option of --burst-size %d must be equal or larger to write length (-l) %d\n", mExtSettings->mBurstSize, mExtSettings->mBufLen);
bail = true;
}
- } else if (!isBounceBack(mExtSettings) && (static_cast<int> (mExtSettings->mBurstSize) > 0)) {
- setPeriodicBurst(mExtSettings);
- mExtSettings->mFPS = 1.0;
- fprintf(stderr, "WARN: option of --burst-size without --burst-period defaults --burst-period to 1 second\n");
+ }
+ if ((mExtSettings->connect_retry_time > 0) && !mExtSettings->connect_retry_timer) {
+ fprintf(stderr, "WARN: companion option of --connect-retry-timer not set - setting to default value of one second\n");
+ mExtSettings->connect_retry_timer = 1000000; // 1 sec in units usecs
+ }
+ if ((mExtSettings->connect_retry_timer > 0) && (mExtSettings->connect_retry_time <= 0)) {
+ fprintf(stderr, "WARN: companion option of --connect-retry-time not set - setting to default value of ten seconds\n");
+ mExtSettings->connect_retry_time = 10;
}
if (isUDP(mExtSettings)) {
if (isPeerVerDetect(mExtSettings)) {
@@ -1615,7 +1830,7 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "ERROR: option --ipg must be a positive value\n");
bail = true;
}
- if (mExtSettings->mConnectRetries > 0) {
+ if (mExtSettings->connect_retry_timer > 0) {
fprintf(stderr, "ERROR: option --connect-retries not supported with -u UDP\n");
bail = true;
}
@@ -1627,18 +1842,22 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "WARN: setting of option --tcp-quickack is not supported with -u UDP\n");
unsetWritePrefetch(mExtSettings);
}
+ if (isTcpTxDelay(mExtSettings)) {
+ fprintf(stderr, "WARN: setting of option --tcp-tx-delay is not supported with -u UDP\n");
+ unsetTcpTxDelay(mExtSettings);
+ }
{
double delay_target;
if (isIPG(mExtSettings)) {
- delay_target = mExtSettings->mBurstIPG * 1e9; // convert from seconds to nanoseconds
+ delay_target = ((mExtSettings->mBurstIPG > 0) ? mExtSettings->mBurstIPG * 1e9 : 0); // convert from seconds to nanoseconds
} else {
// compute delay target in units of nanoseconds
if (mExtSettings->mAppRateUnits == kRate_BW) {
// compute delay for bandwidth restriction, constrained to [0,max] seconds
- delay_target = (mExtSettings->mBufLen * 8e9) / mExtSettings->mAppRate;
+ delay_target = ((mExtSettings->mAppRate > 0) ? ((mExtSettings->mBufLen * 8e9) / mExtSettings->mAppRate) : 0);
} else {
- delay_target = 1e9 / mExtSettings->mAppRate;
+ delay_target = ((mExtSettings->mAppRate > 0) ? (1e9 / mExtSettings->mAppRate) : 0);
}
}
if (delay_target < 0 ||
@@ -1648,9 +1867,9 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
}
}
if (isTripTime(mExtSettings)) {
- if (mExtSettings->mBufLen < MINTRIPTIMEPLAYOAD) {
+ if (mExtSettings->mBufLen < MINTRIPTIMEPAYLOAD) {
if (isReverse(mExtSettings) || isFullDuplex(mExtSettings) || (mExtSettings->mMode != kTest_Normal)) {
- fprintf(stderr, "ERROR: payload (-l) size of %d too small for --trip-times, must be %d or greater\n", mExtSettings->mBufLen, MINTRIPTIMEPLAYOAD);
+ fprintf(stderr, "ERROR: payload (-l) size of %d too small for --trip-times, must be %d or greater\n", mExtSettings->mBufLen, MINTRIPTIMEPAYLOAD);
bail = true;
} else {
setSmallTripTime(mExtSettings);
@@ -1731,6 +1950,11 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
mExtSettings->mListenerTimeout = DEFAULT_PERMITKEY_LIFE;
}
}
+ if ((mExtSettings->mWorkingLoadThreads > 0) || (!isWorkingLoadUp(mExtSettings) && isWorkingLoadDown(mExtSettings)) \
+ || (isWorkingLoadUp(mExtSettings) && !isWorkingLoadDown(mExtSettings))) {
+ fprintf(stderr, "ERROR: setting of --working-load options is not supported on the server, just use --working-load\n");
+ bail = true;
+ }
if (isBounceBack(mExtSettings)) {
fprintf(stderr, "ERROR: setting of option --bounce-back is not supported on the server\n");
bail = true;
@@ -1769,6 +1993,9 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
if (isIncrDstIP(mExtSettings)) {
fprintf(stderr, "WARN: option of --incr-dstip is not supported on the server\n");
}
+ if (isIgnoreShutdown(mExtSettings)) {
+ fprintf(stderr, "WARN: option of --ignore-shutdown is not supported on the server\n");
+ }
if (isFQPacing(mExtSettings)) {
fprintf(stderr, "WARN: option of --fq-rate is not supported on the server\n");
}
@@ -1778,12 +2005,15 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
if (isPeerVerDetect(mExtSettings)) {
fprintf(stderr, "WARN: option of -X or --peer-detect not supported on the server\n");
}
- if (mExtSettings->mConnectRetries > 0) {
+ if (mExtSettings->connect_retry_timer > 0) {
fprintf(stderr, "WARN: option --connect-retries not supported on the server\n");
}
if (isNearCongest(mExtSettings)) {
fprintf(stderr, "WARN: option of --near-congestion not supported on the server\n");
}
+ if (isSyncTransferID(mExtSettings)) {
+ fprintf(stderr, "WARN: option of --sync-transfer-id is not supported on the server\n");
+ }
if (isPeriodicBurst(mExtSettings)) {
fprintf(stderr, "WARN: option of --burst-period can only be set on the client\n");
}
@@ -1802,15 +2032,15 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
if (isHistogram(mExtSettings)) {
if (!mExtSettings->mHistogramStr) {
if (mExtSettings->mThreadMode == kMode_Server) {
- // set default rx histogram settings, milliseconds bins between 0 and 1 secs
- mExtSettings->mHistBins = 1000;
+ // set default rx histogram settings, milliseconds bins between 0 and 10 secs
+ mExtSettings->mHistBins = 10000;
mExtSettings->mHistBinsize = 1;
mExtSettings->mHistUnits = 3;
mExtSettings->mHistci_lower = 5;
mExtSettings->mHistci_upper = 95;
} else {
// set default tx histogram settings, microseconds with 100 us bins
- mExtSettings->mHistBins = 10000;
+ mExtSettings->mHistBins = 100000;
mExtSettings->mHistBinsize = 100;
mExtSettings->mHistUnits = 6;
mExtSettings->mHistci_lower = 5;
@@ -1910,7 +2140,6 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
// Check for further mLocalhost (-B) and <dev> requests
// full addresses look like 192.168.1.1:6001%eth0 or [2001:e30:1401:2:d46e:b891:3082:b939]:6001%eth0
- iperf_sockaddr tmp;
// Parse -B addresses
if (mExtSettings->mLocalhost) {
if (((results = strtok(mExtSettings->mLocalhost, "%")) != NULL) && ((results = strtok(NULL, "%")) != NULL)) {
@@ -1934,17 +2163,26 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
fprintf(stderr, "WARNING: port %s ignored - set receive port on server via -p or -L\n", results);
}
}
- // Check for multicast per the -B
- SockAddr_setHostname(mExtSettings->mLocalhost, &tmp,
- (isIPV6(mExtSettings) ? 1 : 0));
- if ((mExtSettings->mThreadMode != kMode_Client) && SockAddr_isMulticast(&tmp)) {
- setMulticast(mExtSettings);
- } else if (SockAddr_isMulticast(&tmp)) {
- if (mExtSettings->mIfrname) {
- free(mExtSettings->mIfrname);
- mExtSettings->mIfrname = NULL;
+ // Do multicast address checking and processing
+ SockAddr_setHostname(mExtSettings->mLocalhost, &mExtSettings->multicast_group, \
+ &mExtSettings->size_multicast_group, (isIPV6(mExtSettings) ? 1 : 0));
+ if (SockAddr_isMulticast(&mExtSettings->multicast_group)) {
+ if (mExtSettings->mThreadMode == kMode_Client) {
+ fprintf(stderr, "WARNING: Client src addr (per -B) must be ip unicast\n");
+ exit(1);
+ } else {
+ setMulticast(mExtSettings);
+ if (isSSMMulticast(mExtSettings)) {
+ SockAddr_setHostname(mExtSettings->mSSMMulticastStr, &mExtSettings->multicast_group_source, \
+ &mExtSettings->size_multicast_group, (isIPV6(mExtSettings) ? 1 : 0));
+ if (SockAddr_isMulticast(&mExtSettings->multicast_group_source)) {
+ fprintf(stderr, "WARNING: SSM host src address (-H or --ssm-host) must be ip unicast\n");
+ exit(1);
+ }
+ }
}
- fprintf(stderr, "WARNING: Client src addr (per -B) must be ip unicast\n");
+ } else {
+ SockAddr_zeroAddress(&mExtSettings->multicast_group); // Zero out multicast sockaddr
}
}
// Parse client (-c) addresses for multicast, link-local and bind to device, port incr
@@ -1987,25 +2225,22 @@ void Settings_ModalOptions (struct thread_Settings *mExtSettings) {
}
if (SockAddr_isMulticast(&mExtSettings->peer)) {
bail = false;
- if ((mExtSettings->mThreads > 1) && !isIncrDstIP(mExtSettings)) {
- fprintf(stderr, "ERROR: client option of -P greater than 1 not supported with multicast address\n");
- bail = true;
- } else if (isFullDuplex(mExtSettings) || isReverse(mExtSettings) || (mExtSettings->mMode != kTest_Normal)) {
+ if (isFullDuplex(mExtSettings) || isReverse(mExtSettings) || (mExtSettings->mMode != kTest_Normal)) {
fprintf(stderr, "ERROR: options of --full-duplex, --reverse, -d and -r not supported with multicast addresses\n");
bail = true;
+ } else if (isSyncTransferID(mExtSettings)) {
+ fprintf(stderr, "ERROR: option of --sync-transfer-id incompatibile with multicast\n");
+ bail = true;
}
if (bail)
exit(1);
else
setMulticast(mExtSettings);
}
-#ifndef HAVE_DECL_SO_BINDTODEVICE
- if (mExtSettings->mIfrnametx) {
- fprintf(stderr, "bind to device will be ignored because not supported\n");
- free(mExtSettings->mIfrnametx);
- mExtSettings->mIfrnametx=NULL;
- }
-#endif
+ }
+ if (isIncrSrcPort(mExtSettings) && !mExtSettings->mBindPort) {
+ fprintf(stderr, "WARN: option of --incr-srcport requires -B bind option w/port to be set\n");
+ unsetIncrSrcPort(mExtSettings);
}
if ((mExtSettings->mIntervalMode == kInterval_Time) && (mExtSettings->mIntervalMode <= 0)) {
mExtSettings->mIntervalMode = kInterval_None;
@@ -2151,7 +2386,7 @@ void Settings_GenerateClientSettings (struct thread_Settings *server, struct thr
thread_debug("header set for a version 1 test");
#endif
if (isFullDuplex(server) || isServerReverse(server))
- setTransferID(server, 1);
+ setTransferID(server, REVERSED);
if (isFullDuplex(server) || v1test) {
Settings_Copy(server, client, SHALLOW_COPY);
reversed_thread = *client;
@@ -2291,7 +2526,16 @@ int Settings_GenerateClientHdrV1 (struct thread_Settings *client, struct client_
} else {
hdr->mPort = htonl(client->mPort);
}
- hdr->numThreads = htonl(client->mThreads);
+ if (isSyncTransferID(client)) {
+ if (client->mTransferID & (HEADER_HASTRANSFERID | HEADER_TRANSFERIDMASK)) {
+ fprintf(stderr, "WARN: num threads too large for --sync-transfer-id\n");
+ } else {
+ uint32_t tidthreads = (HEADER_HASTRANSFERID | ((client->mTransferID << HEADER_TRANSFERIDSHIFT) & HEADER_TRANSFERIDMASK) | client->mThreads);
+ hdr->numThreads = htonl(tidthreads);
+ }
+ } else {
+ hdr->numThreads = htonl(client->mThreads);
+ }
if (isModeTime(client)) {
hdr->mAmount = htonl(-(long)client->mAmount);
} else {
@@ -2325,10 +2569,13 @@ int Settings_GenerateClientHdr (struct thread_Settings *client, void *testhdr, s
struct client_udpsmall_testhdr *hdr = static_cast<struct client_udpsmall_testhdr *>(testhdr);
memset(hdr, 0, buflen);
hdr->flags = htons(HEADER16_SMALL_TRIPTIMES);
+ if (isTxStartTime(client) && !TimeZero(startTime)) {
+ hdr->start_tv_sec = htonl(startTime.tv_sec);
+ }
#ifdef HAVE_THREAD_DEBUG
thread_debug("UDP small trip times flags = %X", ntohs(hdr->flags));
#endif
- return (MINIPERFPAYLOAD);
+ return buflen;
}
// flags common to both TCP and UDP
if (isReverse(client) && !isCompat(client)) {
@@ -2473,7 +2720,7 @@ int Settings_GenerateClientHdr (struct thread_Settings *client, void *testhdr, s
}
len += sizeof(struct client_hdrext);
len += Settings_GenerateClientHdrV1(client, &hdr->base);
- if (!isCompat(client) && (client->mMode != kTest_Normal)) {
+ if ((!isCompat(client) && (client->mMode != kTest_Normal)) || isSyncTransferID(client)) {
flags |= HEADER_VERSION1;
if (client->mMode == kTest_DualTest)
flags |= RUN_NOW;
@@ -2481,7 +2728,7 @@ int Settings_GenerateClientHdr (struct thread_Settings *client, void *testhdr, s
if (isPeerVerDetect(client)) {
flags |= (HEADER_V2PEERDETECT | HEADER_VERSION2);
}
- if (isTripTime(client) || isFQPacing(client) || isIsochronous(client) || isTxStartTime(client)) {
+ if (isTripTime(client) || isFQPacing(client) || isIsochronous(client) || isTxStartTime(client) || isLoadCCA(client) || isCongestionControl(client)) {
hdr->start_fq.start_tv_sec = htonl(startTime.tv_sec);
hdr->start_fq.start_tv_usec = htonl(startTime.tv_usec);
hdr->start_fq.fqratel = htonl((uint32_t) client->mFQPacingRate);
@@ -2503,6 +2750,10 @@ int Settings_GenerateClientHdr (struct thread_Settings *client, void *testhdr, s
hdr->extend.TCPWritePrefetch = htonl((long)client->mWritePrefetch);
}
#endif
+ if (client->barrier_time) {
+ lowerflags |= HEADER_BARRIER_TIME;
+ hdr->extend.barrier_usecs = htonl((long)client->barrier_time);
+ }
#if HAVE_DECL_TCP_QUICKACK
if (isTcpQuickAck(client) && (!isReverse(client) || isFullDuplex(client))) {
upperflags |= HEADER_TCPQUICKACK;
@@ -2529,6 +2780,26 @@ int Settings_GenerateClientHdr (struct thread_Settings *client, void *testhdr, s
}
len += sizeof(struct client_hdrext_isoch_settings);
}
+ } else if (isLoadCCA(client) || isCongestionControl(client)) {
+ // just jump the enclave hdr
+ len += sizeof(struct client_hdrext_isoch_settings);
+ }
+ if (isLoadCCA(client) && (isWorkingLoadUp(client) || isWorkingLoadDown(client))) {
+ uint16_t lenfield = ((client->mLoadCCA != NULL) ? (strlen(client->mLoadCCA)) : 0);
+ if (lenfield > 0) {
+ hdr->cca.cca_length = htons(lenfield);
+ lowerflags |= HEADER_CCA;
+ memcpy(hdr->cca.value, client->mLoadCCA, lenfield);
+ len += sizeof(uint16_t) + lenfield;
+ }
+ } else if (isCongestionControl(client)) {
+ uint16_t lenfield = ((client->mCongestion != NULL) ? (strlen(client->mCongestion)) : 0);
+ if (lenfield > 0) {
+ hdr->cca.cca_length = htons(lenfield);
+ lowerflags |= HEADER_CCA;
+ memcpy(hdr->cca.value, client->mCongestion, lenfield);
+ len += sizeof(uint16_t) + lenfield;
+ }
}
if (isReverse(client) || isFullDuplex(client)) {
flags |= HEADER_VERSION2;