mirror of https://git.48k.eu/ogserver
#971 split socket core logic and main files
Extract socket core and main from ogAdmServer file.master
parent
c46fa3c9e5
commit
48de51537e
|
@ -3,7 +3,9 @@ sbin_PROGRAMS = ogserver
|
||||||
AM_CFLAGS = ${LIBDBI_CFLAGS} ${LIBJANSSON_CFLAGS} ${LIBEVENT_CFLAGS} -g -Wall
|
AM_CFLAGS = ${LIBDBI_CFLAGS} ${LIBJANSSON_CFLAGS} ${LIBEVENT_CFLAGS} -g -Wall
|
||||||
|
|
||||||
ogserver_SOURCES= sources/ogAdmServer.c \
|
ogserver_SOURCES= sources/ogAdmServer.c \
|
||||||
|
sources/core.c \
|
||||||
sources/dbi.c \
|
sources/dbi.c \
|
||||||
|
sources/main.c \
|
||||||
sources/schedule.c \
|
sources/schedule.c \
|
||||||
sources/utils.c \
|
sources/utils.c \
|
||||||
sources/rest.c \
|
sources/rest.c \
|
||||||
|
|
|
@ -0,0 +1,433 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation, version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ogAdmServer.h"
|
||||||
|
#include "dbi.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "rest.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "json.h"
|
||||||
|
#include "schedule.h"
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static void og_client_release(struct ev_loop *loop, struct og_client *cli)
|
||||||
|
{
|
||||||
|
if (cli->keepalive_idx >= 0) {
|
||||||
|
syslog(LOG_DEBUG, "closing keepalive connection for %s:%hu in slot %d\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port), cli->keepalive_idx);
|
||||||
|
tbsockets[cli->keepalive_idx].cli = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_del(&cli->list);
|
||||||
|
ev_io_stop(loop, &cli->io);
|
||||||
|
close(cli->io.fd);
|
||||||
|
free(cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_client_keepalive(struct ev_loop *loop, struct og_client *cli)
|
||||||
|
{
|
||||||
|
struct og_client *old_cli;
|
||||||
|
|
||||||
|
old_cli = tbsockets[cli->keepalive_idx].cli;
|
||||||
|
if (old_cli && old_cli != cli) {
|
||||||
|
syslog(LOG_DEBUG, "closing old keepalive connection for %s:%hu\n",
|
||||||
|
inet_ntoa(old_cli->addr.sin_addr),
|
||||||
|
ntohs(old_cli->addr.sin_port));
|
||||||
|
|
||||||
|
og_client_release(loop, old_cli);
|
||||||
|
}
|
||||||
|
tbsockets[cli->keepalive_idx].cli = cli;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_client_reset_state(struct og_client *cli)
|
||||||
|
{
|
||||||
|
cli->state = OG_CLIENT_RECEIVING_HEADER;
|
||||||
|
cli->buf_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_client_payload_too_large(struct og_client *cli)
|
||||||
|
{
|
||||||
|
char buf[] = "HTTP/1.1 413 Payload Too Large\r\n"
|
||||||
|
"Content-Length: 0\r\n\r\n";
|
||||||
|
|
||||||
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_client_state_recv_hdr_rest(struct og_client *cli)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = strstr(cli->buf, "\r\n\r\n");
|
||||||
|
if (!ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cli->msg_len = ptr - cli->buf + 4;
|
||||||
|
|
||||||
|
ptr = strstr(cli->buf, "Content-Length: ");
|
||||||
|
if (ptr) {
|
||||||
|
sscanf(ptr, "Content-Length: %i[^\r\n]", &cli->content_length);
|
||||||
|
if (cli->content_length < 0)
|
||||||
|
return -1;
|
||||||
|
cli->msg_len += cli->content_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = strstr(cli->buf, "Authorization: ");
|
||||||
|
if (ptr)
|
||||||
|
sscanf(ptr, "Authorization: %63[^\r\n]", cli->auth_token);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_client_recv(struct og_client *cli, int events)
|
||||||
|
{
|
||||||
|
struct ev_io *io = &cli->io;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (events & EV_ERROR) {
|
||||||
|
syslog(LOG_ERR, "unexpected error event from client %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = recv(io->fd, cli->buf + cli->buf_len,
|
||||||
|
sizeof(cli->buf) - cli->buf_len, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_ERR, "error reading from client %s:%hu (%s)\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
syslog(LOG_DEBUG, "closed connection by %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
||||||
|
{
|
||||||
|
struct og_client *cli;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cli = container_of(io, struct og_client, io);
|
||||||
|
|
||||||
|
ret = og_client_recv(cli, events);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto close;
|
||||||
|
|
||||||
|
if (cli->keepalive_idx >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ev_timer_again(loop, &cli->timer);
|
||||||
|
|
||||||
|
cli->buf_len += ret;
|
||||||
|
if (cli->buf_len >= sizeof(cli->buf)) {
|
||||||
|
syslog(LOG_ERR, "client request from %s:%hu is too long\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
og_client_payload_too_large(cli);
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cli->state) {
|
||||||
|
case OG_CLIENT_RECEIVING_HEADER:
|
||||||
|
ret = og_client_state_recv_hdr_rest(cli);
|
||||||
|
if (ret < 0)
|
||||||
|
goto close;
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cli->state = OG_CLIENT_RECEIVING_PAYLOAD;
|
||||||
|
/* Fall through. */
|
||||||
|
case OG_CLIENT_RECEIVING_PAYLOAD:
|
||||||
|
/* Still not enough data to process request. */
|
||||||
|
if (cli->buf_len < cli->msg_len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cli->state = OG_CLIENT_PROCESSING_REQUEST;
|
||||||
|
/* fall through. */
|
||||||
|
case OG_CLIENT_PROCESSING_REQUEST:
|
||||||
|
ret = og_client_state_process_payload_rest(cli);
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port));
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
goto close;
|
||||||
|
|
||||||
|
if (cli->keepalive_idx < 0) {
|
||||||
|
syslog(LOG_DEBUG, "server closing connection to %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
goto close;
|
||||||
|
} else {
|
||||||
|
syslog(LOG_DEBUG, "leaving client %s:%hu in keepalive mode\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port));
|
||||||
|
og_client_keepalive(loop, cli);
|
||||||
|
og_client_reset_state(cli);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syslog(LOG_ERR, "unknown state, critical internal error\n");
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
close:
|
||||||
|
ev_timer_stop(loop, &cli->timer);
|
||||||
|
og_client_release(loop, cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum og_agent_state {
|
||||||
|
OG_AGENT_RECEIVING_HEADER = 0,
|
||||||
|
OG_AGENT_RECEIVING_PAYLOAD,
|
||||||
|
OG_AGENT_PROCESSING_RESPONSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int og_agent_state_recv_hdr_rest(struct og_client *cli)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = strstr(cli->buf, "\r\n\r\n");
|
||||||
|
if (!ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cli->msg_len = ptr - cli->buf + 4;
|
||||||
|
|
||||||
|
ptr = strstr(cli->buf, "Content-Length: ");
|
||||||
|
if (ptr) {
|
||||||
|
sscanf(ptr, "Content-Length: %i[^\r\n]", &cli->content_length);
|
||||||
|
if (cli->content_length < 0)
|
||||||
|
return -1;
|
||||||
|
cli->msg_len += cli->content_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_agent_reset_state(struct og_client *cli)
|
||||||
|
{
|
||||||
|
cli->state = OG_AGENT_RECEIVING_HEADER;
|
||||||
|
cli->buf_len = 0;
|
||||||
|
cli->content_length = 0;
|
||||||
|
memset(cli->buf, 0, sizeof(cli->buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_agent_deliver_pending_cmd(struct og_client *cli)
|
||||||
|
{
|
||||||
|
const struct og_cmd *cmd;
|
||||||
|
|
||||||
|
cmd = og_cmd_find(inet_ntoa(cli->addr.sin_addr));
|
||||||
|
if (!cmd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
og_send_request(cmd->method, cmd->type, &cmd->params, cmd->json);
|
||||||
|
cli->last_cmd_id = cmd->id;
|
||||||
|
|
||||||
|
og_cmd_free(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_agent_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
||||||
|
{
|
||||||
|
struct og_client *cli;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cli = container_of(io, struct og_client, io);
|
||||||
|
|
||||||
|
ret = og_client_recv(cli, events);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto close;
|
||||||
|
|
||||||
|
ev_timer_again(loop, &cli->timer);
|
||||||
|
|
||||||
|
cli->buf_len += ret;
|
||||||
|
if (cli->buf_len >= sizeof(cli->buf)) {
|
||||||
|
syslog(LOG_ERR, "client request from %s:%hu is too long\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cli->state) {
|
||||||
|
case OG_AGENT_RECEIVING_HEADER:
|
||||||
|
ret = og_agent_state_recv_hdr_rest(cli);
|
||||||
|
if (ret < 0)
|
||||||
|
goto close;
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cli->state = OG_AGENT_RECEIVING_PAYLOAD;
|
||||||
|
/* Fall through. */
|
||||||
|
case OG_AGENT_RECEIVING_PAYLOAD:
|
||||||
|
/* Still not enough data to process request. */
|
||||||
|
if (cli->buf_len < cli->msg_len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cli->state = OG_AGENT_PROCESSING_RESPONSE;
|
||||||
|
/* fall through. */
|
||||||
|
case OG_AGENT_PROCESSING_RESPONSE:
|
||||||
|
ret = og_agent_state_process_response(cli);
|
||||||
|
if (ret < 0) {
|
||||||
|
syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port));
|
||||||
|
goto close;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
og_agent_deliver_pending_cmd(cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "leaving client %s:%hu in keepalive mode\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr),
|
||||||
|
ntohs(cli->addr.sin_port));
|
||||||
|
og_agent_reset_state(cli);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syslog(LOG_ERR, "unknown state, critical internal error\n");
|
||||||
|
goto close;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
close:
|
||||||
|
ev_timer_stop(loop, &cli->timer);
|
||||||
|
og_client_release(loop, cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_client_timer_cb(struct ev_loop *loop, ev_timer *timer, int events)
|
||||||
|
{
|
||||||
|
struct og_client *cli;
|
||||||
|
|
||||||
|
cli = container_of(timer, struct og_client, timer);
|
||||||
|
if (cli->keepalive_idx >= 0) {
|
||||||
|
ev_timer_again(loop, &cli->timer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syslog(LOG_ERR, "timeout request for client %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
|
||||||
|
og_client_release(loop, cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void og_agent_send_refresh(struct og_client *cli)
|
||||||
|
{
|
||||||
|
struct og_msg_params params;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
params.ips_array[0] = inet_ntoa(cli->addr.sin_addr);
|
||||||
|
params.ips_array_len = 1;
|
||||||
|
|
||||||
|
err = og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, ¶ms, NULL);
|
||||||
|
if (err < 0) {
|
||||||
|
syslog(LOG_ERR, "Can't send refresh to: %s\n",
|
||||||
|
params.ips_array[0]);
|
||||||
|
} else {
|
||||||
|
syslog(LOG_INFO, "Sent refresh to: %s\n",
|
||||||
|
params.ips_array[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shut down connection if there is no complete message after 10 seconds. */
|
||||||
|
#define OG_CLIENT_TIMEOUT 10
|
||||||
|
|
||||||
|
/* Agent client operation might take longer, shut down after 30 seconds. */
|
||||||
|
#define OG_AGENT_CLIENT_TIMEOUT 30
|
||||||
|
|
||||||
|
int socket_rest, socket_agent_rest;
|
||||||
|
|
||||||
|
void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
||||||
|
{
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
socklen_t addrlen = sizeof(client_addr);
|
||||||
|
struct og_client *cli;
|
||||||
|
int client_sd;
|
||||||
|
|
||||||
|
if (events & EV_ERROR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
client_sd = accept(io->fd, (struct sockaddr *)&client_addr, &addrlen);
|
||||||
|
if (client_sd < 0) {
|
||||||
|
syslog(LOG_ERR, "cannot accept client connection\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli = (struct og_client *)calloc(1, sizeof(struct og_client));
|
||||||
|
if (!cli) {
|
||||||
|
close(client_sd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(&cli->addr, &client_addr, sizeof(client_addr));
|
||||||
|
if (io->fd == socket_agent_rest)
|
||||||
|
cli->keepalive_idx = 0;
|
||||||
|
else
|
||||||
|
cli->keepalive_idx = -1;
|
||||||
|
|
||||||
|
if (io->fd == socket_rest)
|
||||||
|
cli->rest = true;
|
||||||
|
else if (io->fd == socket_agent_rest)
|
||||||
|
cli->agent = true;
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "connection from client %s:%hu\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
|
|
||||||
|
if (io->fd == socket_agent_rest)
|
||||||
|
ev_io_init(&cli->io, og_agent_read_cb, client_sd, EV_READ);
|
||||||
|
else
|
||||||
|
ev_io_init(&cli->io, og_client_read_cb, client_sd, EV_READ);
|
||||||
|
|
||||||
|
ev_io_start(loop, &cli->io);
|
||||||
|
if (io->fd == socket_agent_rest) {
|
||||||
|
ev_timer_init(&cli->timer, og_client_timer_cb,
|
||||||
|
OG_AGENT_CLIENT_TIMEOUT, 0.);
|
||||||
|
} else {
|
||||||
|
ev_timer_init(&cli->timer, og_client_timer_cb,
|
||||||
|
OG_CLIENT_TIMEOUT, 0.);
|
||||||
|
}
|
||||||
|
ev_timer_start(loop, &cli->timer);
|
||||||
|
og_client_add(cli);
|
||||||
|
|
||||||
|
if (io->fd == socket_agent_rest) {
|
||||||
|
og_agent_send_refresh(cli);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int og_socket_server_init(const char *port)
|
||||||
|
{
|
||||||
|
struct sockaddr_in local;
|
||||||
|
int sd, on = 1;
|
||||||
|
|
||||||
|
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (sd < 0) {
|
||||||
|
syslog(LOG_ERR, "cannot create main socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int));
|
||||||
|
|
||||||
|
local.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
local.sin_family = AF_INET;
|
||||||
|
local.sin_port = htons(atoi(port));
|
||||||
|
|
||||||
|
if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
|
||||||
|
close(sd);
|
||||||
|
syslog(LOG_ERR, "cannot bind socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen(sd, 250);
|
||||||
|
|
||||||
|
return sd;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef _OG_CORE_H
|
||||||
|
#define _OG_CORE_H
|
||||||
|
|
||||||
|
extern int socket_rest, socket_agent_rest;
|
||||||
|
extern struct ev_loop *og_loop;
|
||||||
|
|
||||||
|
int og_socket_server_init(const char *port);
|
||||||
|
void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation, version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "dbi.h"
|
#include "dbi.h"
|
||||||
|
|
||||||
struct og_dbi *og_dbi_open(struct og_dbi_config *config)
|
struct og_dbi *og_dbi_open(struct og_dbi_config *config)
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation, version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ogAdmServer.h"
|
||||||
|
#include "dbi.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "rest.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "json.h"
|
||||||
|
#include "schedule.h"
|
||||||
|
#include "core.h"
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct ev_io ev_io_server_rest, ev_io_agent_rest;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
og_loop = ev_default_loop(0);
|
||||||
|
|
||||||
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
openlog("ogAdmServer", LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
|
if (!validacionParametros(argc, argv, 1)) // Valida parámetros de ejecución
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if (!tomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuracion
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAXIMOS_CLIENTES; i++) {
|
||||||
|
tbsockets[i].ip[0] = '\0';
|
||||||
|
tbsockets[i].cli = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(og_loop, &ev_io_server_rest);
|
||||||
|
|
||||||
|
socket_agent_rest = og_socket_server_init("8889");
|
||||||
|
if (socket_agent_rest < 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
ev_io_init(&ev_io_agent_rest, og_server_accept_cb, socket_agent_rest, EV_READ);
|
||||||
|
ev_io_start(og_loop, &ev_io_agent_rest);
|
||||||
|
|
||||||
|
if (og_dbi_schedule_get() < 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
og_schedule_next(og_loop);
|
||||||
|
|
||||||
|
syslog(LOG_INFO, "Waiting for connections\n");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
ev_loop(og_loop, 0);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
|
@ -115,3 +115,6 @@ char* escaparCadena(char *cadena);
|
||||||
typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool tomaConfiguracion(const char *filecfg);
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct og_dbi_config dbi_config = {
|
||||||
// true: Si el proceso es correcto
|
// true: Si el proceso es correcto
|
||||||
// false: En caso de ocurrir algún error
|
// false: En caso de ocurrir algún error
|
||||||
//________________________________________________________________________________________________________
|
//________________________________________________________________________________________________________
|
||||||
static bool tomaConfiguracion(const char *filecfg)
|
bool tomaConfiguracion(const char *filecfg)
|
||||||
{
|
{
|
||||||
char buf[1024], *line;
|
char buf[1024], *line;
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
|
@ -131,12 +131,6 @@ static bool tomaConfiguracion(const char *filecfg)
|
||||||
|
|
||||||
#define OG_CMD_MAXLEN 64
|
#define OG_CMD_MAXLEN 64
|
||||||
|
|
||||||
/* Shut down connection if there is no complete message after 10 seconds. */
|
|
||||||
#define OG_CLIENT_TIMEOUT 10
|
|
||||||
|
|
||||||
/* Agent client operation might take longer, shut down after 30 seconds. */
|
|
||||||
#define OG_AGENT_CLIENT_TIMEOUT 30
|
|
||||||
|
|
||||||
// ________________________________________________________________________________________________________
|
// ________________________________________________________________________________________________________
|
||||||
// Función: clienteDisponible
|
// Función: clienteDisponible
|
||||||
//
|
//
|
||||||
|
@ -1305,469 +1299,3 @@ bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void og_client_release(struct ev_loop *loop, struct og_client *cli)
|
|
||||||
{
|
|
||||||
if (cli->keepalive_idx >= 0) {
|
|
||||||
syslog(LOG_DEBUG, "closing keepalive connection for %s:%hu in slot %d\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port), cli->keepalive_idx);
|
|
||||||
tbsockets[cli->keepalive_idx].cli = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_del(&cli->list);
|
|
||||||
ev_io_stop(loop, &cli->io);
|
|
||||||
close(cli->io.fd);
|
|
||||||
free(cli);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_client_keepalive(struct ev_loop *loop, struct og_client *cli)
|
|
||||||
{
|
|
||||||
struct og_client *old_cli;
|
|
||||||
|
|
||||||
old_cli = tbsockets[cli->keepalive_idx].cli;
|
|
||||||
if (old_cli && old_cli != cli) {
|
|
||||||
syslog(LOG_DEBUG, "closing old keepalive connection for %s:%hu\n",
|
|
||||||
inet_ntoa(old_cli->addr.sin_addr),
|
|
||||||
ntohs(old_cli->addr.sin_port));
|
|
||||||
|
|
||||||
og_client_release(loop, old_cli);
|
|
||||||
}
|
|
||||||
tbsockets[cli->keepalive_idx].cli = cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_client_reset_state(struct og_client *cli)
|
|
||||||
{
|
|
||||||
cli->state = OG_CLIENT_RECEIVING_HEADER;
|
|
||||||
cli->buf_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int og_client_payload_too_large(struct og_client *cli)
|
|
||||||
{
|
|
||||||
char buf[] = "HTTP/1.1 413 Payload Too Large\r\n"
|
|
||||||
"Content-Length: 0\r\n\r\n";
|
|
||||||
|
|
||||||
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int og_client_state_recv_hdr_rest(struct og_client *cli)
|
|
||||||
{
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
ptr = strstr(cli->buf, "\r\n\r\n");
|
|
||||||
if (!ptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cli->msg_len = ptr - cli->buf + 4;
|
|
||||||
|
|
||||||
ptr = strstr(cli->buf, "Content-Length: ");
|
|
||||||
if (ptr) {
|
|
||||||
sscanf(ptr, "Content-Length: %i[^\r\n]", &cli->content_length);
|
|
||||||
if (cli->content_length < 0)
|
|
||||||
return -1;
|
|
||||||
cli->msg_len += cli->content_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = strstr(cli->buf, "Authorization: ");
|
|
||||||
if (ptr)
|
|
||||||
sscanf(ptr, "Authorization: %63[^\r\n]", cli->auth_token);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int og_client_recv(struct og_client *cli, int events)
|
|
||||||
{
|
|
||||||
struct ev_io *io = &cli->io;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (events & EV_ERROR) {
|
|
||||||
syslog(LOG_ERR, "unexpected error event from client %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = recv(io->fd, cli->buf + cli->buf_len,
|
|
||||||
sizeof(cli->buf) - cli->buf_len, 0);
|
|
||||||
if (ret <= 0) {
|
|
||||||
if (ret < 0) {
|
|
||||||
syslog(LOG_ERR, "error reading from client %s:%hu (%s)\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
|
|
||||||
strerror(errno));
|
|
||||||
} else {
|
|
||||||
syslog(LOG_DEBUG, "closed connection by %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
|
||||||
{
|
|
||||||
struct og_client *cli;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
cli = container_of(io, struct og_client, io);
|
|
||||||
|
|
||||||
ret = og_client_recv(cli, events);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto close;
|
|
||||||
|
|
||||||
if (cli->keepalive_idx >= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ev_timer_again(loop, &cli->timer);
|
|
||||||
|
|
||||||
cli->buf_len += ret;
|
|
||||||
if (cli->buf_len >= sizeof(cli->buf)) {
|
|
||||||
syslog(LOG_ERR, "client request from %s:%hu is too long\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
og_client_payload_too_large(cli);
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cli->state) {
|
|
||||||
case OG_CLIENT_RECEIVING_HEADER:
|
|
||||||
ret = og_client_state_recv_hdr_rest(cli);
|
|
||||||
if (ret < 0)
|
|
||||||
goto close;
|
|
||||||
if (!ret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cli->state = OG_CLIENT_RECEIVING_PAYLOAD;
|
|
||||||
/* Fall through. */
|
|
||||||
case OG_CLIENT_RECEIVING_PAYLOAD:
|
|
||||||
/* Still not enough data to process request. */
|
|
||||||
if (cli->buf_len < cli->msg_len)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cli->state = OG_CLIENT_PROCESSING_REQUEST;
|
|
||||||
/* fall through. */
|
|
||||||
case OG_CLIENT_PROCESSING_REQUEST:
|
|
||||||
ret = og_client_state_process_payload_rest(cli);
|
|
||||||
if (ret < 0) {
|
|
||||||
syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port));
|
|
||||||
}
|
|
||||||
if (ret < 0)
|
|
||||||
goto close;
|
|
||||||
|
|
||||||
if (cli->keepalive_idx < 0) {
|
|
||||||
syslog(LOG_DEBUG, "server closing connection to %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
goto close;
|
|
||||||
} else {
|
|
||||||
syslog(LOG_DEBUG, "leaving client %s:%hu in keepalive mode\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port));
|
|
||||||
og_client_keepalive(loop, cli);
|
|
||||||
og_client_reset_state(cli);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
syslog(LOG_ERR, "unknown state, critical internal error\n");
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
close:
|
|
||||||
ev_timer_stop(loop, &cli->timer);
|
|
||||||
og_client_release(loop, cli);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum og_agent_state {
|
|
||||||
OG_AGENT_RECEIVING_HEADER = 0,
|
|
||||||
OG_AGENT_RECEIVING_PAYLOAD,
|
|
||||||
OG_AGENT_PROCESSING_RESPONSE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int og_agent_state_recv_hdr_rest(struct og_client *cli)
|
|
||||||
{
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
ptr = strstr(cli->buf, "\r\n\r\n");
|
|
||||||
if (!ptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cli->msg_len = ptr - cli->buf + 4;
|
|
||||||
|
|
||||||
ptr = strstr(cli->buf, "Content-Length: ");
|
|
||||||
if (ptr) {
|
|
||||||
sscanf(ptr, "Content-Length: %i[^\r\n]", &cli->content_length);
|
|
||||||
if (cli->content_length < 0)
|
|
||||||
return -1;
|
|
||||||
cli->msg_len += cli->content_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_agent_reset_state(struct og_client *cli)
|
|
||||||
{
|
|
||||||
cli->state = OG_AGENT_RECEIVING_HEADER;
|
|
||||||
cli->buf_len = 0;
|
|
||||||
cli->content_length = 0;
|
|
||||||
memset(cli->buf, 0, sizeof(cli->buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_agent_deliver_pending_cmd(struct og_client *cli)
|
|
||||||
{
|
|
||||||
const struct og_cmd *cmd;
|
|
||||||
|
|
||||||
cmd = og_cmd_find(inet_ntoa(cli->addr.sin_addr));
|
|
||||||
if (!cmd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
og_send_request(cmd->method, cmd->type, &cmd->params, cmd->json);
|
|
||||||
cli->last_cmd_id = cmd->id;
|
|
||||||
|
|
||||||
og_cmd_free(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_agent_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
|
||||||
{
|
|
||||||
struct og_client *cli;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
cli = container_of(io, struct og_client, io);
|
|
||||||
|
|
||||||
ret = og_client_recv(cli, events);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto close;
|
|
||||||
|
|
||||||
ev_timer_again(loop, &cli->timer);
|
|
||||||
|
|
||||||
cli->buf_len += ret;
|
|
||||||
if (cli->buf_len >= sizeof(cli->buf)) {
|
|
||||||
syslog(LOG_ERR, "client request from %s:%hu is too long\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cli->state) {
|
|
||||||
case OG_AGENT_RECEIVING_HEADER:
|
|
||||||
ret = og_agent_state_recv_hdr_rest(cli);
|
|
||||||
if (ret < 0)
|
|
||||||
goto close;
|
|
||||||
if (!ret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cli->state = OG_AGENT_RECEIVING_PAYLOAD;
|
|
||||||
/* Fall through. */
|
|
||||||
case OG_AGENT_RECEIVING_PAYLOAD:
|
|
||||||
/* Still not enough data to process request. */
|
|
||||||
if (cli->buf_len < cli->msg_len)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cli->state = OG_AGENT_PROCESSING_RESPONSE;
|
|
||||||
/* fall through. */
|
|
||||||
case OG_AGENT_PROCESSING_RESPONSE:
|
|
||||||
ret = og_agent_state_process_response(cli);
|
|
||||||
if (ret < 0) {
|
|
||||||
syslog(LOG_ERR, "Failed to process HTTP request from %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port));
|
|
||||||
goto close;
|
|
||||||
} else if (ret == 0) {
|
|
||||||
og_agent_deliver_pending_cmd(cli);
|
|
||||||
}
|
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "leaving client %s:%hu in keepalive mode\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr),
|
|
||||||
ntohs(cli->addr.sin_port));
|
|
||||||
og_agent_reset_state(cli);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
syslog(LOG_ERR, "unknown state, critical internal error\n");
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
close:
|
|
||||||
ev_timer_stop(loop, &cli->timer);
|
|
||||||
og_client_release(loop, cli);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_client_timer_cb(struct ev_loop *loop, ev_timer *timer, int events)
|
|
||||||
{
|
|
||||||
struct og_client *cli;
|
|
||||||
|
|
||||||
cli = container_of(timer, struct og_client, timer);
|
|
||||||
if (cli->keepalive_idx >= 0) {
|
|
||||||
ev_timer_again(loop, &cli->timer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
syslog(LOG_ERR, "timeout request for client %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
|
|
||||||
og_client_release(loop, cli);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void og_agent_send_refresh(struct og_client *cli)
|
|
||||||
{
|
|
||||||
struct og_msg_params params;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
params.ips_array[0] = inet_ntoa(cli->addr.sin_addr);
|
|
||||||
params.ips_array_len = 1;
|
|
||||||
|
|
||||||
err = og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, ¶ms, NULL);
|
|
||||||
if (err < 0) {
|
|
||||||
syslog(LOG_ERR, "Can't send refresh to: %s\n",
|
|
||||||
params.ips_array[0]);
|
|
||||||
} else {
|
|
||||||
syslog(LOG_INFO, "Sent refresh to: %s\n",
|
|
||||||
params.ips_array[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int socket_rest, socket_agent_rest;
|
|
||||||
|
|
||||||
static void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io,
|
|
||||||
int events)
|
|
||||||
{
|
|
||||||
struct sockaddr_in client_addr;
|
|
||||||
socklen_t addrlen = sizeof(client_addr);
|
|
||||||
struct og_client *cli;
|
|
||||||
int client_sd;
|
|
||||||
|
|
||||||
if (events & EV_ERROR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
client_sd = accept(io->fd, (struct sockaddr *)&client_addr, &addrlen);
|
|
||||||
if (client_sd < 0) {
|
|
||||||
syslog(LOG_ERR, "cannot accept client connection\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cli = (struct og_client *)calloc(1, sizeof(struct og_client));
|
|
||||||
if (!cli) {
|
|
||||||
close(client_sd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(&cli->addr, &client_addr, sizeof(client_addr));
|
|
||||||
if (io->fd == socket_agent_rest)
|
|
||||||
cli->keepalive_idx = 0;
|
|
||||||
else
|
|
||||||
cli->keepalive_idx = -1;
|
|
||||||
|
|
||||||
if (io->fd == socket_rest)
|
|
||||||
cli->rest = true;
|
|
||||||
else if (io->fd == socket_agent_rest)
|
|
||||||
cli->agent = true;
|
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "connection from client %s:%hu\n",
|
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
|
||||||
|
|
||||||
if (io->fd == socket_agent_rest)
|
|
||||||
ev_io_init(&cli->io, og_agent_read_cb, client_sd, EV_READ);
|
|
||||||
else
|
|
||||||
ev_io_init(&cli->io, og_client_read_cb, client_sd, EV_READ);
|
|
||||||
|
|
||||||
ev_io_start(loop, &cli->io);
|
|
||||||
if (io->fd == socket_agent_rest) {
|
|
||||||
ev_timer_init(&cli->timer, og_client_timer_cb,
|
|
||||||
OG_AGENT_CLIENT_TIMEOUT, 0.);
|
|
||||||
} else {
|
|
||||||
ev_timer_init(&cli->timer, og_client_timer_cb,
|
|
||||||
OG_CLIENT_TIMEOUT, 0.);
|
|
||||||
}
|
|
||||||
ev_timer_start(loop, &cli->timer);
|
|
||||||
og_client_add(cli);
|
|
||||||
|
|
||||||
if (io->fd == socket_agent_rest) {
|
|
||||||
og_agent_send_refresh(cli);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int og_socket_server_init(const char *port)
|
|
||||||
{
|
|
||||||
struct sockaddr_in local;
|
|
||||||
int sd, on = 1;
|
|
||||||
|
|
||||||
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
||||||
if (sd < 0) {
|
|
||||||
syslog(LOG_ERR, "cannot create main socket\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int));
|
|
||||||
|
|
||||||
local.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
local.sin_family = AF_INET;
|
|
||||||
local.sin_port = htons(atoi(port));
|
|
||||||
|
|
||||||
if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
|
|
||||||
close(sd);
|
|
||||||
syslog(LOG_ERR, "cannot bind socket\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
listen(sd, 250);
|
|
||||||
|
|
||||||
return sd;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ev_loop *og_loop;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct ev_io ev_io_server_rest, ev_io_agent_rest;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
og_loop = ev_default_loop(0);
|
|
||||||
|
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
openlog("ogAdmServer", LOG_PID, LOG_DAEMON);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------------------------------
|
|
||||||
Validación de parámetros de ejecución y lectura del fichero de configuración del servicio
|
|
||||||
---------------------------------------------------------------------------------------------------------*/
|
|
||||||
if (!validacionParametros(argc, argv, 1)) // Valida parámetros de ejecución
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
if (!tomaConfiguracion(szPathFileCfg)) { // Toma parametros de configuracion
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------------------------------
|
|
||||||
// Inicializa array de información de los clientes
|
|
||||||
---------------------------------------------------------------------------------------------------------*/
|
|
||||||
for (i = 0; i < MAXIMOS_CLIENTES; i++) {
|
|
||||||
tbsockets[i].ip[0] = '\0';
|
|
||||||
tbsockets[i].cli = NULL;
|
|
||||||
}
|
|
||||||
/*--------------------------------------------------------------------------------------------------------
|
|
||||||
Creación y configuración del socket del servicio
|
|
||||||
---------------------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
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(og_loop, &ev_io_server_rest);
|
|
||||||
|
|
||||||
socket_agent_rest = og_socket_server_init("8889");
|
|
||||||
if (socket_agent_rest < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
ev_io_init(&ev_io_agent_rest, og_server_accept_cb, socket_agent_rest, EV_READ);
|
|
||||||
ev_io_start(og_loop, &ev_io_agent_rest);
|
|
||||||
|
|
||||||
if (og_dbi_schedule_get() < 0)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
og_schedule_next(og_loop);
|
|
||||||
|
|
||||||
syslog(LOG_INFO, "Waiting for connections\n");
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
ev_loop(og_loop, 0);
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
struct ev_loop *og_loop;
|
||||||
|
|
||||||
static TRAMA *og_msg_alloc(char *data, unsigned int len)
|
static TRAMA *og_msg_alloc(char *data, unsigned int len)
|
||||||
{
|
{
|
||||||
TRAMA *ptrTrama;
|
TRAMA *ptrTrama;
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation, version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue