summaryrefslogtreecommitdiff
path: root/src/lbtest_icmp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lbtest_icmp.cc')
-rw-r--r--src/lbtest_icmp.cc128
1 files changed, 49 insertions, 79 deletions
diff --git a/src/lbtest_icmp.cc b/src/lbtest_icmp.cc
index c032b42..645aeed 100644
--- a/src/lbtest_icmp.cc
+++ b/src/lbtest_icmp.cc
@@ -11,6 +11,7 @@
#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>
@@ -25,7 +26,6 @@
#include <iostream>
#include <string>
#include <algorithm>
-
#include "lbdata.hh"
#include "lbtest_icmp.hh"
@@ -40,52 +40,10 @@ using namespace std;
void
ICMPEngine::init()
{
- _results.erase(_results.begin(),_results.end());
- if (_initialized == true) {
- return;
- }
- _initialized = true;
if (_debug) {
cout << "LBTestICMP::init(): initializing test system" << endl;
}
-
- struct protoent *ppe = getprotobyname("icmp");
- _send_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto);
- if (_send_sock < 0){
- if (_debug) {
- cerr << "LBTestICMP::LBTestICMP(): no send sock: " << _send_sock << endl;
- }
- syslog(LOG_ERR, "wan_lb: failed to acquired socket");
- _send_sock = 0;
- return;
- }
-
- //set options for broadcasting.
- int val = 1;
- setsockopt(_send_sock, SOL_SOCKET, SO_BROADCAST, &val, 4);
- setsockopt(_send_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_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto);
- if (_recv_sock < 0) {
- if (_debug) {
- cerr << "LBTestICMP::LBTestICMP(): no recv sock: " << _recv_sock << endl;
- }
- syslog(LOG_ERR, "wan_lb: failed to acquired socket");
- _recv_sock = 0;
- return;
- }
- if (bind(_recv_sock, (struct sockaddr*)&addr, sizeof(addr))==-1) {
- if (_debug) {
- cerr << "failed on bind" << endl;
- }
- syslog(LOG_ERR, "wan_lb: failed to bind recv sock");
- }
+ _results.erase(_results.begin(),_results.end());
}
/**
@@ -114,7 +72,7 @@ ICMPEngine::process(LBHealth &health,LBTestICMP *data)
cout << "LBTestICMP::start(): sending ping test for: " << health._interface << " for " << target << endl;
}
_packet_id = ++_packet_id % 32767;
- send(health._interface, target, _packet_id);
+ send(data->_send_icmp_sock, health._interface, target, _packet_id);
_results.insert(pair<int,PktData>(_packet_id,PktData(health._interface,-1)));
}
@@ -127,6 +85,10 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data)
{
struct timeval send_time;
gettimeofday(&send_time,NULL);
+
+ if (_results.empty() == true) {
+ return -1;
+ }
//use gettimeofday to calculate time to millisecond
//then iterate over recv socket and receive and record
@@ -137,10 +99,11 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data)
unsigned long timeout = si.uptime + 5; //seconds
unsigned long cur_time = si.uptime;
while (cur_time < timeout) {
- int id = receive();
+ int id = receive(data->_recv_icmp_sock);
if (_debug) {
cout << "LBTestICMP::start(): " << id << endl;
}
+
//update current time for comparison
struct sysinfo si;
sysinfo(&si);
@@ -162,9 +125,11 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data)
//time in milliseconds below
int rtt = abs(msecs) / 1000 + 1000 * secs;
if (rtt < data->_resp_time) {
- return rtt;
+ data->_state = LBTest::K_SUCCESS;
+ return rtt;
}
else {
+ data->_state = LBTest::K_FAILURE;
return -1;
}
_results.erase(r_iter);
@@ -174,20 +139,16 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data)
if (_debug) {
cout << "LBTestICMP::start(): finished heath test" << endl;
}
+ data->_state = LBTest::K_FAILURE;
return -1;
}
-
-
-
-
-
/**
*
*
**/
void
-ICMPEngine::send(const string &iface, const string &target_addr, int packet_id)
+ICMPEngine::send(int send_sock, const string &iface, const string &target_addr, int packet_id)
{
int err;
sockaddr_in taddr;
@@ -200,12 +161,6 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id)
return;
}
- // 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) {
- syslog(LOG_ERR, "wan_lb: failure to bind to interface: %s", iface.c_str());
- return; //will allow the test to time out then
- }
-
//convert target_addr to ip addr
struct hostent *h = gethostbyname(target_addr.c_str());
if (h == NULL) {
@@ -216,6 +171,12 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id)
return;
}
+ // 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) {
+ syslog(LOG_ERR, "wan_lb: failure to bind to interface: %s", iface.c_str());
+ return; //will allow the test to time out then
+ }
+
icmp_hdr = (struct icmphdr *)buffer;
icmp_hdr->type = ICMP_ECHO;
icmp_hdr->code = 0;
@@ -250,12 +211,11 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id)
bzero(&(taddr.sin_zero), 8);
//need to direct this packet out a specific interface!!!!!!!!!!!!!
- err = sendto(_send_sock, buffer, icmp_pktsize, 0, (struct sockaddr*)&taddr, sizeof(taddr));
+ err = sendto(send_sock, buffer, icmp_pktsize, 0, (struct sockaddr*)&taddr, sizeof(taddr));
if (_debug) {
cout << "LBTestICMP::send(): sendto: " << err << ", packet id: " << packet_id << endl;
}
- if(err < 0)
- {
+ if(err < 0) {
if (_debug) {
if (errno == EBADF)
cout << "EBADF" << endl;
@@ -293,7 +253,7 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id)
*
**/
int
-ICMPEngine::receive()
+ICMPEngine::receive(int recv_sock)
{
int icmp_pktsize = 40;
char resp_buf[icmp_pktsize];
@@ -303,7 +263,7 @@ ICMPEngine::receive()
int ret;
FD_ZERO(&readfs);
- FD_SET(_recv_sock, &readfs);
+ FD_SET(recv_sock, &readfs);
wait_time.tv_usec = 0;
wait_time.tv_sec = 3; //3 second timeout
@@ -312,27 +272,25 @@ ICMPEngine::receive()
cout << "LBTestICMP::receive(): start" << endl;
}
- while (select(_recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0)
+ while (select(recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0)
{
- ret = ::recv(_recv_sock, &resp_buf, icmp_pktsize, 0);
- if (ret != -1)
- {
+ ret = ::recv(recv_sock, &resp_buf, icmp_pktsize, 0);
+ if (ret != -1) {
if (_debug) {
cout << "LBTestICMP::receive(): recv: " << ret << endl;
}
-
+
icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr));
- if (icmp_hdr->type == ICMP_ECHOREPLY)
- {
+ if (icmp_hdr->type == ICMP_ECHOREPLY) {
+ //process packet data
+ char* data;
+ int id = 0;
+ data = (char*)(&resp_buf) + 36;
+ memcpy(&id, data, sizeof(unsigned short));
if (_debug) {
- cout << "LBTestICMP::receive(): " << endl;
+ cout << "LBTestICMP::receive(): " << id << endl;
}
- //process packet data
- char* data;
- int id = 0;
- data = (char*)(&resp_buf) + 36;
- memcpy(&id, data, sizeof(unsigned short));
- return id;
+ return id;
}
}
}
@@ -347,10 +305,22 @@ unsigned short
ICMPEngine::in_checksum(const unsigned short *buffer, int length) const
{
unsigned long sum;
- for (sum=0; length>0; length--)
+ for (sum=0; length>0; length--) {
sum += *buffer++;
+ }
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
+/**
+ *
+ *
+ **/
+string
+LBTestICMP::dump()
+{
+ char buf[20];
+ sprintf(buf,"%u",_resp_time);
+ return (string("target: ") + _target + ", resp_time: " + buf);
+}