]> sjero.net Git - iperf/blob - include/Settings.hpp
Add a --bindport option to specify the client source port
[iperf] / include / Settings.hpp
1 /*--------------------------------------------------------------- 
2  * Copyright (c) 1999,2000,2001,2002,2003                              
3  * The Board of Trustees of the University of Illinois            
4  * All Rights Reserved.                                           
5  *--------------------------------------------------------------- 
6  * Permission is hereby granted, free of charge, to any person    
7  * obtaining a copy of this software (Iperf) and associated       
8  * documentation files (the "Software"), to deal in the Software  
9  * without restriction, including without limitation the          
10  * rights to use, copy, modify, merge, publish, distribute,        
11  * sublicense, and/or sell copies of the Software, and to permit     
12  * persons to whom the Software is furnished to do
13  * so, subject to the following conditions: 
14  *
15  *     
16  * Redistributions of source code must retain the above 
17  * copyright notice, this list of conditions and 
18  * the following disclaimers. 
19  *
20  *     
21  * Redistributions in binary form must reproduce the above 
22  * copyright notice, this list of conditions and the following 
23  * disclaimers in the documentation and/or other materials 
24  * provided with the distribution. 
25  * 
26  *     
27  * Neither the names of the University of Illinois, NCSA, 
28  * nor the names of its contributors may be used to endorse 
29  * or promote products derived from this Software without
30  * specific prior written permission. 
31  * 
32  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
33  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
34  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
35  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT 
36  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
37  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
38  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
39  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
40  * ________________________________________________________________
41  * National Laboratory for Applied Network Research 
42  * National Center for Supercomputing Applications 
43  * University of Illinois at Urbana-Champaign 
44  * http://www.ncsa.uiuc.edu
45  * ________________________________________________________________ 
46  *
47  * Settings.hpp
48  * by Mark Gates <mgates@nlanr.net>
49  * &  Ajay Tirumala <tirumala@ncsa.uiuc.edu>
50  * -------------------------------------------------------------------
51  * Stores and parses the initial values for all the global variables.
52  * -------------------------------------------------------------------
53  * headers
54  * uses
55  *   <stdlib.h>
56  *   <assert.h>
57  * ------------------------------------------------------------------- */
58
59 #ifndef SETTINGS_H
60 #define SETTINGS_H
61
62 #include "headers.h"
63 #include "Thread.h"
64
65 /* -------------------------------------------------------------------
66  * constants
67  * ------------------------------------------------------------------- */
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71
72 // Convention: odd=connection-oriented, even=connection-less
73 typedef enum Protocol {
74         kProto_TCP     = IPPROTO_TCP,
75         kProto_DCCP    = IPPROTO_DCCP,
76         kProto_UDP     = IPPROTO_UDP,
77         kProto_UDPLITE = IPPROTO_UDPLITE,
78 } Protocol;
79
80 static inline const char *protoName(const unsigned proto)
81 {
82         switch(proto) {
83         case kProto_TCP:     return "TCP";
84         case kProto_DCCP:    return "DCCP";
85         case kProto_UDP:     return "UDP";
86         case kProto_UDPLITE: return "UDP-Lite";
87         default:             return "(unknown)";
88         }
89 }
90
91 static inline unsigned sockType(const Protocol p)
92 {
93         switch (p) {
94         case kProto_TCP:        return SOCK_STREAM;
95         case kProto_UDPLITE:    /* fall through */
96         case kProto_UDP:        return SOCK_DGRAM;
97         case kProto_DCCP:       return SOCK_DCCP;
98         }
99 }
100
101 static inline bool is_connectionless(const Protocol p)
102 {
103         return p == kProto_UDP || p == kProto_UDPLITE;
104 }
105
106 // server/client mode
107 typedef enum ThreadMode {
108     kMode_Unknown = 0,
109     kMode_Server,
110     kMode_Client,
111     kMode_Reporter,
112     kMode_Listener
113 } ThreadMode;
114
115 // report mode
116 typedef enum ReportMode {
117     kReport_Default = 0,
118     kReport_CSV,
119     //kReport_XML,
120     kReport_MAXIMUM
121 } ReportMode;
122
123 // test mode
124 typedef enum TestMode {
125     kTest_Normal = 0,
126     kTest_DualTest,
127     kTest_TradeOff,
128     kTest_Unknown
129 } TestMode;
130
131 #include "Reporter.h"
132 /*
133  * The thread_Settings is a structure that holds all
134  * options for a given execution of either a client
135  * or server. By using this structure rather than
136  * a global structure or class we can have multiple
137  * clients or servers running with different settings.
138  * In version 2.0 and above this structure contains 
139  * all the information needed for a thread to execute
140  * and contains only C elements so it can be manipulated
141  * by either C or C++.
142  */
143 typedef struct thread_Settings {
144     // Pointers
145     char*  mFileName;               // -F
146     char*  mHost;                   // -c
147     char*  mLocalhost;              // -B
148     char*  mOutputFileName;         // -o
149     FILE*  Extractor_file;
150     ReportHeader*  reporthdr;
151     MultiHeader*   multihdr;
152     struct thread_Settings *runNow;
153     struct thread_Settings *runNext;
154     // int's
155     int mThreads;                   // -P
156     int mTOS;                       // -S
157     int mSock;                      // socket descriptor
158     int mSockAF;                    // type of @mSock
159     int Extractor_size;
160     int mBufLen;                    // -l
161     int mMSS;                       // -M
162     int mWinSize;                    // -w
163     int mCCID;                          // -Z
164     int mBindPort;                      // -O
165     /*   flags is a BitMask of old bools
166         bool   mBufLenSet;              // -l
167         bool   mCompat;                 // -C
168         bool   mDaemon;                 // -D
169         bool   mDomain;                 // -V
170         bool   mFileInput;              // -F or -I
171         bool   mNodelay;                // -N
172         bool   mPrintMSS;               // -m
173         bool   mRemoveService;          // -R
174         bool   mStdin;                  // -I
175         bool   mStdout;                 // -o
176         bool   mSuggestWin;             // -W
177         bool   mUDP;                    // -u
178         bool   mMode_time;
179         bool   mReportSettings;
180         bool   mMulticast;
181         bool   mNoSettingsReport;       // -x s
182         bool   mNoConnectionReport;     // -x c
183         bool   mNoDataReport;           // -x d
184         bool   mNoServerReport;         // -x 
185         bool   mNoMultReport;           // -x m
186         bool   mSinlgeClient;           // -1 */
187     int flags;
188     Protocol   mProtocol;
189
190     // enums (which should be special int's)
191     ThreadMode mThreadMode;         // -s or -c
192     ReportMode mReportMode;
193     TestMode   mMode;               // -r or -d
194     // Hopefully int64_t's
195     max_size_t mDgramRate;          // -b
196     max_size_t mAmount;             // -n or -t
197     // doubles
198     double mInterval;               // -i
199     // shorts
200     unsigned short mListenPort;     // -L
201     unsigned short mPort;           // -p
202     unsigned short mMcastIface;     // -j or -J
203     // chars
204     char   mFormat;                 // -f
205     int    mTTL;                    // -T
206     int    cscov;                   // -u (partial csums)
207     char  *congAlgo;                // -A
208     char pad1[2];
209     // structs or miscellaneous
210     struct sockaddr_storage peer;   // remote part of socket
211     struct sockaddr_storage local;  // local part of socket
212     nthread_t mTID;
213 } thread_Settings;
214
215 /*
216  * Due to the use of thread_Settings in C and C++
217  * we are unable to use bool values. To provide
218  * the functionality of bools we use the following
219  * bitmask over an assumed 32 bit int. This will
220  * work fine on 64bit machines we will just be ignoring
221  * the upper 32bits.
222  *
223  * To add a flag simply define it as the next bit then
224  * add the 3 support functions below.
225  */
226 #define FLAG_BUFLENSET      0x00000001
227 #define FLAG_COMPAT         0x00000002
228 #define FLAG_DAEMON         0x00000004
229 #define FLAG_DOMAIN         0x00000008
230 #define FLAG_FILEINPUT      0x00000010
231 #define FLAG_NODELAY        0x00000020
232 #define FLAG_PRINTMSS       0x00000040
233 #define FLAG_REMOVESERVICE  0x00000080
234 #define FLAG_STDIN          0x00000100
235 #define FLAG_STDOUT         0x00000200
236 #define FLAG_SUGGESTWIN     0x00000400
237 #define FLAG_MODETIME       0x00001000
238 #define FLAG_REPORTSETTINGS 0x00002000
239 #define FLAG_MULTICAST      0x00004000
240 #define FLAG_NOSETTREPORT   0x00008000
241 #define FLAG_NOCONNREPORT   0x00010000
242 #define FLAG_NODATAREPORT   0x00020000
243 #define FLAG_NOSERVREPORT   0x00040000
244 #define FLAG_NOMULTREPORT   0x00080000
245 #define FLAG_SINGLECLIENT   0x00100000
246 #define FLAG_SINGLEUDP      0x00200000
247 #define FLAG_PACKETORIENTED 0x01000000
248
249
250 #define isBuflenSet(settings)      ((settings->flags & FLAG_BUFLENSET) != 0)
251 #define isCompat(settings)         ((settings->flags & FLAG_COMPAT) != 0)
252 #define isDaemon(settings)         ((settings->flags & FLAG_DAEMON) != 0)
253 #define isIPV6(settings)           ((settings->flags & FLAG_DOMAIN) != 0)
254 #define isFileInput(settings)      ((settings->flags & FLAG_FILEINPUT) != 0)
255 #define isNoDelay(settings)        ((settings->flags & FLAG_NODELAY) != 0)
256 #define isPrintMSS(settings)       ((settings->flags & FLAG_PRINTMSS) != 0)
257 #define isRemoveService(settings)  ((settings->flags & FLAG_REMOVESERVICE) != 0)
258 #define isSTDIN(settings)          ((settings->flags & FLAG_STDIN) != 0)
259 #define isSTDOUT(settings)         ((settings->flags & FLAG_STDOUT) != 0)
260 #define isSuggestWin(settings)     ((settings->flags & FLAG_SUGGESTWIN) != 0)
261 #define isModeTime(settings)       ((settings->flags & FLAG_MODETIME) != 0)
262 #define isReport(settings)         ((settings->flags & FLAG_REPORTSETTINGS) != 0)
263 #define isMulticast(settings)      ((settings->flags & FLAG_MULTICAST) != 0)
264 // Active Low for Reports
265 #define isSettingsReport(settings) ((settings->flags & FLAG_NOSETTREPORT) == 0)
266 #define isConnectionReport(settings)  ((settings->flags & FLAG_NOCONNREPORT) == 0)
267 #define isDataReport(settings)     ((settings->flags & FLAG_NODATAREPORT) == 0)
268 #define isServerReport(settings)   ((settings->flags & FLAG_NOSERVREPORT) == 0)
269 #define isMultipleReport(settings) ((settings->flags & FLAG_NOMULTREPORT) == 0)
270 // end Active Low
271 #define isSingleClient(settings)   ((settings->flags & FLAG_SINGLECLIENT) != 0)
272 #define isSingleUDP(settings)      ((settings->flags & FLAG_SINGLEUDP) != 0)
273 #define isConnectionLess(settings) is_connectionless((settings)->mProtocol)
274 #define isPacketOriented(settings) (((settings)->flags & FLAG_PACKETORIENTED) != 0)
275
276 #define setBuflenSet(settings)     settings->flags |= FLAG_BUFLENSET
277 #define setCompat(settings)        settings->flags |= FLAG_COMPAT
278 #define setDaemon(settings)        settings->flags |= FLAG_DAEMON
279 #define setIPV6(settings)          settings->flags |= FLAG_DOMAIN
280 #define setFileInput(settings)     settings->flags |= FLAG_FILEINPUT
281 #define setNoDelay(settings)       settings->flags |= FLAG_NODELAY
282 #define setPrintMSS(settings)      settings->flags |= FLAG_PRINTMSS
283 #define setRemoveService(settings) settings->flags |= FLAG_REMOVESERVICE
284 #define setSTDIN(settings)         settings->flags |= FLAG_STDIN
285 #define setSTDOUT(settings)        settings->flags |= FLAG_STDOUT
286 #define setSuggestWin(settings)    settings->flags |= FLAG_SUGGESTWIN
287 #define setModeTime(settings)      settings->flags |= FLAG_MODETIME
288 #define setReport(settings)        settings->flags |= FLAG_REPORTSETTINGS
289 #define setMulticast(settings)     settings->flags |= FLAG_MULTICAST
290 #define setNoSettReport(settings)  settings->flags |= FLAG_NOSETTREPORT
291 #define setNoConnReport(settings)  settings->flags |= FLAG_NOCONNREPORT
292 #define setNoDataReport(settings)  settings->flags |= FLAG_NODATAREPORT
293 #define setNoServReport(settings)  settings->flags |= FLAG_NOSERVREPORT
294 #define setNoMultReport(settings)  settings->flags |= FLAG_NOMULTREPORT
295 #define setSingleClient(settings)  settings->flags |= FLAG_SINGLECLIENT
296 #define setSingleUDP(settings)     settings->flags |= FLAG_SINGLEUDP
297 #define setPacketOriented(settings) settings->flags |= FLAG_PACKETORIENTED
298
299 #define unsetBuflenSet(settings)   settings->flags &= ~FLAG_BUFLENSET
300 #define unsetCompat(settings)      settings->flags &= ~FLAG_COMPAT
301 #define unsetDaemon(settings)      settings->flags &= ~FLAG_DAEMON
302 #define unsetIPV6(settings)        settings->flags &= ~FLAG_DOMAIN
303 #define unsetFileInput(settings)   settings->flags &= ~FLAG_FILEINPUT
304 #define unsetNoDelay(settings)     settings->flags &= ~FLAG_NODELAY
305 #define unsetPrintMSS(settings)    settings->flags &= ~FLAG_PRINTMSS
306 #define unsetRemoveService(settings)  settings->flags &= ~FLAG_REMOVESERVICE
307 #define unsetSTDIN(settings)       settings->flags &= ~FLAG_STDIN
308 #define unsetSTDOUT(settings)      settings->flags &= ~FLAG_STDOUT
309 #define unsetSuggestWin(settings)  settings->flags &= ~FLAG_SUGGESTWIN
310 #define unsetModeTime(settings)    settings->flags &= ~FLAG_MODETIME
311 #define unsetReport(settings)      settings->flags &= ~FLAG_REPORTSETTINGS
312 #define unsetMulticast(settings)   settings->flags &= ~FLAG_MULTICAST
313 #define unsetNoSettReport(settings)   settings->flags &= ~FLAG_NOSETTREPORT
314 #define unsetNoConnReport(settings)   settings->flags &= ~FLAG_NOCONNREPORT
315 #define unsetNoDataReport(settings)   settings->flags &= ~FLAG_NODATAREPORT
316 #define unsetNoServReport(settings)   settings->flags &= ~FLAG_NOSERVREPORT
317 #define unsetNoMultReport(settings)   settings->flags &= ~FLAG_NOMULTREPORT
318 #define unsetSingleClient(settings)   settings->flags &= ~FLAG_SINGLECLIENT
319 #define unsetSingleUDP(settings)      settings->flags &= ~FLAG_SINGLEUDP
320 #define unsetPacketOriented(settings) settings->flags &= ~FLAG_PACKETORIENTED
321
322
323 #define HEADER_VERSION1 0x80000000
324 #define RUN_NOW         0x00000001
325
326 /*
327  * Datagram record for record-oriented applications
328  * used to reference the 4 byte ID number we place in UDP datagrams
329  * use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90)
330  */
331 typedef struct dgram_record {
332 #ifdef HAVE_INT32_T
333     int32_t id;
334     u_int32_t tv_sec;
335     u_int32_t tv_usec;
336 #else
337     signed   int id      : 32;
338     unsigned int tv_sec  : 32;
339     unsigned int tv_usec : 32;
340 #endif
341 } dgram_record;
342
343 /*
344  * The client_hdr structure is sent from clients
345  * to servers to alert them of things that need
346  * to happen. Order must be perserved in all 
347  * future releases for backward compatibility.
348  * 1.7 has flags, numThreads, mPort, and bufferlen
349  */
350 typedef struct client_hdr {
351
352 #ifdef HAVE_INT32_T
353
354     /*
355      * flags is a bitmap for different options
356      * the most significant bits are for determining
357      * which information is available. So 1.7 uses
358      * 0x80000000 and the next time information is added
359      * the 1.7 bit will be set and 0x40000000 will be
360      * set signifying additional information. If no 
361      * information bits are set then the header is ignored.
362      * The lowest order diferentiates between dualtest and
363      * tradeoff modes, wheither the speaker needs to start 
364      * immediately or after the audience finishes.
365      */
366     int32_t flags;
367     int32_t numThreads;
368     int32_t mPort;
369     int32_t bufferlen;
370     int32_t mWinBand;
371     int32_t mAmount;
372 #else
373     signed int flags      : 32;
374     signed int numThreads : 32;
375     signed int mPort      : 32;
376     signed int bufferlen  : 32;
377     signed int mWinBand   : 32;
378     signed int mAmount    : 32;
379 #endif
380 } client_hdr;
381
382 /*
383  * The server_hdr structure facilitates the server
384  * report of jitter and loss on the client side.
385  * It piggy_backs on the existing clear to close
386  * packet.
387  */
388 typedef struct server_hdr {
389
390 #ifdef HAVE_INT32_T
391
392     /*
393      * flags is a bitmap for different options
394      * the most significant bits are for determining
395      * which information is available. So 1.7 uses
396      * 0x80000000 and the next time information is added
397      * the 1.7 bit will be set and 0x40000000 will be
398      * set signifying additional information. If no 
399      * information bits are set then the header is ignored.
400      */
401     int32_t flags;
402     int32_t total_len1;
403     int32_t total_len2;
404     int32_t stop_sec;
405     int32_t stop_usec;
406     int32_t error_cnt;
407     int32_t outorder_cnt;
408     int32_t datagrams;
409     int32_t jitter1;
410     int32_t jitter2;
411 #else
412     signed int flags        : 32;
413     signed int total_len1   : 32;
414     signed int total_len2   : 32;
415     signed int stop_sec     : 32;
416     signed int stop_usec    : 32;
417     signed int error_cnt    : 32;
418     signed int outorder_cnt : 32;
419     signed int datagrams    : 32;
420     signed int jitter1      : 32;
421     signed int jitter2      : 32;
422 #endif
423
424 } server_hdr;
425
426     // set to defaults
427     void Settings_Initialize( thread_Settings* main );
428
429     // copy structure
430     void Settings_Copy( thread_Settings* from, thread_Settings** into );
431
432     // free associated memory
433     void Settings_Destroy( thread_Settings *mSettings );
434
435     // parse settings from user's environment variables
436     void Settings_ParseEnvironment( thread_Settings *mSettings );
437
438     // parse settings from app's command line
439     void Settings_ParseCommandLine( int argc, char **argv, thread_Settings *mSettings );
440
441     // convert to lower case for [KMG]bits/sec
442     void Settings_GetLowerCaseArg(const char *,char *);
443
444     // convert to upper case for [KMG]bytes/sec
445     void Settings_GetUpperCaseArg(const char *,char *);
446
447     // generate settings for listener instance
448     void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener);
449
450     // generate settings for speaker instance
451     void Settings_GenerateClientSettings( thread_Settings *server, 
452                                           thread_Settings **client,
453                                           client_hdr *hdr );
454
455     // generate client header for server
456     void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr );
457
458 #ifdef __cplusplus
459 } /* end extern "C" */
460 #endif
461
462 #endif // SETTINGS_H