Server.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. #include "Server.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/socket.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <sys/types.h>
  10. #include <signal.h>
  11. #include "SocketUtils.h"
  12. void serverInitDefaults(Server* s)
  13. {
  14. s->maxClients = -1;
  15. s->port = -1;
  16. s->threads = NULL;
  17. s->clientSockets = NULL;
  18. s->loginTries = NULL;
  19. s->clientUser = NULL;
  20. s->connectSocket = -1;
  21. s->handler = NULL;
  22. s->banns = NULL;
  23. s->directory = NULL;
  24. }
  25. int serverInit(Server* s, int maxClients, short port, char* directory)
  26. {
  27. s->maxClients = maxClients;
  28. s->port = port;
  29. s->directory = directory;
  30. if(chdir(directory) == -1)
  31. {
  32. perror("cannot change directory");
  33. serverRemove(s);
  34. return -1;
  35. }
  36. // initialize storage for clients
  37. s->threads = malloc(sizeof(pthread_t) * maxClients);
  38. s->clientSockets = malloc(sizeof(int) * maxClients);
  39. s->loginTries = malloc(sizeof(int) * maxClients);
  40. s->ips = malloc(sizeof(int) * maxClients);
  41. s->clientUser = malloc(sizeof(char*) * maxClients);
  42. for(int i = 0; i < maxClients; i++)
  43. {
  44. s->threads[i] = -1;
  45. s->clientSockets[i] = -1;
  46. s->clientUser[i] = NULL;
  47. s->loginTries[i] = 0;
  48. s->ips[i] = 0;
  49. }
  50. // create the socket for clients to connect
  51. s->connectSocket = socket(AF_INET, SOCK_STREAM, 0);
  52. if(s->connectSocket == -1)
  53. {
  54. perror("Cannot create socket");
  55. serverRemove(s);
  56. return -1;
  57. }
  58. // prevents clients from blocking the port if the server exits
  59. struct linger sl;
  60. sl.l_onoff = 1;
  61. sl.l_linger = 0;
  62. if(setsockopt(s->connectSocket, SOL_SOCKET, SO_LINGER, &sl, sizeof(struct linger)) == -1)
  63. {
  64. perror("Cannot set non lingering");
  65. serverRemove(s);
  66. return -1;
  67. }
  68. // specifies data of the port and binds it
  69. struct sockaddr_in connectSocketData;
  70. memset(&connectSocketData, 0, sizeof(struct sockaddr_in));
  71. connectSocketData.sin_family = AF_INET;
  72. connectSocketData.sin_addr.s_addr = INADDR_ANY;
  73. connectSocketData.sin_port = htons(port);
  74. if(bind(s->connectSocket, (struct sockaddr*) &connectSocketData, sizeof(struct sockaddr_in)) != 0)
  75. {
  76. perror("Cannot bind socket");
  77. serverRemove(s);
  78. return -1;
  79. }
  80. // mark this socket as handler for connection requests
  81. if(listen(s->connectSocket, 5) != 0)
  82. {
  83. perror("Cannot start listening");
  84. serverRemove(s);
  85. return -1;
  86. }
  87. s->banns = bannsNew();
  88. return 0;
  89. }
  90. void serverRemove(Server* s)
  91. {
  92. s->port = -1;
  93. if(s->threads != NULL)
  94. {
  95. for(int i = 0; i < s->maxClients; i++)
  96. {
  97. if(s->threads[i] != -1)
  98. {
  99. printf("%d thread\n", i);
  100. pthread_cancel(s->threads[i]);
  101. pthread_join(s->threads[i], NULL);
  102. }
  103. }
  104. free(s->threads);
  105. s->threads = NULL;
  106. }
  107. if(s->clientSockets != NULL)
  108. {
  109. for(int i = 0; i < s->maxClients; i++)
  110. {
  111. if(s->clientSockets[i] != -1)
  112. {
  113. if(close(s->clientSockets[i]) == -1)
  114. {
  115. printf("%d", i);
  116. perror(" cannot close client socket");
  117. }
  118. else
  119. {
  120. printf("%d closed\n", i);
  121. }
  122. }
  123. }
  124. free(s->clientSockets);
  125. s->clientSockets = NULL;
  126. }
  127. if(s->clientUser != NULL)
  128. {
  129. for(int i = 0; i < s->maxClients; i++)
  130. {
  131. if(s->clientUser[i] != NULL)
  132. {
  133. free(s->clientUser[i]);
  134. s->clientUser[i] = NULL;
  135. }
  136. }
  137. free(s->clientUser);
  138. s->clientUser = NULL;
  139. }
  140. if(s->loginTries != NULL)
  141. {
  142. free(s->loginTries);
  143. s->loginTries = NULL;
  144. }
  145. if(s->ips != NULL)
  146. {
  147. free(s->ips);
  148. s->ips = NULL;
  149. }
  150. s->maxClients = -1;
  151. if(s->connectSocket != -1)
  152. {
  153. if(close(s->connectSocket) != 0)
  154. {
  155. perror("Cannot close server socket");
  156. }
  157. else
  158. {
  159. printf("connection listener closed\n");
  160. }
  161. s->connectSocket = -1;
  162. }
  163. s->handler = NULL;
  164. if(s->banns != NULL)
  165. {
  166. bannsRemove(s->banns);
  167. s->banns = NULL;
  168. }
  169. }
  170. static void* clientHandler(void* data)
  171. {
  172. int id = ((ThreadData*) data)->id;
  173. Server* s = ((ThreadData*) data)->server;
  174. Stream in;
  175. while(1)
  176. {
  177. streamInit(&in, 1024);
  178. int size = receiveAll(s->clientSockets[id], &in);
  179. if(size > 0)
  180. {
  181. if(s->handler(id, s->clientSockets[id], &in))
  182. {
  183. break;
  184. }
  185. }
  186. else if(size == 0)
  187. {
  188. printf("Client %d closed remote socket\n", id);
  189. streamRemove(&in);
  190. break;
  191. }
  192. else
  193. {
  194. perror("recv error");
  195. streamRemove(&in);
  196. break;
  197. }
  198. streamRemove(&in);
  199. }
  200. if(close(s->clientSockets[id]) != 0)
  201. {
  202. printf("%d", id);
  203. perror(" cannot close client socket");
  204. }
  205. else
  206. {
  207. printf("%d closed\n", id);
  208. }
  209. s->loginTries[id] = 0;
  210. serverFreeUser(s, id);
  211. s->clientSockets[id] = -1;
  212. return NULL;
  213. }
  214. int serverSend(int clientSocket, Stream* out)
  215. {
  216. if(sendAll(clientSocket, out) == -1)
  217. {
  218. return -1;
  219. }
  220. return 0;
  221. }
  222. void serverWaitForConnection(Server* s)
  223. {
  224. socklen_t addrlen = sizeof(struct sockaddr_in);
  225. while(1)
  226. {
  227. printf("Waiting for connections...\n");
  228. struct sockaddr_in clientSocketData;
  229. int clientSocket = accept(s->connectSocket, (struct sockaddr*) &clientSocketData, &addrlen);
  230. if(clientSocket >= 0)
  231. {
  232. printf("Client connected from %s:%d...\n", inet_ntoa(clientSocketData.sin_addr), (int) ntohs(clientSocketData.sin_port));
  233. if(bannsIsBanned(s->banns, clientSocketData.sin_addr.s_addr))
  234. {
  235. close(clientSocket);
  236. printf("Banned user tried joining\n");
  237. continue;
  238. }
  239. int i = 0;
  240. while(1)
  241. {
  242. if(s->clientSockets[i] == -1)
  243. {
  244. s->ips[i] = clientSocketData.sin_addr.s_addr;
  245. if(s->threads[i] != -1)
  246. {
  247. pthread_cancel(s->threads[i]);
  248. pthread_join(s->threads[i], NULL);
  249. }
  250. ThreadData data;
  251. data.id = i;
  252. data.server = s;
  253. if(pthread_create(&s->threads[i], NULL, clientHandler, (void*) &data) != 0)
  254. {
  255. perror("Cannot create thread");
  256. Stream out;
  257. streamInit(&out, 16);
  258. streamWriteChar(&out, -1);
  259. streamWriteChars(&out, "Cannot create thread\n");
  260. serverSend(clientSocket, &out);
  261. streamRemove(&out);
  262. close(clientSocket);
  263. }
  264. else
  265. {
  266. s->clientSockets[i] = clientSocket;
  267. Stream out;
  268. streamInit(&out, 64);
  269. streamWriteChar(&out, 1);
  270. streamWriteChars(&out, "Welcome to the server, please enter one of these commands:\n");
  271. streamWriteChars(&out, "- HELP\n");
  272. streamWriteChars(&out, "- SEND\n");
  273. streamWriteChars(&out, "- LIST\n");
  274. streamWriteChars(&out, "- READ\n");
  275. streamWriteChars(&out, "- DEL\n");
  276. streamWriteChars(&out, "- QUIT\n");
  277. if(serverSend(clientSocket, &out) == -1)
  278. {
  279. perror("Cannot send welcome message");
  280. close(clientSocket);
  281. s->clientSockets[i] = -1;
  282. }
  283. streamRemove(&out);
  284. }
  285. break;
  286. }
  287. i++;
  288. if(i >= s->maxClients)
  289. {
  290. printf("max clients reached\n");
  291. Stream out;
  292. streamInit(&out, 16);
  293. streamWriteChar(&out, -1);
  294. streamWriteChars(&out, "the server is full\n");
  295. serverSend(clientSocket, &out);
  296. streamRemove(&out);
  297. close(clientSocket);
  298. break;
  299. }
  300. }
  301. }
  302. }
  303. }
  304. void serverRegisterHandler(Server* s, ServerStreamFunction f)
  305. {
  306. s->handler = f;
  307. }
  308. int serverSetUser(Server* s, int clientId, char* name)
  309. {
  310. if(clientId < 0 || clientId >= s->maxClients)
  311. {
  312. return -1;
  313. }
  314. int l = strlen(name) + 1;
  315. s->clientUser[clientId] = malloc(sizeof(char) * l);
  316. strncpy(s->clientUser[clientId], name, l);
  317. return 0;
  318. }
  319. char* serverGetUser(Server* s, int clientId)
  320. {
  321. if(clientId < 0 || clientId >= s->maxClients)
  322. {
  323. return NULL;
  324. }
  325. return s->clientUser[clientId];
  326. }
  327. void serverFreeUser(Server* s, int clientId)
  328. {
  329. if(clientId < 0 || clientId >= s->maxClients)
  330. {
  331. return;
  332. }
  333. if(s->clientUser[clientId] != NULL)
  334. {
  335. free(s->clientUser[clientId]);
  336. s->clientUser[clientId] = NULL;
  337. }
  338. }
  339. int serverRaiseLoginFails(Server* s, int clientId)
  340. {
  341. if(clientId < 0 || clientId >= s->maxClients)
  342. {
  343. return 0;
  344. }
  345. s->loginTries[clientId]++;
  346. return s->loginTries[clientId] >= 3;
  347. }
  348. void serverResetLoginFails(Server* s, int clientId)
  349. {
  350. if(clientId < 0 || clientId >= s->maxClients)
  351. {
  352. return;
  353. }
  354. s->loginTries[clientId] = 0;
  355. }
  356. void serverBann(Server* s, int clientId)
  357. {
  358. if(clientId < 0 || clientId >= s->maxClients)
  359. {
  360. return;
  361. }
  362. bannsAdd(s->banns, s->ips[clientId]);
  363. }