diff -urNp iperf-1.7.0/confdefs.h iperf-1.7.0-new/confdefs.h --- iperf-1.7.0/confdefs.h 2002-11-25 16:26:00.000000000 -0500 +++ iperf-1.7.0-new/confdefs.h 2007-03-08 00:53:52.000000000 -0500 @@ -27,7 +27,7 @@ #define HAVE_GETTIMEOFDAY 1 #define HAVE_PTHREAD_CANCEL 1 #define HAVE_USLEEP 1 - +#define TCP_CONGESTION 13 diff -urNp iperf-1.7.0/src/Listener.cpp iperf-1.7.0-new/src/Listener.cpp --- iperf-1.7.0/src/Listener.cpp 2003-03-04 17:47:32.000000000 -0500 +++ iperf-1.7.0-new/src/Listener.cpp 2007-02-02 22:07:55.000000000 -0500 @@ -107,6 +107,7 @@ Thread() { Listener::~Listener() { DELETE_ARRAY( mSettings->mHost ); DELETE_ARRAY( mSettings->mLocalhost ); + DELETE_ARRAY( mSettings->mCongestion ); DELETE_ARRAY( mSettings->mFileName ); DELETE_ARRAY( mSettings->mOutputFileName ); DELETE_PTR( mSettings ); diff -urNp iperf-1.7.0/src/Locale.hpp iperf-1.7.0-new/src/Locale.hpp --- iperf-1.7.0/src/Locale.hpp 2003-03-03 16:17:08.000000000 -0500 +++ iperf-1.7.0-new/src/Locale.hpp 2007-02-02 19:39:30.000000000 -0500 @@ -104,6 +104,7 @@ Client specific:\n\ -L, --listenport # port to recieve bidirectional tests back on\n\ -P, --parallel # number of parallel client threads to run\n\ -T, --ttl # time-to-live, for multicast (default 1)\n\ + -Z, --congestion set TCP congestion control algorithm\n\ \n\ Miscellaneous:\n\ -h, --help print this message and quit\n\ @@ -233,7 +234,7 @@ const char report_bw_header[] = "[ ID] Interval Transfer Bandwidth\n"; const char report_bw_format[] = -"[%3d] %4.1f-%4.1f sec %ss %ss/sec\n"; +"LS-TH:%.1f %.1f %d\n"; const char report_sum_bw_format[] = "[SUM] %4.1f-%4.1f sec %ss %ss/sec\n"; diff -urNp iperf-1.7.0/src/Notify.cpp iperf-1.7.0-new/src/Notify.cpp --- iperf-1.7.0/src/Notify.cpp 2003-02-27 16:57:14.000000000 -0500 +++ iperf-1.7.0-new/src/Notify.cpp 2007-02-02 22:07:11.000000000 -0500 @@ -79,6 +79,7 @@ Notify::~Notify() { DELETE_ARRAY( mSettings->mHost ); DELETE_ARRAY( mSettings->mLocalhost ); DELETE_ARRAY( mSettings->mFileName ); + DELETE_ARRAY( mSettings->mCongestion ); DELETE_ARRAY( mSettings->mOutputFileName ); DELETE_PTR( mSettings ); } diff -urNp iperf-1.7.0/src/PerfSocket.cpp iperf-1.7.0-new/src/PerfSocket.cpp --- iperf-1.7.0/src/PerfSocket.cpp 2003-03-12 13:54:52.000000000 -0500 +++ iperf-1.7.0-new/src/PerfSocket.cpp 2007-02-02 22:56:01.000000000 -0500 @@ -167,6 +167,10 @@ void PerfSocket::InitTransfer( void ) { mPNextTime = mStartTime; mPNextTime.add( mPInterval ); + mCwndInterval.set(1, 0); + mCwndNextTime = mStartTime; + mCwndNextTime.add(mCwndInterval); + // setup termination variables mMode_time = ( mSettings->mAmount < 0 ); if ( mMode_time ) { @@ -179,6 +183,33 @@ void PerfSocket::InitTransfer( void ) { // end InitTransfer /* ------------------------------------------------------------------- + * Periodically report the cwnd and ssthresh, and rtt + * ------------------------------------------------------------------- */ + +void PerfSocket::ReportPeriodicCwnd( void ) { + if (mPacketTime.after( mCwndNextTime ) ) { + + double inStop = mPacketTime.subSec( mStartTime ); + + struct tcp_info info; + socklen_t len = sizeof(info); + memset((void *)&info, 0, len); + int rc = getsockopt( mSock, SOL_TCP, TCP_INFO, + (void *) &info, &len ); + if ((rc==0) && (len>0)) { + sReporting.Lock(); + printf("LS-CWND:%.2f %i %.2f %i %i %i %d\n", inStop, info.tcpi_snd_cwnd, info.tcpi_rtt/1000.0, + info.tcpi_snd_ssthresh, info.tcpi_ca_state, info.tcpi_reordering, mSock); + sReporting.Unlock(); + } + + mCwndNextTime = mPacketTime; + mCwndNextTime.add( mCwndInterval ); + } +} + + +/* ------------------------------------------------------------------- * Periodically report the bandwidth. * ------------------------------------------------------------------- */ @@ -269,16 +300,16 @@ void PerfSocket::ReportBW( max_size_t in sReportCount = 20; } - char bytes[ 32 ]; - char speed[ 32 ]; +// char bytes[ 32 ]; +// char speed[ 32 ]; - byte_snprintf( bytes, sizeof(bytes), (double) inBytes, - toupper( mSettings->mFormat)); - byte_snprintf( speed, sizeof(speed), - inBytes / (inStop - inStart), mSettings->mFormat); +// byte_snprintf( bytes, sizeof(bytes), (double) inBytes, + // toupper( mSettings->mFormat)); +// byte_snprintf( speed, sizeof(speed), + // inBytes / (inStop - inStart), mSettings->mFormat); printf( report_bw_format, - mSock, inStart, inStop, bytes, speed ); + inStop, inBytes*8/(inStop-inStart)/1024/1024, mSock ); fflush( stdout ); } @@ -526,6 +557,16 @@ void PerfSocket::SetSocketOptions( void // must occur before call to accept() for large window sizes set_tcp_windowsize( mSock, mSettings->mTCPWin ); +#ifdef TCP_CONGESTION + if (mSettings->mCongestion != NULL && mSettings->mHost) { + Socklen_t len = strlen(mSettings->mCongestion); + int rc = setsockopt(mSock, IPPROTO_TCP, TCP_CONGESTION, + mSettings->mCongestion, len); + WARN_errno( rc == SOCKET_ERROR, "set congestion" ); + } +#endif + + #ifdef IP_TOS // set IP TOS (type-of-service) field diff -urNp iperf-1.7.0/src/PerfSocket.hpp iperf-1.7.0-new/src/PerfSocket.hpp --- iperf-1.7.0/src/PerfSocket.hpp 2003-02-27 16:59:05.000000000 -0500 +++ iperf-1.7.0-new/src/PerfSocket.hpp 2007-03-08 00:53:18.000000000 -0500 @@ -108,6 +108,7 @@ protected: // General, in PerfSocket.cpp void InitTransfer( void ); + void ReportPeriodicCwnd( void ); void ReportPeriodicBW( void ); void ReportBW( max_size_t inBytes, double inStart, double inStop ); @@ -158,6 +159,8 @@ protected: Timestamp mPLastTime; Timestamp mPNextTime; Timestamp mPInterval; + Timestamp mCwndNextTime; + Timestamp mCwndInterval; bool mPReporting; int32_t mPLastErrorcnt; diff -urNp iperf-1.7.0/src/PerfSocket_TCP.cpp iperf-1.7.0-new/src/PerfSocket_TCP.cpp --- iperf-1.7.0/src/PerfSocket_TCP.cpp 2003-03-05 15:30:50.000000000 -0500 +++ iperf-1.7.0-new/src/PerfSocket_TCP.cpp 2005-08-18 01:00:15.000000000 -0400 @@ -124,6 +124,7 @@ void PerfSocket::Send_TCP( void ) { } // periodically report bandwidths + ReportPeriodicCwnd(); ReportPeriodicBW(); mTotalLen += currLen; @@ -148,7 +149,9 @@ void PerfSocket::Send_TCP( void ) { // stop timing mEndTime.setnow(); sReporting.Lock(); - ReportBW( mTotalLen, 0.0, mEndTime.subSec( mStartTime )); + //ReportBW( mTotalLen, 0.0, mEndTime.subSec( mStartTime )); + printf( "AVG : %.1f\n", mTotalLen*8/mEndTime.subSec(mStartTime)/1024/1024 ); + fflush( stdout ); sReporting.Unlock(); if ( mSettings->mPrintMSS ) { diff -urNp iperf-1.7.0/src/Settings.cpp iperf-1.7.0-new/src/Settings.cpp --- iperf-1.7.0/src/Settings.cpp 2003-03-03 16:17:08.000000000 -0500 +++ iperf-1.7.0-new/src/Settings.cpp 2007-02-02 22:55:28.000000000 -0500 @@ -113,6 +113,7 @@ const struct option long_options[] = {"ttl", required_argument, NULL, 'T'}, {"ipv6_domian", no_argument, NULL, 'V'}, {"suggest_win_size", no_argument, NULL, 'W'}, +{"congestion", required_argument, NULL, 'Z'}, {0, 0, 0, 0} }; @@ -151,12 +152,13 @@ const struct option env_options[] = {"IPERF_TTL", required_argument, NULL, 'T'}, {"IPERF_IPV6_DOMAIN", no_argument, NULL, 'V'}, {"IPERF_SUGGEST_WIN_SIZE", required_argument, NULL, 'W'}, +{"TCP_CONGESTION", required_argument, NULL, 'Z'}, {0, 0, 0, 0} }; #define SHORT_OPTIONS() -const char short_options[] = "b:c:df:hi:l:mn:o:p:rst:uvw:B:CDF:IL:M:NP:RS:T:VW"; +const char short_options[] = "b:c:df:hi:l:mn:o:p:rst:uvw:B:CDF:IL:M:NP:RS:T:VWZ:"; /* ------------------------------------------------------------------- * defaults @@ -197,6 +199,7 @@ Settings::Settings( ext_Settings *main ) // mUDPRate > 0 means UDP // -u, N/A, see kDefault_UDPRate // skip version // -v, mExtSettings->mTCPWin = 0; // -w, ie. don't set window + mExtSettings->mCongestion = NULL; // -z, congestion control // more esoteric options mExtSettings->mLocalhost = NULL; // -B, none @@ -502,6 +505,7 @@ void Settings::Interpret( char option, c break; case 'P': // number of client threads + #ifdef HAVE_THREAD mExtSettings->mThreads = atoi( optarg ); #else @@ -537,6 +541,11 @@ void Settings::Interpret( char option, c printf("The -W option is not available in this release\n"); break; + case 'Z' : + mExtSettings->mCongestion = new char[strlen(optarg)+1]; + strcpy(mExtSettings->mCongestion, optarg); + break; + default: // ignore unknown break; } @@ -586,6 +595,7 @@ void Settings::GenerateListenerSettings( (*listener)->mFileName = NULL; (*listener)->mHost = NULL; (*listener)->mLocalhost = NULL; + (*listener)->mCongestion = NULL; (*listener)->mOutputFileName = NULL; (*listener)->mMode = kTest_Normal; (*listener)->mServerMode = kMode_Server; @@ -634,6 +644,7 @@ void Settings::GenerateSpeakerSettings( (*speaker)->mFileName = NULL; (*speaker)->mHost = NULL; (*speaker)->mLocalhost = NULL; + (*speaker)->mCongestion = NULL; (*speaker)->mOutputFileName = NULL; (*speaker)->mMode = ((flags & RUN_NOW) == 0 ? kTest_TradeOff : kTest_DualTest); diff -urNp iperf-1.7.0/src/Settings.hpp iperf-1.7.0-new/src/Settings.hpp --- iperf-1.7.0/src/Settings.hpp 2003-02-27 17:35:24.000000000 -0500 +++ iperf-1.7.0-new/src/Settings.hpp 2007-03-08 00:53:02.000000000 -0500 @@ -134,6 +134,7 @@ struct ext_Settings { bool mStdin; // -I bool mStdout; // -o bool mSuggestWin; // -W + char* mCongestion; // -Z }; #define HEADER_VERSION1 0x80000000