21namespace ph = std::placeholders;
 
   31    : wildcard_used_(false), socket_type_(
SOCKET_RAW), re_detect_(false),
 
   32      service_socket_require_all_(false), service_sockets_retry_wait_time_(5000),
 
   33      service_sockets_max_retries_(0),
 
 
   44    return (iface_set_ == other.iface_set_ &&
 
   45            address_map_ == other.address_map_ &&
 
   46            wildcard_used_ == other.wildcard_used_ &&
 
   47            socket_type_ == other.socket_type_);
 
 
   51CfgIface::multipleAddressesPerInterfaceActive() {
 
   53        if (iface->countActive4() > 1) {
 
   62                      const bool use_bcast) {
 
   69    bool loopback_used_ = 
false;
 
   70    if ((family == AF_INET6) || (socket_type_ == 
SOCKET_UDP)) {
 
   72        for (
auto const& iface_name : iface_set_) {
 
   74            if (iface && iface->flag_loopback_) {
 
   75                loopback_used_ = 
true;
 
   79        for (
auto const& unicast : address_map_) {
 
   81            if (iface && iface->flag_loopback_) {
 
   82                loopback_used_ = 
true;
 
   91    setState(family, !wildcard_used_, !loopback_used_);
 
  112    if (!wildcard_used_) {
 
  113        for (
auto const& iface_name : iface_set_) {
 
  121                          "fail to open socket on interface '" 
  122                          << iface_name << 
"' as this interface doesn't" 
  125            } 
else if (family == AF_INET) {
 
  126                iface->inactive4_ = 
false;
 
  127                setIfaceAddrsState(family, 
true, *iface);
 
  130                iface->inactive6_ = 
false;
 
  137    for (
auto const& unicast : address_map_) {
 
  141                      "fail to open unicast socket on interface '" 
  142                      << unicast.first << 
"' as this interface doesn't" 
  145        if (family == AF_INET6) {
 
  146            iface->addUnicast(unicast.second);
 
  147            iface->inactive6_ = 
false;
 
  150            iface->setActive(unicast.second, 
true);
 
  151            iface->inactive4_ = 
false;
 
  157    const bool can_use_bcast = use_bcast && (socket_type_ == 
SOCKET_RAW);
 
  164    if (family == AF_INET && can_use_bcast && multipleAddressesPerInterfaceActive()) {
 
  168    reconnect_ctl_ = makeReconnectCtl();
 
  169    auto sopen = openSocketsWithRetry(reconnect_ctl_, family, port, can_use_bcast);
 
 
  179CfgIface::openSocketsForFamily(
const uint16_t family, 
const uint16_t port,
 
  180                               const bool can_use_bcast, 
const bool skip_opened) {
 
  181    bool no_errors = 
true;
 
  185    auto error_callback = [&no_errors](
const std::string& errmsg) {
 
  186        socketOpenErrorHandler(errmsg);
 
  193    if (family == AF_INET) {
 
  195                                                  error_callback, skip_opened);
 
  202    return (std::make_pair(sopen, no_errors));
 
  207    std::string timer_name = 
"SocketReopenTimer";
 
  209    auto on_fail_action = OnFailAction::SERVE_RETRY_CONTINUE;
 
  211        on_fail_action = OnFailAction::SERVE_RETRY_EXIT;
 
  215    auto reconnect_ctl = boost::make_shared<ReconnectCtl>(
"Socket", timer_name,
 
  220    return (reconnect_ctl);
 
  225                               const uint16_t family, 
const uint16_t port,
 
  226                               const bool can_use_bcast) {
 
  227    MultiThreadingCriticalSection cs;
 
  230    bool is_initial_call = (reconnect_ctl->retriesLeft() == reconnect_ctl->maxRetries());
 
  231    auto result_pair = openSocketsForFamily(family, port, can_use_bcast, !is_initial_call);
 
  232    bool sopen = result_pair.first;
 
  233    bool has_errors = !result_pair.second;
 
  235    auto timer_name = reconnect_ctl->timerName();
 
  243    if (has_errors && reconnect_ctl->retriesLeft() > 0) {
 
  245        reconnect_ctl->checkRetries();
 
  249                                                std::bind(&CfgIface::openSocketsWithRetry,
 
  250                                                          reconnect_ctl, family,
 
  251                                                          port, can_use_bcast),
 
  252                                                reconnect_ctl->retryInterval(),
 
  274    wildcard_used_ = 
false;
 
  276    address_map_.clear();
 
 
  281CfgIface::setState(
const uint16_t family, 
const bool inactive,
 
  282                   const bool loopback_inactive)
 const {
 
  284        bool iface_inactive = iface->flag_loopback_ ? loopback_inactive : inactive;
 
  285        if (family == AF_INET) {
 
  286            iface->inactive4_ = iface_inactive;
 
  288            iface->inactive6_ = iface_inactive;
 
  292        setIfaceAddrsState(family, !inactive, *iface);
 
  297CfgIface::setIfaceAddrsState(
const uint16_t family, 
const bool active,
 
  298                             Iface& iface)
 const {
 
  300    for (
auto const& addr : iface.getAddresses()) {
 
  301        if (addr.get().getFamily() == family) {
 
  302            iface.setActive(addr.get(), active);
 
  308CfgIface::socketOpenErrorHandler(
const std::string& errmsg) {
 
  314    switch (socket_type_) {
 
 
  330    if (socket_type_name == 
"udp") {
 
  333    } 
else if (socket_type_name == 
"raw") {
 
  338                  << socket_type_name << 
"'");
 
 
  344    return (outbound_iface_);
 
 
  349    switch (outbound_iface_) {
 
  351        return (
"same-as-inbound");
 
  353        return (
"use-routing");
 
 
  362    if (txt == 
"same-as-inbound") {
 
  365    } 
else if (txt == 
"use-routing") {
 
 
  376    outbound_iface_ = outbound_iface;
 
 
  387    size_t pos = iface_name.find(
"/");
 
  389    std::string addr_str;
 
  391    if (pos == std::string::npos) {
 
  395                      "empty interface name used in configuration");
 
  400                          << 
"' doesn't exist in the system");
 
  403        } 
else if (wildcard_used_) {
 
  410            wildcard_used_ = 
true;
 
  424                      "empty interface name specified in the" 
  425                      " interface configuration");
 
  429        if (addr_str.empty()) {
 
  431                      "empty address specified in the interface" 
  432                      << 
" configuration");
 
  440                      << 
"' must not be used in conjunction with an" 
  449                      << 
"' doesn't exist in the system");
 
  458        if (family == AF_INET6) {
 
  462                          " a valid IPv6 unicast address");
 
  469                    .arg(addr.
toText()).arg(name);
 
  475                          " a valid IPv4 address");
 
  480        if (!iface->hasAddress(addr)) {
 
  482                      "interface '" << name << 
"' doesn't have address '" 
  483                      << addr << 
"' assigned");
 
  489        if ((family == AF_INET) && (iface_set_.find(iface->getName()) != iface_set_.end())) {
 
  491                      << 
"' has already been selected");
 
  495        std::pair<const std::string, IOAddress> iface_address_tuple(name, addr);
 
  496        if (std::find(address_map_.begin(), address_map_.end(),
 
  497                      iface_address_tuple) != address_map_.end()) {
 
  499                      << addr << 
"' for interface '" << name << 
"' " 
  500                      "because this address is already selected");
 
  503        if (family == AF_INET6) {
 
  505                .arg(addr.
toText()).arg(name);
 
  509                .arg(addr.
toText()).arg(name);
 
  511        address_map_.insert(std::pair<std::string, IOAddress>(name, addr));
 
  519        if ((iface_set_.find(name) != iface_set_.end()) ||
 
  520            ((family == AF_INET) && address_map_.count(name) > 0)) {
 
  522                      << 
"' has already been specified");
 
  527        if (addr_str.empty()) {
 
  530        iface_set_.insert(name);
 
 
  537    if (family != AF_INET) {
 
  539                  " the DHCPv6 server");
 
  541    socket_type_ = socket_type;
 
 
  548                        const std::string& socket_type_name) {
 
 
  561    if (wildcard_used_) {
 
  564    for (
auto const& iface : iface_set_) {
 
  567    for (
auto const& address : address_map_) {
 
  568        std::string spec = address.first + 
"/" + address.second.toText();
 
  571    result->set(
"interfaces", ifaces);
 
  587    if (service_socket_require_all_) {
 
  588        result->set(
"service-sockets-require-all", 
Element::create(service_socket_require_all_));
 
  591    if (service_sockets_max_retries_ != 0) {
 
  592        result->set(
"service-sockets-max-retries", 
Element::create(
static_cast<int>(service_sockets_max_retries_)));
 
  594        result->set(
"service-sockets-retry-wait-time", 
Element::create(
static_cast<int>(service_sockets_retry_wait_time_)));
 
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
std::string toText() const
Convert the address to a string.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
bool isV6Multicast() const
checks whether and address is IPv6 and is multicast
bool isV6LinkLocal() const
checks whether and address is IPv6 and is link-local
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
static const char * ALL_IFACES_KEYWORD
Keyword used to enable all interfaces.
void closeSockets() const
Convenience function which closes all open sockets.
std::string socketTypeToText() const
Returns the socket type in the textual format.
void reset()
Puts the interface configuration into default state.
uint32_t getServiceSocketsRetryWaitTime() const
Indicates the socket service binding retry interval between attempts.
OutboundIface
Indicates how outbound interface is selected for relayed traffic.
@ USE_ROUTING
Server uses routing to determine the right interface to send response.
@ SAME_AS_INBOUND
Server sends responses over the same interface on which queries are received.
OutboundIface getOutboundIface() const
Returns outbound interface selection mode.
bool getServiceSocketsRequireAll() const
Indicates that Kea must successfully bind all socket services on init.
void openSockets(const uint16_t family, const uint16_t port, const bool use_bcast=true)
Tries to open sockets on selected interfaces.
static OutboundIface textToOutboundIface(const std::string &txt)
Converts text to outbound interface selection mode.
void use(const uint16_t family, const std::string &iface_name)
Select interface to be used to receive DHCP traffic.
bool equals(const CfgIface &other) const
Compares two CfgIface objects for equality.
SocketType
Socket type used by the DHCPv4 server.
@ SOCKET_UDP
Datagram socket, i.e. IP/UDP socket.
@ SOCKET_RAW
Raw socket, used for direct DHCPv4 traffic.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
std::string outboundTypeToText() const
Returns outbound interface selection mode as string.
void setOutboundIface(const OutboundIface &outbound_iface)
Sets outbound interface selection mode.
SocketType textToSocketType(const std::string &socket_type_name) const
Converts the socket type in the textual format to the type represented by the SocketType.
static OpenSocketsFailedCallback open_sockets_failed_callback_
Optional callback function to invoke if all retries of the opening sockets fail.
void useSocketType(const uint16_t family, const SocketType &socket_type)
Sets the specified socket type to be used by the server.
std::function< void(util::ReconnectCtlPtr)> OpenSocketsFailedCallback
Represents a callback invoked if all retries of the opening sockets fail.
uint32_t getServiceSocketsMaxRetries() const
Indicates the maximum number of service sockets bind attempts.
Exception thrown when duplicated address specified.
Exception thrown when duplicated interface names specified.
Handles network interfaces, transmission and reception.
bool openSockets4(const uint16_t port=DHCP4_SERVER_PORT, const bool use_bcast=true, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv4 sockets on detected interfaces.
IfacePtr getIface(const unsigned int ifindex)
Returns interface specified interface index.
bool openSockets6(const uint16_t port=DHCP6_SERVER_PORT, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv6 sockets on detected interfaces.
void detectIfaces(bool update_only=false)
Detects network interfaces.
void clearUnicasts()
Clears unicast addresses on all interfaces.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool isDirectResponseSupported() const
Check if packet be sent directly to the client having no address.
void closeSockets()
Closes all open sockets.
void setMatchingPacketFilter(const bool direct_response_desired=false)
Set Packet Filter object to handle send/receive packets.
void setAllowLoopBack(const bool allow_loopback)
Allows or disallows the loopback interface.
Represents a single network interface.
Exception thrown when specified interface name is invalid.
Exception thrown when invalid socket type has been specified for the given family.
Exception thrown when specified unicast address is not assigned to the interface specified.
Exception thrown when specified interface doesn't exist in a system.
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< Element > ElementPtr
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_IFACE
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
const isc::log::MessageID DHCPSRV_CFGMGR_USE_ADDRESS
const isc::log::MessageID DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE
const isc::log::MessageID DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT
const isc::log::MessageID DHCPSRV_CFGMGR_ALL_IFACES_ACTIVE
const isc::log::MessageID DHCPSRV_CFGMGR_UNICAST_LINK_LOCAL
const isc::log::MessageID DHCPSRV_NO_SOCKETS_OPEN
const isc::log::MessageID DHCPSRV_OPEN_SOCKET_FAIL
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_CFGMGR_SOCKET_RAW_UNSUPPORTED
const isc::log::MessageID DHCPSRV_CFGMGR_USE_UNICAST
string trim(const string &input)
Trim leading and trailing spaces.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.