summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--sources/ogAdmServer.cpp182
-rw-r--r--tests/post_clients.json1
-rwxr-xr-xtests/run-tests.sh1
4 files changed, 181 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 6af423f..bffa4dc 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ CFLAGS += -g -Wall -I../../Includes
CPPFLAGS := $(CFLAGS)
# Opciones de linkado
-LDFLAGS := -Wl,--no-as-needed $(shell mysql_config --libs) -lev
+LDFLAGS := -Wl,--no-as-needed $(shell mysql_config --libs) -lev -ljansson
# Ficheros objetos
OBJS := ../../Includes/Database.o sources/ogAdmServer.o
diff --git a/sources/ogAdmServer.cpp b/sources/ogAdmServer.cpp
index 6ec9c2d..1dab006 100644
--- a/sources/ogAdmServer.cpp
+++ b/sources/ogAdmServer.cpp
@@ -12,6 +12,7 @@
#include <syslog.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
+#include <jansson.h>
static char usuario[LONPRM]; // Usuario de acceso a la base de datos
static char pasguor[LONPRM]; // Password del usuario
@@ -126,6 +127,7 @@ struct og_client {
unsigned int buf_len;
unsigned int msg_len;
int keepalive_idx;
+ bool rest;
};
static inline int og_client_socket(const struct og_client *cli)
@@ -3616,6 +3618,160 @@ static int og_client_state_process_payload(struct og_client *cli)
return 1;
}
+struct og_msg_params {
+ const char *ips_array[64];
+ unsigned int ips_array_len;
+};
+
+static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
+{
+ unsigned int i;
+ json_t *k;
+
+ if (json_typeof(element) != JSON_ARRAY)
+ return -1;
+
+ for (i = 0; i < json_array_size(element); i++) {
+ k = json_array_get(element, i);
+ if (json_typeof(k) != JSON_STRING)
+ return -1;
+
+ params->ips_array[params->ips_array_len++] =
+ json_string_value(k);
+ }
+ return 0;
+}
+
+static int og_cmd_legacy_sondeo(struct og_msg_params *params)
+{
+ char buf[4096] = {};
+ int len, err = 0;
+ TRAMA *msg;
+
+ len = snprintf(buf, sizeof(buf), "nfn=Sondeo\r");
+
+ msg = og_msg_alloc(buf, len);
+ if (!msg)
+ return -1;
+
+ if (!og_send_cmd((char **)params->ips_array, params->ips_array_len,
+ CLIENTE_APAGADO, msg))
+ err = -1;
+
+ og_msg_free(msg);
+
+ return err;
+}
+
+static int og_cmd_post_clients(json_t *element, struct og_msg_params *params)
+{
+ const char *key;
+ json_t *value;
+ int err = 0;
+
+ if (json_typeof(element) != JSON_OBJECT)
+ return -1;
+
+ json_object_foreach(element, key, value) {
+ if (!strcmp(key, "clients"))
+ err = og_json_parse_clients(value, params);
+
+ if (err < 0)
+ break;
+ }
+
+ return og_cmd_legacy_sondeo(params);
+}
+
+static int og_client_not_found(struct og_client *cli)
+{
+ char buf[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
+
+ send(og_client_socket(cli), buf, strlen(buf), 0);
+
+ return -1;
+}
+
+static int og_client_ok(struct og_client *cli)
+{
+ char buf[] = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n";
+
+ send(og_client_socket(cli), buf, strlen(buf), 0);
+
+ return 0;
+}
+
+enum og_rest_method {
+ OG_METHOD_GET = 0,
+ OG_METHOD_POST,
+};
+
+static int og_client_state_process_payload_rest(struct og_client *cli)
+{
+ struct og_msg_params params = {};
+ const char *cmd, *body, *ptr;
+ enum og_rest_method method;
+ int content_length = 0;
+ json_error_t json_err;
+ json_t *root = NULL;
+ int err = 0;
+
+ if (!strncmp(cli->buf, "GET", strlen("GET"))) {
+ method = OG_METHOD_GET;
+ cmd = cli->buf + strlen("GET") + 2;
+ } else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
+ method = OG_METHOD_POST;
+ cmd = cli->buf + strlen("POST") + 2;
+ } else
+ return -1;
+
+ body = strstr(cli->buf, "\r\n\r\n") + 4;
+
+ ptr = strstr(cli->buf, "Content-Length: ");
+ if (ptr)
+ sscanf(ptr, "Content-Length: %i[^\r\n]", &content_length);
+
+ if (content_length) {
+ root = json_loads(body, 0, &json_err);
+ if (!root) {
+ syslog(LOG_ERR, "malformed json line %d: %s\n",
+ json_err.line, json_err.text);
+ return og_client_not_found(cli);
+ }
+ }
+
+ if (!strncmp(cmd, "clients", strlen("clients"))) {
+ if (method != OG_METHOD_POST)
+ return -1;
+ if (!root) {
+ syslog(LOG_ERR, "command clients with no payload\n");
+ return og_client_not_found(cli);
+ }
+ err = og_cmd_post_clients(root, &params);
+ } else {
+ syslog(LOG_ERR, "unknown command %s\n", cmd);
+ err = og_client_not_found(cli);
+ }
+
+ json_decref(root);
+
+ if (!err)
+ og_client_ok(cli);
+
+ return err;
+}
+
+static int og_client_state_recv_hdr_rest(struct og_client *cli)
+{
+ char *trailer;
+
+ trailer = strstr(cli->buf, "\r\n\r\n");
+ if (!trailer)
+ return 0;
+
+ return 1;
+}
+
static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
{
struct og_client *cli;
@@ -3653,7 +3809,11 @@ static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events
switch (cli->state) {
case OG_CLIENT_RECEIVING_HEADER:
- ret = og_client_state_recv_hdr(cli);
+ if (cli->rest)
+ ret = og_client_state_recv_hdr_rest(cli);
+ else
+ ret = og_client_state_recv_hdr(cli);
+
if (ret < 0)
goto close;
if (!ret)
@@ -3673,7 +3833,10 @@ static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events
inet_ntoa(cli->addr.sin_addr),
ntohs(cli->addr.sin_port));
- ret = og_client_state_process_payload(cli);
+ if (cli->rest)
+ ret = og_client_state_process_payload_rest(cli);
+ else
+ ret = og_client_state_process_payload(cli);
if (ret < 0)
goto close;
@@ -3714,6 +3877,8 @@ static void og_client_timer_cb(struct ev_loop *loop, ev_timer *timer, int events
og_client_release(loop, cli);
}
+static int socket_s, socket_rest;
+
static void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io,
int events)
{
@@ -3739,6 +3904,9 @@ static void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io,
memcpy(&cli->addr, &client_addr, sizeof(client_addr));
cli->keepalive_idx = -1;
+ if (io->fd == socket_rest)
+ cli->rest = true;
+
syslog(LOG_DEBUG, "connection from client %s:%hu\n",
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
@@ -3776,9 +3944,8 @@ static int og_socket_server_init(const char *port)
int main(int argc, char *argv[])
{
+ struct ev_io ev_io_server, ev_io_server_rest;
struct ev_loop *loop = ev_default_loop(0);
- struct ev_io ev_io_server;
- int socket_s;
int i;
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
@@ -3813,6 +3980,13 @@ int main(int argc, char *argv[])
ev_io_init(&ev_io_server, og_server_accept_cb, socket_s, EV_READ);
ev_io_start(loop, &ev_io_server);
+ socket_rest = og_socket_server_init("8888");
+ if (socket_rest < 0)
+ exit(EXIT_FAILURE);
+
+ ev_io_init(&ev_io_server_rest, og_server_accept_cb, socket_rest, EV_READ);
+ ev_io_start(loop, &ev_io_server_rest);
+
infoLog(1); // Inicio de sesiĆ³n
/* old log file has been deprecated. */
diff --git a/tests/post_clients.json b/tests/post_clients.json
new file mode 100644
index 0000000..4667303
--- /dev/null
+++ b/tests/post_clients.json
@@ -0,0 +1 @@
+{ "clients" : [ "192.168.2.1", "192.168.2.2" ] }
diff --git a/tests/run-tests.sh b/tests/run-tests.sh
new file mode 100755
index 0000000..e187abb
--- /dev/null
+++ b/tests/run-tests.sh
@@ -0,0 +1 @@
+curl -X POST http://127.0.0.1:8888/clients -d @post_clients.json