|
27 | 27 | using Org.BouncyCastle.Utilities.Encoders; |
28 | 28 | using System; |
29 | 29 | using System.Collections.Generic; |
30 | | -using System.Text; |
31 | 30 |
|
32 | 31 | namespace SIPSorcery.Net.SharpSRTP.DTLS |
33 | 32 | { |
34 | 33 | public class DtlsServer : DefaultTlsServer, IDtlsPeer |
35 | 34 | { |
36 | | - protected DatagramTransport _clientDatagramTransport; // valid only for the current session |
| 35 | + private readonly object _syncRoot = new object(); |
| 36 | + protected DatagramTransport _clientDatagramTransport = null; |
37 | 37 |
|
38 | 38 | public int TimeoutMilliseconds { get; set; } = 20000; |
39 | 39 |
|
@@ -131,81 +131,33 @@ protected override int[] GetSupportedCipherSuites() |
131 | 131 | } |
132 | 132 | } |
133 | 133 |
|
134 | | - public virtual DtlsTransport DoHandshake(out string handshakeError, DatagramTransport datagramTransport, Func<string> getRemoteEndpoint, Func<string, DatagramTransport> createClientDatagramTransport) |
| 134 | + public virtual DtlsTransport DoHandshake(out string handshakeError, DatagramTransport datagramTransport, DtlsRequest request = null) |
135 | 135 | { |
136 | | - if (datagramTransport == null) |
| 136 | + lock (_syncRoot) |
137 | 137 | { |
138 | | - throw new ArgumentNullException(nameof(datagramTransport)); |
139 | | - } |
140 | | - |
141 | | - if (createClientDatagramTransport == null) |
142 | | - { |
143 | | - throw new ArgumentNullException(nameof(createClientDatagramTransport)); |
144 | | - } |
145 | | - |
146 | | - DtlsTransport transport = null; |
147 | | - |
148 | | - try |
149 | | - { |
150 | | - DtlsServerProtocol serverProtocol = new DtlsServerProtocol(); |
151 | | - DtlsRequest request = null; |
152 | | - string remoteEndpoint = null; |
153 | | - |
154 | | - if (getRemoteEndpoint != null) |
| 138 | + if (datagramTransport == null) |
155 | 139 | { |
156 | | - // Use DtlsVerifier to require a HelloVerifyRequest cookie exchange before accepting |
157 | | - DtlsVerifier verifier = new DtlsVerifier(Crypto); |
158 | | - int receiveLimit = datagramTransport.GetReceiveLimit(); |
159 | | - byte[] buf = new byte[receiveLimit]; |
160 | | - int receiveAttemptCounter = 0; |
161 | | - |
162 | | - do |
163 | | - { |
164 | | - const int RECEIVE_TIMEOUT = 100; |
165 | | - int length = datagramTransport.Receive(buf, 0, receiveLimit, RECEIVE_TIMEOUT); |
166 | | - if (length > 0) |
167 | | - { |
168 | | - remoteEndpoint = getRemoteEndpoint(); |
169 | | - if (string.IsNullOrEmpty(remoteEndpoint)) |
170 | | - { |
171 | | - throw new InvalidOperationException(); |
172 | | - } |
173 | | - |
174 | | - byte[] clientID = Encoding.UTF8.GetBytes(remoteEndpoint); |
175 | | - request = verifier.VerifyRequest(clientID, buf, 0, length, datagramTransport); |
176 | | - } |
177 | | - else |
178 | | - { |
179 | | - receiveAttemptCounter++; |
180 | | - |
181 | | - if (receiveAttemptCounter * RECEIVE_TIMEOUT >= TimeoutMilliseconds) // 20 seconds so that we don't wait forever |
182 | | - { |
183 | | - handshakeError = "HelloVerifyRequest cookie exchange could not be verified due to a timeout"; |
184 | | - return null; |
185 | | - } |
186 | | - } |
187 | | - } |
188 | | - while (request == null); |
| 140 | + throw new ArgumentNullException(nameof(datagramTransport)); |
189 | 141 | } |
190 | 142 |
|
191 | | - var clientDatagramTransport = createClientDatagramTransport(remoteEndpoint); |
| 143 | + DtlsTransport transport = null; |
192 | 144 |
|
193 | | - // store the current client datagram transport for this session |
194 | | - _clientDatagramTransport = clientDatagramTransport; |
195 | | - |
196 | | - transport = serverProtocol.Accept(this, clientDatagramTransport, request); |
| 145 | + try |
| 146 | + { |
| 147 | + DtlsServerProtocol serverProtocol = new DtlsServerProtocol(); |
| 148 | + _clientDatagramTransport = datagramTransport; |
| 149 | + transport = serverProtocol.Accept(this, datagramTransport, request); |
| 150 | + _clientDatagramTransport = null; |
| 151 | + } |
| 152 | + catch (Exception ex) |
| 153 | + { |
| 154 | + handshakeError = ex.Message; |
| 155 | + return null; |
| 156 | + } |
197 | 157 |
|
198 | | - // clear the reference to the transport after handshake is done |
199 | | - _clientDatagramTransport = null; |
200 | | - } |
201 | | - catch (Exception ex) |
202 | | - { |
203 | | - handshakeError = ex.Message; |
204 | | - return null; |
| 158 | + handshakeError = null; |
| 159 | + return transport; |
205 | 160 | } |
206 | | - |
207 | | - handshakeError = null; |
208 | | - return transport; |
209 | 161 | } |
210 | 162 |
|
211 | 163 | public override void NotifyAlertRaised(short alertLevel, short alertDescription, string message, Exception cause) |
|
0 commit comments