diff options
Diffstat (limited to '')
-rw-r--r-- | src/Settings.cpp | 429 |
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, ¬cpbbquickack, 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; |