Resolve "you are registering twice the same counter address" warning on Windows Relea...
[mono.git] / mcs / class / System / ReferenceSources / _SslState.cs
1 //
2 // Mono-specific additions to Microsoft's _SslState.cs
3 //
4 #if MONO_FEATURE_NEW_TLS && SECURITY_DEP
5 #if MONO_SECURITY_ALIAS
6 extern alias MonoSecurity;
7 using MonoSecurity::Mono.Security.Interface;
8 #else
9 using Mono.Security.Interface;
10 #endif
11 namespace System.Net.Security
12 {
13         using System.IO;
14         using System.Threading;
15         using System.Net.Sockets;
16
17         partial class SslState
18         {
19                 int _SentShutdown;
20
21                 internal MonoTlsConnectionInfo GetMonoConnectionInfo ()
22                 {
23                         return Context.GetMonoConnectionInfo ();
24                 }
25
26                 internal bool IsClosed {
27                         get { return Context.IsClosed; }
28                 }
29
30                 internal ProtocolToken CreateShutdownMessage ()
31                 {
32                         return Context.CreateShutdownMessage ();
33                 }
34
35                 internal ProtocolToken CreateHelloRequestMessage ()
36                 {
37                         return Context.CreateHelloRequestMessage ();
38                 }
39
40                 internal IAsyncResult BeginShutdown (AsyncCallback asyncCallback, object asyncState)
41                 {
42                         var shutdownResult = new ShutdownAsyncResult (this, asyncState, asyncCallback);
43
44                         if (Interlocked.CompareExchange (ref _SentShutdown, 1, 0) == 1) {
45                                 shutdownResult.InvokeCallback ();
46                                 return shutdownResult;
47                         }
48
49                         try
50                         {
51                                 CheckThrow (false);
52                                 shutdownResult.SentShutdown = true;
53                                 SecureStream.BeginShutdown (shutdownResult);
54                                 return shutdownResult;
55                         } catch (Exception e) {
56                                 if (e is IOException)
57                                         throw;
58                                 throw new IOException (SR.GetString (SR.mono_net_io_shutdown), e);
59                         }
60                 }
61
62                 internal void EndShutdown (IAsyncResult asyncResult)
63                 {
64                         if (asyncResult == null)
65                                 throw new ArgumentNullException ("asyncResult");
66
67                         var shutdownResult = asyncResult as ShutdownAsyncResult;
68                         if (shutdownResult == null)
69                                 throw new ArgumentException (SR.GetString (SR.net_io_async_result, asyncResult.GetType ().FullName), "asyncResult");
70
71                         if (shutdownResult.SentShutdown)
72                                 SecureStream.EndShutdown (shutdownResult);
73                 }
74
75                 internal IAsyncResult BeginRenegotiate (AsyncCallback asyncCallback, object asyncState)
76                 {
77                         var lazyResult = new LazyAsyncResult (this, asyncState, asyncCallback);
78
79                         if (Interlocked.Exchange (ref _NestedAuth, 1) == 1)
80                                 throw new InvalidOperationException (SR.GetString (SR.net_io_invalidnestedcall, "BeginRenegotiate", "renegotiate"));
81                         if (Interlocked.CompareExchange (ref _PendingReHandshake, 1, 0) == 1)
82                                 throw new InvalidOperationException (SR.GetString (SR.net_io_invalidnestedcall, "BeginRenegotiate", "renegotiate"));
83
84                         try {
85                                 CheckThrow (false);
86                                 SecureStream.BeginRenegotiate (lazyResult);
87                                 return lazyResult;
88                         } catch (Exception e) {
89                                 _NestedAuth = 0;
90                                 if (e is IOException)
91                                         throw;
92                                 throw new IOException (SR.GetString (SR.mono_net_io_renegotiate), e);
93                         }
94                 }
95
96                 internal void EndRenegotiate (IAsyncResult result)
97                 {
98                         if (result == null)
99                                 throw new ArgumentNullException ("asyncResult");
100
101                         LazyAsyncResult lazyResult = result as LazyAsyncResult;
102                         if (lazyResult == null)
103                                 throw new ArgumentException (SR.GetString (SR.net_io_async_result, result.GetType ().FullName), "asyncResult");
104
105                         if (Interlocked.Exchange (ref _NestedAuth, 0) == 0)
106                                 throw new InvalidOperationException (SR.GetString (SR.net_io_invalidendcall, "EndRenegotiate"));
107
108                         SecureStream.EndRenegotiate (lazyResult);
109                 }
110
111                 internal bool CheckEnqueueHandshakeWrite (byte[] buffer, AsyncProtocolRequest asyncRequest)
112                 {
113                         return CheckEnqueueHandshake (buffer, asyncRequest);
114                 }
115
116                 internal void StartReHandshake (AsyncProtocolRequest asyncRequest)
117                 {
118                         if (IsServer) {
119                                 byte[] buffer = null;
120                                 if (CheckEnqueueHandshakeRead (ref buffer, asyncRequest))
121                                         return;
122
123                                 StartReceiveBlob (buffer, asyncRequest);
124                                 return;
125                         }
126
127                         ForceAuthentication (false, null, asyncRequest);
128                 }
129
130                 class ShutdownAsyncResult : LazyAsyncResult
131                 {
132                         public bool SentShutdown;
133
134                         internal ShutdownAsyncResult (SslState instance, object userState, AsyncCallback callback)
135                                 : base (instance, userState, callback)
136                         {
137                         }
138                 }
139         }
140 }
141 #endif