A DNS TXT record can be up to 65535 (0xFFFF) bytes long. The total length is indicated by the length given in the resource record header in the DNS message. There is no way to tell directly from the data alone how long it is (e.g. there is no length count at the start, or terminating NULL byte at the end).
The format of the data within a DNS TXT record is zero or more strings, packed together in memory without any intervening gaps or padding bytes for word alignment.
The format of each constituent string within the DNS TXT record is a single length byte, followed by 0-255 bytes of text data.
These format rules are defined in Section 3.3.14 of RFC 1035, and are not specific to DNS-SD. DNS-SD simply specifies a usage convention for what data should be stored in those constituent strings.
DNS TXT record format rules for use in DNS-SD (Rendezvous)
DNS-SD uses DNS TXT records to store arbitrary name/value pairs conveying additional information about the named service. Each name/value pair is encoded as it's own constituent string within the DNS TXT record, in the form "name=value". Everything up to the first '=' character is the name. Everything after the first '=' character to the end of the string (including subsequent '=' characters, if any) is the value. Specific rules governing names and values are given below. Each author defining a DNS-SD (Rendezvous) profile for discovering instances of a particular type of service should define the base set of name/value attributes that are valid for that type of service. Using this standardized name/value syntax within the TXT record makes it easier for these base definitions to be expanded later by defining additional named attributes. If an implementation sees unknown attribute names in a service TXT record, it SHOULD silently ignore them.
The TCP (or UDP) port number of the service, and target host name, are given in the SRV record. This information — target host name and port number — MUST NOT be duplicated using name/value attributes in the TXT record.
The intention of DNS-SD TXT records is convey a small amout of useful additional information about a service. Ideally it SHOULD NOT be necessary for a client to retrieve this additional information before it an usefully establish a connection to the service. For a well-designed TCP-based application protocol, it should be possible, knowing only the host name and port number, to open a connection to that listening process, and then perform version- or feature-negotiation to determine the capabilities of the service instance. For example, when connecting to an AppleShare server over TCP, the client enters into a protocol exchange with the server to determine which version of the AppleShare protocol the server implements, and which optional features or capabilities (if any) are available. For a well-designed application protocol, clients should be able to connect and use the service even if there is no information at all in the TXT record. In this case, the information in the TXT record should be viewed as a performance optimization — when a client discovers many instances of a service, the TXT record allows the client to know some rudimentary information about each instance without having open a TCP connection to each one and interrogate every service instance separately. Extreme care should be taken when doing this to ensure that the information in the TXT record is in agreement with the information retrieved by a client connecting over TCP.
There are legacy protocols which provide no feature negotiation capability, and in these cases it may be useful to convey necessary information in the TXT record. For example, when printing using the old Unix LPR (port 515) protocol, the LPR service provides no way for the client to determine whether a particular printer accepts PostScript, or what version of PostScript, etc. In this case it is appropriate to embed this information in the TXT record, because the alternative is worse — passing around written instructions to the users, arcane manual configuration of "/etc/printcap" files, etc.
DNS-SD TXT record size
The total size of a typical DNS-SD TXT record is intended to be small — 100 bytes or less.
In cases where more data is justified (e.g. LPR printing), 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 this is not enough, keeping size of the TXT record under 1300 bytes should allow it to fit in a single 1500-byte Ethernet packet.
Using TXT records larger than 1300 bytes is NOT RECOMMENDED at this time.
Rules for Names in DNS-SD Name/Value pairs
The "Name" MUST be at least one character. Strings beginning with an '=' character (i.e. the name is missing) SHOULD be silently ignored.
The characters of "Name" MUST be printable US-ASCII values (0x20-0x7E), excluding '=' (0x3D).
Spaces in the name are significant, whether leading, trailing, or in the middle — so don't include any spaces unless you really indend that!
Case is ignored when interpreting a name, so "papersize=A4", "PAPERSIZE=A4" and "Papersize=A4" are all identical.
If there is no '=', then it is a boolean attribute, and is simply identified as being present, with no value.
When examining a TXT record for a given named attribute, there are therefore four broad categories of result which may be returned:
Attribute not present (Absent)
Attribute present, with no value (e.g. "Anon Allowed" — server allows anonymous connections)
Attribute present, with empty value (e.g. "Installed PlugIns=" — server supports plugins, but none are presently installed)
Attribute present, with non-empty value (e.g. "Installed PlugIns=JPEG,MPEG2,MPEG4")
Unless specified otherwise by a particular DNS-SD (Rendezvous) profile, a given attribute name may appear at most once in a TXT record. If a client receives a TXT record containing the same attribute name more than once, then the client SHOULD silently ignore all but the first occurrence of that attribute. For client implementations that process a DNS-SD TXT record from start to end, placing name/value pairs into a hash table, using the name as the hash table key, this means that if the implementation attempts to add a new name/value pair into the table and finds an entry with the same name already present, then the new entry being added should be silently discarded instead. For client implementations that retrieve name/value pairs by searching the TXT record for the requested name, they should search the TXT record from the start, and simply return the first matching name they find.
Each author defining a DNS-SD (Rendezvous) profile for discovering instances of a particular type of service should define the interpretation of these different kinds of result. For example, for some keys, there may be a natural boolean interpretation:
Absent implies 'false'
Present with no value implies 'true'
For other keys it may be sensible to define other semantics, such as:
Present with value implies that value. E.g. "Color=4" for a four-color ink-jet printer, or "Color=6" for a six-color ink-jet printer.
Present with emply value implies 'false'. E.g. Not a color printer.
Absent implies 'Unknown'. E.g. A print server connected to some unknown printer where the print server doesn't actually know if the printer does color or not — which gives a very bad user experience and should be avoided wherever possible.
(Note that this is a hypothetical example, not an example of real name/value keys for printing.)
As a general rule, names that contain no dots are defined as part of the open-standard definition written by the person or group defining the DNS-SD (Rendezvous) profile for discovering that particular service type. Vendor-specific extensions should be given names of the form "keyname.company.com=value", using a domain name legitimately registered to the person or organization creating the vendor-specific key. This reduces the risk of accidental conflict if different organizations each define their own vendor-specific keys.
Rules for values in DNS-SD Name/Value pairs
If there is an '=', then everything after the first '=' to the end of the string is the value. The value can contain any eight-bit values including '='. Leading or trailing spaces are part of the value, so don't put them there unless you intend them to be there. Any quotation marks around the value are part of the value, so don't put them there unless you intend them to be part of the value.
The value is opaque binary data. Often the value for a particular attribute will be US-ASCII (or UTF-8) text, but it is legal for a value to be any binary data. For example, if the value of a key is an IPv4 address, that address should simply be stored as four bytes of binary data, not as a variable-length 7-15 byte ASCII string giving the address represented in textual dotted decimal notation.
Generic debugging tools should generally display all attribute values as if they were UTF-8 text, except for attributes where the debugging tool has embedded knowledge that the value is some other kind of data.
Authors defining DNS-SD (Rendezvous) profiles SHOULD NOT convert binary attribute data types into printable text (e.g. using hexadecimal, Base64 or UU encoding) merely for the sake of making the data be printable text when seen in a generic debugging tool. Doing this simply bloats the size of the TXT record, without truly making the data any more understandable to someone looking at it in a generic debugging tool.
Example TXT record containing three name/value pairs
It is recommended that authors defining DNS-SD (Rendezvous) profiles include an attribute of the form "version=xxx" in their definition, and require it to be the first name/value pair in the TXT record. This information in the TXT record can be useful help clients maintain backwards compatibility with older implementations if becomes necessary to change or update the specification over time. Even if the profile author doesn't anticipate the need for any future incompatible changes, having a version number in the specification provides useful insurance should incompatible changes become unavoidable. Clients should ignore TXT records with a version number higher (or lower) than the version(s) they know how to interpret.
Legacy Implementations
Do not assume that all current Apple products using Rendezvous present a model example of how to structure Rendezvous TXT records. Like all companies, Apple sometimes works under severe time pressure, and some of the current Apple Rendezvous products were written in a great hurry. Consequently you should not assume that any particular behaviour of a current Apple Rendezvous product necessarily constitutes an endorsement that that behaviour is correct, or an acceptable model to emulate.
OS X APIs
Jaguar's DNSServiceDiscovery.h APIs are, like most Unix APIs, based on C strings. How then does a client encode multiple pascal strings containing name/value pairs using a single C string? The answer is that Jaguar's DNSServiceDiscovery.h APIs use ASCII 1 as the boundary marker between constituent strings within the DNS TXT record. This value can be inserted into a C string using '\001', as shown below:
DNSServiceRegistrationCreate(..., "a=1\001b=2\001c=3", ...);The results returned from DNSServiceResolverResolve() return the TXT data similarly encoded, so that each name/value pair except the last is followed by ASCII 1, and the last is followed (as usual for a C string) by ASCII 0.
See SamplemDNSClient.c in the Darwin Open Source Code for simple sample code showing how to do this.
This encoding as C strings means that binary values containing the value 0 or 1 cannot be used with this API. For clients wishing to create binary values in TXT records, the registration can be created with an empty TXT record, and then the DNSServiceRegistrationUpdateRecord() call can be used to update the TXT record, as shown below.
DNSServiceRegistrationUpdateRecord(ref, 0, len, buffer, ttl);The buffer passed to this call is used as-is without interpretation or modification, so it is the client's responsibility to ensure that it is a properly formatted DNS TXT record.
To obtain the raw binary-format TXT record associated with a service, without interpretation or modification, the client should use the standard Unix res_query() call. Unfortunately, in OS X 10.2 and 10.2.1, the res_query() call does not work with local multicast Rendezvous names (names ending in ".local."). This bug has been fixed, and is planned for an upcoming OS X update.
Client applications that really really need to obtain raw binary-format TXT records for local multicast Rendezvous names right right now, and can't wait for the OS X update, can embed the Darwin mDNSResponder source code directly in their application, and use that API do do the record lookup. This course of action is recommended only for the very bold (and impatient).
DNS-SD TXT Records for _http._tcp service
Currently only one key is defined for _http._tcp service; the "path" key. The value of the path key is everything that comes after the optional port number in an HTTP URL, as defined in section 3.2.2 of RFC 2616 ("HTTP/1.1"):
http URL
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]If you are writing a web browser, then the path key gives you the text that should appear directly after "GET " in an HTTP "GET" request.
If you are writing a tool to generate a URL to send to a web browser for display, then you should generate a URL of the form shown below, where {host} and {port} are obtained from the information in the service's SRV record, and {path} is obtained from the "path" key in the TXT record.
http://{host}:{port}{path}The path key in the TXT record MUST include the leading slash of the abs_path, e.g. the following is a legal DNS-SD TXT record for an _http._tcp service:
path=/thepage.htmlIf the path key is missing, or present with no value or empty value, or otherwise invalid, then the path is assumed to be "/".
意圖的DNS -統計處TXT等記錄,是傳達一個小量的有益補充資料服務。最理想的,不應該有必要為客戶取回這筆額外資料,然後它是一個有益的建立連線,以提供服務。一個設計良好的TCP基於套用協定的,它應該有可能,只知道主機名稱和連線埠號,打開一個連線,收聽過程中,然後再演出版本或功能談判,以確定能力服務例如。舉例來說,當連線到appleshare伺服器TCP時,客戶簽訂了協定交換與伺服器,以確定哪個版本的appleshare議定書伺服器執行的,並且可選的特性或功能(如果有的話)可供選擇。一個設計良好的套用協定,客戶應能連線上,並使用該服務,因此,即使沒有這方面的資料都在上班時間記錄。在這種情況下,信息在TXT的記錄應被看作是一個性能最佳化-當客戶發現許多一項服務, T XT等記錄在案,使客戶了解一些最起碼的信息,比如每不必打開一個T CP連線,以每一個和審問每個服務實例都分開。極端應注意的時候,這樣做是為了確保資料在上班時間紀錄,是在協定與信息檢索客戶端連線在TCP 。
有遺留議定書,其中規定,沒有特色的談判能力,並且在這些情況下,它可能是有用的,以傳達必要的信息,在TXT的記錄。舉例來說,當印刷使用舊的Unix車牌識別(連線埠515 )議定書中,車牌識別服務,不提供任何方式為客戶確定某一特定印表機接受後記中,或有什麼版本的後記中,等等,在這種情況下,是適當的嵌入這一信息在上班時間記錄的,因為另一種方法是壞-通過圍繞在批示中向用戶,難懂的手工配置的" /等/ p rintcap"檔案等。