Background

This is the first article of many, where I will talk about the practical uses of Microsoft's Peer-to-Peer technology. Peer-to-Peer technology has been around since the late 90's. There have been several articles written for CodeProject that discuss the various aspects and implementations of a peer-to-peer infrastructure. There are also several open-source implementations including Gnucleus and Shareaza.

Microsoft recognized the value of this technology and spun up various research projects to investigate and document implementation approaches. Pastry was the earliest project that I recall that tackled the issues involved in building a peer-to-peer network. By late 2003, Microsoft released the Advanced Networking Pack for Windows XP SP1 which added basic Peer-to-Peer technology plumbing into Windows. While characteristically late to the game, their implementation recognized the value of using IPv6 as the foundation for building peer-to-peer networks. Microsoft has subsequently rolled this technology into Windows XP Service Pack 2 and continues to expand the infrastructure's capabilities into Windows Vista. Finally, given the nature of the technology, it's interesting to note that Microsoft has not included this support on any of its server platforms.

Introduction

Microsoft's entire Peer-to-Peer technology is exposed through the latest Platform SDK as C/C++ API calls. That's great for anyone who still develops applications in unmanaged code or managed C++. However, I'm a big fan of .NET managed code, and have been busy importing each API call into C# and creating a managed framework to simplify, as much as possible, peer-to-peer application development in .NET. So, without further delay, let's roll our sleeves up and dig in.

Clouds

As previously mentioned, IPv6 is at the heart of Microsoft's Peer-to-Peer technology. The beauty of IPv6 is that besides an address and port, a registered resource also has a scope. Scope was added to further identify the services/resources listening on a port. A group of resources connected in a peer-to-peer network using the same scope is also known as a Cloud. Clouds are closely related to IPv6 scopes but there are some minor differences.

A Cloud is like a membership at the YMCA, where only members (registered peers) can use the facilities (in this case, communicate). All members can use the facilities at any YMCA and so belong to the organization. In Peer-to-Peer terms, this organization is called the Global Cloud. The equivalent to individual YMCA facilities are called Link Clouds. That is, each LAN the computer is connected to has a Link Cloud.

The Global Cloud has the greatest range and allows applications to communicate over the Internet. Link clouds allow applications behind a firewall or connected through a common subnet to communicate.

To enumerate the available clouds, you must indicate the scope of the search:

Any

Return any cloud the computer is connected to

Global

Return the global cloud

LinkLocal

Return any link local clouds

Next comes a series of of Windows Socket calls to synchronously begin a lookup and iterate over the results:

Call WSALookupServiceBegin to begin the enumeration and return a handle.

Call WSALookupServiceNext to retrieve a set of clouds matching the scope. Call this function until the application has retrieved all the clouds.

Call WSALookupServiceEnd to finish the enumeration.

To encapsulate this functionality, I created a Collection class that implements IEnumerable with an embedded class that implements IEnumerator. This allows a simple foreach loop to enumerate the clouds.

The Reset function passes a complicated set of data structures into the WSALookupServiceBegin function. The LUP_RETURN_ALL parameter tells the subsequent call to WSALookupServiceNext to fully populate the PNRPCLOUDINFO data structure. MoveNext uses the WSALookupServiceNext to retrieve the results. true or false is returned depending on whether a result was returned. The Current function marshals the data structures into managed equivalents and creates a PeerCloud class to represent each cloud as a managed object. The following VB code shows how to use this cloud collection:

Of course, before peers in a cloud can communicate, they must be able to locate each other. This is were Peer Name Resolution comes in.

Peer Name Resolution (PNRP)

PNRP; it's a mouthful. It's also a serverless DNS technology that allows nodes to discover each other. Think about that for a second. It allows your Windows XP box to become its own DNS server. No need to pay $10 to register each domain name. But there's a catch; it's limited to the domain name pnrp.net.

As the first letter in PNRP suggests, you must register a Peer Name. Peer names are fixed names for resources such as computers, users, groups, or services. This is similar to today's DNS except, instead of just IP addresses, the resources can be more granular. A Peer Name is a case-sensitive text string that has the format "Authority.Classifier". The value of Authority depends on whether the name is secured or unsecured. The value is always 0 for an unsecured Authority (secured names will be discussed in a later article). The value of Classifier is a text string name you give for the resource and cannot contain spaces. The following list shows some examples of peer names:

0.test

0.my.peername

6520c005f63fc1864b7d8f3cabebd4916ae7f33d.test

PNRP uses peer names to identify resources in a peer network. The key here is "Peer Network". This isn't the whole IPv6 network that the computer is connected to, it's limited to just the resources available within a Cloud. Registering any resource not managed by the Peer-to-Peer networking APIs either will result in an error or won't be resolved later.

Register and Unregister a Peer Name

To register an unsecured Peer Name, you must provide a valid unsecured Peer Name and an IP address. Optionally, you can indicate the Cloud name (Global by default) and an additional comment or description associated with the resource. This information is stored in the WSAQUERYSET data structure and passed to the WSASetService with the Register option.

To unregister an unsecured Peer Name, you must provide a valid unsecured Peer Name and optionally the Cloud name (Global by default). This information is stored in the WSAQUERYSET data structure and passed to the WSASetService with the Delete option. While not listed here, the code is included in the download.

Searching for a Peer Name

PNRP includes the ability to search for registered Peer Names. To resolve a Peer Name, you must provide the Peer Name, search criteria and optional cloud name (Global by default) and IP address hint. Typically, a lookup is used to determine if a Peer Name already exists or to contact it directly. The following search criteria options are supported:

Default

Uses the NonCurrentProcessPeerName option.

AnyPeerName

The matching peer name can be registered locally or remotely.

NearestNonCurrentProcessName

The matching peer name can be registered locally or remotely, but the resolve request excludes any peer name registered by the process making the resolve request and looks for the service closest to the local IP address.

NearestPeerName

The matching peer name can be registered locally or remotely, but the resolve request looks for the service closest to the local IP address.

NearestRemotePeerName

The resolve request excludes any peer name registered locally on this computer and looks for the service closest to the local IP address.

NonCurrentProcessPeerName

The matching peer name can be registered locally or remotely, but the resolve request excludes any peer name registered by the process making the resolve request.

RemotePeerName

The resolve request excludes any peer name registered locally on this computer.

Again, a series of Windows Socket calls are used to synchronously begin a lookup.

Call WSALookupServiceBegin to begin the enumeration and return a handle.

DNS Name Corresponding to a Peer Name

Since PNRP is a serverless DNS, it makes sense to be able to lookup the DNS name associated with a Peer Name. It's also useful to determine the Peer Name given a DNS name. Starting in Windows Vista, two additional Peer-to-Peer APIs are provided to do just this. The code below shows calling these functions from C#:

Points of Interest

Now that you've seen the gory details of using the WSAxx functions to interact with PNRP, you'll be glad to know that Microsoft will be providing wrapper functions to hide these details. These wrapper functions will be available for Windows Vista Beta 2 and later. I can only guess that these functions will also be available in Windows XP Service Pack 3. While there is currently no documentation for these functions, I've taken a guess at their purpose.

PeerPnrpGetCloudInfo - returns an array of PNRPCLOUDINFO structures matching the given scope.

Conclusion

I hope you have found this article as a useful starting point. I'm considering writing more articles on the following subjects to further your understanding of Microsoft's Peer-to-Peer technology:

Peer Name Resolution - netsh.

Peer Graph - The Basics

Peer Graph - Nodes and Connections

Peer Graph - Records

Peer Graph - Attributes

Peer Graph - Searching

Peer Groups and Identity

Peer Collaboration - People Near Me

Peer Collaboration - EndPoints

Peer Collaboration - Capabilities

Peer Collaboration - Presence

Peer Collaboration - Invitations

If you have suggestions or other topics, please leave a comment. Oh! and don't forget to vote.

History

Initial revision.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Adrian Moore is the Development Manager for the SCADA Vision system developed by ABB Inc in Calgary, Alberta.

He has been interested in compilers, parsers, real-time database systems and peer-to-peer solutions since the early 90's. In his spare time, he is currently working on a SQL parser for querying .NET DataSets (http://www.queryadataset.com).

Comments and Discussions

I have an small doubt. Please answer this. Can any two people connect through this application. I mean i want to develop an P2P chat. While the the two people are using internet. Can i use this application this method to make this possible. Thanks in advance

Hi,
I tried to test the cloud, by installing the application into VPC, but when I run it it doesn't show Global_ in the list, while on my local machine it shows the Global_, so I couldn't register the node from VPC and try to look it up from my local PC. Any clue?

I start your Peer Name Resolution demo, first thing I do is click on 'lookup', it starts 'looking'. After several seconds it returns 'Name not registered'.
Next I click on 'register', it suddenly returns 'Type could not be marshaled because the length of an embedded instance...'.
What am i doing wrong? Thanks.

I have the same problems, but there are only two file in %windir%\Microsoft.NET\Framework\v1.1.4322\CONFIG.
gacutil.exe.config
regsvcs.exe.config
There's no IPv6 configuration in the files.
What sould I do for that?
Thank you.