public override ReadOnlyCollection<PeerNodeAddress> Resolve(string meshId, int maxAddresses, TimeSpan timeout) { UnsafePnrpNativeMethods.PeerNameResolver resolver; this.ThrowIfNoPnrp(); List<UnsafePnrpNativeMethods.PeerNameResolver> list = new List<UnsafePnrpNativeMethods.PeerNameResolver>(); List<PnrpRegistration> results = new List<PnrpRegistration>(); List<PnrpRegistration> list3 = new List<PnrpRegistration>(); List<PnrpRegistration> list4 = new List<PnrpRegistration>(); List<WaitHandle> list5 = new List<WaitHandle>(); Dictionary<uint, string> siteCloudNames = new Dictionary<uint, string>(); Dictionary<uint, string> linkCloudNames = new Dictionary<uint, string>(); UnsafePnrpNativeMethods.PnrpResolveCriteria nearestNonCurrentProcess = UnsafePnrpNativeMethods.PnrpResolveCriteria.NearestNonCurrentProcess; TimeoutHelper helper = new TimeoutHelper((TimeSpan.Compare(timeout, MaxResolveTimeout) <= 0) ? timeout : MaxResolveTimeout); if (!HasPeerNodeForMesh(meshId)) { nearestNonCurrentProcess = UnsafePnrpNativeMethods.PnrpResolveCriteria.Any; } PnrpResolveScope scope = this.EnumerateClouds(true, linkCloudNames, siteCloudNames); if (this.remoteExtension != null) { meshId = meshId + this.remoteExtension; } string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", new object[] { meshId }); if ((scope & PnrpResolveScope.Global) != PnrpResolveScope.None) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, 0, "Global_", helper.RemainingTime(), results); list5.Add(resolver.AsyncWaitHandle); list.Add(resolver); } if ((scope & PnrpResolveScope.LinkLocal) != PnrpResolveScope.None) { foreach (KeyValuePair<uint, string> pair in linkCloudNames) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, pair.Key, pair.Value, helper.RemainingTime(), list3); list5.Add(resolver.AsyncWaitHandle); list.Add(resolver); } } if ((scope & PnrpResolveScope.SiteLocal) != PnrpResolveScope.None) { foreach (KeyValuePair<uint, string> pair2 in siteCloudNames) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver(peerName, maxAddresses, nearestNonCurrentProcess, pair2.Key, pair2.Value, helper.RemainingTime(), list4); list5.Add(resolver.AsyncWaitHandle); list.Add(resolver); } } if (list5.Count == 0) { if (DiagnosticUtility.ShouldTraceWarning) { Exception exception = new InvalidOperationException(System.ServiceModel.SR.GetString("PnrpNoClouds")); PnrpResolveExceptionTraceRecord extendedData = new PnrpResolveExceptionTraceRecord(meshId, string.Empty, exception); TraceUtility.TraceEvent(TraceEventType.Warning, 0x4004a, System.ServiceModel.SR.GetString("TraceCodePnrpResolvedAddresses"), extendedData, this, null); } return new ReadOnlyCollection<PeerNodeAddress>(new List<PeerNodeAddress>()); } Exception exception2 = null; foreach (UnsafePnrpNativeMethods.PeerNameResolver resolver2 in list) { try { resolver2.End(); } catch (SocketException exception3) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Information); exception2 = exception3; } } List<PeerNodeAddress> nodeAddressList = new List<PeerNodeAddress>(); this.MergeResults(nodeAddressList, results, list3, list4); if ((exception2 != null) && (nodeAddressList.Count == 0)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception2); } if (DiagnosticUtility.ShouldTraceInformation) { PnrpPeerResolverTraceRecord record2 = new PnrpPeerResolverTraceRecord(meshId, nodeAddressList); TraceUtility.TraceEvent(TraceEventType.Information, 0x4004a, System.ServiceModel.SR.GetString("TraceCodePnrpResolvedAddresses"), record2, this, null); } return new ReadOnlyCollection<PeerNodeAddress>(nodeAddressList); }
public override ReadOnlyCollection<PeerNodeAddress> Resolve(string meshId, int maxAddresses, TimeSpan timeout) { ThrowIfNoPnrp(); UnsafePnrpNativeMethods.PeerNameResolver resolver; List<UnsafePnrpNativeMethods.PeerNameResolver> resolvers = new List<UnsafePnrpNativeMethods.PeerNameResolver>(); List<PnrpRegistration> globalRegistrations = new List<PnrpRegistration>(); List<PnrpRegistration> linkRegistrations = new List<PnrpRegistration>(); List<PnrpRegistration> siteRegistrations = new List<PnrpRegistration>(); List<WaitHandle> handles = new List<WaitHandle>(); Dictionary<uint, string> SiteCloudNames = new Dictionary<uint, string>(); Dictionary<uint, string> LinkCloudNames = new Dictionary<uint, string>(); UnsafePnrpNativeMethods.PnrpResolveCriteria targetScope = resolutionScope; TimeoutHelper timeoutHelper = new TimeoutHelper(TimeSpan.Compare(timeout, MaxResolveTimeout) <= 0 ? timeout : MaxResolveTimeout); if (!HasPeerNodeForMesh(meshId)) targetScope = UnsafePnrpNativeMethods.PnrpResolveCriteria.Any; PnrpResolveScope currentScope = EnumerateClouds(true, LinkCloudNames, SiteCloudNames); if (remoteExtension != null) meshId += remoteExtension; // prepend a 0. for unsecured peername string peerName = string.Format(CultureInfo.InvariantCulture, "0.{0}", meshId); if ((currentScope & PnrpResolveScope.Global) != 0) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver( peerName, maxAddresses, targetScope, 0, GlobalCloudName, timeoutHelper.RemainingTime(), globalRegistrations); handles.Add(resolver.AsyncWaitHandle); resolvers.Add(resolver); } if ((currentScope & PnrpResolveScope.LinkLocal) != 0) { foreach (KeyValuePair<uint, string> linkEntry in LinkCloudNames) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver( peerName, maxAddresses, targetScope, linkEntry.Key, linkEntry.Value, timeoutHelper.RemainingTime(), linkRegistrations); handles.Add(resolver.AsyncWaitHandle); resolvers.Add(resolver); } } if ((currentScope & PnrpResolveScope.SiteLocal) != 0) { foreach (KeyValuePair<uint, string> siteEntry in SiteCloudNames) { resolver = new UnsafePnrpNativeMethods.PeerNameResolver( peerName, maxAddresses, targetScope, siteEntry.Key, siteEntry.Value, timeoutHelper.RemainingTime(), siteRegistrations); handles.Add(resolver.AsyncWaitHandle); resolvers.Add(resolver); } } if (handles.Count == 0) { //could not find any clouds. if (DiagnosticUtility.ShouldTraceWarning) { Exception exception = new InvalidOperationException(SR.GetString(SR.PnrpNoClouds)); PnrpResolveExceptionTraceRecord record = new PnrpResolveExceptionTraceRecord(meshId, string.Empty, exception); TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.PnrpResolvedAddresses, SR.GetString(SR.TraceCodePnrpResolvedAddresses), record, this, null); } return new ReadOnlyCollection<PeerNodeAddress>(new List<PeerNodeAddress>()); } Exception lastException = null; foreach (UnsafePnrpNativeMethods.PeerNameResolver handle in resolvers) { try { handle.End(); } catch (SocketException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); lastException = e; } } List<PeerNodeAddress> nodeAddressList = new List<PeerNodeAddress>(); MergeResults(nodeAddressList, globalRegistrations, linkRegistrations, siteRegistrations); if ((lastException != null) && (nodeAddressList.Count == 0)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(lastException); if (DiagnosticUtility.ShouldTraceInformation) { PnrpPeerResolverTraceRecord record = new PnrpPeerResolverTraceRecord(meshId, nodeAddressList); TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PnrpResolvedAddresses, SR.GetString(SR.TraceCodePnrpResolvedAddresses), record, this, null); } return new ReadOnlyCollection<PeerNodeAddress>(nodeAddressList); }
public void SyncEnumeration(object state) { PnrpPeerResolver.UnsafePnrpNativeMethods.CriticalLookupHandle handle; int num = 0; PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySetSafe safeQuerySet = PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet.ToWsaQuerySetSafe(this.resolveQuery); using (safeQuerySet) { num = PnrpPeerResolver.UnsafePnrpNativeMethods.WSALookupServiceBegin(PnrpPeerResolver.UnsafePnrpNativeMethods.CriticalAllocHandleWsaQuerySetSafe.FromWsaQuerySetSafe(safeQuerySet), PnrpPeerResolver.UnsafePnrpNativeMethods.WsaNspControlFlags.ReturnAll, out handle); } if (num != 0) { this.lastException = new PnrpPeerResolver.PnrpException(PnrpPeerResolver.UnsafePnrpNativeMethods.WSAGetLastError(), this.resolveQuery.Context); Utility.CloseInvalidOutCriticalHandle(handle); base.Complete(false, this.lastException); } else { PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet set = new PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySet(); int size = Marshal.SizeOf(typeof(PnrpPeerResolver.UnsafePnrpNativeMethods.WsaQuerySetSafe)) + 400; CriticalAllocHandle handle3 = CriticalAllocHandle.FromSize(size); try { using (handle) { Label_0090: if (this.timeoutHelper.RemainingTime() != TimeSpan.Zero) { if (PnrpPeerResolver.UnsafePnrpNativeMethods.WSALookupServiceNext(handle, 0, ref size, (IntPtr) handle3) != 0) { int errorCode = PnrpPeerResolver.UnsafePnrpNativeMethods.WSAGetLastError(); switch (errorCode) { case 0x2776: case 0x277e: return; case 0x271e: handle3 = CriticalAllocHandle.FromSize(size); goto Label_0090; } PeerExceptionHelper.ThrowPnrpError(errorCode, set.Context); goto Label_0090; } if (handle3 == IntPtr.Zero) { goto Label_0090; } set = MarshalWsaQuerySetNativeToWsaQuerySet((IntPtr) handle3, this.scopeId); PnrpPeerResolver.PnrpRegistration item = new PnrpPeerResolver.PnrpRegistration { CloudName = set.Context, Comment = set.Comment, PeerName = set.ServiceInstanceName, Addresses = new IPEndPoint[set.CsAddrInfos.Length] }; for (int i = 0; i < set.CsAddrInfos.Length; i++) { item.Addresses[i] = set.CsAddrInfos[i].LocalAddr; } lock (this.results) { this.results.Add(item); goto Label_0090; } } } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); if (DiagnosticUtility.ShouldTraceInformation) { PnrpResolveExceptionTraceRecord extendedData = new PnrpResolveExceptionTraceRecord(this.resolveQuery.ServiceInstanceName, this.resolveQuery.Context, exception); if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, 0x4004b, System.ServiceModel.SR.GetString("TraceCodePnrpResolveException"), extendedData, this, null); } } this.lastException = exception; } finally { base.Complete(false, this.lastException); } } }
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); } }