in nlsCppSdk/transport/connectNode.cpp [2923:3063]
int ConnectNode::dnsProcess(int aiFamily, char *directIp, bool sysGetAddr) {
EXIT_CANCEL_CHECK(_exitStatus, this);
struct evutil_addrinfo hints;
NlsNodeManager *node_manager = _instance->getNodeManger();
int status = NodeStatusInvalid;
int result = node_manager->checkNodeExist(this, &status);
if (result != Success) {
LOG_ERROR("Node(%p) checkNodeExist failed, result:%d.", this, result);
return result;
}
/* 当node处于长链接模式且已经链接, 无需进入握手阶段, 直接进入starting阶段. */
if (_isLongConnection && _isConnected) {
LOG_DEBUG(
"Node(%p) has connected, current is longConnection and connected.",
this);
#ifdef ENABLE_REQUEST_RECORDING
if (_isLongConnection) {
_nodeProcess.connect_type = ConnectWithLongConnect;
}
#endif
_workStatus = NodeStarting;
node_manager->updateNodeStatus(this, NodeStatusRunning);
if (_request->getRequestParam()->_requestType == SpeechTextDialog) {
addCmdDataBuffer(CmdTextDialog);
} else {
addCmdDataBuffer(CmdStart);
}
result = nlsSendFrame(getCmdEvBuffer());
if (result < 0) {
LOG_ERROR("Node(%p) response failed, result:%d.", this, result);
handlerTaskFailedEvent(getErrorMsg());
closeConnectNode();
return result;
}
return Success;
}
/* 尝试链接校验 */
if (!checkConnectCount()) {
LOG_ERROR("Node(%p) restart connect failed.", this);
handlerTaskFailedEvent(TASKFAILED_CONNECT_JSON_STRING, SysConnectFailed);
return -(ConnectFailed);
}
_workStatus = NodeConnecting;
node_manager->updateNodeStatus(this, NodeStatusConnecting);
if (!parseUrlInformation(directIp)) {
return -(ParseUrlFailed);
}
_url._enableSysGetAddr = sysGetAddr;
if (_url._isSsl) {
LOG_INFO("Node(%p) _url._isSsl is True, _url._enableSysGetAddr is %s.",
this, _url._enableSysGetAddr ? "True" : "False");
} else {
LOG_INFO("Node(%p) _url._isSsl is False, _url._enableSysGetAddr is %s.",
this, _url._enableSysGetAddr ? "True" : "False");
}
if (_url._directIp) {
LOG_INFO("Node(%p) _url._directIp is True.", this);
#ifdef ENABLE_REQUEST_RECORDING
_nodeProcess.connect_type = ConnectWithDirectIP;
#endif
WorkThread::directConnect(this, _url._address);
} else {
LOG_INFO("Node(%p) _url._directIp is False.", this);
if (aiFamily != AF_UNSPEC && aiFamily != AF_INET && aiFamily != AF_INET6) {
LOG_WARN("Node(%p) aiFamily is invalid, use default AF_INET.", this,
aiFamily);
aiFamily = AF_INET;
}
#ifdef ENABLE_DNS_IP_CACHE
std::string tmp_ip = _eventThread->getIpFromCache(
(char *)_request->getRequestParam()->_url.c_str());
if (tmp_ip.length() > 0) {
LOG_INFO("Node(%p) find IP in cache, connect directly.", this);
// 从dns cache中获得IP进行直连
#ifdef ENABLE_REQUEST_RECORDING
_nodeProcess.connect_type = ConnectWithIpCache;
#endif
WorkThread::directConnect(this, (char *)tmp_ip.c_str());
} else
#endif
{
memset(&hints, 0, sizeof(hints));
hints.ai_family = aiFamily;
hints.ai_flags = EVUTIL_AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
LOG_INFO("Node(%p) dns url:%s, enableSysGetAddr:%s.", this,
_request->getRequestParam()->_url.c_str(),
_url._enableSysGetAddr ? "True" : "False");
if (_url._enableSysGetAddr) {
#ifdef __LINUX__
/*
* 在内部ws协议下或者主动使用系统getaddrinfo_a的情况下,
* 使用系统的getaddrinfo_a()
*/
result = native_getaddrinfo(_url._host, NULL,
WorkThread::dnsEventCallback, this);
if (result != Success) {
result = -(GetAddrinfoFailed);
}
#else
if (NULL == _eventThread || NULL == _eventThread->_dnsBase) {
LOG_ERROR("Node:%p dns source is invalid.", this);
return -(InvalidDnsSource);
}
_dnsRequest =
evdns_getaddrinfo(_eventThread->_dnsBase, _url._host, NULL, &hints,
WorkThread::dnsEventCallback, this);
#endif
} else {
if (NULL == _eventThread || NULL == _eventThread->_dnsBase) {
LOG_ERROR("Node(%p) dns source is invalid.", this);
return -(InvalidDnsSource);
}
_dnsRequest =
evdns_getaddrinfo(_eventThread->_dnsBase, _url._host, NULL, &hints,
WorkThread::dnsEventCallback, this);
if (_dnsRequest == NULL) {
LOG_ERROR("Node:%p dnsRequest evdns_getaddrinfo failed!", this);
/*
* No need to free user_data ordecrement n_pending_requests; that
* happened in the callback.
*/
return -(InvalidDnsSource);
}
}
}
}
return result;
}