server.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include <system.h>
  2. #include "netban.h"
  3. #include "network.h"
  4. #include "main.h"
  5. #include "server.h"
  6. int CServer::NewClientCallback(int ClientID, void *pUser)
  7. {
  8. CServer *pThis = (CServer *)pUser;
  9. char aAddrStr[NETADDR_MAXSTRSIZE];
  10. net_addr_str(pThis->m_Network.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true);
  11. if(pThis->Main()->Config()->m_Verbose)
  12. dbg_msg("server", "Connection accepted. ncid=%d addr=%s'", ClientID, aAddrStr);
  13. pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTED;
  14. pThis->m_aClients[ClientID].m_TimeConnected = time_get();
  15. pThis->m_Network.Send(ClientID, "Authentication required:");
  16. return 0;
  17. }
  18. int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser)
  19. {
  20. CServer *pThis = (CServer *)pUser;
  21. char aAddrStr[NETADDR_MAXSTRSIZE];
  22. net_addr_str(pThis->m_Network.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true);
  23. if(pThis->Main()->Config()->m_Verbose)
  24. dbg_msg("server", "Client dropped. ncid=%d addr=%s reason='%s'", ClientID, aAddrStr, pReason);
  25. if(pThis->m_aClients[ClientID].m_State == CClient::STATE_AUTHED)
  26. pThis->Main()->OnDelClient(ClientID);
  27. pThis->m_aClients[ClientID].m_State = CClient::STATE_EMPTY;
  28. return 0;
  29. }
  30. int CServer::Init(CMain *pMain, const char *Bind, int Port)
  31. {
  32. m_pMain = pMain;
  33. m_NetBan.Init();
  34. for(int i = 0; i < NET_MAX_CLIENTS; i++)
  35. m_aClients[i].m_State = CClient::STATE_EMPTY;
  36. m_Ready = false;
  37. if(Port == 0)
  38. {
  39. dbg_msg("server", "Will not bind to port 0.");
  40. return 1;
  41. }
  42. NETADDR BindAddr;
  43. if(Bind[0] && net_host_lookup(Bind, &BindAddr, NETTYPE_ALL) == 0)
  44. {
  45. // got bindaddr
  46. BindAddr.type = NETTYPE_ALL;
  47. BindAddr.port = Port;
  48. }
  49. else
  50. {
  51. mem_zero(&BindAddr, sizeof(BindAddr));
  52. BindAddr.type = NETTYPE_ALL;
  53. BindAddr.port = Port;
  54. }
  55. if(m_Network.Open(BindAddr, &m_NetBan))
  56. {
  57. m_Network.SetCallbacks(NewClientCallback, DelClientCallback, this);
  58. m_Ready = true;
  59. dbg_msg("server", "Bound to %s:%d", Bind, Port);
  60. return 0;
  61. }
  62. else
  63. dbg_msg("server", "Couldn't open socket. Port (%d) might already be in use.", Port);
  64. return 1;
  65. }
  66. void CServer::Update()
  67. {
  68. if(!m_Ready)
  69. return;
  70. m_NetBan.Update();
  71. m_Network.Update();
  72. char aBuf[NET_MAX_PACKETSIZE];
  73. int ClientID;
  74. while(m_Network.Recv(aBuf, (int)(sizeof(aBuf))-1, &ClientID))
  75. {
  76. dbg_assert(m_aClients[ClientID].m_State != CClient::STATE_EMPTY, "Got message from empty slot.");
  77. if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTED)
  78. {
  79. int ID = -1;
  80. char aUsername[128] = {0};
  81. char aPassword[128] = {0};
  82. const char *pTmp;
  83. if(!(pTmp = str_find(aBuf, ":"))
  84. || (unsigned)(pTmp - aBuf) > sizeof(aUsername) || (unsigned)(str_length(pTmp) - 1) > sizeof(aPassword))
  85. {
  86. m_Network.NetBan()->BanAddr(m_Network.ClientAddr(ClientID), 60, "You're an idiot, go away.");
  87. m_Network.Drop(ClientID, "Fuck off.");
  88. return;
  89. }
  90. str_copy(aUsername, aBuf, pTmp - aBuf + 1);
  91. str_copy(aPassword, pTmp + 1, sizeof(aPassword));
  92. if(!*aUsername || !*aPassword)
  93. {
  94. m_Network.NetBan()->BanAddr(m_Network.ClientAddr(ClientID), 60, "You're an idiot, go away.");
  95. m_Network.Drop(ClientID, "Username and password must not be blank.");
  96. return;
  97. }
  98. for(int i = 0; i < NET_MAX_CLIENTS; i++)
  99. {
  100. if(!Main()->Client(i)->m_Active)
  101. continue;
  102. if(str_comp(Main()->Client(i)->m_aUsername, aUsername) == 0 && str_comp(Main()->Client(i)->m_aPassword, aPassword) == 0)
  103. ID = i;
  104. }
  105. if(ID == -1)
  106. {
  107. m_Network.NetBan()->BanAddr(m_Network.ClientAddr(ClientID), 60, "Wrong username and/or password.");
  108. m_Network.Drop(ClientID, "Wrong username and/or password.");
  109. }
  110. else if(Main()->Client(ID)->m_ClientNetID != -1)
  111. {
  112. m_Network.Drop(ClientID, "Only one connection per user allowed.");
  113. }
  114. else
  115. {
  116. m_aClients[ClientID].m_State = CClient::STATE_AUTHED;
  117. m_aClients[ClientID].m_LastReceived = time_get();
  118. m_Network.Send(ClientID, "Authentication successful. Access granted.");
  119. if(m_Network.ClientAddr(ClientID)->type == NETTYPE_IPV4)
  120. m_Network.Send(ClientID, "You are connecting via: IPv4");
  121. else if(m_Network.ClientAddr(ClientID)->type == NETTYPE_IPV6)
  122. m_Network.Send(ClientID, "You are connecting via: IPv6");
  123. if(Main()->Config()->m_Verbose)
  124. dbg_msg("server", "ncid=%d authed", ClientID);
  125. Main()->OnNewClient(ClientID, ID);
  126. }
  127. }
  128. else if(m_aClients[ClientID].m_State == CClient::STATE_AUTHED)
  129. {
  130. m_aClients[ClientID].m_LastReceived = time_get();
  131. if(Main()->Config()->m_Verbose)
  132. dbg_msg("server", "ncid=%d cmd='%s'", ClientID, aBuf);
  133. if(str_comp(aBuf, "logout") == 0)
  134. m_Network.Drop(ClientID, "Logout. Bye Bye ~");
  135. else
  136. Main()->HandleMessage(ClientID, aBuf);
  137. }
  138. }
  139. for(int i = 0; i < NET_MAX_CLIENTS; ++i)
  140. {
  141. if(m_aClients[i].m_State == CClient::STATE_CONNECTED &&
  142. time_get() > m_aClients[i].m_TimeConnected + 5 * time_freq())
  143. {
  144. m_Network.NetBan()->BanAddr(m_Network.ClientAddr(i), 30, "Authentication timeout.");
  145. m_Network.Drop(i, "Authentication timeout.");
  146. }
  147. else if(m_aClients[i].m_State == CClient::STATE_AUTHED &&
  148. time_get() > m_aClients[i].m_LastReceived + 15 * time_freq())
  149. m_Network.Drop(i, "Timeout.");
  150. }
  151. }
  152. void CServer::Send(int ClientID, const char *pLine)
  153. {
  154. if(!m_Ready)
  155. return;
  156. if(ClientID == -1)
  157. {
  158. for(int i = 0; i < NET_MAX_CLIENTS; i++)
  159. {
  160. if(m_aClients[i].m_State == CClient::STATE_AUTHED)
  161. m_Network.Send(i, pLine);
  162. }
  163. }
  164. else if(ClientID >= 0 && ClientID < NET_MAX_CLIENTS && m_aClients[ClientID].m_State == CClient::STATE_AUTHED)
  165. m_Network.Send(ClientID, pLine);
  166. }
  167. void CServer::Shutdown()
  168. {
  169. if(!m_Ready)
  170. return;
  171. m_Network.Close();
  172. }