00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "NetServer.h"
00012
00013 NetServer::NetServer(const char *pKeyFile, const char *pCertifFile)
00014 {
00015 conInfo = NULL;
00016 limit = NET_LIMIT;
00017 sslCTX = NULL;
00018 crypt = NET_T_NORMAL;
00019
00020 if(pKeyFile && pCertifFile)
00021 {
00022 SSL_METHOD *sslMethode;
00023
00024 SSL_library_init();
00025 SSL_load_error_strings();
00026 sslMethode = SSLv23_server_method();
00027
00028 sslCTX = SSL_CTX_new(sslMethode);
00029 if(!sslCTX)
00030 throw ERROR_C_SSLCTXINIT;
00031
00032 if(SSL_CTX_use_PrivateKey_file(sslCTX, pKeyFile, SSL_FILETYPE_PEM) < 1)
00033 throw ERROR_C_SSLKEY;
00034
00035 if(SSL_CTX_use_certificate_file(sslCTX, pCertifFile, SSL_FILETYPE_PEM) < 1)
00036 throw ERROR_C_SSLCERTIF;
00037
00038 if(SSL_CTX_check_private_key(sslCTX) < 1)
00039 throw ERROR_C_SSLCHECK;
00040
00041 keyFile = pKeyFile;
00042 certifFile = pCertifFile;
00043
00044 crypt = NET_T_SSL;
00045 }
00046 }
00047
00048 NetServer::~NetServer()
00049 {
00050 Stop();
00051 }
00052
00053 void ThreadWaitClient(NetServer *pServeur)
00054 {
00055 pServeur->WaitClient();
00056 }
00057
00058 void ThreadGarbageClient(NetServer *pServeur)
00059 {
00060 pServeur->GarbageClient();
00061 }
00062
00063 void NetServer::Start(unsigned int iPort, ROUTINE pRoutine, unsigned int iLimit)
00064 {
00065 BEGIN
00066
00067 if(!conInfo)
00068 throw ERROR_C_ALREADY_START;
00069
00070 conInfo = new NetConnect(crypt);
00071 conInfo->port = iPort;
00072
00073 limit = iLimit;
00074 routineClient = pRoutine;
00075
00076 if(SocketLoad())
00077 throw ERROR_C_LOAD_DLL;
00078
00079 conInfo->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00080 if(conInfo->sock < 0)
00081 throw ERROR_C_INIT_CONNECT;
00082
00083 memset(&conInfo->sockName, 0, sizeof(conInfo->sockName));
00084 conInfo->sockName.sin_port = htons(conInfo->port);
00085 conInfo->sockName.sin_family = AF_INET;
00086 conInfo->sockName.sin_addr.s_addr = INADDR_ANY;
00087
00088 if(bind(conInfo->sock,(struct sockaddr*)&conInfo->sockName, sizeof(conInfo->sockName)))
00089 throw ERROR_C_BIND_CONNECT;
00090
00091 if(listen(conInfo->sock, limit))
00092 throw ERROR_C_LISTEN;
00093
00094 if(ThreadStart(&threadGarbage, (ROUTINE)ThreadGarbageClient, this))
00095 throw ERROR_C_THREAD;
00096
00097 if(ThreadStart(&threadClients, (ROUTINE)ThreadWaitClient, this))
00098 throw ERROR_C_THREAD;
00099
00100 ENDBEGIN
00101 }
00102
00103 void NetServer::Stop()
00104 {
00105 if(conInfo)
00106 {
00107 delete conInfo;
00108 conInfo = NULL;
00109 }
00110
00111 ThreadWait(&threadClients);
00112
00113 while(clients.size())
00114 KillClientNo(0);
00115 clients.clear();
00116
00117 ThreadWait(&threadGarbage);
00118 }
00119
00120 void NetServer::GarbageClient()
00121 {
00122 unsigned int i;
00123 BEGIN
00124
00125 do
00126 {
00127 for(i = 0; i < clients.size(); i++)
00128 {
00129 if(!clients[i]->ip.size())
00130 {
00131 SocketClose(clients[i]->sock);
00132
00133 if(clients[i]->crypt == NET_T_SSL)
00134 {
00135 SSL_shutdown(clients[i]->sslFD);
00136 SSL_free(clients[i]->sslFD);
00137 }
00138
00139 ThreadWait(&(clients[i]->thread));
00140
00141 clients.erase(clients.begin() + i);
00142 }
00143 }
00144 TempWait(NET_GARBAGE);
00145 }
00146 while(conInfo);
00147
00148 ENDBEGINPRINT
00149
00150 ThreadExit(0);
00151 }
00152
00153 void NetServer::WaitClient()
00154 {
00155 unsigned int lenght = 0, err = 0;
00156 BEGIN
00157
00158 while(conInfo)
00159 {
00160 if(clients.size() < limit)
00161 {
00162 err = 0;
00163 clients.push_back(new NetConnect(crypt));
00164 lenght = sizeof(clients.back()->sockName);
00165 clients.back()->sock = accept(conInfo->sock, (struct sockaddr*)&clients.back()->sockName, (socklen_t *)&lenght);
00166
00167 if(clients.back()->sock != -1)
00168 {
00169 unsigned char *pIp = (unsigned char *)&clients.back()->sockName.sin_addr.s_addr;
00170 clients.back()->ip = ItoA(pIp[0]);
00171 clients.back()->ip += ItoA(pIp[1]);
00172 clients.back()->ip += ItoA(pIp[2]);
00173 clients.back()->ip += ItoA(pIp[3]);
00174
00175 if(crypt == NET_T_SSL)
00176 {
00177 clients.back()->sslFD = SSL_new(sslCTX);
00178 if( (!clients.back()->sslFD) ||
00179 (SSL_set_fd(clients.back()->sslFD, clients.back()->sock) < 1) ||
00180 (SSL_accept(clients.back()->sslFD) < 1)
00181 )
00182 {
00183 SSL_shutdown(clients.back()->sslFD);
00184 SSL_free(clients.back()->sslFD);
00185 err = 1;
00186 }
00187 }
00188
00189 if(!err)
00190 if(!ThreadStart(&clients.back()->thread, routineClient, (PARAMETRE)clients.back()))
00191 err = 1;
00192 }
00193 else
00194 err = 1;
00195
00196 if(err)
00197 clients.erase(clients.begin() + clients.size());
00198 }
00199 else
00200 TempWait(NET_WAIT_FULL);
00201 }
00202
00203 ENDBEGINPRINT
00204
00205 ThreadExit(0);
00206 }
00207
00208 void NetServer::KillClient(unsigned int iId)
00209 {
00210 for(unsigned int i = 0; i < clients.size(); i++)
00211 if(clients[i]->GetId() == iId)
00212 clients[i]->ip = "";
00213 }
00214
00215 void NetServer::KillClientNo(unsigned int iNo)
00216 {
00217 if(iNo < clients.size())
00218 clients[iNo]->ip = "";
00219 }
00220