Esempio n. 1
0
//-------------------------------------------------------------------------------------
BundleBroadcast::BundleBroadcast(NetworkInterface & networkInterface, 
								   uint16 bindPort, uint32 recvWindowSize):
	Bundle(NULL, Network::PROTOCOL_UDP),
	epListen_(),
	networkInterface_(networkInterface),
	recvWindowSize_(recvWindowSize),
	good_(false),
	itry_(5)
{
	epListen_.socket(SOCK_DGRAM);
	epBroadcast_.socket(SOCK_DGRAM);

	if (!epListen_.good() || !epBroadcast_.good())
	{
		ERROR_MSG(fmt::format("BundleBroadcast::BundleBroadcast: init socket is error, {}\n", 
			kbe_strerror()));

		networkInterface_.dispatcher().breakProcessing();
	}
	else
	{
		int count = 0;

		while(true)
		{
			if (epListen_.bind(htons(bindPort), htonl(INADDR_ANY)) != 0)
			{
				good_ = false;
				KBEngine::sleep(10);
				count++;

				if(count > 30)
				{
					WARNING_MSG(fmt::format("BundleBroadcast::BundleBroadcast: Couldn't bind listener socket to port {}, {}\n",
						bindPort, kbe_strerror()));

					break;
				}
			}
			else
			{
				epListen_.addr(htons(bindPort), htonl(INADDR_ANY));
				good_ = true;

				// DEBUG_MSG(fmt::format("BundleBroadcast::BundleBroadcast: epListen {}\n", epListen_.c_str()));
				break;
			}
		}
	}

	pCurrPacket()->data_resize(recvWindowSize_);
}
Esempio n. 2
0
//-------------------------------------------------------------------------------------
bool EPoller::doRegister(int fd, bool isRead, bool isRegister)
{
	struct epoll_event ev;
	memset(&ev, 0, sizeof(ev)); // stop valgrind warning
	int op;

	ev.data.fd = fd;

	// Handle the case where the file is already registered for the opposite
	// action.
	if (this->isRegistered(fd, !isRead))
	{
		op = EPOLL_CTL_MOD;

		ev.events = isRegister ? EPOLLIN|EPOLLOUT :
					isRead ? EPOLLOUT : EPOLLIN;
	}
	else
	{
		// TODO: Could be good to use EPOLLET (leave like select for now).
		ev.events = isRead ? EPOLLIN : EPOLLOUT;
		op = isRegister ? EPOLL_CTL_ADD : EPOLL_CTL_DEL;
	}

	if (epoll_ctl(epfd_, op, fd, &ev) < 0)
	{
		const char* MESSAGE = "EPoller::doRegister: Failed to %s %s file "
				"descriptor %d (%s)\n";
		if (errno == EBADF)
		{
			WARNING_MSG(boost::format(MESSAGE) %
					(isRegister ? "add" : "remove") %
					(isRead ? "read" : "write") %
					fd %
					kbe_strerror());
		}
		else
		{
			ERROR_MSG(boost::format(MESSAGE) %
					(isRegister ? "add" : "remove") %
					(isRead ? "read" : "write") %
					fd %
					kbe_strerror());
		}

		return false;
	}

	return true;
}
Esempio n. 3
0
//-------------------------------------------------------------------------------------		
void Components::removeComponentByChannel(Network::Channel * pChannel, bool isShutingdown)
{
	int ifind = 0;
	while(ALL_COMPONENT_TYPES[ifind] != UNKNOWN_COMPONENT_TYPE)
	{
		COMPONENT_TYPE componentType = ALL_COMPONENT_TYPES[ifind++];
		COMPONENTS& components = getComponents(componentType);
		COMPONENTS::iterator iter = components.begin();

		for(; iter != components.end();)
		{
			if((*iter).pChannel == pChannel)
			{
				//SAFE_RELEASE((*iter).pIntAddr);
				//SAFE_RELEASE((*iter).pExtAddr);
				// (*iter).pChannel->decRef();

				if (!isShutingdown && g_componentType != LOGGER_TYPE)
				{
					ERROR_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n",
						COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror()));

#if KBE_PLATFORM == PLATFORM_WIN32
					printf("[ERROR]: %s.\n", (fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n",
						COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror())).c_str());
#endif
				}
				else
				{
					INFO_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Normal exit!\n",
						COMPONENT_NAME_EX(componentType), (*iter).cid));
				}

				ComponentInfos* componentInfos = &(*iter);

				if(_pHandler)
					_pHandler->onRemoveComponent(componentInfos);

				iter = components.erase(iter);
				return;
			}
			else
				iter++;
		}
	}

	// KBE_ASSERT(false && "channel is not found!\n");
}
//-------------------------------------------------------------------------------------
int ListenerReceiver::handleInputNotification(int fd)
{
	int tickcount = 0;

	while(tickcount ++ < 256)
	{
		EndPoint* pNewEndPoint = endpoint_.accept();
		if(pNewEndPoint == NULL){

			if(tickcount == 1)
			{
				WARNING_MSG(fmt::format("PacketReceiver::handleInputNotification: accept endpoint({}) {}!\n",
					 fd, kbe_strerror()));
				
				this->dispatcher().errorReporter().reportException(
						REASON_GENERAL_NETWORK);
			}

			break;
		}
		else
		{
			Channel* pchannel = new Channel(networkInterface_, pNewEndPoint, traits_);
			if(!networkInterface_.registerChannel(pchannel))
			{
				ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification:registerChannel({}) is failed!\n",
					pchannel->c_str()));
			}
		}
	}

	return 0;
}
Esempio n. 5
0
//-------------------------------------------------------------------------------------
Mercury::Channel* ClientObjectBase::initBaseappChannel()
{
	Mercury::EndPoint* pEndpoint = new Mercury::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObjectBase::initBaseappChannel: couldn't create a socket\n");
		delete pEndpoint;
		return false;
	}
	
	u_int32_t address;

	pEndpoint->convertAddress(ip_.c_str(), address);
	if(pEndpoint->connect(htons(port_), address) == -1)
	{
		ERROR_MSG(boost::format("ClientObjectBase::initBaseappChannel: connect server is error(%1%)!\n") %
			kbe_strerror());

		delete pEndpoint;
		return NULL;
	}

	Mercury::Address addr(ip_.c_str(), port_);
	pEndpoint->addr(addr);

	pServerChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	connectedGateway_ = true;
	return pServerChannel_;
}
Esempio n. 6
0
//-------------------------------------------------------------------------------------
Mercury::Channel* ClientObjectBase::initLoginappChannel(std::string accountName, std::string passwd, std::string ip, KBEngine::uint32 port)
{
	Mercury::EndPoint* pEndpoint = new Mercury::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObjectBase::initLoginappChannel: couldn't create a socket\n");
		delete pEndpoint;
		return NULL;
	}
	

	u_int32_t address;
	pEndpoint->convertAddress(ip.c_str(), address);
	if(pEndpoint->connect(htons(port), address) == -1)
	{
		ERROR_MSG(boost::format("ClientObjectBase::initLoginappChannel: connect server is error(%1%)!\n") %
			kbe_strerror());

		delete pEndpoint;
		return NULL;
	}

	Mercury::Address addr(ip.c_str(), port);
	pEndpoint->addr(addr);

	pServerChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	password_ = passwd;
	name_ = accountName;
	return pServerChannel_;
}
//-------------------------------------------------------------------------------------
Reason NetworkInterface::getSendErrorReason(const EndPoint * endpoint, 
											int retSendSize, int packetTotalSize)
{
	int err;
	Reason reason;

	#ifdef unix
		err = errno;

		switch (err)
		{
			case ECONNREFUSED:	reason = REASON_NO_SUCH_PORT; break;
			case EAGAIN:		reason = REASON_RESOURCE_UNAVAILABLE; break;
			case ENOBUFS:		reason = REASON_TRANSMIT_QUEUE_FULL; break;
			default:			reason = REASON_GENERAL_NETWORK; break;
		}
	#else
		err = WSAGetLastError();

		if (err == WSAEWOULDBLOCK || err == WSAEINTR)
		{
			reason = REASON_RESOURCE_UNAVAILABLE;
		}
		else
		{
			reason = REASON_GENERAL_NETWORK;
		}
	#endif

	if (retSendSize == -1)
	{
		if (reason != REASON_NO_SUCH_PORT)
		{
			ERROR_MSG( "NetworkInterface::getSendErrorReason( %s ): "
					"Could not send packet: %s\n",
				endpoint->addr().c_str(), kbe_strerror( err ) );
		}
	}
	else
	{
		WARNING_MSG( "NetworkInterface::getSendErrorReason( %s ): "
			"Packet length %d does not match sent length %d (err = %s)\n",
			endpoint->addr().c_str(), packetTotalSize, retSendSize, kbe_strerror( err ) );
	}

	return reason;
}
Esempio n. 8
0
//-------------------------------------------------------------------------------------
BundleBroadcast::BundleBroadcast(NetworkInterface & networkInterface, 
								   uint16 bindPort, uint32 recvWindowSize):
	Bundle(NULL, Mercury::PROTOCOL_UDP),
	epListen_(),
	networkInterface_(networkInterface),
	recvWindowSize_(recvWindowSize),
	good_(false),
	itry_(5)
{
	epListen_.socket(SOCK_DGRAM);
	epBroadcast_.socket(SOCK_DGRAM);

	if (!epListen_.good() || !epBroadcast_.good())
	{
		ERROR_MSG("BundleBroadcast::BundleBroadcast: init socket is error, %s\n", 
			kbe_strerror());
		networkInterface_.mainDispatcher().breakProcessing();
	}
	else
	{
		int count = 0;

		while(true)
		{
			if (epListen_.bind(htons(bindPort), htonl(INADDR_ANY)) != 0)
			{
				good_ = false;
				WARNING_MSG("BundleBroadcast::BundleBroadcast: Couldn't bind listener socket to port %d, %s\n", 
					bindPort, kbe_strerror());
				
				KBEngine::sleep(100);
				count++;
				if(count > 3)
				{
					break;
				}
			}
			else
			{
				epListen_.addr(htons(bindPort), htonl(INADDR_ANY));
				good_ = true;
				DEBUG_MSG("BundleBroadcast::BundleBroadcast: epListen %s\n", epListen_.c_str());
				break;
			}
		}
	}
}
Esempio n. 9
0
//-------------------------------------------------------------------------------------
int SelectPoller::processPendingEvents(double maxWait)
{
	fd_set	readFDs;
	fd_set	writeFDs;
	struct timeval		nextTimeout;

	FD_ZERO(&readFDs);
	FD_ZERO(&writeFDs);

	readFDs = fdReadSet_;
	writeFDs = fdWriteSet_;

	nextTimeout.tv_sec = (int)maxWait;
	nextTimeout.tv_usec =
		(int)((maxWait - (double)nextTimeout.tv_sec) * 1000000.0);

#if ENABLE_WATCHERS
	g_idleProfile.start();
#else
	uint64 startTime = timestamp();
#endif

	KBEConcurrency::onStartMainThreadIdling();

	int countReady = 0;

#if KBE_PLATFORM == PLATFORM_WIN32
	if (fdLargest_ == -1)
	{
		Sleep(int(maxWait * 1000.0));
	}
	else
#endif
	{
		countReady = select(fdLargest_+1, &readFDs,
				fdWriteCount_ ? &writeFDs : NULL, NULL, &nextTimeout);
	}

	KBEConcurrency::onEndMainThreadIdling();

#if ENABLE_WATCHERS
	g_idleProfile.stop();
	spareTime_ += g_idleProfile.lastTime_;
#else
	spareTime_ += timestamp() - startTime;
#endif
	
	if (countReady > 0)
	{
		this->handleNotifications(countReady, readFDs, writeFDs);
	}
	else if (countReady == -1)
	{
		WARNING_MSG(fmt::format("EventDispatcher::processContinuously: "
			"error in select(): {}\n", kbe_strerror()));
	}

	return countReady;
}
Esempio n. 10
0
//-------------------------------------------------------------------------------------
bool Machine::findBroadcastInterface()
{

	std::map<u_int32_t, std::string> interfaces;
	Mercury::BundleBroadcast bhandler(networkInterface_, KBE_PORT_BROADCAST_DISCOVERY);

	if (!bhandler.epListen().getInterfaces(interfaces))
	{
		ERROR_MSG("Machine::findBroadcastInterface: Failed to discover network interfaces\n");
		return false;
	}

	uint8 data = 1;
	bhandler << data;
	if (!bhandler.broadcast(KBE_PORT_BROADCAST_DISCOVERY))
	{
		ERROR_MSG(boost::format("Machine::findBroadcastInterface:Failed to send broadcast discovery message. error:%1%\n") %
			kbe_strerror());
		return false;
	}
	
	sockaddr_in	sin;

	if(bhandler.receive(NULL, &sin))
	{
		INFO_MSG(boost::format("Machine::findBroadcastInterface:Machine::findBroadcastInterface: Broadcast discovery receipt from %1%.\n") %
					inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) );

		std::map< u_int32_t, std::string >::iterator iter;

		iter = interfaces.find( (u_int32_t &)sin.sin_addr.s_addr );
		if (iter != interfaces.end())
		{
			INFO_MSG(boost::format("Machine::findBroadcastInterface: Confirmed %1% (%2%) as default broadcast route interface.\n") %
				inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) %
				iter->second.c_str());

			broadcastAddr_ = sin.sin_addr.s_addr;
			return true;
		}
	}
	
	std::string sinterface = "\t[";
	std::map< u_int32_t, std::string >::iterator iter = interfaces.begin();
	for(; iter != interfaces.end(); iter++)
	{
		sinterface += inet_ntoa((struct in_addr&)iter->first);
		sinterface += ", ";
	}

	sinterface += "]";

	ERROR_MSG(boost::format("Machine::findBroadcastInterface: Broadcast discovery [%1%] "
		"not a valid interface. available interfaces:%2%\n") %
		inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) % sinterface.c_str());

	return false;
}
Esempio n. 11
0
//-------------------------------------------------------------------------------------
bool ClientObject::initCreate()
{
	Network::EndPoint* pEndpoint = new Network::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n");
		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}
	
	ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots();
	u_int32_t address;

	pEndpoint->convertAddress(infos.login_ip, address);
	if(pEndpoint->connect(htons(infos.login_port), address) == -1)
	{
		ERROR_MSG(fmt::format("ClientObject::initNetwork({1}): connect server({2}:{3}) is error({0})!\n",
			kbe_strerror(), name_, infos.login_ip, infos.login_port));

		delete pEndpoint;
		// error_ = C_ERROR_INIT_NETWORK_FAILED;
		state_ = C_STATE_INIT;
		return false;
	}

	Network::Address addr(infos.login_ip, infos.login_port);
	pEndpoint->addr(addr);

	pServerChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	pServerChannel_->pMsgHandlers(&ClientInterface::messageHandlers);
	Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this);

	Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
	(*pBundle).newMessage(LoginappInterface::hello);
	(*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString();

	if(Network::g_channelExternalEncryptType == 1)
	{
		pBlowfishFilter_ = new Network::BlowfishFilter();
		(*pBundle).appendBlob(pBlowfishFilter_->key());
	}
	else
	{
		std::string key = "";
		(*pBundle).appendBlob(key);
	}

	pServerChannel_->pushBundle(pBundle);

	this->pEndpoint_ = pEndpoint;
	return true;
}
Esempio n. 12
0
//-------------------------------------------------------------------------------------
EPoller::EPoller(int expectedSize) :
	epfd_(epoll_create(expectedSize))
{
	if (epfd_ == -1)
	{
		ERROR_MSG(boost::format("EPoller::EPoller: epoll_create failed: %1%\n") %
				kbe_strerror());
	}
};
Esempio n. 13
0
//-------------------------------------------------------------------------------------
bool ClientObject::initLoginGateWay()
{
	Bots::getSingleton().pEventPoller()->deregisterForRead(*pServerChannel_->endpoint());
	Network::EndPoint* pEndpoint = new Network::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n");
		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}
	
	u_int32_t address;

	pEndpoint->convertAddress(ip_.c_str(), address);
	if(pEndpoint->connect(htons(port_), address) == -1)
	{
		ERROR_MSG(fmt::format("ClientObject::initLogin({}): connect server is error({})!\n",
			kbe_strerror(), name_));

		delete pEndpoint;
		// error_ = C_ERROR_INIT_NETWORK_FAILED;
		state_ = C_STATE_LOGIN_GATEWAY_CREATE;
		return false;
	}

	Network::Address addr(ip_.c_str(), port_);
	pEndpoint->addr(addr);

	pServerChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this);
	connectedGateway_ = true;

	Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
	(*pBundle).newMessage(BaseappInterface::hello);
	(*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString();
	
	if(Network::g_channelExternalEncryptType == 1)
	{
		pBlowfishFilter_ = new Network::BlowfishFilter();
		(*pBundle).appendBlob(pBlowfishFilter_->key());
		pServerChannel_->pFilter(NULL);
	}
	else
	{
		std::string key = "";
		(*pBundle).appendBlob(key);
	}

	pServerChannel_->pushBundle(pBundle);
	return true;
}
//-------------------------------------------------------------------------------------
EpollPoller::EpollPoller(int expectedSize) :
	epfd_(epoll_create(expectedSize))
{
	if (epfd_ == -1)
	{
		ERROR_MSG(fmt::format("EpollPoller::EpollPoller: epoll_create failed: {}\n",
				kbe_strerror()));
	}
};
//-------------------------------------------------------------------------------------
HTTPCBHandler::HTTPCBHandler():
pEndPoint_(NULL),
clients_()
{
	pEndPoint_ = new Network::EndPoint();

	pEndPoint_->socket(SOCK_STREAM);

	if (!pEndPoint_->good())
	{
		ERROR_MSG("HTTPCBHandler::process: couldn't create a socket\n");
		return;
	}

	if (pEndPoint_->bind(htons(g_kbeSrvConfig.getLoginApp().http_cbport), 
		Loginapp::getSingleton().networkInterface().extaddr().ip) == -1)
	{
		ERROR_MSG(fmt::format("HTTPCBHandler::bind({}): {}:{}\n",
			 kbe_strerror(), inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip),
			g_kbeSrvConfig.getLoginApp().http_cbport));

		pEndPoint_->close();
		return;
	}

	if(pEndPoint_->listen() == -1)
	{
		ERROR_MSG(fmt::format("HTTPCBHandler::listeningSocket({}): {}:{}\n",
			 kbe_strerror(), inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip),
			g_kbeSrvConfig.getLoginApp().http_cbport));

		pEndPoint_->close();
		return;
	}

	pEndPoint_->setnonblocking(true);

	Loginapp::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor(*pEndPoint_, this);

	INFO_MSG(fmt::format("HTTPCBHandler::bind: {}:{}\n",
		inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip),
		g_kbeSrvConfig.getLoginApp().http_cbport));
}
Esempio n. 16
0
//-------------------------------------------------------------------------------------
int	TelnetServer::handleInputNotification(int fd)
{
	KBE_ASSERT(listener_ == fd);

	int tickcount = 0;

	while(tickcount ++ < 1024)
	{
		Mercury::EndPoint* pNewEndPoint = listener_.accept();
		if(pNewEndPoint == NULL){

			if(tickcount == 1)
			{
				WARNING_MSG(fmt::format("TelnetServer::handleInputNotification: accept endpoint({}) {}!\n",
					 fd, kbe_strerror()));
			}

			break;
		}
		else
		{
			TelnetHandler* pTelnetHandler = new TelnetHandler(pNewEndPoint, this, pNetworkInterface_, passwd_.size() > 0 ? 
				TelnetHandler::TELNET_STATE_PASSWD : (TelnetHandler::TELNET_STATE)this->deflayer());

			if(!pDispatcher_->registerFileDescriptor((*pNewEndPoint), pTelnetHandler))
			{
				ERROR_MSG(fmt::format("TelnetServer::start:: registerFileDescriptor(pTelnetHandler) is failed! addr={}\n", 
					pNewEndPoint->c_str()));
				
				delete pTelnetHandler;
				continue;
			}

			INFO_MSG(fmt::format("TelnetServer::handleInputNotification: new handler({})!\n",
				pNewEndPoint->c_str()));

			handlers_[(*pNewEndPoint)].reset(pTelnetHandler);

			std::string s;

			if(passwd_.size() > 0)
			{
				s = "password:";
			}
			else
			{
				s = pTelnetHandler->getWelcome();
			}

			pNewEndPoint->send(s.c_str(), s.size());
		}
	}

	return 0;
}
Esempio n. 17
0
//-------------------------------------------------------------------------------------
int ListenerReceiver::handleInputNotification(int fd)
{
	int tickcount = 0;

	while(tickcount ++ < 256)
	{
		EndPoint* pNewEndPoint = endpoint_.accept();
		if(pNewEndPoint == NULL){

			if(tickcount == 1)
			{
				WARNING_MSG(fmt::format("PacketReceiver::handleInputNotification: accept endpoint({}) {}!\n",
					 fd, kbe_strerror()));
				
				this->dispatcher().errorReporter().reportException(
						REASON_GENERAL_NETWORK);
			}

			break;
		}
		else
		{
			Channel* pChannel = Network::Channel::createPoolObject();
			bool ret = pChannel->initialize(networkInterface_, pNewEndPoint, traits_);
			if(!ret)
			{
				ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification: initialize({}) is failed!\n",
					pChannel->c_str()));

				pChannel->destroy();
				Network::Channel::reclaimPoolObject(pChannel);
				return 0;
			}

			if(!networkInterface_.registerChannel(pChannel))
			{
				ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification: registerChannel({}) is failed!\n",
					pChannel->c_str()));

				pChannel->destroy();
				Network::Channel::reclaimPoolObject(pChannel);
			}
		}
	}

	return 0;
}
Esempio n. 18
0
//-------------------------------------------------------------------------------------
bool BundleBroadcast::broadcast(uint16 port)
{
	if (!epBroadcast_.good())
		return false;
	
	if(port == 0)
		port = KBE_MACHINE_BRAODCAST_SEND_PORT;

	epBroadcast_.addr(port, Mercury::BROADCAST);

	if(epBroadcast_.setbroadcast(true) != 0)
	{
		ERROR_MSG("BundleBroadcast::broadcast: Couldn't broadcast socket, port %d, %s\n", 
			port, kbe_strerror());
		networkInterface_.mainDispatcher().breakProcessing();
		return false;
	}

	this->sendto(epBroadcast_, htons(port), Mercury::BROADCAST);
	return true;
}
Esempio n. 19
0
//-------------------------------------------------------------------------------------
bool ClientObject::initLoginGateWay()
{
	Bots::getSingleton().pEventPoller()->deregisterForRead(*pChannel_->endpoint());
	Mercury::EndPoint* pEndpoint = new Mercury::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n");
		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}
	
	u_int32_t address;

	pEndpoint->convertAddress(ip_.c_str(), address);
	if(pEndpoint->connect(htons(port_), address) == -1)
	{
		ERROR_MSG(boost::format("ClientObject::initLogin: connect server is error(%1%)!\n") %
			kbe_strerror());

		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}

	Mercury::Address addr(ip_.c_str(), port_);
	pEndpoint->addr(addr);

	pChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this);
	connectedGateway_ = true;
	return true;
}
Esempio n. 20
0
//-------------------------------------------------------------------------------------
bool ClientObject::initCreate()
{
	Mercury::EndPoint* pEndpoint = new Mercury::EndPoint();
	
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n");
		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}
	
	ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots();
	u_int32_t address;

	pEndpoint->convertAddress(infos.login_ip, address);
	if(pEndpoint->connect(htons(infos.login_port), address) == -1)
	{
		ERROR_MSG(boost::format("ClientObject::initNetwork: connect server is error(%1%)!\n") %
			kbe_strerror());

		delete pEndpoint;
		error_ = C_ERROR_INIT_NETWORK_FAILED;
		return false;
	}

	Mercury::Address addr(infos.login_ip, infos.login_port);
	pEndpoint->addr(addr);

	pChannel_->endpoint(pEndpoint);
	pEndpoint->setnonblocking(true);
	pEndpoint->setnodelay(true);

	pChannel_->pMsgHandlers(&ClientInterface::messageHandlers);
	Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this);
	return true;
}
Esempio n. 21
0
//-------------------------------------------------------------------------------------
bool TPThread::onWaitCondSignal(void)
{
#if KBE_PLATFORM == PLATFORM_WIN32
    if(threadWaitSecond_ <= 0)
    {
        state_ = THREAD_STATE_SLEEP;
        WaitForSingleObject(cond_, INFINITE);
        ResetEvent(cond_);
    }
    else
    {
        state_ = THREAD_STATE_SLEEP;
        DWORD ret = WaitForSingleObject(cond_, threadWaitSecond_ * 1000);
        ResetEvent(cond_);

        // 如果是因为超时了, 说明这个线程很久没有被用到, 我们应该注销这个线程。
        // 通知ThreadPool注销自己
        if (ret == WAIT_TIMEOUT)
        {
            threadPool_->removeHangThread(this);
            return false;
        }
        else if(ret != WAIT_OBJECT_0)
        {
            ERROR_MSG(fmt::format("TPThread::onWaitCondSignal: WaitForSingleObject is error, ret={0}\n",
                                  ret));
        }
    }
#else
    if(threadWaitSecond_ <= 0)
    {
        lock();
        state_ = THREAD_STATE_SLEEP;
        pthread_cond_wait(&cond_, &mutex_);
        unlock();
    }
    else
    {
        struct timeval now;
        struct timespec timeout;
        gettimeofday(&now, NULL);
        timeout.tv_sec = now.tv_sec + threadWaitSecond_;
        timeout.tv_nsec = now.tv_usec * 1000;

        lock();
        state_ = THREAD_STATE_SLEEP;
        int ret = pthread_cond_timedwait(&cond_, &mutex_, &timeout);
        unlock();

        // 如果是因为超时了, 说明这个线程很久没有被用到, 我们应该注销这个线程。
        if (ret == ETIMEDOUT)
        {
            // 通知ThreadPool注销自己
            threadPool_->removeHangThread(this);
            return false;
        }
        else if(ret != 0)
        {
            ERROR_MSG(fmt::format("TPThread::onWaitCondSignal: pthread_cond_timedwait is error, {0}\n",
                                  kbe_strerror()));
        }
    }
#endif
    return true;
}
Esempio n. 22
0
//-------------------------------------------------------------------------------------
bool ThreadPool::addTask(TPTask* tptask)
{
    THREAD_MUTEX_LOCK(threadStateList_mutex_);
    if(currentFreeThreadCount_ > 0)
    {
        std::list<TPThread*>::iterator itr = freeThreadList_.begin();
        TPThread* tptd = (TPThread*)(*itr);
        freeThreadList_.erase(itr);
        busyThreadList_.push_back(tptd);
        --currentFreeThreadCount_;

        //INFO_MSG("ThreadPool::currFree:%d, currThreadCount:%d, busy:[%d]\n",
        //		 currentFreeThreadCount_, currentThreadCount_, busyThreadList_count_);

        tptd->task(tptask);												// 给线程设置新任务

#if KBE_PLATFORM == PLATFORM_WIN32
        if(tptd->sendCondSignal()== 0) {
#else
        if(tptd->sendCondSignal()!= 0) {
#endif
            ERROR_MSG("ThreadPool::addTask: pthread_cond_signal is error!\n");
            THREAD_MUTEX_UNLOCK(threadStateList_mutex_);
            return false;
        }

        THREAD_MUTEX_UNLOCK(threadStateList_mutex_);
        return true;
    }

    bufferTask(tptask);

    if(isThreadCountMax())
    {
        THREAD_MUTEX_UNLOCK(threadStateList_mutex_);

        //WARNING_MSG(fmt::format("ThreadPool::addTask: can't createthread, the poolsize is full({}).\n,
        //	maxThreadCount_));

        return false;
    }

    for(uint32 i=0; i<extraNewAddThreadCount_; i++)
    {
        TPThread* tptd = createThread(300);									// 设定5分钟未使用则退出的线程
        if(!tptd)
        {
#if KBE_PLATFORM == PLATFORM_WIN32
            ERROR_MSG("ThreadPool::addTask: the ThreadPool create thread is error! ... \n");
#else
            ERROR_MSG(fmt::format("ThreadPool::addTask: the ThreadPool create thread is error:{0}\n",
                                  kbe_strerror()));
#endif
        }

        allThreadList_.push_back(tptd);										// 所有的线程列表
        freeThreadList_.push_back(tptd);									// 闲置的线程列表
        ++currentThreadCount_;
        ++currentFreeThreadCount_;

    }

    INFO_MSG(fmt::format("ThreadPool::addTask: new Thread, currThreadCount: {0}\n",
                         currentThreadCount_));

    THREAD_MUTEX_UNLOCK(threadStateList_mutex_);
    return true;
}

//-------------------------------------------------------------------------------------
bool ThreadPool::hasThread(TPThread* pTPThread)
{
    bool ret = true;

    THREAD_MUTEX_LOCK(threadStateList_mutex_);

    std::list<TPThread*>::iterator itr1 = find(allThreadList_.begin(), allThreadList_.end(), pTPThread);
    if(itr1 == allThreadList_.end())
        ret = false;

    THREAD_MUTEX_UNLOCK(threadStateList_mutex_);

    return ret;
}
Esempio n. 23
0
//-------------------------------------------------------------------------------------		
int Components::connectComponent(COMPONENT_TYPE componentType, int32 uid, COMPONENT_ID componentID, bool printlog)
{
	Components::ComponentInfos* pComponentInfos = findComponent(componentType, uid, componentID);
	if (pComponentInfos == NULL)
	{
		if (printlog)
		{
			ERROR_MSG(fmt::format("Components::connectComponent: not found componentType={}, uid={}, componentID={}!\n",
				COMPONENT_NAME_EX(componentType), uid, componentID));
		}

		return -1;
	}

	Network::EndPoint * pEndpoint = Network::EndPoint::createPoolObject();
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		if (printlog)
		{
			ERROR_MSG("Components::connectComponent: couldn't create a socket\n");
		}

		Network::EndPoint::reclaimPoolObject(pEndpoint);
		return -1;
	}

	pEndpoint->addr(*pComponentInfos->pIntAddr);
	int ret = pEndpoint->connect(pComponentInfos->pIntAddr->port, pComponentInfos->pIntAddr->ip);

	if(ret == 0)
	{
		Network::Channel* pChannel = Network::Channel::createPoolObject();
		bool ret = pChannel->initialize(*_pNetworkInterface, pEndpoint, Network::Channel::INTERNAL);
		if(!ret)
		{
			if (printlog)
			{
				ERROR_MSG(fmt::format("Components::connectComponent: initialize({}) is failed!\n",
					pChannel->c_str()));
			}

			pChannel->destroy();
			Network::Channel::reclaimPoolObject(pChannel);
			return -1;
		}

		pComponentInfos->pChannel = pChannel;
		pComponentInfos->pChannel->componentID(componentID);
		if(!_pNetworkInterface->registerChannel(pComponentInfos->pChannel))
		{
			if (printlog)
			{
				ERROR_MSG(fmt::format("Components::connectComponent: registerChannel({}) is failed!\n",
					pComponentInfos->pChannel->c_str()));
			}

			pComponentInfos->pChannel->destroy();
			Network::Channel::reclaimPoolObject(pComponentInfos->pChannel);

			// 此时不可强制释放内存,destroy中已经对其减引用
			// SAFE_RELEASE(pComponentInfos->pChannel);
			pComponentInfos->pChannel = NULL;
			return -1;
		}
		else
		{
			Network::Bundle* pBundle = Network::Bundle::createPoolObject();
			if(componentType == BASEAPPMGR_TYPE)
			{
				(*pBundle).newMessage(BaseappmgrInterface::onRegisterNewApp);
				
				BaseappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else if(componentType == CELLAPPMGR_TYPE)
			{
				(*pBundle).newMessage(CellappmgrInterface::onRegisterNewApp);
				
				CellappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else if(componentType == CELLAPP_TYPE)
			{
				(*pBundle).newMessage(CellappInterface::onRegisterNewApp);
				
				CellappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
						_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else if(componentType == BASEAPP_TYPE)
			{
				(*pBundle).newMessage(BaseappInterface::onRegisterNewApp);
				
				BaseappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else if(componentType == DBMGR_TYPE)
			{
				(*pBundle).newMessage(DbmgrInterface::onRegisterNewApp);
				
				DbmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else if(componentType == LOGGER_TYPE)
			{
				(*pBundle).newMessage(LoggerInterface::onRegisterNewApp);
				
				LoggerInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), 
					componentType_, componentID_, 
					g_componentGlobalOrder, g_componentGroupOrder,
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress);
			}
			else
			{
				KBE_ASSERT(false && "invalid componentType.\n");
			}

			pComponentInfos->pChannel->send(pBundle);
		}
	}
	else
	{
		if (printlog)
		{
			ERROR_MSG(fmt::format("Components::connectComponent: connect({}) is failed! {}.\n",
				pComponentInfos->pIntAddr->c_str(), kbe_strerror()));
		}

		Network::EndPoint::reclaimPoolObject(pEndpoint);
		return -1;
	}

	return ret;
}
Esempio n. 24
0
//-------------------------------------------------------------------------------------
bool ClientObject::initLoginGateWay()
{
    Bots::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*pTCPPacketReceiverEx_->pEndPoint());
    pServerChannel_->stopSend();
    pServerChannel_->pPacketSender(NULL);
    SAFE_RELEASE(pTCPPacketSenderEx_);
    SAFE_RELEASE(pTCPPacketReceiverEx_);

    Network::EndPoint* pEndpoint = Network::EndPoint::ObjPool().createObject();

    pEndpoint->socket(SOCK_STREAM);
    if (!pEndpoint->good())
    {
        ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n");
        Network::EndPoint::ObjPool().reclaimObject(pEndpoint);
        error_ = C_ERROR_INIT_NETWORK_FAILED;
        return false;
    }

    u_int32_t address;

    Network::Address::string2ip(ip_.c_str(), address);
    if(pEndpoint->connect(htons(port_), address) == -1)
    {
        ERROR_MSG(fmt::format("ClientObject::initLogin({}): connect server is error({})!\n",
                              kbe_strerror(), name_));

        Network::EndPoint::ObjPool().reclaimObject(pEndpoint);
        // error_ = C_ERROR_INIT_NETWORK_FAILED;
        state_ = C_STATE_LOGIN_GATEWAY_CREATE;
        return false;
    }

    Network::Address addr(ip_.c_str(), port_);
    pEndpoint->addr(addr);
    pServerChannel_->pEndPoint(pEndpoint);
    pEndpoint->setnonblocking(true);
    pEndpoint->setnodelay(true);

    pTCPPacketSenderEx_ = new Network::TCPPacketSenderEx(*pEndpoint, this->networkInterface_, this);
    pTCPPacketReceiverEx_ = new Network::TCPPacketReceiverEx(*pEndpoint, this->networkInterface_, this);
    Bots::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor((*pEndpoint), pTCPPacketReceiverEx_);

    //²»ÔÚÕâÀï×¢²á
    //Bots::getSingleton().networkInterface().dispatcher().registerWriteFileDescriptor((*pEndpoint), pTCPPacketSenderEx_);
    pServerChannel_->pPacketSender(pTCPPacketSenderEx_);

    connectedGateway_ = true;

    Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
    (*pBundle).newMessage(BaseappInterface::hello);
    (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString();

    if(Network::g_channelExternalEncryptType == 1)
    {
        pBlowfishFilter_ = new Network::BlowfishFilter();
        (*pBundle).appendBlob(pBlowfishFilter_->key());
        pServerChannel_->pFilter(NULL);
    }
    else
    {
        std::string key = "";
        (*pBundle).appendBlob(key);
    }

    pEndpoint->send(pBundle);
    Network::Bundle::ObjPool().reclaimObject(pBundle);
    return true;
}
Esempio n. 25
0
//-------------------------------------------------------------------------------------
bool ClientObject::initCreate()
{
    Network::EndPoint* pEndpoint = Network::EndPoint::ObjPool().createObject();

    pEndpoint->socket(SOCK_STREAM);
    if (!pEndpoint->good())
    {
        ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n");
        Network::EndPoint::ObjPool().reclaimObject(pEndpoint);
        error_ = C_ERROR_INIT_NETWORK_FAILED;
        return false;
    }

    ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots();
    u_int32_t address;

    Network::Address::string2ip(infos.login_ip, address);
    if(pEndpoint->connect(htons(infos.login_port), address) == -1)
    {
        ERROR_MSG(fmt::format("ClientObject::initNetwork({1}): connect server({2}:{3}) is error({0})!\n",
                              kbe_strerror(), name_, infos.login_ip, infos.login_port));

        Network::EndPoint::ObjPool().reclaimObject(pEndpoint);
        // error_ = C_ERROR_INIT_NETWORK_FAILED;
        state_ = C_STATE_INIT;
        return false;
    }

    Network::Address addr(infos.login_ip, infos.login_port);
    pEndpoint->addr(addr);

    pServerChannel_->pEndPoint(pEndpoint);
    pEndpoint->setnonblocking(true);
    pEndpoint->setnodelay(true);

    pServerChannel_->pMsgHandlers(&ClientInterface::messageHandlers);

    pTCPPacketSenderEx_ = new Network::TCPPacketSenderEx(*pEndpoint, this->networkInterface_, this);
    pTCPPacketReceiverEx_ = new Network::TCPPacketReceiverEx(*pEndpoint, this->networkInterface_, this);
    Bots::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor((*pEndpoint), pTCPPacketReceiverEx_);

    //²»ÔÚÕâÀï×¢²á
    //Bots::getSingleton().networkInterface().dispatcher().registerWriteFileDescriptor((*pEndpoint), pTCPPacketSenderEx_);
    pServerChannel_->pPacketSender(pTCPPacketSenderEx_);

    Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
    (*pBundle).newMessage(LoginappInterface::hello);
    (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString();

    if(Network::g_channelExternalEncryptType == 1)
    {
        pBlowfishFilter_ = new Network::BlowfishFilter();
        (*pBundle).appendBlob(pBlowfishFilter_->key());
    }
    else
    {
        std::string key = "";
        (*pBundle).appendBlob(key);
    }

    pEndpoint->send(pBundle);
    Network::Bundle::ObjPool().reclaimObject(pBundle);
    return true;
}
Esempio n. 26
0
//-------------------------------------------------------------------------------------
bool ThreadPool::_addTask(TPTask* tptask)
{
	std::list<TPThread*>::iterator itr = freeThreadList_.begin();
	TPThread* tptd = (TPThread*)(*itr);
	freeThreadList_.erase(itr);
	busyThreadList_.push_back(tptd);
	--currentFreeThreadCount_;

	//INFO_MSG("ThreadPool::currFree:%d, currThreadCount:%d, busy:[%d]\n",
	//		 currentFreeThreadCount_, currentThreadCount_, busyThreadList_count_);

	tptd->task(tptask);

#if KBE_PLATFORM == PLATFORM_WIN32
	if (tptd->sendCondSignal() == 0) {
#else
	if (tptd->sendCondSignal() != 0) {
#endif
		ERROR_MSG("ThreadPool::addTask: pthread_cond_signal error!\n");
		return false;
	}

	return true;
}

//-------------------------------------------------------------------------------------
bool ThreadPool::addTask(TPTask* tptask)
{
	THREAD_MUTEX_LOCK(threadStateList_mutex_);
	if(currentFreeThreadCount_ > 0)
	{
		bool ret = _addTask(tptask);
		THREAD_MUTEX_UNLOCK(threadStateList_mutex_);

		return ret;
	}
	
	bufferTask(tptask);
	
	if(isThreadCountMax())
	{
		THREAD_MUTEX_UNLOCK(threadStateList_mutex_);

		//WARNING_MSG(fmt::format("ThreadPool::addTask: can't createthread, the poolsize is full({}).\n,
		//	maxThreadCount_));

		return false;
	}

	for(uint32 i=0; i<extraNewAddThreadCount_; ++i)
	{
		bool threadStartsImmediately = i > 0;

		// 设定5分钟未使用则退出的线程
		TPThread* tptd = createThread(ThreadPool::timeout, threadStartsImmediately);
		if(!tptd)
		{
#if KBE_PLATFORM == PLATFORM_WIN32		
			ERROR_MSG("ThreadPool::addTask: the ThreadPool create thread error! ... \n");
#else
			ERROR_MSG(fmt::format("ThreadPool::addTask: the ThreadPool create thread error:{0}\n", 
				kbe_strerror()));
#endif				
		}
		
		// 所有的线程列表
		allThreadList_.push_back(tptd);	
		
		if (threadStartsImmediately)
		{
			// 闲置的线程列表
			freeThreadList_.push_back(tptd);
			++currentFreeThreadCount_;
		}
		else
		{
			TPTask * pTask = tptd->tryGetTask();
			if (pTask)
			{
				busyThreadList_.push_back(tptd);
				tptd->task(pTask);
			}
			else
			{
				freeThreadList_.push_back(tptd);
				++currentFreeThreadCount_;
			}

			tptd->createThread();
		}

		++currentThreadCount_;
		
		
	}
	
	INFO_MSG(fmt::format("ThreadPool::addTask: new Thread, currThreadCount: {0}\n", 
		currentThreadCount_));

	THREAD_MUTEX_UNLOCK(threadStateList_mutex_);
	return true;
}
Esempio n. 27
0
//-------------------------------------------------------------------------------------
bool UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket)
{
	if (len == 0)
	{
		WARNING_MSG( "PacketReceiver::processPendingEvents: "
			"Throwing REASON_GENERAL_NETWORK (1)- %s\n",
			strerror( errno ) );

		this->dispatcher().errorReporter().reportException(
				REASON_GENERAL_NETWORK );

		return true;
	}
	
#ifdef _WIN32
	DWORD wsaErr = WSAGetLastError();
#endif //def _WIN32

	if (
#ifdef _WIN32
		wsaErr == WSAEWOULDBLOCK && !expectingPacket
#else
		errno == EAGAIN && !expectingPacket
#endif
		)
	{
		return false;
	}

#ifdef unix
	if (errno == EAGAIN ||
		errno == ECONNREFUSED ||
		errno == EHOSTUNREACH)
	{
#if defined(PLAYSTATION3)
		this->dispatcher().errorReporter().reportException(
				REASON_NO_SUCH_PORT);
		return true;
#else
		Mercury::Address offender;

		if (pEndpoint_->getClosedPort(offender))
		{
			// If we got a NO_SUCH_PORT error and there is an internal
			// channel to this address, mark it as remote failed.  The logic
			// for dropping external channels that get NO_SUCH_PORT
			// exceptions is built into BaseApp::onClientNoSuchPort().
			if (errno == ECONNREFUSED)
			{
				// н╢й╣ож
			}

			this->dispatcher().errorReporter().reportException(
					REASON_NO_SUCH_PORT, offender);

			return true;
		}
		else
		{
			WARNING_MSG("UDPPacketReceiver::processPendingEvents: "
				"getClosedPort() failed\n");
		}
#endif
	}
#else
	if (wsaErr == WSAECONNRESET)
	{
		return true;
	}
#endif // unix

#ifdef _WIN32
	WARNING_MSG("UDPPacketReceiver::processPendingEvents: "
				"Throwing REASON_GENERAL_NETWORK - %d\n",
				wsaErr);
#else
	WARNING_MSG("UDPPacketReceiver::processPendingEvents: "
				"Throwing REASON_GENERAL_NETWORK - %s\n",
			kbe_strerror());
#endif
	this->dispatcher().errorReporter().reportException(
			REASON_GENERAL_NETWORK);

	return true;
}
Esempio n. 28
0
PacketReceiver::RecvState UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket)
{
	if (len == 0)
	{
		/*SL_ELOG(fmt::format("PacketReceiver::processPendingEvents: "
			"Throwing REASON_GENERAL_NETWORK (1)- {}\n",
			strerror( errno )));*/

		/*this->dispatcher().errorReporter().reportException(
			REASON_GENERAL_NETWORK );*/

		return RECV_STATE_CONTINUE;
	}

#ifdef _WIN32
	DWORD wsaErr = WSAGetLastError();
#endif //def _WIN32

	if (
#ifdef _WIN32
		wsaErr == WSAEWOULDBLOCK && !expectingPacket
#else
		errno == EAGAIN && !expectingPacket
#endif
		)
	{
		return RECV_STATE_BREAK;
	}

#ifdef unix
	if (errno == EAGAIN ||
		errno == ECONNREFUSED ||
		errno == EHOSTUNREACH)
	{
		Network::Address offender;

		if (pEndpoint_->getClosedPort(offender))
		{
			// If we got a NO_SUCH_PORT error and there is an internal
			// channel to this address, mark it as remote failed.  The logic
			// for dropping external channels that get NO_SUCH_PORT
			// exceptions is built into BaseApp::onClientNoSuchPort().
			if (errno == ECONNREFUSED)
			{
				// 未实现
			}

			this->dispatcher().errorReporter().reportException(
				REASON_NO_SUCH_PORT, offender);

			return RECV_STATE_CONTINUE;
		}
		else
		{
			WARNING_MSG("UDPPacketReceiver::processPendingEvents: "
				"getClosedPort() failed\n");
		}
	}
#else
	if (wsaErr == WSAECONNRESET)
	{
		return RECV_STATE_CONTINUE;
	}
#endif // unix

#ifdef _WIN32
	/*WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: "
		"Throwing REASON_GENERAL_NETWORK - {}\n",
		wsaErr));*/
#else
	WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: "
		"Throwing REASON_GENERAL_NETWORK - {}\n",
		kbe_strerror()));
#endif
	/*this->dispatcher().errorReporter().reportException(
		REASON_GENERAL_NETWORK);*/

	return RECV_STATE_CONTINUE;
}
//-------------------------------------------------------------------------------------
int HTTPCBHandler::handleInputNotification(int fd)
{
	if(fd == *pEndPoint_)
	{
		u_int16_t port;
		u_int32_t addr;

		Network::EndPoint* newclient = pEndPoint_->accept(&port, &addr);

		if(newclient == NULL)
		{
			ERROR_MSG(fmt::format("HTTPCBHandler::handleInputNotification: accept is error:{}.\n", kbe_strerror()));
			return 0;
		}

		INFO_MSG(fmt::format("HTTPCBHandler:handleInputNotification: newclient = {}\n",
			newclient->c_str()));
		
		newclient->setnonblocking(true);
		CLIENT& client = clients_[*newclient];
		client.endpoint = KBEShared_ptr< Network::EndPoint >(newclient);
		client.state = 0;
		Loginapp::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor(*newclient, this);
	}
	else
	{
		std::map< int, CLIENT >::iterator iter = clients_.find(fd);
		if(iter == clients_.end())
		{
			ERROR_MSG(fmt::format("HTTPCBHandler:handleInputNotification: fd({}) not found!\n",
				fd));
			return 0;
		}

		CLIENT& client = iter->second;
		Network::EndPoint* newclient = iter->second.endpoint.get();

		char buffer[1024];
		int len = newclient->recv(&buffer, 1024);

		if(len <= 0)
		{
			ERROR_MSG(fmt::format("HTTPCBHandler:handleInputNotification: recv error, newclient = {}, recv={}.\n",
				newclient->c_str(), len));
		
			if(len == 0)
			{
				Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient);
				clients_.erase(iter);
			}
			return 0;
		}

		if(client.state == 1)
		{
			Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient);
			clients_.erase(iter);
		}

		int type = 0;
		std::string s = buffer;
		
		std::string keys = "<policy-file-request/>";
		std::string::size_type fi0 = s.find(keys);
		if(fi0 != std::string::npos)
		{
			if(client.state != 1)
			{
				std::string response = "<?xml version='1.0'?><cross-domain-policy><allow-access-from domain=""*"" to-ports=""*"" /></cross-domain-policy>";
				iter->second.endpoint->send(response.c_str(), response.size());
				Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient);
				clients_.erase(iter);
			}

			return 0;
		}

		keys = "accountactivate_";
		std::string::size_type fi1 = s.find(keys);
		if(fi1 == std::string::npos)
		{
			keys = "resetpassword_";
			fi1 = s.find(keys);
			if(fi1 == std::string::npos)
			{
				keys = "bindmail_";
				fi1 = s.find(keys);
				if(fi1 != std::string::npos)
				{
					type = 3;
				}
			}
			else
			{
				type = 2;
			}
		}
		else
		{
			type = 1;
		}

		std::string::size_type fi2 = s.find("?");
		std::string::size_type fi3 = s.find(" HTTP/");

		if(fi2 == std::string::npos || fi2 > fi3)
			fi2 = fi3;

		if(fi2 <= fi1)
		{
			return 0;
		}

		std::string code;
		if(fi1 != std::string::npos && fi2 != std::string::npos)
		{
			int ilen = keys.size();
			code.assign(s.c_str() + fi1 + ilen, fi2 - (fi1 + ilen));
		}

		client.state = 1;
		
		code = KBEngine::strutil::kbe_trim(code);

		if(code.size() > 0)
		{
			INFO_MSG(fmt::format("HTTPCBHandler:handleInputNotification: code = {}\n",
				code.c_str()));

			client.code = code;

			Components::COMPONENTS& cts = Components::getSingleton().getComponents(DBMGR_TYPE);
			Components::ComponentInfos* dbmgrinfos = NULL;

			if(cts.size() > 0)
				dbmgrinfos = &(*cts.begin());

			if(dbmgrinfos == NULL || dbmgrinfos->pChannel == NULL || dbmgrinfos->cid == 0)
			{
				return 0;
			}

			std::string hellomessage;

			if(type == 1)
			{
				// Ïòdbmgr¼¤»îÕ˺Å
				Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
				(*pBundle).newMessage(DbmgrInterface::accountActivate);
				(*pBundle) << code;
				dbmgrinfos->pChannel->send(pBundle);

				hellomessage = g_kbeSrvConfig.emailAtivationInfo_.backlink_hello_message;
			}
			else if(type == 2)
			{
				std::string::size_type fi1 = s.find("password="******"&", fi1);

				std::string password;
				
				if(fi1 != std::string::npos && fi2 != std::string::npos)
				{
					client.state = 2;
					if(fi1 < fi2)
					{
						int ilen = strlen("password="******"username="******"&", fi1);

					std::string username;
					
					if(fi1 != std::string::npos && fi2 != std::string::npos)
					{
						if(fi1 < fi2)
						{
							int ilen = strlen("username="******"username="******" HTTP/");
				
				if(fi1 != std::string::npos && fi2 != std::string::npos)
				{
					if(fi1 < fi2)
					{
						int ilen = strlen("username="******"${backlink}", fmt::format("http://{}:{}/{}{}", 
					Loginapp::getSingleton().networkInterface().extaddr().ipAsString(),
					g_kbeSrvConfig.getLoginApp().http_cbport,
					keys,
					code));

				KBEngine::strutil::kbe_replace(hellomessage, "${code}", code);

				std::string response = fmt::format("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n{}", 
					hellomessage.size(), hellomessage);

				newclient->send(response.c_str(), response.size());
			}

			client.state = 2;
		}
		else
		{
			if(client.state != 2)
			{
				Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient);
				clients_.erase(iter);
			}
		}
	}

	return 0;
}
Esempio n. 30
0
//-------------------------------------------------------------------------------------		
int Components::connectComponent(COMPONENT_TYPE componentType, int32 uid, COMPONENT_ID componentID)
{
	Components::ComponentInfos* pComponentInfos = findComponent(componentType, uid, componentID);
	KBE_ASSERT(pComponentInfos != NULL);

	Mercury::EndPoint * pEndpoint = new Mercury::EndPoint;
	pEndpoint->socket(SOCK_STREAM);
	if (!pEndpoint->good())
	{
		ERROR_MSG("Components::connectComponent: couldn't create a socket\n");
		delete pEndpoint;
		return -1;
	}

	pEndpoint->addr(*pComponentInfos->pIntAddr);
	int ret = pEndpoint->connect(pComponentInfos->pIntAddr->port, pComponentInfos->pIntAddr->ip);

	if(ret == 0)
	{
		pComponentInfos->pChannel = new Mercury::Channel(*_pNetworkInterface, pEndpoint, Mercury::Channel::INTERNAL);
		if(!_pNetworkInterface->registerChannel(pComponentInfos->pChannel))
		{
			ERROR_MSG("Components::connectComponent: registerChannel(%s) is failed!\n",
				pComponentInfos->pChannel->c_str());

			delete pComponentInfos->pChannel;
			pComponentInfos->pChannel = NULL;
			return -1;
		}
		else
		{
			Mercury::Bundle bundle(pComponentInfos->pChannel);
			if(componentType == BASEAPPMGR_TYPE)
			{
				bundle.newMessage(BaseappmgrInterface::onRegisterNewApp);
				
				BaseappmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == CELLAPPMGR_TYPE)
			{
				bundle.newMessage(CellappmgrInterface::onRegisterNewApp);
				
				CellappmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == CELLAPP_TYPE)
			{
				bundle.newMessage(CellappInterface::onRegisterNewApp);
				
				CellappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
						_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == BASEAPP_TYPE)
			{
				bundle.newMessage(BaseappInterface::onRegisterNewApp);
				
				BaseappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == DBMGR_TYPE)
			{
				bundle.newMessage(DbmgrInterface::onRegisterNewApp);
				
				DbmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == MESSAGELOG_TYPE)
			{
				bundle.newMessage(MessagelogInterface::onRegisterNewApp);
				
				MessagelogInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else if(componentType == RESOURCEMGR_TYPE)
			{
				bundle.newMessage(ResourcemgrInterface::onRegisterNewApp);
				
				ResourcemgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), 
					Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), 
					_pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port,
					_pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port);
			}
			else
			{
				KBE_ASSERT(false && "invalid componentType.\n");
			}

			bundle.send(*_pNetworkInterface, pComponentInfos->pChannel);
		}
	}
	else
	{
		ERROR_MSG("Components::connectComponent: connect(%s) is failed! %s.\n",
			pComponentInfos->pIntAddr->c_str(), kbe_strerror());

		return -1;
	}

	return ret;
}