1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of "Eclipse Public License v1.0" |
4 // under the terms of "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
102 |
101 |
103 // Copy the remote host IP address and port |
102 // Copy the remote host IP address and port |
104 iHost = HBufC::NewL(aRemoteHost.Length()); |
103 iHost = HBufC::NewL(aRemoteHost.Length()); |
105 iHost->Des().Copy(aRemoteHost); |
104 iHost->Des().Copy(aRemoteHost); |
106 iPort = aRemotePort; |
105 iPort = aRemotePort; |
107 |
106 |
|
107 TInt error = KErrNone; |
108 // Move to the PendingDNSLookup state and self complete. |
108 // Move to the PendingDNSLookup state and self complete. |
109 if(aRemoteAddress == NULL) |
109 if(aRemoteAddress == NULL) |
110 { |
110 { |
|
111 RDebug::Printf("RemoteAddress is NULL so doing a DNS lookup"); |
|
112 iState = EPendingDNSLookup; |
111 // Address is unknown / DNS lookup is needed |
113 // Address is unknown / DNS lookup is needed |
112 iState = EPendingDNSLookup; |
114 error = DoPendingDNSLookup(); |
113 } |
115 } |
114 else |
116 else |
115 { |
117 { |
|
118 RDebug::Printf("Remote address is known so doing a direct connect"); |
|
119 iState = EConnecting; |
116 // Address is know. No lookup is needed. Just go and connect. |
120 // Address is know. No lookup is needed. Just go and connect. |
117 iHostDnsEntry().iAddr = *aRemoteAddress; |
121 iHostDnsEntry().iAddr = *aRemoteAddress; |
118 iState = EConnecting; |
122 error = DoConnect(); |
119 } |
123 } |
120 CompleteSelf(); |
124 |
|
125 if(error != KErrNone) |
|
126 { |
|
127 iState = EPendingDNSLookup; |
|
128 // Error the AO and handle the error in the normal path. |
|
129 TRequestStatus* pStat = &iStatus; |
|
130 User::RequestComplete(pStat, error); |
|
131 SetActive(); |
|
132 } |
121 } |
133 } |
122 |
134 |
123 void CSocketConnector::CompleteSelf() |
135 void CSocketConnector::CompleteSelf() |
124 /** |
136 /** |
125 Requests that the socket connector complete itself. This will caused the |
137 Requests that the socket connector complete itself. This will caused the |
191 |
203 |
192 switch( iState ) |
204 switch( iState ) |
193 { |
205 { |
194 case EPendingDNSLookup: |
206 case EPendingDNSLookup: |
195 { |
207 { |
196 #if defined (_DEBUG) && defined (_LOGGING) |
208 User::LeaveIfError(DoPendingDNSLookup()); |
197 TBuf8<KHostNameSize> host; |
|
198 host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters |
|
199 |
|
200 __FLOG_1(_T8("Doing DNS lookup -> searching for host %S"), &host); |
|
201 #endif |
|
202 |
|
203 __OOM_LEAVE_TEST |
|
204 |
|
205 if ( iCommsInfoProvider.HasConnection() ) |
|
206 { |
|
207 // Open the host resolver session with the preffered connection |
|
208 User::LeaveIfError(iHostResolver.Open( |
|
209 iCommsInfoProvider.SocketServer(), |
|
210 iCommsInfoProvider.ProtocolDescription().iAddrFamily, |
|
211 KProtocolInetUdp, |
|
212 iCommsInfoProvider.Connection() |
|
213 )); |
|
214 } |
|
215 else |
|
216 { |
|
217 // Open the host resolver session with no connection |
|
218 User::LeaveIfError(iHostResolver.Open( |
|
219 iCommsInfoProvider.SocketServer(), |
|
220 iCommsInfoProvider.ProtocolDescription().iAddrFamily, |
|
221 KProtocolInetUdp |
|
222 )); |
|
223 } |
|
224 |
|
225 // Start the DNS lookup for the remote host name. |
|
226 iHostResolver.GetByName(*iHost, iHostDnsEntry, iStatus); |
|
227 |
|
228 // Move to the Connecting state and go active |
|
229 iState = EConnecting; |
|
230 SetActive(); |
|
231 } break; |
209 } break; |
232 case EConnecting: |
210 case EConnecting: |
233 { |
211 { |
234 __OOM_LEAVE_TEST |
212 User::LeaveIfError(DoConnect()); |
235 |
|
236 // DNS lookup successful - form the internet address object |
|
237 iAddress = TInetAddr(iHostDnsEntry().iAddr); |
|
238 iAddress.SetPort(iPort); |
|
239 |
|
240 #if defined (_DEBUG) && defined (_LOGGING) |
|
241 TBuf8<KHostNameSize> host; |
|
242 host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters |
|
243 |
|
244 TBuf<KIpv6MaxAddrSize> ip16bit; |
|
245 iAddress.Output(ip16bit); |
|
246 |
|
247 TBuf8<KIpv6MaxAddrSize> ip; |
|
248 ip.Copy(ip16bit); |
|
249 |
|
250 __FLOG_2(_T8("DNS lookup complete -> host %S has IP address %S"), &host, &ip); |
|
251 #endif |
|
252 |
|
253 // Start a default RConnection, if one is not started and not local loopback address |
|
254 if ( !iCommsInfoProvider.HasConnection() && !iAddress.IsLoopback() ) |
|
255 { |
|
256 iCommsInfoProvider.StartDefaultCommsConnectionL (); |
|
257 } |
|
258 |
|
259 // Create the connecting socket |
|
260 iConnectingSocket = CSocket::NewL(iCommsInfoProvider, CSocket::EProtocolSocket); |
|
261 |
|
262 // Start connecting to the remote client |
|
263 iConnectingSocket->Connect(iAddress, iStatus); |
|
264 |
|
265 __FLOG_2(_T8("Connecting -> to host %S on IP address %S"), &host, &ip); |
|
266 |
|
267 // Move to the Connected state and go active |
|
268 iState = EConnected; |
|
269 SetActive(); |
|
270 } break; |
213 } break; |
271 case EConnected: |
214 case EConnected: |
272 { |
215 { |
273 __OOM_LEAVE_TEST |
216 __OOM_LEAVE_TEST |
274 |
217 |
429 |
373 |
430 Suicide(); |
374 Suicide(); |
431 |
375 |
432 return error; |
376 return error; |
433 } |
377 } |
|
378 |
|
379 TInt CSocketConnector::DoPendingDNSLookup() |
|
380 { |
|
381 #if defined (_DEBUG) && defined (_LOGGING) |
|
382 TBuf8<KHostNameSize> host; |
|
383 host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters |
|
384 |
|
385 __FLOG_1(_T8("Doing DNS lookup -> searching for host %S"), &host); |
|
386 #endif |
|
387 TInt error = KErrNone; |
|
388 |
|
389 iCommsInfoProvider.HostResolverFromCache(iHostResolver); // Get the RHostResolver from the cache |
|
390 if(iHostResolver.SubSessionHandle() <= 0) |
|
391 { |
|
392 RDebug::Printf("No host resolver. Open a new one..."); |
|
393 if ( iCommsInfoProvider.HasConnection() ) |
|
394 { |
|
395 // Open the host resolver session with the preffered connection |
|
396 error = iHostResolver.Open(iCommsInfoProvider.SocketServer(), |
|
397 iCommsInfoProvider.ProtocolDescription().iAddrFamily, |
|
398 KProtocolInetUdp, |
|
399 iCommsInfoProvider.Connection()); |
|
400 } |
|
401 else |
|
402 { |
|
403 // Open the host resolver session with no connection |
|
404 error = iHostResolver.Open(iCommsInfoProvider.SocketServer(), |
|
405 iCommsInfoProvider.ProtocolDescription().iAddrFamily, |
|
406 KProtocolInetUdp); |
|
407 } |
|
408 } |
|
409 |
|
410 if(error != KErrNone) |
|
411 { |
|
412 return error; |
|
413 } |
|
414 |
|
415 // Start the DNS lookup for the remote host name. |
|
416 iHostResolver.GetByName(*iHost, iHostDnsEntry, iStatus); |
|
417 |
|
418 // Move to the Connecting state and go active |
|
419 iState = EConnecting; |
|
420 SetActive(); |
|
421 return error; |
|
422 } |
|
423 |
|
424 TInt CSocketConnector::DoConnect() |
|
425 { |
|
426 // DNS lookup successful - form the internet address object |
|
427 iAddress = TInetAddr(iHostDnsEntry().iAddr); |
|
428 iAddress.SetPort(iPort); |
|
429 |
|
430 // Add the RHostResolver to the cache. |
|
431 if(iHostResolver.SubSessionHandle() > 0) |
|
432 { |
|
433 iCommsInfoProvider.AddToHostResolverCache(iHostResolver); |
|
434 } |
|
435 |
|
436 #if defined (_DEBUG) && defined (_LOGGING) |
|
437 TBuf8<KHostNameSize> host; |
|
438 host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters |
|
439 |
|
440 TBuf<KIpv6MaxAddrSize> ip16bit; |
|
441 iAddress.Output(ip16bit); |
|
442 |
|
443 TBuf8<KIpv6MaxAddrSize> ip; |
|
444 ip.Copy(ip16bit); |
|
445 |
|
446 __FLOG_2(_T8("DNS lookup complete -> host %S has IP address %S"), &host, &ip); |
|
447 #endif |
|
448 |
|
449 // Start a default RConnection, if one is not started and not local loopback address |
|
450 if ( !iCommsInfoProvider.HasConnection() && !iAddress.IsLoopback() ) |
|
451 { |
|
452 // it is ok to TRAP here as the method will be called only once. |
|
453 TRAPD(error, iCommsInfoProvider.StartDefaultCommsConnectionL ()); |
|
454 if(error != KErrNone) |
|
455 { |
|
456 return error; |
|
457 } |
|
458 } |
|
459 |
|
460 // Create the connecting socket |
|
461 iConnectingSocket = CSocket::New(iCommsInfoProvider, CSocket::EProtocolSocket); |
|
462 if(!iConnectingSocket) |
|
463 { |
|
464 return KErrNoMemory; |
|
465 } |
|
466 |
|
467 // Start connecting to the remote client |
|
468 iConnectingSocket->Connect(iAddress, iStatus); |
|
469 SetActive(); |
|
470 __FLOG_2(_T8("Connecting -> to host %S on IP address %S"), &host, &ip); |
|
471 |
|
472 // Move to the Connected state and go active |
|
473 iState = EConnected; |
|
474 return KErrNone; |
|
475 } |
|
476 |
|
477 |