From a660a50b3e9e08f71aee558f3a51d002bee05be7 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 24 Feb 2009 20:52:37 +0100 Subject: [PATCH] Support for UDP-Lite in iperf Applies on top of the DCCP patch and requires host support for UDP-Lite, which means two minor changes to header include files. See Documentation/networking/udplite.txt in the kernel sources (2.6.20 or higher) on how to set this up. --- include/Settings.hpp | 6 +++++- include/headers.h | 11 +++++++++++ include/version.h | 2 +- src/Locale.c | 7 ++++--- src/PerfSocket.cpp | 12 ++++++++++++ src/Settings.cpp | 15 ++++++++++++--- src/main.cpp | 1 + 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/include/Settings.hpp b/include/Settings.hpp index 0fe9921..d4c4244 100644 --- a/include/Settings.hpp +++ b/include/Settings.hpp @@ -74,6 +74,7 @@ typedef enum Protocol { kProto_TCP = IPPROTO_TCP, kProto_DCCP = IPPROTO_DCCP, kProto_UDP = IPPROTO_UDP, + kProto_UDPLITE = IPPROTO_UDPLITE, } Protocol; static inline const char *protoName(const unsigned proto) @@ -82,6 +83,7 @@ static inline const char *protoName(const unsigned proto) case kProto_TCP: return "TCP"; case kProto_DCCP: return "DCCP"; case kProto_UDP: return "UDP"; + case kProto_UDPLITE: return "UDP-Lite"; default: return "(unknown)"; } } @@ -90,6 +92,7 @@ static inline unsigned sockType(const Protocol p) { switch (p) { case kProto_TCP: return SOCK_STREAM; + case kProto_UDPLITE: /* fall through */ case kProto_UDP: return SOCK_DGRAM; case kProto_DCCP: return SOCK_DCCP; } @@ -97,7 +100,7 @@ static inline unsigned sockType(const Protocol p) static inline bool is_connectionless(const Protocol p) { - return p == kProto_UDP; + return p == kProto_UDP || p == kProto_UDPLITE; } // server/client mode @@ -198,6 +201,7 @@ typedef struct thread_Settings { // chars char mFormat; // -f int mTTL; // -T + int cscov; // -u (partial csums) char *congAlgo; // -A char pad1[2]; // structs or miscellaneous diff --git a/include/headers.h b/include/headers.h index 0ef1c2e..05d05c3 100644 --- a/include/headers.h +++ b/include/headers.h @@ -163,4 +163,15 @@ typedef uintmax_t max_size_t; #ifndef SOL_DCCP #define SOL_DCCP 269 /* include/linux/socket.h */ #endif + +/* UDP-Lite specific definitions and includes */ +#ifdef IPPROTO_UDPLITE +#include +#else +#define IPPROTO_UDPLITE 136 +#define SOL_UDPLITE 136 + +#define UDPLITE_SEND_CSCOV 10 +#define UDPLITE_RECV_CSCOV 11 +#endif #endif /* HEADERS_H */ diff --git a/include/version.h b/include/version.h index 1e65913..ccfa57b 100644 --- a/include/version.h +++ b/include/version.h @@ -1,2 +1,2 @@ -#define IPERF_VERSION "2.0.2 with support for DCCP and TCP CC" +#define IPERF_VERSION "2.0.2 with support for DCCP, UDP-Lite, and TCP CC" #define IPERF_VERSION_DATE "20th Jan 2009" diff --git a/src/Locale.c b/src/Locale.c index cc02522..cd05ba5 100644 --- a/src/Locale.c +++ b/src/Locale.c @@ -78,8 +78,9 @@ Client/Server:\n\ -l, --len #[KM] length of buffer to read or write (default 8 KB)\n\ -m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)\n\ -p, --port # server port to listen on/connect to\n\ - -u, --udp use UDP as transport protocol\n\ - -d, --dccp use DCCP as transport protocol\n\ + -u, --udp use UDP as transport; no argument may follow\n\ + -u --udplite # use UDP-Lite as transport; arg: cscov (0=full coverage)\n\ + -d, --dccp use DCCP as transport\n\ -w, --window #[KM] TCP window size (socket buffer size)\n\ -A, --algorithm set TCP congestion control algorithm\n\ -B, --bind bind to , an interface or multicast address\n\ @@ -94,7 +95,7 @@ Server specific:\n\ -D, --daemon run the server as a daemon\n\ \n\ Client specific:\n\ - -b, --bandwidth #[KM] for UDP/DCCP, bandwidth to send at in bits/sec\n\ + -b, --bandwidth #[KM] for UDP(-Lite)/DCCP, bandwidth to send at in bits/sec\n\ (default 1 Mbit/sec, implies -u)\n\ -c, --client run in client mode, connecting to \n\ -2, --dualtest Do a bidirectional test simultaneously\n\ diff --git a/src/PerfSocket.cpp b/src/PerfSocket.cpp index 63e97ff..1c3a779 100644 --- a/src/PerfSocket.cpp +++ b/src/PerfSocket.cpp @@ -157,6 +157,18 @@ void SetSocketOptions( thread_Settings *inSettings ) &val, len ); WARN_errno( rc == SOCKET_ERROR, "setsockopt DCCP_SOCKOPT_SERVICE" ); } + // UDP-Lite specific options + if ( inSettings->mProtocol == kProto_UDPLITE ) { + /* we set the checksum coverage for both directions */ + rc = setsockopt(inSettings->mSock, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, + &inSettings->cscov, len); + WARN_errno(rc == SOCKET_ERROR, "setsockopt UDPLITE_SEND_CSCOV"); + + rc = setsockopt(inSettings->mSock, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, + &inSettings->cscov, len); + + WARN_errno(rc == SOCKET_ERROR, "setsockopt UDPLITE_RECV_CSCOV"); + } // reuse the address, so we can run if a former server was killed off if (inSettings->mThreadMode == kMode_Listener) { diff --git a/src/Settings.cpp b/src/Settings.cpp index 15b5ccd..3cb619f 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -101,6 +101,7 @@ const struct option long_options[] = {"server", no_argument, NULL, 's'}, {"time", required_argument, NULL, 't'}, {"udp", no_argument, NULL, 'u'}, +{"udplite", required_argument, NULL, 'u'}, {"version", no_argument, NULL, 'v'}, {"window", required_argument, NULL, 'w'}, {"reportexclude", required_argument, NULL, 'x'}, @@ -174,7 +175,7 @@ const struct option env_options[] = #define SHORT_OPTIONS() const char short_options[] = - "12b::c:df:hi:j:l:mn:o:p:rst:uvw:x:y:A:B:CDF:IJ:L:M:NP:RS:T:UV:W"; + "12b::c:df:hi:j:l:mn:o:p:rst:u::vw:x:y:A:B:CDF:IJ:L:M:NP:RS:T:UV:W"; /* ------------------------------------------------------------------- * defaults @@ -472,8 +473,16 @@ void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtS mExtSettings->mAmount = (int) (atof( optarg ) * 100.0); break; - case 'u': // UDP instead of TCP - mExtSettings->mProtocol = kProto_UDP; + case 'u': // UDP(-Lite) instead of TCP + if (optarg) { + mExtSettings->mProtocol = kProto_UDPLITE; + // Set partial checksum coverage: + // - 0 means entire datagram, + // - 1..7 is illegal and will be rounded up to 8; + // - 8 and greater mean genuine partial coverage. + mExtSettings->cscov = atoi(optarg); + } else + mExtSettings->mProtocol = kProto_UDP; setPacketOriented(mExtSettings); // if -b has already been processed, UDP rate will diff --git a/src/main.cpp b/src/main.cpp index a69fd0e..d15e5a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,6 +149,7 @@ int main( int argc, char **argv ) { if (isPacketOriented(ext_gSettings) && !(ext_gSettings->mProtocol == kProto_UDP || + ext_gSettings->mProtocol == kProto_UDPLITE || ext_gSettings->mProtocol == kProto_DCCP )) die("Can't use packet-oriented mode with these settings."); -- 2.39.2