Index: src/web100srv.h =================================================================== --- src/web100srv.h (revision 796) +++ src/web100srv.h (working copy) @@ -19,6 +19,9 @@ #ifdef HAVE_LIBWEB100 #include #endif +#ifdef HAVE_LIBTCPE +#include +#endif #ifdef HAVE_LIBPCAP #include #endif @@ -190,6 +193,54 @@ u_int16_t speed[32]; } iflist; +typedef int tcp_stat_var; + +struct tcp_vars { + tcp_stat_var Timeouts; + tcp_stat_var SumRTT; + tcp_stat_var CountRTT; + tcp_stat_var PktsRetrans; + tcp_stat_var FastRetran; + tcp_stat_var DataPktsOut; + tcp_stat_var AckPktsOut; + tcp_stat_var CurrentMSS; + tcp_stat_var DupAcksIn; + tcp_stat_var AckPktsIn; + tcp_stat_var MaxRwinRcvd; + tcp_stat_var Sndbuf; + tcp_stat_var CurrentCwnd; + tcp_stat_var SndLimTimeRwin; + tcp_stat_var SndLimTimeCwnd; + tcp_stat_var SndLimTimeSender; + tcp_stat_var DataBytesOut; + tcp_stat_var SndLimTransRwin; + tcp_stat_var SndLimTransCwnd; + tcp_stat_var SndLimTransSender; + tcp_stat_var MaxSsthresh; + tcp_stat_var CurrentRTO; + tcp_stat_var CurrentRwinRcvd; + tcp_stat_var MaxCwnd; + tcp_stat_var CongestionSignals; + tcp_stat_var PktsOut; + tcp_stat_var MinRTT; + tcp_stat_var RcvWinScale; + tcp_stat_var SndWinScale; + tcp_stat_var CongAvoid; + tcp_stat_var CongestionOverCount; + tcp_stat_var MaxRTT; + tcp_stat_var OtherReductions; + tcp_stat_var CurTimeoutCount; + tcp_stat_var AbruptTimeouts; + tcp_stat_var SendStall; + tcp_stat_var SlowStart; + tcp_stat_var SubsequentTimeouts; + tcp_stat_var ThruBytesAcked; + /* Additional for web10g */ + tcp_stat_var MaxSsCwnd; + tcp_stat_var MaxCaCwnd; +}; + + /* web100-pcap */ #ifdef HAVE_LIBPCAP void init_vars(struct spdpair *cur); @@ -198,40 +249,63 @@ int port3); void init_pkttrace(I2Addr srcAddr, struct sockaddr *sock_addr, socklen_t saddrlen, int monitor_pipe[2], char *device, - PortPair* pair, char * direction, int compress); -int check_signal_flags(); + PortPair* pair, const char *direction, int compress); +void force_breakloop(); #endif /* web100-util */ -#ifdef HAVE_LIBWEB100 +#if defined(HAVE_LIBWEB100) || defined(HAVE_LIBTCPE) void get_iflist(void); -int web100_init(char *VarFileName); -int web100_autotune(int sock, web100_agent* agent, web100_connection* cn); -void web100_middlebox(int sock, web100_agent* agent, web100_connection* cn, +#ifdef FORCE_WEB100 + +typedef web100_agent * tcp_stat_agent; +typedef web100_connection * tcp_stat_connection; +typedef web100_snapshot * tcp_stat_snap; +/* Group only relevent to web100 */ +typedef web100_group * tcp_stat_group; +/* Log currently unimplemented in web100 */ +typedef web100_log * tcp_stat_log; +#define tcp_stat_connection_from_socket web100_connection_from_socket + +#else /* web10g */ +#ifdef HAVE_LIBTCPE + +typedef struct tcpe_client * tcp_stat_agent; +typedef int tcp_stat_connection; +typedef struct tcpe_data * tcp_stat_snap; +/* Not relevent to web10g */ +typedef void * tcp_stat_group; +/* Log currently unimplemented in web100 */ +typedef void * tcp_stat_log; +#define tcp_stat_connection_from_socket web10g_connection_from_socket + +/* Extra Web10G functions web10g-util.c */ +int web10g_find_val(tcpe_data* data, char * name, struct tcpe_val * value); +int web10g_get_val(struct tcpe_client * client, int conn, char * name, struct tcpe_val * value); +int web10g_connection_from_socket(struct tcpe_client * client,int sockfd); +int web10g_get_remote_addr(struct tcpe_client * client, int conn, char * out, int size); + +#endif /* HAVE_LIBTCPE */ +#endif /* FORCE_WEB100 */ + +int tcp_stat_autotune(int sock, tcp_stat_agent agent, tcp_stat_connection cn); +int tcp_stat_init(char *VarFileName); +void tcp_stat_middlebox(int sock, tcp_stat_agent agent, tcp_stat_connection cn, char *results, size_t results_strlen); -int web100_setbuff(int sock, web100_agent* agent, web100_connection* cn, - int autotune); -void web100_get_data_recv(int sock, web100_agent* agent, web100_connection* cn, - int count_vars); -int web100_get_data(web100_snapshot* snap, int ctlsock, web100_agent* agent, - int count_vars); -int CwndDecrease(web100_agent* agent, char* logname, +int tcp_stat_setbuff(int sock, tcp_stat_agent agent, tcp_stat_connection cn, + int autotune);/* Not used so no web10g version */ +void tcp_stat_get_data_recv(int sock, tcp_stat_agent agent, tcp_stat_connection cn, + int count_vars); +int tcp_stat_get_data(tcp_stat_snap snap, int testsock, int ctlsock, tcp_stat_agent agent, + int count_vars); + +/* TODO web10g version of CwndDecrease */ +int CwndDecrease(tcp_stat_agent agent, char* logname, u_int32_t *dec_cnt, u_int32_t *same_cnt, u_int32_t *inc_cnt); -int web100_logvars(int *Timeouts, int *SumRTT, int *CountRTT, - int *PktsRetrans, int *FastRetran, int *DataPktsOut, - int *AckPktsOut, int *CurrentMSS, int *DupAcksIn, - int *AckPktsIn, int *MaxRwinRcvd, int *Sndbuf, - int *CurrentCwnd, int *SndLimTimeRwin, int *SndLimTimeCwnd, - int *SndLimTimeSender, int *DataBytesOut, - int *SndLimTransRwin, int *SndLimTransCwnd, - int *SndLimTransSender, int *MaxSsthresh, int *CurrentRTO, - int *CurrentRwinRcvd, int *MaxCwnd, int *CongestionSignals, - int *PktsOut, int *MinRTT, int count_vars, int *RcvWinScale, - int *SndWinScale, int *CongAvoid, int *CongestionOverCount, - int *MaxRTT, int *OtherReductions, int *CurTimeoutCount, - int *AbruptTimeouts, int *SendStall, int *SlowStart, - int *SubsequentTimeouts, int *ThruBytesAcked); -#endif + +int tcp_stat_logvars(struct tcp_vars * vars, int count_vars); + +#endif /* defined(HAVE_LIBWEB100) || defined(HAVE_LIBTCPE)*/ int KillHung(void); void writeMeta(int compress, int cputime, int snaplog, int tcpdump); @@ -244,4 +318,5 @@ sig_atomic_t sig17; pid_t sig17_pid[256]; + #endif // SRC_WEB100SRV_H_ Index: src/tests_srv.h =================================================================== --- src/tests_srv.h (revision 796) +++ src/tests_srv.h (working copy) @@ -11,19 +11,15 @@ #include "testoptions.h" -int test_c2s(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, +int test_c2s(int ctlsockfd, tcp_stat_agent agent, TestOptions* testOptions, int conn_options, double* c2sspd, int set_buff, int window, int autotune, char* device, Options* options, int record_reverse, int count_vars, char spds[4][256], int* spd_index); - -// S2C test -int test_s2c(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, +int test_s2c(int ctlsockfd, tcp_stat_agent agent, TestOptions* testOptions, int conn_options, double* s2cspd, int set_buff, int window, int autotune, char* device, Options* options, char spds[4][256], int* spd_index, int count_vars, CwndPeaks* peaks); - -// the middlebox test -int test_mid(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, +int test_mid(int ctlsockfd, tcp_stat_agent agent, TestOptions* testOptions, int conn_options, double* s2c2spd); #endif // SRC_TESTS_SRV_H_ Index: src/test_results_clt.c =================================================================== --- src/test_results_clt.c (revision 796) +++ src/test_results_clt.c (working copy) @@ -296,7 +296,9 @@ /** * Print if TCP Selective Acknowledgment Options based on RFC 2018 is on - * + * web100 0 off 1< on - directly from tcp_options_received.sack_ok (Storage size is 4bits) + * web10g 1 is on 2 is selfDisabled 3 peerDisabled - split into WillSendSACK + * and WillUseSack. For now change web10G to return either 0 off or 1 on. * @param SACKEnabled */ void print_SAck_RFC2018(int SACKEnabled) { @@ -309,40 +311,57 @@ /** * Print if Nagle algorithm (rfc 896) is on + * web100 1 is on 0 is off + * web10g 1 is on 2 is off * @param is_nagleenabled */ void print_Nagle_RFC896(int is_nagleenabled) { printf("RFC 896 Nagle Algorithm: "); - if (is_nagleenabled == 0) + if (is_nagleenabled == 1) + printf("ON\n"); + else printf("OFF\n"); - else - printf("ON\n"); } /** * Print if Explicit congestion notification to IP is on - RFC 3168 related + * web100 0 is off 1 is on + * web10g 1 is on 2 is selfDisabled 3 peerDisabled * @param is_ECNenabled */ void print_congestion_RFC3168(int is_ECNenabled) { printf("RFC 3168 Explicit Congestion Notification: "); - if (is_ECNenabled == 0) - printf("OFF\n"); - else - printf("ON\n"); + if (is_ECNenabled == 1) + printf("ON\n"); + else if (is_ECNenabled == 0) + printf("OFF\n"); + else if (is_ECNenabled == 2) + printf("OFF - disabled by server\n"); + else if (is_ECNenabled == 3) + printf("OFF - disabled by client\n"); + else + printf("OFF? - unable to determine setting\n"); } /** * Print details of whether time stamping is on - RFC 1323 related. - * + * web100 1 is on 0 is off - directly from tcp_options_received.tstamp_ok (Storage size is 1bit) + * web10g 1 is on 2 is selfDisabled 3 peerDisabled. * @param is_timestampenabled */ void print_timestamping_RFC1323(int is_timestampenabled) { printf("RFC 1323 Time Stamping: "); - if (is_timestampenabled == 0) - printf("OFF\n"); - else - printf("ON\n"); + if (is_timestampenabled == 1) + printf("ON\n"); + else if (is_timestampenabled == 0) + printf("OFF\n"); + else if (is_timestampenabled == 2) + printf("OFF - disabled by server\n"); + else if (is_timestampenabled == 3) + printf("OFF - disabled by client\n"); + else + printf("OFF? - unable to determine setting\n"); } /** Index: src/web100-util.c =================================================================== --- src/web100-util.c (revision 796) +++ src/web100-util.c (working copy) @@ -17,6 +17,61 @@ #include "protocol.h" #include "strlutils.h" +struct tcp_name { + char* web100_name; + char* web10g_name; +}; + +/* Must match in-order with tcp_vars in web100srv.h struct */ +static struct tcp_name tcp_names[] = { +/* {"WEB100", "WEB10G" } / tcp_vars name / */ + {"Timeouts", "Timeouts"}, /* Timeouts */ + {"SumRTT", "SumRTT"}, /* SumRTT */ + {"CountRTT", "CountRTT"}, /* CountRTT */ + {"PktsRetrans", "SegsRetrans"}, /* PktsRetrans */ + {"FastRetran", "FastRetran"}, /* FastRetran */ + {"DataPktsOut", "DataSegsOut"}, /* DataPktsOut */ + {"AckPktsOut", NULL}, /* AckPktsOut - not included in web10g */ + {"CurMSS", "CurMSS"}, /* CurrentMSS */ + {"DupAcksIn", "DupAcksIn"}, /* DupAcksIn */ + /* NOTE: in the server to client throughput test all packets received from client are ack's + * So SegsIn == AckPktsIn. I don't see a replacement in web10g maybe (SegsIn - DataSegsIn) + */ + {"AckPktsIn", "SegsIn"}, /* AckPktsIn - not included in web10g */ + {"MaxRwinRcvd", "MaxRwinRcvd"}, /* MaxRwinRcvd */ + {"X_Sndbuf", NULL}, /* Sndbuf - Not in Web10g pull from socket */ + {"CurCwnd", "CurCwnd"}, /* CurrentCwnd */ + {"SndLimTimeRwin", "SndLimTimeRwin"}, /* SndLimTimeRwin */ + {"SndLimTimeCwnd", "SndLimTimeCwnd"}, /* SndLimTimeCwnd */ + {"SndLimTimeSender", "SndLimTimeSnd"}, /* SndLimTimeSender */ + {"DataBytesOut", "DataOctetsOut"}, /* DataBytesOut */ + {"SndLimTransRwin", "SndLimTransRwin"}, /* SndLimTransRwin */ + {"SndLimTransCwnd", "SndLimTransCwnd"}, /* SndLimTransCwnd */ + {"SndLimTransSender", "SndLimTransSnd"}, /* SndLimTransSender */ + {"MaxSsthresh", "MaxSsthresh"}, /* MaxSsthresh */ + {"CurRTO", "CurRTO"}, /* CurrentRTO */ + {"CurRwinRcvd", "CurRwinRcvd"}, /* CurrentRwinRcvd */ + {"MaxCwnd", NULL}, /* MaxCwnd split into MaxSsCwnd and MaxCaCwnd web10g */ + {"CongestionSignals", "CongSignals"}, /* CongestionSignals */ + {"PktsOut", "SegsOut"}, /* PktsOut */ + {"MinRTT", "MinRTT"}, /* MinRTT */ + {"RcvWinScale", "WinScaleRcvd"}, /* RcvWinScale */ + {"SndWinScale", "WinScaleSent"}, /* SndWinScale */ + {"CongAvoid", "CongAvoid"}, /* CongAvoid */ + {"CongestionOverCount", "CongOverCount"}, /* CongestionOverCount */ + {"MaxRTT", "MaxRTT"}, /* MaxRTT */ + {"OtherReductions", "OtherReductions"}, /* OtherReductions */ + {"CurTimeoutCount", "CurTimeoutCount"}, /* CurTimeoutCount */ + {"AbruptTimeouts", "AbruptTimeouts"}, /* AbruptTimeouts */ + {"SendStall", "SendStall"}, /* SendStall */ + {"SlowStart", "SlowStart"}, /* SlowStart */ + {"SubsequentTimeouts", "SubsequentTimeouts"}, /* SubsequentTimeouts */ + {"ThruBytesAcked", "ThruOctetsAcked"}, /* ThruBytesAcked */ + { NULL, "MaxSsCwnd" }, /* MaxSsCwnd */ + { NULL, "MaxCaCwnd" } /* MaxCaCwnd */ +}; + + /** * set up the necessary structures for monitoring connections at the * beginning @@ -24,7 +79,8 @@ * @return integer indicating number of web100 variables read * or indicating failure of initialization */ -int web100_init(char *VarFileName) { +int tcp_stat_init(char *VarFileName) { +#ifdef FORCE_WEB100 FILE * fp; char line[256], trimmedline[256]; int count_vars = 0; @@ -54,9 +110,59 @@ log_println(1, "web100_init() read %d variables from file", count_vars); return (count_vars); + +#else /* Must be web10g */ + // Web100 would have setup a table of string's with the variable names + // loaded from an external file + // We already have one of these setup for us in the library itself. + // So we do nothing + return TOTAL_INDEX_MAX; +#endif } /** + * Get a string representation of an ip address. + * + * @param addr A sockaddr structure which contains the address + * @param buf A buffer to fill with the ip address as a string + * @param len The length of buf. + */ +static void addr2a(struct sockaddr_storage * addr,char * buf, int len){ + if(((struct sockaddr *)addr)->sa_family == AF_INET){ + /* IPv4 */ + inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), + buf, len); + } +#ifdef AF_INET6 + else if(((struct sockaddr *)addr)->sa_family == AF_INET6 ){ + /* IPv6 */ + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)addr)->sin6_addr), + buf, len); + } +#endif +} + +/** + * Get a string representation of an port number. + * + * @param addr A sockaddr structure which contains the port number + * @param buf A buffer to fill with the port number as a string + * @param len The length of buf. + */ +static void port2a(struct sockaddr_storage * addr,char * buf, int len){ + if(((struct sockaddr *)addr)->sa_family == AF_INET){ + /* IPv4 */ + snprintf(buf, len, "%hu", ntohs(((struct sockaddr_in *)addr)->sin_port)); + } +#ifdef AF_INET6 + else if(((struct sockaddr *)addr)->sa_family == AF_INET6 ){ + /* IPv6 */ + snprintf(buf, len, "%hu", ntohs(((struct sockaddr_in6 *)addr)->sin6_port)); + } +#endif +} + +/** * Performs part of the middlebox test. * The server sets the maximum value of the * congestion window, and starts a 5 second long @@ -74,11 +180,19 @@ * * */ -void web100_middlebox(int sock, web100_agent* agent, web100_connection* cn, + +void tcp_stat_middlebox(int sock, tcp_stat_agent agent, tcp_stat_connection cn, char *results, size_t results_strlen) { +#ifdef FORCE_WEB100 web100_var* var; web100_group* group; web100_snapshot* snap; + web100_var *LimCwnd; +#else /* Must be web10g */ + struct tcpe_val value; + tcpe_data * data = NULL; +#endif + char buff[8192], line[256]; char* sndbuff; int i, j, k, currentMSSval = 0; @@ -88,12 +202,16 @@ int ret; char tmpstr[200]; size_t tmpstrlen = sizeof(tmpstr); - I2Addr addr = NULL; - web100_var *LimCwnd; u_int32_t limcwnd_val; + struct sockaddr_storage saddr; + socklen_t saddr_size; // middlebox test results +#ifdef FORCE_WEB100 static char vars[][255] = { "CurMSS", "WinScaleSent", "WinScaleRecv", }; +#else + static char vars[][255] = { "CurMSS", "WinScaleSent", "WinScaleRcvd", }; +#endif assert(results); @@ -101,16 +219,24 @@ // get Server address and add to "results" - // get socket name - addr = I2AddrByLocalSockFD(get_errhandle(), sock, False); - memset(tmpstr, 0, 200); - // copy address into tmpstr String - I2AddrNodeName(addr, tmpstr, &tmpstrlen); - // now copy tmpstr containing address into "line" - snprintf(line, sizeof(line), "%s;", tmpstr); - memset(tmpstr, 0, 200); - // service name into tmpstr - I2AddrServName(addr, tmpstr, &tmpstrlen); + // get socket IP address + saddr_size = sizeof(saddr); + if (getsockname(sock,(struct sockaddr *) &saddr, &saddr_size) == -1) { + /* Make it clear something failed but continue test */ + log_println(0,"Middlebox - getsockname() failed: %s", strerror(errno)); + snprintf(line, sizeof(line), "address_error;"); + snprintf(tmpstr, sizeof(tmpstr), "0"); + } else { + // copy address into tmpstr String + memset(tmpstr, 0, 200); + addr2a(&saddr, tmpstr , tmpstrlen); + // now copy tmpstr containing address into "line" + snprintf(line, sizeof(line), "%s;", tmpstr); + memset(tmpstr, 0, 200); + // service name into tmpstr + tmpstrlen = sizeof(tmpstr); + port2a(&saddr, tmpstr, tmpstrlen); + } log_print(3, "Server: %s%s ", line, tmpstr); // copy servers address into the meta test struct memcpy(meta.server_ip, line, strlen(line)); @@ -118,27 +244,35 @@ meta.server_ip[(strlen(line) - 1)] = 0; // Add this address to results strlcat(results, line, results_strlen); - I2AddrFree(addr); // free memory // Now perform the above set of functions for client address/service name // and copy into results tmpstrlen = sizeof(tmpstr); - addr = I2AddrBySockFD(get_errhandle(), sock, False); - memset(tmpstr, 0, 200); - I2AddrNodeName(addr, tmpstr, &tmpstrlen); - snprintf(line, sizeof(line), "%s;", tmpstr); - I2AddrServName(addr, tmpstr, &tmpstrlen); + saddr_size = sizeof(saddr); + if (getpeername(sock,(struct sockaddr *) &saddr, &saddr_size) == -1) { + /* Make it clear something failed but continue test */ + log_println(0,"Middlebox - getpeername() failed: %s", strerror(errno)); + snprintf(line, sizeof(line), "address_error;"); + snprintf(tmpstr, sizeof(tmpstr), "0"); + } else { + // copy address into tmpstr String + memset(tmpstr, 0, 200); + addr2a(&saddr, tmpstr , tmpstrlen); + snprintf(line, sizeof(line), "%s;", tmpstr); + tmpstrlen = sizeof(tmpstr); + port2a(&saddr, tmpstr, tmpstrlen); + } + log_print(3, "Client: %s%s ", line, tmpstr); strlcat(results, line, results_strlen); - I2AddrFree(addr); // get web100 values for the middlebox test result group for (i = 0; i < 3; i++) { +#ifdef FORCE_WEB100 // read web100_group and web100_var of vars[i] into group and var web100_agent_find_var_and_group(agent, vars[i], &group, &var); // read variable value from web100 connection web100_raw_read(var, cn, buff); - // get current MSS in textual format and append to results // get current MSS value and append to "results" @@ -147,6 +281,14 @@ web100_value_to_text(web100_get_var_type(var), buff)); snprintf(line, sizeof(line), "%s;", web100_value_to_text(web100_get_var_type(var), buff)); +#else /* Must be web10g */ + // read a web10g value + web10g_get_val(agent, cn, vars[i], &value); + if (strcmp(vars[i], "CurMSS") == 0) + currentMSSval = value.uv32; + snprintf(line, sizeof(line), "%u;", value.uv32); +#endif + if (strcmp(line, "4294967295;") == 0) snprintf(line, sizeof(line), "%d;", -1); @@ -165,12 +307,15 @@ * RAC 2/28/06 */ + // set TCP CWND web100 variable to twice the current MSS Value + limcwnd_val = 2 * currentMSSval; +#ifdef FORCE_WEB100 // get web100_var and web100_group web100_agent_find_var_and_group(agent, "LimCwnd", &group, &LimCwnd); - - // set TCP CWND web100 variable to twice the current MSS Value - limcwnd_val = 2 * currentMSSval; web100_raw_write(LimCwnd, cn, &limcwnd_val); +#else + tcpe_write_var("LimCwnd", (uint32_t)limcwnd_val, cn, agent); +#endif log_println(5, "Setting Cwnd Limit to %d octets", limcwnd_val); // try to allocate memory of the size of current MSS Value @@ -194,9 +339,14 @@ sndbuff[j] = (k++ & 0x7f); } +#ifdef FORCE_WEB100 // get web100 group with name "read" group = web100_group_find(agent, "read"); snap = web100_snapshot_alloc(group, cn); +#else + // Allocating memory + tcpe_data_new(&data); +#endif FD_ZERO(&wfd); FD_SET(sock, &wfd); @@ -205,7 +355,7 @@ while ((ret = select(sock + 1, NULL, &wfd, NULL, &sel_tv)) > 0) { if ((ret == -1) && (errno == EINTR)) /* a signal arrived, ignore it */ continue; - +#ifdef FORCE_WEB100 web100_snap(snap); // get next sequence # to be sent @@ -216,7 +366,16 @@ web100_agent_find_var_and_group(agent, "SndUna", &group, &var); web100_snap_read(var, snap, line); SndUna = atoi(web100_value_to_text(web100_get_var_type(var), line)); - +#else /* Must be web10g */ + // Grab the current snap of this + tcpe_read_vars(data, cn, agent); + // get next sequence # to be sent + web10g_find_val(data, "SndNxt", &value); + SndMax = value.uv32; + // get oldest un-acked sequence number + web10g_find_val(data, "SndUna", &value); + SndUna = value.uv32; +#endif // stop sending data if (buf size * 16) < // [ (Next Sequence # To Be Sent) - (Oldest Unacknowledged Sequence #) - 1 ] if ((currentMSSval << 4) < (SndMax - SndUna - 1)) { @@ -231,9 +390,16 @@ if (k < 0) // general error writing to socket. quit break; } + +#ifdef FORCE_WEB100 log_println(5, "Finished with web100_middlebox() routine snap-0x%x, " "sndbuff=%x0x", snap, sndbuff); web100_snapshot_free(snap); +#else + tcpe_data_free(&data); + log_println(5, "Finished with web10g_middlebox() routine " + "sndbuff=%x0x", sndbuff); +#endif /* free(sndbuff); */ } @@ -246,12 +412,18 @@ * @param count_vars integer number of web100_variables to get value of * */ -void web100_get_data_recv(int sock, web100_agent* agent, web100_connection* cn, + +void tcp_stat_get_data_recv(int sock, tcp_stat_agent agent, tcp_stat_connection cn, int count_vars) { +#ifdef FORCE_WEB100 + web100_var* var; + web100_group* group; +#else + tcpe_data* data = NULL; +#endif + int i, ok; - web100_var* var; char buf[32], line[256], *ctime(); - web100_group* group; FILE * fp; time_t tt; @@ -263,10 +435,15 @@ fprintf(fp, "%15.15s;", ctime(&tt) + 4); // get values for group, var of IP Address of the Remote host's side of // connection +#ifdef FORCE_WEB100 web100_agent_find_var_and_group(agent, "RemAddress", &group, &var); web100_raw_read(var, cn, buf); snprintf(line, sizeof(line), "%s;", web100_value_to_text(web100_get_var_type(var), buf)); +#else /* web10g */ + web10g_get_remote_addr(agent, cn, buf, sizeof(buf)); + snprintf(line, sizeof(line), "%s;", buf); +#endif // write remote address to log file if (fp) fprintf(fp, "%s", line); @@ -274,7 +451,7 @@ ok = 1; // get values for other web100 variables and write to the log file - +#ifdef FORCE_WEB100 for (i = 0; i < count_vars; i++) { if ((web100_agent_find_var_and_group(agent, web_vars[i].name, &group, &var)) != WEB100_ERR_SUCCESS) { @@ -305,7 +482,46 @@ } ok = 1; } +#else /* web10g */ + tcpe_data_new(&data); + tcpe_read_vars(data, cn, agent) ; + //Loop through all the web10g variables and write to file/log_print them + for(i = 0; i < ARRAYSIZE(data->val); i++) { + if (data->val[i].mask) continue; + + switch(tcpe_var_array[i].type) { + case TCPE_UNSIGNED64: + if (fp) + fprintf(fp, "%" PRIu64 ";", data->val[i].uv64 ); + log_println(9, "%s: %" PRIu64 "", tcpe_var_array[i].name, data->val[i].uv64 ); + break; + case TCPE_UNSIGNED32: + if (fp) + fprintf(fp, "%u;", data->val[i].uv32 ); + log_println(9, "%s: %u", tcpe_var_array[i].name, data->val[i].uv32 ); + break; + case TCPE_SIGNED32: + if (fp) + fprintf(fp, "%d;", data->val[i].sv32 ); + log_println(9, "%s: %d", tcpe_var_array[i].name, data->val[i].sv32 ); + break; + case TCPE_UNSIGNED16: + if (fp) + fprintf(fp, "%" PRIu16 ";", data->val[i].uv16 ); + log_println(9, "%s: %" PRIu16 "", tcpe_var_array[i].name, data->val[i].uv16); + break; + case TCPE_UNSIGNED8: + if (fp) + fprintf(fp, "%" PRIu8 ";", data->val[i].uv8 ); + log_println(9, "%s: %" PRIu8 "", tcpe_var_array[i].name, data->val[i].uv8); + break; + default: + break; + } + } + tcpe_data_free(&data); +#endif // close file pointers after web100 variables have been fetched if (fp) { fprintf(fp, "\n"); @@ -313,6 +529,13 @@ } } +#ifndef FORCE_WEB100 +/* Persistent storage is needed. Replacment for web100 web_vars not very nice TODO */ +static tcpe_data* dataDumpSave; +static int X_Sndbuf; +static int X_Rcvbuf; +#endif + /** * Collect Web100 stats from a snapshot and transmit to a receiver. * The transmission is done using a TES_MSG type message and sent to @@ -324,8 +547,9 @@ * @param count_vars integer number of web100_variables to get value of * */ -int web100_get_data(web100_snapshot* snap, int ctlsock, web100_agent* agent, +int tcp_stat_get_data(tcp_stat_snap snap, int testsock, int ctlsock, tcp_stat_agent agent, int count_vars) { +#ifdef FORCE_WEB100 int i; web100_var* var; char buf[32], line[256]; @@ -371,8 +595,170 @@ } log_println(6, "S2C test - Send web100 data to client pid=%d", getpid()); return (0); +#else /* web10g */ + int j; + char line[256]; + unsigned int m; + struct tcpe_val val; + + m = sizeof(X_Rcvbuf); + getsockopt(testsock, SOL_SOCKET, SO_RCVBUF, (void *)&X_Rcvbuf, &m); + m = sizeof(X_Sndbuf); + getsockopt(testsock, SOL_SOCKET, SO_SNDBUF, (void *)&X_Sndbuf, &m); + + assert(snap); + + tcpe_data_new(&dataDumpSave); + + for(j = 0; j < ARRAYSIZE(snap->val); j++) { + dataDumpSave->val[j].mask = snap->val[j].mask; + dataDumpSave->val[j].uv64 = snap->val[j].uv64; + if (snap->val[j].mask) continue; + + switch(tcpe_var_array[j].type) { + case TCPE_UNSIGNED64: + snprintf(line, sizeof(line), "%s: %" PRIu64 "\n", + tcpe_var_array[j].name, snap->val[j].uv64); + break; + case TCPE_UNSIGNED32: + snprintf(line, sizeof(line), "%s: %u\n", + tcpe_var_array[j].name, snap->val[j].uv32 ); + break; + case TCPE_SIGNED32: + snprintf(line, sizeof(line), "%s: %d\n", + tcpe_var_array[j].name, snap->val[j].sv32 ); + break; + case TCPE_UNSIGNED16: + snprintf(line, sizeof(line), "%s: %" PRIu16 "\n", + tcpe_var_array[j].name, snap->val[j].uv16); + case TCPE_UNSIGNED8: + snprintf(line, sizeof(line), "%s: %" PRIu8 "\n", + tcpe_var_array[j].name, snap->val[j].uv8); + break; + default: + break; + } + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + log_print(9, "%s", line); + } + + /* This is the list of changed variable names that the client tries to read. + * Web100 -> Web10g + * ECNEnabled -> ECN + * NagleEnabled -> Nagle + * SACKEnabled -> WillSendSACK & WillUseSACK + * TimestampsEnabled -> TimeStamps + * PktsRetrans -> SegsRetrans + * X_Rcvbuf -> Not in web10g doesn't acutally use it so just leave it out + * DataPktsOut -> DataSegsOut + * AckPktsOut -> Depreciated + * MaxCwnd -> MaxSsCwnd MaxCaCwnd + * SndLimTimeSender -> SndLimTimeSnd + * DataBytesOut -> DataOctetsOut + * AckPktsIn -> Depreciated + * SndLimTransSender -> SndLimTransSnd + * PktsOut -> SegsOut + * CongestionSignals -> CongSignals + * RcvWinScale -> Same as WinScaleSent if WinScaleSent != -1 + */ + send_msg(ctlsock, TEST_MSG, "-~~~Web100_old_var_names~~~-: 1\n", strlen("-~~~Web100_old_var_names~~~-: 1\n")); + uint32_t temp; + + /* ECNEnabled -> ECN */ + val.uv64 = 0; + web10g_find_val(snap, "ECN", &val); + snprintf(line, sizeof(line), "ECNEnabled: %d\n", val.sv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* NagleEnabled -> Nagle */ + val.uv64 = 0; + web10g_find_val(snap, "Nagle", &val); + snprintf(line, sizeof(line), "NagleEnabled: %d\n", val.sv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* SACKEnabled -> WillUseSACK & WillSendSACK + * keep this in line with web100 for now i.e. 0 == off 1 == on */ + val.uv64 = 0; + web10g_find_val(snap, "WillUseSACK", &val); + snprintf(line, sizeof(line), "SACKEnabled: %d\n", (val.sv32 == 1) ? 1 : 0); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* TimestampsEnabled -> TimeStamps */ + val.uv64 = 0; + web10g_find_val(snap, "TimeStamps", &val); + snprintf(line, sizeof(line), "TimestampsEnabled: %d\n", val.sv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* PktsRetrans -> SegsRetrans */ + val.uv64 = 0; + web10g_find_val(snap, "SegsRetrans", &val); + snprintf(line, sizeof(line), "PktsRetrans: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* DataPktsOut -> DataSegsOut */ + val.uv64 = 0; + web10g_find_val(snap, "DataSegsOut", &val); + snprintf(line, sizeof(line), "DataPktsOut: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* MaxCwnd -> MaxSsCwnd MaxCaCwnd */ + val.uv64 = 0; + web10g_find_val(snap, "MaxSsCwnd", &val); + temp = val.uv32; + val.uv64 = 0; + web10g_find_val(snap, "MaxCaCwnd", &val); + temp = MAX(temp, val.uv32); + snprintf(line, sizeof(line), "DataPktsOut: %u\n", temp); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* SndLimTimeSender -> SndLimTimeSnd */ + val.uv64 = 0; + web10g_find_val(snap, "SndLimTimeSnd", &val); + snprintf(line, sizeof(line), "SndLimTimeSender: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* DataBytesOut -> DataOctetsOut */ + val.uv64 = 0; + web10g_find_val(snap, "DataOctetsOut", &val); + snprintf(line, sizeof(line), "DataBytesOut: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* SndLimTransSender -> SndLimTransSnd */ + val.uv64 = 0; + web10g_find_val(snap, "SndLimTransSnd", &val); + snprintf(line, sizeof(line), "SndLimTransSender: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* PktsOut -> SegsOut */ + val.uv64 = 0; + web10g_find_val(snap, "SegsOut", &val); + snprintf(line, sizeof(line), "PktsOut: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* CongestionSignals -> CongSignals */ + val.uv64 = 0; + web10g_find_val(snap, "CongSignals", &val); + snprintf(line, sizeof(line), "CongestionSignals: %u\n", val.uv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + /* RcvWinScale -> Same as WinScaleSent if WinScaleSent != -1 */ + val.uv64 = 0; + web10g_find_val(snap, "WinScaleSent", &val); + if( val.sv32 == -1) + snprintf(line, sizeof(line), "RcvWinScale: %u\n", 0); + else + snprintf(line, sizeof(line), "RcvWinScale: %d\n", val.sv32); + send_msg(ctlsock, TEST_MSG, line, strlen(line)); + + send_msg(ctlsock, TEST_MSG, "-~~~Web100_old_var_names~~~-: 1\n", strlen("-~~~Web100_old_var_names~~~-: 1\n")); + + log_println(6, "S2C test - Send web100 data to client pid=%d", getpid()); + return 0; +#endif } + +#ifdef FORCE_WEB100 /** * Calculate Web100 based Round-Trip Time (RTT) value. * @@ -417,7 +803,9 @@ sum = atoi(web100_value_to_text(web100_get_var_type(var), buf)); return (sum / count); } +#endif /* Appears to be unused so no need for web10g version */ + /** * Check if the "Auto Tune Send Buffer" and "Auto Tune Receive Buffer" options * are enabled and return status on each @@ -434,8 +822,8 @@ * 22 Cannot find X_SBufMode or X_RBufMode web100_variable's var/group. * 23 cannot read the value of the X_SBufMode or X_RBufMode web100_variable. */ - -int web100_autotune(int sock, web100_agent* agent, web100_connection* cn) { +int tcp_stat_autotune(int sock, tcp_stat_agent agent, tcp_stat_connection cn) { +#ifdef FORCE_WEB100 web100_var* var; char buf[32]; web100_group* group; @@ -476,8 +864,13 @@ if (i == 0) j |= 0x02; return (j); +#else /* web10g */ + return 0x03; /* Disabled, well web10g doesn't autotune the kernel does though */ +#endif } + +#ifdef FORCE_WEB100 /** * Check if the "Auto Tune Send Buffer" and "Auto Tune Receive Buffer" options * are enabled. If not, scale the Send window or receive window sizes based on the @@ -501,7 +894,7 @@ * 35 - cannot read value of RcvWinScale web100 variable. * */ -int web100_setbuff(int sock, web100_agent* agent, web100_connection* cn, +int tcp_stat_setbuff(int sock, tcp_stat_agent agent, tcp_stat_connection cn, int autotune) { web100_var* var; char buf[32]; @@ -566,114 +959,81 @@ return (0); } +#endif /* Not used so don't need to make web10g version */ /** - * @param sock integer socket file descriptor indicating data recipient - * @param pointers to local copies of web100 variables + * @param tcp_vars to local copies of web100 variables + * @param count_vars the number of web100 vars loaded * @return integer 0 * - * */ -int web100_logvars(int *Timeouts, int *SumRTT, int *CountRTT, int *PktsRetrans, - int *FastRetran, int *DataPktsOut, int *AckPktsOut, - int *CurrentMSS, int *DupAcksIn, int *AckPktsIn, - int *MaxRwinRcvd, int *Sndbuf, int *CurrentCwnd, - int *SndLimTimeRwin, int *SndLimTimeCwnd, - int *SndLimTimeSender, int *DataBytesOut, - int *SndLimTransRwin, int *SndLimTransCwnd, - int *SndLimTransSender, int *MaxSsthresh, int *CurrentRTO, - int *CurrentRwinRcvd, int *MaxCwnd, int *CongestionSignals, - int *PktsOut, int *MinRTT, int count_vars, int *RcvWinScale, - int *SndWinScale, int *CongAvoid, int *CongestionOverCount, - int *MaxRTT, int *OtherReductions, int *CurTimeoutCount, - int *AbruptTimeouts, int *SendStall, int *SlowStart, - int *SubsequentTimeouts, int *ThruBytesAcked) { - int i; +int tcp_stat_logvars(struct tcp_vars * vars, int count_vars) +{ +#ifdef FORCE_WEB100 + int a,b; + + for (a = 0; a < (sizeof(struct tcp_vars) / sizeof(tcp_stat_var)); a++) { + if(tcp_names[a].web100_name == NULL) + break; + + /* Find the corresponding value */ + for (b = 0; ;b++){ + if(b == (count_vars + 1)){ + log_println(1,"WARNING: Couldn't Find web100 var %s", tcp_names[a].web100_name); + break; + } + if(strcmp(web_vars[b].name, tcp_names[a].web100_name) == 0){ + ((tcp_stat_var *) vars)[a] = atoi(web_vars[b].value); + log_println(5, "Found %s : %i", tcp_names[a].web100_name, ((tcp_stat_var *) vars)[a]); + break; + } + + } - for (i = 0; i <= count_vars; i++) { - if (strcmp(web_vars[i].name, "Timeouts") == 0) - *Timeouts = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SumRTT") == 0) - *SumRTT = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CountRTT") == 0) - *CountRTT = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "PktsRetrans") == 0) - *PktsRetrans = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "FastRetran") == 0) - *FastRetran = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "DataPktsOut") == 0) - *DataPktsOut = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "AckPktsOut") == 0) - *AckPktsOut = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CurMSS") == 0) - *CurrentMSS = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "DupAcksIn") == 0) - *DupAcksIn = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "AckPktsIn") == 0) - *AckPktsIn = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "MaxRwinRcvd") == 0) - *MaxRwinRcvd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "X_Sndbuf") == 0) - *Sndbuf = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CurCwnd") == 0) - *CurrentCwnd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "MaxCwnd") == 0) - *MaxCwnd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTimeRwin") == 0) - *SndLimTimeRwin = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTimeCwnd") == 0) - *SndLimTimeCwnd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTimeSender") == 0) - *SndLimTimeSender = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "DataBytesOut") == 0) - *DataBytesOut = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTransRwin") == 0) - *SndLimTransRwin = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTransCwnd") == 0) - *SndLimTransCwnd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndLimTransSender") == 0) - *SndLimTransSender = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "MaxSsthresh") == 0) - *MaxSsthresh = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CurRTO") == 0) - *CurrentRTO = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CurRwinRcvd") == 0) - *CurrentRwinRcvd = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CongestionSignals") == 0) - *CongestionSignals = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "PktsOut") == 0) - *PktsOut = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "MinRTT") == 0) - *MinRTT = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "RcvWinScale") == 0) - *RcvWinScale = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SndWinScale") == 0) - *SndWinScale = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CongAvoid") == 0) - *CongAvoid = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CongestionOverCount") == 0) - *CongestionOverCount = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "MaxRTT") == 0) - *MaxRTT = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "OtherReductions") == 0) - *OtherReductions = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "CurTimeoutCount") == 0) - *CurTimeoutCount = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "AbruptTimeouts") == 0) - *AbruptTimeouts = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SendStall") == 0) - *SendStall = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SlowStart") == 0) - *SlowStart = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "SubsequentTimeouts") == 0) - *SubsequentTimeouts = atoi(web_vars[i].value); - else if (strcmp(web_vars[i].name, "ThruBytesAcked") == 0) - *ThruBytesAcked = atoi(web_vars[i].value); } + return 0; +#else /* web10g */ + int a,b; + + /* Set it to zero so we know what we are comparing to later */ + vars->MaxCwnd = 0; + + for (a = 0; a < (sizeof(struct tcp_vars) / sizeof(tcp_stat_var)); a++) { + if(tcp_names[a].web10g_name == NULL) + continue; + + /* Find the corresponding value */ + for (b = 0; ; b++){ + if(b == ARRAYSIZE(dataDumpSave->val)){ + log_println(1, "WARNING: Couldn't Find web10g var %s", tcp_names[a].web10g_name); + break; + } - return (0); + if (dataDumpSave->val[b].mask) continue; + if(strcmp(tcpe_var_array[b].name, tcp_names[a].web10g_name) == 0){ + ((tcp_stat_var *) vars)[a] = dataDumpSave->val[b].uv32; + log_println(5, "Found %s : %i", tcp_names[a].web10g_name, ((tcp_stat_var *) vars)[a]); + break; + } + } + + } + + /* Now lets deal to those things which are no longer in web10g */ + vars->AckPktsOut = 0; + vars->Sndbuf = X_Sndbuf; + vars->MaxCwnd = MAX(vars->MaxSsCwnd,vars->MaxCaCwnd); + + /* Free the data */ + tcpe_data_free(&dataDumpSave); + dataDumpSave = NULL; + return 0; +#endif } + + +#ifdef FORCE_WEB100 /** * Routine to read snaplog file and determine the number of times the * congestion window is reduced. @@ -687,7 +1047,7 @@ * @return Integer, 0 on success, -1 on failure */ -int CwndDecrease(web100_agent* agent, char* logname, u_int32_t *dec_cnt, +int CwndDecrease(tcp_stat_agent agent, char* logname, u_int32_t *dec_cnt, u_int32_t *same_cnt, u_int32_t *inc_cnt) { web100_var* var; char buff[256]; @@ -751,7 +1111,9 @@ *inc_cnt, *dec_cnt, *same_cnt); return (0); } +#endif /* web10g TODO when logging is do-able*/ +#ifdef FORCE_WEB100 /** * Generate TCP/IP checksum for our packet * @@ -939,3 +1301,4 @@ return (-1); return (0); } +#endif Index: src/web100-pcap.c =================================================================== --- src/web100-pcap.c (revision 796) +++ src/web100-pcap.c (working copy) @@ -90,6 +90,19 @@ pcap_freealldevs(alldevs); } +/** + * Force the pcap_loop to return, this is safe to call from a signal handler. + * Note this will break the loop without a packet being received if + * used from a signal handler due to the EINTR interrupting pcaps 'read'. + * + * This calls pcap_breakloop with the correct capture. + */ +void force_breakloop(){ + if (pd != NULL) { + pcap_breakloop(pd); + } +} + /** Check signal flags and process them accordingly. * If signal indicates request to terminate data collection for the speed bins, * make packet-pair based speed bins available to the parent process. @@ -97,7 +110,7 @@ * @return 1 if data was successfully written * 0 if no relevant signals were actually received */ -int check_signal_flags() { +static int check_signal_flags() { if ((sig1 == 1) || (sig2 == 1)) { log_println( 5, @@ -135,9 +148,6 @@ usleep(30000); /* wait here 30 msec, for parent to read this data */ print_bins(&rev, mon_pipe1); usleep(30000); /* wait here 30 msec, for parent to read this data */ - if (pd != NULL) { - pcap_breakloop(pd); - } if (dumptrace == 1) pcap_dump_close(pdump); sig1 = 2; @@ -175,9 +185,6 @@ usleep(30000); /* wait here 30 msec, for parent to read this data */ print_bins(&rev, mon_pipe2); usleep(30000); /* wait here 30 msec, for parent to read this data */ - if (pd != NULL) { - pcap_breakloop(pd); - } if (dumptrace == 1) pcap_dump_close(pdump); sig2 = 2; @@ -559,10 +566,6 @@ return; } - if (check_signal_flags()) { - return; - } - current.sec = h->ts.tv_sec; current.usec = h->ts.tv_usec; current.time = (current.sec * 1000000) + current.usec; @@ -787,7 +790,7 @@ void init_pkttrace(I2Addr srcAddr, struct sockaddr *sock_addr, socklen_t saddrlen, int monitor_pipe[2], char *device, - PortPair* pair, char *direction, int compress) { + PortPair* pair, const char*direction, int compress) { char cmdbuf[256], dir[256]; pcap_handler printer; u_char * pcap_userdata = (u_char*) pair; @@ -1046,6 +1049,11 @@ log_println(5, "pcap_loop exited %s", pcap_geterr(pd)); } + /* Send back results to our parent */ + if(check_signal_flags() == 0){ + log_println(5, "Whatever happened, we should have a sig flag set"); + } + pcap_close(pd); log_println( Index: src/test_c2s_srv.c =================================================================== --- src/test_c2s_srv.c (revision 796) +++ src/test_c2s_srv.c (working copy) @@ -61,10 +61,13 @@ * -102 - Retries exceeded while waiting for data from connected client * */ -int test_c2s(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, +int test_c2s(int ctlsockfd, tcp_stat_agent agent, TestOptions* testOptions, int conn_options, double* c2sspd, int set_buff, int window, int autotune, char* device, Options* options, int record_reverse, int count_vars, char spds[4][256], int* spd_index) { + tcp_stat_connection conn; + /* Group only used for web100 */ + tcp_stat_group group = NULL; int recvsfd; // receiver socket file descriptor pid_t c2s_childpid = 0; // child process pids int msgretvalue, tmpbytecount; // used during the "read"/"write" process @@ -85,14 +88,12 @@ char listenc2sport[10]; // listening port pthread_t workerThreadId; - // web_100 related variables - web100_group* group = NULL; - web100_connection* conn = NULL; - // snap related variables SnapArgs snapArgs; snapArgs.snap = NULL; +#ifdef FORCE_WEB100 snapArgs.log = NULL; +#endif snapArgs.delay = options->snapDelay; wait_sig = 0; @@ -253,7 +254,7 @@ I2Addr src_addr = I2AddrByLocalSockFD(get_errhandle(), recvsfd, 0); // Get web100 connection. Used to collect web100 variable statistics - conn = web100_connection_from_socket(agent, recvsfd); + conn = tcp_stat_connection_from_socket(agent, recvsfd); // set up packet tracing. Collected data is used for bottleneck link // calculations @@ -281,10 +282,13 @@ &cli_addr); init_pkttrace(src_addr, (struct sockaddr *) &cli_addr, clilen, mon_pipe1, device, &pair, "c2s", options->compress); + log_println(1, "C2S is exiting gracefully"); exit(0); /* Packet trace finished, terminate gracefully */ } // Get data collected from packet tracing into the C2S "ndttrace" file + /* What is this actually doing? Its seems to be waiting for + * "Ready" to come through on the pipe ?? */ memset(tmpstr, 0, 256); for (i = 0; i < 5; i++) { msgretvalue = read(mon_pipe1[0], tmpstr, 128); @@ -292,7 +296,7 @@ continue; break; } - if (strlen(tmpstr) > 5) + // if (strlen(tmpstr) > 5) memcpy(meta.c2s_ndttrace, tmpstr, strlen(tmpstr)); // name of nettrace file passed back from pcap child log_println(3, "--tracefile after packet_trace %s", @@ -331,6 +335,7 @@ } start_snap_worker(&snapArgs, agent, NULL, options->snaplog, &workerThreadId, meta.c2s_snaplog, options->c2s_logname, conn, group); + // Wait on listening socket and read data once ready. tmptime = secs(); sel_tv.tv_sec = 11; // time out after 11 seconds @@ -375,14 +380,20 @@ // get receiver side Web100 stats and write them to the log file. close // sockets if (record_reverse == 1) - web100_get_data_recv(recvsfd, agent, conn, count_vars); - close(recvsfd); - close(testOptions->c2ssockfd); + tcp_stat_get_data_recv(recvsfd, agent, conn, count_vars); + /*close(recvsfd); + close(testOptions->c2ssockfd);*/ + // Lets move these :) + // Next, send speed-chk a flag to retrieve the data it collected. // Skip this step if speed-chk isn't running. + // Now close sockets once data is recevied + close(recvsfd); + close(testOptions->c2ssockfd); + if (getuid() == 0) { log_println(1, "Signal USR1(%d) sent to child [%d]", SIGUSR1, c2s_childpid); @@ -434,7 +445,7 @@ } } } - + // An empty TEST_FINALIZE message is sent to conclude the test send_msg(ctlsockfd, TEST_FINALIZE, "", 0); Index: src/test_s2c_srv.c =================================================================== --- src/test_s2c_srv.c (revision 796) +++ src/test_s2c_srv.c (working copy) @@ -25,7 +25,7 @@ extern pthread_mutex_t mainmutex; extern pthread_cond_t maincond; -// used to store file descriptors of pipes created for ndttrace for C2S tests +// used to store file descriptors of pipes created for ndttrace for S2C tests int mon_pipe2[2]; /** @@ -46,7 +46,7 @@ * @param testOptions - the test options * @param conn_options - the connection options * @param testOptions Test options - * @param s2cspd In-out parameter to store C2S throughput value + * @param s2cspd In-out parameter to store S2C throughput value * @param set_buff enable setting TCP send/recv buffer size to be used (seems unused in file) * @param window value of TCP send/rcv buffer size intended to be used. * @param autotune autotuning option. Deprecated. @@ -70,10 +70,26 @@ * -102 - Retries exceeded while waiting for data from connected client * -errno - Other specific socket error numbers */ -int test_s2c(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, + +int test_s2c(int ctlsockfd, tcp_stat_agent agent, TestOptions* testOptions, int conn_options, double* s2cspd, int set_buff, int window, int autotune, char* device, Options* options, char spds[4][256], int* spd_index, int count_vars, CwndPeaks* peaks) { +#ifdef FORCE_WEB100 + /* experimental code to capture and log multiple copies of the + * web100 variables using the web100_snap() & log() functions. + */ + web100_snapshot* tsnap = NULL; + web100_snapshot* rsnap = NULL; + web100_group* tgroup; + web100_group* rgroup; + web100_var* var; +#else /* web10g */ + tcpe_data* snap; +#endif + tcp_stat_connection conn; + /* Just a holder for web10g */ + tcp_stat_group group; int ret; // ctrl protocol read/write return status int j, k, n; int xmitsfd; // transmit (i.e server) socket fd @@ -101,16 +117,6 @@ int sndqueue; struct sigaction new, old; - /* experimental code to capture and log multiple copies of the - * web100 variables using the web100_snap() & log() functions. - */ - web100_snapshot* tsnap = NULL; - web100_snapshot* rsnap = NULL; - web100_group* group; - web100_group* tgroup; - web100_group* rgroup; - web100_connection* conn; - web100_var* var; pthread_t workerThreadId; int nextseqtosend = 0, lastunackedseq = 0; int drainingqueuecount = 0, bufctlrnewdata = 0; @@ -124,7 +130,9 @@ SnapArgs snapArgs; snapArgs.snap = NULL; +#ifdef FORCE_WEB100 snapArgs.log = NULL; +#endif snapArgs.delay = options->snapDelay; wait_sig = 0; @@ -224,7 +232,7 @@ clilen = sizeof(cli_addr); FD_ZERO(&rfd); - FD_SET(testOptions->c2ssockfd, &rfd); + FD_SET(testOptions->s2csockfd, &rfd); sel_tv.tv_sec = 5; // wait for 5 secs sel_tv.tv_usec = 0; for (j = 0; j < RETRY_COUNT; j++) { @@ -276,8 +284,9 @@ } } src_addr = I2AddrByLocalSockFD(get_errhandle(), xmitsfd, 0); - conn = web100_connection_from_socket(agent, xmitsfd); + conn = tcp_stat_connection_from_socket(agent, xmitsfd); + // set up packet capture. The data collected is used for bottleneck link // calculations if (xmitsfd > 0) { @@ -326,8 +335,9 @@ /* experimental code, delete when finished */ setCwndlimit(conn, group, agent, options); + /* End of test code */ - + // create directory to write web100 snaplog trace create_client_logdir((struct sockaddr *) &cli_addr, clilen, options->s2c_logname, sizeof(options->s2c_logname), @@ -340,10 +350,15 @@ // system("/sbin/sysctl -w net.ipv4.route.flush=1"); system("echo 1 > /proc/sys/net/ipv4/route/flush"); } +#ifdef FORCE_WEB100 rgroup = web100_group_find(agent, "read"); rsnap = web100_snapshot_alloc(rgroup, conn); tgroup = web100_group_find(agent, "tune"); tsnap = web100_snapshot_alloc(tgroup, conn); +#else /* Web10g */ + /* One data snap includes all 'groups' in web10g */ + tcpe_data_new(&snap); +#endif // fill send buffer with random printable data for throughput test bytes_written = 0; @@ -392,6 +407,7 @@ if (options->avoidSndBlockUp) { // Do not block send buffers pthread_mutex_lock(&mainmutex); +#ifdef FORCE_WEB100 // get details of next sequence # to be sent and fetch value from // snap file web100_agent_find_var_and_group(agent, "SndNxt", &group, @@ -407,6 +423,16 @@ lastunackedseq = atoi( web100_value_to_text(web100_get_var_type(var), tmpstr)); +#else /* web10g */ + struct tcpe_val value; + // get details of next sequence # to be sent and fetch value from + // snap file + web10g_find_val(snapArgs.snap, "SndNxt", &value); + nextseqtosend = value.uv32; + // get oldest un-acked sequence number + web10g_find_val(snapArgs.snap, "SndUna", &value); + lastunackedseq = value.uv32; +#endif pthread_mutex_unlock(&mainmutex); // Temporarily stop sending data if you sense that the buffer is @@ -462,9 +488,12 @@ log_println(6, "S2C test - failed to send test message to pid=%d", s2c_childpid); - +#ifdef FORCE_WEB100 web100_snap(rsnap); web100_snap(tsnap); +#else /* web10g */ + tcpe_read_vars(snap, conn, agent); +#endif log_println(1, "sent %d bytes to client in %0.2f seconds", (int) bytes_written, tx_duration); @@ -545,13 +574,18 @@ /* alarm(30); */ // Get web100 variables from snapshot taken earlier and send to client log_println(6, "S2C-Send web100 data vars to client pid=%d", - s2c_childpid); + s2c_childpid); +#ifdef FORCE_WEB100 // send web100 data to client - ret = web100_get_data(tsnap, ctlsockfd, agent, count_vars); + ret = tcp_stat_get_data(tsnap, xmitsfd, ctlsockfd, agent, count_vars); web100_snapshot_free(tsnap); // send tuning-related web100 data collected to client - ret = web100_get_data(rsnap, ctlsockfd, agent, count_vars); + ret = tcp_stat_get_data(rsnap, xmitsfd, ctlsockfd, agent, count_vars); web100_snapshot_free(rsnap); +#else /* web10g*/ + ret = tcp_stat_get_data(snap, xmitsfd, ctlsockfd, agent, count_vars); + tcpe_data_free(&snap); +#endif // If sending web100 variables above failed, indicate to client if (ret < 0) { Index: src/test_sfw_srv.c =================================================================== --- src/test_sfw_srv.c (revision 796) +++ src/test_sfw_srv.c (working copy) @@ -120,8 +120,9 @@ * 5 - Unable to resolve client address */ -int test_sfw_srv(int ctlsockfd, web100_agent* agent, TestOptions* options, +int test_sfw_srv(int ctlsockfd, tcp_stat_agent agent, TestOptions* options, int conn_options) { + char buff[BUFFSIZE + 1]; I2Addr sfwsrv_addr = NULL; int sfwsockfd, sfwsockport, sockfd, sfwport; @@ -130,9 +131,14 @@ fd_set fds; struct timeval sel_tv; int msgLen, msgType; +#ifdef FORCE_WEB100 web100_var* var; web100_connection* cn; web100_group* group; +#else /* Must be web10g */ + struct tcpe_val value; + int cn; +#endif int maxRTT, maxRTO; char hostname[256]; int rc; @@ -169,26 +175,40 @@ sfwsockport = I2AddrPort(sfwsrv_addr); log_println(1, " -- port: %d", sfwsockport); - cn = web100_connection_from_socket(agent, ctlsockfd); + + cn = tcp_stat_connection_from_socket(agent, ctlsockfd); + if (cn) { // Get remote end's address + memset(hostname, 0, sizeof(hostname)); +#ifdef FORCE_WEB100 web100_agent_find_var_and_group(agent, "RemAddress", &group, &var); web100_raw_read(var, cn, buff); - memset(hostname, 0, 256); + // strncpy(hostname, web100_value_to_text(web100_get_var_type(var), buff), // 255); strlcpy(hostname, web100_value_to_text(web100_get_var_type(var), buff), sizeof(hostname)); +#else /* Must be web10g */ + web10g_get_remote_addr(agent, cn, hostname, sizeof(hostname)); +#endif // Determine test time in seconds. // test-time = max(round trip time, timeout) > 3 ? 3 : 1 +#ifdef FORCE_WEB100 web100_agent_find_var_and_group(agent, "MaxRTT", &group, &var); web100_raw_read(var, cn, buff); maxRTT = atoi(web100_value_to_text(web100_get_var_type(var), buff)); web100_agent_find_var_and_group(agent, "MaxRTO", &group, &var); web100_raw_read(var, cn, buff); maxRTO = atoi(web100_value_to_text(web100_get_var_type(var), buff)); +#else /* Must be web10g */ + web10g_get_val(agent, cn, "MaxRTT", &value); + maxRTT = value.uv32; + web10g_get_val(agent, cn, "MaxRTO", &value); + maxRTO = value.uv32; +#endif if (maxRTT > maxRTO) maxRTO = maxRTT; if ((((double) maxRTO) / 1000.0) > 3.0) Index: src/testoptions.c =================================================================== --- src/testoptions.c (revision 796) +++ src/testoptions.c (working copy) @@ -24,11 +24,12 @@ // Worker thread characteristics used to record snaplog and Cwnd peaks typedef struct workerArgs { SnapArgs* snapArgs; // snapArgs struct pointer - web100_agent* agent; // web_100 agent pointer + tcp_stat_agent agent; // web_100/10g agent pointer CwndPeaks* peaks; // data indicating Cwnd values int writeSnap; // enable writing snaplog } WorkerArgs; + int workerLoop = 0; pthread_mutex_t mainmutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t maincond = PTHREAD_COND_INITIALIZER; @@ -45,16 +46,28 @@ * @param snap Web100 snapshot structure */ +#ifdef FORCE_WEB100 void findCwndPeaks(web100_agent* agent, CwndPeaks* peaks, web100_snapshot* snap) { web100_group* group; web100_var* var; + char tmpstr[256]; +#else /* Must be web10g */ +void findCwndPeaks(struct tcpe_client * client, CwndPeaks* peaks, + tcpe_data* snap) { + struct tcpe_val value; +#endif int CurCwnd; - char tmpstr[256]; + +#ifdef FORCE_WEB100 web100_agent_find_var_and_group(agent, "CurCwnd", &group, &var); web100_snap_read(var, snap, tmpstr); CurCwnd = atoi(web100_value_to_text(web100_get_var_type(var), tmpstr)); +#else /* Must be web10g */ + web10g_find_val(snap, "CurCwnd", &value); + CurCwnd = value.uv32; +#endif if (slowStart) { if (CurCwnd < prevCWNDval) { @@ -108,9 +121,12 @@ void* snapWorker(void* arg) { + /* WARNING void* arg i.e workerArgs is on the stack of the function + * below and doesn't exist forever start_snap_worker and is valid for + * a very short time*/ WorkerArgs *workerArgs = (WorkerArgs*) arg; SnapArgs *snapArgs = workerArgs->snapArgs; - web100_agent* agent = workerArgs->agent; + tcp_stat_agent agent = workerArgs->agent; CwndPeaks* peaks = workerArgs->peaks; int writeSnap = workerArgs->writeSnap; @@ -136,6 +152,7 @@ pthread_mutex_unlock(&mainmutex); break; } +#ifdef FORCE_WEB100 web100_snap(snapArgs->snap); if (peaks) { findCwndPeaks(agent, peaks, snapArgs->snap); @@ -143,6 +160,15 @@ if (writeSnap) { web100_log_write(snapArgs->log, snapArgs->snap); } +#else /* Must be web10g */ + tcpe_read_vars(snapArgs->snap, snapArgs->conn, agent); + if (peaks) { + findCwndPeaks(agent, peaks, snapArgs->snap); + } + if (writeSnap) { + /* TODO logging */ + } +#endif pthread_mutex_unlock(&mainmutex); mysleep(delay); } @@ -258,21 +284,26 @@ * @param web100_connection connection pointer * @param web100_group group web100_group pointer */ -void start_snap_worker(SnapArgs *snaparg, web100_agent *agentarg, + +void start_snap_worker(SnapArgs *snaparg, tcp_stat_agent agentarg, CwndPeaks* peaks, char snaplogenabled, pthread_t *wrkrthreadidarg, char *metafilevariablename, - char *metafilename, web100_connection* conn, - web100_group* group) { + char *metafilename, tcp_stat_connection conn, + tcp_stat_group group) { FILE *fplocal; WorkerArgs workerArgs; workerArgs.snapArgs = snaparg; - workerArgs.agent = agentarg; workerArgs.peaks = peaks; workerArgs.writeSnap = snaplogenabled; - + workerArgs.agent = agentarg; + snaparg->conn = conn; // Not actaully used by web100 +#ifdef FORCE_WEB100 group = web100_group_find(agentarg, "read"); snaparg->snap = web100_snapshot_alloc(group, conn); +#else /* web10g */ + tcpe_data_new(&snaparg->snap); +#endif if (snaplogenabled) { // memcpy(metafilevariablename, metafilename, strlen(metafilename)); @@ -280,7 +311,9 @@ // just the file name, but full filename is needed to open the log file fplocal = fopen(get_logfile(), "a"); +#ifdef FORCE_WEB100 snaparg->log = web100_log_open_write(metafilename, conn, group); +#endif /* TODO web10g logging */ if (fplocal == NULL) { log_println( 0, @@ -302,10 +335,16 @@ pthread_mutex_lock(&mainmutex); workerLoop= 1; // obtain web100 snap into "snaparg.snap" +#ifdef FORCE_WEB100 web100_snap(snaparg->snap); if (snaplogenabled) { web100_log_write(snaparg->log, snaparg->snap); } +#else /* web10g */ + tcpe_read_vars(snaparg->snap, conn, agentarg); + /* TODO logging */ +#endif + pthread_cond_wait(&maincond, &mainmutex); pthread_mutex_unlock(&mainmutex); } @@ -325,11 +364,17 @@ pthread_join(*workerThreadId, NULL); } // close writing snaplog, if snaplog recording is enabled +#ifdef FORCE_WEB100 if (snaplogenabled) { web100_log_close_write(snapArgs_ptr->log); } +#endif /* TODO web10g */ +#ifdef FORCE_WEB100 web100_snapshot_free(snapArgs_ptr->snap); +#else /* web10g */ + tcpe_data_free(&snapArgs_ptr->snap); +#endif } /** @@ -415,9 +460,14 @@ * @param group_arg web100 group pointer * @param agentarg web100 agent pointer * */ -void setCwndlimit(web100_connection* connarg, web100_group* grouparg, - web100_agent* agentarg, Options* optionsarg) { + +void setCwndlimit(tcp_stat_connection connarg, tcp_stat_group grouparg, + tcp_stat_agent agentarg, Options* optionsarg) { +#ifdef FORCE_WEB100 web100_var *LimRwin, *yar; +#else /* web10g */ + struct tcpe_val LimRwin, yar; +#endif u_int32_t limrwin_val; char yuff[32]; @@ -427,6 +477,7 @@ if (connarg != NULL) { log_println(1, "Got web100 connection pointer for recvsfd socket\n"); +#ifdef FORCE_WEB100 web100_agent_find_var_and_group(agentarg, "CurMSS", &grouparg, &yar); web100_raw_read(yar, connarg, yuff); @@ -442,6 +493,15 @@ log_print(1, "now write %d to limit the Receive window", limrwin_val); web100_raw_write(LimRwin, connarg, &limrwin_val); +#else /* web10g */ + web10g_get_val(agentarg, connarg, "CurMSS", &yar); + log_println(1, "MSS = %s, multiplication factor = %d", yar.uv32 , + optionsarg->limit); + limrwin_val = optionsarg->limit * yar.uv32; + log_print(1, "now write %d to limit the Receive window", + limrwin_val); + tcpe_write_var("LimRwin", limrwin_val , connarg, agentarg); +#endif log_println(1, " --- Done"); } } Index: src/web10g-util.c =================================================================== --- src/web10g-util.c (revision 0) +++ src/web10g-util.c (revision 0) @@ -0,0 +1,234 @@ +/* + * A handful of functions to handle some web10g specific stuff + * + * Author: Richard Sanger + * + */ + +/* + * These are used to pass information between web10g_connection_from_socket + * and getremote_callback. It would be nice if these were not globals. + */ +#include "web100srv.h" +#include "logging.h" + +static struct sockaddr_storage local_name; +static struct sockaddr_storage peer_name; +static int connection_id; + +/** + * Callback function used by web10g_connection_from_socket, will set + * connection_id if the correct connection is found. + * + * @param ct A tuple containing connection information + */ +static void fromsocket_callback(struct tcpe_connection_tuple* ct){ + + /* I'm assuming local_name and remote_name should both be on + * the same addressing scheme i.e. either IPv4 or IPv6 not a mix of both */ + + if(local_name.ss_family == AF_INET && peer_name.ss_family == AF_INET){ + /* We are IPv4 check if this web10g connection also is */ + if((ct->local_addr[16]) == TCPE_ADDRTYPE_IPV4 + && (ct->rem_addr[16]) == TCPE_ADDRTYPE_IPV4){ + + struct sockaddr_in * ipv4_local = (struct sockaddr_in *) &local_name; + struct sockaddr_in * ipv4_peer = (struct sockaddr_in *) &peer_name; + + /* Compare local and remote ports and addresses */ + if(ct->local_port == ntohs(ipv4_local->sin_port) && + ct->rem_port == ntohs(ipv4_peer->sin_port) && + ((struct in_addr *) ct->rem_addr)->s_addr == ipv4_peer->sin_addr.s_addr && + ((struct in_addr *) ct->local_addr)->s_addr == ipv4_local->sin_addr.s_addr ){ + + /* Found it */ + connection_id = ct->cid; + log_println(2, "Matched socket to web10g IPv4 connection #%d", connection_id); + } + } + } else if(local_name.ss_family == AF_INET6){ + /* We are IPv6 check if this web10g connection also is */ + if((ct->local_addr[16]) == TCPE_ADDRTYPE_IPV6 + && (ct->rem_addr[16]) == TCPE_ADDRTYPE_IPV6){ + + struct sockaddr_in6 * ipv6_local = (struct sockaddr_in6 *) &local_name; + struct sockaddr_in6 * ipv6_peer = (struct sockaddr_in6 *) &peer_name; + + /* Compare local and remote ports and addresses */ + if(ct->local_port == ntohs(ipv6_local->sin6_port) && + ct->rem_port == ntohs(ipv6_peer->sin6_port) && + memcmp(ct->rem_addr, ipv6_peer->sin6_addr.s6_addr, sizeof(struct in6_addr)) == 0 && + memcmp(ct->local_addr, ipv6_local->sin6_addr.s6_addr, sizeof(struct in6_addr)) == 0){ + + /* Found it */ + connection_id = ct->cid; + log_println(2, "Matched socket to web10g IPv6 connection #%d", connection_id); + } + } + } +} + +/** + * Find the web100 connection number related to a given socket. + * + * @param client A web10g client + * @param sockfd The socket file descriptor + * + * @return The connection number if successful. If an error occurs -1 + * will be returned. + * + */ +int web10g_connection_from_socket(struct tcpe_client * client,int sockfd){ + socklen_t local_name_len; + socklen_t peer_name_len; + + local_name_len = sizeof(local_name); + peer_name_len = sizeof(peer_name); + connection_id = -1; + + /* Get the ip address of ourself on the localsocket */ + if (getsockname(sockfd,(struct sockaddr *) &local_name, &local_name_len) == -1) { + log_println(1, "getsockname() failed: %s ", strerror(errno)); + return -1; + } + + /* Get the ip address of our peer */ + if (getpeername(sockfd,(struct sockaddr *) &peer_name, &peer_name_len) == -1) { + log_println(1, "getpeername() failed: %s ", strerror(errno)); + return -1; + } + + tcpe_list_conns(client, fromsocket_callback); + + return connection_id; +} + +/** + * Find the specified web10g variable given a connection at the current + * time. + * Similar to web10g_find_val except this also retrieves data from web10g + * rather than from a provided capture. If many varibles are being read + * it's probably best to capture the data then use web10g_find_val. + * + * @param data A web10g data capture + * @param name The web10g variable name + * @param *value A pointer to a web10g value structure. If successful + * this will contain the requested value upon return. If an error occurs + * it's contents will remain untouched. + * + * @return int 0 if successful otherwise 1 in the event of an error + * (including the case the specified value cannot be found). + * + */ +int web10g_get_val(struct tcpe_client * client, int conn, char * name, struct tcpe_val * value){ + int i; + tcpe_data* data = NULL; + + tcpe_data_new(&data); + tcpe_read_vars(data, conn, client); + + for (i = 0; i < ARRAYSIZE(data->val); i++){ + if (data->val[i].mask) continue; + + if (strcmp(tcpe_var_array[i].name, name) == 0){ + value->uv64 = data->val[i].uv64; + value->mask = data->val[i].mask; + i = -1; + break; + } + } + + tcpe_data_free(&data); + if(i == -1) + return 1; + else + return 0; +} + +/* + * These are used to pass information between web10g_get_remote_addr + * and getremotecallback. It would be nice if these were not globals. + */ +static int connid; +static char * remote_name; +static int remote_name_size; + +/** + * Callback function used by web10g_get_remote_addr, will fill in + * remote_name once if the correct connection is found and set remote_name + * to NULL to indicate to web10g_get_remote_addr that the connection was + * found. + * + * @param ct A tuple containing connection information + * + */ +static void getremote_callback(struct tcpe_connection_tuple* ct){ + if( ct->cid == connid && ct->local_addr[16] == TCPE_ADDRTYPE_IPV4){ + inet_ntop(AF_INET, &(ct->rem_addr[0]), remote_name, remote_name_size); + remote_name = NULL; + } else if( ct->cid == connid && ct->local_addr[16] == TCPE_ADDRTYPE_IPV6){ + inet_ntop(AF_INET6, &(ct->rem_addr[0]), remote_name, remote_name_size); + remote_name = NULL; + } +} + +/** + * Get the remote address given connection number + * + * @param client Web10g client + * @param conn The web10g connection number + * @param out A pointer to a character buffer, into which the remote + * address will be returned if successful. Upon error the contents are + * remain unchanged. + * @param size The size of the buffer 'out'. + * + * @return int 0 if successful otherwise 1 in the event of an error + * (The connection could not be found). + * + */ +int web10g_get_remote_addr(struct tcpe_client * client, int conn, char * out, int size){ + /* Pass these to the callback routine using those globals */ + connid = conn; + remote_name = out; + remote_name_size = size; + /* This will call the getremote_callback once for every tcp connection */ + tcpe_list_conns(client, getremote_callback); + + if(remote_name == NULL) + return 0; + else + return 1; +} + +/** + * Find the specified web10g variables value within a provided capture. + * Similar to web10g_get_val except this works on a previously retrieved + * set of data. + * + * @param data A web10g data capture + * @param name The web10g variable name + * @param *value A pointer to a web10g value structure. If successful + * this will contain the requested value upon return. If an error occurs + * its contents will remain untouched. + * + * @return int 0 if successful otherwise 1 in the event of an error + * (including the case the specified value cannot be found). + * + */ +int web10g_find_val(tcpe_data* data, char * name, struct tcpe_val * value){ + int i; + + if(data == NULL || name == NULL || value == NULL) + return 1; + + for (i = 0; i < ARRAYSIZE(data->val); i++){ + if (data->val[i].mask) continue; + if (strcmp(tcpe_var_array[i].name, name) == 0){ + value->uv64 = data->val[i].uv64; + value->mask = data->val[i].mask; + return 0; + } + } + + return 1; +} Index: src/testoptions.h =================================================================== --- src/testoptions.h (revision 796) +++ src/testoptions.h (working copy) @@ -47,11 +47,13 @@ // Snap log characteristics typedef struct snapArgs { - web100_snapshot* snap; // web_100 snapshot indicator - web100_log* log; // web_100 log + tcp_stat_connection conn; // Only needed by web10g + tcp_stat_snap snap; // web_100 snapshot indicator + tcp_stat_log log; // web_100 log (TODO - not used by 10g yet) int delay; // periodicity, in ms, of collecting snap } SnapArgs; + int wait_sig; int initialize_tests(int ctlsockfd, TestOptions* testOptions, @@ -59,27 +61,24 @@ void catch_s2c_alrm(int signo); -int test_sfw_srv(int ctlsockfd, web100_agent* agent, TestOptions* options, +int test_sfw_srv(int ctlsockfd, tcp_stat_agent agent, TestOptions* options, int conn_options); -int test_meta_srv(int ctlsockfd, web100_agent* agent, TestOptions* options, +int test_meta_srv(int ctlsockfd, tcp_stat_agent not_usedagent, TestOptions* testOptions, int conn_options); +void start_snap_worker(SnapArgs *snaparg, tcp_stat_agent agentarg, + CwndPeaks* peaks, char snaplogenabled, + pthread_t *wrkrthreadidarg, char *metafilevariablename, + char *metafilename, tcp_stat_connection conn, + tcp_stat_group group); +void setCwndlimit(tcp_stat_connection connarg, tcp_stat_group grouparg, + tcp_stat_agent agentarg, Options* optionsarg); int getCurrentTest(); void setCurrentTest(int testId); -// void start_snap_worker(SnapArgs *snaparg, web100_agent *agentarg, -void start_snap_worker(SnapArgs *snaparg, web100_agent *agentarg, - CwndPeaks* peaks, char snaplogenabled, - pthread_t *wrkrthreadidarg, char *metafilevariablename, - char *metafilename, web100_connection* conn, - web100_group* group); - void stop_snap_worker(pthread_t *workerThreadId, char snaplogenabled, SnapArgs* snapArgs_ptr); -void setCwndlimit(web100_connection* connarg, web100_group* grouparg, - web100_agent* agentarg, Options* optionsarg); - int is_buffer_clogged(int nextseqtosend, int lastunackedseq); void stop_packet_trace(int *monpipe_arr); Index: src/web100clt.c =================================================================== --- src/web100clt.c (revision 796) +++ src/web100clt.c (working copy) @@ -19,6 +19,8 @@ #include "clt_tests.h" #include "strlutils.h" #include "test_results_clt.h" +#include +#include extern int h_errno; @@ -237,6 +239,29 @@ } /** + * Get a string representation of an ip address. + * + * @param addr A sockaddr structure which contains the address + * @param buf A buffer to fill with the ip address as a string + * @param len The length of buf. + */ +static void addr2a(struct sockaddr_storage * addr,char * buf, int len){ + + if(((struct sockaddr *)addr)->sa_family == AF_INET){ + /* IPv4 */ + inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), + buf, len); + } +#ifdef AF_INET6 + else if(((struct sockaddr *)addr)->sa_family == AF_INET6 ){ + /* IPv6 */ + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)addr)->sin6_addr), + buf, len); + } +#endif +} + +/** * This routine decodes the middlebox test results. The data is returned * from the server in a specific order. This routine pulls the string apart * and puts the values into the proper variable. It then compares the values @@ -247,14 +272,14 @@ * Client then adds * Server IP; Client IP. * @param midresult_str String containing test results - * @param local_addr Client IP address - * @param peer_addr Server IP address + * @param cltsock Used to get address information */ -void middleboxResults(char *midresult_str, I2Addr local_addr, - I2Addr peer_addr) { +void middleboxResults(char *midresult_str, int cltsock) { char ssip[64], scip[64], *str; char csip[64], ccip[64]; + struct sockaddr_storage addr; + socklen_t addr_size; int mss; size_t tmpLen; @@ -271,14 +296,27 @@ winssent = atoi(str); str = strtok(NULL, ";"); winsrecv = atoi(str); - - memset(ccip, 0, 64); + + /* Get the our local ip address */ + addr_size = sizeof(addr); + memset(csip, 0, 64); tmpLen = 63; - I2AddrNodeName(local_addr, ccip, &tmpLen); + if (getsockname(cltsock,(struct sockaddr *) &addr, &addr_size) == -1) { + perror("Middlebox - getsockname() failed"); + } else { + addr2a(&addr, ccip , tmpLen); + } + + /* Get the Server ip address */ + addr_size = sizeof(addr); memset(csip, 0, 64); tmpLen = 63; - I2AddrNodeName(peer_addr, csip, &tmpLen); - + if (getpeername(cltsock,(struct sockaddr *) &addr, &addr_size) == -1) { + perror("Middlebox - getpeername() failed"); + } else { + addr2a(&addr, csip , tmpLen); + } + // Check if MSS modification is happening check_MSS_modification(TimestampsEnabled, &mss); @@ -486,7 +524,6 @@ int testId; // test ID received from server // addresses.. I2Addr server_addr = NULL; - I2Addr local_addr = NULL, remote_addr = NULL; char* ptr; #ifdef AF_INET6 #define GETOPT_LONG_INET6(x) "46"x @@ -854,9 +891,7 @@ log_println(6, "resultstr = '%s'", resultstr); } - local_addr = I2AddrByLocalSockFD(get_errhandle(), ctlSocket, False); - remote_addr = I2AddrBySockFD(get_errhandle(), ctlSocket, False); - I2AddrFree(server_addr); + strlcpy(varstr, resultstr, sizeof(varstr)); // print test results @@ -864,9 +899,11 @@ // print middlebox test results if (tests & TEST_MID) { - middleboxResults(mid_resultstr, local_addr, remote_addr); + middleboxResults(mid_resultstr, ctlSocket); } - + + I2AddrFree(server_addr); + // print extra information collected from web100 variables if ((tests & TEST_S2C) && (msglvl > 1)) printVariables(varstr); Index: src/test_mid_srv.c =================================================================== --- src/test_mid_srv.c (revision 796) +++ src/test_mid_srv.c (working copy) @@ -9,7 +9,7 @@ * Author: kkumar */ -#include +#include #include #include #include @@ -48,8 +48,7 @@ * 3 Ð Received message is invalid * */ - -int test_mid(int ctlsockfd, web100_agent* agent, TestOptions* options, +int test_mid(int ctlsockfd, tcp_stat_agent agent, TestOptions* options, int conn_options, double* s2c_throughput_mid) { int maxseg = ETHERNET_MTU_SIZE; /* int maxseg=1456, largewin=16*1024*1024; */ @@ -66,7 +65,9 @@ char listenmidport[10]; // listener socket for middlebox tests int msgType; int msgLen; - web100_connection* conn; + + tcp_stat_connection conn; + char tmpstr[256]; // temporary string storage struct timeval sel_tv; // time fd_set rfd; // receiver file descriptor @@ -236,7 +237,7 @@ buff[0] = '\0'; // get web100 connection data - if ((conn = web100_connection_from_socket(agent, midsfd)) == NULL) { + if ((conn = tcp_stat_connection_from_socket(agent, midsfd)) == 0) { log_println( 0, "!!!!!!!!!!! test_mid() failed to get web100 connection data, rc=%d", @@ -246,7 +247,7 @@ } // Perform S->C throughput test. Obtained results in "buff" - web100_middlebox(midsfd, agent, conn, buff, sizeof(buff)); + tcp_stat_middlebox(midsfd, agent, conn, buff, sizeof(buff)); // Transmit results in the form of a TEST_MSG message send_msg(ctlsockfd, TEST_MSG, buff, strlen(buff)); Index: src/test_meta_srv.c =================================================================== --- src/test_meta_srv.c (revision 796) +++ src/test_meta_srv.c (working copy) @@ -22,7 +22,7 @@ /** * Performs the META test. * @param ctlsockfd Client control socket descriptor - * @param agent Web100 agent used to track the connection + * @param not_usedagent Web100 agent or tcpe client used to track the connection not used * @param testOptions The test options * @param conn_options The connection options * @return 0 - success, @@ -38,7 +38,7 @@ * 4 - Invalid data format in received message */ -int test_meta_srv(int ctlsockfd, web100_agent* agent, TestOptions* testOptions, +int test_meta_srv(int ctlsockfd, tcp_stat_agent not_usedagent, TestOptions* testOptions, int conn_options) { int j; int msgLen, msgType; Index: src/web100-admin.c =================================================================== --- src/web100-admin.c (revision 796) +++ src/web100-admin.c (working copy) @@ -17,6 +17,7 @@ #include "web100-admin.h" #include "utils.h" #include "strlutils.h" +#include "heuristics.h" /* Initialize the Administrator view. Process the data in the existing log file to * catch up on what's happened before. Index: src/Makefile.am =================================================================== --- src/Makefile.am (revision 796) +++ src/Makefile.am (working copy) @@ -25,7 +25,7 @@ if HAVE_WEB100 bin_PROGRAMS = web100clt analyze viewtrace tr-mkmap genplot if HAVE_PCAP_H -sbin_PROGRAMS = fakewww web100srv +sbin_PROGRAMS = fakewww web100srv else sbin_PROGRAMS = fakewww endif @@ -33,6 +33,22 @@ bin_PROGRAMS = web100clt endif +if HAVE_TCPE +if HAVE_WEB100 +if HAVE_PCAP_H +sbin_PROGRAMS += web10gsrv +endif +endif +endif + +if HAVE_TCPE +if !HAVE_WEB100 +if HAVE_PCAP_H +sbin_PROGRAMS = fakewww web10gsrv +endif +endif +endif + web100clt_SOURCES = web100clt.c network.c usage.c logging.c utils.c protocol.c runningtest.c ndtptestconstants.c \ test_sfw_clt.c test_mid_clt.c test_c2s_clt.c test_s2c_clt.c test_meta_clt.c strlutils.c \ test_results_clt.c @@ -46,7 +62,7 @@ analyze_SOURCES = analyze.c usage.c logging.c runningtest.c ndtptestconstants.c strlutils.c analyze_LDADD = $(NDTLIBS) $(I2UTILLIBDEPS) $(ZLIB) -analyze_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' +analyze_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' -DFORCE_WEB100 fakewww_SOURCES = fakewww.c troute.c troute6.c tr-tree.c tr-tree6.c network.c usage.c logging.c \ runningtest.c ndtptestconstants.c strlutils.c @@ -59,12 +75,21 @@ test_c2s_srv.c test_s2c_srv.c test_mid_srv.c web100srv_LDFLAGS = $(NDTLDFLAGS) $(I2UTILLDFLAGS) web100srv_LDADD = $(NDTLIBS) $(I2UTILLIBS) $(I2UTILLIBDEPS) -lpthread $(ZLIB) -web100srv_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' +web100srv_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' -DFORCE_WEB100 web100srv_DEPENDENCIES = $(I2UTILLIBDEPS) +web10gsrv_SOURCES = web100srv.c web100-util.c web100-pcap.c web100-admin.c runningtest.c \ + network.c usage.c utils.c mrange.c logging.c testoptions.c ndtptestconstants.c \ + protocol.c test_sfw_srv.c test_meta_srv.c ndt_odbc.c strlutils.c heuristics.c \ + test_c2s_srv.c test_s2c_srv.c test_mid_srv.c web10g-util.c +web10gsrv_LDFLAGS = $(NDTLDFLAGS) $(I2UTILLDFLAGS) +web10gsrv_LDADD = $(NDTLIBS) $(I2UTILLIBS) $(I2UTILLIBDEPS) -lpthread $(ZLIB) +web10gsrv_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' +web10gsrv_DEPENDENCIES = $(I2UTILLIBDEPS) + viewtrace_SOURCES = viewtrace.c usage.c logging.c utils.c runningtest.c ndtptestconstants.c strlutils.c viewtrace_LDADD = $(NDTLIBS) $(I2UTILLIBDEPS) $(ZLIB) -viewtrace_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' +viewtrace_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' -DFORCE_WEB100 tr_mkmap_SOURCES = tr-mkmap.c tr-tree.c tr-tree6.c usage.c logging.c runningtest.c ndtptestconstants.c strlutils.c tr_mkmap_LDADD = $(NDTLIBS) $(I2UTILLIBDEPS) $(ZLIB) Index: src/web100srv.c =================================================================== --- src/web100srv.c (revision 796) +++ src/web100srv.c (working copy) @@ -468,17 +468,19 @@ } exit(0); case SIGUSR1: + /* SIGUSR1 is used exclusively by C2S, to interrupt the pcap capture*/ log_println(6, - "DEBUG, caught SIGUSR1, setting sig1 flag to force exit"); + "DEBUG, caught SIGUSR1, setting sig1 flag and calling force_breakloop"); + force_breakloop(); sig1 = 1; - /* check_signal_flags(); */ break; case SIGUSR2: + /* SIGUSR2 is used exclusively by S2C, to interrupt the pcap capture*/ log_println(6, - "DEBUG, caught SIGUSR2, setting sig2 flag to force exit"); + "DEBUG, caught SIGUSR2, setting sig2 flag and calling force_breakloop"); + force_breakloop(); sig2 = 1; - /* check_signal_flags(); */ break; case SIGALRM: @@ -552,8 +554,7 @@ case SIGHUP: /* Initialize Web100 structures */ - count_vars = web100_init(VarFileName); - + count_vars = tcp_stat_init(VarFileName); /* The administrator view automatically generates a usage page for the * NDT server. This page is then accessable to the general public. * At this point read the existing log file and generate the necessary @@ -628,8 +629,12 @@ set_debuglvl(atoi(val)); continue; } else if (strncasecmp(key, "variable_file", 6) == 0) { +#ifdef FORCE_WEB100 snprintf(wvfn, sizeof(wvfn), "%s", val); VarFileName = wvfn; +#else + log_println(0, "WEB10G doesn't need a variable file, ignoring"); +#endif continue; } else if (strncasecmp(key, "log_file", 3) == 0) { snprintf(lgfn, sizeof(lgfn), "%s", val); @@ -834,12 +839,6 @@ recv_msg(tmp_ptr->ctlsockfd, &msgType, buff, &msgLen); tmp_ptr = tmp_ptr->next; pre_ptr = pre_ptr->next; - /* - if ((sig1 > 0) || (sig2 > 0)) - check_signal_flags(); - if (sig17 > 0) - child_sig(0); - */ break; case -1: // some error status if (errno == EINTR) { @@ -899,8 +898,9 @@ * @param test_suite pointer to string indicating tests to be run * */ -int run_test(web100_agent* agent, int ctlsockfd, TestOptions* testopt, +int run_test(tcp_stat_agent agent, int ctlsockfd, TestOptions* testopt, char *test_suite) { + tcp_stat_connection conn; char date[32]; // date indicator char spds[4][256]; // speed "bin" array containing counters for speeds char logstr1[4096], logstr2[1024]; // log @@ -908,18 +908,10 @@ char isoTime[64]; // int n; // temporary iterator variable --// commented out -> calc_linkspeed - int Timeouts, SumRTT, CountRTT, PktsRetrans, FastRetran, DataPktsOut; - int AckPktsOut, CurrentMSS, DupAcksIn, AckPktsIn, MaxRwinRcvd, Sndbuf; - int CurrentCwnd, SndLimTimeRwin, SndLimTimeCwnd, SndLimTimeSender, - DataBytesOut; - int SndLimTransRwin, SndLimTransCwnd, SndLimTransSender, MaxSsthresh; - int CurrentRTO, CurrentRwinRcvd, MaxCwnd, CongestionSignals, PktsOut, - MinRTT; - int CongAvoid, CongestionOverCount, MaxRTT, OtherReductions, - CurTimeoutCount = 0; - int AbruptTimeouts, SendStall, SlowStart, SubsequentTimeouts, - ThruBytesAcked; - int RcvWinScale, SndWinScale; + + /* TCP variables used in calculations */ + struct tcp_vars vars; + int link = CANNOT_DETERMINE_LINK; // local temporary variable indicative of // link speed. Transmitted but unused at client end , which has a similar // link speed variable @@ -974,8 +966,6 @@ FILE * fp; - web100_connection* conn; - // start with a clean slate of currently running test and direction setCurrentTest(TEST_NONE); log_println(7, "Remote host= %s", get_remotehost()); @@ -989,11 +979,11 @@ for (ret = 0; ret < 256; ret++) spds[spd_index][ret] = 0x00; spd_index = 0; - + // obtain web100 connection and check auto-tune status - conn = web100_connection_from_socket(agent, ctlsockfd); - autotune = web100_autotune(ctlsockfd, agent, conn); - + conn = tcp_stat_connection_from_socket(agent, ctlsockfd); + autotune = tcp_stat_autotune(ctlsockfd, agent, conn); + // client needs to be version compatible. Send current version snprintf(buff, sizeof(buff), "v%s", VERSION); send_msg(ctlsockfd, MSG_LOGIN, buff, strlen(buff)); @@ -1086,75 +1076,70 @@ // Get web100 vars // ...determine number of times congestion window has been changed +#ifdef FORCE_WEB100 if (options.cwndDecrease) { dec_cnt = inc_cnt = same_cnt = 0; CwndDecrease(agent, options.s2c_logname, &dec_cnt, &same_cnt, &inc_cnt); log_println(2, "####### decreases = %d, increases = %d, no change = %d", dec_cnt, inc_cnt, same_cnt); } - +#endif +/* TODO remove #ifdef once CwndDecrease has a web10g version + * looks like these variables dec_cnt ... are only used here and logged.*/ + // ...other variables - web100_logvars(&Timeouts, &SumRTT, &CountRTT, &PktsRetrans, &FastRetran, - &DataPktsOut, &AckPktsOut, &CurrentMSS, &DupAcksIn, &AckPktsIn, - &MaxRwinRcvd, &Sndbuf, &CurrentCwnd, &SndLimTimeRwin, - &SndLimTimeCwnd, &SndLimTimeSender, &DataBytesOut, - &SndLimTransRwin, &SndLimTransCwnd, &SndLimTransSender, - &MaxSsthresh, &CurrentRTO, &CurrentRwinRcvd, &MaxCwnd, - &CongestionSignals, &PktsOut, &MinRTT, count_vars, - &RcvWinScale, &SndWinScale, &CongAvoid, &CongestionOverCount, - &MaxRTT, &OtherReductions, &CurTimeoutCount, &AbruptTimeouts, - &SendStall, &SlowStart, &SubsequentTimeouts, &ThruBytesAcked); + tcp_stat_logvars(&vars, count_vars); // end getting web100 variable values /* if (rc == 0) { */ // section to calculate duplex mismatch // Calculate average round trip time and convert to seconds - rttsec = calc_avg_rtt(SumRTT, CountRTT, &avgrtt); + rttsec = calc_avg_rtt(vars.SumRTT, vars.CountRTT, &avgrtt); // Calculate packet loss - packetloss_s2c = calc_packetloss(CongestionSignals, PktsOut, + packetloss_s2c = calc_packetloss(vars.CongestionSignals, vars.PktsOut, c2s_linkspeed_data); // Calculate ratio of packets arriving out of order - oo_order = calc_packets_outoforder(DupAcksIn, AckPktsIn); + oo_order = calc_packets_outoforder(vars.DupAcksIn, vars.AckPktsIn); // calculate theoretical maximum goodput in bits - bw_theortcl = calc_max_theoretical_throughput(CurrentMSS, rttsec, + bw_theortcl = calc_max_theoretical_throughput(vars.CurrentMSS, rttsec, packetloss_s2c); // get window sizes - calc_window_sizes(&SndWinScale, &RcvWinScale, Sndbuf, MaxRwinRcvd, - MaxCwnd, &rwin, &swin, &cwin); + calc_window_sizes(&vars.SndWinScale, &vars.RcvWinScale, vars.Sndbuf, vars.MaxRwinRcvd, + vars.MaxCwnd, &rwin, &swin, &cwin); // Total test time - totaltime = calc_totaltesttime(SndLimTimeRwin, SndLimTimeCwnd, - SndLimTimeSender); + totaltime = calc_totaltesttime(vars.SndLimTimeRwin, vars.SndLimTimeCwnd, + vars.SndLimTimeSender); // time spent being send-limited due to client's recv window - rwintime = calc_sendlimited_rcvrfault(SndLimTimeRwin, totaltime); + rwintime = calc_sendlimited_rcvrfault(vars.SndLimTimeRwin, totaltime); // time spent in being send-limited due to congestion window - cwndtime = calc_sendlimited_cong(SndLimTimeCwnd, totaltime); + cwndtime = calc_sendlimited_cong(vars.SndLimTimeCwnd, totaltime); // time spent in being send-limited due to own fault - sendtime = calc_sendlimited_sndrfault(SndLimTimeSender, totaltime); + sendtime = calc_sendlimited_sndrfault(vars.SndLimTimeSender, totaltime); timesec = totaltime / MEGA; // total time in microsecs // get fraction of total test time waiting for packets to arrive - RTOidle = calc_RTOIdle(Timeouts, CurrentRTO, timesec); + RTOidle = calc_RTOIdle(vars.Timeouts, vars.CurrentRTO, timesec); // get timeout, retransmission, acks and dup acks ratios. - tmoutsratio = (double) Timeouts / PktsOut; - rtranratio = (double) PktsRetrans / PktsOut; - acksratio = (double) AckPktsIn / PktsOut; - dackratio = (double) DupAcksIn / (double) AckPktsIn; + tmoutsratio = (double) vars.Timeouts / vars.PktsOut; + rtranratio = (double) vars.PktsRetrans / vars.PktsOut; + acksratio = (double) vars.AckPktsIn / vars.PktsOut; + dackratio = (double) vars.DupAcksIn / (double) vars.AckPktsIn; // get actual throughput in Mbps (totaltime is in microseconds) - realthruput = calc_real_throughput(DataBytesOut, totaltime); + realthruput = calc_real_throughput(vars.DataBytesOut, totaltime); // total time spent waiting - waitsec = cal_totalwaittime(CurrentRTO, Timeouts); + waitsec = cal_totalwaittime(vars.CurrentRTO, vars.Timeouts); log_println(2, "CWND limited test = %0.2f while unlimited = %0.2f", s2c2spd, s2cspd); @@ -1175,8 +1160,8 @@ old_mismatch = 1; if (old_mismatch == 1) { - if (detect_duplexmismatch(cwndtime, bw_theortcl, PktsRetrans, timesec, - MaxSsthresh, RTOidle, link, s2cspd, s2c2spd, + if (detect_duplexmismatch(cwndtime, bw_theortcl, vars.PktsRetrans, timesec, + vars.MaxSsthresh, RTOidle, link, s2cspd, s2c2spd, multiple)) { if (is_c2s_throughputbetter(c2sspd, s2cspd)) { // also, S->C throughput is lesser than C->S throughput @@ -1213,7 +1198,7 @@ // Faulty hardware link heuristic. if (detect_faultyhardwarelink(packetloss_s2c, cwndtime, timesec, - MaxSsthresh)) + vars.MaxSsthresh)) bad_cable = POSSIBLE_BAD_CABLE; // test for Ethernet link (assume Fast E.) @@ -1222,12 +1207,12 @@ link = LINK_ETHERNET; // test for wireless link - if (detect_wirelesslink(sendtime, realthruput, bw_theortcl, SndLimTransRwin, - SndLimTransCwnd, rwintime, link)) + if (detect_wirelesslink(sendtime, realthruput, bw_theortcl, vars.SndLimTransRwin, + vars.SndLimTransCwnd, rwintime, link)) link = LINK_WIRELESS; // test for DSL/Cable modem link - if (detect_DSLCablelink(SndLimTimeSender, SndLimTransSender, realthruput, + if (detect_DSLCablelink(vars.SndLimTimeSender, vars.SndLimTransSender, realthruput, bw_theortcl, link)) link = LINK_DSLORCABLE; @@ -1238,7 +1223,7 @@ // ...and the number of transitions into the 'Sender Limited' state is // greater than 30 per second - if (detect_halfduplex(rwintime, SndLimTransRwin, SndLimTransSender, + if (detect_halfduplex(rwintime, vars.SndLimTransRwin, vars.SndLimTransSender, timesec)) half_duplex = POSSIBLE_HALF_DUPLEX; @@ -1272,7 +1257,7 @@ snprintf(buff, sizeof(buff), "cwin: %0.4f\nrttsec: %0.6f\nSndbuf: %d\naspd: %0.5f\n" - "CWND-Limited: %0.2f\n", cwin, rttsec, Sndbuf, aspd, s2c2spd); + "CWND-Limited: %0.2f\n", cwin, rttsec, vars.Sndbuf, aspd, s2c2spd); send_msg(ctlsockfd, MSG_RESULTS, buff, strlen(buff)); snprintf(buff, sizeof(buff), @@ -1295,15 +1280,15 @@ memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr), "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", - (int) s2c2spd, (int) s2cspd, (int) c2sspd, Timeouts, SumRTT, - CountRTT, PktsRetrans, FastRetran, DataPktsOut, AckPktsOut, - CurrentMSS, DupAcksIn, AckPktsIn); + (int) s2c2spd, (int) s2cspd, (int) c2sspd, vars.Timeouts, vars.SumRTT, + vars.CountRTT, vars.PktsRetrans, vars.FastRetran, vars.DataPktsOut, vars.AckPktsOut, + vars.CurrentMSS, vars.DupAcksIn, vars.AckPktsIn); memcpy(meta.summary, tmpstr, strlen(tmpstr)); memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr), "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", - MaxRwinRcvd, Sndbuf, MaxCwnd, SndLimTimeRwin, SndLimTimeCwnd, - SndLimTimeSender, DataBytesOut, SndLimTransRwin, SndLimTransCwnd, - SndLimTransSender, MaxSsthresh, CurrentRTO, CurrentRwinRcvd); + vars.MaxRwinRcvd, vars.Sndbuf, vars.MaxCwnd, vars.SndLimTimeRwin, vars.SndLimTimeCwnd, + vars.SndLimTimeSender, vars.DataBytesOut, vars.SndLimTransRwin, vars.SndLimTransCwnd, + vars.SndLimTransSender, vars.MaxSsthresh, vars.CurrentRTO, vars.CurrentRwinRcvd); strlcat(meta.summary, tmpstr, sizeof(meta.summary)); memset(tmpstr, 0, sizeof(tmpstr)); @@ -1314,15 +1299,15 @@ memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr), ",%d,%d,%d,%d,%d,%d,%d,%d,%d", c2s_linkspeed_data, c2s_linkspeed_ack, s2c_linkspeed_data, - s2c_linkspeed_ack, CongestionSignals, PktsOut, MinRTT, RcvWinScale, + s2c_linkspeed_ack, vars.CongestionSignals, vars.PktsOut, vars.MinRTT, vars.RcvWinScale, autotune); strlcat(meta.summary, tmpstr, sizeof(meta.summary)); memset(tmpstr, 0, sizeof(tmpstr)); - snprintf(tmpstr, sizeof(tmpstr), ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", CongAvoid, - CongestionOverCount, MaxRTT, OtherReductions, CurTimeoutCount, - AbruptTimeouts, SendStall, SlowStart, SubsequentTimeouts, - ThruBytesAcked); + snprintf(tmpstr, sizeof(tmpstr), ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", vars.CongAvoid, + vars.CongestionOverCount, vars.MaxRTT, vars.OtherReductions, vars.CurTimeoutCount, + vars.AbruptTimeouts, vars.SendStall, vars.SlowStart, vars.SubsequentTimeouts, + vars.ThruBytesAcked); strlcat(meta.summary, tmpstr, sizeof(meta.summary)); memset(tmpstr, 0, sizeof(tmpstr)); @@ -1342,39 +1327,39 @@ snprintf(date, sizeof(date), "%15.15s", ctime(&stime) + 4); fprintf(fp, "%s,", date); fprintf(fp, "%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", rmt_host, - (int) s2c2spd, (int) s2cspd, (int) c2sspd, Timeouts, SumRTT, - CountRTT, PktsRetrans, FastRetran, DataPktsOut, AckPktsOut, - CurrentMSS, DupAcksIn, AckPktsIn); - fprintf(fp, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", MaxRwinRcvd, - Sndbuf, MaxCwnd, SndLimTimeRwin, SndLimTimeCwnd, - SndLimTimeSender, DataBytesOut, SndLimTransRwin, - SndLimTransCwnd, SndLimTransSender, MaxSsthresh, CurrentRTO, - CurrentRwinRcvd); + (int) s2c2spd, (int) s2cspd, (int) c2sspd, vars.Timeouts, vars.SumRTT, + vars.CountRTT, vars.PktsRetrans, vars.FastRetran, vars.DataPktsOut, vars.AckPktsOut, + vars.CurrentMSS, vars.DupAcksIn, vars.AckPktsIn); + fprintf(fp, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", vars.MaxRwinRcvd, + vars.Sndbuf, vars.MaxCwnd, vars.SndLimTimeRwin, vars.SndLimTimeCwnd, + vars.SndLimTimeSender, vars.DataBytesOut, vars.SndLimTransRwin, + vars.SndLimTransCwnd, vars.SndLimTransSender, vars.MaxSsthresh, vars.CurrentRTO, + vars.CurrentRwinRcvd); fprintf(fp, "%d,%d,%d,%d,%d", link, mismatch, bad_cable, half_duplex, congestion); fprintf(fp, ",%d,%d,%d,%d,%d,%d,%d,%d,%d", c2s_linkspeed_data, c2s_linkspeed_ack, s2c_linkspeed_data, s2c_linkspeed_ack, - CongestionSignals, PktsOut, MinRTT, RcvWinScale, autotune); - fprintf(fp, ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", CongAvoid, - CongestionOverCount, MaxRTT, OtherReductions, CurTimeoutCount, - AbruptTimeouts, SendStall, SlowStart, SubsequentTimeouts, - ThruBytesAcked); + vars.CongestionSignals, vars.PktsOut, vars.MinRTT, vars.RcvWinScale, autotune); + fprintf(fp, ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", vars.CongAvoid, + vars.CongestionOverCount, vars.MaxRTT, vars.OtherReductions, vars.CurTimeoutCount, + vars.AbruptTimeouts, vars.SendStall, vars.SlowStart, vars.SubsequentTimeouts, + vars.ThruBytesAcked); fprintf(fp, ",%d,%d,%d\n", peaks.min, peaks.max, peaks.amount); fclose(fp); } db_insert(spds, runave, cputimelog, options.s2c_logname, options.c2s_logname, testName, testPort, date, rmt_host, s2c2spd, - s2cspd, c2sspd, Timeouts, SumRTT, CountRTT, PktsRetrans, FastRetran, - DataPktsOut, AckPktsOut, CurrentMSS, DupAcksIn, AckPktsIn, - MaxRwinRcvd, Sndbuf, MaxCwnd, SndLimTimeRwin, SndLimTimeCwnd, - SndLimTimeSender, DataBytesOut, SndLimTransRwin, SndLimTransCwnd, - SndLimTransSender, MaxSsthresh, CurrentRTO, CurrentRwinRcvd, link, + s2cspd, c2sspd, vars.Timeouts, vars.SumRTT, vars.CountRTT, vars.PktsRetrans, vars.FastRetran, + vars.DataPktsOut, vars.AckPktsOut, vars.CurrentMSS, vars.DupAcksIn, vars.AckPktsIn, + vars.MaxRwinRcvd, vars.Sndbuf, vars.MaxCwnd, vars.SndLimTimeRwin, vars.SndLimTimeCwnd, + vars.SndLimTimeSender, vars.DataBytesOut, vars.SndLimTransRwin, vars.SndLimTransCwnd, + vars.SndLimTransSender, vars.MaxSsthresh, vars.CurrentRTO, vars.CurrentRwinRcvd, link, mismatch, bad_cable, half_duplex, congestion, c2s_linkspeed_data, c2s_linkspeed_ack, s2c_linkspeed_data, s2c_linkspeed_ack, - CongestionSignals, PktsOut, MinRTT, RcvWinScale, autotune, - CongAvoid, CongestionOverCount, MaxRTT, OtherReductions, - CurTimeoutCount, AbruptTimeouts, SendStall, SlowStart, - SubsequentTimeouts, ThruBytesAcked, peaks.min, peaks.max, + vars.CongestionSignals, vars.PktsOut, vars.MinRTT, vars.RcvWinScale, autotune, + vars.CongAvoid, vars.CongestionOverCount, vars.MaxRTT, vars.OtherReductions, + vars.CurTimeoutCount, vars.AbruptTimeouts, vars.SendStall, vars.SlowStart, + vars.SubsequentTimeouts, vars.ThruBytesAcked, peaks.min, peaks.max, peaks.amount); if (usesyslog == 1) { snprintf( @@ -1382,19 +1367,19 @@ "client_IP=%s,c2s_spd=%2.0f,s2c_spd=%2.0f,Timeouts=%d,SumRTT=%d," "CountRTT=%d,PktsRetrans=%d,FastRetran=%d,DataPktsOut=%d,AckPktsOut=%d," "CurrentMSS=%d,DupAcksIn=%d,AckPktsIn=%d,", - rmt_host, c2sspd, s2cspd, Timeouts, SumRTT, CountRTT, - PktsRetrans, FastRetran, DataPktsOut, AckPktsOut, CurrentMSS, - DupAcksIn, AckPktsIn); + rmt_host, c2sspd, s2cspd, vars.Timeouts, vars.SumRTT, vars.CountRTT, + vars.PktsRetrans, vars.FastRetran, vars.DataPktsOut, vars.AckPktsOut, vars.CurrentMSS, + vars.DupAcksIn, vars.AckPktsIn); snprintf( logstr2, sizeof(logstr2), "MaxRwinRcvd=%d,Sndbuf=%d,MaxCwnd=%d,SndLimTimeRwin=%d," "SndLimTimeCwnd=%d,SndLimTimeSender=%d,DataBytesOut=%d," "SndLimTransRwin=%d,SndLimTransCwnd=%d,SndLimTransSender=%d," "MaxSsthresh=%d,CurrentRTO=%d,CurrentRwinRcvd=%d,", - MaxRwinRcvd, Sndbuf, MaxCwnd, SndLimTimeRwin, SndLimTimeCwnd, - SndLimTimeSender, DataBytesOut, SndLimTransRwin, - SndLimTransCwnd, SndLimTransSender, MaxSsthresh, CurrentRTO, - CurrentRwinRcvd); + vars.MaxRwinRcvd, vars.Sndbuf, vars.MaxCwnd, vars.SndLimTimeRwin, vars.SndLimTimeCwnd, + vars.SndLimTimeSender, vars.DataBytesOut, vars.SndLimTransRwin, + vars.SndLimTransCwnd, vars.SndLimTransSender, vars.MaxSsthresh, vars.CurrentRTO, + vars.CurrentRwinRcvd); strlcat(logstr1, logstr2, sizeof(logstr1)); snprintf( logstr2, sizeof(logstr2), @@ -1403,7 +1388,7 @@ "CongestionSignals=%d,PktsOut=%d,MinRTT=%d,RcvWinScale=%d\n", link, mismatch, bad_cable, half_duplex, congestion, c2s_linkspeed_data, c2s_linkspeed_ack, s2c_linkspeed_data, s2c_linkspeed_ack, - CongestionSignals, PktsOut, MinRTT, RcvWinScale); + vars.CongestionSignals, vars.PktsOut, vars.MinRTT, vars.RcvWinScale); strlcat(logstr1, logstr2, sizeof(logstr1)); syslog(LOG_FACILITY | LOG_INFO, "%s", logstr1); closelog(); @@ -1421,14 +1406,14 @@ * updated. Otherwise the changes are lost when the client terminates. */ if (admin_view == 1) { - totalcnt = calculate(date, SumRTT, CountRTT, CongestionSignals, PktsOut, - DupAcksIn, AckPktsIn, CurrentMSS, SndLimTimeRwin, - SndLimTimeCwnd, SndLimTimeSender, MaxRwinRcvd, - CurrentCwnd, Sndbuf, DataBytesOut, mismatch, bad_cable, + totalcnt = calculate(date, vars.SumRTT, vars.CountRTT, vars.CongestionSignals, vars.PktsOut, + vars.DupAcksIn, vars.AckPktsIn, vars.CurrentMSS, vars.SndLimTimeRwin, + vars.SndLimTimeCwnd, vars.SndLimTimeSender, vars.MaxRwinRcvd, + vars.CurrentCwnd, vars.Sndbuf, vars.DataBytesOut, mismatch, bad_cable, (int) c2sspd, (int) s2cspd, c2s_linkspeed_data, s2c_linkspeed_ack, 1); - gen_html((int) c2sspd, (int) s2cspd, MinRTT, PktsRetrans, Timeouts, - Sndbuf, MaxRwinRcvd, CurrentCwnd, mismatch, bad_cable, totalcnt, + gen_html((int) c2sspd, (int) s2cspd, vars.MinRTT, vars.PktsRetrans, vars.Timeouts, + vars.Sndbuf, vars.MaxRwinRcvd, vars.CurrentCwnd, mismatch, bad_cable, totalcnt, refresh); } shutdown(ctlsockfd, SHUT_WR); @@ -1444,7 +1429,12 @@ * @param argc Number of arguments * @param argv string command line arguments * */ -int main(int argc, char** argv) { + int main(int argc, char** argv) { +#ifndef FORCE_WEB100 + /* web10g */ + struct tcpe_error* err = NULL; +#endif + tcp_stat_agent agent = NULL; pid_t chld_pid = -1; int retcode; int tpid, mwaiting = 0; @@ -1453,7 +1443,7 @@ int i, loopcnt, t_opts = 0; struct sockaddr_storage cli_addr; struct sigaction new; - web100_agent* agent; + char *lbuf = NULL, *ctime(); char buff[32], tmpstr[256]; char test_suite[16]; @@ -1464,7 +1454,6 @@ struct ndtchild *tmp_ptr = NULL, *new_child = NULL, *mchild = NULL; time_t tt; socklen_t clilen; - I2Addr listenaddr = NULL; int listenfd; char* srcname = NULL; @@ -1616,7 +1605,11 @@ admin_view = 1; break; case 'f': +#ifdef FORCE_WEB100 VarFileName = optarg; +#else /* Web10G */ + log_println(2, "WEB10g doesn't need a varfile, ignored"); +#endif break; case 'i': device = optarg; @@ -1817,11 +1810,17 @@ err_sys("server: CreateListenSocket failed"); } listenfd = I2AddrFD(listenaddr); - + + if(listenfd == -1){ + /* If socket isn't opened this will segfault at FDSET for the select */ + log_println(0, "ERROR: Socket already in use this wont work"); + return 0; + } log_println(1, "server ready on port %s", port); - // Initialize Web100 structures - count_vars = web100_init(VarFileName); + /* Initialize Web100 structures */ + count_vars = tcp_stat_init(VarFileName); + if (count_vars == -1) { log_println(0, "No web100 variables file found, terminating program"); exit(-5); @@ -1889,7 +1888,7 @@ // RAC 7/14/09 get_iflist(); - + for (i = 0; iflist.speed[i] > 0; i++) log_println(4, "Generated iflist with device=%s and if_speed=%d", iflist.name[i], iflist.speed[i]); @@ -1923,11 +1922,6 @@ "zombie_check=%d", head_ptr->pid, testing, waiting, mclients, zombie_check); - // moved condition from interrupt handler to here - /* if ((sig1 > 0) || (sig2 > 0)) - * check_signal_flags; - */ - if (sig13 == 1) { log_println(5, "todo: Handle SIGPIPE signal, terminate child?"); child_sig(0); @@ -2599,11 +2593,18 @@ "pid=%d", chld_pipe[0], chld_pipe[1], chld_pid); close(listenfd); close(chld_pipe[1]); +#ifdef FORCE_WEB100 if ((agent = web100_attach(WEB100_AGENT_TYPE_LOCAL, NULL)) == NULL) { web100_perror("web100_attach"); return 1; } +#else + if (tcpe_client_init(&agent) != NULL ){ + log_println(0, "Error: tcpe_client_init failed unable to use web10g"); + return 1; + } +#endif // This is the child process from the above fork(). The parent // is in control, and will send this child a signal when it gets @@ -2727,7 +2728,11 @@ child_sig(0); } close(ctlsockfd); +#ifdef FORCE_WEB100 web100_detach(agent); +#else + tcpe_client_destroy(&agent); +#endif log_free(); if (cputime && workerThreadId) { Index: configure.ac =================================================================== --- configure.ac (revision 796) +++ configure.ac (working copy) @@ -145,6 +145,18 @@ INCLUDED_WEB100LIB="" AM_CONDITIONAL(HAVE_WEB100, false) ]) +AC_CHECK_LIB([tcpe], [tcpe_client_init], + [ + LINKED_TCPELIB="-ltcpe" + INCLUDED_TCPELIB="-I/usr/local/include/tcpe" + AC_DEFINE(HAVE_LIBTCPE, 1, [Define to 1 if you have the 'Web10G' library (-ltcpe).]) + AM_CONDITIONAL(HAVE_TCPE, true) + ], + [ + LINKED_TCPELIB="" + INCLUDED_TCPELIB="" + AM_CONDITIONAL(HAVE_TCPE, false) + ]) AC_CHECK_LIB([pcap], [pcap_open_live], [ @@ -197,14 +209,16 @@ ]) -NDTINCDIR='$(INCLUDED_WEB100LIB) $(INCLUDED_PCAPLIB)' +NDTINCDIR='$(INCLUDED_WEB100LIB) $(INCLUDED_PCAPLIB) $(INCLUDED_TCPELIB)' NDTLIBDIR=/usr/local/lib NDTLDFLAGS='-L$(NDTLIBDIR) -Wl,-rpath,$(NDTLIBDIR)' -NDTLIBS='$(LINKED_WEB100LIB) $(LINKED_PCAPLIB) $(LINKED_ODBCLIB) -lm' +NDTLIBS='$(LINKED_WEB100LIB) $(LINKED_PCAPLIB) $(LINKED_ODBCLIB) $(LINKED_TCPELIB) -lm' NDTINCS='-I$(NDTINCDIR)' AC_SUBST(LINKED_WEB100LIB) AC_SUBST(INCLUDED_WEB100LIB) +AC_SUBST(LINKED_TCPELIB) +AC_SUBST(INCLUDED_TCPELIB) AC_SUBST(LINKED_PCAPLIB) AC_SUBST(INCLUDED_PCAPLIB) AC_SUBST(LINKED_ODBCLIB) @@ -275,6 +289,12 @@ echo "" echo "" +if test -z "$HAVE_TCPE_TRUE" && test -n "$HAVE_TCPE_FALSE"; then +SUMMARY_WEB10GSRV="YES" +else +SUMMARY_WEB10GSRV="NO (missing tcpe (web10g) library)" +fi + SUMMARY_WEB100CLT="YES" if test -z "$HAVE_WEB100_TRUE" && test -n "$HAVE_WEB100_FALSE"; then if test -z "$HAVE_PCAP_H_TRUE" && test -n "$HAVE_PCAP_H_FALSE"; then @@ -314,13 +334,14 @@ echo "* web100clt: ${SUMMARY_WEB100CLT}" echo "" -if test "$SUMMARY_FAKEWWW" = "YES" && test "$SUMMARY_WEB100SRV" = "YES" && test "$SUMMARY_TCPBW100JAR" = "YES"; then +if test "$SUMMARY_FAKEWWW" = "YES" && (test "$SUMMARY_WEB100SRV" = "YES" || test "$SUMMARY_WEB10GSRV" = "YES") && test "$SUMMARY_TCPBW100JAR" = "YES"; then echo "*** Server Tools - complete" else echo "*** Server Tools - incomplete" fi echo "* fakewww: ${SUMMARY_FAKEWWW}" echo "* web100srv: ${SUMMARY_WEB100SRV}" +echo "* web10gsrv: ${SUMMARY_WEB10GSRV}" echo "* Tcpbw100.jar: ${SUMMARY_TCPBW100JAR}" echo "" Index: Applet/Tcpbw100.java =================================================================== --- Applet/Tcpbw100.java (revision 796) +++ Applet/Tcpbw100.java (working copy) @@ -2746,7 +2746,13 @@ _sEmailText += sSysvar + " " + sStrval + "\n%0A"; if (sStrval.indexOf(".") == -1) { // no decimal point, hence // integer - iSysval = Integer.parseInt(sStrval); + try{ + iSysval = Integer.parseInt(sStrval); + // If it fails as an int it's probably to big since the values are often unsigned + } catch (Exception e) { + System.out.println("Exception occured reading a web100 var - " + e); + iSysval = -1; + } // save value into a key value expected by us save_int_values(sSysvar, iSysval); } else { // if not integer, save as double @@ -3373,7 +3379,7 @@ _txtStatistics.append("\n" + _resBundDisplayMsgs.getString("web100tcpOpts") + " \n"); _txtStatistics.append("RFC 2018 Selective Acknowledgment: "); - if (_iSACKEnabled == iZero) + if (_iSACKEnabled == 0) _txtStatistics.append(_resBundDisplayMsgs.getString("off") + "\n"); else @@ -3381,29 +3387,31 @@ + "\n"); _txtStatistics.append("RFC 896 Nagle Algorithm: "); - if (_iNagleEnabled == iZero) - _txtStatistics.append(_resBundDisplayMsgs.getString("off") + if (_iNagleEnabled == NDTConstants.RFC_896_ENABLED) + _txtStatistics.append(_resBundDisplayMsgs.getString("on") + "\n"); else - _txtStatistics.append(_resBundDisplayMsgs.getString("on") + _txtStatistics.append(_resBundDisplayMsgs.getString("off") + "\n"); _txtStatistics.append("RFC 3168 Explicit Congestion Notification: "); - if (_iECNEnabled == iZero) - _txtStatistics.append(_resBundDisplayMsgs.getString("off") + if (_iECNEnabled == NDTConstants.RFC_3168_ENABLED) + _txtStatistics.append(_resBundDisplayMsgs.getString("on") + "\n"); else - _txtStatistics.append(_resBundDisplayMsgs.getString("on") + _txtStatistics.append(_resBundDisplayMsgs.getString("off") + "\n"); - + /* TODO - Ideally print who disabled it - but need translations */ + _txtStatistics.append("RFC 1323 Time Stamping: "); - if (_iTimestampsEnabled == NDTConstants.RFC_1323_DISABLED) - _txtStatistics.append(_resBundDisplayMsgs.getString("off") + if (_iTimestampsEnabled == NDTConstants.RFC_1323_ENABLED) + _txtStatistics.append(_resBundDisplayMsgs.getString("on") + "\n"); else - _txtStatistics.append(_resBundDisplayMsgs.getString("on") + _txtStatistics.append(_resBundDisplayMsgs.getString("off") + "\n"); - + /* TODO - Ideally print who disabled it - but need translations */ + _txtStatistics.append("RFC 1323 Window Scaling: "); if (_iMaxRwinRcvd < NDTConstants.TCP_MAX_RECV_WIN_SIZE) _iWinScaleRcvd = 0; //Max rec window size lesser than TCP's max value, @@ -3592,12 +3600,16 @@ // get client side IP String sClientSideClientIp = tokens.nextToken(); - k = sClientSideServerIp.indexOf("/"); - sClientSideServerIp = sClientSideServerIp.substring(k + 1); - + System.out.println("IP --" + sClientSideClientIp ); + k = sClientSideClientIp.indexOf("/"); + System.out.println("k is: " + k ); + sClientSideClientIp = sClientSideClientIp.substring(k + 1); + System.out.println("IP --" + sClientSideClientIp ); // MSS = 1456 = Ethernet MTU = 1500 - 24 -20 (bytes of IP header) = // 1456, thus preserved - + if(_iTimestampsEnabled == NDTConstants.RFC_1323_ENABLED) + iMss += 12; + if (iMss == NDTConstants.ETHERNET_MTU_SIZE) _txtStatistics.append(_resBundDisplayMsgs .getString("packetSizePreserved") + "\n"); Index: Applet/NDTConstants.java =================================================================== --- Applet/NDTConstants.java (revision 796) +++ Applet/NDTConstants.java (working copy) @@ -98,9 +98,25 @@ public static final String RTT_STR = "rtt"; // round trip time // Section: RFC 1323 options ( Seems like 0/1/2/3 are the options available) + // Not sure 0 is available maybe really old web100? - public static final int RFC_1323_DISABLED = 0; + public static final int RFC_1323_ENABLED = 1; + // Note Self disabled from servers standpoint i.e. disabled by server + public static final int RFC_1323_SELF_DISABLED = 2; + public static final int RFC_1323_PEER_DISABLED = 3; + // Section: RFC2018 SAck + public static final int RFC_2018_ENABLED = 1; + + // Section: RFC2018 Nagle + public static final int RFC_896_ENABLED = 1; + + // Section: RFC3168 + public static final int RFC_3168_ENABLED = 1; + // Note Self disabled from servers standpoint i.e. disabled by server + public static final int RFC_3168_SELF_DISABLED = 2; + public static final int RFC_3168_PEER_DISABLED = 3; + // Section: Buffer limitation test thresholds public static final float BUFFER_LIMITED = 0.15f; //unused right now Index: Applet/Tcpbw100_msgs_en_US.properties =================================================================== --- Applet/Tcpbw100_msgs_en_US.properties (revision 796) +++ Applet/Tcpbw100_msgs_en_US.properties (working copy) @@ -32,7 +32,7 @@ clientInfo = Client System Details clientIpModified = Information: Network Address Translation (NAT) box is modifying the Client's IP address clientIpNotFound = Client IP address not found. For IE users, modify the Java parameters\n click Tools - Internet Options - Security - Custom Level, scroll down to\n Microsoft VM - Java permissions and click Custom, click Java Custom Settings\n Edit Permissions - Access to all Network Addresses, click Eanble and save changes -clientIpPreserved = Server IP addresses are preserved End-to-End +clientIpPreserved = Client IP addresses are preserved End-to-End clientSays = but Client says close = Close comments = Comments Index: WEB10G README =================================================================== --- WEB10G README (revision 0) +++ WEB10G README (revision 0) @@ -0,0 +1,19 @@ +Quick Build Notes +Although you don't need a web10g kernel to build, if you wish to run the server you will. + +I've tested with linux 3.5.1 kernel patched with web10g (web10.org - Web10G-0.4-3.5-patch). I had to modify the patch - Swap ktime_to_ns(...) with ktime_to_us(...). + +You need to make and install the Web10G-userland library I used Web10G-userland-2.0.4. + +Configure and build ndt as normal. Web10G libs should be detected and hence the web10gsrv built. Web100 is still fully supported and if Web100 libs are found web100srv will be built. + +Known issues + +Web10G related +* Logging functionality not yet implemented some related functions are missing. +* Web10g patch not quite right - need to modify ktime_to_ns to ktime_to_us. +* Server and Client(C and Java Applet) have been ported, other tools have not. Depending on there function they may not work. + +Other +* Running the server without a DNS server can cause tests to timeout and fail. Add the NI_NUMERICHOST flag into the getnameinfo call within _I2AddrSetNodePort() in the I2Util library to fix. +* MSS incorrectly detecting modification when testing via IPv6??