private PeerNodeAddress PeerNodeAddressFromPnrpRegistration(PnrpRegistration input)
 {
     Action<IPEndPoint> action = null;
     Action<Guid> action2 = null;
     List<IPAddress> addresses = new List<IPAddress>();
     PeerNodeAddress address = null;
     StringBuilder pathBuilder = new StringBuilder(200);
     int version = 0;
     try
     {
         Guid[] guidArray;
         string str;
         if ((input == null) || string.IsNullOrEmpty(input.Comment))
         {
             return null;
         }
         if (action == null)
         {
             action = delegate (IPEndPoint obj) {
                 addresses.Add(obj.Address);
             };
         }
         Array.ForEach<IPEndPoint>(input.Addresses, action);
         if (addresses.Count == 0)
         {
             return address;
         }
         UriBuilder builder = new UriBuilder {
             Port = input.Addresses[0].Port,
             Host = addresses[0].ToString()
         };
         pathBuilder.Append("PeerChannelEndpoints");
         CharEncoder.Decode(input.Comment, out version, out str, out guidArray);
         if (((version != 1) || (guidArray == null)) || ((guidArray.Length > 2) || (guidArray.Length < 1)))
         {
             return address;
         }
         builder.Scheme = str;
         if (action2 == null)
         {
             action2 = delegate (Guid guid) {
                 pathBuilder.Append('/' + string.Format(CultureInfo.InvariantCulture, "{0}", new object[] { guid.ToString() }));
             };
         }
         Array.ForEach<Guid>(guidArray, action2);
         builder.Path = string.Format(CultureInfo.InvariantCulture, "{0}", new object[] { pathBuilder.ToString() });
         address = new PeerNodeAddress(new EndpointAddress(builder.Uri, new AddressHeader[0]), new ReadOnlyCollection<IPAddress>(addresses));
     }
     catch (ArgumentException exception)
     {
         DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
     }
     catch (FormatException exception2)
     {
         DiagnosticUtility.ExceptionUtility.TraceHandledException(exception2, TraceEventType.Information);
     }
     catch (IndexOutOfRangeException exception3)
     {
         DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Information);
     }
     return address;
 }
 private void PeerNodeAddressToPnrpRegistrations(string meshName, Dictionary<uint, string> LinkCloudNames, Dictionary<uint, string> SiteCloudNames, PeerNodeAddress input, out PnrpRegistration[] linkRegs, out PnrpRegistration[] siteRegs, out PnrpRegistration global)
 {
     string str;
     Guid[] guidArray;
     new PnrpRegistration();
     Dictionary<uint, PnrpRegistration> dictionary = new Dictionary<uint, PnrpRegistration>();
     Dictionary<uint, PnrpRegistration> dictionary2 = new Dictionary<uint, PnrpRegistration>();
     PnrpRegistration registration = null;
     this.ParseServiceUri(input.EndpointAddress.Uri, out str, out guidArray);
     int port = input.EndpointAddress.Uri.Port;
     if (port <= 0)
     {
         port = 0x328;
     }
     string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", new object[] { meshName });
     string comment = CharEncoder.Encode(1, str, guidArray);
     global = null;
     string str4 = string.Empty;
     foreach (IPAddress address in input.IPAddresses)
     {
         if ((address.AddressFamily == AddressFamily.InterNetworkV6) && (address.IsIPv6LinkLocal || address.IsIPv6SiteLocal))
         {
             if (address.IsIPv6LinkLocal)
             {
                 if (!dictionary.TryGetValue((uint) address.ScopeId, out registration))
                 {
                     if (!LinkCloudNames.TryGetValue((uint) address.ScopeId, out str4))
                     {
                         continue;
                     }
                     registration = PnrpRegistration.Create(peerName, comment, str4);
                     dictionary.Add((uint) address.ScopeId, registration);
                 }
             }
             else if (!dictionary2.TryGetValue((uint) address.ScopeId, out registration))
             {
                 if (!SiteCloudNames.TryGetValue((uint) address.ScopeId, out str4))
                 {
                     continue;
                 }
                 registration = PnrpRegistration.Create(peerName, comment, str4);
                 dictionary2.Add((uint) address.ScopeId, registration);
             }
             registration.addressList.Add(new IPEndPoint(address, port));
         }
         else
         {
             if (global == null)
             {
                 global = PnrpRegistration.Create(peerName, comment, "Global_");
             }
             global.addressList.Add(new IPEndPoint(address, port));
         }
     }
     if (global != null)
     {
         if (global.addressList != null)
         {
             this.TrimToMaxAddresses(global.addressList);
             global.Addresses = global.addressList.ToArray();
         }
         else
         {
             global.Addresses = new IPEndPoint[0];
         }
     }
     if (dictionary.Count != 0)
     {
         foreach (PnrpRegistration registration2 in dictionary.Values)
         {
             if (registration2.addressList != null)
             {
                 this.TrimToMaxAddresses(registration2.addressList);
                 registration2.Addresses = registration2.addressList.ToArray();
             }
             else
             {
                 registration2.Addresses = new IPEndPoint[0];
             }
         }
         linkRegs = new PnrpRegistration[dictionary.Count];
         dictionary.Values.CopyTo(linkRegs, 0);
     }
     else
     {
         linkRegs = new PnrpRegistration[0];
     }
     if (dictionary2.Count != 0)
     {
         foreach (PnrpRegistration registration3 in dictionary2.Values)
         {
             if (registration3.addressList != null)
             {
                 this.TrimToMaxAddresses(registration3.addressList);
                 registration3.Addresses = registration3.addressList.ToArray();
             }
             else
             {
                 registration3.Addresses = new IPEndPoint[0];
             }
         }
         siteRegs = new PnrpRegistration[dictionary2.Count];
         dictionary2.Values.CopyTo(siteRegs, 0);
     }
     else
     {
         siteRegs = new PnrpRegistration[0];
     }
 }
 internal static PnrpRegistration Create(string peerName, string comment, string cloudName)
 {
     PnrpRegistration reg = new PnrpRegistration();
     reg.Comment = comment;
     reg.CloudName = cloudName;
     reg.PeerName = peerName;
     reg.addressList = new List<IPEndPoint>();
     return reg;
 }
        void PeerNodeAddressToPnrpRegistrations(string meshName, Dictionary<uint, string> LinkCloudNames, Dictionary<uint, string> SiteCloudNames, PeerNodeAddress input, out PnrpRegistration[] linkRegs, out PnrpRegistration[] siteRegs, out PnrpRegistration global)
        {
            PnrpRegistration reg = new PnrpRegistration();

            Dictionary<uint, PnrpRegistration> resultsLink = new Dictionary<uint, PnrpRegistration>();
            Dictionary<uint, PnrpRegistration> resultsSite = new Dictionary<uint, PnrpRegistration>();
            PnrpRegistration entry = null;
            string scheme;
            Guid[] guids;
            ParseServiceUri(input.EndpointAddress.Uri, out scheme, out guids);
            int port = input.EndpointAddress.Uri.Port;
            if (port <= 0)
                port = TcpUri.DefaultPort;
            string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", meshName);
            string comment = CharEncoder.Encode(PayloadVersion, scheme, guids);
            global = null;
            string cloudName = string.Empty;
            foreach (IPAddress address in input.IPAddresses)
            {
                if (address.AddressFamily == AddressFamily.InterNetworkV6
                    &&
                    ((address.IsIPv6LinkLocal) || (address.IsIPv6SiteLocal))
                )
                {
                    if (address.IsIPv6LinkLocal)
                    {
                        if (!resultsLink.TryGetValue((uint)address.ScopeId, out entry))
                        {
                            if (!LinkCloudNames.TryGetValue((uint)address.ScopeId, out cloudName))
                            {
                                continue;
                            }
                            entry = PnrpRegistration.Create(peerName, comment, cloudName);
                            resultsLink.Add((uint)address.ScopeId, entry);
                        }
                    }
                    else
                    {
                        if (!resultsSite.TryGetValue((uint)address.ScopeId, out entry))
                        {
                            if (!SiteCloudNames.TryGetValue((uint)address.ScopeId, out cloudName))
                            {
                                continue;
                            }
                            entry = PnrpRegistration.Create(peerName, comment, cloudName);
                            resultsSite.Add((uint)address.ScopeId, entry);
                        }
                    }
                    entry.addressList.Add(new IPEndPoint(address, port));
                }
                else
                {
                    if (global == null)
                    {
                        global = PnrpRegistration.Create(peerName, comment, GlobalCloudName);
                    }
                    global.addressList.Add(new IPEndPoint(address, port));
                }
            }
            if (global != null)
            {
                if (global.addressList != null)
                {
                    TrimToMaxAddresses(global.addressList);
                    global.Addresses = global.addressList.ToArray();
                }
                else
                    global.Addresses = new IPEndPoint[0];
            }

            if (resultsLink.Count != 0)
            {
                foreach (PnrpRegistration tempLink in resultsLink.Values)
                {
                    if (tempLink.addressList != null)
                    {
                        TrimToMaxAddresses(tempLink.addressList);
                        tempLink.Addresses = tempLink.addressList.ToArray();
                    }
                    else
                    {
                        tempLink.Addresses = new IPEndPoint[0];
                    }
                }
                linkRegs = new PnrpRegistration[resultsLink.Count];
                resultsLink.Values.CopyTo(linkRegs, 0);
            }
            else
                linkRegs = new PnrpRegistration[0];
            if (resultsSite.Count != 0)
            {
                foreach (PnrpRegistration tempSite in resultsSite.Values)
                {
                    if (tempSite.addressList != null)
                    {
                        TrimToMaxAddresses(tempSite.addressList);
                        tempSite.Addresses = tempSite.addressList.ToArray();
                    }
                    else
                    {
                        tempSite.Addresses = new IPEndPoint[0];
                    }
                }
                siteRegs = new PnrpRegistration[resultsSite.Count];
                resultsSite.Values.CopyTo(siteRegs, 0);
            }
            else
                siteRegs = new PnrpRegistration[0];
        }
        //return null in case of unrecognized format. consider adding logging.
        PeerNodeAddress PeerNodeAddressFromPnrpRegistration(PnrpRegistration input)
        {
            List<IPAddress> addresses = new List<IPAddress>();
            PeerNodeAddress result = null;
            Guid[] guids;
            StringBuilder pathBuilder = new StringBuilder(MaxPathLength);
            int version = 0;
            string protocolScheme;

            try
            {
                if (input == null || String.IsNullOrEmpty(input.Comment))
                    return null;
                Array.ForEach(input.Addresses, delegate(IPEndPoint obj) { addresses.Add(obj.Address); });
                if (addresses.Count != 0)
                {
                    UriBuilder uriBuilder = new UriBuilder();
                    uriBuilder.Port = input.Addresses[0].Port;
                    uriBuilder.Host = addresses[0].ToString();
                    pathBuilder.Append(PeerStrings.KnownServiceUriPrefix);
                    CharEncoder.Decode(input.Comment, out version, out protocolScheme, out guids);

                    if (
                        (version == PayloadVersion) &&
                        (guids != null) && (guids.Length <= MaxGuids) &&
                        (guids.Length >= MinGuids)
                    )
                    {
                        uriBuilder.Scheme = protocolScheme;
                        Array.ForEach(guids, delegate(Guid guid)
                                            {
                                                pathBuilder.Append(PathSeparator + String.Format(CultureInfo.InvariantCulture, "{0}", guid.ToString()));
                                            }
                        );
                        uriBuilder.Path = String.Format(CultureInfo.InvariantCulture, "{0}", pathBuilder.ToString());
                        result = new PeerNodeAddress(new EndpointAddress(uriBuilder.Uri), new ReadOnlyCollection<IPAddress>(addresses));
                    }
                }
            }
            catch (ArgumentException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }
            catch (FormatException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }
            catch (IndexOutOfRangeException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }

            return result;

        }
                public void SyncEnumeration(object state)
                {
                    int retval = 0;
                    CriticalLookupHandle hLookup;
                    WsaQuerySetSafe native = WsaQuerySet.ToWsaQuerySetSafe(resolveQuery);
                    using (native)
                    {
                        CriticalAllocHandle handle = CriticalAllocHandleWsaQuerySetSafe.FromWsaQuerySetSafe(native);
                        retval = WSALookupServiceBegin(handle, WsaNspControlFlags.ReturnAll, out hLookup);
                    }
                    if (retval != 0)
                    {
                        lastException = new PnrpException(WSAGetLastError(), resolveQuery.Context);
                        Utility.CloseInvalidOutCriticalHandle(hLookup);
                        Complete(false, lastException);
                        return;
                    }
                    WsaQuerySet querySet = new WsaQuerySet();

                    // start with a sensible default size
                    int size = Marshal.SizeOf(typeof(WsaQuerySetSafe)) + 400;
                    CriticalAllocHandle nativeQuerySetPtr = CriticalAllocHandle.FromSize(size);
                    try
                    {
                        using (hLookup)
                        {
                            while (true)
                            {
                                if (timeoutHelper.RemainingTime() == TimeSpan.Zero)
                                {
                                    break;
                                }
                                retval = WSALookupServiceNext(hLookup, 0, ref size, (IntPtr)nativeQuerySetPtr);
                                if (retval != 0)
                                {
                                    int error = WSAGetLastError();
                                    if (error == (int)WsaError.WSAENOMORE || error == (int)WsaError.WSA_E_NO_MORE)
                                    {
                                        // no more
                                        break;
                                    }

                                    if (error == (int)WsaError.WSAEFAULT)
                                    {
                                        nativeQuerySetPtr = CriticalAllocHandle.FromSize(size);
                                        continue;
                                    }

                                    // unexpected error
                                    PeerExceptionHelper.ThrowPnrpError(error, querySet.Context);
                                }
                                else
                                {
                                    if (nativeQuerySetPtr != IntPtr.Zero)
                                    {
                                        // marshal the results into something useful
                                        querySet = MarshalWsaQuerySetNativeToWsaQuerySet(nativeQuerySetPtr, scopeId);

                                        // allocate the friendly PnrpRegistration and fill it in
                                        PnrpRegistration pnrpRegistration = new PnrpRegistration();
                                        pnrpRegistration.CloudName = querySet.Context;
                                        pnrpRegistration.Comment = querySet.Comment;
                                        pnrpRegistration.PeerName = querySet.ServiceInstanceName;
                                        pnrpRegistration.Addresses = new IPEndPoint[querySet.CsAddrInfos.Length];
                                        for (int i = 0; i < querySet.CsAddrInfos.Length; i++)
                                            pnrpRegistration.Addresses[i] = querySet.CsAddrInfos[i].LocalAddr;

                                        // add it to the list to return later.
                                        // all cloud enumeratos in the same scope will reference the same list and hence the lock.
                                        lock (results)
                                        {
                                            results.Add(pnrpRegistration);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (DiagnosticUtility.ShouldTraceInformation)
                        {
                            PnrpResolveExceptionTraceRecord record = new PnrpResolveExceptionTraceRecord(resolveQuery.ServiceInstanceName, resolveQuery.Context, e);
                            if (DiagnosticUtility.ShouldTraceError)
                            {
                                TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.PnrpResolveException,
                                    SR.GetString(SR.TraceCodePnrpResolveException), record, this, null);
                            }
                        }
                        lastException = e;
                    }
                    finally
                    {
                        Complete(false, lastException);
                    }
                }
                public void Register(PnrpRegistration registration, TimeSpan timeout)
                {
                    // fill in the PnrpInfo blob using the defaults
                    PnrpInfo pnrpInfo = new PnrpInfo();
                    pnrpInfo.dwLifetime = RegistrationLifetime;
                    pnrpInfo.lpwszIdentity = null;
                    pnrpInfo.dwSize = Marshal.SizeOf(pnrpInfo);
                    pnrpInfo.dwFlags = PNRPINFO_HINT;
                    IPEndPoint hint = PnrpPeerResolver.GetHint();
                    pnrpInfo.saHint = SOCKET_ADDRESS_SAFE.SocketAddressFromIPEndPoint(hint);

                    // fill in the query set
                    WsaQuerySet registerQuery = new WsaQuerySet();
                    registerQuery.NameSpace = NspNamespaces.Name;
                    registerQuery.NSProviderId = NsProviderName;
                    registerQuery.ServiceClassId = SvcIdNameV1;
                    registerQuery.ServiceInstanceName = registration.PeerName;
                    registerQuery.Comment = registration.Comment;
                    registerQuery.Context = registration.CloudName;

                    // copy over the addresses
                    if (registration.Addresses != null)
                    {
                        Fx.Assert(registration.Addresses.Length <= 4, "Pnrp supports only 4 addresses");
                        registerQuery.CsAddrInfos = new CsAddrInfo[registration.Addresses.Length];
                        for (int i = 0; i < registration.Addresses.Length; i++)
                        {
                            // the only interesting part of the CsAddrInfo is the LocalAddress
                            registerQuery.CsAddrInfos[i].LocalAddr = registration.Addresses[i];
                            registerQuery.CsAddrInfos[i].iProtocol = (int)ProtocolType.Tcp;
                            registerQuery.CsAddrInfos[i].iSocketType = (int)SocketType.Stream;
                        }
                    }

                    // copy the blob
                    registerQuery.Blob = pnrpInfo;
                    RegisterService(registerQuery);
                }