To make a service discoverable using the P2P infrastructure, you first have to do a so called peer name registration.
A peer name registration has the following properties:
- a name (there are two different flavours: secured and unsecured – more on that later)
- one or more IP addresses and scope
- a port number
- a comment (optional)
- up to 4KB of binary data (optional)
The name of the service you want to register. Names have the following format: ‘authorityId.Name’. Unsecured Names use a ‘0’ as the authorityId and are easy to spoof/squat. When using a secured name, a key/pair is generated on the fly (the first time only) to sign the registration request. The public key hash becomes the authorityId in this case.
IP addresses and scope
That’s the most fascinating (and complicated) part. The peer name registration can have local and/or a global scope. A global scope means that the service can be discovered and contacted – well – globally. How can that work, given the service is behind a NAT device? IPv6 is the answer.
Now you may ask yourself: “but my network/router hardware is not IPv6 enabled, can this still work?”. Yes it does – making the transition between IPv4 and IPv6 is the job of so called transition or tunneling protocols. Teredo is the name of the protocol that is typically used here. Teredo has several jobs – one is to provide a globally unique IPv6 address, the other is to enable NAT traversal. I won’t go into the Teredo details here, but this document describes how it works.
When you do a ‘ipconfig’ on the command line you may already see a bunch of IPv6 addresses. The one that is directly associated with your NIC is the local address. You may also see a “Tunnel Adapter” interface – that would be the global Teredo provided address.
You can check the status/health of the Teredo protocol by using this command: ‘netsh int teredo show state’. This article helps you with troubleshooting if Teredo should not be enabled on your machine.
You can also have a look at the scope of your registration by checking the clouds to which your machine has access. This is done by doing a ‘netsh p2p pnrp cloud show list’. You should see one or more LinkLocal_ clouds and a Global_ cloud.
Again this article has all the details on clouds and their background.
So to wrap it up – by default a peer name registration will use all available NICs/IP addresses. If you have a global IPv6 address (which means that Teredo is working properly and you can ‘see’ the global cloud) this one is used also. This in turn means that the service can be used by every client that also has a global address.
The remaining properties are self explaining I think.
The following code snippet would register a secured peer name in all available clouds (you can find the APIs in the System.Net assembly (v3.5):
private void Register(string name, int port, string comment)
PeerName peerName = new PeerName(name, PeerNameType.Secured);
PeerNameRegistration reg = new PeerNameRegistration();
reg.PeerName = peerName;
reg.Port = port;
reg.Cloud = Cloud.Available;
reg.Comment = _cl.Comment;
The next posts will deal with peer name resolution and how to host a WCF service over this infrastructure.