diff options
| author | slioch <slioch@eng-140.vyatta.com> | 2009-07-28 14:35:37 -0700 |
|---|---|---|
| committer | slioch <slioch@eng-140.vyatta.com> | 2009-07-28 14:35:37 -0700 |
| commit | dfbf4cac22b97eab470ecd251384bf471bfed3e6 (patch) | |
| tree | 5453baa75826ec854b8bc712852fced80106d93a /src | |
| parent | fe6f0901ab0970bcc937328e6093f5b0f118230d (diff) | |
| download | vyatta-wanloadbalance-dfbf4cac22b97eab470ecd251384bf471bfed3e6.tar.gz vyatta-wanloadbalance-dfbf4cac22b97eab470ecd251384bf471bfed3e6.zip | |
reworked tests to fix bug in handling of received packets. modified show cmd output.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lbdata.cc | 169 | ||||
| -rw-r--r-- | src/lbdata.hh | 47 | ||||
| -rw-r--r-- | src/lboutput.cc | 13 | ||||
| -rw-r--r-- | src/lbpathtest.cc | 24 | ||||
| -rw-r--r-- | src/lbtest.cc | 294 | ||||
| -rw-r--r-- | src/lbtest.hh | 87 | ||||
| -rw-r--r-- | src/lbtest_icmp.cc | 170 | ||||
| -rw-r--r-- | src/lbtest_icmp.hh | 72 | ||||
| -rw-r--r-- | src/lbtest_ttl.cc | 191 | ||||
| -rw-r--r-- | src/lbtest_ttl.hh | 100 |
10 files changed, 519 insertions, 648 deletions
diff --git a/src/lbdata.cc b/src/lbdata.cc index dffd422..7226b84 100644 --- a/src/lbdata.cc +++ b/src/lbdata.cc @@ -24,14 +24,11 @@ #include <iostream> #include "rl_str_proc.hh" +#include "lbtest.hh" #include "lbdata.hh" int LBHealthHistory::_buffer_size = 10; -int LBTest::_send_icmp_sock = 0; -int LBTest::_send_raw_sock = 0; -int LBTest::_recv_icmp_sock = 0; -bool LBTest::_initialized = false; /** * @@ -69,8 +66,20 @@ void LBHealth::start_new_test_cycle() { _test_iter = _test_coll.begin(); - _test_success = false; - _new_test = true; + // _test_iter->second->start(); +} + +/** + * + * + **/ +void +LBHealth::start_new_test() +{ + if (_test_iter == _test_coll.end()) { + return; + } + _test_iter->second->start(); } /** @@ -80,18 +89,10 @@ LBHealth::start_new_test_cycle() void LBHealth::send_test() { - if (_test_success == true || _test_iter == _test_coll.end()) { + if (_test_iter == _test_coll.end()) { return; //means we are done } - if (_new_test == true) { - _test_iter->second->init(); - _test_iter->second->send(*this); - - struct sysinfo si; - sysinfo(&si); - _time_start = si.uptime; - _new_test = false; - } + _test_iter->second->send(*this); } /** @@ -101,37 +102,17 @@ LBHealth::send_test() int LBHealth::recv_test() { - if (_test_success == true) { - //shouldn't call this again.... - return 0; //means stop iteration - } - if (_test_iter == _test_coll.end()) { put(-1); - return 0; //means stop iteration + return 0; //means stop iteration, no more tests... } - - int rtt = _test_iter->second->recv(*this); - if (rtt > -1) { - _test_success = true; + int rtt = _test_iter->second->recv(*this); + ++_test_iter; + if (rtt >= 0) { put(rtt); - return rtt; //means stop iterator - } - - struct sysinfo si; - sysinfo(&si); - unsigned long cur_time = si.uptime; - if (cur_time > _time_start + _timeout) { - //move to next test - _new_test = true; - ++_test_iter; + return 0; //means success, testing is done } - - if (_test_iter == _test_coll.end()) { - put(-1); - return 0; //means stop iteration - } - return -1; //means keep going + return -1; //means testing is not done for this interface } /** @@ -151,7 +132,18 @@ LBHealthHistory::LBHealthHistory(int buffer_size) : } } - +/** + * + * + **/ +int +LBHealthHistory::get_last_resp() +{ + if (_resp_data.size() == 0) { + return -1; + } + return (_resp_data[0]); +} /** * @@ -359,94 +351,3 @@ LBData::update_dhcp_nexthop() } } -/** - * - * - **/ -void -LBTest::init() -{ - if (_initialized == true) { - return; - } - _initialized = true; - - if (_debug) { - cout << "LBTest::init()" << endl; - } - - struct protoent *ppe = getprotobyname("icmp"); - _send_icmp_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); - if (_send_icmp_sock < 0){ - if (_debug) { - cerr << "LBTest::init(): no send sock: " << _send_icmp_sock << endl; - } - syslog(LOG_ERR, "wan_lb: failed to acquired socket"); - _send_icmp_sock = 0; - return; - } - - //set options for broadcasting. - int val = 1; - // setsockopt(_send_icmp_sock, SOL_SOCKET, SO_BROADCAST, &val, 4); - setsockopt(_send_icmp_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4); - - _send_raw_sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); - if (_send_raw_sock < 0){ - if (_debug) { - cerr << "LBTest::init(): no send sock: " << _send_raw_sock << endl; - } - syslog(LOG_ERR, "wan_lb: failed to acquired socket"); - _send_raw_sock = 0; - return; - } - - //set options for broadcasting. - // setsockopt(_send_raw_sock, SOL_SOCKET, SO_BROADCAST, &val, 4); - setsockopt(_send_raw_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4); - - struct sockaddr_in addr; - memset( &addr, 0, sizeof( struct sockaddr_in )); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = 0; - - _recv_icmp_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); - if (_recv_icmp_sock < 0) { - if (_debug) { - cerr << "LBTest::init(): no recv sock: " << _recv_icmp_sock << endl; - } - syslog(LOG_ERR, "wan_lb: failed to acquired socket"); - _recv_icmp_sock = 0; - return; - } - if (bind(_recv_icmp_sock, (struct sockaddr*)&addr, sizeof(addr))==-1) { - if (_debug) { - cerr << "failed on bind" << endl; - } - syslog(LOG_ERR, "wan_lb: failed to bind recv sock"); - } -} - -/** - * - * - **/ -LBTest::~LBTest() -{ - if (_recv_icmp_sock != 0) { - close(_recv_icmp_sock); - _recv_icmp_sock = 0; - } - - if (_send_raw_sock != 0) { - close(_send_raw_sock); - _send_raw_sock = 0; - } - - if (_send_icmp_sock != 0) { - close(_send_icmp_sock); - _send_icmp_sock = 0; - } - -} diff --git a/src/lbdata.hh b/src/lbdata.hh index 6673604..287ca35 100644 --- a/src/lbdata.hh +++ b/src/lbdata.hh @@ -17,6 +17,7 @@ using namespace std; class LBHealth; +class LBTest; /** * @@ -77,7 +78,11 @@ public: LBHealthHistory(int buffer_size); //push in the ping response for this... - int push(int rtt); + int + push(int rtt); + + int + get_last_resp(); public: //results of health testing @@ -95,43 +100,6 @@ public: * * **/ -class LBTest { -public: - typedef enum {K_NONE,K_SUCCESS,K_FAILURE} TestState; -public: - LBTest(bool debug) : - _debug(debug), - _state(K_NONE) - {} - virtual ~LBTest(); - - virtual void - init(); - - virtual void - send(LBHealth &health) = 0; - - virtual int - recv(LBHealth &health) = 0; - - virtual string - dump() = 0; - -public: - bool _debug; - string _target; - int _resp_time; - int _state; - static int _recv_icmp_sock; - static int _send_raw_sock; - static int _send_icmp_sock; - static bool _initialized; -}; - -/** - * - * - **/ class LBHealth { public: typedef map<int,LBTest*> TestColl; @@ -185,6 +153,9 @@ public: start_new_test_cycle(); void + start_new_test(); + + void send_test(); int diff --git a/src/lboutput.cc b/src/lboutput.cc index 5977f92..520dd6b 100644 --- a/src/lboutput.cc +++ b/src/lboutput.cc @@ -11,6 +11,7 @@ #include <iostream> +#include "lbtest.hh" #include "lbdata.hh" #include "lboutput.hh" @@ -80,13 +81,13 @@ LBOutput::write(const LBData &lbdata) } if (titer->second->_state == LBTest::K_NONE) { - line += space + string("*Target: ") + target + "\n"; + line += space + "*Test: " + titer->second->name() + "\t" + string("Target: ") + target + "\n"; } else if (titer->second->_state == LBTest::K_FAILURE) { - line += space + string("-Target: ") + target + "\n"; + line += space + "-Test: " + titer->second->name() + "\t" + string("Target: ") + target + "\n"; } else if (titer->second->_state == LBTest::K_SUCCESS) { - line += space + string("+Target: ") + target + "\n"; + line += space + "+Test: " + titer->second->name() + "\t" + string("Target: ") + target + "\n"; } ++titer; @@ -139,7 +140,7 @@ LBOutput::write(const LBData &lbdata) success_time = time_buf + string("\t"); } - line += space + space + string("Last Ping Success: ") + success_time + "\n"; + line += space + space + string("Last Interface Success: ") + success_time + "\n"; time_buf = ""; @@ -183,13 +184,13 @@ LBOutput::write(const LBData &lbdata) failure_time = time_buf + string("\t"); } - line += space + space + string("Last Ping Failure: ") + failure_time + "\n"; + line += space + space + string("Last Interface Failure: ") + failure_time + "\n"; //now failure count sprintf(btmp, "%ld", iter->second._hresults._failure_count); - line += space + space + string("# Ping Failure(s): ") + string(btmp) + "\n\n"; + line += space + space + string("# Interface Failure(s): ") + string(btmp) + "\n\n"; fputs(line.c_str(),fp); ++iter; diff --git a/src/lbpathtest.cc b/src/lbpathtest.cc index a886a37..3e81ed9 100644 --- a/src/lbpathtest.cc +++ b/src/lbpathtest.cc @@ -63,20 +63,27 @@ LBPathTest::start(LBData &lb_data) set<LBHealth*> coll; - //iterate over the health interfaces + //iterate over the health interfaces, until success or test cases exhausted per interface LBData::InterfaceHealthIter iter = lb_data._iface_health_coll.begin(); while (iter != lb_data._iface_health_coll.end()) { - iter->second.start_new_test_cycle(); coll.insert(&(iter->second)); + iter->second.start_new_test_cycle(); ++iter; } while (!coll.empty()) { + cout << "AA:" << coll.size() << endl; + set<LBHealth*>::iterator i = coll.begin(); + while (i != coll.end()) { + (*i)->start_new_test(); + ++i; + } + if (_debug) { cout << "LBPathTest::start(): sending " << coll.size() << " tests" << endl; } //send all interface tests together - set<LBHealth*>::iterator i = coll.begin(); + i = coll.begin(); while (i != coll.end()) { (*i)->send_test(); ++i; @@ -88,12 +95,19 @@ LBPathTest::start(LBData &lb_data) //wait on responses i = coll.begin(); while (i != coll.end()) { - if ((*i)->recv_test() > -1) { - coll.erase(i++); + int resp = (*i)->recv_test(); + if (_debug) { + cout << "LBPathTest::start() interface: " << (*i)->_interface << " response value: " << (*i)->_hresults.get_last_resp() << endl; + } + cout << "A:" << resp << ", " << coll.size() << endl; + if (resp == 0) { //means this interface has either exhausted its test cases or success + cout << "B:" << resp << ", " << coll.size() << endl; + coll.erase(i++); } else { ++i; } + cout << "C:" << coll.size() << endl; } } } diff --git a/src/lbtest.cc b/src/lbtest.cc new file mode 100644 index 0000000..8dd2f24 --- /dev/null +++ b/src/lbtest.cc @@ -0,0 +1,294 @@ +/* + * Module: lbtest.cc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <sys/time.h> +#include <syslog.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/sysinfo.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/udp.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip_icmp.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <time.h> +#include <syslog.h> +#include <iostream> + +#include "rl_str_proc.hh" +#include "lbdata.hh" +#include "lbtest.hh" + +int LBTest::_send_icmp_sock = 0; +int LBTest::_send_raw_sock = 0; +int LBTest::_recv_icmp_sock = 0; +bool LBTest::_initialized = false; +bool LBTest::_received = false; +int LBTest::_packet_id = 0; +map<int,PktData> LBTest::_results; + +/** + * + * + **/ +void +LBTest::init() +{ + if (_initialized == true) { + return; + } + _initialized = true; + + if (_debug) { + cout << "LBTest::init()" << endl; + } + + struct protoent *ppe = getprotobyname("icmp"); + _send_icmp_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); + if (_send_icmp_sock < 0){ + if (_debug) { + cerr << "LBTest::init(): no send sock: " << _send_icmp_sock << endl; + } + syslog(LOG_ERR, "wan_lb: failed to acquired socket"); + _send_icmp_sock = 0; + return; + } + + //set options for broadcasting. + int val = 1; + // setsockopt(_send_icmp_sock, SOL_SOCKET, SO_BROADCAST, &val, 4); + setsockopt(_send_icmp_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4); + + _send_raw_sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); + if (_send_raw_sock < 0){ + if (_debug) { + cerr << "LBTest::init(): no send sock: " << _send_raw_sock << endl; + } + syslog(LOG_ERR, "wan_lb: failed to acquired socket"); + _send_raw_sock = 0; + return; + } + + cout << "send raw sock: " << _send_raw_sock << endl; + + //set options for broadcasting. + // setsockopt(_send_raw_sock, SOL_SOCKET, SO_BROADCAST, &val, 4); + setsockopt(_send_raw_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4); + + struct sockaddr_in addr; + memset( &addr, 0, sizeof( struct sockaddr_in )); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = 0; + + _recv_icmp_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); + if (_recv_icmp_sock < 0) { + if (_debug) { + cerr << "LBTest::init(): no recv sock: " << _recv_icmp_sock << endl; + } + syslog(LOG_ERR, "wan_lb: failed to acquired socket"); + _recv_icmp_sock = 0; + return; + } + if (bind(_recv_icmp_sock, (struct sockaddr*)&addr, sizeof(addr))==-1) { + if (_debug) { + cerr << "failed on bind" << endl; + } + syslog(LOG_ERR, "wan_lb: failed to bind recv sock"); + } +} + +/** + * + * + **/ +LBTest::~LBTest() +{ + if (_recv_icmp_sock != 0) { + close(_recv_icmp_sock); + _recv_icmp_sock = 0; + } + + if (_send_raw_sock != 0) { + close(_send_raw_sock); + _send_raw_sock = 0; + } + + if (_send_icmp_sock != 0) { + close(_send_icmp_sock); + _send_icmp_sock = 0; + } + +} + +/** + * + * + **/ +void +LBTest::start() +{ + _received = false; + _results.erase(_results.begin(),_results.end()); +} + +/** + * + * + **/ +int +LBTest::recv(LBHealth &health) +{ + if (_received == false) { + //let's erase the results first + //use gettimeofday to calculate time to millisecond + //then iterate over recv socket and receive and record + //use sysinfo to make sure we don't get stuck in a loop with timechange + struct timeval send_time; + gettimeofday(&send_time,NULL); + struct sysinfo si; + sysinfo(&si); + //for now hardcode to 5 second overall timeout + unsigned long timeout = si.uptime + 5; //seconds + unsigned long cur_time = si.uptime; + + int pending_result_ct = _results.size(); + while (cur_time < timeout && pending_result_ct != 0) { + int id = receive(_recv_icmp_sock); + if (_debug) { + cout << "LBTest::recv(): " << id << endl; + } + //update current time for comparison + struct sysinfo si; + sysinfo(&si); + cur_time = si.uptime; + timeval recv_time; + gettimeofday(&recv_time,NULL); + map<int,PktData>::iterator r_iter = _results.find(id); + if (r_iter != _results.end()) { + //calculate time in milliseconds + int secs = 0; + int msecs = recv_time.tv_usec - send_time.tv_usec; + if (msecs < 0) { + secs = recv_time.tv_sec - send_time.tv_sec - 1; + } + else { + secs = recv_time.tv_sec - send_time.tv_sec; + } + //time in milliseconds below + r_iter->second._rtt = abs(msecs) / 1000 + 1000 * secs; + --pending_result_ct; + } + } + if (_debug) { + cout << "LBTest::recv(): finished heath test" << endl; + } + _received = true; + } + //now let's just look the packet up since we are through with the receive option + map<int,PktData>::iterator r_iter = _results.begin(); + _state = LBTest::K_FAILURE; + while (r_iter != _results.end()) { + if (r_iter->second._iface == health._interface) { + + if (r_iter->second._rtt < _resp_time && r_iter->second._rtt >= 0) { + _state = LBTest::K_SUCCESS; + if (_debug) { + cout << "LBTest::recv(): success for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; + } + int rtt = r_iter->second._rtt; + _results.erase(r_iter); + return rtt; + } + else { + if (_debug) { + cout << "LBTest::recv(): failure for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; + } + _results.erase(r_iter); + return -1; + } + } + ++r_iter; + } + + if (_debug) { + cout << "LBTest::recv(): failure for " << health._interface << " : unable to find interface" << endl; + } + return -1; +} + + + + +/** + * + * + **/ +int +LBTest::receive(int recv_sock) +{ + timeval wait_time; + int icmp_pktsize = 40; + char resp_buf[icmp_pktsize]; + icmphdr *icmp_hdr; + fd_set readfs; + + FD_ZERO(&readfs); + FD_SET(recv_sock, &readfs); + + wait_time.tv_usec = 0; + wait_time.tv_sec = 3; //3 second timeout + + if (_debug) { + cout << "LBTest::receive(): start" << endl; + } + + //NEW-OLD STUFF HERE + + if (select(recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0) { + int bytes_recv = ::recv(recv_sock, &resp_buf, 56, 0); + if (bytes_recv != -1) { + if (_debug) { + cout << "LBTest::receive() received: " << bytes_recv << endl; + } + icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr)); + if (icmp_hdr->type == ICMP_TIME_EXCEEDED) { + //process packet data + char* data; + int id = 0; + data = (char*)(&resp_buf) + 49; + memcpy(&id, data, sizeof(unsigned short)); + if (_debug) { + cout << "LBTest::receive(): " << id << endl; + } + return id; + } + else if (icmp_hdr->type == ICMP_ECHOREPLY) { + char* data; + int id = 0; + data = (char*)(&resp_buf) + 36; + memcpy(&id, data, sizeof(unsigned short)); + if (_debug) { + cout << "LBTest::receive(): " << id << endl; + } + return id; + } + } + else { + cerr << "LBTest::receive(): error from recvfrom" << endl; + } + } + return -1; +} + + diff --git a/src/lbtest.hh b/src/lbtest.hh new file mode 100644 index 0000000..2719cf5 --- /dev/null +++ b/src/lbtest.hh @@ -0,0 +1,87 @@ +/* + * Module: lbtest.hh + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#ifndef __LBTEST_HH__ +#define __LBTEST_HH__ + +#include <assert.h> +#include <map> +#include <set> +#include <vector> +#include <string> + +using namespace std; + +class LBHealth; + +/** + * + * + **/ +class PktData +{ +public: + PktData(string iface, int rtt) : _iface(iface),_rtt(rtt) {} + string _iface; + int _rtt; +}; + + +/** + * + * + **/ +class LBTest { +public: + typedef enum {K_NONE,K_SUCCESS,K_FAILURE} TestState; +public: + LBTest(bool debug) : + _debug(debug), + _state(K_NONE) + {init();} + + virtual ~LBTest(); + + virtual void + init(); + + virtual void + start(); + + virtual void + send(LBHealth &health) = 0; + + virtual string + dump() = 0; + + int + recv(LBHealth &health); + + virtual string + name() = 0; + +private: + int + receive(int recv_sock); + + +public: + bool _debug; + string _target; + int _resp_time; + int _state; + + static int _recv_icmp_sock; + static int _send_raw_sock; + static int _send_icmp_sock; + static bool _initialized; + static bool _received; + static int _packet_id; + static map<int,PktData> _results; +}; + +#endif //__LBTEST_HH__ diff --git a/src/lbtest_icmp.cc b/src/lbtest_icmp.cc index d6f9e3b..6393b3e 100644 --- a/src/lbtest_icmp.cc +++ b/src/lbtest_icmp.cc @@ -29,8 +29,6 @@ #include "lbdata.hh" #include "lbtest_icmp.hh" -ICMPEngine LBTestICMP::_engine; - using namespace std; /** @@ -38,27 +36,10 @@ using namespace std; * **/ void -ICMPEngine::init() -{ - if (_initialized == false) { - _results.erase(_results.begin(),_results.end()); - } - if (_debug) { - cout << "ICMPEngine::init(): initializing test system" << endl; - } - _initialized = true; - _received = false; -} - -/** - * - * - **/ -int -ICMPEngine::process(LBHealth &health,LBTestICMP *data) +LBTestICMP::send(LBHealth &health) { //iterate over packets and send - string target = data->_target; + string target = _target; if (target.empty()) { if (health._nexthop == "dhcp") { target = health._dhcp_nexthop; @@ -70,102 +51,15 @@ ICMPEngine::process(LBHealth &health,LBTestICMP *data) //don't have target yet... if (target.empty()) { - return -1; + return; } _packet_id = ++_packet_id % 32767; if (_debug) { cout << "ICMPEngine::start(): sending ping test for: " << health._interface << " for " << target << " id: " << _packet_id << endl; } - send(data->_send_icmp_sock, health._interface, target, _packet_id); + send(_send_icmp_sock, health._interface, target, _packet_id); _results.insert(pair<int,PktData>(_packet_id,PktData(health._interface,-1))); - return 0; -} - -/** - * - * - **/ -int -ICMPEngine::recv(LBHealth &health,LBTestICMP *data) -{ - _initialized = false; - if (_received == false) { - //use gettimeofday to calculate time to millisecond - //then iterate over recv socket and receive and record - //use sysinfo to make sure we don't get stuck in a loop with timechange - struct timeval send_time; - gettimeofday(&send_time,NULL); - struct sysinfo si; - sysinfo(&si); - //for now hardcode to 5 second overall timeout - unsigned long timeout = si.uptime + 5; //seconds - unsigned long cur_time = si.uptime; - - int pending_result_ct = _results.size(); - //let's pull off all of the results... - while (cur_time < timeout && pending_result_ct != 0) { - int id = receive(data->_recv_icmp_sock); - if (_debug) { - cout << "ICMPEngine::recv(): " << id << endl; - } - - //update current time for comparison - struct sysinfo si; - sysinfo(&si); - timeval recv_time; - gettimeofday(&recv_time,NULL); - cur_time = si.uptime; - map<int,PktData>::iterator r_iter = _results.find(id); - if (r_iter != _results.end()) { - //calculate time in milliseconds - int secs = 0; - int msecs = recv_time.tv_usec - send_time.tv_usec; - if (msecs < 0) { - secs = recv_time.tv_sec - send_time.tv_sec - 1; - } - else { - secs = recv_time.tv_sec - send_time.tv_sec; - } - //time in milliseconds below - r_iter->second._rtt = abs(msecs) / 1000 + 1000 * secs; - --pending_result_ct; - } - } - if (_debug) { - cout << "ICMPEngine::recv(): finished heath test" << endl; - } - _received = true; - } - - //now let's just look the packet up since we are through with the receive option - map<int,PktData>::iterator r_iter = _results.begin(); - data->_state = LBTest::K_FAILURE; - while (r_iter != _results.end()) { - if (r_iter->second._iface == health._interface) { - if (r_iter->second._rtt < data->_resp_time) { - data->_state = LBTest::K_SUCCESS; - if (_debug) { - cout << "ICMPEngine::recv(): success for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; - } - int rtt = r_iter->second._rtt; - _results.erase(r_iter); - return rtt; - } - else { - if (_debug) { - cout << "ICMPEngine::recv(): failure for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; - } - _results.erase(r_iter); - return -1; - } - } - ++r_iter; - } - - if (_debug) { - cout << "ICMPEngine::recv(): failure for " << health._interface << " : unable to find interface" << endl; - } - return -1; + return; } /** @@ -173,7 +67,7 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data) * **/ void -ICMPEngine::send(int send_sock, const string &iface, const string &target_addr, int packet_id) +LBTestICMP::send(int send_sock, const string &iface, const string &target_addr, int packet_id) { int err; sockaddr_in taddr; @@ -273,63 +167,13 @@ ICMPEngine::send(int send_sock, const string &iface, const string &target_addr, } } -/** - * - * - **/ -int -ICMPEngine::receive(int recv_sock) -{ - int icmp_pktsize = 40; - char resp_buf[icmp_pktsize]; - icmphdr *icmp_hdr; - timeval wait_time; - fd_set readfs; - int ret; - - FD_ZERO(&readfs); - FD_SET(recv_sock, &readfs); - - wait_time.tv_usec = 0; - wait_time.tv_sec = 3; //3 second timeout - - if (_debug) { - cout << "ICMPEngine::receive(): start" << endl; - } - - if (select(recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0) { - ret = ::recv(recv_sock, &resp_buf, icmp_pktsize, MSG_PEEK); - if (ret != -1) { - if (_debug) { - cout << "ICMPEngine::receive(): recv: " << ret << endl; - } - icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr)); - if (icmp_hdr->type == ICMP_ECHOREPLY) { - //then let's pull the packet off, it's ours - ret = ::recv(recv_sock, &resp_buf, icmp_pktsize, 0); - if (ret != -1) { - //process packet data - char* data; - int id = 0; - data = (char*)(&resp_buf) + 36; - memcpy(&id, data, sizeof(unsigned short)); - if (_debug) { - cout << "ICMPEngine::receive(): " << id << endl; - } - return id; - } - } - } - } - return -1; -} /** * * **/ unsigned short -ICMPEngine::in_checksum(const unsigned short *buffer, int length) const +LBTestICMP::in_checksum(const unsigned short *buffer, int length) const { unsigned long sum; for (sum=0; length>0; length--) { diff --git a/src/lbtest_icmp.hh b/src/lbtest_icmp.hh index 8b55130..e9d9a14 100644 --- a/src/lbtest_icmp.hh +++ b/src/lbtest_icmp.hh @@ -12,91 +12,41 @@ #include <sys/socket.h> #include <netdb.h> #include <iostream> -#include "lbdata.hh" +#include "lbtest.hh" using namespace std; -class LBTestICMP; - /** * * **/ -class PktData +class LBTestICMP : public LBTest { public: - PktData(string iface, int rtt) : _iface(iface),_rtt(rtt) {} - string _iface; - int _rtt; -}; - + LBTestICMP(bool debug) : LBTest(debug) {} + ~LBTestICMP() {} -/** - * - * - **/ -class ICMPEngine -{ -public: - ICMPEngine() : - _debug(true), - _initialized(false), - _received(false), - _packet_id(0) - {} + void + init() {} void - init(); + send(LBHealth &health); - int - process(LBHealth &health,LBTestICMP *data); + string + dump(); - int - recv(LBHealth &health,LBTestICMP *data); + string + name() {return string("ping");} private: void send(int sock, const string &iface, const string &target_addr, int packet_id); - int - receive(int sock); - unsigned short in_checksum(const unsigned short *buf, int lenght) const; private: bool _debug; - bool _initialized; - bool _received; - int _packet_id; - map<int,PktData> _results; -}; - -/** - * - * - **/ -class LBTestICMP : public LBTest -{ -public: - LBTestICMP(bool debug) : LBTest(debug) {} - ~LBTestICMP() {} - - void - init() {_engine.init();this->LBTest::init();} - - void - send(LBHealth &health) {_engine.process(health,this);} - - int - recv(LBHealth &health) {return _engine.recv(health,this);} - - string - dump(); - -private: - static ICMPEngine _engine; //singleton - bool _debug; }; #endif //__LBTEST_ICMP_HH__ diff --git a/src/lbtest_ttl.cc b/src/lbtest_ttl.cc index 47d1f4d..551db07 100644 --- a/src/lbtest_ttl.cc +++ b/src/lbtest_ttl.cc @@ -30,8 +30,6 @@ #include "lbdata.hh" #include "lbtest_ttl.hh" -TTLEngine LBTestTTL::_engine; - using namespace std; /** @@ -39,30 +37,25 @@ using namespace std; * **/ void -TTLEngine::init() +LBTestTTL::init() { - if (_initialized == false) { - _results.erase(_results.begin(),_results.end()); - } if (_debug) { - cout << "TTLEngine::init(): initializing test system" << endl; + cout << "LBTestTTL::init(): initializing test system" << endl; } - _initialized = true; - _received = false; } /** * * **/ -int -TTLEngine::process(LBHealth &health,LBTestTTL *data) +void +LBTestTTL::send(LBHealth &health) { if (_debug) { - cout << "TTLEngine::process()" << endl; + cout << "LBTestTTL::process()" << endl; } //iterate over packets and send - string target = data->_target; + string target = _target; if (target.empty()) { if (health._nexthop == "dhcp") { target = health._dhcp_nexthop; @@ -74,130 +67,42 @@ TTLEngine::process(LBHealth &health,LBTestTTL *data) //don't have target yet... if (target.empty()) { - return -1; + return; } if (_debug) { - cout << "TTLEngine::process(): sending ttl test for: " << health._interface << " for " << target << endl; + cout << "LBTestTTL::process(): sending ttl test for: " << health._interface << " for " << target << endl; } _packet_id = get_new_packet_id(); - send(data->_send_raw_sock, health._interface,target,_packet_id,health._address,data->get_ttl(),data->get_port()); + send(_send_raw_sock, health._interface,target,_packet_id,health._address,get_ttl(),get_port()); _results.insert(pair<int,PktData>(_packet_id,PktData(health._interface,-1))); - return 0; -} - -/** - * - * - **/ -int -TTLEngine::recv(LBHealth &health,LBTestTTL *data) -{ - _initialized = false; - if (_received == false) { - //use gettimeofday to calculate time to millisecond - //then iterate over recv socket and receive and record - //use sysinfo to make sure we don't get stuck in a loop with timechange - struct timeval send_time; - gettimeofday(&send_time,NULL); - struct sysinfo si; - sysinfo(&si); - //for now hardcode to 5 second overall timeout - unsigned long timeout = si.uptime + 5; //seconds - unsigned long cur_time = si.uptime; - - int pending_result_ct = _results.size(); - while (cur_time < timeout && pending_result_ct != 0) { - int id = receive(data->_recv_icmp_sock); - if (_debug) { - cout << "TTLEngine::recv(): " << id << endl; - } - //update current time for comparison - struct sysinfo si; - sysinfo(&si); - cur_time = si.uptime; - timeval recv_time; - gettimeofday(&recv_time,NULL); - map<int,PktData>::iterator r_iter = _results.find(id); - if (r_iter != _results.end()) { - //calculate time in milliseconds - int secs = 0; - int msecs = recv_time.tv_usec - send_time.tv_usec; - if (msecs < 0) { - secs = recv_time.tv_sec - send_time.tv_sec - 1; - } - else { - secs = recv_time.tv_sec - send_time.tv_sec; - } - //time in milliseconds below - r_iter->second._rtt = abs(msecs) / 1000 + 1000 * secs; - --pending_result_ct; - } - else { - return -1; - } - } - if (_debug) { - cout << "TTLEngine::recv(): finished heath test" << endl; - } - _received = true; - } - //now let's just look the packet up since we are through with the receive option - map<int,PktData>::iterator r_iter = _results.begin(); - data->_state = LBTest::K_FAILURE; - while (r_iter != _results.end()) { - if (r_iter->second._iface == health._interface) { - if (r_iter->second._rtt < data->_resp_time) { - data->_state = LBTest::K_SUCCESS; - if (_debug) { - cout << "TTLEngine::recv(): success for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; - } - int rtt = r_iter->second._rtt; - _results.erase(r_iter); - return rtt; - } - else { - if (_debug) { - cout << "TTLEngine::recv(): failure for " << r_iter->second._iface << " : " << r_iter->second._rtt << endl; - } - _results.erase(r_iter); - return -1; - } - } - ++r_iter; - } - - if (_debug) { - cout << "EngineTTL::recv(): failure for " << health._interface << " : unable to find interface" << endl; - } - return -1; + return; } - /** * * **/ void -TTLEngine::send(int send_sock, const string &iface, const string &target_addr, unsigned short packet_id, string saddress, int ttl, unsigned short port) +LBTestTTL::send(int send_sock, const string &iface, const string &target_addr, unsigned short packet_id, string saddress, int ttl, unsigned short port) { if (_debug) { - cout << "TTLEngine::send(): packet_id: " << packet_id << ", ttl: " << ttl << ", port: " << port << endl; + cout << "LBTestTTL::send(): packet_id: " << packet_id << ", ttl: " << ttl << ", port: " << port << endl; } if (saddress.empty()) { if (_debug) { - cout << "TTLEngine::send() source address is empty" << endl; + cout << "LBTestTTL::send() source address is empty" << endl; } return; } if (_debug) { - cout << "TTLEngine::send() source address is: " << saddress << endl; + cout << "LBTestTTL::send() source address is: " << saddress << endl; } int err; @@ -214,7 +119,7 @@ TTLEngine::send(int send_sock, const string &iface, const string &target_addr, u struct hostent *h = gethostbyname(target_addr.c_str()); if (h == NULL) { if (_debug) { - cerr << "TTLEngine::send() Error in resolving hostname" << endl; + cerr << "LBTestTTL::send() Error in resolving hostname" << endl; } syslog(LOG_ERR, "wan_lb: error in resolving configured hostname: %s", target_addr.c_str()); return; @@ -222,8 +127,9 @@ TTLEngine::send(int send_sock, const string &iface, const string &target_addr, u // bind a socket to a device name (might not work on all systems): if (setsockopt(send_sock, SOL_SOCKET, SO_BINDTODEVICE, iface.c_str(), iface.size()) != 0) { + cout << "send sock: " << send_sock << endl; if (_debug) { - cerr << "TTLEngine::send() failure to bind to interface: " << iface << endl; + cerr << "LBTestTTL::send() failure to bind to interface: " << iface << endl; } syslog(LOG_ERR, "wan_lb: failure to bind to interface: %s", iface.c_str()); return; //will allow the test to time out then @@ -267,7 +173,7 @@ TTLEngine::send(int send_sock, const string &iface, const string &target_addr, u taddr.sin_port = packet_id; err = sendto(send_sock, buffer, sizeof(iphdr)+sizeof(udphdr)+data_length, 0, (struct sockaddr*)&taddr, sizeof(taddr)); if (_debug) { - cout << "TTLEngine::send(): send " << err << " bytes" << endl; + cout << "LBTestTTL::send(): send " << err << " bytes" << endl; } if (_debug) { if(err < 0) { @@ -299,61 +205,6 @@ TTLEngine::send(int send_sock, const string &iface, const string &target_addr, u } } -/** - * - * - **/ -int -TTLEngine::receive(int recv_sock) -{ - timeval wait_time; - int icmp_pktsize = 40; - char resp_buf[icmp_pktsize]; - icmphdr *icmp_hdr; - fd_set readfs; - - FD_ZERO(&readfs); - FD_SET(recv_sock, &readfs); - - wait_time.tv_usec = 0; - wait_time.tv_sec = 3; //3 second timeout - - if (_debug) { - cout << "TTLEngine::receive(): start" << endl; - } - - //NEW-OLD STUFF HERE - - if (select(recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0) { - int bytes_recv = ::recv(recv_sock, &resp_buf, 56, MSG_PEEK); - if (bytes_recv != -1) { - if (_debug) { - cout << "TTLEngine::receive() received: " << bytes_recv << endl; - } - icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr)); - if (icmp_hdr->type == ICMP_TIME_EXCEEDED) { - //process packet data - int ret = ::recv(recv_sock, &resp_buf, icmp_pktsize, 0); - if (ret != -1) { - char* data; - int id = 0; - data = (char*)(&resp_buf) + 49; - memcpy(&id, data, sizeof(unsigned short)); - if (_debug) { - cout << "TTLEngine::receive(): " << id << endl; - } - return id; - } - } - } - else { - cerr << "TTLEngine::receive(): error from recvfrom" << endl; - } - } - return -1; -} - - /** @@ -362,7 +213,7 @@ TTLEngine::receive(int recv_sock) * **/ unsigned short -TTLEngine::in_checksum(unsigned short *addr, int len) +LBTestTTL::in_checksum(unsigned short *addr, int len) { int sum = 0; unsigned short answer = 0; @@ -392,7 +243,7 @@ TTLEngine::in_checksum(unsigned short *addr, int len) * **/ unsigned short -TTLEngine::udp_checksum(unsigned char proto, char *packet, int length, unsigned long source_address, unsigned long dest_address) +LBTestTTL::udp_checksum(unsigned char proto, char *packet, int length, unsigned long source_address, unsigned long dest_address) { struct PseudoHdr { @@ -433,7 +284,7 @@ TTLEngine::udp_checksum(unsigned char proto, char *packet, int length, unsigned * **/ unsigned short -TTLEngine::get_new_packet_id() +LBTestTTL::get_new_packet_id() { if (_packet_id >= _max_port_id) _packet_id = _min_port_id; diff --git a/src/lbtest_ttl.hh b/src/lbtest_ttl.hh index ca7f38c..7b00a57 100644 --- a/src/lbtest_ttl.hh +++ b/src/lbtest_ttl.hh @@ -12,72 +12,10 @@ #include <sys/socket.h> #include <netdb.h> #include <iostream> -#include "lbdata.hh" +#include "lbtest.hh" using namespace std; -class LBTestTTL; - -/** - * - * - **/ -class TTLEngine -{ - class PktData - { - public: - PktData(string iface, int rtt) : _iface(iface),_rtt(rtt) {} - string _iface; - int _rtt; - }; - -public: - TTLEngine() : - _debug(true), - _initialized(false), - _received(false), - _packet_id(32767), - _min_port_id(32767), - _max_port_id(55000) - {} - - void - init(); - - int - process(LBHealth &health,LBTestTTL *data); - - int - recv(LBHealth &health,LBTestTTL *data); - -private: - void - send(int sock, const string &iface, const string &target_addr, unsigned short packet_id, string address, int ttl, unsigned short port); - - int - receive(int sock); - - unsigned short - udp_checksum(unsigned char ucProto, char *pPacket, int iLength, unsigned long ulSourceAddress, unsigned long ulDestAddress); - - unsigned short - in_checksum(unsigned short *pAddr, int iLen); - - unsigned short - get_new_packet_id(); - -private: - bool _debug; - bool _initialized; - bool _received; - unsigned short _packet_id; - unsigned short _min_port_id; - unsigned long _max_port_id; - - map<int,PktData> _results; -}; - /** * * @@ -88,23 +26,24 @@ public: LBTestTTL(bool debug) : LBTest(debug), _ttl(0), - _port(0) + _port(0), + _min_port_id(32767), + _max_port_id(55000) {} LBTestTTL(bool debug, unsigned short ttl, unsigned short port) : LBTest(debug), _ttl(ttl), - _port(port) + _port(port), + _min_port_id(32767), + _max_port_id(55000) {} ~LBTestTTL() {} void - init() {_engine.init();this->LBTest::init();} + init(); void - send(LBHealth &health) {_engine.process(health,this);} - - int - recv(LBHealth &health) {return _engine.recv(health,this);} + send(LBHealth &health); unsigned short get_ttl() const {return _ttl;} @@ -121,11 +60,30 @@ public: string dump(); + string + name() {return string("ttl");} + +private: + unsigned short + udp_checksum(unsigned char ucProto, char *pPacket, int iLength, unsigned long ulSourceAddress, unsigned long ulDestAddress); + + unsigned short + in_checksum(unsigned short *pAddr, int iLen); + + void + send(int sock, const string &iface, const string &target_addr, unsigned short packet_id, string address, int ttl, unsigned short port); + + unsigned short + get_new_packet_id(); + + + private: - static TTLEngine _engine; //singleton bool _debug; unsigned short _ttl; unsigned short _port; + unsigned short _min_port_id; + unsigned long _max_port_id; }; #endif //__LBTEST_TTL_HH__ |
