#include <ha_service_states.h>
#include <cc/command_interpreter.h>
#include <cc/data.h>
+#include <dhcp/iface_mgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <http/date_time.h>
case HA_HOT_STANDBY_ST:
verboseTransition(HA_HOT_STANDBY_ST);
break;
-
+
case HA_LOAD_BALANCING_ST:
verboseTransition(HA_LOAD_BALANCING_ST);
break;
// Then it returns control to the DHCP server.
runModel(HA_LEASE_UPDATES_COMPLETE_EVT);
}
- });
+ },
+ HttpClient::RequestTimeout(10000),
+ boost::bind(&HAService::clientConnectHandler, this, _1, _2),
+ boost::bind(&HAService::clientCloseHandler, this, _1)
+ );
// Request scheduled, so update the request counters for the query.
if (pending_requests_.count(query) == 0) {
// asynchronous tasks etc. Then it returns control to the DHCP server.
startHeartbeat();
runModel(HA_HEARTBEAT_COMPLETE_EVT);
- });
+ },
+ HttpClient::RequestTimeout(10000),
+ boost::bind(&HAService::clientConnectHandler, this, _1, _2),
+ boost::bind(&HAService::clientCloseHandler, this, _1)
+ );
}
void
post_request_action(error_message.empty(),
error_message);
}
- });
+ },
+ HttpClient::RequestTimeout(10000),
+ boost::bind(&HAService::clientConnectHandler, this, _1, _2),
+ boost::bind(&HAService::clientCloseHandler, this, _1)
+ );
}
void
post_request_action(error_message.empty(),
error_message);
}
- });
+ },
+ HttpClient::RequestTimeout(10000),
+ boost::bind(&HAService::clientConnectHandler, this, _1, _2),
+ boost::bind(&HAService::clientCloseHandler, this, _1)
+ );
}
void
error_message,
dhcp_disabled);
}
- }, HttpClient::RequestTimeout(config_->getSyncTimeout()));
+ },
+ HttpClient::RequestTimeout(config_->getSyncTimeout()),
+ boost::bind(&HAService::clientConnectHandler, this, _1, _2),
+ boost::bind(&HAService::clientCloseHandler, this, _1)
+ );
+
}
ConstElementPtr
return (args);
}
+bool
+HAService::clientConnectHandler(const boost::system::error_code& ec, int tcp_native_fd) {
+ if (!ec || ec.value() == boost::asio::error::in_progress) {
+ IfaceMgr::instance().addExternalSocket(tcp_native_fd,
+ [this]() {
+ // Callback is a NOP. Ready events handlers are run by an explicit
+ // call IOService ready in kea-dhcp<n> code. We are registering
+ // the socket to interrupt main-thread select().
+ });
+ }
+
+ // If ec.value() == boost::asio::error::already_connected, we should already
+ // be registered, so nothing to do. If it is any other value, than connect
+ // failed and Connection logic should handle that, not us, so no matter
+ // what happens we're returning true.
+ return (true);
+}
+
+void
+HAService::clientCloseHandler(int tcp_native_fd) {
+ if (tcp_native_fd >= 0) {
+ IfaceMgr::instance().deleteExternalSocket(tcp_native_fd);
+ }
+};
} // end of namespace isc::ha
} // end of namespace isc
/// @throw CtrlChannelError if response is invalid or contains an error.
data::ConstElementPtr verifyAsyncResponse(const http::HttpResponsePtr& response);
+ /// @brief HttpClient connect callback handler
+ ///
+ /// Passed into HttpClient calls to allow registration of client's TCP socket
+ /// with an external monitor (such as IfaceMgr's main-thread select()).
+ ///
+ /// @param ec Error status of the ASIO connect
+ /// @param tcp_native_fd socket descriptor to register
+ /// @param returns true. Registeration cannot fail, and if ec indicates a real
+ /// error we want Connection logic to process it.
+ virtual bool clientConnectHandler(const boost::system::error_code& ec, int tcp_native_fd);
+
+ /// @brief HttpClient close callback handler
+ ///
+ /// Passed into HttpClient calls to allow unregistration of client's
+ /// TCP socket with an external monitor (such as IfaceMgr's
+ /// main-thread select()).
+ ///
+ /// @param tcp_native_fd socket descriptor to register
+ virtual void clientCloseHandler(int tcp_native_fd);
+
/// @brief Pointer to the IO service object shared between this hooks
/// library and the DHCP server.
asiolink::IOServicePtr io_service_;