Subversion Repositories oidinfo_api

Compare Revisions

No changes between revisions

Regard whitespace Rev 2 → Rev 3

/trunk/csv_lookup_server_example/Makefile
1,0 → 0,0
link ../../confidential/jobs/0077_csv_lookup_server/v2/Makefile
 
all: oid_lookup_srv
 
oid_lookup_srv: oid_lookup_srv.cpp
g++ -std=c++11 -lgmpxx -Wall -fopenmp -O3 -mtune=native -pipe -O3 -mtune=native -o oid_lookup_srv oid_lookup_srv.cpp
 
clean:
rm -f *.o
# TODO: if [ -f ... ] then rm
rm oid_lookup_srv
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/trunk/csv_lookup_server_example/oid_lookup_srv
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:executable
+*
\ No newline at end of property
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Deleted: svn:special
-*
\ No newline at end of property
/trunk/csv_lookup_server_example/oid_lookup_srv.cpp
1,0 → 0,0
link ../../confidential/jobs/0077_csv_lookup_server/v2/oid_lookup_srv.cpp
// **************************************************
// ** OID CSV Lookup Server 1.1 **
// ** (c) 2016-2019 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
 
#include "oid_lookup_srv.h"
 
unordered_set<string> 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, MAXMSG);
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 (int i=0; i<MAXMSG; ++i) {
if ((buffer[i] == 13) || (buffer[i] == 10)) buffer[i] = 0;
}
 
if (strcmp(buffer, "bye") == 0) {
fprintf(stdout, "%s:%d[%d] Client said good bye.\n", inet_ntoa(cons[filedes].clientname.sin_addr), ntohs(cons[filedes].clientname.sin_port), filedes);
return -1;
} else {
cons[filedes].queries++;
 
// 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<FD_SETSIZE; ++i) {
cons[i].last_activity = 0;
memset(&cons[i].clientname, 0, sizeof(sockaddr_in));
cons[i].queries = 0;
}
}
 
int make_socket(uint16_t port) {
int sock;
struct sockaddr_in name;
 
/* Create the socket. */
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
 
int enable = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) {
fprintf(stderr, "ERROR: setsockopt(SO_REUSEADDR) failed");
exit(EXIT_FAILURE);
}
 
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
 
return sock;
}
 
int main(void) {
// extern int make_socket(uint16_t port);
int sock;
fd_set active_fd_set, read_fd_set;
 
fprintf(stdout, "OID CSV Lookup Server 1.0 (c)2016-2019 ViaThinkSoft\n");
fprintf(stdout, "Listening at port: %d\n", PORT);
fprintf(stdout, "Max connections: %d\n", FD_SETSIZE);
 
initConsArray();
 
int loadedOIDs = loadCSVs();
time_t csvLoad = time(NULL);
 
/* Create the socket and set it up to accept connections. */
sock = make_socket(PORT);
if (listen(sock, 1) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
 
/* Initialize the set of active sockets. */
FD_ZERO(&active_fd_set);
FD_SET(sock, &active_fd_set);
 
while (1) {
/* Block until input arrives on one or more active sockets. */
read_fd_set = active_fd_set;
 
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0; // Not init'ing this can cause strange errors
 
int retval = select(FD_SETSIZE, &read_fd_set, NULL, NULL, &tv);
 
if (retval < 0) {
perror("select");
exit(EXIT_FAILURE);
} else if (retval == 0) {
// fprintf(stdout, "Nothing received\n");
} else {
/* Service all the sockets with input pending. */
for (int i=0; i < FD_SETSIZE; ++i) {
if (FD_ISSET (i, &read_fd_set)) {
if (i == sock) {
/* Connection request on original socket. */
int new_fd;
struct sockaddr_in clientname;
socklen_t size = sizeof(clientname);
new_fd = accept(sock, (struct sockaddr *) &clientname, &size);
if (new_fd < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
FD_SET(new_fd, &active_fd_set);
 
cons[new_fd].clientname = clientname;
cons[new_fd].connect_ts = time(NULL);
 
if (loadedOIDs == 0) {
loadedOIDs = loadCSVs();
if (loadedOIDs == 0) {
fprintf(stderr, "%s:%d[%d] Service temporarily unavailable (OID list empty)\n", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), new_fd);
close(new_fd);
FD_CLR(new_fd, &active_fd_set);
}
}
 
if (fd_set_isset_count(active_fd_set)-1 > 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);
}
 
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);
}
}
}
}
}
Property changes:
Added: svn:mime-type
+text/x-c++src
\ No newline at end of property
Deleted: svn:special
-*
\ No newline at end of property
/trunk/csv_lookup_server_example/oid_lookup_srv.h
1,0 → 0,0
link ../../confidential/jobs/0077_csv_lookup_server/v2/oid_lookup_srv.h
 
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <netdb.h>
#include <unistd.h>
#include <sstream>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <cstring>
 
#define PORT 49500 // TODO: konfigurierbar machen / command line
#define MAXMSG 512
 
#define MAX_CONNECTIONS 100
#define CONNECTION_TIMEOUT 60
 
// In seconds. 21600 = 6 hours
#define CSVRELOADINTERVAL 21600
 
#include <unordered_set>
 
using namespace std;
 
Property changes:
Added: svn:mime-type
+text/x-chdr
\ No newline at end of property
Deleted: svn:special
-*
\ No newline at end of property