# Kea is told to listen on eth0 interface only.
"interfaces": [ "eth0" ],
+# We need to specify lease type. As of May 2014, three backends are supported:
+# memfile, mysql and pgsql. We'll just use memfile, because it doesn't require
+# any prior set up.
+ "lease-database": {
+ "type": "memfile"
+ },
+
# Addresses will be assigned with preferred and valid lifetimes
# being 3000 and 4000, respectively. Client is told to start
# renewing after 1000 seconds. If the server does not repond
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET).arg(port);
try {
- // Open sockets only if port is non-zero. Port 0 is used for testing
- // purposes in two cases:
- // - when non-socket related testing is performed
- // - when the particular test supplies its own packet filtering class.
+ // Port 0 is used for testing purposes where we don't open broadcast
+ // capable sockets. So, set the packet filter handling direct traffic
+ // only if we are in non-test mode.
if (port) {
// First call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong.
// may be lacking on some OSes, so there is no guarantee that server
// will be able to respond directly.
IfaceMgr::instance().setMatchingPacketFilter(direct_response_desired);
-
- // Create error handler. This handler will be called every time
- // the socket opening operation fails. We use this handler to
- // log a warning.
- isc::dhcp::IfaceMgrErrorMsgCallback error_handler =
- boost::bind(&Dhcpv4Srv::ifaceMgrSocket4ErrorHandler, _1);
- IfaceMgr::instance().openSockets4(port_, use_bcast_, error_handler);
}
// Instantiate allocation engine
// Initialize objects required for DHCP server operation.
try {
- // Port 0 is used for testing purposes. It means that the server should
- // not open any sockets at all. Some tests, e.g. configuration parser,
- // require Dhcpv6Srv object, but they don't really need it to do
- // anything. This speed up and simplifies the tests.
- if (port > 0) {
- if (IfaceMgr::instance().countIfaces() == 0) {
- LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
- return;
- }
- // Create error handler. This handler will be called every time
- // the socket opening operation fails. We use this handler to
- // log a warning.
- isc::dhcp::IfaceMgrErrorMsgCallback error_handler =
- boost::bind(&Dhcpv6Srv::ifaceMgrSocket6ErrorHandler, _1);
- IfaceMgr::instance().openSockets6(port_, error_handler);
+ // Port 0 is used for testing purposes where in most cases we don't
+ // rely on the physical interfaces. Therefore, it should be possible
+ // to create an object even when there are no usable interfaces.
+ if ((port > 0) && (IfaceMgr::instance().countIfaces() == 0)) {
+ LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
+ return;
}
string duid_file = CfgMgr::instance().getDataDir() + "/" + string(SERVER_DUID_FILE);
if (bind(sock, reinterpret_cast<struct sockaddr*>(&addr4),
sizeof(addr4)) < 0) {
+ // Get the error message immediately after the bind because the
+ // invocation to close() below would override the errno.
+ char* errmsg = strerror(errno);
// Remember to close the socket if we failed to bind it.
close(sock);
isc_throw(SocketConfigError, "failed to bind fallback socket to"
" address " << addr << ", port " << port
- << ", reason: " << strerror(errno)
+ << ", reason: " << errmsg
<< " - is another DHCP server running?");
}
// Set socket to non-blocking mode. This is to prevent the read from the
// fallback socket to block message processing on the primary socket.
if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
+ // Get the error message immediately after the bind because the
+ // invocation to close() below would override the errno.
+ char* errmsg = strerror(errno);
close(sock);
isc_throw(SocketConfigError, "failed to set SO_NONBLOCK option on the"
" fallback socket, bound to " << addr << ", port "
- << port << ", reason: " << strerror(errno));
+ << port << ", reason: " << errmsg);
}
// Successfully created and bound a fallback socket. Return a descriptor.
return (sock);
}
if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
+ // Get the error message immediately after the bind because the
+ // invocation to close() below would override the errno.
+ char* errmsg = strerror(errno);
close(sock);
- std::cout << errno << std::endl;
isc_throw(SocketConfigError, "Failed to bind socket " << sock << " to "
<< addr.toText() << "/port=" << port
- << ": " << strerror(errno));
+ << ": " << errmsg);
}
#ifdef IPV6_RECVPKTINFO
// RFC3542 - a new way