You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			386 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			386 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|   | //------------------------------------------------------------ | ||
|  | // Copyright (c) Microsoft Corporation.  All rights reserved. | ||
|  | //------------------------------------------------------------ | ||
|  | 
 | ||
|  | namespace System.ServiceModel.Channels | ||
|  | { | ||
|  |     using System.Collections.ObjectModel; | ||
|  |     using System.Net; | ||
|  |     using System.Net.Security; | ||
|  |     using System.ServiceModel.Description; | ||
|  |     using System.ServiceModel; | ||
|  |     using System.ServiceModel.PeerResolvers; | ||
|  |     using System.Xml; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     static class PeerTransportPolicyConstants | ||
|  |     { | ||
|  |         public const string PeerTransportSecurityMode = "PeerTransportSecurityMode"; | ||
|  |         public const string PeerTransportCredentialType = "PeerTransportCredentialType"; | ||
|  |         public const string PeerTransportCredentialTypePassword = "PeerTransportCredentialTypePassword"; | ||
|  |         public const string PeerTransportCredentialTypeCertificate = "PeerTransportCredentialTypeCertificate"; | ||
|  |         public const string PeerTransportSecurityModeNone = "PeerTransportSecurityModeNone"; | ||
|  |         public const string PeerTransportSecurityModeTransport = "PeerTransportSecurityModeTransport"; | ||
|  |         public const string PeerTransportSecurityModeMessage = "PeerTransportSecurityModeMessage"; | ||
|  |         public const string PeerTransportSecurityModeTransportWithMessageCredential = "PeerTransportSecurityModeTransportWithMessageCredential"; | ||
|  |         public const string PeerTransportPrefix = "pc"; | ||
|  |     } | ||
|  | 
 | ||
|  |     [ObsoleteAttribute ("PeerChannel feature is obsolete and will be removed in the future.", false)] | ||
|  |     public sealed class PeerTransportBindingElement | ||
|  |         : TransportBindingElement, IWsdlExportExtension, ITransportPolicyImport, IPolicyExportExtension | ||
|  |     { | ||
|  |         IPAddress listenIPAddress; | ||
|  |         int port; | ||
|  |         PeerResolver resolver; | ||
|  |         bool resolverSet; | ||
|  |         PeerSecuritySettings peerSecurity; | ||
|  | 
 | ||
|  |         public PeerTransportBindingElement() | ||
|  |             : base() | ||
|  |         { | ||
|  |             this.listenIPAddress = PeerTransportDefaults.ListenIPAddress; | ||
|  |             this.port = PeerTransportDefaults.Port; | ||
|  |             if (PeerTransportDefaults.ResolverAvailable) | ||
|  |             { | ||
|  |                 this.resolver = PeerTransportDefaults.CreateResolver(); | ||
|  |             } | ||
|  |             peerSecurity = new PeerSecuritySettings(); | ||
|  |         } | ||
|  | 
 | ||
|  |         PeerTransportBindingElement(PeerTransportBindingElement elementToBeCloned) | ||
|  |             : base(elementToBeCloned) | ||
|  |         { | ||
|  |             this.listenIPAddress = elementToBeCloned.listenIPAddress; | ||
|  |             this.port = elementToBeCloned.port; | ||
|  |             this.resolverSet = elementToBeCloned.resolverSet; | ||
|  |             this.resolver = elementToBeCloned.resolver; | ||
|  |             peerSecurity = new PeerSecuritySettings(elementToBeCloned.Security); | ||
|  |         } | ||
|  | 
 | ||
|  |         public IPAddress ListenIPAddress | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return this.listenIPAddress; | ||
|  |             } | ||
|  | 
 | ||
|  |             set | ||
|  |             { | ||
|  |                 PeerValidateHelper.ValidateListenIPAddress(value); | ||
|  |                 this.listenIPAddress = value; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public override long MaxReceivedMessageSize | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return base.MaxReceivedMessageSize; | ||
|  |             } | ||
|  | 
 | ||
|  |             set | ||
|  |             { | ||
|  |                 PeerValidateHelper.ValidateMaxMessageSize(value); | ||
|  |                 base.MaxReceivedMessageSize = value; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public int Port | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return this.port; | ||
|  |             } | ||
|  | 
 | ||
|  |             set | ||
|  |             { | ||
|  |                 PeerValidateHelper.ValidatePort(value); | ||
|  |                 this.port = value; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         internal PeerResolver Resolver | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return this.resolver; | ||
|  |             } | ||
|  | 
 | ||
|  |             set | ||
|  |             { | ||
|  |                 if (value == null) | ||
|  |                 { | ||
|  |                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if (value.GetType() == PeerTransportDefaults.ResolverType) | ||
|  |                 { | ||
|  |                     if (!PeerTransportDefaults.ResolverInstalled) | ||
|  |                     { | ||
|  |                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.PeerPnrpNotInstalled)); | ||
|  |                     } | ||
|  |                     else if (!PeerTransportDefaults.ResolverAvailable) | ||
|  |                     { | ||
|  |                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.PeerPnrpNotAvailable)); | ||
|  |                     } | ||
|  |                 } | ||
|  | 
 | ||
|  |                 this.resolver = value; | ||
|  |                 this.resolverSet = true; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public override string Scheme { get { return PeerStrings.Scheme; } } | ||
|  | 
 | ||
|  |         public PeerSecuritySettings Security | ||
|  |         { | ||
|  |             get { return peerSecurity; } | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |         void ITransportPolicyImport.ImportPolicy(MetadataImporter importer, PolicyConversionContext context) | ||
|  |         { | ||
|  |             if (importer == null) | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("importer"); | ||
|  | 
 | ||
|  |             if (context == null) | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); | ||
|  | 
 | ||
|  |             peerSecurity.OnImportPolicy(importer, context); | ||
|  |         } | ||
|  | 
 | ||
|  |         void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext context) | ||
|  |         { | ||
|  |             if (exporter == null) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter"); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (context == null) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); | ||
|  |             } | ||
|  | 
 | ||
|  |             peerSecurity.OnExportPolicy(exporter, context); | ||
|  | 
 | ||
|  |             bool createdNew; | ||
|  |             MessageEncodingBindingElement encodingBindingElement = FindMessageEncodingBindingElement(context.BindingElements, out createdNew); | ||
|  |             if (createdNew && encodingBindingElement is IPolicyExportExtension) | ||
|  |             { | ||
|  |                 ((IPolicyExportExtension)encodingBindingElement).ExportPolicy(exporter, context); | ||
|  |             } | ||
|  | 
 | ||
|  |             WsdlExporter.WSAddressingHelper.AddWSAddressingAssertion(exporter, context, encodingBindingElement.MessageVersion.Addressing); | ||
|  |         } | ||
|  | 
 | ||
|  |         void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) { } | ||
|  | 
 | ||
|  |         void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext) | ||
|  |         { | ||
|  |             bool createdNew; | ||
|  |             MessageEncodingBindingElement encodingBindingElement = FindMessageEncodingBindingElement(endpointContext, out createdNew); | ||
|  |             TransportBindingElement.ExportWsdlEndpoint( | ||
|  |                 exporter, endpointContext, TransportPolicyConstants.PeerTransportUri, | ||
|  |                 encodingBindingElement.MessageVersion.Addressing); | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void CreateDefaultResolver(PeerResolverSettings settings) | ||
|  |         { | ||
|  |             if (PeerTransportDefaults.ResolverAvailable) | ||
|  |             { | ||
|  |                 this.resolver = new PnrpPeerResolver(settings.ReferralPolicy); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         MessageEncodingBindingElement FindMessageEncodingBindingElement(BindingElementCollection bindingElements, out bool createdNew) | ||
|  |         { | ||
|  |             createdNew = false; | ||
|  |             MessageEncodingBindingElement encodingBindingElement = bindingElements.Find<MessageEncodingBindingElement>(); | ||
|  |             if (encodingBindingElement == null) | ||
|  |             { | ||
|  |                 createdNew = true; | ||
|  |                 encodingBindingElement = new BinaryMessageEncodingBindingElement(); | ||
|  |             } | ||
|  |             return encodingBindingElement; | ||
|  |         } | ||
|  | 
 | ||
|  |         MessageEncodingBindingElement FindMessageEncodingBindingElement(WsdlEndpointConversionContext endpointContext, out bool createdNew) | ||
|  |         { | ||
|  |             BindingElementCollection bindingElements = endpointContext.Endpoint.Binding.CreateBindingElements(); | ||
|  |             return FindMessageEncodingBindingElement(bindingElements, out createdNew); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context) | ||
|  |         { | ||
|  |             if (context == null) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("context")); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (!this.CanBuildChannelFactory<TChannel>(context)) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel))); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (this.ManualAddressing) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ManualAddressingNotSupported))); | ||
|  |             } | ||
|  | 
 | ||
|  |             PeerResolver peerResolver = GetResolver(context); | ||
|  |             return new PeerChannelFactory<TChannel>(this, context, peerResolver); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) | ||
|  |         { | ||
|  |             if (context == null) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); | ||
|  |             } | ||
|  | 
 | ||
|  |             PeerChannelListenerBase peerListener = null; | ||
|  |             PeerResolver peerResolver = GetResolver(context); | ||
|  |             if (typeof(TChannel) == typeof(IInputChannel)) | ||
|  |             { | ||
|  |                 peerListener = new PeerInputChannelListener(this, context, peerResolver); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IDuplexChannel)) | ||
|  |             { | ||
|  |                 peerListener = new PeerDuplexChannelListener(this, context, peerResolver); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TChannel", SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel))); | ||
|  |             } | ||
|  | 
 | ||
|  |             return (IChannelListener<TChannel>)peerListener; | ||
|  |         } | ||
|  | 
 | ||
|  |         public override bool CanBuildChannelFactory<TChannel>(BindingContext context) | ||
|  |         { | ||
|  |             return (typeof(TChannel) == typeof(IOutputChannel) | ||
|  |                 || typeof(TChannel) == typeof(IDuplexChannel)); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override bool CanBuildChannelListener<TChannel>(BindingContext context) | ||
|  |         { | ||
|  |             return (typeof(TChannel) == typeof(IInputChannel) | ||
|  |                 || typeof(TChannel) == typeof(IDuplexChannel)); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override BindingElement Clone() | ||
|  |         { | ||
|  |             return new PeerTransportBindingElement(this); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override T GetProperty<T>(BindingContext context) | ||
|  |         { | ||
|  |             if (context == null) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); | ||
|  |             } | ||
|  |             if (typeof(T) == typeof(IBindingMulticastCapabilities)) | ||
|  |             { | ||
|  |                 return (T)(object)new BindingMulticastCapabilities(); | ||
|  |             } | ||
|  |             else if (typeof(T) == typeof(ISecurityCapabilities)) | ||
|  |             { | ||
|  |                 return (T)(object)new SecurityCapabilities(Security.SupportsAuthentication, Security.SupportsAuthentication, | ||
|  |                     false, Security.SupportedProtectionLevel, Security.SupportedProtectionLevel); | ||
|  |             } | ||
|  |             else if (typeof(T) == typeof(IBindingDeliveryCapabilities)) | ||
|  |             { | ||
|  |                 return (T)(object)new BindingDeliveryCapabilitiesHelper(); | ||
|  |             } | ||
|  | 
 | ||
|  |             return base.GetProperty<T>(context); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Return the resolver member (if set) or create one from the resolver binding element in the context | ||
|  |         PeerResolver GetResolver(BindingContext context) | ||
|  |         { | ||
|  |             if (this.resolverSet) | ||
|  |             { | ||
|  |                 return this.resolver; | ||
|  |             } | ||
|  | 
 | ||
|  |             Collection<PeerCustomResolverBindingElement> customResolverElements | ||
|  |                 = context.BindingParameters.FindAll<PeerCustomResolverBindingElement>(); | ||
|  | 
 | ||
|  |             if (customResolverElements.Count > 1) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultiplePeerCustomResolverBindingElementsInParameters))); | ||
|  |             } | ||
|  |             else if (customResolverElements.Count == 1) | ||
|  |             { | ||
|  |                 context.BindingParameters.Remove<PeerCustomResolverBindingElement>(); | ||
|  |                 return customResolverElements[0].CreatePeerResolver(); | ||
|  |             } | ||
|  | 
 | ||
|  | 
 | ||
|  |             // If resolver binding element is included in the context, use it to create the resolver. elementToBeClonedwise, | ||
|  |             // if default resolver is available, use it. | ||
|  |             Collection<PeerResolverBindingElement> resolverBindingElements | ||
|  |                 = context.BindingParameters.FindAll<PeerResolverBindingElement>(); | ||
|  | 
 | ||
|  |             if (resolverBindingElements.Count > 1) | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultiplePeerResolverBindingElementsinParameters))); | ||
|  |             } | ||
|  |             else if (resolverBindingElements.Count == 0) | ||
|  |             { | ||
|  |                 if (this.resolver != null)  // default resolver available? | ||
|  |                 { | ||
|  |                     return this.resolver; | ||
|  |                 } | ||
|  |                 else | ||
|  |                 { | ||
|  |                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( | ||
|  |                         new InvalidOperationException(SR.GetString(SR.PeerResolverBindingElementRequired, context.Binding.Name))); | ||
|  |                 } | ||
|  |             } | ||
|  |             else if (resolverBindingElements[0].GetType() == PeerTransportDefaults.ResolverBindingElementType) | ||
|  |             { | ||
|  |                 if (!PeerTransportDefaults.ResolverInstalled) | ||
|  |                 { | ||
|  |                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( | ||
|  |                         new InvalidOperationException(SR.GetString(SR.PeerPnrpNotInstalled))); | ||
|  |                 } | ||
|  |                 else if (!PeerTransportDefaults.ResolverAvailable) | ||
|  |                 { | ||
|  |                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( | ||
|  |                         new InvalidOperationException(SR.GetString(SR.PeerPnrpNotAvailable))); | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             context.BindingParameters.Remove<PeerResolverBindingElement>(); | ||
|  |             return resolverBindingElements[0].CreatePeerResolver(); | ||
|  |         } | ||
|  | 
 | ||
|  |         class BindingMulticastCapabilities : IBindingMulticastCapabilities | ||
|  |         { | ||
|  |             public bool IsMulticast { get { return true; } } | ||
|  |         } | ||
|  | 
 | ||
|  |         class BindingDeliveryCapabilitiesHelper : IBindingDeliveryCapabilities | ||
|  |         { | ||
|  |             internal BindingDeliveryCapabilitiesHelper() | ||
|  |             { | ||
|  |             } | ||
|  |             bool IBindingDeliveryCapabilities.AssuresOrderedDelivery | ||
|  |             { | ||
|  |                 get { return false; } | ||
|  |             } | ||
|  | 
 | ||
|  |             bool IBindingDeliveryCapabilities.QueuedDelivery | ||
|  |             { | ||
|  |                 get { return false; } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |     } | ||
|  | } |