Pinger::~Pinger()
{
}
+
+void Pinger::set_myself( const Pinger::WeakPtr &myself)
+{
+ Myself = myself;
+}
+
+Pinger::WeakPtr Pinger::get_myself() const
+{
+ return Myself;
+}
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/asio/io_service.hpp>
+#include <boost/weak_ptr.hpp>
//-----------------------------------------------------------------------------
// IoServiceItem
/**
* @brief Abstract class for pingers.
* Scope: one object per host.
+ *
+ * Holds a weak_ptr to itself, so can create shared_ptrs from self
+ * (adapted from amime project)
*/
class Pinger : boost::noncopyable
{
public:
+ typedef boost::weak_ptr<Pinger> WeakPtr;
+
virtual void ping(
const std::string &destination_ip,
const uint16_t destination_port,
protected:
Pinger();
virtual ~Pinger();
+
+ Pinger::WeakPtr get_myself() const;
+ void set_myself(const Pinger::WeakPtr &myself);
+
+private:
+ Pinger::WeakPtr Myself;
};
+
//-----------------------------------------------------------------------------
// PingerItem
//-----------------------------------------------------------------------------
{
if (protocol == PingProtocol_ICMP)
{
- PingerItem new_pinger(
- new IcmpPinger( io_serv, icmp::v4(), network_interface, ping_reply_timeout )
- );
- IcmpPaketDistributor::get_distributor(icmp::v4(), network_interface, io_serv)
- ->register_pinger(new_pinger);
+ PingerItem new_pinger = IcmpPinger::create( io_serv, icmp::v4(),
+ network_interface,
+ ping_reply_timeout );
return new_pinger;
}
else if (protocol == PingProtocol_ICMPv6)
{
- PingerItem new_pinger(
- new IcmpPinger( io_serv, icmp::v6(), network_interface, ping_reply_timeout )
- );
- IcmpPaketDistributor::get_distributor(icmp::v6(), network_interface, io_serv)
- ->register_pinger(new_pinger);
+ PingerItem new_pinger = IcmpPinger::create( io_serv, icmp::v6(),
+ network_interface,
+ ping_reply_timeout );
return new_pinger;
}
else if (protocol == PingProtocol_TCP)
{
- return PingerItem(
- new TcpPinger( io_serv, tcp_raw_protocol::v4(), network_interface, ping_reply_timeout )
- );
+ PingerItem new_pinger = TcpPinger::create( io_serv, tcp_raw_protocol::v4(),
+ network_interface,
+ ping_reply_timeout );
+ return new_pinger;
}
else if (protocol == PingProtocol_TCP_IPv6)
{
- return PingerItem(
- new TcpPinger( io_serv, tcp_raw_protocol::v6(), network_interface, ping_reply_timeout )
- );
+ PingerItem new_pinger = TcpPinger::create( io_serv, tcp_raw_protocol::v6(),
+ network_interface,
+ ping_reply_timeout );
+ return new_pinger;
}
else
{
void IcmpPinger::stop_pinging()
{
IcmpPaketDistributor::get_distributor(Protocol, NetInterface.get_name())
- ->unregister_pinger(PingerItem(this));
+ ->unregister_pinger( get_myself().lock() );
}
PingerStatus = ping_status;
}
+
+PingerItem IcmpPinger::create(
+ const IoServiceItem io_serv,
+ const icmp::socket::protocol_type &protocol,
+ const string &source_network_interface,
+ const int echo_reply_timeout_in_sec )
+{
+ // create pinger
+ IcmpPinger *ptr = new IcmpPinger(io_serv, protocol, source_network_interface,
+ echo_reply_timeout_in_sec);
+ PingerItem shared_ptr(ptr);
+ Pinger::WeakPtr weak_ptr( shared_ptr );
+
+ // keep weak pointer to self
+ ptr->set_myself( weak_ptr );
+ // shared_ptr->set_myself( weak_ptr ); Error: Pinger::set_myself is protected
+
+ // register in distributor
+ IcmpPaketDistributor::get_distributor(icmp::v4(), source_network_interface, io_serv)
+ ->register_pinger(shared_ptr);
+
+ // done, return shared ptr
+ return shared_ptr;
+}
+
class IcmpPinger : public Pinger
{
public:
- IcmpPinger(
+ static PingerItem create(
const IoServiceItem io_serv,
const boost::asio::ip::icmp::socket::protocol_type &protocol,
const std::string &source_network_interface,
const int echo_reply_timeout_in_sec
);
+
virtual ~IcmpPinger();
virtual void ping(
virtual void stop_pinging();
private:
+ IcmpPinger(
+ const IoServiceItem io_serv,
+ const boost::asio::ip::icmp::socket::protocol_type &protocol,
+ const std::string &source_network_interface,
+ const int echo_reply_timeout_in_sec
+ );
+
void set_destination_endpoint( const std::string &destination_ip );
bool start_send();
bool ReceiveHandlerInPlace;
};
+typedef boost::shared_ptr<IcmpPinger> IcmpPingerItem;
+
#endif // ICMP_PINGER_H
{
PingerStatus = ping_status;
}
+
+PingerItem TcpPinger::create(
+ const IoServiceItem io_serv,
+ const tcp_raw_protocol::socket::protocol_type &protocol,
+ const string &source_network_interface_name,
+ const int rst_reply_timeout_in_sec )
+{
+ TcpPinger *ptr = new TcpPinger(io_serv, protocol, source_network_interface_name,
+ rst_reply_timeout_in_sec);
+ PingerItem shared_ptr(ptr);
+ Pinger::WeakPtr weak_ptr( shared_ptr );
+
+ // keep weak pointer to self
+ ptr->set_myself( weak_ptr );
+ // shared_ptr->set_myself( weak_ptr ); Error: Pinger::set_myself is protected
+
+ // done, return shared ptr
+ return shared_ptr;
+}
class TcpPinger : public Pinger
{
public:
- TcpPinger(
- const IoServiceItem io_serv,
- const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
- const std::string &source_network_interface_name,
- const int rst_reply_timeout_in_sec
- );
virtual ~TcpPinger();
virtual void ping(
virtual void stop_pinging();
+ static PingerItem create(
+ const IoServiceItem io_serv,
+ const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
+ const std::string &source_network_interface_name,
+ const int rst_reply_timeout_in_sec
+ );
+
private:
+ TcpPinger(
+ const IoServiceItem io_serv,
+ const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
+ const std::string &source_network_interface_name,
+ const int rst_reply_timeout_in_sec
+ );
+
boost::asio::ip::address get_source_address() const;
boost::asio::ip::address get_destination_address() const;