TimeSent( microsec_clock::universal_time() ),
ReplyBuffer(),
RepliesCount( 0 ),
- TimesToPingTotal( 0 ),
EchoReplyTimeoutInSec( echo_reply_timeout_in_sec ),
- MinTimesToPing( 1 ),
- MaxTimesToPing( numeric_limits<uint>::max() )
+ PingerStatus( PingStatus_NotSent )
{
}
}
/**
- * Pings a given destination address
+ * Pings a given destination address.
*
* @param destination The address of the host where to ping.
*
- * @param times_to_ping The amount of times the destination host will be pinged.
- *
* @note This method is synchronous, i.e. this method blocks and returns only
- * after the amount of pings requested has finished or timed out.
+ * after the ping requested has finished or timed-out.
*/
-void BoostPinger::ping(
- const string &destination,
- const uint times_to_ping
-)
+void BoostPinger::ping( const string &destination )
{
BOOST_ASSERT( !destination.empty() );
- BOOST_ASSERT( ( MinTimesToPing <= times_to_ping ) && ( times_to_ping <= MaxTimesToPing ) );
icmp::resolver::query query( icmp::v4(), destination, "" );
DestinationEndpoint = *Resolver.resolve( query );
- TimesToPingTotal = times_to_ping;
-
start_pinger();
}
void BoostPinger::start_send()
{
- IcmpPacket icmp_echo_request_packet = create_echo_request();
+ ++SequenceNumber;
- uint times_already_pinged = SequenceNumber;
- if ( times_already_pinged <= TimesToPingTotal )
+ IcmpPacket icmp_echo_request_packet = create_echo_request( SequenceNumber );
+
+ if ( PingerStatus == PingStatus_NotSent )
{
send_echo_request( icmp_echo_request_packet );
}
}
}
-IcmpPacket BoostPinger::create_echo_request()
+IcmpPacket BoostPinger::create_echo_request(
+ const uint16_t sequence_number
+) const
{
IcmpData icmp_data( "ping-message" );
- SequenceNumber++;
IcmpHeader::IcmpType type = IcmpHeader::EchoRequest;
uint8_t code = 0;
uint16_t identifier = get_identifier();
IcmpChecksumCalculator calculator( icmp_data.begin(), icmp_data.end() );
- uint16_t checksum = calculator.compute( type, code, identifier, SequenceNumber );
- IcmpHeader icmp_header( type, code, checksum, identifier, SequenceNumber );
+ uint16_t checksum = calculator.compute(
+ type, code, identifier, sequence_number
+ );
+ IcmpHeader icmp_header(
+ type, code, checksum, identifier, sequence_number
+ );
return IcmpPacket( icmp_header, icmp_data );
}
void BoostPinger::handle_timeout_echo_reply()
{
if ( RepliesCount == 0 )
+ {
cout << "Request timed out" << endl;
+ set_ping_status( PingStatus_FailureTimeout );
+ }
+
schedule_next_echo_request();
}
{
// If this is the first reply, interrupt the echo reply timeout.
if ( RepliesCount == 0 )
+ {
Timer.cancel();
+ }
++RepliesCount;
print_echo_reply( icmp_packet, bytes_transferred );
+
+ set_ping_status( PingStatus_SuccessReply );
}
start_receive();
<< " time=" << time << " ms" << endl;
}
+void BoostPinger::set_ping_status( BoostPinger::PingStatus ping_status )
+{
+ PingerStatus = ping_status;
+}
+
uint16_t BoostPinger::get_identifier() const
{
return static_cast<uint16_t> ( ::getpid() );
);
virtual ~BoostPinger();
- void ping(
- const std::string &destination,
- const uint times_to_ping
- );
+ void ping( const std::string &destination );
+
+private:
+ enum PingStatus {
+ PingStatus_NotSent,
+ PingStatus_SuccessReply,
+ PingStatus_FailureTimeout,
+ };
private:
void start_pinger();
void stop_pinger();
void start_send();
- IcmpPacket create_echo_request();
+ IcmpPacket create_echo_request( const uint16_t sequence_number ) const;
void send_echo_request( const IcmpPacket &icmp_packet );
void schedule_timeout_echo_reply();
void handle_timeout_echo_reply();
const std::size_t &bytes_transferred
) const;
+ void set_ping_status( BoostPinger::PingStatus ping_status );
+
uint16_t get_identifier() const;
private:
boost::posix_time::ptime TimeSent;
boost::asio::streambuf ReplyBuffer;
uint RepliesCount;
- uint TimesToPingTotal;
uint EchoReplyTimeoutInSec;
-
- const uint MinTimesToPing;
- const uint MaxTimesToPing;
+ BoostPinger::PingStatus PingerStatus;
};