|
1 /* |
|
2 * Copyright (c) 2007 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 #include "cnattraversalcontroller.h" |
|
20 #include "sipnattraversalcontrollerinitparams.h" |
|
21 #include "sipnatbindingobserver.h" |
|
22 #include "sipnattraversalrequestobserver.h" |
|
23 #include "cnattraversalconfig.h" |
|
24 #include "cnattraversalsession.h" |
|
25 #include "nattraversalsocketuser.h" |
|
26 #include "nattraversallog.h" |
|
27 #include <siperr.h> |
|
28 |
|
29 _LIT8(KZeroIPAddress, "0.0.0.0"); |
|
30 |
|
31 // ----------------------------------------------------------------------------- |
|
32 // CNATTraversalController::NewL |
|
33 // ----------------------------------------------------------------------------- |
|
34 // |
|
35 CNATTraversalController* CNATTraversalController::NewL(TAny* aInitParams) |
|
36 { |
|
37 __ASSERT_ALWAYS (aInitParams, User::Leave(KErrArgument)); |
|
38 TSIPNATTraversalControllerInitParams* params = |
|
39 static_cast<TSIPNATTraversalControllerInitParams*>(aInitParams); |
|
40 CNATTraversalController* self = |
|
41 new(ELeave)CNATTraversalController(params->iSocketServ); |
|
42 CleanupStack::PushL(self); |
|
43 self->ConstructL(); |
|
44 CleanupStack::Pop(self); |
|
45 return self; |
|
46 } |
|
47 |
|
48 // ----------------------------------------------------------------------------- |
|
49 // CNATTraversalController::CNATTraversalController |
|
50 // ----------------------------------------------------------------------------- |
|
51 // |
|
52 CNATTraversalController::CNATTraversalController(RSocketServ& aSocketServ) |
|
53 : iSocketServ(aSocketServ), |
|
54 iRequestOrder(TNATTraversalPendingRequest::RequestOrder) |
|
55 { |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // CNATTraversalController::ConstructL |
|
60 // ----------------------------------------------------------------------------- |
|
61 // |
|
62 void CNATTraversalController::ConstructL() |
|
63 { |
|
64 iDeltaTimer = CDeltaTimer::NewL(CActive::EPriorityStandard); |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CNATTraversalController::~CNATTraversalController |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 CNATTraversalController::~CNATTraversalController() |
|
72 { |
|
73 iSessions.ResetAndDestroy(); |
|
74 for (TInt i=0; i < iPendingRequests.Count(); i++) |
|
75 { |
|
76 if (iDeltaTimer) |
|
77 { |
|
78 iDeltaTimer->Remove(iPendingRequests[i].DeltaTimerEntry()); |
|
79 } |
|
80 } |
|
81 iPendingRequests.Close(); |
|
82 delete iDeltaTimer; |
|
83 iSocketUserQueue.Close(); |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CNATTraversalController::ResolvePublicAddrL |
|
88 // From CSIPNATTraversalController |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 TUint32 CNATTraversalController::ResolvePublicAddrL( |
|
92 TUint32 aIapId, |
|
93 RConnection& aConnection, |
|
94 const TInetAddr& aLocalAddr, |
|
95 const TDesC8& aDomain, |
|
96 RSocket& aUdpSocket, |
|
97 const TInetAddr& aNextHopAddr, |
|
98 MSIPNATBindingObserver* aBindingObserver, |
|
99 MSIPNATTraversalRequestObserver& aRequestObserver) |
|
100 { |
|
101 __ASSERT_ALWAYS(NULL != aBindingObserver,User::Leave(KErrArgument)); |
|
102 TUint32 requestId = NextRequestId(); |
|
103 TBool asyncCallInitiated = EFalse; |
|
104 |
|
105 if (!BindingExists(aBindingObserver)) |
|
106 { |
|
107 CNATTraversalConfig* config = CNATTraversalConfig::NewLC(aIapId,aDomain); |
|
108 |
|
109 CreateBindingL(requestId,config,aConnection,aLocalAddr,aUdpSocket, |
|
110 aNextHopAddr,*aBindingObserver,aRequestObserver, |
|
111 asyncCallInitiated); |
|
112 |
|
113 CleanupStack::Pop(config); // ownership transferred |
|
114 } |
|
115 |
|
116 if (!asyncCallInitiated) |
|
117 { |
|
118 // Start a timer with a minimum value to make the call asynchronous |
|
119 TNATTraversalPendingRequest request(requestId,&aRequestObserver,*this); |
|
120 iPendingRequests.InsertInOrderL(request,iRequestOrder); |
|
121 TInt index = iPendingRequests.FindInOrder(request,iRequestOrder); |
|
122 if (0 <= index && iPendingRequests.Count() > index) |
|
123 { |
|
124 iDeltaTimer->Queue(1,iPendingRequests[index].DeltaTimerEntry()); |
|
125 } |
|
126 } |
|
127 |
|
128 return requestId; |
|
129 } |
|
130 |
|
131 // ----------------------------------------------------------------------------- |
|
132 // CNATTraversalController::Cancel |
|
133 // From CSIPNATTraversalController |
|
134 // ----------------------------------------------------------------------------- |
|
135 // |
|
136 void CNATTraversalController::Cancel(TUint32 aRequestId) |
|
137 { |
|
138 NATTRAVERSAL_LOG("CNATTraversalController::Cancel") |
|
139 TNATTraversalPendingRequest tmp(aRequestId,0,*this); |
|
140 TInt index = iPendingRequests.FindInOrder(tmp,iRequestOrder); |
|
141 if (0 <= index && iPendingRequests.Count() > index) |
|
142 { |
|
143 iDeltaTimer->Remove(iPendingRequests[index].DeltaTimerEntry()); |
|
144 iPendingRequests.Remove(index); |
|
145 } |
|
146 else |
|
147 { |
|
148 TBool found = EFalse; |
|
149 for (TInt i=0; i < iSessions.Count() && !found; i++) |
|
150 { |
|
151 found = iSessions[i]->RemoveBinding(aRequestId); |
|
152 } |
|
153 } |
|
154 } |
|
155 |
|
156 // ----------------------------------------------------------------------------- |
|
157 // CNATTraversalController::RefreshNATBindingL |
|
158 // From CSIPNATTraversalController |
|
159 // ----------------------------------------------------------------------------- |
|
160 // |
|
161 TBool CNATTraversalController::RefreshNATBindingL( |
|
162 RSocket& aSocket, |
|
163 const MSIPNATBindingObserver* aBindingObserver) |
|
164 { |
|
165 NATTRAVERSAL_LOG("CNATTraversalController::RefreshNATBindingL - TCP/UDP") |
|
166 TBool maintainPersistentConnection = EFalse; |
|
167 TBool handled = EFalse; |
|
168 for (TInt i=0; i < iSessions.Count() && !handled; i++) |
|
169 { |
|
170 iSessions[i]->RefreshNATBindingL( |
|
171 aSocket,aBindingObserver, |
|
172 maintainPersistentConnection,handled); |
|
173 } |
|
174 return maintainPersistentConnection; |
|
175 } |
|
176 |
|
177 // ----------------------------------------------------------------------------- |
|
178 // CNATTraversalController::RefreshNATBindingL |
|
179 // From CSIPNATTraversalController |
|
180 // ----------------------------------------------------------------------------- |
|
181 // |
|
182 TBool CNATTraversalController::RefreshNATBindingL( |
|
183 CSecureSocket& aSecureSocket, |
|
184 const MSIPNATBindingObserver* aBindingObserver) |
|
185 { |
|
186 NATTRAVERSAL_LOG("CNATTraversalController::RefreshNATBindingL - TLS") |
|
187 TBool maintainPersistentConnection = EFalse; |
|
188 TBool handled = EFalse; |
|
189 for (TInt i=0; i < iSessions.Count() && !handled; i++) |
|
190 { |
|
191 iSessions[i]->RefreshNATBindingL( |
|
192 aSecureSocket,aBindingObserver, |
|
193 maintainPersistentConnection,handled); |
|
194 } |
|
195 return maintainPersistentConnection; |
|
196 } |
|
197 |
|
198 // ----------------------------------------------------------------------------- |
|
199 // CNATTraversalController::UpdateNextHop |
|
200 // ----------------------------------------------------------------------------- |
|
201 // |
|
202 void CNATTraversalController::UpdateNextHop( |
|
203 const TInetAddr& aNextHopAddr, |
|
204 const MSIPNATBindingObserver* aBindingObserver) |
|
205 { |
|
206 NATTRAVERSAL_ADDRLOG("CNATTraversalController::UpdateNextHop ->", |
|
207 aNextHopAddr) |
|
208 for (TInt i=0; i < iSessions.Count(); i++) |
|
209 { |
|
210 CNATTraversalSession* session = iSessions[i]; |
|
211 if (session->HasBinding(aBindingObserver)) |
|
212 { |
|
213 session->UpdateNextHop(aNextHopAddr); |
|
214 return; |
|
215 } |
|
216 } |
|
217 } |
|
218 |
|
219 // ----------------------------------------------------------------------------- |
|
220 // CNATTraversalController::SocketIdle |
|
221 // From CSIPNATTraversalController |
|
222 // ----------------------------------------------------------------------------- |
|
223 // |
|
224 void CNATTraversalController::SocketIdle( |
|
225 TBool aIdle, |
|
226 RSocket& aSocket) |
|
227 { |
|
228 NATTRAVERSAL_INTLOG("CNATTraversalController::SocketIdle - TCP/UDP", aIdle) |
|
229 for (TInt i=0; i < iSessions.Count(); i++) |
|
230 { |
|
231 iSessions[i]->SocketIdle(aIdle,aSocket); |
|
232 } |
|
233 if (!aIdle) |
|
234 { |
|
235 TBool firstRemoved = EFalse; |
|
236 for (TInt i=iSocketUserQueue.Count()-1; i >= 0; i--) |
|
237 { |
|
238 const RSocket& socket = iSocketUserQueue[i]->Socket(); |
|
239 if (socket.SubSessionHandle() == aSocket.SubSessionHandle()) |
|
240 { |
|
241 iSocketUserQueue[i]->CancelSending(); |
|
242 iSocketUserQueue.Remove(i); |
|
243 firstRemoved = (i == 0); |
|
244 } |
|
245 } |
|
246 if (firstRemoved) |
|
247 { |
|
248 HandleNextFromSocketUserQueue(); |
|
249 } |
|
250 } |
|
251 } |
|
252 |
|
253 // ----------------------------------------------------------------------------- |
|
254 // CNATTraversalController::SocketIdle |
|
255 // From CSIPNATTraversalController |
|
256 // ----------------------------------------------------------------------------- |
|
257 // |
|
258 void CNATTraversalController::SocketIdle( |
|
259 TBool aIdle, |
|
260 CSecureSocket& aSecureSocket) |
|
261 { |
|
262 NATTRAVERSAL_INTLOG("CNATTraversalController::SocketIdle - TLS", aIdle) |
|
263 for (TInt i=0; i < iSessions.Count(); i++) |
|
264 { |
|
265 iSessions[i]->SocketIdle(aIdle,aSecureSocket); |
|
266 } |
|
267 } |
|
268 |
|
269 // ----------------------------------------------------------------------------- |
|
270 // CNATTraversalController::DataReceived |
|
271 // From CSIPNATTraversalController |
|
272 // ----------------------------------------------------------------------------- |
|
273 // |
|
274 void CNATTraversalController::DataReceivedL( |
|
275 const TDesC8& aData, |
|
276 const RSocket& aSocket, |
|
277 TBool& aHandled) |
|
278 { |
|
279 NATTRAVERSAL_LOG("CNATTraversalController::DataReceivedL"); |
|
280 aHandled = EFalse; |
|
281 for (TInt i=0; i < iSessions.Count() && !aHandled; i++) |
|
282 { |
|
283 iSessions[i]->DataReceivedL(aData,aSocket,aHandled); |
|
284 } |
|
285 } |
|
286 |
|
287 // ----------------------------------------------------------------------------- |
|
288 // CNATTraversalController::FreeResources |
|
289 // From CSIPNATTraversalController |
|
290 // ----------------------------------------------------------------------------- |
|
291 // |
|
292 void CNATTraversalController::FreeResources(TUint32 aIapId) |
|
293 { |
|
294 NATTRAVERSAL_LOG("CNATTraversalController::FreeResources for IAP") |
|
295 for (TInt i = iSessions.Count()-1; i >= 0; i--) |
|
296 { |
|
297 CNATTraversalSession* session = iSessions[i]; |
|
298 if (session->IapId() == aIapId) |
|
299 { |
|
300 iSessions.Remove(i); |
|
301 delete session; |
|
302 } |
|
303 } |
|
304 } |
|
305 |
|
306 // ----------------------------------------------------------------------------- |
|
307 // CNATTraversalController::FreeResources |
|
308 // From CSIPNATTraversalController |
|
309 // ----------------------------------------------------------------------------- |
|
310 // |
|
311 void CNATTraversalController::FreeResources( |
|
312 MSIPNATBindingObserver& aBindingObserver) |
|
313 { |
|
314 NATTRAVERSAL_LOG("CNATTraversalController::FreeResources for observer") |
|
315 for (TInt i=iSessions.Count()-1; i>=0; i--) |
|
316 { |
|
317 CNATTraversalSession* session = iSessions[i]; |
|
318 session->RemoveBinding(aBindingObserver); |
|
319 if (!session->HasBindings()) |
|
320 { |
|
321 iSessions.Remove(i); |
|
322 delete session; |
|
323 } |
|
324 } |
|
325 } |
|
326 |
|
327 // ----------------------------------------------------------------------------- |
|
328 // CNATTraversalController::RequestCompleted |
|
329 // From MNATTraversalPendingRequestContainer |
|
330 // ----------------------------------------------------------------------------- |
|
331 // |
|
332 void CNATTraversalController::RequestCompleted( |
|
333 TUint32 aRequestId) |
|
334 { |
|
335 NATTRAVERSAL_LOG("CNATTraversalController::RequestCompleted") |
|
336 TNATTraversalPendingRequest tmp(aRequestId,0,*this); |
|
337 TInt index = iPendingRequests.FindInOrder(tmp,iRequestOrder); |
|
338 if (0 <= index && iPendingRequests.Count() > index) |
|
339 { |
|
340 TNATTraversalPendingRequest request = iPendingRequests[index]; // copy |
|
341 iDeltaTimer->Remove(iPendingRequests[index].DeltaTimerEntry()); |
|
342 iPendingRequests.Remove(index); // remove from array |
|
343 request.CompleteRequest(); // use copy for informing the observer |
|
344 } |
|
345 } |
|
346 |
|
347 // ----------------------------------------------------------------------------- |
|
348 // CNATTraversalController::STUNClientInitCompleted |
|
349 // From MSTUNClientObserver |
|
350 // ----------------------------------------------------------------------------- |
|
351 // |
|
352 void CNATTraversalController::STUNClientInitCompleted( |
|
353 const CSTUNClient& aClient, |
|
354 TInt aCompletionCode) |
|
355 { |
|
356 TBool found = EFalse; |
|
357 for (TInt i=0; i<iSessions.Count() && !found; i++) |
|
358 { |
|
359 CNATTraversalSession* session = iSessions[i]; |
|
360 if (session->HasSTUNClient(aClient)) |
|
361 { |
|
362 found = ETrue; |
|
363 if (aCompletionCode != KErrNone) |
|
364 { |
|
365 if (KErrNATFWDnsFailure == aCompletionCode) |
|
366 { |
|
367 aCompletionCode = KErrSIPResolvingFailure; |
|
368 } |
|
369 session->InitFailed(aCompletionCode); |
|
370 } |
|
371 else |
|
372 { |
|
373 TRAPD(err,session->InitCompletedL()); |
|
374 if (err) |
|
375 { |
|
376 session->InitFailed(err); |
|
377 } |
|
378 } |
|
379 } |
|
380 } |
|
381 } |
|
382 |
|
383 // ----------------------------------------------------------------------------- |
|
384 // CNATTraversalController::STUNBindingEventOccurredL |
|
385 // From MSTUNClientObserver |
|
386 // ----------------------------------------------------------------------------- |
|
387 // |
|
388 void CNATTraversalController::STUNBindingEventOccurredL( |
|
389 TSTUNBindingEvent aEvent, |
|
390 const CBinding& aBinding) |
|
391 { |
|
392 if (aEvent == MSTUNClientObserver::EPublicAddressResolved) |
|
393 { |
|
394 TBool found = EFalse; |
|
395 for (TInt i=0; i<iSessions.Count() && !found; i++) |
|
396 { |
|
397 CNATTraversalSession* session = iSessions[i]; |
|
398 found = session->AddressResolvedL(aBinding); |
|
399 } |
|
400 } |
|
401 } |
|
402 |
|
403 // ----------------------------------------------------------------------------- |
|
404 // CNATTraversalController::STUNBindingErrorOccurred |
|
405 // From MSTUNClientObserver |
|
406 // ----------------------------------------------------------------------------- |
|
407 // |
|
408 void CNATTraversalController::STUNBindingErrorOccurred( |
|
409 const CBinding& aBinding, |
|
410 TInt aError) |
|
411 { |
|
412 TBool found = EFalse; |
|
413 for (TInt i=0; i<iSessions.Count() && !found; i++) |
|
414 { |
|
415 CNATTraversalSession* session = iSessions[i]; |
|
416 found = session->BindingFailed(aBinding,aError); |
|
417 } |
|
418 } |
|
419 |
|
420 // ----------------------------------------------------------------------------- |
|
421 // CNATTraversalController::AddToSendingQueueL |
|
422 // From MNATTraversalSocketManager |
|
423 // ----------------------------------------------------------------------------- |
|
424 // |
|
425 TBool CNATTraversalController::AddToSendingQueueL( |
|
426 MNATTraversalSocketUser& aUser) |
|
427 { |
|
428 TBool requestPendingForSocket = EFalse; |
|
429 for (TInt i=0; i < iSocketUserQueue.Count(); i++) |
|
430 { |
|
431 const RSocket& socket = iSocketUserQueue[i]->Socket(); |
|
432 if (socket.SubSessionHandle() == aUser.Socket().SubSessionHandle()) |
|
433 { |
|
434 requestPendingForSocket = ETrue; |
|
435 } |
|
436 } |
|
437 iSocketUserQueue.AppendL(&aUser); |
|
438 return requestPendingForSocket; |
|
439 } |
|
440 |
|
441 // ----------------------------------------------------------------------------- |
|
442 // CNATTraversalController::SendingCompleted |
|
443 // From MNATTraversalSocketManager |
|
444 // ----------------------------------------------------------------------------- |
|
445 // |
|
446 void CNATTraversalController::SendingCompleted(MNATTraversalSocketUser& aUser) |
|
447 { |
|
448 TInt index = iSocketUserQueue.Find(&aUser); |
|
449 if (index >= 0) |
|
450 { |
|
451 iSocketUserQueue.Remove(index); |
|
452 if (index == 0) |
|
453 { |
|
454 HandleNextFromSocketUserQueue(); |
|
455 } |
|
456 } |
|
457 } |
|
458 |
|
459 // ----------------------------------------------------------------------------- |
|
460 // CNATTraversalController::NextRequestId |
|
461 // ----------------------------------------------------------------------------- |
|
462 // |
|
463 TUint32 CNATTraversalController::NextRequestId() |
|
464 { |
|
465 if (iRequestIdCounter == KMaxTUint32) |
|
466 { |
|
467 iRequestIdCounter = 1; |
|
468 } |
|
469 else |
|
470 { |
|
471 iRequestIdCounter++; |
|
472 } |
|
473 return iRequestIdCounter; |
|
474 } |
|
475 |
|
476 // ----------------------------------------------------------------------------- |
|
477 // CNATTraversalController::CreateBindingL |
|
478 // ----------------------------------------------------------------------------- |
|
479 // |
|
480 void CNATTraversalController::CreateBindingL( |
|
481 TUint32 aRequestId, |
|
482 CNATTraversalConfig* aConfig, |
|
483 RConnection& aConnection, |
|
484 const TInetAddr& aLocalAddr, |
|
485 RSocket& aUdpSocket, |
|
486 const TInetAddr& aNextHopAddr, |
|
487 MSIPNATBindingObserver& aBindingObserver, |
|
488 MSIPNATTraversalRequestObserver& aRequestObserver, |
|
489 TBool& aAsyncInitiated) |
|
490 { |
|
491 __ASSERT_ALWAYS(aConfig, User::Leave(KErrArgument)); |
|
492 |
|
493 __ASSERT_ALWAYS(!BindingExists(&aBindingObserver), |
|
494 User::Leave(KErrAlreadyExists)); |
|
495 |
|
496 TBool useSTUN = (aConfig->STUNServer().Compare(KZeroIPAddress) != 0); |
|
497 if (!useSTUN) |
|
498 { |
|
499 aAsyncInitiated = EFalse; |
|
500 if ( aConfig->CRLFRefreshEnabledToProxyValue() != |
|
501 CNATTraversalConfig::EEnabled ) |
|
502 { |
|
503 // No need to create binding nor a dummy CRLF refresh |
|
504 delete aConfig; |
|
505 return; |
|
506 } |
|
507 } |
|
508 |
|
509 TInt index = FindSessionIndex(aConfig->IapId(),aConfig->Domain()); |
|
510 if (index >= 0) |
|
511 { |
|
512 // Session exists |
|
513 CNATTraversalSession* session = iSessions[index]; |
|
514 session->CreateNATBindingL(aRequestId,aUdpSocket, |
|
515 aBindingObserver,aRequestObserver, |
|
516 aAsyncInitiated); |
|
517 delete aConfig; // ownership transferred after leaving functions |
|
518 } |
|
519 else |
|
520 { |
|
521 // Create new session and add a binding |
|
522 CNATTraversalSession* session = |
|
523 CNATTraversalSession::NewLC(*iDeltaTimer,iSocketServ,aConnection, |
|
524 aLocalAddr,aNextHopAddr,aConfig, |
|
525 *this,*this); |
|
526 TCleanupItem cleanupItem(DetachConfigFromSession,session); |
|
527 CleanupStack::PushL(cleanupItem); |
|
528 session->CreateNATBindingL(aRequestId,aUdpSocket, |
|
529 aBindingObserver,aRequestObserver, |
|
530 aAsyncInitiated); |
|
531 iSessions.AppendL(session); |
|
532 CleanupStack::Pop(); // cleanupItem |
|
533 CleanupStack::Pop(session); |
|
534 } |
|
535 } |
|
536 |
|
537 // ----------------------------------------------------------------------------- |
|
538 // CNATTraversalController::FindSessionIndex |
|
539 // ----------------------------------------------------------------------------- |
|
540 // |
|
541 TInt CNATTraversalController::FindSessionIndex( |
|
542 TUint32 aIapId, |
|
543 const TDesC8& aDomain) const |
|
544 { |
|
545 for (TInt i=0; i < iSessions.Count(); i++) |
|
546 { |
|
547 CNATTraversalSession* session = iSessions[i]; |
|
548 if (session->IapId() == aIapId && |
|
549 session->Domain().CompareF(aDomain) == 0) |
|
550 { |
|
551 return i; |
|
552 } |
|
553 } |
|
554 return KErrNotFound; |
|
555 } |
|
556 |
|
557 // ----------------------------------------------------------------------------- |
|
558 // CNATTraversalController::BindingExists |
|
559 // ----------------------------------------------------------------------------- |
|
560 // |
|
561 TBool CNATTraversalController::BindingExists( |
|
562 const MSIPNATBindingObserver* aObserver) const |
|
563 { |
|
564 for (TInt i=0; i < iSessions.Count(); i++) |
|
565 { |
|
566 if (iSessions[i]->HasBinding(aObserver)) |
|
567 { |
|
568 return ETrue; |
|
569 } |
|
570 } |
|
571 return EFalse; |
|
572 } |
|
573 |
|
574 // ----------------------------------------------------------------------------- |
|
575 // CNATTraversalController::DetachConfigFromSession |
|
576 // ----------------------------------------------------------------------------- |
|
577 // |
|
578 void CNATTraversalController::DetachConfigFromSession(TAny* aSession) |
|
579 { |
|
580 CNATTraversalSession* session = |
|
581 reinterpret_cast<CNATTraversalSession*>(aSession); |
|
582 if (session) |
|
583 { |
|
584 session->DetachConfig(); |
|
585 } |
|
586 } |
|
587 |
|
588 // ----------------------------------------------------------------------------- |
|
589 // CNATTraversalController::HandleNextFromSocketUserQueue |
|
590 // ----------------------------------------------------------------------------- |
|
591 // |
|
592 void CNATTraversalController::HandleNextFromSocketUserQueue() |
|
593 { |
|
594 if (iSocketUserQueue.Count() > 0 && !iSocketUserQueue[0]->IsSending()) |
|
595 { |
|
596 iSocketUserQueue[0]->SendingAllowed(); |
|
597 } |
|
598 } |