4.6. DNS-SD TXT RecordsIn many cases, all a client needs to know to contact and use a service are the hostname or IP address where that service resides and the port number on that host. There are other cases where more information is required. For example, a print server may advertise three LPR printers. All three logical printing services are being offered on the same host. All are being offered via the LPR port. What distinguishes them is the LPR queue name. How does a client, having discovered an advertised printer, know what LPR queue name to specify when contacting the machine hosting that service? If it doesn't specify the right LPR queue name, its output may not go to the right physical printer. The answer is the DNS TXT record. In addition to the SRV record, every DNS-SD service has a TXT record, optionally containing additional parameters and attributes of interest to clients. DNS-SD uses the DNS TXT record to store a series of key/value pair attributes in the form "key=value." The TXT record is a standard DNS record type, but DNS-SD establishes some conventions about how it is used for DNS-SD service types. Those conventions are described in this section.
4.6.1. Format for DNS TXT RecordsSince DNS-SD uses standard DNS TXT records , these records must conform to format rules. In particular, the data consists of one or more strings , each of which consists of a single length byte followed by 0-255 bytes of text. An example of such a string is: | 0x08 | p | a | p | e | r | = | A | 4 | In this diagram, the first byte of data is a binary byte with value 8. It is then followed by eight more bytes of data, each containing the ASCII (or UTF-8) codes for the character indicated. For example, the second byte contains the value 0x70, the ASCII code for lowercase P; the third byte contains the value 0x61, the ASCII code for lowercase A. Note that there is no terminating zero at the end of the string, as there conventionally is with strings in the C programming language. According to the DNS specification (RFC 1035), a TXT record must contain at least one string. An empty TXT record with zero strings is not allowed. Because of this, you'll often see DNS-SD services advertised with a TXT record containing a single empty string (a single zero length byte, followed by no data). The total size of a typical DNS-SD TXT record is intended to be small200 bytes or less. If large amounts of data need to be transferred, making this part of the client protocol is better than using a large TXT record. However, there are some cases in which we are dealing with a legacy protocol like LPR, and we are not at liberty to change the client protocol. In this case, it is sometimes necessary to use TXT records of around 400 bytes to provide sufficient information to the client. Keeping the total size under 400 bytes should allow it to fit in a single standard 512-byte DNS message. (This standard DNS message size is defined in RFC 1035.) In extreme cases where even 400 bytes is not enough, keeping the size of the TXT record below 1,300 bytes allows it to fit in a single 1,500-byte Ethernet packet. Using TXT records larger than 1,300 bytes becomes much less efficient on the network and is not recommended. 4.6.2. Content of DNS-SD TXT RecordsEach component string in a DNS-SD TXT record consists of a key/value pair preceded by a byte giving the length of the string containing this information. The example given above was: | x08 | p | a | p | e | r | = | A | 4 | In this example, the key is paper, the value is A4, and the length of the string "paper=A4" is eight bytes, which is given by the initial length byte x08. The key component is interpreted without regard for case, so paper, Paper, and PAPER are seen as identical. Spaces are significant in keys, so the strings "Papersize" and "Paper size" are distinct. Note that this means that if you insert a space before the equals sign, it is interpreted as a trailing space in the key. So paper=A4 and paper =A4 are distinct key/value pairs. The moral is: don't add unintended spaces. The key must consist of at least one character, while the value may be absent. The way the key/value pair is parsed is that everything after the length byte until the first equals sign is the key, and everything following the first equals sign to the end of the string is the value. This means that a key cannot contain an equals sign as one of its characters. The key is allowed to contain any printable US-ASCII character other than = (0x3D). Other UTF-8 values are not permitted in key names because they complicate things without increasing the expressive power of the protocolkey names are not intended to be user-visible. They just need to be unique identifierssuch as C variable namesthat are used by the software. If the string contains no equals sign, then the entire string is the key, which is interpreted conceptually as a Boolean attribute; it exists but has no assigned value. In general, for a key that is used to indicate a Boolean value, if the key is present the Boolean is true, and if the key is absent the Boolean is false. A value is made up of any eight-bit binary values. In the case of textual data, UTF-8 encoding is strongly recommended, but TXT record values don't have to be readable text. If you have some binary data to store, it is much more efficient to store it as binary data than to convert it to text using hexadecimal or Base-64 encoding. For example, an IPv4 address is just 4 bytes as binary data but up to 15 when written as text (e.g., "192.168.108.221"). A string beginning with an equals sign will be ignored, as it would have to be interpreted as a key/value pair with an empty key, which is not allowed. If any key appears more than once in a TXT record, any appearances other than the first are silently ignored. 4.6.3. Interpreting DNS-SD TXT RecordsWhen examining a TXT record for a given named attribute, there are four types of results :
The specification for a given DNS-SD service specifies how these four states are to be interpreted. For example, for some keys, there may be a natural true/false Boolean interpretation:
For other keys it may be sensible to define other semantics, such as value/no value/unknown. Clients should ignore unknown keys they find in TXT records. This allows the protocol to be enhanced over time, adding new keys with new meanings, without breaking compatibility with older clients. To further support possible changes to the specification of a particular service type, authors are encouraged to include a version attribute of the form txtvers=xxx. Even if you don't anticipate future versions of your specification, you may still find in the future that you need to make a correction or addition to fix a mistake, or to address an unanticipated condition in the use of your service. Version numbers allow a client to ignore TXT records with versions newer than the highest txtvers number that the client knows how to interpret. The initial value of txtvers should be 1. Then, at a later time, if changes have to be made that result in a TXT record that is fundamentally incompatible with older clients, which they have no hope of reading correctly, then incrementing the txtvers to the next number signals to those older clients that they shouldn't even bother trying to parse this TXT record data. Such incompatible changes are best avoided if at all possible, but it is still good to have a mechanism available so that if incompatible changes are unavoidable, it is at least possible to make the change safely, without confusing old clients or causing them to behave incorrectly. |