// ************************************************** // ** OID CSV Lookup Server 1.2 ** // ** (c) 2016-2020 ViaThinkSoft, Daniel Marschall ** // ************************************************** // todo: log verbosity + datetime // todo: publish at codelib // todo: server hat sich einfach so beendet... "read: connection reset by peer" // todo: 2019-02-24 service was booted together with the system, and i got "0 OIDs loaded". why??? // todo: create vnag monitor that checks if this service is OK // todo: unexplained crash with version 1.1 : Signal "pipefail" (141) received after someone connected?! #include "oid_lookup_srv.h" unordered_set lines; int loadfile(const string &filename) { int cnt = 0; ifstream infile(filename); string line; while (getline(infile, line)) { lines.insert(line); ++cnt; } infile.close(); fprintf(stdout, "Loaded %d OIDs from %s\n", cnt, filename.c_str()); return cnt; } bool stringAvailable(const string &str) { return lines.find(str) != lines.end(); } // Template of this code: http://www.gnu.org/software/libc/manual/html_node/Server-Example.html // http://www.gnu.org/software/libc/manual/html_node/Inet-Example.html#Inet-Example struct con_descriptor { time_t last_activity; struct sockaddr_in clientname; int queries; time_t connect_ts; }; con_descriptor cons[FD_SETSIZE]; int read_from_client(int filedes) { char buffer[MAXMSG]; int nbytes; nbytes = read(filedes, buffer, sizeof(buffer)); buffer[sizeof(buffer)-1] = 0; // Terminator if (nbytes < 0) { /* Read error. */ //perror("read"); //exit(EXIT_FAILURE); return -1; } else if (nbytes == 0) { /* End-of-file. */ return -1; } else { /* Data read. */ for (uint i=0; i= '0') && (buffer[i] <= '9')) && !(buffer[i] == '.')) { fprintf(stdout, "%s:%d[%d] Client sent an invalid request.\n", inet_ntoa(cons[filedes].clientname.sin_addr), ntohs(cons[filedes].clientname.sin_port), filedes); return -1; } } // fprintf(stdout, "%s:%d[%d] Query #%d: %s\n", inet_ntoa(cons[filedes].clientname.sin_addr), ntohs(cons[filedes].clientname.sin_port), filedes, cons[filedes].queries, buffer); if (stringAvailable(buffer)) { write(filedes, "1\n", 2); } else { write(filedes, "0\n", 2); } return 0; } } } int fd_set_isset_count(const fd_set &my_fd_set) { int cnt = 0; for (int fd = 0; fd < FD_SETSIZE; ++fd) { if (FD_ISSET(fd, &my_fd_set)) { ++cnt; } } return cnt; } int loadCSVs() { return loadfile("oid_table.csv"); } void initConsArray() { for (int i=0; i MAX_CONNECTIONS) { // -1 is because we need to exclude the listening socket (i=sock) which is not a connected client fprintf(stderr, "%s:%d[%d] Rejected because too many connections are open\n", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), new_fd); close(new_fd); FD_CLR(new_fd, &active_fd_set); } else { fprintf(stdout, "%s:%d[%d] Connected\n", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), new_fd); } if (new_fd >= FD_SETSIZE) { fprintf(stderr, "%s:%d[%d] new_fd reached cons[FD_SETSIZE] limit\n", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), new_fd); close(new_fd); FD_CLR(new_fd, &active_fd_set); } cons[new_fd].last_activity = time(NULL); cons[new_fd].queries = 0; } else { /* Data arriving on an already-connected socket. */ cons[i].last_activity = time(NULL); if (read_from_client(i) < 0) { fprintf(stdout, "%s:%d[%d] Connection closed after %d queries in %lu seconds.\n", inet_ntoa(cons[i].clientname.sin_addr), ntohs(cons[i].clientname.sin_port), i, cons[i].queries, time(NULL)-cons[i].connect_ts); close(i); FD_CLR(i, &active_fd_set); } } } } } /* Check if we need to reload the CSV */ if (time(NULL)-csvLoad >= CSVRELOADINTERVAL) { loadCSVs(); csvLoad = time(NULL); } /* Check if we can close connections due to timeout */ for (int i=0; i < FD_SETSIZE; ++i) { if (FD_ISSET(i, &active_fd_set)) { if (i == sock) continue; if (time(NULL)-cons[i].last_activity >= CONNECTION_TIMEOUT) { fprintf(stdout, "%s:%d[%d] Connection timeout.\n", inet_ntoa(cons[i].clientname.sin_addr), ntohs(cons[i].clientname.sin_port), i); fprintf(stdout, "%s:%d[%d] Connection closed after %d queries in %lu seconds.\n", inet_ntoa(cons[i].clientname.sin_addr), ntohs(cons[i].clientname.sin_port), i, cons[i].queries, time(NULL)-cons[i].connect_ts); close(i); FD_CLR(i, &active_fd_set); } } } } }