int ConnectNode::dnsProcess()

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;
}