RFC 7724

Active DHCPv4 Lease Query

πŸ“… published December 2015, from ietf

RFC 7724: Active DHCPv4 Lease Query πŸŽ€

okay bestie, so this is RFC 7724, and it's giving Standards Track πŸ’… It was published in December 2015 and has ISSN 2070-1721. Kinnear, Stapp, and Volz wrote it from Cisco Systems, and N. Russell wrote it from Staples 🫢. It updates RFC 6926 ("DHCPv4 Bulk Leasequery"), and the header has no Obsoletes entry, so it doesn't replace anything 🌸.

Abstract

okay so DHCPv4 already has a Leasequery feature (RFC 4388) that lets you ask about bindings, but it only handles one binding per question πŸ™ˆ That gets slow, and sometimes it just isn't possible. Sometimes you also want an outside requestor to keep getting updates nonstop ✨ This document levels up DHCPv4 Leasequery so near real-time binding info can be actively transferred over TCP πŸ¦‹ It also updates RFC 6926, "DHCPv4 Bulk Leasequery", so it's a whole glow-up for that one too πŸ’–

Status of This Memo

this is an Internet Standards Track document 🌈

this doc is a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 5741 πŸŽ€

for the current status of this doc, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc7724 πŸ”₯

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved. πŸ’œ

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please read these carefully, bestie, because they explain your rights and restrictions for this document πŸ™ˆ Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License ⚠️

Table of Contents

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   4
3.  Protocol Overview . . . . . . . . . . . . . . . . . . . . . .   6
4.  Interaction Between Active Leasequery and Bulk Leasequery . .   8
5.  Message and Option Definitions  . . . . . . . . . . . . . . .   9
  5.1.  Message Framing for TCP . . . . . . . . . . . . . . . . .   9
  5.2.  New or Changed Options  . . . . . . . . . . . . . . . . .   9
    5.2.1.  dhcp-message-type . . . . . . . . . . . . . . . . . .  10
    5.2.2.  dhcp-status-code  . . . . . . . . . . . . . . . . . .  10
  5.3.  Connection and Transmission Parameters  . . . . . . . . .  11
6.  Information Communicated by Active Leasequery . . . . . . . .  11
7.  Requestor Behavior  . . . . . . . . . . . . . . . . . . . . .  12
  7.1.  General Processing  . . . . . . . . . . . . . . . . . . .  12
  7.2.  Initiating a Connection . . . . . . . . . . . . . . . . .  13
  7.3.  Forming an Active Leasequery  . . . . . . . . . . . . . .  14
  7.4.  Processing Active Replies . . . . . . . . . . . . . . . .  15
    7.4.1.  Processing Replies from a Request Containing a
            query-start-time  . . . . . . . . . . . . . . . . . .  17
  7.5.  Closing Connections . . . . . . . . . . . . . . . . . . .  19
8.  Server Behavior . . . . . . . . . . . . . . . . . . . . . . .  19
  8.1.  Accepting Connections . . . . . . . . . . . . . . . . . .  19
    8.1.1.  Update to RFC 6926  . . . . . . . . . . . . . . . . .  21
  8.2.  Replying to an Active Leasequery  . . . . . . . . . . . .  21
  8.3.  Multiple or Parallel Queries  . . . . . . . . . . . . . .  23
  8.4.  Closing Connections . . . . . . . . . . . . . . . . . . .  24
9.  Security Considerations . . . . . . . . . . . . . . . . . . .  24
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  25
11. References  . . . . . . . . . . . . . . . . . . . . . . . . .  26
  11.1.  Normative References . . . . . . . . . . . . . . . . . .  26
  11.2.  Informative References . . . . . . . . . . . . . . . . .  27
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  27
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  28

1. Introduction ✨

okay so the DHCPv4 Leasequery capability [RFC4388] builds on the basic DHCPv4 capability [RFC2131] [RFC2132]. It lets an outside entity ask a DHCPv4 server to recover lease state info about a particular IPv4 address or client, in near real-time πŸ¦‹

sometimes you want an external requestor to get Leasequery data continuously. These requestors have to keep up with what the DHCPv4 server is doing with bindings right now πŸƒβ€β™€οΈ That's called "active" leasequery πŸ’œ

the DHCPv4 Bulk Leasequery [RFC6926] capability is great for pulling useful info out of a DHCPv4 server when some external entity first starts up 🌸 That entity could be something directly involved in the DHCPv4 client-server transactions (like a relay agent), or it could be an external process that needs stuff from the DHCPv4 server's lease state database πŸ“

the Active Leasequery capability in this doc is for an entity that is not directly involved in DHCPv4 client-server transactions, but still wants to stay current with the DHCPv4 lease state info in real-time 🧚

this document updates DHCPv4 Bulk Leasequery [RFC6926] in that it specifies the DHCPv4 server must close the TCP connection if it receives a DHCPv4 message that is not allowed over the TCP connection (for example, DHCPDISCOVER, DHCPLEASEQUERY). See Section 8.1.1 πŸ™ˆ

2. Terminology πŸ“–

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read as described in [RFC2119] πŸŽ€

this doc uses the following terms, so let's get on the same page bestie πŸ’…

  • "Active Leasequery"
    • Keeping up to date in real-time (or near real-time) with DHCPv4 binding activity. ⏱️
  • "binding"
    • The info that a DHCPv4 server keeps about the relationship between a DHCPv4 client and an IPv4 address. This includes the identity of the DHCPv4 client and the expiration time (if there is one) of any lease that client has on a particular IPv4 address. πŸ”—
  • "Bulk Leasequery"
    • Requesting and receiving info about all or some of the existing DHCPv4 binding info in an efficient way, as defined by [RFC6926] ✨
  • "blocked TCP connection"
    • A TCP connection counts as blocked if the underlying TCP transport won't accept new messages to be sent without blocking the thread that is trying to send the message 🚧
  • "catch-up information"
    • If a DHCPv4 Active Leasequery requestor sends a query-start-time option in a DHCPACTIVELEASEQUERY message, the DHCPv4 server will try to send the requestor the info that changed since the time given in the query-start-time option. The binding info sent to satisfy this request is the catch-up information 🧠
  • "catch-up phase"
    • The period while the catch-up information is being sent is the catch-up phase πŸƒ
  • "clock skew"
    • The difference between the absolute time on a DHCPv4 server and the absolute time on the system where a requestor of an Active or Bulk Leasequery is running is called the "clock skew" for that Active or Bulk Leasequery connection. It isn't perfectly constant, but it's likely to vary only slowly πŸ•°οΈ It seems like you could calculate it exactly after one packet arrives from a DHCPv4 server, but a more accurate value comes from continuously examining the instantaneous value developed from each packet received from a DHCPv4 server and using it to make small adjustments to the value the requestor already holds πŸ’–
  • "DHCPv4 client"
    • A DHCPv4 client is an IPv4 node that uses DHCP to get configuration parameters, like a network address πŸ“±
  • "DHCPv4 relay agent"
    • A DHCPv4 relay agent is a third-party agent that passes BOOTP and DHCPv4 messages between clients and servers on different subnets, per [RFC951] and [RFC1542] πŸ”€
  • "DHCPv4 server"
    • A DHCPv4 server is an IPv4 node that hands configuration parameters back to DHCPv4 clients πŸ–₯️
  • "insecure mode"
    • In insecure mode, the TCP connection between the requestor and DHCPv4 server is not protected in any way. The server doesn't validate the identity of the requestor, and the requestor doesn't validate the identity of the server πŸ™ˆ
  • "MAC address"
    • In the context of a DHCP message, a Media Access Control (MAC) address is made up of these fields: hardware type htype, hardware length hlen, and client hardware address chaddr πŸ“
  • "requestor"
    • The node that sends LEASEQUERY messages to one or more servers to get info on the bindings for a client 🫢
  • "secure mode"
    • In secure mode, the TCP connection between the requestor and the DHCPv4 server is protected by TLS [RFC5246]. The requestor also uses the certificates exchanged between it and the DHCPv4 server while setting up the TLS connection to validate the server's identity. The DHCPv4 server uses these same certificates to validate the requestor's identity πŸ”

⏭️ that's part 1 of the glow-up, bestie, and part 2 is coming up next 🌈

3. Protocol Overview ✨

okay so Active Leasequery is basically modeled on the individual Leasequery protocol in [RFC4388] plus the related DHCPv4 Bulk Leasequery work in [RFC6926] 🧚. Most of the differences come from one thing: the long-term nature of the TCP [RFC7414] connection that Active Leasequery needs πŸ”₯. Also, a DHCPv4 server that supports Active Leasequery must support Bulk Leasequery [RFC6926] as well πŸ’…. See Section 8.

An Active Leasequery requestor opens a TCP connection to a DHCPv4 server on port 67 πŸŽ€. Note that this means the requestor has to know the server's IPv4 address(es) through configuration or some other means, and it needs unicast IP reachability to the DHCPv4 server. The message framing for TCP is covered in Section 5.1. No relaying for Active Leasequery is specified πŸ™ˆ.

After the connection is established, the requestor sends a DHCPACTIVELEASEQUERY message over it. The server answers with updates using DHCPLEASEACTIVE and DHCPLEASEUNASSIGNED messages, which are extensions of those messages as defined in [RFC4388] and [RFC6926] ✨. This response procedure is similar to the one in [RFC6926], except that with Active Leasequery the server sends updates whenever some activity changes the binding state. That's the whole reason for the long-lived connection πŸ¦‹. Also, the Active Leasequery server should provide a mechanism to control which data is allowed to be included in the messages sent to the requestor. See Section 8.2.

Since [RFC6926] didn't specify what to do with an unknown message type received over the DHCP TCP connection, system administrators SHOULD NOT allow a DHCPACTIVELEASEQUERY message to be sent over a DHCP TCP connection to a DHCPv4 server that does not support Active Leasequery πŸ’€. Not the vibe, bestie.

Active Leasequery is designed to provide continuous updates of DHCPv4 binding activity to an external entity 🌈.

Active Leasequery also has features that let this external entity lose its connection, reconnect, and receive the latest information about any IPv4 bindings that changed while it was disconnected 🫢.

These capabilities are designed so the Active Leasequery requestor can efficiently get current with the lease state database after it has restarted, or after the machine it runs on has been reinitialized 🌸. It's easy to define a protocol that works when the requestor is always connected to the DHCPv4 server. Since that isn't robust enough, much of the mechanism in this document is designed to handle the situations that happen when the requestor gets disconnected from the DHCPv4 server it's receiving updates from, and then reconnects to that same server 😭.

The central idea here is this: if the Active Leasequery requestor loses service, it is allowed to specify the time of its most recent update in a later Active Leasequery request. The DHCPv4 server then works out whether any data was missed while the requestor was disconnected ✨.

The DHCP server processing the Active Leasequery request MAY limit the amount of data it saves. There are also methods for the DHCPv4 server to tell the Active Leasequery requestor that more data was missed than could be saved πŸ‘‘. In that situation, the requestor would issue a Bulk Leasequery [RFC6926] to recover the information that isn't available through Active Leasequery.

DHCPv4 servers are not required to keep any data corresponding to data missed on an Active Leasequery connection. They will typically choose to keep data about some recent activity, though, so it's available for later queries from a DHCPv4 Active Leasequery requestor whose connection was temporarily interrupted πŸ“.

An Active Leasequery requestor would typically use Bulk Leasequery to initialize its database with all current data when that database contains no binding information. It would also use Bulk Leasequery to recover missed information if its connection with the DHCPv4 server was lost for longer than the server keeps track of specific changes to the IPv4 binding information ⭐.

The messages the server sends in response to an Active Leasequery request should be identical to the messages it sends for a Bulk Leasequery request, in terms of how the data is encoded into the Active Leasequery responses. The requestor's actions for interpreting Active Leasequery responses should also be identical to how it interprets Bulk Leasequery responses. So the handling of time, clock skew, data source, and other items discussed in the Bulk Leasequery specification [RFC6926] is to be followed when implementing Active Leasequery πŸŽ€. The one exception: a server responding to an Active Leasequery request SHOULD be able to be configured to prevent specific data items from being included in the response to the requestor, even if they were requested by inclusion in the dhcp-parameter-request-list option πŸ”₯.


4. Interaction between Active Leasequery and Bulk Leasequery πŸ¦‹

Active Leasequery is an extension of the Bulk Leasequery protocol [RFC6926] πŸ’œ. The contents of messages returned to an Active Leasequery requestor are identical to those defined for the Bulk Leasequery protocol.

Applications that use Active Leasequery to keep a database up to date with the DHCPv4 server's lease state database should start with an initial Bulk Leasequery to bring their database into equivalence with the server's. Then they use Active Leasequery to keep that database current with the DHCPv4 server's lease state database 🫢.

There are several differences between the Active and Bulk Leasequery protocols πŸ‘€. Active Leasequery defines only one qualifier (the query-start-time) and no query types, while Bulk Leasequery defines several query types and qualifiers. An Active Leasequery connection sends all available updates to the requestor.

An Active Leasequery connection never "completes" πŸ™ƒ. The DHCPv4 server can close the connection, though, for a variety of reasons tied to some kind of exception condition.


5. Message and Option Definitions 🌈

5.1. Message Framing for TCP

The use of TCP for the Active Leasequery protocol lets one or more DHCPv4 messages be sent in response to a single Active Leasequery request 🧚. The receiver needs to be able to determine how large each message is. The same framing technique used for Bulk Leasequery [RFC6926] is used for Active Leasequery ✨.

When TLS is used to secure a connection [RFC5246], the message framing for TLS uses the same format as TCP. One DHCP message is carried in one TLS record πŸ”.

5.2. New or Changed Options

The existing messages DHCPLEASEUNASSIGNED and DHCPLEASEACTIVE are used as the value of the dhcp-message-type option. They indicate an IPv4 address that is currently not leased, or one that is currently leased to a DHCPv4 client, respectively πŸ’–.

All of the message types and options defined for Bulk Leasequery [RFC6926] are also used by Active Leasequery. On top of that, new message types and option types are defined for Active Leasequery, as described below 🌸.

5.2.1. dhcp-message-type

The message type option (option 53) from [RFC2132] needs additional values πŸ‘‘. The values of these message types are shown below, as an extension of the table from Section 9.6 of [RFC2132]:

                 +-------+----------------------+
                 | Value | Message Type         |
                 +-------+----------------------+
                 | 16    | DHCPACTIVELEASEQUERY |
                 | 17    | DHCPLEASEQUERYSTATUS |
                 | 18    | DHCPTLS              |
                 +-------+----------------------+

5.2.2. dhcp-status-code

The dhcp-status-code option defined in [RFC6926] lets you return more detail about the status of a DHCP request πŸ“. It's specified in the Bulk Leasequery document, but this DHCPv4 option is also used in Active Leasequery.

This option has two possible scopes when used with Active Leasequery, depending on where it appears. It refers to the information in a single leasequery reply if the value of the dhcp-message-type is DHCPLEASEACTIVE, DHCPLEASEUNASSIGNED, or DHCPTLS. It refers to the message stream for an entire request if the value of the dhcp-message-type is DHCPLEASEQUERYSTATUS 🧠.

Here are the additional status codes defined to support Active Leasequery πŸ“‹:

   +----------------------+-------------+------------------------------+
   | Name                 | Status-Code | Description                  |
   +----------------------+-------------+------------------------------+
   | DataMissing          | 5           | Indicates that IPv4 binding  |
   |                      |             | information requested is not |
   |                      |             | available.                   |
   | ConnectionActive     | 6           | Indicates that this          |
   |                      |             | connection remains active.   |
   | CatchUpComplete      | 7           | Indicates that this Active   |
   |                      |             | Leasequery connection has    |
   |                      |             | completed sending all of the |
   |                      |             | saved data requested.        |
   | TLSConnectionRefused | 8           | Indicates that a TLS         |
   |                      |             | connection is not allowed.   |
   +----------------------+-------------+------------------------------+

A dhcp-status-code option MAY appear in the options field of a DHCP message. If the dhcp-status-code option does not appear, the operation is assumed to have been successful πŸ₯°. The dhcp-status-code option SHOULD NOT appear in a message that is successful, unless it's needed to convey some text message along with the Success status code.

5.3. Connection and Transmission Parameters

Active Leasequery uses the same port configuration as DHCPv4 Bulk Leasequery [RFC6926] πŸŽ€. It also uses the other transmission parameters (BULK_LQ_DATA_TIMEOUT and BULK_LQ_MAX_CONNS) as defined in [RFC6926].

This section presents a table of values used to control Active Leasequery behavior, including recommended defaults 🧁. Implementations MAY make these values configurable. However, configuring timeout values that are too small may lead to harmful behavior, both for this application and for other traffic in the network 😬. As a result, timeout values smaller than the default values SHOULD NOT be used.

   +------------------------+---------+-------------------------------+
   | Parameter              | Default | Description                   |
   +------------------------+---------+-------------------------------+
   | ACTIVE_LQ_RCV_TIMEOUT  | 120 s   | Active Leasequery receive     |
   |                        |         | timeout                       |
   | ACTIVE_LQ_SEND_TIMEOUT | 120 s   | Active Leasequery send        |
   |                        |         | timeout                       |
   | ACTIVE_LQ_IDLE_TIMEOUT | 60 s    | Active Leasequery idle        |
   |                        |         | timeout                       |
   +------------------------+---------+-------------------------------+

6. Information Communicated by Active Leasequery ✨

Okay so, a Bulk Leasequery [RFC6926] pulls its info straight from the DHCPv4 server's lease state database πŸ“š, but an Active Leasequery gives you real-time info πŸ”₯. That means you get whatever is currently attached to a particular binding in that database. Main character energy, but make it live.

This matters because if your Active Leasequery requestor is running slow, or it disconnects and then reconnects with a query-start-time (that's the catch-up move πŸƒβ€β™€οΈ), the requestor only gets the most current info from the DHCPv4 server's lease state database. Older stuff can just vanish 🫠.

The requestor of an Active Leasequery MUST NOT assume that every lease state change is communicated across an Active Leasequery connection. 🚫 Even if the requestor stays connected the whole time, the DHCPv4 server is only required to transmit information about a binding that is current when the packet is created and handed off to the TCP stack to send to the requestor. Literally just the snapshot at that moment πŸ“Έ.

If the TCP connection blocks and the DHCPv4 server is waiting to send information down the connection, then when the connection becomes writable again, the DHCPv4 server MAY create the packet to send at this time. The current state of the binding will be sent, and any transition in state or other info that happened while the TCP connection was blocked will be lost πŸ’€. Gone, bestie.

So yeah, the Active Leasequery protocol does NOT let the requestor build a complete history of every activity on every lease πŸ™ˆ. You can make an effective history of the important state changes for a lease, though, if the parameters of the DHCPv4 server are tuned with an Active Leasequery requestor in mind πŸŽ€. For instance, the period after the expiration or release of a binding could be configured long enough (say, several minutes, well more than the receive timeout), so that an Active Leasequery requestor would never miss any changes in the binding. Big brain move 🧠✨.

7. Requestor Behavior πŸ‘‘

7.1. General Processing 🧚

A requestor tries to establish a TCP connection to a DHCPv4 server so it can start a Leasequery exchange 🀝. If that attempt fails, the Requestor MAY retry. Retries should not be more frequent than one every ACTIVE_LQ_IDLE_TIMEOUT. See Section 5.3.

If an Active Leasequery gets terminated early, either by a DHCPLEASEQUERYDONE with a dhcp-message status-code of QueryTerminated or by the connection it was being submitted over failing, the requestor MAY retry the request after it creates a new connection πŸ”. Again, retries should not be more frequent than one every ACTIVE_LQ_IDLE_TIMEOUT. See Section 5.3.

Messages from the DHCPv4 server come back as multiple responses to a single DHCPACTIVELEASEQUERY message πŸ“¬. So each DHCPACTIVELEASEQUERY or DHCPBULKLEASEQUERY request must have an xid (transaction-id) that's unique on the connection it's sent on (see Section 7.3), and all of the messages that come back as a response to it contain the same xid as the request. Matching energy πŸ’….

Only one DHCPACTIVELEASEQUERY is allowed on any one TCP connection at a time 🚦. Parallel DHCPACTIVELEASEQUERY requests on the same TCP connection are not allowed. Nope, not happening πŸ™…β€β™€οΈ.

7.2. Initiating a Connection πŸŽ€

A requestor SHOULD be able to operate in either insecure or secure mode. See Section 9. This MAY be a feature that is administratively controlled πŸ”.

When operating in insecure mode, the requestor sends a DHCPACTIVELEASEQUERY request after the TCP connection is established 🌸.

When operating in secure mode, the requestor MUST attempt to negotiate a TLS [RFC5246] connection over the TCP connection. If this negotiation fails, the requestor MUST close the TCP connection πŸ”’. The recommendations in [RFC7525] apply when negotiating this connection.

A requestor asks for a TLS connection by sending the DHCPTLS message to the DHCPv4 server as the first message over the TCP connection πŸ™‹β€β™€οΈ. The DHCPTLS message SHOULD be sent without any options. This message tells the DHCPv4 server that a TLS connection over this TCP connection is wanted. After the requestor sends the DHCPTLS message to the DHCPV4 server, there are four possibilities πŸ‘€:

  1. No response from the DHCPv4 server.
  2. The DHCPv4 server closes the TCP connection after it receives the DHCPTLS message.
  3. The DHCPv4 server responds with a DHCPTLS message with a dhcp-status-code of TLSConnectionRefused.
  4. The DHCPv4 server responds with a DHCPTLS message with no dhcp-status-code, indicating success βœ….

In any of the first three possibilities, the DHCPv4 server can be assumed to not support TLS 😬. In this case, the requestor MUST close the connection.

In the final possibility, where the DHCPv4 server has responded with a DHCPTLS message with no dhcp-status-code in response to the requestor's DHCPTLS message, the requestor SHOULD start the exchange of messages involved in a TLS handshake [RFC5246] 🀝✨.

During the TLS handshake, the requestor MUST validate the DHCPv4 server's digital certificates πŸ•΅οΈβ€β™€οΈ. No skipping this part, periodt.

If the handshake exchange yields a functioning TLS connection, then the requestor SHOULD transmit a DHCPACTIVELEASEQUERY message over that TLS connection, and use that TLS connection for all further interactions with the DHCPv4 server over this TCP connection πŸ¦‹.

If the handshake exchange does NOT yield a functioning TLS connection, then the requestor MUST close the TCP connection πŸ’”.

7.3. Forming an Active Leasequery πŸ’œ

The Active Leasequery is designed to create a long-lived connection between the requestor and the DHCPv4 server processing the active query 🌈. The DHCPv4 server SHOULD send binding information back across this connection with minimal delay after it learns of the binding information ⚑. It learns about bindings either because it makes them itself, or because it received info about a binding from another server.

An Active Leasequery is a DHCPv4 request with a dhcp-message-type of DHCPACTIVELEASEQUERY. The DHCPv4 request MUST NOT have a ciaddr, a chaddr, or a dhcp-client-identifier 🚫. The DHCPv4 request MUST have an xid (transaction-id) that's unique on the connection it's sent on. The DHCPv4 request SHOULD have a dhcp-parameter-request-list to tell the DHCPv4 server which DHCPv4 options the requestor sending the DHCPACTIVELEASEQUERY message is interested in πŸ“.

An important capability of the Active Leasequery is that the requestor can ask for some recent data to be sent immediately, in parallel with the ongoing binding info that's being sent in more or less real time ⏩. This is how an Active Leasequery requestor recovers missed info if it temporarily loses connectivity with the DHCPv4 server that was processing a previous Active Leasequery πŸ›Ÿ. It's giving resilience 🫢.

This capability is turned on by sending a 4-octet base-time option with each Leasequery reply that comes back from a previous Active Leasequery πŸ•°οΈ. The requestor SHOULD keep track of the highest base-time received from a particular DHCPv4 server over an Active Leasequery connection. If the requestor finds it necessary (for whatever reason) to re-establish an Active Leasequery connection to that DHCPv4 server, it should put this highest base-time value into a query-start-time option in the new DHCPACTIVELEASEQUERY request. (See Sections 6.2.5 and 7.2 of [RFC6926] for information on the query-start-time option.) πŸ“–

Note that until all of the recent data (catch-up data) has been received, the requestor MUST NOT keep track of the base-time received in Leasequery reply messages to use later in a subsequent Bulk Leasequery or Active Leasequery request ⏳. Patience is a virtue, babe.

If the requestor doesn't want to request an update of info it missed while it wasn't connected to the DHCPv4 server, then it leaves the query-start-time option out of the DHCPACTIVELEASEQUERY request πŸ™….

If the TCP connection becomes blocked or stops being writable while the requestor is sending its query, the requestor SHOULD terminate the connection after BULK_LQ_DATA_TIMEOUT. ⏰ We make this recommendation so requestors can control how long they're willing to wait before abandoning a connection, independent of notifications from whatever TCP implementations they're using. Control your timeline, queen πŸ‘‘.

7.4. Processing Active Replies ✨

Okay so the Requestor tries to read a DHCPv4 leasequery reply message off the TCP connection πŸ“¬

Bestie, the connection from accepting a DHCPACTIVELEASEQUERY request can be super long-lived πŸ¦‹, and it might not have data flowing nonstop the whole time. So the DHCPv4 server SHOULD send a DHCPLEASEQUERYSTATUS message with a dhcp-status-code of ConnectionActive every ACTIVE_LQ_IDLE_TIMEOUT seconds (default 60) so the requestor knows the connection is still alive πŸ’–. This only happens when the connection is idle, aka the server has no binding data to send πŸ™ˆ. During normal binding data exchange, getting DHCPLEASEACTIVE or DHCPLEASEUNASSIGNED messages already tells the requestor the connection is active, no cap πŸ’…. The default for ACTIVE_LQ_RCV_TIMEOUT is 120 seconds, which is twice the 60-second default of ACTIVE_LQ_IDLE_TIMEOUT (the thing that drives the DHCPv4 server to send messages). So ACTIVE_LQ_RCV_TIMEOUT basically controls how sensitive the requestor is to be to delays by the DHCPv4 server in sending updates or DHCPLEASEQUERYSTATUS messages 🫢.

If the stream of replies goes quiet and no messages are being received, the Requestor SHOULD terminate the connection after ACTIVE_LQ_RCV_TIMEOUT, and MAY begin retry processing if it's configured to do so 😭.

A successful query that returns binding data MUST include a non-zero ciaddr. It may also include a non-zero chaddr, htype, and hlen, plus additional options ✨. If there are more bindings to return, they'll be carried in additional Active Leasequery messages 🧚.

Any requestor of an Active Leasequery operation MUST be prepared to receive multiple copies of the binding information for a particular IPv4 address πŸ‘€. Check the Bulk Leasequery document [RFC6926] for how to deal with that situation πŸ“.

A single Active Leasequery can and usually will result in a large number of replies 🌈. The Requestor MUST be prepared to receive more than one reply with transaction-ids matching a single DHCPACTIVELEASEQUERY message from a single DHCPv4 server πŸ’œ.

A DHCPACTIVELEASEQUERY has two regimes: the catch-up phase (if there is one) and the stuff after any catch-up phase. If the DHCPACTIVELASEQUERY request had a query-start-time, then the DHCPACTIVELEASEQUERY starts out in the catch-up phase. See Section 7.4.1 for info on processing during the catch-up phase, and how to tell when it's complete πŸŽ€.

After the catch-up phase, or during the entire series of messages received as the response to a DHCPACTIVELEASEQUERY request with no query-start-time (and therefore no catch-up phase), the base-time option of the most recent message SHOULD be saved as a record of the most recent time that data was received πŸ“. In the context of the DHCPv4 server, this base-time can be used in a later DHCPACTIVELEASEQUERY message's query-start-time, or in a DHCPBULKLEASEQUERY message's query-start-time if one is needed, after the Active Leasequery connection is lost πŸ”.

The DHCPLEASEQUERYSTATUS message MAY unilaterally terminate a successful DHCPACTIVELEASEQUERY request that's currently in progress, in case the DHCPv4 server decides it can't keep processing that request πŸ›‘. For example, when a server is asked to shut down, it SHOULD send a DHCPLEASEQUERYSTATUS message with a dhcp-status-code of QueryTerminated and include a base-time in the message. This MUST be the last message on that connection, and once the message has been sent, the server MUST close the connection πŸšͺ.

After receiving DHCPLEASEQUERYSTATUS with a QueryTerminated status from a server, the Requestor MAY close the TCP connection to that server πŸ’….

The DHCPv4 Leasequery protocol uses the associated-ip option as an indicator that multiple bindings were present in response to a single client-based query. For Active Leasequery, client-based queries are not supported, so the associated-ip option is not used and MUST NOT be present in replies πŸ™….


7.4.1. Processing Replies from a Request Containing a query-start-time πŸ•°οΈ

If the DHCPACTIVELEASEQUERY was requested with a query-start-time, the DHCPv4 server will try to send info about all bindings that changed since the time in query-start-time. This is the catch-up phase of DHCPACTIVELEASEQUERY processing πŸƒβ€β™€οΈ. The DHCPv4 server MAY also begin immediate updates of real-time binding information changes over the same connection. Thus, the catch-up phase can run in parallel with the normal updates generated by the DHCPACTIVELEASEQUERY request 🍭.

A DHCPv4 server MAY keep only a limited amount of time-ordered information available to respond to a DHCPACTIVELEASEQUERY request containing a query-start-time. So it's possible that the time in query-start-time is a time not covered by the time-ordered info the DHCPv4 server kept. In that case, when there's not enough data saved in the DHCPv4 server to satisfy the request, the DHCPv4 server will reply immediately with a DHCPLEASEQUERYSTATUS message with a dhcp-status-code of DataMissing and a base-time option equal to the server's current time πŸ₯². This signals the end of the catch-up phase, and the only updates received on this connection after that are the real-time updates from the DHCPACTIVELEASEQUERY request πŸ›‘.

If there's enough data saved to satisfy the request, then DHCPLEASEACTIVE and DHCPLEASEUNASSIGNED messages will start arriving from the DHCPv4 server. Some of these are related to the query-start-time request and part of the catch-up phase. Some are real-time updates of binding changes happening in the DHCPv4 server. In general, there's no way to tell where each message came from πŸ€·β€β™€οΈ.

The updates sent during the catch-up phase are not in the order the binding data was updated. So until the catch-up phase is complete, the latest base-time value received from a DHCPv4 server processing an Active Leasequery request cannot be reset from the incoming messages (and used in a later Active Leasequery's query-start-time option). Doing that would compromise the ability to recover lost info if the DHCPACTIVELEASEQUERY terminated before catch-up finished 😱.

The requestor knows the catch-up phase is complete because the DHCPv4 server transmits a DHCPLEASEQUERYSTATUS message with the dhcp-status-code of CatchUpComplete (or, as discussed above, DataMissing). Once that message is transmitted, all additional DHCPLEASEACTIVE and DHCPLEASEUNASSIGNED messages relate to real-time ("new") binding changes in the DHCPv4 server πŸŽ‰.

As discussed in Section 6.3, the requestor SHOULD keep track of the latest base-time option value received over a particular connection, to be used in a later DHCPACTIVELEASEQUERY request, but only if the catch-up phase is complete 🧠. Before the catch-up phase is complete, if the connection goes away or the requestor receives a DHCPLEASEQUERYDONE message, then when it reconnects it MUST use the base-time value from the previous connection, and not any base-time value received from the recently closed connection πŸ”™.

In the event there was enough data available to the DHCPv4 server to begin satisfying the request implied by the query-start-time option, but during processing the server found it was unable to continue (maybe there was barely enough, the connection was very slow, and the aging algorithm made the saved data unavailable), the DHCPv4 server will terminate the catch-up phase immediately by sending a DHCPLEASEQUERYSTATUS message with a dhcp-status-code of DataMissing and a base-time option of the current time πŸ’€.

The requestor must not assume that every individual state change of every binding during the period from the time specified in the query-start-time to the present is replicated in an Active Leasequery reply message. See Section 6. The requestor MAY assume that at least one Active Leasequery reply message will exist for every binding that had one or more changes of state during the period specified by the query-start-time and the current time. The last message for each binding will contain the state at the current time, and there can be one or more messages about a single binding during the catch-up phase 🧩.

Bindings can change multiple times while the requestor is not connected. The requestor will only receive info about the current state of the binding, not info about each state change that happened from the query-start-time to the present πŸŒ€.

If the DHCPLEASEQUERYSTATUS message with a dhcp-status-code of DataMissing is received and the requestor wants its database kept up to date with the current state of the bindings in the DHCPv4 server, then the requestor SHOULD issue a DHCPBULKLEASEQUERY request to recover the missing info πŸ› οΈ. This DHCPBULKLEASEQUERY should include a query-start-time option set to the same value as the query-start-time option previously included in the DHCPACTIVELEASEQUERY requests to the DHCPv4 server, and a query-end-time option equal to the base-time option returned by the DHCPv4 server in the DHCPLEASEQUERYSTATUS message with the dhcp-status-code of DataMissing.

Typically, the requestor would have one connection open to a DHCPv4 server for a DHCPACTIVELEASEQUERY request, and possibly one more connection open for a DHCPBULKLEASEQUERY request to the same DHCPv4 server, to fill in the data that might have been missed before the DHCPACTIVELEASEQUERY was started. The Bulk Leasequery connection would typically run to completion and be closed, leaving one Active Leasequery connection open to a single DHCPv4 server πŸŽ€.


7.5. Closing Connections πŸ”’

The Requestor or DHCPv4 leasequery server MAY close its end of the TCP connection at any time. The Requestor MAY choose to retain the connection if it intends to issue additional queries. Note that this requestor behavior does not guarantee that the connection will be available for additional queries: the server might decide to close the connection based on its own configuration 😀.


8. Server Behavior ✨

A DHCPv4 server that supports Active Leasequery MUST support Bulk Leasequery [RFC6926] as well πŸ‘‘.

8.1. Accepting Connections ✨

Okay bestie, so DHCPv4 servers that do Active Leasequery have to listen for incoming TCP connections πŸ¦‹ The way they accept the requestor's connection is the same as in DHCPv4 Bulk Leasequery [RFC6926], with one big twist: Active Leasequery support MUST NOT be turned on by default πŸ™…β€β™€οΈ It MUST need an explicit configuration step before it'll actually operate πŸ”’

DHCPv4 servers SHOULD be able to run in either insecure or secure mode πŸ’œ (see Section 9). This MAY be a mode that the admin controls, where the server will require a TLS connection to operate or will only operate without one. Either way, insecure mode MUST NOT be the default, even if secure mode isn't supported at all πŸ™ˆ Running in insecure mode MUST always need its own explicit configuration step, separate from the one you need to turn on Active Leasequery support. Main character energy, but make it intentional πŸ’…

When a server is in insecure mode, it just waits for the requestor to send the Active Leasequery after the TCP connection is set up. If it gets a DHCPTLS message, it'll reply with TLSConnectionRefused inside a DHCPTLS message πŸ™…

When a server is in secure mode, DHCPv4 servers MUST support TLS [RFC5246] to protect the integrity and privacy of the data sent over the TCP connection πŸ” They MUST also be configurable about which requestors they'll talk to. The certificate a requestor shows when starting the TLS connection is what decides who's acceptable and who isn't. It's giving bouncer at the club πŸͺ©

Also in secure mode, a DHCPv4 server MUST begin negotiating a TLS connection with any requestor who asks for one, and MUST close any TCP connection that isn't secured with TLS or whose requestor certificate is deemed unacceptable πŸšͺ The recommendations in [RFC7525] apply when negotiating a TLS connection πŸ“œ

Here's how the requestor asks for TLS: it sends a DHCPTLS as the very first message over a brand new TCP connection ✨ If the DHCPv4 server supports TLS connections and hasn't been configured to refuse them on this link, it MUST respond to that DHCPTLS by sending back a DHCPTLS message with no dhcp-status-code. That's the server basically saying "yes bestie, we can do TLS over this connection" 🫢

If a connection needs to be rejected because the server is at its limit of open connections, the TCP connection itself should be rejected, or the following ACTIVELEASEQUERY message should be rejected. Capacity-related rejections SHOULD NOT affect the response to the DHCPTLS message 🌸

Any options that show up in a DHCPTLS message received by a DHCPv4 server SHOULD be ignored 🧚 This is a "SHOULD" instead of a "MUST" so that later documents can use the DHCPTLS message, maybe with options, without having to update this document first. Smart, right? 🧠

If for some reason the DHCPv4 server can't support a TLS connection, or it's been configured not to, then it sends back a DHCPTLS message with a dhcp-status-code of TLSConnectionRefused πŸ’”

When the server sends a DHCPTLS message with no dhcp-status-code option (which means "success" βœ…), the requestor is supposed to start a TLS handshake [RFC5246] (see Section 7.2). During that handshake, the DHCPv4 server MUST validate the requestor's digital certificate πŸ•΅οΈβ€β™€οΈ The certificate is also used to decide whether this requestor is allowed to run an Active Leasequery at all. If the certificate is unacceptable, the server MUST abort the creation of the TLS connection πŸ›‘

Every TLS connection set up between a requestor and a DHCPv4 server for Active Leasequery purposes MUST be mutually authenticated 🀝

If the TLS handshake fails to create a TLS connection, the server MUST close the TCP connection πŸ’€

If the TCP connection gets blocked while the server is accepting a connection or reading a query, it SHOULD terminate the connection after a BULK_LQ_DATA_TIMEOUT ⏰ We're recommending this so servers can decide how long they're willing to wait before giving up on an inactive connection, no matter which TCP implementation they're using. Boundaries, bestie 🫢

8.1.1. Update to RFC 6926 πŸ’…

Okay so this is an update to the DHCPv4 Bulk Leasequery protocol [RFC6926], which didn't really talk about this situation directly πŸ‘€ If a DHCPv4 server gets a DHCPv4 message with a dhcp-message-type option whose value isn't supported over a TCP connection, it MUST close that TCP connection 🚫

8.2. Replying to an Active Leasequery πŸ’Œ

If the connection gets blocked while the server is trying to send reply messages, the server SHOULD terminate the TCP connection after ACTIVE_LQ_SEND_TIMEOUT ⏳ This timeout is how long the DHCPv4 server is willing to wait for the requestor to read and process enough info to unblock the connection. The default is two minutes, so if more than two minutes pass without the requestor reading enough to unblock the TCP connection, the DHCPv4 server SHOULD close it. Patience is a virtue, but only for so long 😀

If the DHCPv4 server runs into an error while processing a DHCPACTIVELEASEQUERY message, whether during the initial processing or later on, it SHOULD send a DHCPLEASEQUERYSTATUS containing some kind of error code in a dhcp-status-code option 🚨 After signaling that error, it SHOULD close the connection. Dramatic exit, but make it make sense πŸ’€

Every reply to a DHCPACTIVELEASEQUERY request MUST contain the same information that replies to a DHCPBULKLEASEQUERY request must contain [RFC6926] πŸ“¦ The one exception: a server implementing Active Leasequery SHOULD be able to be configured to stop specific data items from being sent to the requestor, even if the requestor asked for them in the dhcp-parameter-request-list option πŸ™Š

Some servers can answer a DHCPv4 Leasequery [RFC4388] or a DHCPBULKLEASEQUERY [RFC6926] for an IPv4 binding that's reserved in a way that makes it look like it's leased to the DHCP client it's reserved for πŸ‘» Those servers SHOULD also respond to a DHCPACTIVELEASEQUERY request with the same info they'd send for a DHCPBULKLEASEQUERY request, as soon as they realize the IPv4 binding is reserved to a DHCP client πŸŽ€

If a DHCPACTIVELEASEQUERY request has a query-start-time option, it means the requestor wants the DHCPv4 server to send messages not just for binding activity happening after the DHCPLEASEACTIVE request came in, but also for binding activity that happened before the DHCPACTIVELEASEQUERY request πŸ•°οΈ Time travel, but make it networking πŸ€“

If a query-end-time option shows up in a DHCPACTIVELEASEQUERY, the DHCPv4 server should send a DHCPLEASEQUERYSTATUS message with a dhcp-status-code of MalformedQuery and terminate the connection ❌

To give a meaningful response to this query, the DHCPv4 server MAY keep track of binding activity and link changes to particular base-time values from the messages πŸ“ Then, when a DHCPACTIVELEASEQUERY request with a query-start-time option asks for it, the server can reply with everything that happened on that query-start-time or later 🧠

Those replies based on the query-start-time MAY be interleaved with the messages that come from current binding activity πŸŒ€

Once the transmission of the DHCPv4 Leasequery messages tied to the query-start-time option is complete, a DHCPLEASEQUERYSTATUS message MUST be sent with a dhcp-status-code value of CatchUpComplete βœ… That's the "we caught you up, bestie" moment πŸŽ‰

The DHCPv4 server SHOULD keep track of previous binding activity, and it SHOULD limit how much previous binding activity it tracks πŸ“Š It MAY choose to do this only after it has received at least one DHCPACTIVELEASEQUERY request in the past. Why? Because tracking history will almost certainly use resources that would be totally wasted if there are no Active Leasequery requestors around πŸ—‘οΈ The DHCPv4 server SHOULD make the amount of previous binding activity it keeps configurable. There's no requirement for the server to keep this info across a restart (or even to keep it at all) 🫠

Unless there's an error, or some requirement to stop processing a DHCPACTIVELEASEQUERY request that would produce a DHCPLEASEQUERYSTATUS message (like a server shutdown), there won't be a DHCPLEASEQUERYSTATUS message at the end of the DHCPACTIVELEASEQUERY processing πŸ™ƒ That's because the processing never really wraps up. It keeps going until either the requestor or the server closes the connection πŸ”„

The form of the data sent in a DHCPACTIVELEASEQUERY is basically the same as what's sent in a DHCPBULKLEASEQUERY, but the reasons for sending it are very different 🀯 With Bulk, the whole lease state database (subject to the query options) is returned to the requestor. With Active, changes to the lease state database are sent to the requestor pretty much as they happen ⚑ For example, when an IPv4 binding moves from the leased state to some other state, the DHCPACTIVELEASEQUERY will send a DHCPLEASEUNASSIGNED packet with info about that binding. The server might forget about that binding afterwards (or not), but it's really important to tell the Active Leasequery requestor that the binding left the leased state πŸ“’

How long the server takes to reply to a DHCP client request versus how long it takes to send a reply to a DHCPACTIVELEASEQUERY message is up to the implementation, so this document doesn't define it πŸ€·β€β™€οΈ However, the server SHOULD NOT delay responding to the DHCP client just to send a reply to a DHCPACTIVELEASEQUERY message, and the server SHOULD send the reply to the DHCPACTIVELEASEQUERY message as soon as possible after responding to the client πŸƒβ€β™€οΈπŸ’¨

8.3. Multiple or Parallel Queries πŸ‘―

Every Active Leasequery request MUST be made on a single TCP connection where no other request is active at the time πŸ”’ Note that this is different from what was allowed for Bulk Leasequery requests in Section 7.7 of [RFC6926] 🧐

Usually, a requestor of an Active Leasequery wouldn't need to send a second Active Leasequery while the first one is still going πŸ’β€β™€οΈ However, sending an Active Leasequery and a Bulk Leasequery in parallel would be possible and reasonable πŸ™Œ When it's parallel Active and Bulk Leasequery requests, the requestor MUST use different connections πŸ”€

This MAY be a feature that's controlled by the admin πŸŽ›οΈ Servers that can process queries in parallel SHOULD offer configuration that limits how many simultaneous queries are allowed from any one requestor. That keeps resource use under control when there are lots of requestors wanting service 🫢✨

8.4. Closing Connections ✨

okay so the server gets to decide how the chat ends πŸ’… It MAY end things by sending a DHCPLEASEQUERYSTATUS message and then immediately closing the TCP connection πŸ¦‹ Or it MAY keep the connection open and wait for more queries from the requestor, which is giving "stay for round two" energy 🫢 Also, the server SHOULD limit how many connections it keeps around and SHOULD close idle ones to stay under that limit, because nobody needs a server with 500 open tabs πŸ’€

this part is non-negotiable bestie 😭 The server MUST close its end of the TCP connection if it runs into an error sending data on that connection. The server MUST also close its end of the TCP connection if it has to abort an in-process request. A server that's aborting an in-process request SHOULD try to tell its requestors by using the QueryTerminated status code in the dhcp-status-code option in a DHCPLEASEQUERYSTATUS message 🚨 And if the server notices that the requestor end has closed, the server MUST close its end of the connection too. we don't leave people on read here 🌸


9. Security Considerations πŸ”

okay this section is serious but still iconic, so let's go 🧚 The Security Considerations section of [RFC2131] covers the general threats to DHCPv4. Then the DHCPv4 Leasequery spec [RFC4388] lays out recommendations for the Leasequery protocol, especially around relayed LEASEQUERY messages, handling packet-flooding DoS attacks, restricting things to trusted requestors, and using IPsec [RFC4301] πŸ’œ

the TCP part adds some extra drama 😭 Attacks that try to exhaust the DHCPv4 server's TCP connection resources can wreck the ability of legit clients to get service. Malicious requestors who manage to connect but then send invalid queries, partial queries, or no queries at all can also drain a server's pool of available connections. not it πŸ’€

there are two modes for this protocol: insecure mode and secure mode πŸ¦‹ These exist because there are basically two ways people use it. In the first model, the requestor of an Active Leasequery is connected to the Internet from some random location, so the info sent needs to be protected while it's in transit. The identities of both requestor and server also need to be verified. For this model, secure mode is the move πŸ”’

the second model is where the requestor sits in a network element that's basically "next to" the element holding the DHCP server, and both of those elements live inside a protected environment. For that setup, insecure mode is enough, since there are other, more global protections already guarding this info 🌈

when you're in secure mode, TLS [RFC5246] secures the connection. The recommendations in [RFC7525] apply when you're negotiating a TLS connection πŸŽ€

heads up: operating in insecure mode (see Section 8.1) does not give you any way to validate the authorization of requestors of a DHCPV4 Active Leasequery request. zero validation, bestie πŸ’€

Servers SHOULD offer configuration parameters that limit where incoming connections can come from, by validating and using the digital certificates presented to set up a TLS connection πŸ” They SHOULD also limit how many connections they accept and how long an idle connection can stay open ⏳

the data you get from an Active Leasequery has the same potential for abuse as the data the DHCPv4 server holds in the first place πŸ‘€ So it SHOULD be secured by mechanisms as strong as the ones used for the server's own data. And the data acquired by using an Active Leasequery SHOULD be deleted as soon as possible after the use it was acquired for has passed πŸ—‘οΈ clean up after yourself, periodt ✨

Servers that implement the Bulk Leasequery protocol [RFC6926] but don't implement the Active Leasequery protocol SHOULD implement the update to [RFC6926] discussed in Section 8.1.1 🌸


10. IANA Considerations πŸ“‹

IANA has assigned the following new DHCP message types from the registry "DHCP Message Type 53 Values," which is maintained at <http://www.iana.org/assignments/bootp-dhcp-parameters> πŸ“

  1. A dhcp-message-type of 16 for DHCPACTIVELEASEQUERY.
  2. A dhcp-message-type of 17 for DHCPLEASEQUERYSTATUS.
  3. A dhcp-message-type of 18 for DHCPTLS.

IANA has also assigned the following new DHCP status codes from the registry "DHCP Status Code Type 151 Values," which is maintained at <http://www.iana.org/assignments/bootp-dhcp-parameters> ✨

                  +----------------------+-------------+
                  | Name                 | Status-Code |
                  +----------------------+-------------+
                  | DataMissing          | 5           |
                  | ConnectionActive     | 6           |
                  | CatchUpComplete      | 7           |
                  | TLSConnectionRefused | 8           |
                  +----------------------+-------------+

11. References πŸ“š

11.1. Normative References

11.2. Informative References


Acknowledgments 🫢

the ideas in this document came partly from work in DHCPv6 and DHCPv4 Bulk Leasequery, plus some seriously deep discussions between the authors 🧠 Ted Lemon, Scott Bradner, Francis Dupont, and Stephen Farrell left useful review comments on drafts for DHCPv6 Active Leasequery, and those got included here too πŸ’– Brian Haberman's review pulled this document way closer into line with DHCPv6 Active Leasequery πŸ‘‘ And Alissa Cooper, Spencer Dawkins, Christer Holmberg, and Ben Campbell added extra clarity with their reviews 🌟 real ones, every single one πŸ₯Ή


Authors' Addresses πŸŽ€

Kim Kinnear
Cisco Systems, Inc.
1414 Massachusetts Ave
Boxborough, MA  01719
United States

Email: kkinnear@cisco.com


Mark Stapp
Cisco Systems, Inc.
1414 Massachusetts Ave
Boxborough, MA  01719
United States

Email: mjs@cisco.com


Bernie Volz
Cisco Systems, Inc.
1414 Massachusetts Ave
Boxborough, MA  01719
United States

Email: volz@cisco.com


Neil Russell
Staples
500 Staples Drive
Framingham, MA  01702
United States

Email: neil.e.russell@gmail.com

the end, bestie πŸŒˆπŸ’–βœ¨

πŸ“¦ where this page comes from