2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FNet_DnsRequestHandler.cpp
19 * @brief This is the implementation file for the _DnsRequestHandler Class.
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <FNetIp4Address.h>
27 #include <FNetIpHostEntry.h>
28 #include <FBaseSysLog.h>
29 #include "FNet_NetTypes.h"
30 #include "FNet_IpHostEntryImpl.h"
31 #include "FNet_DnsEvent.h"
32 #include "FNet_DnsEventArg.h"
33 #include "FNet_DnsRequestHandler.h"
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Runtime;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Base::Utility;
41 namespace Tizen { namespace Net
44 _DnsRequestHandler::_DnsRequestHandler(_DnsRequest* pDnsRequest)
48 __pDnsRequest.reset(pDnsRequest);
52 _DnsRequestHandler::Construct()
56 unique_ptr<Thread> pThread(new (std::nothrow) Thread());
57 SysTryReturnResult(NID_NET, pThread != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
59 r = pThread->Construct(*this);
60 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
61 "A system error has been occurred. Failed to construct a thread.");
63 __pThread = move(pThread);
68 _DnsRequestHandler::~_DnsRequestHandler()
70 if (__pThread != null)
77 _DnsRequestHandler::Run()
79 if (__pDnsRequest.get() != null)
81 __pDnsRequest->Execute();
83 __pDnsRequest.reset(null);
90 _DnsRequestHandler::Start()
95 SysTryReturnResult(NID_NET, __pThread != null, E_SYSTEM,
96 "A system error has been occurred. __pThread must not be null.");
98 r = __pThread->Start();
99 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
100 "A system error has been occurred. Failed to start the thread.");
108 _DnsRequestHandler::IsRequestStarted()
114 _DnsRequestHandler::FireNetworkStoppedEvent()
116 result r = E_SUCCESS;
118 _DnsEventArg* pDnsEventArg = null;
120 _DnsEvent& dnsEvent = __pDnsRequest->GetDnsEvent();
122 // callback app with error E_NETWORK_UNAVAILABLE
123 pDnsEventArg = new (std::nothrow) _DnsEventArg(E_NETWORK_UNAVAILABLE, null);
124 SysTryReturnResult(NID_NET, pDnsEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
126 r = dnsEvent.FireAsync(*pDnsEventArg);
132 _DnsRequestHandler::DnsCallBack(struct hostent* pHostent, int dnsId, _DnsEvent& dnsEvent)
134 //NOTE: DONOT DELETE pHostent
136 result r = E_SUCCESS;
138 _DnsEventArg* pDnsEventArg = null;
139 unique_ptr<IpHostEntry> pIpHostEntry;
140 _IpHostEntryImpl* pIpHostEntryImpl = null;
142 SysLog(NID_NET, "DnsCallBack() has been called with DNS ID:%d", dnsId);
144 // we need to check for null, if null send callback to listener with E_DNS_NOT_FOUND error
145 if (pHostent != null)
147 struct in_addr** pInAddrList = null;
149 pInAddrList = (struct in_addr**) pHostent->h_addr_list;
151 //check we have got IP addresses and host name
152 if (pInAddrList != null && *pInAddrList != null && pHostent->h_name != null)
154 // we have resolved the host. now populate the contents
155 pIpHostEntry.reset(_IpHostEntryImpl::CreateIpHostEntryN());
156 SysTryReturnResult(NID_NET, pIpHostEntry != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
158 pIpHostEntryImpl = _IpHostEntryImpl::GetInstance(*pIpHostEntry);
159 SysTryReturnResult(NID_NET, pIpHostEntryImpl != null, E_SYSTEM,
160 "A system error has been occurred. Failed to get IpHostEntry instance.");
163 r = SetAddressList(pHostent, *pIpHostEntryImpl);
164 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
165 "A system error has been occurred. Failed to set hostent to address list.");
168 r = SetAliasList(pHostent, *pIpHostEntryImpl);
169 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
170 "A system error has been occurred. Failed to set hostent to alias list.");
175 SysLogException(NID_NET, r, "[%s] An error has been occurred getting host information.", GetErrorMessage(E_DNS_NOT_FOUND));
181 SysLogException(NID_NET, r, "[%s] An error has been occurred getting host information.", GetErrorMessage(E_DNS_NOT_FOUND));
184 // call app calback now.
185 //ownership of pIpHostEntry transferred to pDnsEventArg
186 pDnsEventArg = new (std::nothrow) _DnsEventArg(r, pIpHostEntry.get());
187 SysTryReturnResult(NID_NET, pDnsEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
189 pIpHostEntry.release();
191 r = dnsEvent.FireAsync(*pDnsEventArg);
193 SysLog(NID_NET, "[%s] DnsCallBack() has been done.", GetErrorMessage(r));
199 _DnsRequestHandler::SetAddressList(const struct hostent* pHostent, _IpHostEntryImpl& ipHostEntryImpl)
201 result r = E_SUCCESS;
204 struct in_addr** pInAddrList = null;
206 pInAddrList = (struct in_addr**) pHostent->h_addr_list;
207 SysTryReturnResult(NID_NET, pInAddrList != null, E_OPERATION_FAILED, "An error has been occurred in DNS response.");
209 unique_ptr<ArrayList, _CollectionDeleter> pAddrList(new (std::nothrow) ArrayList());
210 SysTryReturnResult(NID_NET, pAddrList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
212 r = pAddrList->Construct();
213 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
214 "A system error has been occurred. Failed to construct an address list.");
216 for (int addrCount = 0; pInAddrList[addrCount] != null; addrCount++)
218 SysLog(NID_NET, "Resolved IP Address is %s", inet_ntoa(*pInAddrList[addrCount]));
220 unique_ptr<IpAddress> pIpAddress(new (std::nothrow) Ip4Address(ntohl((*pInAddrList[addrCount]).s_addr)));
221 SysTryReturnResult(NID_NET, pIpAddress != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
223 r = pAddrList->Add(*pIpAddress);
224 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
225 "A system error has been occurred. Failed to add the address to address list.");
227 pIpAddress.release();
230 r = ipHostEntryImpl.SetAddressList(*pAddrList);
231 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM, "A system error has been occurred. Failed to set address list.");
239 _DnsRequestHandler::SetAliasList(const struct hostent* pHostent, _IpHostEntryImpl& ipHostEntryImpl)
241 result r = E_SUCCESS;
243 unique_ptr<ArrayList, _CollectionDeleter> pAliasList(new (std::nothrow) ArrayList());
244 SysTryReturnResult(NID_NET, pAliasList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
246 r = pAliasList->Construct();
247 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
248 "A system error has been occurred. Failed to construct an alias list.");
250 //Add Hostname to alias list
251 if (pHostent->h_name != null)
253 SysSecureLog(NID_NET, "Hostname: %s", pHostent->h_name);
255 unique_ptr<String> pHostName(new (std::nothrow) String());
256 SysTryReturnResult(NID_NET, pHostName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
258 r = StringUtil::Utf8ToString(pHostent->h_name, *pHostName);
259 SysTryReturnResult(NID_NET, r != E_OUT_OF_MEMORY, r, "Propagating.");
260 if (r == E_INVALID_ENCODING_RANGE)
262 SysLog(NID_NET, "Failed to convert UTF-8 string into a Unicode string.");
266 r = pAliasList->Add(*pHostName);
267 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
268 "A system error has been occurred. Failed to add the hostname to alias list.");
274 r = ipHostEntryImpl.SetAliasList(*pAliasList);
275 SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM,
276 "A system error has been occurred. Failed to set alias list.");
278 pAliasList.release();
283 // _DnsRequest class implementation
284 _DnsRequest::_DnsRequest(_NetDnsEventType msgType, char* pMsgData, _DnsEvent& dnsEvent)
286 , __dnsEvent(dnsEvent)
288 __pMsgData.reset(pMsgData);
291 _DnsRequest::~_DnsRequest()
296 _DnsRequest::Execute()
298 if (__msgType == NET_DNS_EVENT_HOSTNAME)
300 struct hostent* pHostent = null;
302 pHostent = (hostent*) gethostbyname(__pMsgData.get());
303 _DnsRequestHandler::DnsCallBack(pHostent, NET_DNS_EVENT_HOSTNAME, __dnsEvent);
305 else if (__msgType == NET_DNS_EVENT_ADDRESS)
307 struct hostent* pHostent = null;
308 struct in_addr ipv4addr;
310 inet_pton(AF_INET, __pMsgData.get(), &ipv4addr);
312 pHostent = (hostent*) gethostbyaddr(&ipv4addr, sizeof(ipv4addr), AF_INET);
313 _DnsRequestHandler::DnsCallBack(pHostent, NET_DNS_EVENT_ADDRESS, __dnsEvent);
319 _DnsRequest::GetDnsEvent()