|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #ifndef C_CSTUNTRANSACTION_H |
|
22 #define C_CSTUNTRANSACTION_H |
|
23 |
|
24 // INCLUDES |
|
25 #include <e32base.h> |
|
26 #include <in_sock.h> |
|
27 #include "mnatfwunsafudpsenderobserver.h" |
|
28 #include "cstuntimeruser.h" |
|
29 #include "cnatfwunsafmediaconnsender.h" |
|
30 #include "mncmsenderobserver.h" |
|
31 #include "natfwstunclientdefs.h" |
|
32 |
|
33 // FORWARD DECLARATIONS |
|
34 class RSocket; |
|
35 class CNATFWUNSAFMessage; |
|
36 class CNATFWUNSAFBindingRequest; |
|
37 class CNATFWUNSAFUnknownAttributesAttribute; |
|
38 class CNATFWUNSAFUdpSender; |
|
39 class MSTUNTransactionObserver; |
|
40 class MNcmConnectionMultiplexer; |
|
41 |
|
42 // CLASS DECLARATION |
|
43 |
|
44 /** |
|
45 * This class presents a single STUN transaction. |
|
46 */ |
|
47 class CSTUNTransaction : |
|
48 public CSTUNTimerUser, |
|
49 public MNATFWUNSAFUdpSenderObserver, |
|
50 public MNcmSenderObserver |
|
51 { |
|
52 |
|
53 friend class ut_cstuntransaction; |
|
54 |
|
55 public: // Constructors and destructor |
|
56 |
|
57 /** |
|
58 * Creates a new instance of CSTUNTransaction |
|
59 * @pre aAddress.IsUnspecified() == EFalse |
|
60 * @param aSocket UDP socket to use |
|
61 * @param aAddress STUN server's address where the request is sent to |
|
62 * @param aSharedSecret Shared secret to be used to calculate |
|
63 * a hash over the encoded UNSAF message. |
|
64 * @param aObserver An observer to receive callbacks |
|
65 * @param aTimer Timer provider |
|
66 * @param aRetransmitInterval Initial retransmission interval |
|
67 * @param aTransportProtocol Used transport protocol. |
|
68 * @return A new instance of CSTUNTransaction, ownership is transferred. |
|
69 */ |
|
70 static CSTUNTransaction* |
|
71 NewL( CNATFWUNSAFMessage& aRequest, |
|
72 const TInetAddr& aAddress, |
|
73 const TDesC8& aSharedSecret, |
|
74 RSocket& aSocket, |
|
75 CDeltaTimer& iTimer, |
|
76 TInt aRetransmitInterval, |
|
77 MSTUNTransactionObserver& aObserver, |
|
78 const TDesC8& aProtocol, |
|
79 TTransportProtocol aTransportProtocol ); |
|
80 |
|
81 /** |
|
82 * Overload version of NewL |
|
83 * |
|
84 * Creates a new instance of CSTUNTransaction |
|
85 * @pre aAddress.IsUnspecified() == EFalse |
|
86 * @param aRequest Binding Request message |
|
87 * @param aAddress STUN server's address where the request is sent to |
|
88 * @param aSharedSecret Shared secret to be used to calculate |
|
89 * a hash over the encoded UNSAF message. |
|
90 * @param aStreamId Used natfw stream id |
|
91 * @param aSubstreamId Used natfw stream related sub stream id |
|
92 * @param aTimer Timer provider |
|
93 * @param aRetransmitInterval Initial retransmission interval |
|
94 * @param aObserver An observer to receive callbacks |
|
95 * @param aProtocol Used protocol, either "stun" or "stun-relay" |
|
96 * @param aMux instance of connection multiplexer |
|
97 * @param aTransportProtocol Used transport protocol. |
|
98 * @param aUseFingerprint ETrue if fingerprint is added to request |
|
99 * @param aDestAddr Destination address |
|
100 * @return A new instance of CSTUNTransaction, ownership is transferred. |
|
101 */ |
|
102 static CSTUNTransaction* |
|
103 NewL( CNATFWUNSAFMessage& aRequest, |
|
104 const TInetAddr& aAddress, |
|
105 const TDesC8& aSharedSecret, |
|
106 TUint aStreamId, |
|
107 TUint aSubstreamId, |
|
108 CDeltaTimer& aTimer, |
|
109 TInt aRetransmitInterval, |
|
110 MSTUNTransactionObserver& aObserver, |
|
111 const TDesC8& aProtocol, |
|
112 MNcmConnectionMultiplexer& aMux, |
|
113 TTransportProtocol aTransportProtocol, |
|
114 TBool aUseFingerprint=EFalse, |
|
115 const TInetAddr& aDestAddr=KAFUnspec ); |
|
116 |
|
117 ~CSTUNTransaction(); |
|
118 |
|
119 public: // From CSTUNTimerUser |
|
120 |
|
121 void TimerExpiredL(); |
|
122 |
|
123 void LeaveFromTimerExpired( TInt aError ); |
|
124 |
|
125 public: // From MUNSAFUdpSenderObserver |
|
126 |
|
127 void UNSAFUdpMessageSentL(); |
|
128 |
|
129 void UNSAFUdpMessageFailure( TInt aError ); |
|
130 |
|
131 public: // From MNcmSenderObserver |
|
132 |
|
133 void MessageSent(); |
|
134 |
|
135 void MessageSentFailure( TInt aError ); |
|
136 |
|
137 public: // New functions |
|
138 |
|
139 void SendRequestL(); |
|
140 |
|
141 void RetransmitRequestL(); |
|
142 |
|
143 /** |
|
144 * Transaction receives a Binding (Error) Response message. |
|
145 * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse || |
|
146 * aResponse.Type() == CUNSAFMessage::EBindingErrorResponse |
|
147 * @param aResponse STUN message, either a Binding Response or a |
|
148 * Binding Error Response |
|
149 * @param aByteStream Same STUN message as aResponse, but in undecoded |
|
150 * format. |
|
151 */ |
|
152 void ReceiveL( CNATFWUNSAFMessage& aResponse, const TDesC8& aByteStream ); |
|
153 |
|
154 /** |
|
155 * Transaction has encountered an error and enters terminated state. |
|
156 * @param aError Error reason. If transaction ends successfully, value |
|
157 * is KErrNone. |
|
158 */ |
|
159 void Terminate( TInt aError ); |
|
160 |
|
161 /** |
|
162 * TimerValue can be queried. This timer value is from |
|
163 * SetActiveDestinationResponse TIMERVAL attribute. |
|
164 * |
|
165 * @since s60 3.2 |
|
166 * @return timer value |
|
167 */ |
|
168 const TUint32& TimerValue() const; |
|
169 |
|
170 /** |
|
171 * ICE specific cancel for stopping ongoing message retransmission. |
|
172 * Response is waited as long as sending timer expires. After that |
|
173 * client will be notified with error response. |
|
174 * |
|
175 * @since s60 3.2 |
|
176 * @return void |
|
177 */ |
|
178 void CancelRetransmission(); |
|
179 |
|
180 |
|
181 private: // Enumerations |
|
182 |
|
183 enum TRetransmissionCount |
|
184 { |
|
185 // Maximum amount of Binding Requests to send |
|
186 KMaxRequestSentCount = 7 // rfc3489bis-06#section-7.1 |
|
187 }; |
|
188 |
|
189 private: // Constructors |
|
190 |
|
191 CSTUNTransaction( CNATFWUNSAFMessage& aRequest, |
|
192 const TInetAddr& aAddress, |
|
193 const TDesC8& aSharedSecret, |
|
194 CDeltaTimer& iTimer, |
|
195 TInt aRetransmitInterval, |
|
196 MSTUNTransactionObserver& aObserver, |
|
197 TTransportProtocol aTransportProtocol ); |
|
198 |
|
199 CSTUNTransaction( CNATFWUNSAFMessage& aRequest, |
|
200 const TInetAddr& aAddress, |
|
201 const TDesC8& aSharedSecret, |
|
202 TUint aStreamId, |
|
203 TUint aSubstreamId, |
|
204 CDeltaTimer& iTimer, |
|
205 TInt aRetransmitInterval, |
|
206 MSTUNTransactionObserver& aObserver, |
|
207 const TInetAddr& aDestAddr, |
|
208 TTransportProtocol aTransportProtocol, |
|
209 TBool aUseFingerprint ); |
|
210 |
|
211 CSTUNTransaction(); |
|
212 |
|
213 CSTUNTransaction( const CSTUNTransaction& aTransaction ); |
|
214 |
|
215 void ConstructL( RSocket& aSocket, const TDesC8& aProtocol ); |
|
216 |
|
217 void ConstructL( const TDesC8& aProtocol, |
|
218 MNcmConnectionMultiplexer& aMux ); |
|
219 |
|
220 private: // New functions, for internal use |
|
221 |
|
222 /** |
|
223 * Return the current retransmission interval in milliseconds. |
|
224 * @return Retransmission interval |
|
225 */ |
|
226 TInt RetransmitInterval(); |
|
227 |
|
228 /** |
|
229 * Computes how long transaction waits for response after it has received |
|
230 * a Binding Error Response with response code 100-399. |
|
231 * @return Duration in milliseconds. |
|
232 */ |
|
233 TInt ComputeWaitDuration(); |
|
234 |
|
235 /** |
|
236 * Determines if the response should be ignored or processed. |
|
237 * @param aResponse STUN Binding (Error) Response |
|
238 * @return ETrue Response must be ignored, EFalse otherwise |
|
239 */ |
|
240 TBool ShouldIgnoreResponse( const CNATFWUNSAFMessage& aResponse ) const; |
|
241 |
|
242 /** |
|
243 * Determines if the response should be ignored or processed. |
|
244 * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse || |
|
245 * aResponse.Type() == CUNSAFMessage::EBindingErrorResponse |
|
246 * @param aResponse STUN message, either a Binding Response or a |
|
247 * Binding Error Response |
|
248 * @param aByteStream Same STUN message as aResponse, but in undecoded |
|
249 * format. |
|
250 * @return KErrNone if transaction ends successfully, 400-699 if a |
|
251 * Binding Error Response was received, or a system wide error |
|
252 * code. |
|
253 */ |
|
254 TInt ProcessResponseL( CNATFWUNSAFMessage& aResponse, |
|
255 const TDesC8& aByteStream ); |
|
256 |
|
257 /** |
|
258 * Verify the integrity of a Binding Response. |
|
259 * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse |
|
260 * @param aResponse Binding Response |
|
261 * @param aByteStream Same message as aResponse, but in undecoded format |
|
262 * @return KErrNone If integrity check succeeded |
|
263 * ERetryAfterAddingXorOnly If integrity fails because a NAT has |
|
264 * overwritten ip-address in MAPPED-ADDRESS. |
|
265 * KErrCorrupt Integrity fails for some other reason. |
|
266 */ |
|
267 TInt CheckIntegrityL( const CNATFWUNSAFMessage& aResponse, |
|
268 const TDesC8& aByteStream ); |
|
269 |
|
270 /** |
|
271 * Check if the Binding Response has a different MAPPED-ADDRESS or |
|
272 * XOR-MAPPED-ADDRESS from the ones that have been received earlier. |
|
273 * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse |
|
274 * @param aResponse STUN Binding Response |
|
275 * @return ETrue The address in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS of |
|
276 * the aResponse differs from the earlier address. |
|
277 * EFalse otherwise |
|
278 */ |
|
279 TBool AddressDiffersL( const CNATFWUNSAFMessage& aResponse ) const; |
|
280 |
|
281 /** |
|
282 * Determines if the message integrity check failed because of a NAT has |
|
283 * overwritten the IP-address in the MAPPED-ADDRESS. |
|
284 * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse |
|
285 * @param aResponse STUN Binding Response |
|
286 * @return ETrue NAT probably overwrote the IP-address in MAPPED-ADDRESS |
|
287 * EFalse Integrity check failed for some other reason |
|
288 */ |
|
289 TBool CheckForNatOverwriteL( const CNATFWUNSAFMessage& aResponse ); |
|
290 |
|
291 /** |
|
292 * Gets the response code value from a ERROR-CODE attribute of the |
|
293 * aResponse. |
|
294 * @param aResponse UNSAF Binding Response or UNSAF Binding Error |
|
295 * Response |
|
296 * @return Response code, or KErrNotFound if ERROR-CODE was not present. |
|
297 */ |
|
298 TInt GetResponseCode( const CNATFWUNSAFMessage& aResponse ) const; |
|
299 |
|
300 /** |
|
301 * Checks if used protocol is valid. Will leave with KErrArgument |
|
302 * if protocol is not valid. |
|
303 * |
|
304 * @since s60 3.2 |
|
305 * @param aProtocol Used protocol ("stun" or "stun-relay"). |
|
306 * @return void |
|
307 */ |
|
308 void CheckProtocolL( const TDesC8& aProtocol ); |
|
309 |
|
310 /** |
|
311 * Gets the response code value from a ERROR-CODE attribute of the |
|
312 * aResponse. |
|
313 * |
|
314 * @since s60 3.2 |
|
315 * @return true if relay used |
|
316 */ |
|
317 TBool StunRelayUsed(); |
|
318 |
|
319 /** |
|
320 * Method for new RTT sample measuring |
|
321 * |
|
322 * @since s60 3.2 |
|
323 * @return void |
|
324 */ |
|
325 void MeasureNewRTTSample(); |
|
326 |
|
327 |
|
328 private: // Data |
|
329 |
|
330 MSTUNTransactionObserver& iObserver; |
|
331 |
|
332 // Binding Request message. Not owned. |
|
333 CNATFWUNSAFMessage& iRequest; |
|
334 |
|
335 // STUN server's address where the request is sent to |
|
336 const TInetAddr& iAddress; |
|
337 |
|
338 // Shared secret for calculating a hash |
|
339 const TDesC8& iSharedSecret; |
|
340 |
|
341 // Provides UDP sending services. Owned. |
|
342 CNATFWUNSAFUdpSender* iSender; |
|
343 |
|
344 // Provides sending services. Owned. |
|
345 CNATFWUNSAFMediaConnSender* iMediaConSender; |
|
346 |
|
347 // Amount of sent Binding Requests |
|
348 TInt iSendCount; |
|
349 |
|
350 // Initial retransmission interval, milliseconds |
|
351 TInt iInitialRetransmitInterval; |
|
352 |
|
353 // Current retransmission interval, milliseconds |
|
354 TInt iRetransmitInterval; |
|
355 |
|
356 // Public address received from a Binding Response's MAPPED-ADDRESS |
|
357 // attribute |
|
358 TInetAddr iMappedAddress; |
|
359 |
|
360 // Public address received from a Binding Response's XOR-MAPPED-ADDRESS |
|
361 // attribute |
|
362 TInetAddr iXorMappedAddress; |
|
363 |
|
364 // Public address received from a Binding Response's RELAY-ADDRESS |
|
365 // attribute |
|
366 TInetAddr iRelayAddress; |
|
367 |
|
368 // UNKNOWN-ATTRIBUTES received from a 420 error response. Owned. |
|
369 CNATFWUNSAFUnknownAttributesAttribute* iUnknownAttr; |
|
370 |
|
371 // ETrue if the request should be retransmitted with specified interval. |
|
372 // EFalse when retransmission must not be done any longer. |
|
373 TBool iRetransmit; |
|
374 |
|
375 // Has the transaction terminated |
|
376 TBool iTerminated; |
|
377 |
|
378 // Used natfw stream id |
|
379 TUint iStreamId; |
|
380 |
|
381 // Used natfw substream id |
|
382 TUint iSubstreamId; |
|
383 |
|
384 /** |
|
385 * Used protocol, either "stun" or "stun-relay" |
|
386 */ |
|
387 HBufC8* iProtocol; |
|
388 |
|
389 /** |
|
390 * Timer value from attribute |
|
391 */ |
|
392 TUint32 iTimerValue; |
|
393 |
|
394 /** |
|
395 * Destination Address |
|
396 */ |
|
397 TInetAddr iDestAddr; |
|
398 |
|
399 /** |
|
400 * Contains state information, e.g. request is pending --> ETrue |
|
401 */ |
|
402 TBool iRequestPending; |
|
403 |
|
404 /** |
|
405 * Used transport protocol |
|
406 */ |
|
407 TTransportProtocol iTransportProtocol; |
|
408 |
|
409 /** |
|
410 * Indicates hometime for last sent transaction. |
|
411 */ |
|
412 TTime iSendTime; |
|
413 |
|
414 /** |
|
415 * This is compare value to find out is the request retransmitted. |
|
416 * Default value is one. |
|
417 */ |
|
418 TInt iRetransmitCompareValue; |
|
419 |
|
420 /** |
|
421 * ETrue if fingerprint will be added to transactions |
|
422 */ |
|
423 TBool iUseFingerprint; |
|
424 |
|
425 /** |
|
426 * Disable resending packets in this transaction, only consume time |
|
427 * while this flag is ETrue. |
|
428 */ |
|
429 TBool iDisableSending; |
|
430 |
|
431 private: // For testing purposes |
|
432 |
|
433 #ifdef TEST_EUNIT |
|
434 friend class CSTUNClientTest; |
|
435 friend class CSTUNBindingTest; |
|
436 friend class CSTUNBindingImplementationTest; |
|
437 friend class CSTUNTransactionTest; |
|
438 #endif |
|
439 __DECLARE_TEST; |
|
440 }; |
|
441 |
|
442 #endif // C_CSTUNTRANSACTION_H |