1 /* 2 ** $Id: owamp.h 1089 2012-03-27 02:23:05Z boote $ 3 */ 4 /************************************************************************ 5 * * 6 * Copyright (C) 2002 * 7 * Internet2 * 8 * All Rights Reserved * 9 * * 10 ************************************************************************/ 11 /* 12 ** File: owamp.h 13 ** 14 ** Author: Jeff W. Boote 15 ** Anatoly Karp 16 ** 17 ** Date: Wed Mar 20 11:10:33 2002 18 ** 19 ** Description: 20 ** This header file describes the owamp API. The owamp API is intended 21 ** to provide a portable layer for implementing the owamp protocol. 22 */ 23 #ifndef OWAMP_H 24 #define OWAMP_H 25 26 /* 27 * Portablility sanity checkes. 28 */ 29 #if HAVE_CONFIG_H 30 #undef PACKAGE_BUGREPORT 31 #undef PACKAGE_NAME 32 #undef PACKAGE_STRING 33 #undef PACKAGE_TARNAME 34 #undef PACKAGE_VERSION 35 36 #include <owamp/config.h> 37 #endif /* HAVE_CONFIG_H */ 38 39 #if !HAVE_ERRNO_H || !HAVE_NETDB_H || !HAVE_STDLIB_H || !HAVE_SYS_PARAM_H 40 #error Missing Header! 41 #endif 42 43 #if !HAVE_GETADDRINFO || !HAVE_SOCKET 44 #error Missing needed networking capabilities! (getaddrinfo and socket) 45 #endif 46 47 48 #if !HAVE_MALLOC || !HAVE_MEMSET 49 #error Missing needed memory functions! 50 #endif 51 52 #ifndef HAVE___ATTRIBUTE__ 53 #define __attribute__(x) 54 #endif 55 56 #if defined HAVE_DECL_FSEEKO && !HAVE_DECL_FSEEKO 57 #define fseeko(a,b,c) fseek(a,b,c) 58 #endif 59 60 #include <limits.h> 61 #include <sys/types.h> 62 #ifdef HAVE_INTTYPES_H 63 #include <inttypes.h> 64 #endif 65 #include <sys/stat.h> 66 #include <sys/time.h> 67 #include <sys/socket.h> 68 /* sys/param.h defines MIN/MAX on some systems... */ 69 #ifdef MIN 70 #undef MIN 71 #endif 72 #ifdef MAX 73 #undef MAX 74 #endif 75 #include <sys/param.h> 76 #include <netdb.h> 77 #include <time.h> 78 79 /* Deal with needed inttypes.h - hopefully these were already defined... */ 80 #ifndef PRIuPTR 81 #if SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG 82 #define PRIuPTR "lu" 83 #elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG_LONG 84 #define PRIuPTR "llu" 85 #else 86 #error "Need real PRIuPTR defined by inttypes.h on this system" 87 #endif 88 #endif /* PRIuPTR */ 89 90 #ifndef PRIu64 91 #if SIZEOF_UINT64_T == SIZEOF_UNSIGNED_LONG 92 #define PRIu64 "lu" 93 #elif SIZEOF_UINT64_T == SIZEOF_UNSIGNED_LONG_LONG 94 #define PRIu64 "llu" 95 #else 96 #error "Need real PRIu64 defined by inttypes.h on this system" 97 #endif 98 #endif /* PRIu64 */ 99 100 #ifndef False 101 #define False (0) 102 #endif 103 #ifndef True 104 #define True (!False) 105 #endif 106 107 #ifndef MIN 108 #define MIN(a,b) ((a<b)?a:b) 109 #endif 110 #ifndef MAX 111 #define MAX(a,b) ((a>b)?a:b) 112 #endif 113 114 #include <I2util/util.h> 115 116 /* 117 * Filename/path component macros used by various parts of owamp. 118 */ 119 #ifndef OWP_PATH_SEPARATOR 120 #define OWP_PATH_SEPARATOR "/" 121 #endif 122 #ifndef OWP_PATH_SEPARATOR_LEN 123 #define OWP_PATH_SEPARATOR_LEN 1 124 #endif 125 #ifndef OWP_FILE_EXT 126 #define OWP_FILE_EXT ".owp" 127 #endif 128 129 /* 130 * The ascii decimal encoding of the 64 bit timestamps takes this many 131 * chars. Log(2^64) 132 * 133 * fmt indicates 0 padding, 20 significant digits. 134 */ 135 #ifndef OWP_TSTAMPFMT 136 #define OWP_TSTAMPFMT "%020" PRIu64 137 #endif 138 139 #ifndef OWP_TSTAMPCHARS 140 #define OWP_TSTAMPCHARS 20 141 #endif 142 143 /* 144 * Char used between start_end.owp files. 145 */ 146 #ifndef OWP_NAME_SEP 147 #define OWP_NAME_SEP "_" 148 #endif 149 150 151 #include <owamp/rijndael-api-fst.h> 152 153 /* Default mode offered by the server */ 154 #define OWP_DEFAULT_OFFERED_MODE (OWP_MODE_OPEN|OWP_MODE_AUTHENTICATED|OWP_MODE_ENCRYPTED) 155 156 /* 157 * IANA 'blessed' port number for OWAMP 158 */ 159 #define OWP_CONTROL_SERVICE_NAME "861" 160 161 /* 162 * Default value to use for the listen backlog. We pick something large 163 * and let the OS truncate it if it isn't willing to do that much. 164 */ 165 #define OWP_LISTEN_BACKLOG (64) 166 167 /* 168 * OWPNum64 is interpreted as 32bits of "seconds" and 32bits of 169 * "fractional seconds". 170 * The byte ordering is defined by the hardware for this value. 4 MSBytes are 171 * seconds, 4 LSBytes are fractional. Each set of 4 Bytes is pulled out 172 * via shifts/masks as a 32bit unsigned int when needed independently. 173 * 174 * sync/multiplier/scale are defined as in Section 5.1 of 175 * draft-ietf-ippm-owdp-05.txt: 176 * If sync is non-zero, then the party generating the timestamp claims to 177 * have an external source of synchronization to UTC. 178 * multiplier and scale are used to indicate the estimated error of 179 * owptime. 180 * They are interpreted as follows: 181 * multiplier*(2^(-32))*(2^Scale) 182 * 183 * (implementor note) 184 * Effectively, this breaks down such that if Scale is 0, then the multiplier 185 * is the error in the same scale as the fractional seconds of owptime. 186 * Therefore, for "real" errors greater than an 8 bit number at that scale 187 * the value can just be right shifted until it fits into an 8 bit integer, 188 * and the number of shifts would indicate the "Scale" value. 189 */ 190 typedef uint64_t OWPNum64; 191 192 /* 193 * Arithmetic/Conversion functions on OWPNum64 numbers. 194 */ 195 196 /* 197 * These macros should be used instead of directly using 198 * arithmetic on these types in the event that the underlying 199 * type is changed from an uint64_t to some kind of structure. 200 * 201 */ 202 #define OWPNum64Add(x,y) (x+y) 203 #define OWPNum64Sub(x,y) (x-y) 204 #define OWPNum64Cmp(x,y) ((x<y)?\ 205 (-1):\ 206 ((x>y)?1:0)) 207 #define OWPNum64Diff(x,y) ((x>y)?\ 208 (x-y):\ 209 (y-x)) 210 #define OWPNum64Min(x,y) MIN(x,y) 211 #define OWPNum64Max(x,y) MAX(x,y) 212 213 extern OWPNum64 214 OWPNum64Mult( 215 OWPNum64 x, 216 OWPNum64 y 217 ); 218 219 extern OWPNum64 220 OWPULongToNum64( 221 uint32_t from 222 ); 223 224 225 extern void 226 OWPNum64ToTimeval( 227 struct timeval *to, 228 OWPNum64 from 229 ); 230 231 extern void 232 OWPTimevalToNum64( 233 OWPNum64 *to, 234 struct timeval *from 235 ); 236 237 extern void 238 OWPNum64ToTimespec( 239 struct timespec *to, 240 OWPNum64 from 241 ); 242 243 extern void 244 OWPTimespecToNum64( 245 OWPNum64 *to, 246 struct timespec *from 247 ); 248 249 extern double 250 OWPNum64ToDouble( 251 OWPNum64 from 252 ); 253 254 extern OWPNum64 255 OWPDoubleToNum64( 256 double from 257 ); 258 259 extern OWPNum64 260 OWPUsecToNum64( 261 uint32_t usec 262 ); 263 264 /* 265 * These structures are opaque to the API user. 266 * They are used to maintain state internal to the library. 267 */ 268 typedef struct OWPContextRec *OWPContext; 269 typedef struct OWPControlRec *OWPControl; 270 271 /* 272 * Timestamp related types and structures needed throughout. 273 */ 274 275 typedef struct OWPTimeStampRec{ 276 OWPNum64 owptime; 277 uint8_t sync; 278 uint8_t multiplier; 279 uint8_t scale; 280 } OWPTimeStamp; 281 282 283 /* Codes for returning error severity and type. */ 284 /* values are mapped to syslog "priorities" we want to use. */ 285 typedef enum { 286 OWPErrFATAL=3, 287 OWPErrWARNING=4, 288 OWPErrINFO=6, 289 OWPErrDEBUG=7, 290 OWPErrOK=8 291 } OWPErrSeverity; 292 293 typedef enum { 294 OWPErrUNKNOWN=0, 295 OWPErrPOLICY, 296 OWPErrINVALID, 297 OWPErrUNSUPPORTED 298 } OWPErrType; 299 300 301 /* 302 * Valid values for "accept" - this will be added to for the purpose of 303 * enumerating the reasons for rejecting a session, or early termination 304 * of a test session. 305 */ 306 typedef enum{ 307 OWP_CNTRL_INVALID=-1, /* No value yet */ 308 OWP_CNTRL_ACCEPT=0, /* ok */ 309 OWP_CNTRL_REJECT=1, /* reject for any reason */ 310 OWP_CNTRL_FAILURE=2, /* internal failure */ 311 OWP_CNTRL_UNSUPPORTED=3, /* request functionality unsupported */ 312 OWP_CNTRL_UNAVAILABLE_PERM=4, /* Permanent resource limitation */ 313 OWP_CNTRL_UNAVAILABLE_TEMP=5 /* Temporary resource limitation */ 314 } OWPAcceptType; 315 316 typedef intptr_t OWPBoolean; 317 typedef uint8_t OWPSID[16]; 318 typedef uint8_t OWPSequence[4]; 319 320 /* 321 * technically the username in the client greeting message can have uint8_t 322 * but this implementation limits it to a valid "char" type. 323 */ 324 #define OWP_USERID_LEN 80 325 typedef char OWPUserID[OWP_USERID_LEN+1]; /* add 1 for '\0' */ 326 327 328 #define OWP_MODE_UNDEFINED (0) 329 #define OWP_MODE_OPEN (01) 330 #define OWP_MODE_AUTHENTICATED (02) 331 #define OWP_MODE_ENCRYPTED (04) 332 #define OWP_MODE_DOCIPHER (OWP_MODE_AUTHENTICATED|OWP_MODE_ENCRYPTED) 333 334 typedef uint32_t OWPSessionMode; 335 336 typedef enum { 337 OWPSlotUnspecifiedType = -1, /* invalid value */ 338 OWPSlotRandExpType = 0, 339 OWPSlotLiteralType = 1 340 } OWPSlotType; 341 342 typedef struct{ 343 OWPSlotType slot_type; 344 OWPNum64 mean; 345 } OWPSlotRandExp; 346 347 typedef struct{ 348 OWPSlotType slot_type; 349 OWPNum64 offset; 350 } OWPSlotLiteral; 351 352 /* 353 * For now - all current slot types are of the exact same format, and 354 * the "time" element can be interpreted as the mean_delay between packets 355 * for the purposes of bandwidth calculations. If that is ever not true, 356 * this type should be removed, and any code that uses it will need to 357 * have a switch statement to do whatever is appropriate for each individual 358 * slot type. 359 */ 360 typedef struct{ 361 OWPSlotType slot_type; 362 OWPNum64 mean_delay; 363 } OWPSlotAny; 364 365 typedef union OWPSlotUnion{ 366 OWPSlotType slot_type; 367 OWPSlotRandExp rand_exp; 368 OWPSlotLiteral literal; 369 OWPSlotAny any; 370 } OWPSlot; 371 372 typedef struct{ 373 OWPNum64 start_time; 374 OWPNum64 loss_timeout; 375 uint32_t typeP; 376 uint32_t packet_size_padding; 377 uint32_t npackets; 378 uint32_t nslots; 379 OWPSlot *slots; 380 } OWPTestSpec; 381 382 typedef uint32_t OWPPacketSizeT; 383 384 /* 385 * an OWPScheduleContextRec is used to maintain state for the schedule 386 * generator. Multiple contexts can be allocated to maintain multiple 387 * "streams" of schedules. 388 */ 389 typedef struct OWPScheduleContextRec *OWPScheduleContext; 390 391 OWPScheduleContext 392 OWPScheduleContextCreate( 393 OWPContext ctx, 394 OWPSID sid, 395 OWPTestSpec *tspec 396 ); 397 398 void 399 OWPScheduleContextFree( 400 OWPScheduleContext sctx 401 ); 402 403 OWPErrSeverity 404 OWPScheduleContextReset( 405 OWPScheduleContext sctx, 406 OWPSID sid, 407 OWPTestSpec *tspec 408 ); 409 410 OWPNum64 411 OWPScheduleContextGenerateNextDelta( 412 OWPScheduleContext sctx 413 ); 414 void 415 OWPScheduleContextFree( 416 OWPScheduleContext sctx 417 ); 418 419 /* 420 * These functions expose the exponential deviates for the exponential 421 * distribution used to generate send schedules. 422 */ 423 typedef struct OWPExpContextRec *OWPExpContext; 424 425 OWPExpContext 426 OWPExpContextCreate( 427 OWPContext ctx, 428 uint8_t seed[16] 429 ); 430 OWPNum64 431 OWPExpContextNext( 432 OWPExpContext exp 433 ); 434 435 void 436 OWPExpContextFree( 437 OWPExpContext exp 438 ); 439 440 441 /* 442 * Error Reporting: 443 * 444 * Notice that this macro expands to multiple statements so it is 445 * imperative that you enclose it's use in {} in single statement 446 * context's such as: 447 * if(test) 448 * OWPError(...); NO,NO,NO,NO! 449 * Instead: 450 * if(test){ 451 * OWPError(...); 452 * } 453 * 454 * 455 * (Sure would be nice if it were possible to to vararg macros...) 456 */ 457 #define OWPError I2ErrLocation_(__FILE__,__DATE__,__LINE__); \ 458 OWPError_ 459 460 /* 461 * Don't call this directly - use the OWPError macro. 462 * Let me repeat. 463 * Don't call this directly - use the OWPError macro. 464 */ 465 extern void 466 OWPError_( 467 OWPContext ctx, 468 OWPErrSeverity severity, 469 OWPErrType etype, 470 const char *fmt, 471 ... 472 ); 473 474 /* 475 * The "context" is used to basically initialize the library. There is no 476 * "global" state - so you can create more than one "context" if you like. 477 * (Well... SIGPIPE is disabled... I suppose that is global.) 478 * 479 * There are specific defaults that can be modified within the context by 480 * calling the OWPContextConfigSet{F,V} function with the following keys and 481 * types. (The key is a string - the type indicates what type of data 482 * will be stored/retrieved using that key. 483 * The 'F' version is for setting/getting functions and the 'V' version 484 * is for values. (The C standard does not allow us to treat them 485 * generically - I suppose I could have exposed a union, but this 486 * seems easier.) 487 */ 488 489 /* 490 * This typedef is used for the "generic" type of all function pointer 491 * types. (void *) is used for the 'value' equivalent. 492 */ 493 494 typedef void (*OWPFunc)(void); 495 496 /* 497 * This type is used to hold a pointer to an integer pointer. That pointer 498 * points at a value that determines if the low/level i/o functions should 499 * return on interrupt. If it is non-zero an interrupt will cause the i/o 500 * routine to fail and return. If it is zero, the low level i/o routine will 501 * ignore the interrupt and restart the i/o. 502 * (this can be used to ignore some signals and return on others.) 503 */ 504 #define OWPInterruptIO "OWPInterruptIO" 505 506 /* 507 * This type is used to hold a pointer to a port-range record. This 508 * record is used to indicate what port ranges should be used for 509 * opening test connections. 510 */ 511 #define OWPTestPortRange "OWPTestPortRange" 512 typedef struct OWPPortRangeRec{ 513 uint16_t low; 514 uint16_t high; 515 } OWPPortRangeRec, *OWPPortRange; 516 517 /* 518 * This type is used to define the function that retrieves the shared 519 * secret from whatever key-store is in use. 520 * It should return True if it is able to returnfill in the key_ret variable that 521 * is passed in from the caller. False if not. If the function returns false, 522 * the caller should check the err_ret value. If OK, then the userid simply 523 * didn't exist - otherwise it indicates an error in the key store mechanism. 524 * 525 * If an application doesn't set this, Encrypted and Authenticated 526 * mode will be disabled. 527 * 528 * The 'pf_free' pointer will be set to the memory block allocated for pf 529 * if the caller needs to free the memory after calling this function. 530 * (Different pass-phrase stores use different memory models. The returned 531 * pf value should NOT be freed directly!) 532 */ 533 #define OWPGetPF "OWPGetPF" 534 typedef OWPBoolean (*OWPGetPFFunc)( 535 OWPContext ctx, 536 const OWPUserID userid, 537 uint8_t **pf, 538 size_t *pf_len, 539 void **pf_free, /* If implementation uses dynamic memory */ 540 OWPErrSeverity *err_ret 541 ); 542 543 /* 544 * This function will be called from OWPControlOpen and OWPServerAccept 545 * to determine if the control connection should be accepted. 546 * It is called after connecting, and after determining the userid. 547 * On failure, value of *err_ret can be inspected: if > OWPErrWARNING, 548 * this means rejection based on policy, otherwise there was an error 549 * in the function itself. 550 * 551 * If an application doesn't set this, all connections will be allowed. 552 */ 553 #define OWPCheckControlPolicy "OWPCheckControlPolicy" 554 typedef OWPBoolean (*OWPCheckControlPolicyFunc)( 555 OWPControl cntrl, 556 OWPSessionMode mode_req, 557 const OWPUserID userid, 558 struct sockaddr *local_sa_addr, 559 struct sockaddr *remote_sa_addr, 560 OWPErrSeverity *err_ret 561 ); 562 563 /* 564 * This function will be called by OWPRequestTestSession if 565 * one of the endpoints of the test is on the localhost. 566 * If err_ret returns OWPErrFATAL, OWPRequestTestSession/OWPProcessTestSession 567 * will not continue, and return OWPErrFATAL as well. 568 * 569 * Only the IP address values will be set in the sockaddr structures - 570 * i.e. port numbers will not be valid. 571 * 572 * If an application doesn't set this, all tests will be allowed. 573 * 574 * The application can use the "closure" pointer to store data that will 575 * be passed onto the Open/Close and TestComplete functions. The intended 576 * purpose of this pointer is to keep track of resources that are "reserved" 577 * from this function - allowing the other functions to "free" or modify 578 * those resource reservations. 579 */ 580 #define OWPCheckTestPolicy "OWPCheckTestPolicy" 581 typedef OWPBoolean (*OWPCheckTestPolicyFunc)( 582 OWPControl cntrl, 583 OWPBoolean local_sender, 584 struct sockaddr *local_sa_addr, 585 struct sockaddr *remote_sa_addr, 586 socklen_t sa_len, 587 OWPTestSpec *test_spec, 588 void **closure, 589 OWPErrSeverity *err_ret 590 ); 591 592 /* 593 * This function will be called by OWPProcessFetchSession to implement 594 * the 'policy' decision if the fetch request should be allowed. 595 * If err_ret returns OWPErrFATAL, OWPProcessFetchSession 596 * will not continue, and return OWPErrFATAL as well. 597 * 598 * Only the IP address values will be set in the sockaddr structures - 599 * i.e. port numbers will not be valid. 600 * 601 * If an application doesn't set this, all data that is buffered 602 * that can be found, will be returned. 603 * 604 * The application can use the "closure" pointer to store data that will 605 * be passed onto the Open/Close and TestComplete functions. The intended 606 * purpose of this pointer is to keep track of resources that are "reserved" 607 * from this function - allowing the other functions to "free" or modify 608 * those resource reservations. 609 * 610 */ 611 #define OWPCheckFetchPolicy "OWPCheckFetchPolicy" 612 typedef OWPBoolean (*OWPCheckFetchPolicyFunc)( 613 OWPControl cntrl, 614 struct sockaddr *local_sa_addr, 615 struct sockaddr *remote_sa_addr, 616 socklen_t sa_len, 617 uint32_t begin, 618 uint32_t end, 619 OWPSID sid, 620 void **closure, 621 OWPErrSeverity *err_ret 622 ); 623 624 /* 625 * This function will be called when a test is "complete". It is used 626 * to free resources that were allocated on behalf of the test including 627 * memory associated with the "closure" pointer itself if necessary. 628 */ 629 #define OWPTestComplete "OWPTestComplete" 630 typedef void (*OWPTestCompleteFunc)( 631 OWPControl cntrl, 632 void *closure, 633 OWPAcceptType aval 634 ); 635 636 /* 637 * This function will be called by the test endpoint initialization 638 * code to open a file for writing. It will also be called by the 639 * fetch-session code to open an existing file to return the data 640 * to an application. (fname_ret is PATH_MAX+1 to include a nul byte.) 641 * (if 642 */ 643 #define OWPOpenFile "OWPOpenFile" 644 typedef FILE* (*OWPOpenFileFunc)( 645 OWPControl cntrl, 646 void *closure, 647 OWPSID sid, 648 char fname_ret[PATH_MAX+1] 649 ); 650 651 /* 652 * This function will be called by the test endpoint "cleanup" code 653 * to indicate that the given fp (from OWPOpenFile) is no longer needed. 654 * This allows the implementation to do it's own cleanup based on policy. 655 * For example, a delete-on-fetch functionality could be implemented here 656 * to delete the given file now that is it no longer needed. 657 */ 658 #define OWPCloseFile "OWPCloseFile" 659 typedef void (*OWPCloseFileFunc)( 660 OWPControl cntrl, 661 void *closure, 662 FILE *fp, 663 OWPAcceptType aval 664 ); 665 666 #ifndef NDEBUG 667 /* 668 * This integer type is used to aid in child-debugging. If OWPChildWait is 669 * set and non-zero forked off endpoints will go into a busy-wait loop to 670 * allow a debugger to attach to the process. (i.e. they will be hung until 671 * attached and the loop variable modified with the debugger. This should 672 * not strictly be needed, but the gdb on many of the test plateforms I 673 * used did not implement the follow-fork-mode option.) This was a quick 674 * fix. (This will not be used if owamp is compiled with -DNDEBUG.) 675 */ 676 #define OWPChildWait "OWPChildWait" 677 #endif 678 679 /* 680 * If this variable is set in the context, send/recv children processes 681 * are directed to detach from the process group. (This is useful to 682 * catch ^C from a shell in the parent process without having the 683 * SIGINT being sent to the children processes. By doing this, it is 684 * possible to gracefully shutdown an owamp test session in response 685 * to SIGINT.) 686 */ 687 #define OWPDetachProcesses "OWPDetachProcesses" 688 689 /* 690 * Set the 'count' value for the pbkdf2 function. 691 */ 692 #define OWPKeyDerivationCount "OWPKeyDerivationCount" 693 694 /* 695 * Set the 'enddelay' (time for a sender to wait after session completion 696 * to actually send the stop session message). 697 * (double ptr) 698 */ 699 #define OWPEndDelay "OWPEndDelay" 700 701 /* 702 * Use IPv4 addresses only. 703 */ 704 #define OWPIPv4Only "OWPIPv4Only" 705 706 /* 707 * Use IPv6 addresses only. 708 */ 709 #define OWPIPv6Only "OWPIPv6Only" 710 711 extern OWPContext 712 OWPContextCreate( 713 I2ErrHandle eh 714 ); 715 716 extern void 717 OWPContextFree( 718 OWPContext ctx 719 ); 720 721 extern I2ErrHandle 722 OWPContextErrHandle( 723 OWPContext ctx 724 ); 725 726 extern OWPBoolean 727 OWPContextConfigSetF( 728 OWPContext ctx, 729 const char *key, 730 OWPFunc func 731 ); 732 733 extern OWPBoolean 734 OWPContextConfigSetV( 735 OWPContext ctx, 736 const char *key, 737 void *value 738 ); 739 740 extern OWPBoolean 741 OWPContextConfigSetU32( 742 OWPContext ctx, 743 const char *key, 744 uint32_t value 745 ); 746 747 extern OWPFunc 748 OWPContextConfigGetF( 749 OWPContext ctx, 750 const char *key 751 ); 752 753 extern void* 754 OWPContextConfigGetV( 755 OWPContext ctx, 756 const char *key 757 ); 758 759 extern OWPBoolean 760 OWPContextConfigGetU32( 761 OWPContext ctx, 762 const char *key, 763 uint32_t *val 764 ); 765 766 extern OWPBoolean 767 OWPContextConfigDelete( 768 OWPContext ctx, 769 const char *key 770 ); 771 772 /* 773 * The following functions are completely analogous to the Context versions 774 * but are used to maintain state information about a particular control 775 * connection. 776 */ 777 extern OWPBoolean 778 OWPControlConfigSetF( 779 OWPControl cntrl, 780 const char *key, 781 OWPFunc func 782 ); 783 784 extern OWPBoolean 785 OWPControlConfigSetV( 786 OWPControl cntrl, 787 const char *key, 788 void *value 789 ); 790 791 extern OWPFunc 792 OWPControlConfigGetF( 793 OWPControl cntrl, 794 const char *key 795 ); 796 797 extern void* 798 OWPControlConfigGetV( 799 OWPControl cntrl, 800 const char *key 801 ); 802 803 extern OWPBoolean 804 OWPControlConfigDelete( 805 OWPControl cntrl, 806 const char *key 807 ); 808 809 /* 810 * OWPControlOpen allocates an OWPclient structure, opens a connection to 811 * the OWP server and goes through the initialization phase of the 812 * connection. This includes AES/CBC negotiation. It returns after receiving 813 * the ServerStart message. 814 * 815 * This is typically only used by an OWP client application (or a server 816 * when acting as a client of another OWP server). 817 * 818 * err_ret values: 819 * OWPErrOK completely successful - highest level mode ok'd 820 * OWPErrINFO session connected with less than highest level mode 821 * OWPErrWARNING session connected but future problems possible 822 * OWPErrFATAL function will return NULL - connection is closed. 823 * (Errors will have been reported through the OWPErrFunc 824 * in all cases.) 825 * function return values: 826 * If successful - even marginally - a valid OWPclient handle 827 * is returned. If unsuccessful, NULL is returned. 828 * 829 * Once an I2Addr record is passed into this function - it is 830 * automatically free'd and should not be referenced again in any way. 831 * 832 * Client 833 */ 834 extern OWPControl 835 OWPControlOpen( 836 OWPContext ctx, 837 I2Addr local_addr, /* src addr or NULL */ 838 I2Addr server_addr, /* server addr or NULL */ 839 uint32_t mode_mask, /* OR of OWPSessionMode vals */ 840 OWPUserID userid, /* null if unwanted */ 841 OWPNum64 *uptime_ret, /* server uptime - ret or NULL */ 842 OWPErrSeverity *err_ret 843 ); 844 845 /* 846 * Client and Server 847 */ 848 extern OWPErrSeverity 849 OWPControlClose( 850 OWPControl cntrl 851 ); 852 853 /* 854 * Request a test session - if the function returns True, then the function 855 * returns a valid SID for the session. 856 * 857 * If the function returns False - check err_ret. If err_ret is ErrOK, the 858 * session was denied by the server, and the control connection is still 859 * valid. 860 * 861 * TODO:Add OWPControlStatus(cntrl) function to determine cntrl status... 862 * 863 * Reasons this function will return False: 864 * 1. Server denied test: err_ret==ErrOK 865 * 2. Control connection failure: err_ret == ErrFATAL 866 * 3. Local resource problem (malloc/fork/fdopen): err_ret == ErrFATAL 867 * 4. Bad addresses: err_ret == ErrWARNING 868 * 869 * Once an I2Addr record has been passed into this function, it 870 * is automatically free'd. It should not be referenced again in any way. 871 * 872 * Conversely, the test_spec is completely copied, and the caller continues 873 * to "own" all memory associated with it after this call. (Including 874 * the "slots" array that is part of the test_spec.) 875 * 876 * Client 877 */ 878 extern OWPBoolean 879 OWPSessionRequest( 880 OWPControl control_handle, 881 I2Addr sender, 882 OWPBoolean server_conf_sender, 883 I2Addr receiver, 884 OWPBoolean server_conf_receiver, 885 OWPTestSpec *test_spec, 886 FILE *fp, 887 OWPSID sid_ret, 888 OWPErrSeverity *err_ret 889 ); 890 891 /* 892 * Start all test sessions - if successful, returns OWPErrOK. 893 * 894 * Client and Server 895 */ 896 extern OWPErrSeverity 897 OWPStartSessions( 898 OWPControl control_handle 899 ); 900 901 /* 902 * Wait for test sessions to complete. This function will return the 903 * following integer values: 904 * <0 ErrorCondition 905 * 0 StopSessions received, acted upon, and sent back. 906 * 1 wake_time reached 907 * 908 * 2 system event (signal) 909 * 910 * To effect a poll - specify a waketime in the past. 1 will be returned 911 * if there is nothing to read. 912 * 913 * To use a signal interaction instead of the waketime interface, set the 914 * retn_on_intr pointer. Install a signal handler that sets the value 915 * to non-zero, and this function will return 2. (If wake_time is non-null, 916 * retn_on_intr is not used.) This interface can be used without signal 917 * handlers as well be simply passing in a pointer to a non-zero value. 918 * This function will return for any interrupt. (The signal interface 919 * allows you to set the value to non-zero only for signals you are 920 * actually interested in.) 921 * 922 * To block indefinately, specify NULL for wake_time and NULL for 923 * retn_on_intr. (StopSessionsWait will poll the status of current tests 924 * automatically whenever a system event takes place in this case, so 925 * StopSessionsWait will never return 1 or 2 in this case.) 926 * 927 * If wake_time or retn_on_intr is set, and this function returns 1 or 2, then 928 * it is required to poll the status of each local endpoint using 929 * OWPTestSessionStatus until all sessions complete. (OWPSessionsActive is 930 * a simple way to poll all of them - you know you are done when it returns 0.) 931 * You can of course recall StopSessionsWait in this case. 932 * 933 * If acceptval returns anything other than OWP_CNTRL_ACCEPT, the 934 * data files associated with the recieve sessions SHOULD be deleted. 935 * 936 * Client and Server 937 */ 938 extern int 939 OWPStopSessionsWait( 940 OWPControl control_handle, 941 OWPNum64 *wake_time, /* abs time */ 942 int *retn_on_intr, 943 OWPAcceptType *acceptval, /* out */ 944 OWPErrSeverity *err_ret 945 ); 946 947 /* 948 * Used to poll the status of a test endpoint. 949 * 950 * returns: 951 * True if it could get the status, 952 * False if it could not. (session with given sid wasn't found, 953 * or "send" indicated a remote endpoint.) 954 * 955 * aval returns the following for status: 956 * <0 Test is not yet complete. 957 * >=0 Accept value of completed test. 0 indicates success 958 * other values indicate type of error test encountered. 959 */ 960 extern OWPBoolean 961 OWPSessionStatus( 962 OWPControl cntrl, 963 OWPSID sid, /* SID of test to poll */ 964 OWPAcceptType *aval /* out - return accept value */ 965 ); 966 967 /* 968 * Used to determine how many local endpoints are still active. 969 * (effectively calls the OWPTestSessionStatus function on all endpoints 970 * and determines if they are complete yet.) 971 * 972 * If acceptval is non-null it is set to the MAX acceptval of any 973 * complete session. 974 * 975 * returns: 976 * number of active endpoints. 977 */ 978 extern int 979 OWPSessionsActive( 980 OWPControl cntrl, 981 OWPAcceptType *acceptval /* rtn */ 982 ); 983 984 /* 985 * Send the StopSession message, and wait for the response. 986 * 987 * Client and Server. 988 */ 989 extern OWPErrSeverity 990 OWPStopSessions( 991 OWPControl control_handle, 992 int *retn_on_intr, 993 OWPAcceptType *acceptval /* in/out */ 994 ); 995 996 997 /* 998 * Return the file descriptor being used for the control connection. An 999 * application can use this to call select or otherwise poll to determine 1000 * if anything is ready to be read but they should not read or write to 1001 * the descriptor. 1002 * This can be used in conjunction with the OWPStopSessionsWait 1003 * function so that the application can recieve user input, and only call 1004 * the OWPStopSessionsWait function when there is something to read 1005 * from the connection. (A nul timestamp would be used in this case 1006 * so that OWPStopSessionsWait does not block.) 1007 * 1008 * This is also useful in a policy context - getpeername can be called 1009 * on this descriptor. 1010 * 1011 * If the control_handle is no longer connected - the function will return 1012 * a negative value. 1013 * 1014 * Client and Server. 1015 */ 1016 extern int 1017 OWPControlFD( 1018 OWPControl control_handle 1019 ); 1020 1021 extern int 1022 OWPErrorFD( 1023 OWPContext ctx 1024 ); 1025 1026 extern 1027 I2Addr 1028 OWPServerSockCreate( 1029 OWPContext ctx, 1030 I2Addr addr, 1031 OWPErrSeverity *err_ret 1032 ); 1033 1034 1035 /*! 1036 * Function: OWPControlAccept 1037 * 1038 * Description: 1039 * This function is used to initialiize the communication 1040 * to the peer. 1041 * 1042 * In Args: 1043 * connfd,connsaddr, and connsaddrlen are all returned 1044 * from "accept". 1045 * 1046 * Returns: Valid OWPControl handle on success, NULL if 1047 * the request has been rejected, or error has occurred. 1048 * 1049 * If *rtn_on_intr and an inturrupt happens during write/read 1050 * err_ret will be set to OWPErrWARNING. 1051 * 1052 * Return value does not distinguish between illegal 1053 * requests, those rejected on policy reasons, or 1054 * errors encountered by the server during execution. 1055 * 1056 * Side Effect: 1057 */ 1058 extern OWPControl 1059 OWPControlAccept( 1060 OWPContext ctx, /* library context */ 1061 int connfd, /* conencted socket */ 1062 struct sockaddr *connsaddr, /* connected socket addr */ 1063 socklen_t connsaddrlen, /* connected socket addr len */ 1064 uint32_t mode_offered, /* advertised server mode */ 1065 OWPNum64 uptime, /* uptime report */ 1066 int *retn_on_intr, /* return on i/o interrupt */ 1067 OWPErrSeverity *err_ret /* err - return */ 1068 ); 1069 1070 typedef enum OWPRequestType{ 1071 OWPReqInvalid=-1, 1072 OWPReqSockClose=10, 1073 OWPReqSockIntr=11, 1074 OWPReqTest=1, 1075 OWPReqStartSessions=2, 1076 OWPReqStopSessions=3, 1077 OWPReqFetchSession=4 1078 } OWPRequestType; 1079 1080 extern OWPRequestType 1081 OWPReadRequestType( 1082 OWPControl cntrl, 1083 int *retn_on_intr 1084 ); 1085 1086 extern OWPErrSeverity 1087 OWPProcessTestRequest( 1088 OWPControl cntrl, 1089 int *retn_on_intr 1090 ); 1091 1092 extern OWPErrSeverity 1093 OWPProcessStartSessions( 1094 OWPControl cntrl, 1095 int *retn_on_intr 1096 ); 1097 1098 extern OWPErrSeverity 1099 OWPProcessStopSessions( 1100 OWPControl cntrl 1101 ); 1102 1103 extern OWPErrSeverity 1104 OWPProcessFetchSession( 1105 OWPControl cntrl, 1106 int *retn_on_intr 1107 ); 1108 1109 extern OWPContext 1110 OWPGetContext( 1111 OWPControl cntrl 1112 ); 1113 1114 extern OWPSessionMode 1115 OWPGetMode( 1116 OWPControl cntrl 1117 ); 1118 1119 1120 /* 1121 ** Given the protocol family, OWAMP mode and packet padding, 1122 ** compute the size of resulting full IP test packet. 1123 */ 1124 1125 /* 1126 * Payload size is used to determine how large the buffers need to be 1127 * to read a packet. 1128 */ 1129 extern OWPPacketSizeT 1130 OWPTestPayloadSize( 1131 OWPSessionMode mode, 1132 uint32_t padding 1133 ); 1134 /* 1135 * PacketSize is used to compute the full packet size - this is used to 1136 * determine bandwidth requirements for policy purposes. 1137 */ 1138 extern OWPPacketSizeT 1139 OWPTestPacketSize( 1140 int af, 1141 OWPSessionMode mode, 1142 uint32_t padding 1143 ); 1144 1145 /* 1146 * Returns # packets/second: 0.0 on error. 1147 */ 1148 extern double 1149 OWPTestPacketRate( 1150 OWPContext ctx, 1151 OWPTestSpec *tspec 1152 ); 1153 1154 /* 1155 * Returns bits/second: 0.0 on error. 1156 */ 1157 extern double 1158 OWPTestPacketBandwidth( 1159 OWPContext ctx, 1160 int af, 1161 OWPSessionMode mode, 1162 OWPTestSpec *tspec 1163 ); 1164 1165 extern uint32_t 1166 OWPFetchSession( 1167 OWPControl cntrl, 1168 FILE *fp, 1169 uint32_t begin, 1170 uint32_t end, 1171 OWPSID sid, 1172 OWPErrSeverity *err_ret 1173 ); 1174 1175 /* 1176 ** Processing Session data to/from local disk. 1177 */ 1178 typedef enum{ 1179 OWP_SESSION_FINISHED_ERROR=0, /* Invalid session datafile */ 1180 OWP_SESSION_FINISHED_NORMAL=1, /* Complete datafile */ 1181 OWP_SESSION_FINISHED_INCOMPLETE=2 /* StopSessions did not happen */ 1182 } OWPSessionFinishedType; 1183 1184 /* 1185 * This data structure is used to read/write a session header. When 1186 * reading a header, if the "header" element returns false, the file 1187 * did not contain any header information, and the remaining fields 1188 * are not valid. 1189 */ 1190 typedef struct OWPSessionHeaderRec{ 1191 OWPBoolean header; /* RO: TestSession header? */ 1192 uint32_t version; /* RO: File version */ 1193 uint32_t rec_size; /* RO: data record size */ 1194 OWPSessionFinishedType finished; /* RW: is session finished? 1195 0:no,1:yes,2:unknown */ 1196 1197 uint32_t next_seqno; /* RW: next seq for sender */ 1198 uint32_t num_skiprecs; /* RW: nskips */ 1199 uint32_t num_datarecs; /* RW: nrecs */ 1200 1201 off_t oset_skiprecs; /* RO: file offset to skips */ 1202 off_t oset_datarecs; /* RO: file offset to data */ 1203 struct stat sbuf; /* RO: sbuf of file */ 1204 1205 uint8_t ipvn; /* RO: ipvn of addrs */ 1206 socklen_t addr_len; /* RO: saddr_len of saddrs */ 1207 struct sockaddr_storage addr_sender; /* RW */ 1208 struct sockaddr_storage addr_receiver; /* RW */ 1209 OWPBoolean conf_sender; /* RW */ 1210 OWPBoolean conf_receiver; /* RW */ 1211 OWPSID sid; /* RW */ 1212 OWPTestSpec test_spec; /* RW */ 1213 } OWPSessionHeaderRec, *OWPSessionHeader; 1214 1215 /* 1216 * Write data header to the file. 1217 * Returns: 1218 */ 1219 extern OWPBoolean 1220 OWPWriteDataHeader( 1221 OWPContext ctx, 1222 FILE *fp, 1223 OWPSessionHeader hdr 1224 ); 1225 1226 /* 1227 * OWPWriteDataHeaderNumSkipRecs 1228 * Sets num_skips filed and the oset_skips field. oset_datarecs and 1229 * num_datarecs MUST be set in the file before this call. (Either by 1230 * calling OWPWriteDataHeader with num_datarecs or by calling 1231 * OWPWriteDataHeaderNumDataRecs.) 1232 * 1233 * This funciton should only be called if skip records are being placed 1234 * in the file after datarecs, and then only after the number of datarecs 1235 * has been fixed. 1236 */ 1237 extern OWPBoolean 1238 OWPWriteDataHeaderNumSkipRecs( 1239 OWPContext ctx, 1240 FILE *fp, 1241 uint32_t num_skiprecs 1242 ); 1243 1244 /* 1245 * OWPWriteDataHeaderNumDataRecs 1246 * Sets the num_datarecs field in the file. If oset_skiprecs is nil, this 1247 * function sets that to just beyond the data records. 1248 */ 1249 extern OWPBoolean 1250 OWPWriteDataHeaderNumDataRecs( 1251 OWPContext ctx, 1252 FILE *fp, 1253 uint32_t num_datarecs 1254 ); 1255 1256 /* 1257 * Returns: 1258 * number of records in the file. 0 on error. (errno will be set.) 1259 * fp is moved to beginning of data records. 1260 */ 1261 extern uint32_t 1262 OWPReadDataHeader( 1263 OWPContext ctx, 1264 FILE *fp, 1265 OWPSessionHeader hdr_ret 1266 ); 1267 1268 /* 1269 * OWPReadDataHeaderSlots 1270 * This function is used to read the "slots" out of the file. It is only 1271 * valid for data files of version 2 or above so it is important to check 1272 * the file version using OWPReadDataHeader before calling this function. 1273 * OWPReadDataHeader only reads the fixed portion of the TestReq out 1274 * of the file. OWPReadDataHeader can be used to determine how many slots 1275 * are in the file, and the caller of this function is required to pass 1276 * in the memory for "slots". 1277 * 1278 * Returns: 1279 * OWPBoolean - T if successful, F if not. 1280 */ 1281 extern OWPBoolean 1282 OWPReadDataHeaderSlots( 1283 OWPContext ctx, 1284 FILE *fp, 1285 uint32_t nslots, 1286 OWPSlot *slots 1287 ); 1288 1289 /* 1290 * Applications use this type to manipulate individual timestamp data records. 1291 */ 1292 typedef struct OWPDataRec { 1293 uint32_t seq_no; 1294 OWPTimeStamp send; 1295 OWPTimeStamp recv; 1296 uint8_t ttl; 1297 } OWPDataRec; 1298 1299 /* 1300 * Write data record to a file. 1301 * Returns: 1302 * 0 Success 1303 */ 1304 extern OWPBoolean 1305 OWPWriteDataRecord( 1306 OWPContext ctx, 1307 FILE *fp, 1308 OWPDataRec *rec 1309 ); 1310 1311 /* 1312 * This (type of) function is used by Fetch-Client to process 1313 * data records. 1314 * 1315 * The function should return < 0 to indicate an error condition in which 1316 * case OWPParseRecords will return OWPErrFATAL. 1317 * It should return 0 to continue parsing. 1318 * It should return 1 to terminate parsing in which case OWPParseRecords will 1319 * return OWPErrOK. 1320 * 1321 * num_rec can be any number less than or equal to the number of valid 1322 * records in the file reported by OWPReadDataHeader. This function assumes 1323 * the fp is currently pointing at the beginning of a data record. 1324 * (This can be done simply by calling OWPReadDataHeader or fseek'ing to 1325 * the offset reported by OWPReadDataHeader.) Or advancing by some multiple 1326 * of hdr.rec_size. 1327 * 1328 * If OWPParseRecords completes parsing "num_rec" records with out error, 1329 * it will return OWPErrOK. 1330 * If OWPParseRecords is unable to complete parsing because of file i/o problems 1331 * it will return OWPErrFATAL. 1332 */ 1333 typedef int (*OWPDoDataRecord)( 1334 OWPDataRec *rec, 1335 void *udata 1336 ); 1337 1338 extern OWPErrSeverity 1339 OWPParseRecords( 1340 OWPContext ctx, 1341 FILE *fp, 1342 uint32_t num_rec, 1343 uint32_t file_version, /* from OWPReadDataHeader */ 1344 OWPDoDataRecord proc_rec, 1345 void *udata /* passed into proc_rec */ 1346 ); 1347 1348 /* 1349 * OWPReadDataSkipRecs 1350 * This function is used to read the "skips" out of the file. It is only 1351 * valid for data files of version 2 or above so it is important to check 1352 * the file version. 1353 * OWPReadDataHeader can be used to determine how many skips 1354 * are in the file, and the caller of this function is required to pass 1355 * in the memory for "skips". 1356 * 1357 * (For very large session files it may become necessary to create a 1358 * Parse interface so the entire array does not have to be in memory 1359 * at one time - but for now I will be wasteful.) 1360 * 1361 * Returns: 1362 * OWPBoolean - T if successful, F if not. 1363 */ 1364 typedef struct OWPSkipRec OWPSkipRec, *OWPSkip; 1365 struct OWPSkipRec{ 1366 uint32_t begin; 1367 uint32_t end; 1368 }; 1369 1370 extern OWPBoolean 1371 OWPReadDataSkips( 1372 OWPContext ctx, 1373 FILE *fp, 1374 uint32_t nskips, 1375 OWPSkip skips 1376 ); 1377 1378 1379 extern double 1380 OWPDelay( 1381 OWPTimeStamp *send_time, 1382 OWPTimeStamp *recv_time 1383 ); 1384 1385 extern OWPBoolean 1386 OWPIsLostRecord( 1387 OWPDataRec *rec 1388 ); 1389 1390 extern I2Boolean 1391 OWPParsePortRange ( 1392 char *pspec, 1393 OWPPortRangeRec *portspec 1394 ); 1395 /* 1396 * TODO: This needs lots of clean-up to be a good public interface. 1397 * Most of these fields do not really need to be exposed. 1398 * 1399 * This structure is used to pass into a OWPDoDataRecord function 1400 * that will parse an owd file and generate some statistics. 1401 */ 1402 typedef struct OWPPacketRec OWPPacketRec, *OWPPacket; 1403 struct OWPPacketRec{ 1404 OWPPacket next; 1405 uint32_t seq; /* packet seq no */ 1406 OWPNum64 schedtime; /* scheduled send time */ 1407 uint32_t seen; /* how many times seen? */ 1408 OWPBoolean lost; 1409 }; 1410 1411 typedef struct OWPBucketRec OWPBucketRec, *OWPBucket; 1412 struct OWPBucketRec{ 1413 OWPBucket next; 1414 int b; /* bucket index */ 1415 uint32_t n; /* samples in this bucket */ 1416 }; 1417 1418 typedef struct OWPStatsRec{ 1419 1420 /* 1421 * Error reporting context 1422 */ 1423 OWPContext ctx; 1424 1425 /* 1426 * Output values 1427 */ 1428 FILE *output; /* If set, verbose description of rec's */ 1429 1430 char fromhost[NI_MAXHOST]; 1431 char fromaddr[NI_MAXHOST]; 1432 char fromserv[NI_MAXSERV]; 1433 1434 char tohost[NI_MAXHOST]; 1435 char toaddr[NI_MAXHOST]; 1436 char toserv[NI_MAXSERV]; 1437 1438 float scale_factor; 1439 char scale_abrv[3]; 1440 1441 /* 1442 * data file information 1443 */ 1444 FILE *fp; 1445 OWPSessionHeaderRec hdr_rec; 1446 OWPSessionHeader hdr; /* file header */ 1447 OWPSkip skips; 1448 long int iskip; 1449 1450 /* 1451 * TestSession information 1452 */ 1453 OWPScheduleContext sctx; 1454 uint32_t isctx; /* index for next seq_no */ 1455 OWPNum64 endnum; /* current sched time for (isctx-1) */ 1456 1457 OWPNum64 start_time; /* send time for first scheduled packet */ 1458 OWPNum64 end_time; /* send time for last scheduled packet */ 1459 1460 /* 1461 * Parsing information 1462 */ 1463 uint32_t i; /* keeps track of current record index */ 1464 1465 uint32_t first; /* first seqno of interest (inclusive) */ 1466 uint32_t last; /* last seqno of interest (non-inclusive) */ 1467 1468 off_t begin_oset; /* starting file offset */ 1469 off_t next_oset; /* upon completing, this will have either 1470 * null, or the offset of the first seqno 1471 * greater than or equal to "last". 1472 */ 1473 uint32_t sent; /* actual number sent */ 1474 1475 /* 1476 * Packet records (used to count dups/lost) 1477 */ 1478 I2Table ptable; 1479 long int plistlen; 1480 OWPPacket pallocated; 1481 OWPPacket pfreelist; 1482 OWPPacket pbegin; 1483 OWPPacket pend; 1484 1485 /* 1486 * Delay histogram 1487 */ 1488 double bucketwidth; 1489 I2Table btable; 1490 long int blistlen; 1491 OWPBucket ballocated; 1492 OWPBucket bfreelist; 1493 OWPBucket *bsort; 1494 uint32_t bsorti; /* current index */ 1495 uint32_t bsortsize; /* number used in sort array */ 1496 uint32_t bsortlen; /* number allocated */ 1497 1498 /* 1499 * TTL info - histogram of received TTL values. 1500 */ 1501 uint8_t ttl_count[256]; 1502 1503 /* 1504 * Reordering buffers 1505 */ 1506 long int rlistlen; 1507 long int rindex; 1508 long int rnumseqno; 1509 uint32_t *rseqno; /* buffer of seqno's seen */ 1510 uint32_t *rn; /* number of j-reordered packets */ 1511 1512 /* 1513 * Summary Stats 1514 */ 1515 double inf_delay; 1516 double min_delay; 1517 double max_delay; 1518 OWPBoolean sync; 1519 double maxerr; 1520 1521 uint32_t dups; 1522 uint32_t lost; 1523 1524 } OWPStatsRec, *OWPStats; 1525 1526 /* 1527 * Stats utility functions: 1528 * 1529 * The Stats functions are used to create/free context for statistics 1530 * functions as well as providing those functions. 1531 */ 1532 1533 extern void 1534 OWPStatsFree( 1535 OWPStats stats 1536 ); 1537 1538 extern OWPStats 1539 OWPStatsCreate( 1540 OWPContext ctx, 1541 FILE *fp, 1542 OWPSessionHeader hdr, 1543 char *fromhost, /* from hostname */ 1544 char *tohost, /* to hostname */ 1545 char scale, 1546 double bucketWidth 1547 ); 1548 1549 extern OWPBoolean 1550 OWPStatsParse( 1551 OWPStats stats, /* Stats record */ 1552 FILE *output, /* Print packet records here */ 1553 off_t begin_oset, /* Hint:start offset - multistage parsing */ 1554 uint32_t first, /* first seq num inclusive */ 1555 uint32_t last /* last seq num non-inclusive */ 1556 ); 1557 1558 extern OWPBoolean 1559 OWPStatsPrintSummary( 1560 OWPStats stats, 1561 FILE *output, 1562 float *percentiles, 1563 uint32_t npercentiles 1564 ); 1565 1566 extern OWPBoolean 1567 OWPStatsPrintMachine( 1568 OWPStats stats, 1569 FILE *output 1570 ); 1571 1572 extern float 1573 OWPStatsScaleFactor( 1574 char scale, 1575 char *abrv, 1576 size_t *abrv_len 1577 ); 1578 1579 /* 1580 * How much disk space will a given test require? 1581 * (This is only an estimate - duplicates/loss will change this.) 1582 */ 1583 extern uint64_t 1584 OWPTestDiskspace( 1585 OWPTestSpec *tspec 1586 ); 1587 1588 /* 1589 * time.c conversion functions. 1590 */ 1591 1592 #define OWPJAN_1970 (unsigned long)0x83aa7e80 /* diffs in epoch*/ 1593 1594 #ifndef tvalclear 1595 #define tvalclear(a) (a)->tv_sec = (a)->tv_usec = 0 1596 #endif 1597 1598 #ifndef tvaladd 1599 #define tvaladd(a,b) \ 1600 do{ \ 1601 (a)->tv_sec += (b)->tv_sec; \ 1602 (a)->tv_usec += (b)->tv_usec; \ 1603 if((a)->tv_usec >= 1000000){ \ 1604 (a)->tv_sec++; \ 1605 (a)->tv_usec -= 1000000; \ 1606 } \ 1607 } while (0) 1608 #endif 1609 1610 #ifndef tvalsub 1611 #define tvalsub(a,b) \ 1612 do{ \ 1613 (a)->tv_sec -= (b)->tv_sec; \ 1614 (a)->tv_usec -= (b)->tv_usec; \ 1615 if((a)->tv_usec < 0){ \ 1616 (a)->tv_sec--; \ 1617 (a)->tv_usec += 1000000; \ 1618 } \ 1619 } while (0) 1620 #endif 1621 1622 #ifndef tvalcmp 1623 #define tvalcmp(tvp,uvp,cmp) \ 1624 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 1625 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 1626 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 1627 #endif 1628 1629 /* Operations on timespecs */ 1630 #ifndef timespecclear 1631 #define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) 1632 #endif 1633 1634 #ifndef timespecisset 1635 #define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) 1636 #endif 1637 1638 #undef timespeccmp 1639 #define timespeccmp(tvp, uvp, cmp) \ 1640 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 1641 ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ 1642 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 1643 1644 #undef timespecadd 1645 #define timespecadd(vvp, uvp) \ 1646 do { \ 1647 (vvp)->tv_sec += (uvp)->tv_sec; \ 1648 (vvp)->tv_nsec += (uvp)->tv_nsec; \ 1649 if ((vvp)->tv_nsec >= 1000000000){ \ 1650 (vvp)->tv_sec++; \ 1651 (vvp)->tv_nsec -= 1000000000; \ 1652 } \ 1653 } while (0) 1654 1655 #undef timespecsub 1656 #define timespecsub(vvp, uvp) \ 1657 do { \ 1658 (vvp)->tv_sec -= (uvp)->tv_sec; \ 1659 (vvp)->tv_nsec -= (uvp)->tv_nsec; \ 1660 if ((vvp)->tv_nsec < 0) { \ 1661 (vvp)->tv_sec--; \ 1662 (vvp)->tv_nsec += 1000000000; \ 1663 } \ 1664 } while (0) 1665 1666 #undef timespecdiff 1667 #define timespecdiff(vvp,uvp) \ 1668 do { \ 1669 struct timespec ts1_,ts2_; \ 1670 if(timespeccmp(vvp,uvp,>)){ \ 1671 ts1_ = *vvp; \ 1672 ts2_ = *uvp; \ 1673 }else{ \ 1674 ts1_ = *uvp; \ 1675 ts2_ = *vvp; \ 1676 } \ 1677 timespecsub(&ts1_,&ts2_); \ 1678 *vvp = ts1_; \ 1679 } while(0) 1680 1681 extern OWPNum64 1682 OWPGetRTTBound( 1683 OWPControl cntrl 1684 ); 1685 1686 extern double 1687 OWPGetTimeStampError( 1688 OWPTimeStamp *tstamp 1689 ); 1690 1691 extern OWPTimeStamp * 1692 OWPGetTimeOfDay( 1693 OWPContext ctx, 1694 OWPTimeStamp *tstamp 1695 ); 1696 1697 extern OWPTimeStamp * 1698 OWPTimevalToTimestamp( 1699 OWPTimeStamp *tstamp, 1700 struct timeval *tval 1701 ); 1702 1703 extern struct timeval * 1704 OWPTimestampToTimeval( 1705 struct timeval *tval, 1706 OWPTimeStamp *tstamp 1707 ); 1708 1709 extern OWPTimeStamp * 1710 OWPTimespecToTimestamp( 1711 OWPTimeStamp *tstamp, 1712 struct timespec *tval, 1713 uint32_t *errest, /* usec's */ 1714 uint32_t *last_errest /* usec's */ 1715 ); 1716 1717 extern struct timespec * 1718 OWPTimestampToTimespec( 1719 struct timespec *tval, 1720 OWPTimeStamp *tstamp 1721 ); 1722 1723 #endif /* OWAMP_H */ 1724