- 655. [func] tmark
-6XX. [func] tomek
++656. [func] tomek
+ Additional hooks (buffer6_receive, lease6_renew,
+ lease6_release, buffer6_send) added to the DHCPv6 server.
- (Trac #2984, git ABCD)
++ (Trac #2984, git 540dd0449121094a56f294c500c2ed811f6016b6)
++
++655. [func] tmark
+ Added D2UpdateMgr class to b10-dhcp-ddns. This class is the b10-dhcp-ddns
+ task master, instantiating and supervising transactions that carry out the
+ DNS updates needed to fulfill the requests (NameChangeRequests) received
+ from b10-dhcp-ddns clients (e.g. DHCP servers).
- (Trac #3059 git d72675617d6b60e3eb6160305738771f015849ba)
++ (Trac #3059 git d72675617d6b60e3eb6160305738771f015849ba)
+
+654. [bug] stephen
+ Always clear "skip" flag before calling any callouts on a hook.
+ (Trac# 3050, git ff0b9b45869b1d9a4b99e785fbce421e184c2e93)
+
+653. [func] tmark
+ Added initial implementation of D2QueueMgr to
+ b10-dhcp-ddns. This class manages the receipt and
+ queueing of requests received by b10-dhcp-ddns from
+ its clients (e.g. DHCP servers)
+ (Trac# 3052, git a970f6c5255e000c053a2dc47926cea7cec2761c)
+
+652. [doc] stephen
+ Added the "Hook Developer's Guide" to the BIND 10 developer
+ documentation.
+ (Trac# 2982, git 26a805c7e49a9ec85ee825f179cda41a2358f4c6)
+
+651. [bug] muks
+ A race condition when creating cmdctl certificates caused corruption
+ of these certificates in rare cases. This has now been fixed.
+ (Trac# 2962, git 09f557d871faef090ed444ebeee7f13e142184a0)
+
+650. [func] muks
+ The DomainTree rebalancing code has been updated to be more
+ understandable. This ChangeLog entry is made just to make a note
+ of this change. The change should not cause any observable
+ difference whatsoever.
+ (Trac# 2811, git 7c0bad1643af13dedf9356e9fb3a51264b7481de)
+
+649. [func] muks
+ The default b10-xfrout also_notify port has been changed from
+ 0 to 53.
+ (Trac# 2925, git 8acbf043daf590a9f2ad003e715cd4ffb0b3f979)
+
+648. [func] tmark
+ Moved classes pertaining to sending and receiving
+ NameChangeRequests from src/bin/d2 into their own library,
+ libdhcp_ddns, in src/lib/dhcp_ddns. This allows the
+ classes to be shared between DHDCP-DDNS and its clients,
+ such as the DHCP servers.
+ (Trac# 3065, git 3d39bccaf3f0565152ef73ec3e2cd03e77572c56)
+
+647. [func] tmark
+ Added initial implementation of classes for sending
+ and receiving NameChangeRequests between DHCP-DDNS
+ and its clients such as DHCP. This includes both
+ abstract classes and a derivation which traffics
+ requests across UDP sockets.
+ (Trac #3008, git b54530b4539cec4476986442e72c047dddba7b48)
+
+646. [func] stephen
+ Extended the hooks framework to add a "validate libraries" function.
+ This will be used to check libraries specified during BIND 10
+ configuration.
+ (Trac #3054, git 0f845ed94f462dee85b67f056656b2a197878b04)
645. [func] tomek
- Added initial set of hooks (pk4_receive, subnet4_select,
+ Added initial set of hooks (pkt4_receive, subnet4_select,
lease4_select, pkt4_send) to the DHCPv6 server.
(Trac #2994, git be65cfba939a6a7abd3c93931ce35c33d3e8247b)
LOG_ERROR(dhcp6_logger, DHCP6_PACKET_RECEIVE_FAIL).arg(e.what());
}
- if (query) {
- if (!query->unpack()) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
- DHCP6_PACKET_PARSE_FAIL);
- continue;
- }
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PACKET_RECEIVED)
- .arg(query->getName());
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_QUERY_DATA)
- .arg(static_cast<int>(query->getType()))
- .arg(query->getBuffer().getLength())
- .arg(query->toText());
-
- // Let's execute all callouts registered for packet_received
- if (HooksManager::getHooksManager().calloutsPresent(hook_index_pkt6_receive_)) {
- CalloutHandlePtr callout_handle = getCalloutHandle(query);
+ // Timeout may be reached or signal received, which breaks select() with no packet received
+ if (!query) {
+ continue;
+ }
- // Delete previously set arguments
- callout_handle->deleteAllArguments();
+ bool skip_unpack = false;
- // Pass incoming packet as argument
- callout_handle->setArgument("query6", query);
+ // The packet has just been received so contains the uninterpreted wire
+ // data; execute callouts registered for buffer6_receive.
+ if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_buffer6_receive_)) {
+ CalloutHandlePtr callout_handle = getCalloutHandle(query);
- // Call callouts
- HooksManager::callCallouts(hook_index_pkt6_receive_, *callout_handle);
+ // Delete previously set arguments
+ callout_handle->deleteAllArguments();
- // Callouts decided to skip the next processing step. The next
- // processing step would to process the packet, so skip at this
- // stage means drop.
- if (callout_handle->getSkip()) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_RCVD_SKIP);
- continue;
- }
+ // Pass incoming packet as argument
+ callout_handle->setArgument("query6", query);
- callout_handle->getArgument("query6", query);
+ // Call callouts
+ HooksManager::callCallouts(Hooks.hook_index_buffer6_receive_, *callout_handle);
+
+ // Callouts decided to skip the next processing step. The next
+ // processing step would to parse the packet, so skip at this
+ // stage means that callouts did the parsing already, so server
+ // should skip parsing.
+ if (callout_handle->getSkip()) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_RCVD_SKIP);
+ skip_unpack = true;
}
- try {
- switch (query->getType()) {
- case DHCPV6_SOLICIT:
- rsp = processSolicit(query);
- break;
+ callout_handle->getArgument("query6", query);
+ }
- case DHCPV6_REQUEST:
- rsp = processRequest(query);
- break;
+ // Unpack the packet information unless the buffer6_receive callouts
+ // indicated they did it
+ if (!skip_unpack) {
+ if (!query->unpack()) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
+ DHCP6_PACKET_PARSE_FAIL);
+ continue;
+ }
+ }
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PACKET_RECEIVED)
+ .arg(query->getName());
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_QUERY_DATA)
+ .arg(static_cast<int>(query->getType()))
+ .arg(query->getBuffer().getLength())
+ .arg(query->toText());
+
+ // At this point the information in the packet has been unpacked into
+ // the various packet fields and option objects has been cretated.
+ // Execute callouts registered for packet6_receive.
+ if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_pkt6_receive_)) {
+ CalloutHandlePtr callout_handle = getCalloutHandle(query);
+
+ // Delete previously set arguments
+ callout_handle->deleteAllArguments();
+
+ // Pass incoming packet as argument
+ callout_handle->setArgument("query6", query);
+
+ // Call callouts
+ HooksManager::callCallouts(Hooks.hook_index_pkt6_receive_, *callout_handle);
+
+ // Callouts decided to skip the next processing step. The next
+ // processing step would to process the packet, so skip at this
+ // stage means drop.
+ if (callout_handle->getSkip()) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_RCVD_SKIP);
+ continue;
+ }
- case DHCPV6_RENEW:
- rsp = processRenew(query);
- break;
+ callout_handle->getArgument("query6", query);
+ }
- case DHCPV6_REBIND:
- rsp = processRebind(query);
+ try {
+ switch (query->getType()) {
+ case DHCPV6_SOLICIT:
+ rsp = processSolicit(query);
break;
- case DHCPV6_CONFIRM:
- rsp = processConfirm(query);
- break;
+ case DHCPV6_REQUEST:
+ rsp = processRequest(query);
+ break;
+
+ case DHCPV6_RENEW:
+ rsp = processRenew(query);
+ break;
+
+ case DHCPV6_REBIND:
+ rsp = processRebind(query);
+ break;
+
+ case DHCPV6_CONFIRM:
+ rsp = processConfirm(query);
+ break;
+
+ case DHCPV6_RELEASE:
+ rsp = processRelease(query);
+ break;
+
+ case DHCPV6_DECLINE:
+ rsp = processDecline(query);
+ break;
+
+ case DHCPV6_INFORMATION_REQUEST:
+ rsp = processInfRequest(query);
+ break;
+
+ default:
+ // We received a packet type that we do not recognize.
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_UNKNOWN_MSG_RECEIVED)
+ .arg(static_cast<int>(query->getType()))
+ .arg(query->getIface());
+ // Only action is to output a message if debug is enabled,
+ // and that will be covered by the debug statement before
+ // the "switch" statement.
+ ;
+ }
- case DHCPV6_RELEASE:
- rsp = processRelease(query);
- break;
+ } catch (const RFCViolation& e) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_REQUIRED_OPTIONS_CHECK_FAIL)
+ .arg(query->getName())
+ .arg(query->getRemoteAddr().toText())
+ .arg(e.what());
+
+ } catch (const isc::Exception& e) {
+
+ // Catch-all exception (at least for ones based on the isc
+ // Exception class, which covers more or less all that
+ // are explicitly raised in the BIND 10 code). Just log
+ // the problem and ignore the packet. (The problem is logged
+ // as a debug message because debug is disabled by default -
+ // it prevents a DDOS attack based on the sending of problem
+ // packets.)
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_PROCESS_FAIL)
+ .arg(query->getName())
+ .arg(query->getRemoteAddr().toText())
+ .arg(e.what());
+ }
- case DHCPV6_DECLINE:
- rsp = processDecline(query);
- break;
+ if (rsp) {
+ rsp->setRemoteAddr(query->getRemoteAddr());
+ rsp->setLocalAddr(query->getLocalAddr());
+ rsp->setRemotePort(DHCP6_CLIENT_PORT);
+ rsp->setLocalPort(DHCP6_SERVER_PORT);
+ rsp->setIndex(query->getIndex());
+ rsp->setIface(query->getIface());
+
+ // Specifies if server should do the packing
+ bool skip_pack = false;
+
+ // Server's reply packet now has all options and fields set.
+ // Options are represented by individual objects, but the
+ // output wire data has not been prepared yet.
+ // Execute all callouts registered for packet6_send
+ if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_pkt6_send_)) {
+ CalloutHandlePtr callout_handle = getCalloutHandle(query);
- case DHCPV6_INFORMATION_REQUEST:
- rsp = processInfRequest(query);
- break;
+ // Delete all previous arguments
+ callout_handle->deleteAllArguments();
+
+ // Set our response
+ callout_handle->setArgument("response6", rsp);
- default:
- // Only action is to output a message if debug is enabled,
- // and that will be covered by the debug statement before
- // the "switch" statement.
- ;
+ // Call all installed callouts
+ HooksManager::callCallouts(Hooks.hook_index_pkt6_send_, *callout_handle);
+
+ // Callouts decided to skip the next processing step. The next
+ // processing step would to pack the packet (create wire data).
+ // That step will be skipped if any callout sets skip flag.
+ // It essentially means that the callout already did packing,
+ // so the server does not have to do it again.
+ if (callout_handle->getSkip()) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_SEND_SKIP);
+ skip_pack = true;
}
+ }
- } catch (const RFCViolation& e) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_REQUIRED_OPTIONS_CHECK_FAIL)
- .arg(query->getName())
- .arg(query->getRemoteAddr().toText())
- .arg(e.what());
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA,
+ DHCP6_RESPONSE_DATA)
+ .arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
- } catch (const isc::Exception& e) {
-
- // Catch-all exception (at least for ones based on the isc
- // Exception class, which covers more or less all that
- // are explicitly raised in the BIND 10 code). Just log
- // the problem and ignore the packet. (The problem is logged
- // as a debug message because debug is disabled by default -
- // it prevents a DDOS attack based on the sending of problem
- // packets.)
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_PROCESS_FAIL)
- .arg(query->getName())
- .arg(query->getRemoteAddr().toText())
- .arg(e.what());
+ if (!skip_pack) {
- if (!rsp->pack()) {
- LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
++ try {
++ rsp->pack();
++ } catch (const std::exception& e) {
++ LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL)
++ .arg(e.what());
+ continue;
+ }
}
- if (rsp) {
- rsp->setRemoteAddr(query->getRemoteAddr());
- rsp->setLocalAddr(query->getLocalAddr());
- rsp->setRemotePort(DHCP6_CLIENT_PORT);
- rsp->setLocalPort(DHCP6_SERVER_PORT);
- rsp->setIndex(query->getIndex());
- rsp->setIface(query->getIface());
+ try {
- // Execute all callouts registered for packet6_send
- if (HooksManager::getHooksManager().calloutsPresent(hook_index_pkt6_send_)) {
+ // Now all fields and options are constructed into output wire buffer.
+ // Option objects modification does not make sense anymore. Hooks
+ // can only manipulate wire buffer at this stage.
+ // Let's execute all callouts registered for buffer6_send
+ if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_buffer6_send_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
- // Delete all previous arguments
+ // Delete previously set arguments
callout_handle->deleteAllArguments();
- // Set our response
+ // Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
-
- // Call all installed callouts
- HooksManager::callCallouts(hook_index_pkt6_send_, *callout_handle);
-
+
+ // Call callouts
+ HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle);
+
// Callouts decided to skip the next processing step. The next
- // processing step would to send the packet, so skip at this
- // stage means "drop response".
+ // processing step would to parse the packet, so skip at this
+ // stage means drop.
if (callout_handle->getSkip()) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_SEND_SKIP);
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP);
continue;
}
+
+ callout_handle->getArgument("response6", rsp);
}
-
+
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA,
+ DHCP6_RESPONSE_DATA)
+ .arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
+
- try {
- rsp->pack();
- sendPacket(rsp);
- } catch (const std::exception& e) {
- LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL)
- .arg(e.what());
- }
+ sendPacket(rsp);
+ } catch (const std::exception& e) {
- LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what());
++ LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL)
++ .arg(e.what());
}
- }
+ }
}
return (true);