The BoostPinger is more picky about received packets, because when running in
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Mon, 2 May 2011 10:30:42 +0000 (12:30 +0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Mon, 2 May 2011 10:30:42 +0000 (12:30 +0200)
parallel with other BoostPingers, it could receive echo replies from any host,
leading to things like:
    26 bytes from 209.85.149.104: icmp_seq=1 ttl=54 time=24 ms   <-- pinger A received packet from host A
    26 bytes from 209.85.149.104: icmp_seq=1 ttl=54 time=1999 ms <-- pinger B received packet from host A??
     - Host up: www.postbank.de                                  <-- what? You didn't receive any packet from the host you had ping
     - Stick to the original ping interval: 10s
     - Time elapsed since last ping: 12s                         <-- OK, pinger A parsed the packet from host A
     - Stick to the original ping interval: 5s
     - Time elapsed since last ping: 6s                          <-- WRONG, pinger B should not parse the packet from host A

src/host/boostpinger.cpp
src/icmp/icmppacket.cpp
src/icmp/icmppacket.h

index b962ce0..da72f42 100644 (file)
@@ -239,10 +239,12 @@ void BoostPinger::handle_receive_icmp_packet( const size_t &bytes_transferred )
     is >> icmp_packet;
 
     // We can receive all ICMP packets received by the host, so we need to
-    // filter out only the echo replies that match the our identifier and
-    // expected sequence number.
+    // filter out only the echo replies that match the our identifier,
+    // expected sequence number, and destination host address (receive just the
+    // ICMP packets from the host we had ping).
     if ( icmp_packet.match(
-            IcmpType_EchoReply, get_identifier(), SequenceNumber
+            IcmpType_EchoReply, get_identifier(), SequenceNumber,
+            DestinationEndpoint.address()
     ) )
     {
         // If this is the first reply, interrupt the echo reply timeout.
@@ -258,7 +260,8 @@ void BoostPinger::handle_receive_icmp_packet( const size_t &bytes_transferred )
         set_ping_status( PingStatus_SuccessReply );
     }
     else if ( icmp_packet.match(
-            IcmpType_DestinationUnreachable, get_identifier(), SequenceNumber
+            IcmpType_DestinationUnreachable, get_identifier(), SequenceNumber,
+            DestinationEndpoint.address()
     ) )
     {
         // If this is the first reply, interrupt the echo reply timeout.
index 87f242f..2f75248 100644 (file)
@@ -1,5 +1,8 @@
 #include "icmp/icmppacket.h"
 
+using namespace std;
+using boost::asio::ip::address;
+
 //-----------------------------------------------------------------------------
 // IcmpPacket
 //-----------------------------------------------------------------------------
@@ -41,20 +44,22 @@ IcmpData IcmpPacket::get_icmp_data() const
 }
 
 bool IcmpPacket::match(
-        IcmpType type,
-        uint16_t identifier,
-        uint16_t sequence_number
+        const IcmpType type,
+        const uint16_t identifier,
+        const uint16_t sequence_number,
+        const address &source_address
 ) const
 {
     bool type_match = IcmpPayloadHeader.get_type() == type;
     bool identifier_match = IcmpPayloadHeader.get_identifier() == identifier;
     bool seq_num_match = IcmpPayloadHeader.get_sequence_number() == sequence_number;
+    bool address_match = IpHeader.get_source_address() == source_address;
 
-    return ( type_match && identifier_match && seq_num_match );
+    return ( type_match && identifier_match && seq_num_match && address_match );
 }
 
-std::istream& operator>>(
-        std::istream &is,
+istream& operator>>(
+        istream &is,
         IcmpPacket &packet
 )
 {
@@ -63,8 +68,8 @@ std::istream& operator>>(
     return is;
 }
 
-std::ostream& operator<<(
-        std::ostream& os,
+ostream& operator<<(
+        ostream& os,
         const IcmpPacket& packet
 )
 {
index b232fee..f3a5249 100644 (file)
@@ -6,6 +6,8 @@
 #include <istream>
 #include <ostream>
 
+#include <boost/asio.hpp>
+
 #include "icmp/ipv4header.h"
 #include "icmp/icmpheader.h"
 #include "icmp/icmpdata.h"
@@ -68,9 +70,10 @@ public:
     IcmpData get_icmp_data() const;
 
     bool match(
-            IcmpType type,
-            uint16_t identifier,
-            uint16_t sequence_number
+            const IcmpType type,
+            const uint16_t identifier,
+            const uint16_t sequence_number,
+            const boost::asio::ip::address &source_address
     ) const;
 
     friend std::istream& operator>>(