Registering a Peer Name

To register a peer name, an application must provide the following information:

If a peer name is unsecured, an identity is optional. If a peer identity is specified as NULL, the Peer Name Resolution Protocol (PNRP) uses an internal, default peer identity.

Registering a Peer Name

After the IP address list, peer identity, and peer name are identified, the application can register a peer name by calling WSASetService. Use the guidelines in the following sections of this topic to make the required configurations to the WSASetService parameters and the WSAQUERYSET structure.

Configuring WSASetService

When an application calls WSASetService, the parameters must be configured according to the following specifications:

  • essOperation must have a value of RNRSERVICE_REGISTER.
  • dwFlags must be zero (0).
  • lpqsRegInfo must point to a WSAQUERYSET structure, which must be configured by using the guidelines in the following Configuring WSAQUERYSET section of this topic.

Configuring WSAQUERYSET

The WSAQUERYSET structure must be configured according to the following specifications:

  • dwSize must specify the size the WSAQUERYSET structure.
  • lpszServiceInstanceName must point to the peer name that is being registered.
  • lpBlob must point to a PNRPINFO structure.
  • lpcsaBuffer must point to the address list.

Note

The remaining members are described in PNRP and WSASetService.

 

After a peer name is registered, the information is available to the Peer Infrastructure. However, there is a delay between the registration time and the propagation of the registration information to other nodes. During that time, other nodes may not be able to resolve the newly registered peer.

Example of Registering a Peer Name

The following code snippet shows you how to register a peer name by providing the correct information when calling WSASetService using the WSAQUERYSET structure.

#define UNICODE
#include <initguid.h>
#include <p2p.h>

#pragma comment(lib, "ws2_32.lib")

//-------------------------------------------------------------------------
// Function: PnrpRegister
//
// Purpose:  Register the given name in the PNRP cloud
//
// Arguments:
//   pwzIdentity : identity string created using PeerIdentityCreate
//   pwzName     : name to register in PNRP
//   pwzCloud    : name of the cloud to register in, NULL = global cloud
//   pNodeInfo   : local node info returned from 

//
// Returns:  HRESULT
//
HRESULT PnrpRegister(PWSTR pwzIdentity, PWSTR pwzName, PWSTR pwzCloud, SOCKADDR_IN6* pAddress)
{
    HRESULT         hr = S_OK;
    CSADDR_INFO     csaAddr = {0};
    PNRPINFO        pnrpInfo = {0};
    BLOB            blPnrpData = {0};
    WSAQUERYSET     querySet = {0};
    INT             iRet;

    //
    // fill a CSADDR_INFO structure from the address
    //
    csaAddr.iProtocol = IPPROTO_TCP;
    csaAddr.iSocketType = SOCK_STREAM;
    csaAddr.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_IN6);
    csaAddr.LocalAddr.lpSockaddr = (LPSOCKADDR)pAddress; 

    //
    // build the WSAQUERYSET required to register
    //
    pnrpInfo.dwSize = sizeof(pnrpInfo);
    pnrpInfo.dwLifetime = 60 * 60 * 8; //8 hours
    pnrpInfo.lpwszIdentity = pwzIdentity;

    blPnrpData.cbSize = sizeof(pnrpInfo);
    blPnrpData.pBlobData = (BYTE*)&pnrpInfo;

    querySet.dwSize = sizeof(querySet);
    querySet.dwNameSpace = NS_PNRPNAME;
    querySet.dwNumberOfCsAddrs = 1; // one address
    querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME;
    querySet.lpszServiceInstanceName = pwzName;
    querySet.lpszContext = pwzCloud;
    querySet.lpszComment = L"SomeComment";
    querySet.lpcsaBuffer = &csaAddr;
    querySet.lpBlob = &blPnrpData;

    // register the name with PNRP
    iRet = WSASetService(&querySet, RNRSERVICE_REGISTER, 0);
    if (iRet != 0)
    {
        hr = HRESULT_FROM_WIN32(WSAGetLastError());
    }
    
    return hr;
}