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); }