ZOOOO

Untitled

Apr 19th, 2016
15,756
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.50 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/ioctl.h>
  4. #include <sys/poll.h>
  5. #include <sys/socket.h>
  6. #include <sys/time.h>
  7. #include <netinet/in.h>
  8. #include <errno.h>
  9. #include <map>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include <unistd.h>
  13.  
  14.  
  15. #define SERVER_PORT 12345
  16.  
  17. #define TRUE 1
  18. #define FALSE 0
  19. #define CONST 128
  20.  
  21. #define BUF_LEN 1 << 20
  22. #define PORT 5001
  23. #define SSYMBOL(x) #x
  24. #define SYMBOL(X) SSYMBOL(X)
  25. #define F_NAME "log.txt"
  26.  
  27. #include <iostream>
  28. #include <cstdio>
  29. #include <cstring>
  30. #include <cstdlib>
  31. #include <map>
  32. #include <fstream>
  33. #include <iomanip>
  34. #include <chrono>
  35.  
  36. #include <sys/types.h>
  37. #include <sys/socket.h>
  38. #include <errno.h>
  39. #include <netinet/in.h>
  40. #include <sys/epoll.h>
  41. #include <arpa/inet.h>
  42. #include <unistd.h>
  43. #include <fcntl.h>
  44.  
  45. #include <asn1/Request.h>
  46. #include <asn1/Response.h>
  47.  
  48. int recvn(int sock, void *buf, int buflen) {
  49. int n, total = 0;
  50. while (total != buflen) {
  51. n = recv(sock, (char*) buf + total, buflen - total, 0);
  52. if (n <= 0)
  53. return n;
  54. total += n;
  55. }
  56. return total;
  57. }
  58.  
  59. //проверка записи на соответсвие условиям из get запроса
  60. int check_record_get(LogRecord_t *rec, GetRequest_t &req) {
  61. return (((req.level && *req.level != rec->level)) ||
  62. ((req.begin && asn_GT2time(req.begin, nullptr, 0)
  63. > asn_GT2time(&rec->timestamp, nullptr, 0))) ||
  64. ((req.end && asn_GT2time(req.end, nullptr, 0)
  65. < asn_GT2time(&rec->timestamp, nullptr, 0)))) ? 0 : 1;
  66. }
  67.  
  68. //проверка записи на соответсвие условия из clear запроса
  69. int check_record_clear(LogRecord_t *rec, ClearRequest_t &req) {
  70. return (asn_GT2time(&rec->timestamp, nullptr, 0)
  71. >= asn_GT2time(&req.choice.olderThan, nullptr, 0)) ? 0 : 1;
  72. }
  73.  
  74. void process_request(Request_t *req, Response_t *&resp, FILE *&log,
  75. sockaddr_in &client) {
  76. if (req->present == Request_PR_add) {
  77. //заполняем поля
  78.  
  79. AddRequest_t &areq = req->choice.add;
  80. LogRecord_t rec;
  81. memset(&rec, 0, sizeof(rec));
  82. rec.level = areq.level;
  83. rec.msg = areq.msg;
  84. {
  85. uint8_t *tmp = (uint8_t*)malloc(rec.msg.size);
  86. memcpy(tmp, rec.msg.buf, rec.msg.size);
  87. rec.msg.buf = tmp;
  88. }
  89. time_t tt = std::chrono::system_clock::to_time_t(
  90. std::chrono::system_clock::now());
  91. tm *pt = localtime(&tt);
  92. asn_time2GT(&rec.timestamp, pt, 0);
  93. rec.ip.present = IPAddress_PR_iPBinaryAddress;
  94. rec.ip.choice.iPBinaryAddress.present =
  95. IPBinaryAddress_PR_iPBinV4Address;
  96. //зрабиваем ip на байты и записываем
  97.  
  98. char ip[4];
  99. ip[0] = client.sin_addr.s_addr & 0xFF;
  100. ip[1] = (client.sin_addr.s_addr >> 8) & 0xFF;
  101. ip[2] = (client.sin_addr.s_addr >> 16) & 0xFF;
  102. ip[3] = (client.sin_addr.s_addr >> 24) & 0xFF;
  103. OCTET_STRING_fromBuf(
  104. &rec.ip.choice.iPBinaryAddress.choice.iPBinV4Address, ip, 4);
  105.  
  106.  
  107. char *buffer = (char*) malloc(BUF_LEN * sizeof(char));
  108. asn_enc_rval_t er;
  109. //кодируем и пишем в файл
  110.  
  111. er = der_encode_to_buffer(&asn_DEF_LogRecord, &rec, buffer,
  112. BUF_LEN);
  113. if (er.encoded == -1) {
  114. perror("cannot encode" SYMBOL(__LINE__));
  115. ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LogRecord, &rec);
  116. return;
  117. }
  118. int len = er.encoded;
  119. fwrite(&len, sizeof(len), 1, log);
  120. fwrite(buffer, sizeof(char), len, log);
  121. free(buffer);
  122. ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LogRecord, &rec);
  123.  
  124. } else if (req->present == Request_PR_get) {
  125. resp = (Response_t *) calloc(1, sizeof(Response_t));
  126. resp->present = Response_PR_NOTHING;
  127. //получаем размер файла
  128.  
  129. fseek(log, 0, SEEK_END);
  130. int len, endpos = ftell(log);
  131. //перемещаемся в начало
  132.  
  133. fseek(log, 0, 0);
  134. while (ftell(log) != endpos) {
  135. //считываем размер закодированного блока и сам блок
  136. fread(&len, sizeof(len), 1, log);
  137. char *buffer = (char*) malloc(len * sizeof(char));
  138. fread(buffer, sizeof(char), len, log);
  139. LogRecord_t *tmp = nullptr;
  140. asn_dec_rval_t rv;
  141. //декодируем
  142. rv = ber_decode(0, &asn_DEF_LogRecord, (void**) &tmp, buffer, len);
  143. if (rv.code != RC_OK) {
  144. perror("cannot decode" SYMBOL(__LINE__));
  145. ASN_STRUCT_FREE(asn_DEF_LogRecord, tmp);
  146. continue;
  147. }
  148. //проверяем
  149. if (check_record_get(tmp, req->choice.get)) {
  150. resp->present = Response_PR_records;
  151. asn_sequence_add(&resp->choice.records.list, tmp);
  152. } else
  153. ASN_STRUCT_FREE(asn_DEF_LogRecord, tmp);
  154. free(buffer);
  155. }
  156. } else if (req->present == Request_PR_clear) {
  157. if (req->choice.clear.present == ClearRequest_PR_all) {
  158. //пересоздаем файл, если удаляем все
  159. fflush(log);
  160. fclose(log);
  161. log = fopen(F_NAME, "wb+");
  162. } else {
  163. //получаем размер файл
  164. fseek(log, 0, SEEK_END);
  165. int len, endpos = ftell(log);
  166. //идем в начало
  167. fseek(log, 0, 0);
  168. while (ftell(log) != endpos) {
  169. //считываем длину блока и сам блок
  170. fread(&len, sizeof(len), 1, log);
  171. char *buffer = (char*) malloc(len * sizeof(char));
  172. fread(buffer, sizeof(char), len, log);
  173. LogRecord_t *tmp = nullptr;
  174. asn_dec_rval_t rv;
  175. //декодируем
  176. rv = ber_decode(0, &asn_DEF_LogRecord, (void**) &tmp, buffer,
  177. len);
  178. if (rv.code != RC_OK) {
  179. perror("cannot decode" SYMBOL(__LINE__));
  180. ASN_STRUCT_FREE(asn_DEF_LogRecord, tmp);
  181. continue;
  182. }
  183. //проверяем
  184. if (!check_record_clear(tmp, req->choice.clear)) {
  185. //перемещаемся в файл к началу блок, чтоб не упустить его
  186. fseek(log, -(len * sizeof(char) + sizeof(len)), SEEK_CUR);
  187. ASN_STRUCT_FREE(asn_DEF_LogRecord, tmp);
  188. free(buffer);
  189. break;
  190. }
  191. ASN_STRUCT_FREE(asn_DEF_LogRecord, tmp);
  192. free(buffer);
  193. }
  194. if (ftell(log) == endpos) {
  195. //на случай если удалить надо все
  196. fflush(log);
  197. fclose(log);
  198. log = fopen(F_NAME, "wb+");
  199.  
  200. } else {
  201. //копируем остаток файл в другой, а потом переименовываем
  202. FILE *log2 = fopen(F_NAME ".tmp", "wb+");
  203. int cpsize = endpos - ftell(log);
  204. char *buffer = (char*) malloc(cpsize * sizeof(char));
  205. fread(buffer, sizeof(char), cpsize, log);
  206. fwrite(buffer, sizeof(char), cpsize, log2);
  207. fclose(log);
  208. fclose(log2);
  209. remove(F_NAME);
  210. rename(F_NAME ".tmp", F_NAME);
  211. log = fopen(F_NAME, "ab+");
  212. free(buffer);
  213. }
  214. }
  215. }
  216. }
  217.  
  218. struct buf_data {
  219. int size;
  220. int pos;
  221. char *buffer;
  222. };
  223.  
  224. int buf_write(const void *buffer, size_t size, void *app_key) {
  225. buf_data *data = (buf_data*)app_key;
  226. data->pos += size;
  227. if(data->pos > data->size) {
  228. data->buffer = (char*)realloc(data->buffer, data->size *= 2);
  229.  
  230. }
  231. memcpy(data->buffer + (data->pos - size), buffer, size);
  232. return 0;
  233. }
  234.  
  235. int main(void)
  236. {
  237. socklen_t client_len;
  238. int rc, on = 1;
  239. int listen_sd = -1, new_sd = -1, client_sock;
  240. int end_server = FALSE, compress_array = FALSE;
  241. int close_conn;
  242.  
  243. struct sockaddr_in addr, client_addr;
  244. int timeout;
  245. struct pollfd fds[200];
  246. int nfds = 1, current_size = 0, i, j;
  247. listen_sd = socket(AF_INET, SOCK_STREAM, 0);
  248. bool flag = false;
  249. if (listen_sd >= 0) {
  250. rc = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
  251.  
  252. if (rc >= 0) {
  253. rc = ioctl(listen_sd, FIONBIO, (char *)&on);
  254. if (rc >= 0 ) {
  255. addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY);
  256. addr.sin_port = htons(SERVER_PORT); rc = bind(listen_sd,(struct sockaddr *)&addr, sizeof(addr));
  257. if ( rc >= 0 ) {
  258. rc = listen(listen_sd, 32);
  259. if ( rc >= 0 ) {
  260. timeout = (3 * 60 * 1000);
  261. fds[0].events = POLLIN;
  262. fds[0].fd = listen_sd;
  263. flag = true;
  264. }
  265. }
  266. }
  267. }
  268. }
  269.  
  270. if (!flag) {
  271. perror("fail");
  272. return -1;
  273. }
  274.  
  275. FILE *log = fopen(F_NAME, "ab+");
  276. std::map<int, sockaddr_in> clients;
  277. //прослушка
  278.  
  279. //цикл ожиданий
  280. do
  281. {
  282.  
  283. printf("download...\n");
  284. rc = poll(fds, nfds, timeout);
  285.  
  286.  
  287. if (rc == 0 || rc < 0)
  288. {
  289. printf(rc == 0 ? " timed out. End program.\n" : "fail" );
  290. break;
  291. }
  292.  
  293.  
  294. //ищем сигнал
  295. current_size = nfds;
  296. for (i = 0; i < current_size; i++)
  297. {
  298.  
  299. if (fds[i].revents == 0)
  300. continue;
  301.  
  302. //обработка случая, когда сервак можешь свалиться
  303. if (fds[i].revents != POLLIN)
  304. {
  305. printf(" Error! revents = %d\n", fds[i].revents);
  306. end_server = TRUE;
  307. break;
  308.  
  309. }
  310. if (fds[i].fd == listen_sd)
  311. {
  312.  
  313. printf(" Listening socket is readable\n");
  314. client_len = sizeof(sockaddr);
  315. client_sock = new_sd = accept(listen_sd, (sockaddr *) &client_addr,
  316. &client_len);
  317.  
  318.  
  319. clients[client_sock] = client_addr;
  320. printf(" New incoming connection - %d\n", new_sd);
  321. fds[nfds].fd = new_sd;
  322. fds[nfds].events = POLLIN;
  323. nfds++;
  324.  
  325. }
  326.  
  327. //для отправок и приемов
  328.  
  329.  
  330. else {
  331.  
  332. printf(" Descriptor %d is readable\n", fds[i].fd);
  333. close_conn = FALSE;
  334. uint32_t len;
  335. int n, sock = fds[i].fd;
  336. //получаем длину блока и проверяем на отключение
  337. n = recvn(sock, &len, sizeof(len));
  338. if ( n <= 0 ) {
  339. continue;
  340. }
  341. len = ntohl(len);
  342.  
  343. char *buffer = (char*) malloc(sizeof(char) * len);
  344. //получаем сам блок
  345. n = recvn(sock, buffer, len);
  346. if ( n <= 0 ) {
  347. continue;
  348. }
  349.  
  350. asn_dec_rval_t rv;
  351. Request_t *req = nullptr;
  352. rv = ber_decode(0, &asn_DEF_Request, (void**) &req, buffer,
  353. len);
  354. if(rv.code != RC_OK) {
  355. perror("decode");
  356. ASN_STRUCT_FREE(asn_DEF_Request, req);
  357. free(buffer);
  358. return 1;
  359. }
  360. free(buffer);
  361. Response_t *resp = nullptr;
  362. //обрабатываем
  363. process_request(req, resp, log, clients[sock]);
  364. if (resp != nullptr) {
  365. asn_enc_rval_t er;
  366. buf_data data;
  367. data.buffer = (char*)malloc(sizeof(char) * 1024);
  368. data.size = 1024;
  369. data.pos = 0;
  370. er = der_encode(&asn_DEF_Response, resp, buf_write, &data);
  371. //отправляем длину блока и сам блок
  372. if (er.encoded == -1) {
  373. printf("%s ", er.failed_type->name);
  374. perror("encode" SYMBOL(__LINE__));
  375.  
  376. } else {
  377. uint32_t len = er.encoded;
  378. len = htonl(len);
  379. if (send(sock, &len, sizeof(len), 0) < 0) {
  380. perror("send");
  381. free(data.buffer);
  382. return 1;
  383. }
  384. len = ntohl(len);
  385. if (send(sock, data.buffer, len, 0) < 0) {
  386. perror("send");
  387. free(data.buffer);
  388. return 1;
  389. }
  390.  
  391. }
  392. free(data.buffer);
  393. }
  394. ASN_STRUCT_FREE(asn_DEF_Request, req);
  395. ASN_STRUCT_FREE(asn_DEF_Response, resp);
  396. }
  397.  
  398. if (close_conn)
  399. {
  400. close(fds[i].fd);
  401. fds[i].fd = -1;
  402. compress_array = TRUE;
  403. }
  404.  
  405.  
  406. }
  407.  
  408. if (compress_array)
  409. {
  410. compress_array = FALSE;
  411. for (i = 0; i < nfds; i++)
  412. {
  413. if (fds[i].fd == -1)
  414. {
  415. for (j = i; j < nfds; j++)
  416. {
  417. fds[j].fd = fds[j + 1].fd;
  418. }
  419. nfds--;
  420. }
  421. }
  422. }
  423.  
  424. } while (end_server == FALSE);
  425. for (i = 0; i < nfds; i++)
  426. {
  427. if (fds[i].fd >= 0)
  428. close(fds[i].fd); //сворачиваемся
  429. }
  430. }
Add Comment
Please, Sign In to add comment