There are several lease query mechanisms. The simplest one, usually referred to as leasequery, is defined in RFC4388 and RFC5007. It allows UDP packets to query about various things with the expectation that the response will be a response covering at most a single DHCP client. Two query types are defined: query by address ("who owns this address?") and query by client-id ("what address does this client have?"). The answer is being sent back over UDP. The primary use case for this is an advanced relay (such as CMTS), losing information after reboot. It then tries to repopulate its own state tables with information being retrieved from the DHCP server. As of Kea 1.7.4, it seems all the information are already stored in our lease database (sadly, even the basic leasequery expects relay options to be returned).
The next, more complex mechanism is Bulk Leasequery, defined in RFC6926 and RFC5460. This is a TCP based service where requestor can ask a single query and get a response covering multiple clients. Three new query types are defined: query by relay-id (which introduces a new option that can be inserted by relay), query by identifier-id (which is expected to return all clients that are connecting through a relay with specific interface-id) and query by remote-id (which is expected to return all clients that got specific remote-id inserted by their relay). This is significantly more complex for several reasons. First, Kea will have to implement TCP-based traffic with similar, but slightly different framing (every DHCP packet is preceded with 2 bytes specifying length). Second, Kea will need to respond with many (possibly thousands if a subnet is big) responses, which imply some sort of scheduling or sending responses in chunks mechanism. Third, we don't store relay-id, interface-id or remote-id. Those are options that may be inserted by relays. We don't store them. One way to solve this is to use user-context mechanism to store received relay options.
The last and most complex type of leasequery is Active Leasequery. This is effectively a subscription mechanism. Some entity can connect to a server and subscribe to any lease changes occurring at almost real-time. In a sense, this mechanism can be perceived as poor-man's failover. Defined in RFC7724 and RFC7653. In a sense, this can be perceived as continuous, ongoing bulk leasequery. It adds additional complication, TLS. If we ever decide to implement active leasequery, our initial implementation will skip the TLS part for sure.
Problems to be solved
Access control - this can be reasonably simple. The LQ queries should be disabled by default. We could implement some sort of a simple ACL that would enable it per interface and only accept queries coming from specific IP address.
Packet processing - new message types need to be implemented. Should be easy as they're not different than other existing messages we already support.
Storing extra information (relay options) in leases - We can use user-context mechanism that was designed specifically for that kind of things or add a new mechanism, but that would require updating all lease backends.
Access control - something similar to basic LQ should be enough. Reject connections from addresses that are not explicitly allowed in the config file.
Sending potentially huge responses. A single query can generate huge (potentially all leases in a subnet, so 1000s of clients) response. There has to be some sort of a mechanism that would send those back in chunks or we risk starving the server.
Three new query modes. This will imply new lease mgr querying mechanism. We could possibly get all leases in a subnet and then then further filter them out.
The following are notes collected prior to the design:
The entity that sends leasequery queries is called a requestor. In most cases it's a hardware relay, but from the protocol perspective it's a separate entity called requestor.
It would be very useful to have a requestor for debugging and testing. Two places to look at are:
dug - an experiment Shane did years ago. The idea was to come up with dig for dhcp. I've pushed Shane's original branch as experiments/dug and rebased as experiments/dug2 and managed to build it. However, it fails to bind sockets.
Dibbler has a v6 only requestor. See the code on github. Building is straightforward: ./configure && make. The dibbler-requestor binary supports basic v6 leasequery only.
There were two attempts by students to implement bulk leasequery. Neither of them was completed. I've scavenged bits and pieces to latest master. See bulk-leasequery branch in the base dibbler repo.I just checked that it compiles, but the requestor crashed when I tried it. ./dibbler-requestor shows this:
$./dibbler-requestor --help| Dibbler - a portable DHCPv6, version 1.0.0RC1 (REQUESTOR)| Authors : Tomasz Mrugalski<thomson(at)klub.com.pl>,Marek Senderski<msend(at)o2.pl>| Licence : GNU GPL v2 only. Developed at Gdansk University of Technology.| Homepage: http://klub.com.pl/dhcpv6/2019.11.07 16:08:35 Requestor Critical Aborted. Invalid command-line parameters or help called.Usage:-i IFACE - send query using iface inteface, e.g. -i eth0-addr ADDR - query about address, e.g. -addr 2000::43-duid DUID - query about DUID, e.g. -duid 00:11:22:33:44:55:66:77:88To send bulk (multiple) query:- bulk -dstaddr -m ADDRESS  CLIENT_ID  LINK_ADDRESS  RELAY_ID  REMOTE_ID , e.g. -bulk -m 2000::43 00:11:22:33:44:55:66:77:88 00:11:22:33:88:44:55:66:77-timeout 10 - query timeout, specified in seconds-dstaddr 2000::1 - destination address (by default it is ff02::1:2)
so there's some hope for v6 bulk leasequery requestor, although it would require some work.
LQ may have similar use case to DHCPv6 reconfigure. Both require storing extra information regarding clients. Marcin used to work on the reconfigure. Perhaps he'll have some thoughts to share?