[coop] Temporarily restore MonoThreadInfo when TLS destructor runs. Fixes #43099
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Channels / TransportDefaults.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.ServiceModel.Channels
6 {
7     using System.Net;
8     using System.Net.Security;
9     using System.Net.WebSockets;
10     using System.Runtime;
11     using System.Security.Authentication;
12     using System.Security.Principal;
13     using System.ServiceModel;
14     using System.ServiceModel.Dispatcher;
15     using System.ServiceModel.Security;
16     using System.Text;
17     using System.Xml;
18
19     internal static class TransactionFlowDefaults
20     {
21         internal const TransactionFlowOption IssuedTokens = TransactionFlowOption.NotAllowed;
22         internal const bool Transactions = false;
23         internal static TransactionProtocol TransactionProtocol = System.ServiceModel.TransactionProtocol.OleTransactions;
24         internal const string TransactionProtocolString = System.ServiceModel.Configuration.ConfigurationStrings.OleTransactions;
25     }
26
27     static class EncoderDefaults
28     {
29         internal const int MaxReadPoolSize = 64;
30         internal const int MaxWritePoolSize = 16;
31
32         internal const int MaxDepth = 32;
33         internal const int MaxStringContentLength = 8192;
34         internal const int MaxArrayLength = 16384;
35         internal const int MaxBytesPerRead = 4096;
36         internal const int MaxNameTableCharCount = 16384;
37
38         internal const int BufferedReadDefaultMaxDepth = 128;
39         internal const int BufferedReadDefaultMaxStringContentLength = Int32.MaxValue;
40         internal const int BufferedReadDefaultMaxArrayLength = Int32.MaxValue;
41         internal const int BufferedReadDefaultMaxBytesPerRead = Int32.MaxValue;
42         internal const int BufferedReadDefaultMaxNameTableCharCount = Int32.MaxValue;
43
44         internal const CompressionFormat DefaultCompressionFormat = CompressionFormat.None;
45
46         internal static readonly XmlDictionaryReaderQuotas ReaderQuotas = new XmlDictionaryReaderQuotas();
47
48         internal static bool IsDefaultReaderQuotas(XmlDictionaryReaderQuotas quotas)
49         {
50             return quotas.ModifiedQuotas == 0x00;
51         }
52     }
53
54     static class TextEncoderDefaults
55     {
56         internal static readonly Encoding Encoding = Encoding.GetEncoding(TextEncoderDefaults.EncodingString, new EncoderExceptionFallback(), new DecoderExceptionFallback());
57         internal const string EncodingString = "utf-8";
58         internal static readonly Encoding[] SupportedEncodings = new Encoding[] { Encoding.UTF8, Encoding.Unicode, Encoding.BigEndianUnicode };
59         internal const string MessageVersionString = System.ServiceModel.Configuration.ConfigurationStrings.Soap12WSAddressing10;
60         internal static readonly CharSetEncoding[] CharSetEncodings = new CharSetEncoding[]
61         {
62             new CharSetEncoding("utf-8", Encoding.UTF8),
63             new CharSetEncoding("utf-16LE", Encoding.Unicode),
64             new CharSetEncoding("utf-16BE", Encoding.BigEndianUnicode),
65             new CharSetEncoding("utf-16", null),   // Ignore.  Ambiguous charSet, so autodetect.
66             new CharSetEncoding(null, null),       // CharSet omitted, so autodetect.
67         };
68
69         internal static void ValidateEncoding(Encoding encoding)
70         {
71             string charSet = encoding.WebName;
72             Encoding[] supportedEncodings = SupportedEncodings;
73             for (int i = 0; i < supportedEncodings.Length; i++)
74             {
75                 if (charSet == supportedEncodings[i].WebName)
76                     return;
77             }
78             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageTextEncodingNotSupported, charSet), "encoding"));
79         }
80
81         internal static string EncodingToCharSet(Encoding encoding)
82         {
83             string webName = encoding.WebName;
84             CharSetEncoding[] charSetEncodings = CharSetEncodings;
85             for (int i = 0; i < charSetEncodings.Length; i++)
86             {
87                 Encoding enc = charSetEncodings[i].Encoding;
88                 if (enc == null)
89                     continue;
90
91                 if (enc.WebName == webName)
92                     return charSetEncodings[i].CharSet;
93             }
94             return null;
95         }
96
97         internal static bool TryGetEncoding(string charSet, out Encoding encoding)
98         {
99             CharSetEncoding[] charSetEncodings = CharSetEncodings;
100
101             // Quick check for exact equality
102             for (int i = 0; i < charSetEncodings.Length; i++)
103             {
104                 if (charSetEncodings[i].CharSet == charSet)
105                 {
106                     encoding = charSetEncodings[i].Encoding;
107                     return true;
108                 }
109             }
110
111             // Check for case insensative match
112             for (int i = 0; i < charSetEncodings.Length; i++)
113             {
114                 string compare = charSetEncodings[i].CharSet;
115                 if (compare == null)
116                     continue;
117
118                 if (compare.Equals(charSet, StringComparison.OrdinalIgnoreCase))
119                 {
120                     encoding = charSetEncodings[i].Encoding;
121                     return true;
122                 }
123             }
124
125             encoding = null;
126             return false;
127         }
128
129         internal class CharSetEncoding
130         {
131             internal string CharSet;
132             internal Encoding Encoding;
133
134             internal CharSetEncoding(string charSet, Encoding enc)
135             {
136                 CharSet = charSet;
137                 Encoding = enc;
138             }
139         }
140     }
141
142     static class MtomEncoderDefaults
143     {
144         internal const int MaxBufferSize = 65536;
145     }
146
147     static class BinaryEncoderDefaults
148     {
149         internal static EnvelopeVersion EnvelopeVersion { get { return EnvelopeVersion.Soap12; } }
150         internal static BinaryVersion BinaryVersion { get { return BinaryVersion.Version1; } }
151         internal const int MaxSessionSize = 2048;
152     }
153
154     static class MsmqDefaults
155     {
156         internal const MessageCredentialType DefaultClientCredentialType = MessageCredentialType.Windows;
157         internal const Uri CustomDeadLetterQueue = null;
158         internal const DeadLetterQueue DeadLetterQueue = System.ServiceModel.DeadLetterQueue.System;
159         internal const bool Durable = true;
160         internal const bool ExactlyOnce = true;
161         internal const bool ReceiveContextEnabled = true;
162         internal const int MaxRetryCycles = 2;
163         internal const int MaxPoolSize = 8;
164         internal const MsmqAuthenticationMode MsmqAuthenticationMode = System.ServiceModel.MsmqAuthenticationMode.WindowsDomain;
165         internal const MsmqEncryptionAlgorithm MsmqEncryptionAlgorithm = System.ServiceModel.MsmqEncryptionAlgorithm.RC4Stream;
166         internal const MsmqSecureHashAlgorithm MsmqSecureHashAlgorithm = System.ServiceModel.MsmqSecureHashAlgorithm.Sha1;
167         internal const ProtectionLevel MsmqProtectionLevel = ProtectionLevel.Sign;
168         internal const ReceiveErrorHandling ReceiveErrorHandling = System.ServiceModel.ReceiveErrorHandling.Fault;
169         internal const int ReceiveRetryCount = 5;
170         internal const QueueTransferProtocol QueueTransferProtocol = System.ServiceModel.QueueTransferProtocol.Native;
171         internal static TimeSpan RetryCycleDelay { get { return TimeSpanHelper.FromMinutes(30, MsmqDefaults.RetryCycleDelayString); } }
172         internal const string RetryCycleDelayString = "00:30:00";
173         internal static TimeSpan TimeToLive { get { return TimeSpanHelper.FromDays(1, MsmqDefaults.TimeToLiveString); } }
174         internal const string TimeToLiveString = "1.00:00:00";
175         internal const bool UseActiveDirectory = false;
176         internal const bool UseSourceJournal = false;
177         internal const bool UseMsmqTracing = false;
178         internal static TimeSpan ValidityDuration { get { return TimeSpanHelper.FromMinutes(5, MsmqDefaults.ValidityDurationString); } }
179         internal const string ValidityDurationString = "00:05:00";
180         internal static SecurityAlgorithmSuite MessageSecurityAlgorithmSuite
181         {
182             get { return SecurityAlgorithmSuite.Default; }
183         }
184     }
185
186     static class MsmqIntegrationDefaults
187     {
188         internal const System.ServiceModel.MsmqIntegration.MsmqMessageSerializationFormat SerializationFormat =
189             System.ServiceModel.MsmqIntegration.MsmqMessageSerializationFormat.Xml;
190     }
191
192     static class TransportDefaults
193     {
194         internal const bool ExtractGroupsForWindowsAccounts = SspiSecurityTokenProvider.DefaultExtractWindowsGroupClaims;
195         internal const HostNameComparisonMode HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.Exact;
196         internal const TokenImpersonationLevel ImpersonationLevel = TokenImpersonationLevel.Identification;
197         internal const bool ManualAddressing = false;
198         internal const long MaxReceivedMessageSize = 65536;
199         internal const int MaxDrainSize = (int)MaxReceivedMessageSize;
200         internal const long MaxBufferPoolSize = 512 * 1024;
201         internal const int MaxBufferSize = (int)MaxReceivedMessageSize;
202         internal const bool RequireClientCertificate = false;
203         internal const int MaxFaultSize = MaxBufferSize;
204         internal const int MaxSecurityFaultSize = 16384;
205         internal const SslProtocols SslProtocols = System.Security.Authentication.SslProtocols.Ssl3 |
206                                                    System.Security.Authentication.SslProtocols.Tls |
207                                                    System.Security.Authentication.SslProtocols.Tls11 |
208                                                    System.Security.Authentication.SslProtocols.Tls12;
209
210         // Calling CreateFault on an incoming message can expose some DoS-related security 
211         // vulnerabilities when a service is in streaming mode.  See MB 47592 for more details. 
212         // The RM protocol service does not use streaming mode on any of its bindings, so the
213         // message we have in hand has already passed the binding\92s MaxReceivedMessageSize check.
214         // Custom transports can use RM so int.MaxValue is dangerous.
215         internal const int MaxRMFaultSize = (int)MaxReceivedMessageSize;
216
217         internal static MessageEncoderFactory GetDefaultMessageEncoderFactory()
218         {
219             return new BinaryMessageEncodingBindingElement().CreateMessageEncoderFactory();
220         }
221     }
222
223     static class ConnectionOrientedTransportDefaults
224     {
225         internal const bool AllowNtlm = SspiSecurityTokenProvider.DefaultAllowNtlm;
226         internal const int ConnectionBufferSize = 8192;
227         internal const string ConnectionPoolGroupName = "default";
228         internal const HostNameComparisonMode HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.StrongWildcard;
229         internal static TimeSpan IdleTimeout { get { return TimeSpanHelper.FromMinutes(2, IdleTimeoutString); } }
230         internal const string IdleTimeoutString = "00:02:00";
231         internal static TimeSpan ChannelInitializationTimeout { get { return TimeSpanHelper.FromSeconds(30, ChannelInitializationTimeoutString); } }
232         internal const string ChannelInitializationTimeoutString = "00:00:30";
233         internal const int MaxContentTypeSize = 256;
234         internal const int MaxOutboundConnectionsPerEndpoint = 10;
235         internal const int MaxPendingConnectionsConst = 0;
236         internal static TimeSpan MaxOutputDelay { get { return TimeSpanHelper.FromMilliseconds(200, MaxOutputDelayString); } }
237         internal const string MaxOutputDelayString = "00:00:00.2";
238         internal const int MaxPendingAcceptsConst = 0;
239         internal const int MaxViaSize = 2048;
240         internal const ProtectionLevel ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
241         internal const TransferMode TransferMode = System.ServiceModel.TransferMode.Buffered;
242
243         private const int MaxPendingConnectionsPre45 = 10;
244         private const int MaxPendingAcceptsPre45 = 1;
245
246         internal static int GetMaxConnections()
247         {
248             return GetMaxPendingConnections();
249         }
250
251         internal static int GetMaxPendingConnections()
252         {
253             // OSEnvironmentHelper.IsApplicationTargeting45 checks for whether target Fx version is >= 4.5 despite its name
254             if (OSEnvironmentHelper.IsApplicationTargeting45)
255             {
256                 return 12 * OSEnvironmentHelper.ProcessorCount;
257             }
258
259             return MaxPendingConnectionsPre45;
260         }
261
262         internal static int GetMaxPendingAccepts()
263         {
264             // OSEnvironmentHelper.IsApplicationTargeting45 checks for whether target Fx version is >= 4.5 despite its name
265             if (OSEnvironmentHelper.IsApplicationTargeting45)
266             {
267                 return 2 * OSEnvironmentHelper.ProcessorCount;
268             }
269
270             return MaxPendingAcceptsPre45;
271         }
272     }
273
274     static class TcpTransportDefaults
275     {
276         internal const int ListenBacklogConst = 0;
277         internal static TimeSpan ConnectionLeaseTimeout { get { return TimeSpanHelper.FromMinutes(5, TcpTransportDefaults.ConnectionLeaseTimeoutString); } }
278         internal const string ConnectionLeaseTimeoutString = "00:05:00";
279         internal const bool PortSharingEnabled = false;
280         internal const bool TeredoEnabled = false;
281         
282         private const int ListenBacklogPre45 = 10;
283
284         internal static int GetListenBacklog()
285         {
286             // OSEnvironmentHelper.IsApplicationTargeting45 checks for whether target Fx version is >= 4.5 despite its name
287             if (OSEnvironmentHelper.IsApplicationTargeting45)
288             {
289                 return 12 * OSEnvironmentHelper.ProcessorCount;
290             }
291
292             return ListenBacklogPre45;
293         }
294     }
295
296     static class ApplicationContainerSettingsDefaults
297     {
298         internal const string CurrentUserSessionDefaultString = "CurrentSession";
299         internal const string Session0ServiceSessionString = "ServiceSession";
300         internal const string PackageFullNameDefaultString = null;
301
302         /// <summary>
303         /// The current session will be used for resource lookup.
304         /// </summary>
305         internal const int CurrentSession = -1;
306
307         /// <summary>
308         /// Session 0 is the NT Service session
309         /// </summary>
310         internal const int ServiceSession = 0;
311     }
312
313     static class HttpTransportDefaults
314     {
315         internal const bool AllowCookies = false;
316         internal const AuthenticationSchemes AuthenticationScheme = AuthenticationSchemes.Anonymous;
317         internal const bool BypassProxyOnLocal = false;
318         internal const bool DecompressionEnabled = true;
319         internal const HostNameComparisonMode HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.StrongWildcard;
320         internal const bool KeepAliveEnabled = true;
321         internal const Uri ProxyAddress = null;
322         internal const AuthenticationSchemes ProxyAuthenticationScheme = AuthenticationSchemes.Anonymous;
323         internal const string Realm = "";
324         internal const TransferMode TransferMode = System.ServiceModel.TransferMode.Buffered;
325         internal const bool UnsafeConnectionNtlmAuthentication = false;
326         internal const bool UseDefaultWebProxy = true;
327         internal const string UpgradeHeader = "Upgrade";
328         internal const string ConnectionHeader = "Connection";
329         internal const HttpMessageHandlerFactory MessageHandlerFactory = null;
330
331         internal static TimeSpan RequestInitializationTimeout { get { return TimeSpanHelper.FromMilliseconds(0, RequestInitializationTimeoutString); } }
332         internal const string RequestInitializationTimeoutString = "00:00:00";
333
334         // We use 0 as the default value of the MaxPendingAccepts property on HttpTransportBindingElement. In 4.5 we always
335         // use 10 under the hood if the default value is picked. In future releases, we could adjust the underlying default
336         // value when we have the dynamic expending pattern of BeginGetContext call implemented and the heap fragmentation issue
337         // from NCL layer solved.
338         const int PendingAcceptsConstant = 10;
339         internal const int DefaultMaxPendingAccepts = 0;
340         internal const int MaxPendingAcceptsUpperLimit = 100000;
341         internal static int GetEffectiveMaxPendingAccepts(int maxPendingAccepts)
342         {
343             return maxPendingAccepts == HttpTransportDefaults.DefaultMaxPendingAccepts ?
344                                         PendingAcceptsConstant :
345                                         maxPendingAccepts;
346         }
347
348
349         internal static WebSocketTransportSettings GetDefaultWebSocketTransportSettings()
350         {
351             return new WebSocketTransportSettings();
352         }
353
354         internal static MessageEncoderFactory GetDefaultMessageEncoderFactory()
355         {
356             return new TextMessageEncoderFactory(MessageVersion.Default, TextEncoderDefaults.Encoding, EncoderDefaults.MaxReadPoolSize, EncoderDefaults.MaxWritePoolSize, EncoderDefaults.ReaderQuotas);
357         }
358
359         internal static SecurityAlgorithmSuite MessageSecurityAlgorithmSuite
360         {
361             get { return SecurityAlgorithmSuite.Default; }
362         }
363     }
364
365     static class NetTcpDefaults
366     {
367         internal const MessageCredentialType MessageSecurityClientCredentialType = MessageCredentialType.Windows;
368         internal const bool TransactionsEnabled = false;
369
370         internal static TransactionProtocol TransactionProtocol
371         {
372             get { return TransactionProtocol.Default; }
373         }
374
375         internal static SecurityAlgorithmSuite MessageSecurityAlgorithmSuite
376         {
377             get { return SecurityAlgorithmSuite.Default; }
378         }
379     }
380
381     static class NetHttpDefaults
382     {
383         internal static TransactionProtocol TransactionProtocol
384         {
385             get { return TransactionProtocol.Default; }
386         }
387     }
388
389     static class PeerTransportDefaults
390     {
391         internal const IPAddress ListenIPAddress = null;
392         internal const int Port = 0;
393         internal const string ResolverTypeString = null;
394         internal const PeerAuthenticationMode PeerNodeAuthenticationMode = PeerAuthenticationMode.Password;
395         internal const bool MessageAuthentication = false;
396
397         internal static bool ResolverAvailable
398         {
399             get { return PnrpPeerResolver.IsPnrpAvailable; }
400         }
401
402         internal static bool ResolverInstalled
403         {
404             get { return PnrpPeerResolver.IsPnrpInstalled; }
405         }
406
407         internal static Type ResolverType
408         {
409             get { return typeof(PnrpPeerResolver); }
410         }
411
412         internal static Type ResolverBindingElementType
413         {
414             get { return typeof(PnrpPeerResolverBindingElement); }
415         }
416
417         internal static PeerResolver CreateResolver()
418         {
419             return new PnrpPeerResolver();
420         }
421
422     }
423
424     static class OneWayDefaults
425     {
426         internal static TimeSpan IdleTimeout { get { return TimeSpanHelper.FromMinutes(2, IdleTimeoutString); } }
427         internal const string IdleTimeoutString = "00:02:00";
428         internal const int MaxOutboundChannelsPerEndpoint = 10;
429         internal static TimeSpan LeaseTimeout { get { return TimeSpanHelper.FromMinutes(10, LeaseTimeoutString); } }
430         internal const string LeaseTimeoutString = "00:10:00";
431         internal const int MaxAcceptedChannels = 10;
432         internal const bool PacketRoutable = false;
433     }
434
435     static class ReliableSessionDefaults
436     {
437         internal const string AcknowledgementIntervalString = "00:00:00.2";
438         internal static TimeSpan AcknowledgementInterval { get { return TimeSpanHelper.FromMilliseconds(200, AcknowledgementIntervalString); } }
439         internal const bool Enabled = false;
440         internal const bool FlowControlEnabled = true;
441         internal const string InactivityTimeoutString = "00:10:00";
442         internal static TimeSpan InactivityTimeout { get { return TimeSpanHelper.FromMinutes(10, InactivityTimeoutString); } }
443         internal const int MaxPendingChannels = 4;
444         internal const int MaxRetryCount = 8;
445         internal const int MaxTransferWindowSize = 8;
446         internal const bool Ordered = true;
447         internal static ReliableMessagingVersion ReliableMessagingVersion { get { return System.ServiceModel.ReliableMessagingVersion.WSReliableMessagingFebruary2005; } }
448         internal const string ReliableMessagingVersionString = System.ServiceModel.Configuration.ConfigurationStrings.WSReliableMessagingFebruary2005;
449     }
450
451     static class BasicHttpBindingDefaults
452     {
453         internal const BasicHttpMessageCredentialType MessageSecurityClientCredentialType = BasicHttpMessageCredentialType.UserName;
454         internal const WSMessageEncoding MessageEncoding = WSMessageEncoding.Text;
455         internal const TransferMode TransferMode = System.ServiceModel.TransferMode.Buffered;
456         internal static Encoding TextEncoding
457         {
458             get { return TextEncoderDefaults.Encoding; }
459         }
460     }
461
462     static class WSHttpBindingDefaults
463     {
464         internal const WSMessageEncoding MessageEncoding = WSMessageEncoding.Text;
465     }
466
467     static class WSDualHttpBindingDefaults
468     {
469         internal const WSMessageEncoding MessageEncoding = WSMessageEncoding.Text;
470     }
471
472     static class WebSocketDefaults
473     {
474         internal const WebSocketTransportUsage TransportUsage = WebSocketTransportUsage.Never;
475         internal const bool CreateNotificationOnConnection = false;
476         internal const string DefaultKeepAliveIntervalString = "00:00:00";
477         internal static readonly TimeSpan DefaultKeepAliveInterval = TimeSpanHelper.FromSeconds(0, DefaultKeepAliveIntervalString);
478
479         internal const int BufferSize = 16 * 1024;
480         internal const int MinReceiveBufferSize = 256;
481         internal const int MinSendBufferSize = 16;
482         internal const bool DisablePayloadMasking = false;
483         internal const WebSocketMessageType DefaultWebSocketMessageType = WebSocketMessageType.Binary;
484         internal const string SubProtocol = null;
485
486         internal const int DefaultMaxPendingConnections = 0;
487         // We set this number larger than that in TCP transport because in WebSocket cases, the connection is already authenticated
488         // after we create the half-open channel. The default value is set as the default one as MaxConcurrentSessions to make it work
489         // well in burst scenarios.
490         internal static readonly int MaxPendingConnectionsCpuCount = ServiceThrottle.DefaultMaxConcurrentSessionsCpuCount;
491
492         internal const string WebSocketConnectionHeaderValue = "Upgrade";
493         internal const string WebSocketUpgradeHeaderValue = "websocket";
494
495         [System.Diagnostics.CodeAnalysis.SuppressMessage(FxCop.Category.Globalization, "CA1303",
496                             Justification = "These strings don't need to be localized.")]
497         static WebSocketDefaults()
498         {
499         }
500     }
501
502     static class NetHttpBindingDefaults
503     {
504         internal const NetHttpMessageEncoding MessageEncoding = NetHttpMessageEncoding.Binary;
505         internal const WebSocketTransportUsage TransportUsage = WebSocketTransportUsage.WhenDuplex;
506     }
507 }