There’s a little known, but extremely useful feature of PNRP we call extended payload. Every time I explain this feature to someone, their eyes light up. It’s always fun to surprise someone with a tidbit like extended payload, but it disappoints me that more PNRP developers don’t know about this feature already. Time to fix that!
Extended payload allows an application to attach an arbitrary blob of data to a PNRP name at registration time. When a searching application resolves the name, it will download the blob along with the endpoints (addresses and ports) describing the publisher. This is a great way to attach any extra information to your application endpoint that might be needed for the application session. If you were publishing a name identifying a multi-player gaming session, for example, you might include the game level or even level map as extended payload.
It’s important to point out that the extended payload isn’t pushed out into the PNRP cloud. It only lives on the publishers machine, and is only transferred from publisher to resolver at the time of a PNRP name resolution. If your machine is participating in the PNRP cloud by publishing a name, it is helping other nodes to publish and resolve, but it is never hosting extended payload on behalf of another computer. It’s also important to note that the extended payload cannot be tampered with if it is attached to a secure PNRP name, because it is included in a signed message.
If you’re using the native Windows PNRP API, you can register a name with an extended payload using the PeerPnrpRegister function. PeerPnrpRegister takes a PEER_PNRP_REGISTRATION_INFO structure as an argument. The payload member of this structure can be filled out with a blob that will become extended payload. If you’re using System.Net.PeerToPeer, look for the Data property of the PeerNameRegistration and PeerNameRecord classes.
The extended payload cannot exceed 4KB in size, and it’s best to keep your extended payload as small as possible. All PNRP messages are delivered over a UDP transport. This includes the message that carries the extended payload. There is logic in PNRP that breaks up a large extended payload and splits it across multiple UDP packets, allowing you to have a payload greater than 1 MTU. This logic handles message ordering, reassembly and some level of delivery guarantee, but large payloads can hurt performance, especially if the publisher or resolver is on a very lossy network. A PNRP resolve will not complete until the entire extended payload has been transmitted from the publisher to the resolver. If it takes too long to transmit all the pieces of the payload, the whole resolve may fail. If the extended payload is large, the message will be fragmented across multiple UDP packets. A larger number of packets increases the chance that a portion of the message will get lost. Be careful with extended payload, but remember that it’s there if you need it.