You've already forked linux-packaging-mono
acceptance-tests
data
debian
docs
external
ikvm-native
libgc
llvm
m4
man
mcs
build
class
Accessibility
Commons.Xml.Relaxng
Cscompmgd
CustomMarshalers
Facades
I18N
IBM.Data.DB2
ICSharpCode.SharpZipLib
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Tasks
Microsoft.Build.Utilities
Microsoft.CSharp
Microsoft.NuGet.Build.Tasks
Microsoft.VisualC
Microsoft.Web.Infrastructure
MicrosoftAjaxLibrary
Mono.Btls.Interface
Mono.C5
Mono.CSharp
Mono.Cairo
Mono.Cecil
Mono.Cecil.Mdb
Mono.CodeContracts
Mono.CompilerServices.SymbolWriter
Mono.Data.Sqlite
Mono.Data.Tds
Mono.Debugger.Soft
Mono.Http
Mono.Management
Mono.Messaging
Mono.Messaging.RabbitMQ
Mono.Options
Mono.Parallel
Mono.Posix
Mono.Profiler.Log
Mono.Runtime.Tests
Mono.Security
Mono.Security.Win32
Mono.Simd
Mono.Tasklets
Mono.WebBrowser
Mono.XBuild.Tasks
Novell.Directory.Ldap
PEAPI
RabbitMQ.Client
SMDiagnostics
System
System.ComponentModel.Composition.4.5
System.ComponentModel.DataAnnotations
System.Configuration
System.Configuration.Install
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Linq
System.Data.OracleClient
System.Data.Services
System.Data.Services.Client
System.Deployment
System.Design
System.DirectoryServices
System.DirectoryServices.Protocols
System.Drawing
System.Drawing.Design
System.Dynamic
System.EnterpriseServices
System.IO.Compression
System.IO.Compression.FileSystem
System.IdentityModel
System.IdentityModel.Selectors
System.Json
System.Json.Microsoft
System.Management
System.Messaging
System.Net
System.Net.Http
System.Net.Http.Formatting
System.Net.Http.WebRequest
System.Net.Http.WinHttpHandler
System.Numerics
System.Numerics.Vectors
System.Reactive.Core
System.Reactive.Debugger
System.Reactive.Experimental
System.Reactive.Interfaces
System.Reactive.Linq
System.Reactive.Observable.Aliases
System.Reactive.PlatformServices
System.Reactive.Providers
System.Reactive.Runtime.Remoting
System.Reactive.Windows.Forms
System.Reactive.Windows.Threading
System.Reflection.Context
System.Runtime.Caching
System.Runtime.CompilerServices.Unsafe
System.Runtime.DurableInstancing
System.Runtime.Remoting
System.Runtime.Serialization
System.Runtime.Serialization.Formatters.Soap
System.Security
System.ServiceModel
System.ServiceModel.Activation
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.Web
System.ServiceProcess
System.Threading.Tasks.Dataflow
System.Transactions
System.Web
System.Web.Abstractions
System.Web.ApplicationServices
System.Web.DynamicData
System.Web.Extensions
System.Web.Extensions.Design
System.Web.Http
System.Web.Http.SelfHost
System.Web.Http.WebHost
System.Web.Mobile
System.Web.Mvc3
System.Web.Razor
System.Web.RegularExpressions
System.Web.Routing
System.Web.Services
System.Web.WebPages
System.Web.WebPages.Deployment
System.Web.WebPages.Razor
System.Windows
System.Windows.Forms
System.Windows.Forms.DataVisualization
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.XML
System.Xaml
System.Xml.Linq
System.Xml.Serialization
SystemWebTestShim
WebMatrix.Data
WindowsBase
aot-compiler
corlib
dlr
doc
legacy
lib
monodoc
notes
reference-assemblies
referencesource
SMDiagnostics
System
System.Activities
System.Activities.Core.Presentation
System.Activities.DurableInstancing
System.Activities.Presentation
System.ComponentModel.DataAnnotations
System.Configuration
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Entity.Design
System.Data.Linq
System.Data.SqlXml
System.IdentityModel
System.IdentityModel.Selectors
System.Net
System.Numerics
System.Runtime.Caching
System.Runtime.DurableInstancing
System.Runtime.Serialization
System.ServiceModel
InternalApis
Serialization
System
Collections
ServiceModel
Activation
Administration
Channels
AddressHeader.cs
AddressHeaderCollection.cs
Addressing.cs
AddressingVersion.cs
AppContainerInfo.cs
ApplicationContainerSettings.cs
AsymmetricSecurityBindingElement.cs
AuthenticationSchemesBindingParameter.cs
AuthenticationSchemesHelper.cs
BaseUriWithWildcard.cs
BinaryMessageEncoder.cs
BinaryMessageEncodingBindingElement.cs
BinaryVersion.cs
Binding.cs
BindingContext.cs
BindingElement.cs
BindingElementCollection.cs
BindingParameterCollection.cs
BodyWriter.cs
BufferManager.cs
BufferManagerOutputStream.cs
BufferedConnection.cs
BufferedMessageData.cs
BufferedMessageWriter.cs
BufferedOutputAsyncStream.cs
BufferedReceiveMessageProperty.cs
BufferedRequestContext.cs
CallbackContextMessageHeader.cs
CallbackContextMessageProperty.cs
ChainedAsyncResult.cs
ChannelAcceptor.cs
ChannelBase.cs
ChannelBindingMessageProperty.cs
ChannelBindingProviderHelper.cs
ChannelBindingUtility.cs
ChannelBuilder.cs
ChannelDemuxer.cs.REMOVED.git-id
ChannelFactoryBase.cs
ChannelListenerBase.cs
ChannelManagerBase.cs
ChannelParameterCollection.cs
ChannelPool.cs
ChannelPoolSettings.cs
ChannelReliableSession.cs
ChannelRequirements.cs
ChannelTracker.cs
ClientContextProtocol.cs
ClientReliableChannelBinder.cs
ClientWebSocketFactory.cs
ClientWebSocketTransportDuplexSessionChannel.cs
CloseCollectionAsyncResult.cs
CloseSequence.cs
CloseSequenceResponse.cs
CommunicationObject.cs
CommunicationObjectManager.cs
CompositeDuplexBindingElement.cs
CompositeDuplexBindingElementImporter.cs
CompressionFormat.cs
CompressionFormatHelper.cs
ConnectAlgorithms.cs
Connection.cs
ConnectionAcceptor.cs
ConnectionBufferPool.cs
ConnectionDemuxer.cs
ConnectionDumpInitiator.cs
ConnectionModeReader.cs
ConnectionOrientedTransportBindingElement.cs
ConnectionOrientedTransportChannelFactory.cs
ConnectionOrientedTransportChannelListener.cs
ConnectionOrientedTransportManager.cs
ConnectionPool.cs
ConnectionPoolRegistry.cs
ContentOnlyMessage.cs
ContextAddressHeader.cs
ContextBindingElement.cs
ContextBindingElementImporter.cs
ContextBindingElementPolicy.cs
ContextChannelFactory.cs
ContextChannelListener.cs
ContextChannelRequestContext.cs
ContextDictionary.cs
ContextDuplexSessionChannel.cs
ContextExchangeCorrelationHelper.cs
ContextExchangeMechanism.cs
ContextExchangeMechanismHelper.cs
ContextInputChannel.cs
ContextInputChannelBase.cs
ContextInputSessionChannel.cs
ContextMessageHeader.cs
ContextMessageProperty.cs
ContextOutputChannel.cs
ContextOutputChannelBase.cs
ContextOutputSessionChannel.cs
ContextProtocol.cs
ContextReplyChannel.cs
ContextReplySessionChannel.cs
ContextRequestChannel.cs
ContextRequestChannelBase.cs
ContextRequestSessionChannel.cs
CorrelationCallbackMessageProperty.cs
CorrelationDataDescription.cs
CorrelationDataMessageProperty.cs
CorrelationDataSourceHelper.cs
CorrelationKey.cs
CorrelationMessageProperty.cs
CreateSequence.cs
CreateSequenceResponse.cs
CustomBinding.cs
DatagramAdapter.cs
DefaultWebSocketConnectionHandler.cs
DelegatingChannelListener.cs
DelegatingMessage.cs
DelegatingStream.cs
DeliveryFailure.cs
DeliveryStatus.cs
DeliveryStrategy.cs
DetectEofStream.cs
DirectionalAction.cs
DnsCache.cs
DoneReceivingAsyncResult.cs
DuplexChannel.cs
EncoderHelpers.cs
EndpointSettings.cs
ExclusiveNamedPipeTransportManager.cs
ExclusiveTcpTransportManager.cs
FaultConverter.cs
FramingChannels.cs
FramingDecoders.cs
FramingEncoders.cs
FramingFormat.cs
HttpAnonymousUriPrefixMatcher.cs
HttpChannelFactory.cs
HttpChannelHelpers.cs.REMOVED.git-id
HttpChannelListener.cs
HttpCookieContainerBindingElement.cs
HttpCookieContainerManager.cs
HttpHeaderInfo.cs
HttpHeadersWebHeaderCollection.cs
HttpMessageHandlerFactory.cs
HttpMessageSettings.cs
HttpPipeline.cs
HttpPipelineCancellationTokenSource.cs
HttpRequestContext.cs
HttpRequestMessageExtensionMethods.cs
HttpRequestMessageProperty.cs
HttpResponseMessageExtensionMethods.cs
HttpResponseMessageProperty.cs
HttpTransportBindingElement.cs
HttpTransportManager.cs
HttpsChannelFactory.cs
HttpsChannelListener.cs
HttpsTransportBindingElement.cs
IAnonymousUriPrefixMatcher.cs
IBindingDeliveryCapabilities.cs
IBindingMulticastCapabilities.cs
IBindingRuntimePreferences.cs
IChannel.cs
IChannelAcceptor.cs
IChannelBindingProvider.cs
IChannelFactory.cs
IChannelListener.cs
ICompressedMessageEncoder.cs
IContextBindingElement.cs
IContextManager.cs
ICorrelationDataSource.cs
ICorrelatorKey.cs
IDuplexChannel.cs
IDuplexSession.cs
IDuplexSessionChannel.cs
IHttpCookieContainerManager.cs
IInputChannel.cs
IInputSession.cs
IInputSessionChannel.cs
ILockingQueue.cs
IMergeEnabledMessageProperty.cs
IMessageProperty.cs
IMessageSource.cs
IOutputChannel.cs
IOutputSession.cs
IOutputSessionChannel.cs
IPeerNeighbor.cs
IPoisonHandlingStrategy.cs
IReceiveContextSettings.cs
IReliableChannelBinder.cs
IReliableFactorySettings.cs
IReplyChannel.cs
IReplySessionChannel.cs
IRequestChannel.cs
IRequestReplyCorrelator.cs
IRequestSessionChannel.cs
ISecurityCapabilities.cs
ISession.cs
ISessionChannel.cs
IStreamUpgradeChannelBindingProvider.cs
IStreamedMessageEncoder.cs
ITransactedBindingElement.cs
ITransactionChannelManager.cs
ITransportCompressionSupport.cs
ITransportFactorySettings.cs
ITransportTokenAssertionProvider.cs
IWebMessageEncoderHelper.cs
IWebsocketCloseDetails.cs
IdlingCommunicationPool.cs
InitialServerConnectionReader.cs
InputChannel.cs
InputChannelAcceptor.cs
InputQueueChannel.cs
InputQueueChannelAcceptor.cs
InternalDuplexBindingElement.cs
InternalDuplexChannelFactory.cs
InternalDuplexChannelListener.cs
InvalidChannelBindingException.cs
LateBoundChannelParameterCollection.cs
LayeredChannel.cs
LayeredChannelFactory.cs
LayeredChannelListener.cs
LifetimeManager.cs
LocalClientSecuritySettings.cs
LocalServiceSecuritySettings.cs
LockHelper.cs
MaxMessageSizeStream.cs
Message.cs
MessageBuffer.cs
MessageEncoder.cs
MessageEncoderCompressionHandler.cs
MessageEncoderFactory.cs
MessageEncodingBindingElement.cs
MessageEncodingBindingElementImporter.cs
MessageFault.cs
MessageHeader.cs
MessageHeaderInfo.cs
MessageHeaders.cs
MessageProperties.cs
MessageState.cs
MessageVersion.cs
Msmq.cs
Msmq3PoisonHandler.cs
Msmq4PoisonHandler.cs
Msmq4SubqueuePoisonHandler.cs
MsmqBindingElementBase.cs
MsmqBindingFilter.cs
MsmqBindingMonitor.cs
MsmqChannelFactory.cs
MsmqChannelFactoryBase.cs
MsmqChannelListenerBase.cs
MsmqDecodeHelper.cs
MsmqDefaultLockingQueue.cs
MsmqDiagnostics.cs
MsmqInputChannel.cs
MsmqInputChannelBase.cs
MsmqInputChannelListener.cs
MsmqInputChannelListenerBase.cs
MsmqInputMessage.cs
MsmqInputMessagePool.cs
MsmqInputSessionChannel.cs
MsmqInputSessionChannelListener.cs
MsmqMessageProperty.cs
MsmqNonTransactedPoisonHandler.cs
MsmqOutputChannel.cs
MsmqOutputMessage.cs
MsmqOutputSessionChannel.cs
MsmqQueue.cs
MsmqReceiveContext.cs
MsmqReceiveContextLockManager.cs
MsmqReceiveHelper.cs
MsmqReceiveParameters.cs
MsmqSubqueueLockingQueue.cs
MsmqTransportBindingElement.cs
MsmqTransportReceiveParameters.cs
MsmqUri.cs
MsmqVerifier.cs
MtomMessageEncoder.cs
MtomMessageEncodingBindingElement.cs
NamedPipeChannelFactory.cs
NamedPipeChannelListener.cs
NamedPipeConnectionPool.cs
NamedPipeConnectionPoolSettings.cs
NamedPipeSettings.cs
NamedPipeTransportBindingElement.cs
NamedPipeTransportManager.cs
NativeMsmqMessage.cs
OneWayBindingElement.cs
OneWayBindingElementImporter.cs
OneWayChannelFactory.cs
OneWayChannelListener.cs
OpaqueContent.cs
OpenCollectionAsyncResult.cs
OutputChannel.cs
OverlappedContext.cs
PeerChannelFactory.cs
PeerChannelListener.cs
PeerConnector.cs
PeerCustomResolverBindingElement.cs
PeerDuplexChannel.cs
PeerDuplexChannelListener.cs
PeerFlooder.cs
PeerHelpers.cs
PeerIPHelper.cs
PeerInputChannel.cs
PeerInputChannelListener.cs
PeerMaintainer.cs
PeerMessageDispatcher.cs
PeerNeighborManager.cs
PeerNodeImplementation.cs
PeerNodeStateManager.cs
PeerOutputChannel.cs
PeerResolverBindingElement.cs
PeerSecurityHelpers.cs
PeerSecurityManager.cs
PeerService.cs
PeerServiceMessageContracts.cs
PeerTransportBindingElement.cs
PeerUnsafeNativeCryptMethods.cs
PeerUnsafeNativeMethods.cs
PipeConnection.cs.REMOVED.git-id
PipeException.cs
PnrpPeerResolver.cs.REMOVED.git-id
PnrpPeerResolverBindingElement.cs
PrivacyNoticeBindingElement.cs
PrivacyNoticeBindingElementImporter.cs
QueuedObjectPool.cs
ReceiveContext.cs
ReceiveContextState.cs
RedirectionConstants.cs
RedirectionDuration.cs
RedirectionException.cs
RedirectionLocation.cs
RedirectionScope.cs
RedirectionType.cs
RedirectionUtility.cs
ReliableChannelBinder.cs.REMOVED.git-id
ReliableChannelFactory.cs
ReliableChannelListener.cs
ReliableDuplexSessionChannel.cs
ReliableInputConnection.cs
ReliableInputSessionChannel.cs
ReliableMessagingHelpers.cs.REMOVED.git-id
ReliableOutputConnection.cs
ReliableOutputSessionChannel.cs
ReliableReplySessionChannel.cs
ReliableRequestSessionChannel.cs
ReliableSessionBindingElement.cs
ReliableSessionBindingElementImporter.cs
RemoteEndpointMessageProperty.cs
ReplyAdapterChannelListener.cs
ReplyChannel.cs
ReplyChannelAcceptor.cs
RequestChannel.cs
RequestContext.cs
RequestContextBase.cs
RequestReplyCorrelator.cs
RetryException.cs
SafeNativeMethods.cs
SecurityAttributeGenerationHelper.cs
SecurityBindingElement.cs.REMOVED.git-id
SecurityBindingElementImporter.cs
SecurityCapabilities.cs
SecurityChannelFactory.cs
SecurityChannelFaultConverter.cs
SecurityChannelListener.cs
SecurityHeaderLayout.cs
SelfSignedCertificate.cs
SequenceRange.cs
SequenceRangeCollection.cs
ServerReliableChannelBinder.cs
ServerWebSocketTransportDuplexSessionChannel.cs
ServiceChannel.cs
ServiceChannelFactory.cs
ServiceChannelProxy.cs
ServiceContextProtocol.cs
ServiceWebSocketContext.cs
SessionConnectionReader.cs
SessionOpenNotification.cs
SharedConnectionListener.cs
SharedHttpTransportManager.cs
SharedHttpsTransportManager.cs
SharedTcpTransportManager.cs
SingletonChannelAcceptor.cs
SingletonConnectionReader.cs
SocketAsyncEventArgsPool.cs
SocketConnection.cs
SslStreamSecurityBindingElement.cs
SslStreamSecurityUpgradeProvider.cs
StandardBindingImporter.cs
StreamSecurityUpgradeAcceptor.cs
StreamSecurityUpgradeAcceptorAsyncResult.cs
StreamSecurityUpgradeAcceptorBase.cs
StreamSecurityUpgradeInitiator.cs
StreamSecurityUpgradeInitiatorAsyncResult.cs
StreamSecurityUpgradeInitiatorBase.cs
StreamSecurityUpgradeProvider.cs
StreamUpgradeAcceptor.cs
StreamUpgradeBindingElement.cs
StreamUpgradeInitiator.cs
StreamUpgradeProvider.cs
StreamedFramingRequestChannel.cs
SupportedAddressingMode.cs
SymmetricSecurityBindingElement.cs
SynchronizedMessageSource.cs
TcpChannelFactory.cs
TcpChannelListener.cs
TcpConnectionPool.cs
TcpConnectionPoolSettings.cs
TcpTransportBindingElement.cs
TcpTransportManager.cs
TerminateSequence.cs
TerminateSequenceResponse.cs
TextMessageEncoder.cs
TextMessageEncodingBindingElement.cs
TimeoutStream.cs
TracingConnection.cs
TracingConnectionInitiator.cs
TracingConnectionListener.cs
TransactionChannel.cs
TransactionChannelFactory.cs
TransactionChannelFaultConverter.cs
TransactionChannelListener.cs
TransactionFlowBindingElement.cs
TransactionFlowBindingElementImporter.cs
TransactionFlowProperty.cs
TransferSession.cs
TransmissionStrategy.cs
TransportBindingElement.cs
TransportBindingElementImporter.cs
TransportChannelFactory.cs
TransportChannelListener.cs
TransportDefaults.cs
TransportDuplexSessionChannel.cs
TransportManager.cs
TransportOutputChannel.cs
TransportReplyChannelAcceptor.cs
TransportSecurityBindingElement.cs
TransportSecurityHelpers.cs
UnderstoodHeaders.cs
UniqueTransportManagerRegistration.cs
UnrecognizedAssertionsBindingElement.cs
UnsafeNativeMethods.cs
UriGenerator.cs
UriHelper.cs
UriPrefixTable.cs
UseManagedPresentationBindingElement.cs
UseManagedPresentationBindingElementImporter.cs
UtilityExtension.cs
WebSocketConnectionHandler.cs
WebSocketHelper.cs
WebSocketMessageProperty.cs
WebSocketTransportDuplexSessionChannel.cs
WebSocketTransportSettings.cs
WebSocketTransportUsage.cs
WebSocketTransportUsageHelper.cs
WindowsStreamSecurityBindingElement.cs
WindowsStreamSecurityUpgradeProvider.cs
WrappedOptions.cs
WsrmFault.cs
WsrmMessageInfo.cs
XmlSerializerImportOptions.cs
ComIntegration
Configuration
Description
Diagnostics
Dispatcher
MsmqIntegration
PeerResolvers
Security
Syndication
Transactions
XamlIntegration
ActionMismatchAddressingException.cs
ActionNotSupportedException.cs
AddressAccessDeniedException.cs
AddressAlreadyInUseException.cs
AddressFilterMode.cs
AppContextDefaultValues.Default.cs
AuditLevel.cs
AuditLogLocation.cs
BasicHttpBinding.cs
BasicHttpContextBinding.cs
BasicHttpMessageCredentialType.cs
BasicHttpMessageSecurity.cs
BasicHttpSecurity.cs
BasicHttpSecurityMode.cs
BasicHttpsBinding.cs
BasicHttpsSecurity.cs
BasicHttpsSecurityMode.cs
CacheSetting.cs
CallbackBehaviorAttribute.cs
ChannelFactory.cs
ChannelFactoryRefCache.cs
ChannelTerminatedException.cs
ClientBase.cs
CommunicationException.cs
CommunicationObjectAbortedException.cs
CommunicationObjectFaultedException.cs
CommunicationState.cs
ConcurrencyMode.cs
ConfigurationEndpointTrait.cs
DXD.cs
DataContractFormatAttribute.cs
DeadLetterQueue.cs
DeliveryRequirementsAttribute.cs
DnsEndpointIdentity.cs
DuplexChannelFactory.cs
DuplexClientBase.cs
EmptyArray.cs
EndpointAddress.cs
EndpointAddress10.cs
EndpointAddressAugust2004.cs
EndpointIdentity.cs
EndpointNotFoundException.cs
EndpointTrait.cs
EnvelopeVersion.cs
ExceptionDetail.cs
ExceptionMapper.cs
ExtensionCollection.cs
FaultCode.cs
FaultCodeConstants.cs
FaultContractAttribute.cs
FaultException.cs
FaultImportOptions.cs
FaultReason.cs
FaultReasonText.cs
FederatedMessageSecurityOverHttp.cs
GeneralEndpointIdentity.cs
HostnameComparisonMode.cs
HttpBindingBase.cs
HttpClientCredentialType.cs
HttpProxyCredentialType.cs
HttpTransportSecurity.cs
IChannelBaseProxy.cs
IClientChannel.cs
ICommunicationObject.cs
IContextChannel.cs
IContextSessionProvider.cs
IDefaultCommunicationTimeouts.cs
IDuplexContextChannel.cs
IExtensibleObject.cs
IExtension.cs
IExtensionCollection.cs
IOnlineStatus.cs
IOperationContractAttributeProvider.cs
IServiceChannel.cs
ImpersonationOption.cs
InstanceContext.cs
InstanceContextMode.cs
InvalidMessageContractException.cs
KeyedByTypeCollection.cs
LocalAppContextSwitches.cs
MessageBodyMemberAttribute.cs
MessageContractAttribute.cs
MessageContractMemberAttribute.cs
MessageCredentialType.cs
MessageHeaderArrayAttribute.cs
MessageHeaderAttribute.cs
MessageHeaderException.cs
MessageHeaderT.cs
MessageParameterAttribute.cs
MessagePropertyAttribute.cs
MessageSecurityOverHttp.cs
MessageSecurityOverMsmq.cs
MessageSecurityOverTcp.cs
MessageSecurityVersion.cs
MostlySingletonList.cs
MsmqAuthenticationMode.cs
MsmqBindingBase.cs
MsmqEncryptionAlgorithm.cs
MsmqException.cs
MsmqPoisonMessageException.cs
MsmqSecureHashAlgorithm.cs
MsmqTransportSecurity.cs
MustUnderstandSoapException.cs
NamedPipeTransportSecurity.cs
NetHttpBinding.cs
NetHttpMessageEncoding.cs
NetHttpMessageEncodingHelper.cs
NetHttpsBinding.cs
NetMsmqBinding.cs
NetMsmqSecurity.cs
NetMsmqSecurityMode.cs
NetNamedPipeBinding.cs
NetNamedPipeSecurity.cs
NetNamedPipeSecurityMode.cs
NetPeerTcpBinding.cs
NetTcpBinding.cs
NetTcpContextBinding.cs
NetTcpSecurity.cs
NonDualMessageSecurityOverHttp.cs
OSEnvironmentHelper.cs
OSVersion.cs
OperationBehaviorAttribute.cs
OperationContext.cs
OperationContextScope.cs
OperationContractAttribute.cs
OperationFormatStyle.cs
OperationFormatUse.cs
PeerHopCountAttribute.cs
PeerMessageOrigination.cs
PeerMessagePropagation.cs
PeerMessagePropagationFilter.cs
PeerNode.cs
PeerNodeAddress.cs
PeerResolver.cs
PeerSecuritySettings.cs
PeerTransportCredentialType.cs
PeerTransportSecuritySettings.cs
PoisonMessageException.cs
Pool.cs
ProgrammaticEndpointTrait.cs
ProtocolException.cs
QueueTransferProtocol.cs
QueuedDeliveryRequirementsMode.cs
QuotaExceededException.cs
ReceiveContextEnabledAttribute.cs
ReceiveErrorHandling.cs
ReleaseInstanceMode.cs
ReliableMessagingVersion.cs
ReliableSession.cs
RsaEndpointIdentity.cs
SecurityMode.cs
ServerTooBusyException.cs
ServiceActivationException.cs
ServiceAuthenticationManager.cs
ServiceAuthorizationManager.cs
ServiceBehaviorAttribute.cs
ServiceChannelManager.cs
ServiceConfiguration.cs
ServiceContractAttribute.cs
ServiceDefaults.cs
ServiceEndpointTrait.cs
ServiceHost.cs
ServiceKnownTypeAttribute.cs
ServiceModelAppSettings.cs
ServiceModelAttributeTargets.cs
ServiceModelDictionary.cs
ServiceModelStrings.cs
ServiceModelStringsVersion1.cs
ServiceSecurityContext.cs
SessionMode.cs
SpnEndpointIdentity.cs
StringUtil.cs
SynchronizedCollection.cs
SynchronizedDisposablePool.cs
SynchronizedKeyedCollection.cs
SynchronizedReadOnlyCollection.cs
TcpClientCredentialType.cs
TcpTransportSecurity.cs
ThreadTrace.cs
TimeSpanHelper.cs
TransactionFlowAttribute.cs
TransactionFlowOption.cs
TransactionProtocol.cs
TransferMode.cs
UnifiedSecurityMode.cs
UnknownMessageReceivedEventArgs.cs
UpnEndpointIdentity.cs
UriSchemeKeyedCollection.cs
WS2007FederationHttpBinding.cs
WS2007HttpBinding.cs
WSAddressing10ProblemHeaderQNameFault.cs
WSDualHttpBinding.cs
WSDualHttpSecurity.cs
WSDualHttpSecurityMode.cs
WSFederationHttpBinding.cs
WSFederationHttpSecurity.cs
WSFederationHttpSecurityMode.cs
WSHttpBinding.cs
WSHttpBindingBase.cs
WSHttpContextBinding.cs
WSHttpSecurity.cs
WSMessageEncoding.cs
WrappedDispatcherException.cs
X509CertificateEndpointIdentity.cs
XD.cs.REMOVED.git-id
XPathMessageQuery.cs
XmlBuffer.cs
XmlSerializerFormatAttribute.cs
XmlUtil.cs
UriTemplate.cs
UriTemplateCompoundPathSegment.cs
UriTemplateEquivalenceComparer.cs
UriTemplateHelpers.cs
UriTemplateLiteralPathSegment.cs
UriTemplateLiteralQueryValue.cs
UriTemplateMatch.cs
UriTemplateMatchException.cs
UriTemplatePartType.cs
UriTemplatePathPartiallyEquivalentSet.cs
UriTemplatePathSegment.cs
UriTemplateQueryValue.cs
UriTemplateTable.cs
UriTemplateTableMatchCandidate.cs
UriTemplateTrieIntraNodeLocation.cs
UriTemplateTrieLocation.cs
UriTemplateTrieNode.cs
UriTemplateVariablePathSegment.cs
UriTemplateVariableQueryValue.cs
AssemblyInfo.cs
System.ServiceModel.txt.REMOVED.git-id
TD.Designer.cs.REMOVED.git-id
System.ServiceModel.Activation
System.ServiceModel.Activities
System.ServiceModel.Channels
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.WasHosting
System.ServiceModel.Web
System.Web
System.Web.ApplicationServices
System.Web.DataVisualization
System.Web.DynamicData
System.Web.Entity
System.Web.Entity.Design
System.Web.Extensions
System.Web.Mobile
System.Web.Routing
System.Web.Services
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.WorkflowServices
System.Xaml.Hosting
System.Xml
System.Xml.Linq
XamlBuildTask
mscorlib
LICENSE.txt
PATENTS.TXT
README.Mono.md
README.md
test-helpers
LICENSE
Makefile
Open.snk
README
ecma.pub
mono.pub
mono.snk
msfinal.pub
reactive.pub
silverlight.pub
winfx.pub
winfx3.pub
docs
errors
ilasm
jay
mcs
packages
tests
tools
AUTHORS
COPYING
INSTALL.txt
Makefile
MonoIcon.png
README
ScalableMonoIcon.svg
mkinstalldirs
mk
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
677 lines
28 KiB
C#
677 lines
28 KiB
C#
![]() |
//------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Channels
|
||
|
{
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Diagnostics;
|
||
|
using System.Runtime;
|
||
|
using System.Security;
|
||
|
using System.Security.Permissions;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Diagnostics;
|
||
|
using System.Threading;
|
||
|
using Microsoft.Win32;
|
||
|
|
||
|
|
||
|
delegate void NeighborClosedHandler(IPeerNeighbor neighbor);
|
||
|
delegate void NeighborConnectedHandler(IPeerNeighbor neighbor);
|
||
|
delegate void MaintainerClosedHandler();
|
||
|
delegate void ReferralsAddedHandler(IList<Referral> referrals, IPeerNeighbor neighbor);
|
||
|
|
||
|
interface IPeerMaintainer
|
||
|
{
|
||
|
event NeighborClosedHandler NeighborClosed;
|
||
|
event NeighborConnectedHandler NeighborConnected;
|
||
|
event MaintainerClosedHandler MaintainerClosed;
|
||
|
event ReferralsAddedHandler ReferralsAdded;
|
||
|
|
||
|
int ConnectedNeighborCount { get; }
|
||
|
int NonClosingNeighborCount { get; }
|
||
|
bool IsOpen { get; }
|
||
|
|
||
|
IAsyncResult BeginOpenNeighbor(PeerNodeAddress to, TimeSpan timeout, AsyncCallback callback, object asyncState);
|
||
|
IPeerNeighbor EndOpenNeighbor(IAsyncResult result);
|
||
|
|
||
|
void CloseNeighbor(IPeerNeighbor neighbor, PeerCloseReason closeReason);
|
||
|
|
||
|
IPeerNeighbor FindDuplicateNeighbor(PeerNodeAddress address);
|
||
|
PeerNodeAddress GetListenAddress();
|
||
|
IPeerNeighbor GetLeastUsefulNeighbor();
|
||
|
}
|
||
|
|
||
|
interface IConnectAlgorithms : IDisposable
|
||
|
{
|
||
|
void Connect(TimeSpan timeout);
|
||
|
void Initialize(IPeerMaintainer maintainer, PeerNodeConfig config, int wantedConnectedNeighbors, Dictionary<EndpointAddress, Referral> referralCache);
|
||
|
void PruneConnections();
|
||
|
void UpdateEndpointsCollection(ICollection<PeerNodeAddress> src);
|
||
|
}
|
||
|
|
||
|
class PeerMaintainerBase<TConnectAlgorithms> : IPeerMaintainer where TConnectAlgorithms : IConnectAlgorithms, new()
|
||
|
{
|
||
|
public delegate void ConnectCallback(Exception e);
|
||
|
|
||
|
ConnectCallback connectCallback;
|
||
|
|
||
|
PeerNodeConfig config;
|
||
|
PeerFlooder flooder;
|
||
|
PeerNeighborManager neighborManager;
|
||
|
Dictionary<EndpointAddress, Referral> referralCache;
|
||
|
object thisLock;
|
||
|
PeerNodeTraceRecord traceRecord;
|
||
|
|
||
|
// Double-checked locking pattern requires volatile for read/write synchronization
|
||
|
volatile bool isRunningMaintenance = false; // true indicates performing connection Maintenance
|
||
|
volatile bool isOpen = false;
|
||
|
IOThreadTimer maintainerTimer;
|
||
|
public event ReferralsAddedHandler ReferralsAdded;
|
||
|
|
||
|
object ThisLock
|
||
|
{
|
||
|
get { return thisLock; }
|
||
|
}
|
||
|
|
||
|
public PeerMaintainerBase(PeerNodeConfig config, PeerNeighborManager neighborManager, PeerFlooder flooder)
|
||
|
{
|
||
|
this.neighborManager = neighborManager;
|
||
|
this.flooder = flooder;
|
||
|
this.config = config;
|
||
|
thisLock = new object();
|
||
|
|
||
|
referralCache = new Dictionary<EndpointAddress, Referral>();
|
||
|
maintainerTimer = new IOThreadTimer(new Action<object>(OnMaintainerTimer), this, false);
|
||
|
}
|
||
|
|
||
|
// Maintainer is expected to validate and accept the contents of referrals
|
||
|
// and to determine how many referrals it will accept from the array.
|
||
|
// Neighbor reference is passed in case the Maintainer decided to reject a referral
|
||
|
// based on invalid content and close the neighbor.
|
||
|
public bool AddReferrals(IList<Referral> referrals, IPeerNeighbor neighbor)
|
||
|
{
|
||
|
Fx.Assert(null != config.Resolver, "");
|
||
|
|
||
|
bool valid = true;
|
||
|
bool canShareReferrals = false;
|
||
|
try
|
||
|
{
|
||
|
canShareReferrals = config.Resolver.CanShareReferrals;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(SR.GetString(SR.ResolverException), e);
|
||
|
}
|
||
|
if (referrals != null && canShareReferrals)
|
||
|
{
|
||
|
foreach (Referral referral in referrals)
|
||
|
{
|
||
|
// If any referral is invalid then the connection is bad so don't accept any referals from this neighbor.
|
||
|
if (referral == null
|
||
|
|| referral.NodeId == PeerTransportConstants.InvalidNodeId
|
||
|
|| !PeerValidateHelper.ValidNodeAddress(referral.Address)
|
||
|
|| !PeerValidateHelper.ValidReferralNodeAddress(referral.Address))
|
||
|
{
|
||
|
valid = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (valid)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
foreach (Referral referral in referrals)
|
||
|
{
|
||
|
EndpointAddress key = referral.Address.EndpointAddress;
|
||
|
if (referralCache.Count <= this.config.MaxReferralCacheSize && !referralCache.ContainsKey(key))
|
||
|
{
|
||
|
referralCache.Add(key, referral);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Invoke any handler that is interested in Referrals being added.
|
||
|
ReferralsAddedHandler handler = ReferralsAdded;
|
||
|
if (handler != null)
|
||
|
{
|
||
|
ReferralsAdded(referrals, neighbor);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return valid;
|
||
|
}
|
||
|
|
||
|
[PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
|
||
|
public void Close()
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
isOpen = false;
|
||
|
}
|
||
|
maintainerTimer.Cancel(); // No reconnect while closed
|
||
|
SystemEvents.PowerModeChanged -= new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
|
||
|
MaintainerClosedHandler handler = MaintainerClosed;
|
||
|
if (handler != null)
|
||
|
{
|
||
|
handler();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void InitialConnection(object dummy)
|
||
|
{
|
||
|
// Are we open and is any maintenance activity occuring
|
||
|
if (isOpen)
|
||
|
{
|
||
|
bool continueMaintenance = false;
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
isRunningMaintenance = true;
|
||
|
continueMaintenance = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (continueMaintenance)
|
||
|
{
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerInitialConnect, this.config.MeshId));
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
|
||
|
TimeoutHelper timeoutHelper = new TimeoutHelper(config.MaintainerTimeout);
|
||
|
Exception exception = null;
|
||
|
// The connection algorithm may be pluggable if we provide an api or metadata to enable it.
|
||
|
// I am sure that research would be interested in doing such a thing.
|
||
|
try
|
||
|
{
|
||
|
maintainerTimer.Cancel(); // No reconnect until after connect has succeeded
|
||
|
|
||
|
using (IConnectAlgorithms connectAlgorithm = (IConnectAlgorithms)new TConnectAlgorithms())
|
||
|
{
|
||
|
connectAlgorithm.Initialize(this, config, config.MinNeighbors, referralCache);
|
||
|
if (referralCache.Count == 0)
|
||
|
{
|
||
|
ReadOnlyCollection<PeerNodeAddress> addresses = ResolveNewAddresses(timeoutHelper.RemainingTime(), false);
|
||
|
connectAlgorithm.UpdateEndpointsCollection(addresses);
|
||
|
}
|
||
|
if (isOpen)
|
||
|
{
|
||
|
connectAlgorithm.Connect(timeoutHelper.RemainingTime());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning suppress 56500 // covered by FxCOP
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
|
||
|
exception = e; // Exeption is saved and transferred
|
||
|
}
|
||
|
if (isOpen)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (isOpen)
|
||
|
{
|
||
|
// No reconnect until after connect has succeeded
|
||
|
if (neighborManager.ConnectedNeighborCount < 1)
|
||
|
{
|
||
|
maintainerTimer.Set(config.MaintainerRetryInterval);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
maintainerTimer.Set(config.MaintainerInterval);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
|
||
|
if (exception == null) exception = e; // Exeption is saved and transferred via callback
|
||
|
}
|
||
|
}
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
isRunningMaintenance = false;
|
||
|
}
|
||
|
if (connectCallback != null)
|
||
|
{
|
||
|
connectCallback(exception);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This activity maintains the connected nodes
|
||
|
void MaintainConnections(object dummy)
|
||
|
{
|
||
|
// Are we open and is any maintenance activity occuring
|
||
|
if (isOpen)
|
||
|
{
|
||
|
bool continueMaintenance = false;
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
isRunningMaintenance = true;
|
||
|
continueMaintenance = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (continueMaintenance)
|
||
|
{
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerStarting, this.config.MeshId));
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
|
||
|
TimeoutHelper timeoutHelper = new TimeoutHelper(config.MaintainerTimeout);
|
||
|
try
|
||
|
{
|
||
|
maintainerTimer.Cancel(); // No reconnect until after connect has succeeded
|
||
|
|
||
|
int currentlyConnected = neighborManager.ConnectedNeighborCount;
|
||
|
if (currentlyConnected != config.IdealNeighbors) // Already at ideal no work to do
|
||
|
{
|
||
|
using (IConnectAlgorithms connectAlgorithm = (IConnectAlgorithms)new TConnectAlgorithms())
|
||
|
{
|
||
|
connectAlgorithm.Initialize(this, config, config.IdealNeighbors, referralCache);
|
||
|
if (currentlyConnected > config.IdealNeighbors)
|
||
|
{
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerPruneMode, this.config.MeshId));
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
connectAlgorithm.PruneConnections();
|
||
|
}
|
||
|
|
||
|
// During Prune some other neighbor may have gone away which leaves us below Ideal
|
||
|
// So try to reconnect
|
||
|
currentlyConnected = neighborManager.ConnectedNeighborCount;
|
||
|
if (currentlyConnected < config.IdealNeighbors)
|
||
|
{
|
||
|
if (referralCache.Count == 0)
|
||
|
{
|
||
|
ReadOnlyCollection<PeerNodeAddress> addresses = ResolveNewAddresses(timeoutHelper.RemainingTime(), true);
|
||
|
connectAlgorithm.UpdateEndpointsCollection(addresses);
|
||
|
}
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerConnectMode, this.config.MeshId));
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
connectAlgorithm.Connect(timeoutHelper.RemainingTime());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning suppress 56500 // covered by FxCOP
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
|
||
|
// We ---- all non Fatal exceptions because this is a worker thread, with no user code waiting
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord("Maintainer cycle finish");
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
}
|
||
|
ResetMaintenance();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void OnMaintainerTimer(object state)
|
||
|
{
|
||
|
ActionItem.Schedule(new Action<object>(MaintainConnections), null);
|
||
|
}
|
||
|
|
||
|
public void RefreshConnection()
|
||
|
{
|
||
|
// Are we open and is any maintenance activity occuring
|
||
|
if (isOpen)
|
||
|
{
|
||
|
bool continueMaintenance = false;
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (!isRunningMaintenance)
|
||
|
{
|
||
|
isRunningMaintenance = true;
|
||
|
continueMaintenance = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (continueMaintenance)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
TimeoutHelper timeoutHelper = new TimeoutHelper(config.MaintainerTimeout);
|
||
|
maintainerTimer.Cancel(); // No maintainer until after connect has succeeded
|
||
|
|
||
|
using (IConnectAlgorithms connectAlgorithm = (IConnectAlgorithms)new TConnectAlgorithms())
|
||
|
{
|
||
|
// Always go to the resolver for RefreshConnection
|
||
|
ReadOnlyCollection<PeerNodeAddress> addresses = ResolveNewAddresses(timeoutHelper.RemainingTime(), true);
|
||
|
connectAlgorithm.Initialize(this, config, neighborManager.ConnectedNeighborCount + 1, new Dictionary<EndpointAddress, Referral>());
|
||
|
if (addresses.Count > 0)
|
||
|
{
|
||
|
if (isOpen)
|
||
|
{
|
||
|
connectAlgorithm.UpdateEndpointsCollection(addresses);
|
||
|
connectAlgorithm.Connect(timeoutHelper.RemainingTime());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
ResetMaintenance();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ResetMaintenance()
|
||
|
{
|
||
|
if (isOpen)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (isOpen)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
maintainerTimer.Set(config.MaintainerInterval); // No reconnect until after connect has succeeded
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
|
||
|
// We ---- all non Fatal exceptions because this is a worker thread, with no user code waiting
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
isRunningMaintenance = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void ScheduleConnect(ConnectCallback connectCallback)
|
||
|
{
|
||
|
this.connectCallback = connectCallback;
|
||
|
ActionItem.Schedule(new Action<object>(InitialConnection), null);
|
||
|
}
|
||
|
|
||
|
public Referral[] GetReferrals()
|
||
|
{
|
||
|
Fx.Assert(null != config.Resolver, "");
|
||
|
|
||
|
Referral[] referrals = null;
|
||
|
bool canShareReferrals = false;
|
||
|
try
|
||
|
{
|
||
|
canShareReferrals = config.Resolver.CanShareReferrals;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(SR.GetString(SR.ResolverException), e);
|
||
|
}
|
||
|
|
||
|
if (canShareReferrals)
|
||
|
{
|
||
|
List<IPeerNeighbor> neighbors = this.neighborManager.GetConnectedNeighbors();
|
||
|
int count = Math.Min(this.config.MaxReferrals, neighbors.Count);
|
||
|
referrals = new Referral[count];
|
||
|
for (int i = 0; i < count; i++)
|
||
|
{
|
||
|
referrals[i] = new Referral(neighbors[i].NodeId, neighbors[i].ListenAddress);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
referrals = new Referral[0];
|
||
|
}
|
||
|
return referrals;
|
||
|
}
|
||
|
|
||
|
// Notify whoever is interested in NeighborClosed, and start the Maintenance algorithms at threshold
|
||
|
public virtual void OnNeighborClosed(IPeerNeighbor neighbor)
|
||
|
{
|
||
|
if (isOpen)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
if (neighbor != null && neighbor.ListenAddress != null)
|
||
|
{
|
||
|
EndpointAddress key = neighbor.ListenAddress.EndpointAddress;
|
||
|
}
|
||
|
|
||
|
if (isOpen && !isRunningMaintenance && neighborManager.ConnectedNeighborCount < config.MinNeighbors)
|
||
|
{
|
||
|
maintainerTimer.Set(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
NeighborClosedHandler handler = NeighborClosed;
|
||
|
if (handler != null)
|
||
|
{
|
||
|
handler(neighbor);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public virtual void OnNeighborConnected(IPeerNeighbor neighbor)
|
||
|
{
|
||
|
NeighborConnectedHandler handler = NeighborConnected;
|
||
|
if (handler != null)
|
||
|
{
|
||
|
handler(neighbor);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
|
||
|
public void Open()
|
||
|
{
|
||
|
traceRecord = new PeerNodeTraceRecord(config.NodeId);
|
||
|
|
||
|
if (isRunningMaintenance)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
|
||
|
isOpen = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get some addresses and make sure they are not in my neighborlist
|
||
|
ReadOnlyCollection<PeerNodeAddress> ResolveNewAddresses(TimeSpan timeLeft, bool retryResolve)
|
||
|
{
|
||
|
TimeoutHelper timeoutHelper = new TimeoutHelper(timeLeft);
|
||
|
Dictionary<string, PeerNodeAddress> alreadySeen = new Dictionary<string, PeerNodeAddress>();
|
||
|
List<PeerNodeAddress> reply = new List<PeerNodeAddress>();
|
||
|
|
||
|
// Is this address me
|
||
|
PeerNodeAddress lclNodeAddress = config.GetListenAddress(true);
|
||
|
alreadySeen.Add(lclNodeAddress.ServicePath, lclNodeAddress);
|
||
|
|
||
|
// Maximum of 2 resolves to get new addresses - if the resolver doesn't return us good addresses in 2 goes (8 randomly returned addresses)
|
||
|
// it is probably messing with us
|
||
|
int nresolves = (retryResolve) ? 2 : 1;
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord("Resolving");
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < nresolves && reply.Count < config.MaxResolveAddresses && isOpen && timeoutHelper.RemainingTime() > TimeSpan.Zero; i++)
|
||
|
{
|
||
|
ReadOnlyCollection<PeerNodeAddress> addresses;
|
||
|
try
|
||
|
{
|
||
|
addresses = config.Resolver.Resolve(config.MeshId, config.MaxResolveAddresses, timeoutHelper.RemainingTime());
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e)) throw;
|
||
|
if (DiagnosticUtility.ShouldTraceInformation)
|
||
|
{
|
||
|
PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord("Resolve exception " + e.Message);
|
||
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity),
|
||
|
record, this, null);
|
||
|
}
|
||
|
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.ResolverException), e));
|
||
|
}
|
||
|
|
||
|
if (addresses != null)
|
||
|
{
|
||
|
foreach (PeerNodeAddress address in addresses)
|
||
|
{
|
||
|
if (!alreadySeen.ContainsKey(address.ServicePath))
|
||
|
{
|
||
|
alreadySeen.Add(address.ServicePath, address);
|
||
|
if (((IPeerMaintainer)this).FindDuplicateNeighbor(address) == null)
|
||
|
{
|
||
|
reply.Add(address);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return (new ReadOnlyCollection<PeerNodeAddress>(reply));
|
||
|
}
|
||
|
|
||
|
// interface IPeerMaintainer implementation
|
||
|
public event NeighborClosedHandler NeighborClosed;
|
||
|
public event NeighborConnectedHandler NeighborConnected;
|
||
|
public event MaintainerClosedHandler MaintainerClosed;
|
||
|
|
||
|
void IPeerMaintainer.CloseNeighbor(IPeerNeighbor neighbor, PeerCloseReason closeReason)
|
||
|
{
|
||
|
neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.LocalNode);
|
||
|
}
|
||
|
|
||
|
IPeerNeighbor IPeerMaintainer.FindDuplicateNeighbor(PeerNodeAddress address)
|
||
|
{
|
||
|
return neighborManager.FindDuplicateNeighbor(address);
|
||
|
}
|
||
|
|
||
|
PeerNodeAddress IPeerMaintainer.GetListenAddress()
|
||
|
{
|
||
|
return config.GetListenAddress(true);
|
||
|
}
|
||
|
|
||
|
IPeerNeighbor IPeerMaintainer.GetLeastUsefulNeighbor()
|
||
|
{
|
||
|
IPeerNeighbor leastUsefulNeighbor = null;
|
||
|
uint minUtility = UInt32.MaxValue;
|
||
|
|
||
|
foreach (IPeerNeighbor neighbor in this.neighborManager.GetConnectedNeighbors())
|
||
|
{
|
||
|
UtilityExtension utilityExtension = neighbor.Extensions.Find<UtilityExtension>();
|
||
|
if (utilityExtension != null && utilityExtension.IsAccurate && utilityExtension.LinkUtility < minUtility && !neighbor.IsClosing)
|
||
|
{
|
||
|
minUtility = utilityExtension.LinkUtility;
|
||
|
leastUsefulNeighbor = neighbor;
|
||
|
}
|
||
|
}
|
||
|
return leastUsefulNeighbor;
|
||
|
}
|
||
|
|
||
|
IAsyncResult IPeerMaintainer.BeginOpenNeighbor(PeerNodeAddress address, TimeSpan timeout, AsyncCallback callback, object asyncState)
|
||
|
{
|
||
|
lock (ThisLock)
|
||
|
{
|
||
|
EndpointAddress key = address.EndpointAddress;
|
||
|
if (referralCache.ContainsKey(key))
|
||
|
{
|
||
|
referralCache.Remove(key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return neighborManager.BeginOpenNeighbor(address, timeout, callback, asyncState);
|
||
|
}
|
||
|
|
||
|
IPeerNeighbor IPeerMaintainer.EndOpenNeighbor(IAsyncResult result)
|
||
|
{
|
||
|
return neighborManager.EndOpenNeighbor(result);
|
||
|
}
|
||
|
|
||
|
int IPeerMaintainer.ConnectedNeighborCount
|
||
|
{
|
||
|
get { return neighborManager.ConnectedNeighborCount; }
|
||
|
}
|
||
|
|
||
|
int IPeerMaintainer.NonClosingNeighborCount
|
||
|
{
|
||
|
get { return neighborManager.NonClosingNeighborCount; }
|
||
|
}
|
||
|
|
||
|
bool IPeerMaintainer.IsOpen
|
||
|
{
|
||
|
get { return isOpen; }
|
||
|
}
|
||
|
|
||
|
public void PingConnections()
|
||
|
{
|
||
|
neighborManager.PingNeighbors();
|
||
|
}
|
||
|
|
||
|
public void PingAndRefresh(object state)
|
||
|
{
|
||
|
PingConnections();
|
||
|
if (this.neighborManager.ConnectedNeighborCount < this.config.IdealNeighbors)
|
||
|
MaintainConnections(null);
|
||
|
}
|
||
|
|
||
|
[PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
|
||
|
void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||
|
{
|
||
|
if (e.Mode != PowerModes.Resume)
|
||
|
return;
|
||
|
if (!isOpen)
|
||
|
return;
|
||
|
ActionItem.Schedule(new Action<object>(PingAndRefresh), null);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
partial class PeerMaintainer : PeerMaintainerBase<ConnectAlgorithms>
|
||
|
{
|
||
|
public PeerMaintainer(PeerNodeConfig config, PeerNeighborManager neighborManager, PeerFlooder flooder)
|
||
|
: base(config, neighborManager, flooder)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
}
|