A name can start with real labels and then finish with a pointer, and that pointer can lead to a name that itself ends in another pointer. Today you handle both - the general case where labels and pointers mix and chain.
Decode a name made of leading labels followed by a pointer, including a chain of pointers.
Real compression is rarely a bare pointer. More often a name is a few fresh
labels followed by a pointer to a shared suffix - www written out, then a
pointer to an example.com that appeared earlier. And that earlier name may itself
end in a pointer, forming a chain: www points to example which points to
com. Your decoder handles this naturally if it accumulates leading labels
normally and, the moment it meets a pointer, follows it and appends whatever full
name comes back - recursion does the chaining for you.
The consumed length still counts only the bytes at the starting offset: at
offset 15 you read www (four bytes) plus the two pointer bytes, so six bytes were
spent there regardless of how far the chain wanders. Decoding partway into the
chain, at offset 5, gives example.com because the example labels are followed
by a pointer to com. This mixed case is what nearly every compressed name in a
real response looks like, so getting it right makes the record parsing ahead
straightforward.
// accumulate leading labels, then when a pointer appears follow it// and append the name it yields - which may itself follow more pointersfor b[i] != 0 {if isPointer(b[i]) {rest, _ := decodeName(b, pointerTarget(b[i], b[i+1]))labels = append(labels, rest)break}// read a normal label and continue}