⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upnpnat.cpp

📁 这是一个嵌入式linux系统下的BT下载工具包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  /* get the baseURL of the device */  if((baseURLNode = xmlnode_get_child(xmlRootNode, "URLBase")) != NULL)  {    baseURL = g_strdup(xmlnode_get_data(baseURLNode));  } else  {    baseURL = g_strdup(httpURL);  }  /* get the serviceType child that has the service type as it's data */  /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1     and it's devicelist */  serviceTypeNode = xmlnode_get_child(xmlRootNode, "device");  while(serviceTypeNode != NULL  		&& !compareDevice(serviceTypeNode, "urn:schemas-upnp-org:device:InternetGatewayDevice:1"))  {    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);  }  if(serviceTypeNode == NULL)  {  	return false;  }  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");  if(serviceTypeNode == NULL)  {  	return false;  }  /* get urn:schemas-upnp-org:device:WANDevice:1     and it's devicelist */  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");  while(serviceTypeNode != NULL  		&& !compareDevice(serviceTypeNode, "urn:schemas-upnp-org:device:WANDevice:1"))  {    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);  }  if(serviceTypeNode == NULL)  {  	return false;  }  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");  if(serviceTypeNode == NULL)  {  	return false;  }  /* get urn:schemas-upnp-org:device:WANConnectionDevice:1     and it's servicelist */  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");  while(serviceTypeNode != NULL  		&& !compareDevice(serviceTypeNode, "urn:schemas-upnp-org:device:WANConnectionDevice:1"))  {    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);  }  if(serviceTypeNode == NULL)  {  	return false;  }  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "serviceList");  if(serviceTypeNode == NULL)  {  	return false;  }  /* get the serviceType variable passed to this function */  service = g_strdup_printf(SEARCH_REQUEST_DEVICE, serviceType);  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "service");  while(serviceTypeNode != NULL  		&& !compareService(serviceTypeNode, service))  {    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);  }  g_free(service);  if(serviceTypeNode == NULL)  {  	return false;  }  /* get the controlURL of the service */  if((controlURLNode = xmlnode_get_child(serviceTypeNode, "controlURL")) == NULL)  { 	return false;  }  if(g_strstr_len(xmlnode_get_data(controlURLNode),                  SIZEOF_HTTP, "http://") == NULL &&     g_strstr_len(xmlnode_get_data(controlURLNode),                  SIZEOF_HTTP, "HTTP://") == NULL) {    controlURL = g_strdup_printf("%s%s", baseURL,                                 xmlnode_get_data(controlURLNode));  }else{    controlURL = g_strdup(xmlnode_get_data(controlURLNode));  }    if(_eventHandler != NULL)	  {  	_eventHandler->OnGetControlUrl(controlURL, serviceType);  }    return true;}bool CUPnpNatDescriptionParser::compareService(xmlnode* service, const char* serviceType){  xmlnode* serviceTypeNode = xmlnode_get_child(service, "serviceType");  if(serviceTypeNode == NULL) {    return FALSE;  }  return !g_ascii_strcasecmp(xmlnode_get_data(serviceTypeNode), serviceType);	}bool CUPnpNatDescriptionParser::compareDevice(xmlnode* device, const char* deviceType){  xmlnode* deviceTypeNode = xmlnode_get_child(device, "deviceType");  if(deviceTypeNode == NULL) {    return FALSE;  }  return !g_ascii_strcasecmp(xmlnode_get_data(deviceTypeNode), deviceType);	}TDescriptionParserState CUPnpNatDescriptionParser::getState(){	return _state;}const char* CPnpNatController::ActionAdd = "AddPortMapping";const char* CPnpNatController::ActionDelete = "DeletePortMapping";CPnpNatController::CPnpNatController(): _reactor(NULL), _state(CS_INIT){}CPnpNatController::~CPnpNatController(){}void CPnpNatController::setSocketReactor(ISocketReactor* reactor){	_reactor = reactor;}void CPnpNatController::setControlUrl(const char*controlUrl, const char* service){	_controlUrl = controlUrl;	_service = service;}void CPnpNatController::setAction(const char* action, unsigned short port, const char* protocol){	_actionName = action;	_port = port;	_protocol = protocol;	}void CPnpNatController::start(){	std::string ip;	std::string path;	unsigned short port;	parseUrl(_controlUrl.c_str(), ip, &port, path);		_state = CS_WORKING;		CSocket::createTCPSocket();	CSocket::setReactor(_reactor);	CSocket::maskWrite(true);	CSocket::connect(ip.c_str(), port);			_timeoutTimerID = _reactor->addTimer(this, 5000, true);}void CPnpNatController::stop(){	LOG_DEBUG("CPnpNatController stopping");		if(_timeoutTimerID != 0		&& _reactor != NULL)	{		_reactor->removeTimer(_timeoutTimerID);		_timeoutTimerID = 0;	}		CSocket::setReactor(NULL);	CSocket::close();			LOG_DEBUG("CPnpNatController stoped");}TControllerState CPnpNatController::getState(){	return _state;}int CPnpNatController::handleRead(){	char buffer[1024];	for(;;)	{		int ret = recv(getHandle(), buffer, sizeof(buffer), 0);		LOG_DEBUG("recv return "<<ret);		if(ret == 0)		{			maskRead(false);			return -1;		}				if(ret == -1)		{			if(errno == EINTR)			{				continue;			}						if(errno != EAGAIN)			{				maskRead(false);				return -1;			}			break;		}				if(ret > 0)		{			_recvBuffer.append(buffer, ret);		}	}			return 0;	}int CPnpNatController::handleWrite(){	//get local ip from socket handle	struct sockaddr_in addr;	socklen_t len = sizeof(addr);	getsockname(getHandle(), (struct sockaddr*)&addr, &len);	_localIP = inet_ntoa(addr.sin_addr);			LOG_DEBUG("localIP="<<_localIP);		sendRequest();	maskWrite(false);	return 0;}void CPnpNatController::handleClose(){	if(_recvBuffer.find(HTTP_OK) != _recvBuffer.npos)	{		_state = CS_OK;		LOG_DEBUG("port mapping ok");	}	else	{		_state = CS_ERROR;		LOG_DEBUG("port mapping error");	}	CSocket::setReactor(NULL);	CSocket::close();}void CPnpNatController::onTimer(unsigned int id){	if(id == _timeoutTimerID		&& _state == CS_WORKING)	{		handleClose();		_timeoutTimerID = 0;	}}void CPnpNatController::sendRequest(){		gchar* actionParams = g_strdup_printf(ADD_PORT_MAPPING_PARAMS,					_port,					_protocol.c_str(),					_port,					_localIP.c_str());	gchar* soapMessage = g_strdup_printf(SOAP_ACTION,					_actionName.c_str(),					_service.c_str(),					actionParams,					_actionName.c_str());						std::string ip;	std::string path;	unsigned short port;	parseUrl(_controlUrl.c_str(), ip, &port, path);						gchar* addressPortOfControl = g_strdup_printf("%s:%u", ip.c_str(), port);		gchar* actionMessage = g_strdup_printf(HTTP_HEADER_ACTION,					path.c_str(),					addressPortOfControl,					_service.c_str(),					_actionName.c_str(),					strlen(soapMessage));						gchar* totalSendMessage = g_strdup_printf("%s%s", actionMessage, soapMessage);		int ret = send(getHandle(), totalSendMessage, strlen(totalSendMessage), 0);			LOG_DEBUG("msg len="<<strlen(totalSendMessage)<<" send return "<<ret);	LOG_DEBUG("totalSendMessage = \n"<<totalSendMessage);		g_free(actionParams);	g_free(soapMessage);	g_free(addressPortOfControl);	g_free(actionMessage);	g_free(totalSendMessage);		maskRead(true);												}CUPnpNat::CUPnpNat(): _reactor(NULL), _state(NS_INIT), _discoverTimerID(0), _controlTimerID(0){}CUPnpNat::~CUPnpNat(){}void CUPnpNat::setReactor(ISocketReactor* reactor){	_reactor = reactor;}void CUPnpNat::start(){	_state = NS_DISCOVER;	_natExplorer.setSocketReactor(_reactor);	_natExplorer.setEventHandler(this);	_natExplorer.start();	_discoverTimerID = _reactor->addTimer(this, 10000, true);	_controlTimerID = _reactor->addTimer(this, 2000, false);}void CUPnpNat::stop(){	if(_discoverTimerID != 0)	{		_reactor->removeTimer(_discoverTimerID);		_discoverTimerID = 0;	}	if(_controlTimerID != 0)	{		_reactor->removeTimer(_controlTimerID);		_controlTimerID = 0;	}			_natExplorer.stop();	_natParser.stop();			TNatPortInfoList::iterator iter = _portList.begin();	for(; iter!=_portList.end(); ++iter)	{		if(iter->controller != NULL)		{			iter->controller->stop();			delete iter->controller;			iter->controller = NULL;		}	}		_portList.clear();}TUPnpNATState CUPnpNat::getState(){	return _state;}void CUPnpNat::addPortMapping(unsigned int port,const char* protocol){	TNatPortInfo info;	info.port = port;	info.protocol = protocol;			if(_state != NS_OK)	{		info.controller = NULL;	}	else	{		info.controller = new CPnpNatController();		info.controller->setSocketReactor(_reactor);		info.controller->setControlUrl(_controlUrl.c_str(), _service.c_str());		info.controller->setAction(CPnpNatController::ActionAdd, port, protocol);		info.controller->start();	}		_portList.push_back(info);}void CUPnpNat::removePortMapping(unsigned int port,const char* protocol){}void CUPnpNat::onTimer(unsigned int id){	if(id == _discoverTimerID)	{		if(_state == NS_OK)		{			_discoverTimerID = 0;		}		else		{			LOG_INFO("NAT discover timeout");			_natExplorer.stop();						start();					}	}		if(id == _controlTimerID)	{		if(_state == NS_OK)		{			TNatPortInfoList::iterator iter = _portList.begin();			for(; iter!=_portList.end(); ++iter)			{				if(iter->controller == NULL)				{					iter->controller = new CPnpNatController();					iter->controller->setSocketReactor(_reactor);					iter->controller->setControlUrl(_controlUrl.c_str(), _service.c_str());					iter->controller->setAction(CPnpNatController::ActionAdd, iter->port, iter->protocol.c_str());					iter->controller->start();									}			}					}	}}void CUPnpNat::OnGetDescriptionUrl(const char* url){	LOG_DEBUG("CUPnpNat::OnGetDescriptionUrl, url="<<url);		if(_state == NS_GETDESCRIPTION)	{		return;	}		_state = NS_GETDESCRIPTION;		_natParser.stop();	_natParser.setSocketReactor(_reactor);	_natParser.setEventHandler(this);	_natParser.setDescriptionUrl(url);	_natParser.start();}void CUPnpNat::OnGetControlUrl(const char* controlUrl, const char* service){	LOG_DEBUG("controlUrl="<<controlUrl<<" service="<<service);		_controlUrl = controlUrl;	_service = service;		_state = NS_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -