ahmedhaies

desc_manager.cpp

Mar 23rd, 2016
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.23 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "config.h"
  3. #include "utils.h"
  4. #include "crc32.h"
  5. #include "desc.h"
  6. #include "desc_p2p.h"
  7. #include "desc_client.h"
  8. #include "desc_manager.h"
  9. #include "char.h"
  10. #include "protocol.h"
  11. #include "messenger_manager.h"
  12. #include "p2p.h"
  13. #include "ip_ban.h"
  14. #include "dev_log.h"
  15. #include "ClientPackageCryptInfo.h"
  16.  
  17. struct valid_ip
  18. {
  19.     const char *    ip;
  20.     BYTE    network;
  21.     BYTE    mask;
  22. };
  23.  
  24. static struct valid_ip admin_ip[] =
  25. {
  26.     { "210.123.10",     128,    128     },
  27.     { "\n",             0,      0       }
  28. };
  29.  
  30. int IsValidIP(struct valid_ip* ip_table, const char *host)
  31. {
  32.     int         i, j;
  33.     char        ip_addr[256];
  34.  
  35.     for (i = 0; *(ip_table + i)->ip != '\n'; ++i)
  36.     {
  37.         j = 255 - (ip_table + i)->mask;
  38.  
  39.         do
  40.         {
  41.             snprintf(ip_addr, sizeof(ip_addr), "%s.%d", (ip_table + i)->ip, (ip_table + i)->network + j);
  42.  
  43.             if (!strcmp(ip_addr, host))
  44.                 return TRUE;
  45.  
  46.             if (!j)
  47.                 break;
  48.         }
  49.         while (j--);
  50.     }
  51.  
  52.     return FALSE;
  53. }
  54.  
  55. DESC_MANAGER::DESC_MANAGER() : m_bDestroyed(false)
  56. {
  57.     Initialize();
  58.     //NOTE : Destroy 끝에서 Initialize 를 부르는건 또 무슨 짓이냐..-_-; 정말
  59.  
  60.     m_pPackageCrypt = new CClientPackageCryptInfo;
  61. }
  62.  
  63. DESC_MANAGER::~DESC_MANAGER()
  64. {
  65.     Destroy();
  66.     delete m_pPackageCrypt;
  67. }
  68.  
  69. void DESC_MANAGER::Initialize()
  70. {
  71.     m_iSocketsConnected = 0;
  72.     m_iHandleCount = 0;
  73.     m_iLocalUserCount = 0;
  74.     memset(m_aiEmpireUserCount, 0, sizeof(m_aiEmpireUserCount));
  75.     m_bDisconnectInvalidCRC = false;
  76. }
  77.  
  78. void DESC_MANAGER::Destroy()
  79. {
  80.     if (m_bDestroyed) {
  81.         return;
  82.     }
  83.     m_bDestroyed = true;
  84.  
  85.     DESC_SET::iterator i = m_set_pkDesc.begin();
  86.  
  87.     while (i != m_set_pkDesc.end())
  88.     {
  89.         LPDESC d = *i;
  90.         DESC_SET::iterator ci = i;
  91.         ++i;
  92.  
  93.         if (d->GetType() == DESC_TYPE_CONNECTOR)
  94.             continue;
  95.  
  96.         if (d->IsPhase(PHASE_P2P))
  97.             continue;
  98.  
  99.         DestroyDesc(d, false);
  100.         m_set_pkDesc.erase(ci);
  101.     }
  102.  
  103.     i = m_set_pkDesc.begin();
  104.  
  105.     while (i != m_set_pkDesc.end())
  106.     {
  107.         LPDESC d = *i;
  108.         DESC_SET::iterator ci = i;
  109.         ++i;
  110.  
  111.         DestroyDesc(d, false);
  112.         m_set_pkDesc.erase(ci);
  113.     }
  114.  
  115.     m_set_pkClientDesc.clear();
  116.  
  117.     //m_AccountIDMap.clear();
  118.     m_map_loginName.clear();
  119.     m_map_handle.clear();
  120.  
  121.     Initialize();
  122. }
  123.  
  124. DWORD DESC_MANAGER::CreateHandshake()
  125. {
  126.     char crc_buf[8];
  127.     crc_t crc;
  128.     DESC_HANDSHAKE_MAP::iterator it;
  129.  
  130. RETRY:
  131.     do
  132.     {
  133.         DWORD val = thecore_random() % (1024 * 1024);
  134.  
  135.         *(DWORD *) (crc_buf    ) = val;
  136.         *((DWORD *) crc_buf + 1) = get_global_time();
  137.  
  138.         crc = GetCRC32(crc_buf, 8);
  139.         it = m_map_handshake.find(crc);
  140.     }
  141.     while (it != m_map_handshake.end());
  142.  
  143.     if (crc == 0)
  144.         goto RETRY;
  145.  
  146.     return (crc);
  147. }
  148.  
  149. LPDESC DESC_MANAGER::AcceptDesc(LPFDWATCH fdw, socket_t s)
  150. {
  151.     socket_t                    desc;
  152.     LPDESC                      newd;
  153.     static struct sockaddr_in   peer;
  154.     static char                 host[MAX_HOST_LENGTH + 1];
  155.  
  156.     if ((desc = socket_accept(s, &peer)) == -1)
  157.         return NULL;
  158.  
  159.     strlcpy(host, inet_ntoa(peer.sin_addr), sizeof(host));
  160.  
  161.     if (g_bAuthServer)
  162.     {
  163.         if (IsBanIP(peer.sin_addr))
  164.         {
  165.             sys_log(0, "connection from %s was banned.", host);
  166.             socket_close(desc);
  167.             return NULL;
  168.         }
  169.     }
  170.  
  171.     if (!IsValidIP(admin_ip, host)) // admin_ip 에 등록된 IP 는 최대 사용자 수에 구애받지 않는다.
  172.     {
  173.         if (m_iSocketsConnected >= MAX_ALLOW_USER)
  174.         {
  175.             sys_err("max connection reached. MAX_ALLOW_USER = %d", MAX_ALLOW_USER);
  176.             socket_close(desc);
  177.             return NULL;
  178.         }
  179.     }
  180.  
  181.     newd = M2_NEW DESC;
  182.     crc_t handshake = CreateHandshake();
  183.  
  184.     if (!newd->Setup(fdw, desc, peer, ++m_iHandleCount, handshake))
  185.     {
  186.         socket_close(desc);
  187.         M2_DELETE(newd);
  188.         return NULL;
  189.     }
  190.  
  191.     m_map_handshake.insert(DESC_HANDSHAKE_MAP::value_type(handshake, newd));
  192.     m_map_handle.insert(DESC_HANDLE_MAP::value_type(newd->GetHandle(), newd));
  193.  
  194.     m_set_pkDesc.insert(newd);
  195.     ++m_iSocketsConnected;
  196.     return (newd);
  197. }
  198.  
  199. LPDESC DESC_MANAGER::AcceptP2PDesc(LPFDWATCH fdw, socket_t bind_fd)
  200. {
  201.     socket_t           fd;
  202.     struct sockaddr_in peer;
  203.     char               host[MAX_HOST_LENGTH + 1];
  204.  
  205.     if ((fd = socket_accept(bind_fd, &peer)) == -1)
  206.         return NULL;
  207.  
  208.     strlcpy(host, inet_ntoa(peer.sin_addr), sizeof(host));
  209.  
  210.     LPDESC_P2P pkDesc = M2_NEW DESC_P2P;
  211.  
  212.     if (!pkDesc->Setup(fdw, fd, host, peer.sin_port))
  213.     {
  214.         sys_err("DESC_MANAGER::AcceptP2PDesc : Setup failed");
  215.         socket_close(fd);
  216.         M2_DELETE(pkDesc);
  217.         return NULL;
  218.     }
  219.  
  220.     m_set_pkDesc.insert(pkDesc);
  221.     ++m_iSocketsConnected;
  222.  
  223.     sys_log(0, "DESC_MANAGER::AcceptP2PDesc  %s:%u", host, peer.sin_port);
  224.     P2P_MANAGER::instance().RegisterAcceptor(pkDesc);
  225.     return (pkDesc);
  226. }
  227.  
  228. void DESC_MANAGER::ConnectAccount(const std::string& login, LPDESC d)
  229. {
  230. dev_log(LOG_DEB0, "BBBB ConnectAccount(%s)", login.c_str());
  231.     m_map_loginName.insert(DESC_LOGINNAME_MAP::value_type(login,d));
  232. }
  233.  
  234. void DESC_MANAGER::DisconnectAccount(const std::string& login)
  235. {
  236. dev_log(LOG_DEB0, "BBBB DisConnectAccount(%s)", login.c_str());
  237.     m_map_loginName.erase(login);
  238. }
  239.  
  240. void DESC_MANAGER::DestroyDesc(LPDESC d, bool bEraseFromSet)
  241. {
  242.     if (bEraseFromSet)
  243.         m_set_pkDesc.erase(d);
  244.  
  245.     if (d->GetHandshake())
  246.         m_map_handshake.erase(d->GetHandshake());
  247.  
  248.     if (d->GetHandle() != 0)
  249.         m_map_handle.erase(d->GetHandle());
  250.     else
  251.         m_set_pkClientDesc.erase((LPCLIENT_DESC) d);
  252.  
  253.     // Explicit call to the virtual function Destroy()
  254.     d->Destroy();
  255.  
  256.     M2_DELETE(d);
  257.     --m_iSocketsConnected;
  258. }
  259.  
  260. void DESC_MANAGER::DestroyClosed()
  261. {
  262.     DESC_SET::iterator i = m_set_pkDesc.begin();
  263.  
  264.     while (i != m_set_pkDesc.end())
  265.     {
  266.         LPDESC d = *i;
  267.         DESC_SET::iterator ci = i;
  268.         ++i;
  269.  
  270.         if (d->IsPhase(PHASE_CLOSE))
  271.         {
  272.             if (d->GetType() == DESC_TYPE_CONNECTOR)
  273.             {
  274.                 LPCLIENT_DESC client_desc = (LPCLIENT_DESC)d;
  275.  
  276.                 if (client_desc->IsRetryWhenClosed())
  277.                 {
  278.                     client_desc->Reset();
  279.                     continue;
  280.                 }
  281.             }
  282.  
  283.             DestroyDesc(d, false);
  284.             m_set_pkDesc.erase(ci);
  285.         }
  286.     }
  287. }
  288.  
  289. LPDESC DESC_MANAGER::FindByLoginName(const std::string& login)
  290. {
  291.     DESC_LOGINNAME_MAP::iterator it = m_map_loginName.find(login);
  292.  
  293.     if (m_map_loginName.end() == it)
  294.         return NULL;
  295.  
  296.     return (it->second);
  297. }
  298.  
  299. LPDESC DESC_MANAGER::FindByHandle(DWORD handle)
  300. {
  301.     DESC_HANDLE_MAP::iterator it = m_map_handle.find(handle);
  302.  
  303.     if (m_map_handle.end() == it)
  304.         return NULL;
  305.  
  306.     return (it->second);
  307. }
  308.  
  309. const DESC_MANAGER::DESC_SET & DESC_MANAGER::GetClientSet()
  310. {
  311.     return m_set_pkDesc;
  312. }
  313.  
  314. struct name_with_desc_func
  315. {
  316.     const char * m_name;
  317.  
  318.     name_with_desc_func(const char * name) : m_name(name)
  319.     {
  320.     }
  321.  
  322.     bool operator () (LPDESC d)
  323.     {
  324.         if (d->GetCharacter() && !strcmp(d->GetCharacter()->GetName(), m_name))
  325.             return true;
  326.  
  327.         return false;
  328.     }
  329. };
  330.  
  331. LPDESC DESC_MANAGER::FindByCharacterName(const char *name)
  332. {
  333.     DESC_SET::iterator it = std::find_if (m_set_pkDesc.begin(), m_set_pkDesc.end(), name_with_desc_func(name));
  334.     return (it == m_set_pkDesc.end()) ? NULL : (*it);
  335. }
  336.  
  337. LPCLIENT_DESC DESC_MANAGER::CreateConnectionDesc(LPFDWATCH fdw, const char * host, WORD port, int iPhaseWhenSucceed, bool bRetryWhenClosed)
  338. {
  339.     LPCLIENT_DESC newd;
  340.  
  341.     newd = M2_NEW CLIENT_DESC;
  342.  
  343.     newd->Setup(fdw, host, port);
  344.     newd->Connect(iPhaseWhenSucceed);
  345.     newd->SetRetryWhenClosed(bRetryWhenClosed);
  346.  
  347.     m_set_pkDesc.insert(newd);
  348.     m_set_pkClientDesc.insert(newd);
  349.  
  350.     ++m_iSocketsConnected;
  351.     return (newd);
  352. }
  353.  
  354. struct FuncTryConnect
  355. {
  356.     void operator () (LPDESC d)
  357.     {
  358.         ((LPCLIENT_DESC)d)->Connect();
  359.     }
  360. };
  361.  
  362. void DESC_MANAGER::TryConnect()
  363. {
  364.     FuncTryConnect f;
  365.     std::for_each(m_set_pkClientDesc.begin(), m_set_pkClientDesc.end(), f);
  366. }
  367.  
  368. bool DESC_MANAGER::IsP2PDescExist(const char * szHost, WORD wPort)
  369. {
  370.     CLIENT_DESC_SET::iterator it = m_set_pkClientDesc.begin();
  371.  
  372.     while (it != m_set_pkClientDesc.end())
  373.     {
  374.         LPCLIENT_DESC d = *(it++);
  375.  
  376.         if (!strcmp(d->GetP2PHost(), szHost) && d->GetP2PPort() == wPort)
  377.             return true;
  378.     }
  379.  
  380.     return false;
  381. }
  382.  
  383. LPDESC DESC_MANAGER::FindByHandshake(DWORD dwHandshake)
  384. {
  385.     DESC_HANDSHAKE_MAP::iterator it = m_map_handshake.find(dwHandshake);
  386.  
  387.     if (it == m_map_handshake.end())
  388.         return NULL;
  389.  
  390.     return (it->second);
  391. }
  392.  
  393. class FuncWho
  394. {
  395.     public:
  396.         int iTotalCount;
  397.         int aiEmpireUserCount[EMPIRE_MAX_NUM];
  398.  
  399.         FuncWho()
  400.         {
  401.             iTotalCount = 0;
  402.             memset(aiEmpireUserCount, 0, sizeof(aiEmpireUserCount));
  403.         }
  404.  
  405.         void operator() (LPDESC d)
  406.         {
  407.             if (d->GetCharacter())
  408.             {
  409.                 ++iTotalCount;
  410.                 ++aiEmpireUserCount[d->GetEmpire()];
  411.             }
  412.         }
  413. };
  414.  
  415. void DESC_MANAGER::UpdateLocalUserCount()
  416. {
  417.     const DESC_SET & c_ref_set = GetClientSet();
  418.     FuncWho f;
  419.     f = std::for_each(c_ref_set.begin(), c_ref_set.end(), f);
  420.  
  421.     m_iLocalUserCount = f.iTotalCount;
  422.     thecore_memcpy(m_aiEmpireUserCount, f.aiEmpireUserCount, sizeof(m_aiEmpireUserCount));
  423.  
  424.     m_aiEmpireUserCount[1] += P2P_MANAGER::instance().GetEmpireUserCount(1);
  425.     m_aiEmpireUserCount[2] += P2P_MANAGER::instance().GetEmpireUserCount(2);
  426.     m_aiEmpireUserCount[3] += P2P_MANAGER::instance().GetEmpireUserCount(3);
  427. }
  428.  
  429. void DESC_MANAGER::GetUserCount(int & iTotal, int ** paiEmpireUserCount, int & iLocalCount)
  430. {
  431.     *paiEmpireUserCount = &m_aiEmpireUserCount[0];
  432.  
  433.     int iCount = P2P_MANAGER::instance().GetCount();
  434.     if (iCount < 0)
  435.     {
  436.         sys_err("P2P_MANAGER::instance().GetCount() == -1");
  437.     }
  438.     iTotal = m_iLocalUserCount + iCount;
  439.     iLocalCount = m_iLocalUserCount;
  440. }
  441.  
  442.  
  443. DWORD DESC_MANAGER::MakeRandomKey(DWORD dwHandle)
  444. {
  445.     DWORD random_key = thecore_random();
  446.     m_map_handle_random_key.insert(std::make_pair(dwHandle, random_key));
  447.     return random_key;
  448. }
  449.  
  450. bool DESC_MANAGER::GetRandomKey(DWORD dwHandle, DWORD* prandom_key)
  451. {
  452.     DESC_HANDLE_RANDOM_KEY_MAP::iterator it = m_map_handle_random_key.find(dwHandle);
  453.  
  454.     if (it == m_map_handle_random_key.end())
  455.         return false;
  456.  
  457.     *prandom_key = it->second;
  458.     return true;
  459. }
  460.  
  461. LPDESC DESC_MANAGER::FindByLoginKey(DWORD dwKey)
  462. {
  463.     std::map<DWORD, CLoginKey *>::iterator it = m_map_pkLoginKey.find(dwKey);
  464.  
  465.     if (it == m_map_pkLoginKey.end())
  466.         return NULL;
  467.  
  468.     return it->second->m_pkDesc;
  469. }
  470.  
  471.  
  472. DWORD DESC_MANAGER::CreateLoginKey(LPDESC d)
  473. {
  474.     DWORD dwKey = 0;
  475.  
  476.     do
  477.     {
  478.         dwKey = number(1, INT_MAX);
  479.  
  480.         if (m_map_pkLoginKey.find(dwKey) != m_map_pkLoginKey.end())
  481.             continue;
  482.  
  483.         CLoginKey * pkKey = M2_NEW CLoginKey(dwKey, d);
  484.         d->SetLoginKey(pkKey);
  485.         m_map_pkLoginKey.insert(std::make_pair(dwKey, pkKey));
  486.         break;
  487.     } while (1);
  488.  
  489.     return dwKey;
  490. }
  491.  
  492. void DESC_MANAGER::ProcessExpiredLoginKey()
  493. {
  494.     DWORD dwCurrentTime = get_dword_time();
  495.  
  496.     std::map<DWORD, CLoginKey *>::iterator it, it2;
  497.  
  498.     it = m_map_pkLoginKey.begin();
  499.  
  500.     while (it != m_map_pkLoginKey.end())
  501.     {
  502.         it2 = it++;
  503.  
  504.         if (it2->second->m_dwExpireTime == 0)
  505.             continue;
  506.  
  507.         if (dwCurrentTime - it2->second->m_dwExpireTime > 60000)
  508.         {
  509.             M2_DELETE(it2->second);
  510.             m_map_pkLoginKey.erase(it2);
  511.         }
  512.     }
  513. }
  514.  
  515. bool DESC_MANAGER::LoadClientPackageCryptInfo(const char* pDirName)
  516. {
  517.     return m_pPackageCrypt->LoadPackageCryptInfo(pDirName);
  518. }
  519. #ifdef __FreeBSD__
  520. void DESC_MANAGER::NotifyClientPackageFileChanged( const std::string& dirName, eFileUpdatedOptions eUpdateOption )
  521. {
  522.      Instance().LoadClientPackageCryptInfo(dirName.c_str());
  523. }
  524. #endif
  525.  
  526.  
  527. void DESC_MANAGER::SendClientPackageCryptKey( LPDESC desc )
  528. {
  529.     if( !desc )
  530.     {
  531.         return;
  532.     }
  533.  
  534.     TPacketGCHybridCryptKeys packet;
  535.     {
  536.         packet.bHeader = HEADER_GC_HYBRIDCRYPT_KEYS;
  537.         m_pPackageCrypt->GetPackageCryptKeys( &(packet.pDataKeyStream), packet.KeyStreamLen );
  538.     }
  539.  
  540.     if( packet.KeyStreamLen > 0 )
  541.     {
  542.         if (test_server)
  543.         {
  544.             // keys를 string으로 남기는 건 문제가 있음. 중간에 NULL 있으면 잘릴테니.. 그래도 혹시 모르니 남김.
  545.             sys_log(0, "[PackageCryptInfo] send to %s. (keys: %s, len: %d)", desc->GetAccountTable().login, std::string((char*)packet.pDataKeyStream).c_str(), packet.KeyStreamLen);
  546.         }
  547.         desc->Packet( packet.GetStreamData(), packet.GetStreamSize() );
  548.     }
  549. }
  550.  
  551. void DESC_MANAGER::SendClientPackageSDBToLoadMap( LPDESC desc, const char* pMapName )
  552. {
  553.     if( !desc )
  554.     {
  555.         return;
  556.     }
  557.  
  558.     TPacketGCPackageSDB packet;
  559.     {
  560.         packet.bHeader      = HEADER_GC_HYBRIDCRYPT_SDB;
  561.         if( !m_pPackageCrypt->GetRelatedMapSDBStreams( pMapName, &(packet.m_pDataSDBStream), packet.iStreamLen ) )
  562.             return;
  563.         if (test_server)
  564.             sys_log(0, "[PackageCryptInfo] send to %s from map %s. (SDB len: %d)", desc->GetAccountTable().login, pMapName, packet.iStreamLen);
  565.     }
  566.  
  567.     if( packet.iStreamLen > 0 )
  568.     {
  569.         desc->Packet( packet.GetStreamData(), packet.GetStreamSize());
  570.     }
  571. }
Advertisement
Add Comment
Please, Sign In to add comment