summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorslioch <slioch@eng-140.vyatta.com>2009-07-28 14:35:37 -0700
committerslioch <slioch@eng-140.vyatta.com>2009-07-28 14:35:37 -0700
commitdfbf4cac22b97eab470ecd251384bf471bfed3e6 (patch)
tree5453baa75826ec854b8bc712852fced80106d93a /src
parentfe6f0901ab0970bcc937328e6093f5b0f118230d (diff)
downloadvyatta-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.cc169
-rw-r--r--src/lbdata.hh47
-rw-r--r--src/lboutput.cc13
-rw-r--r--src/lbpathtest.cc24
-rw-r--r--src/lbtest.cc294
-rw-r--r--src/lbtest.hh87
-rw-r--r--src/lbtest_icmp.cc170
-rw-r--r--src/lbtest_icmp.hh72
-rw-r--r--src/lbtest_ttl.cc191
-rw-r--r--src/lbtest_ttl.hh100
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__