summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOpenGnSys Support Team <soporte-og@soleta.eu>2021-04-27 23:45:28 +0200
committerOpenGnSys Support Team <soporte-og@soleta.eu>2021-04-29 11:52:32 +0200
commit1f13855e412bba26064672b02dff78deecb795ab (patch)
tree7a44db095824ef03cedaa597485ca5d5c73969b6 /src
parentc05f1345e76e26eadc798425d820665b9fb8a819 (diff)
#1043 add WOL_SENT state
WOL_SENT tells that WakeOnLan was sent to computer, after 60 seconds, if computer does not boot, this state is released.
Diffstat (limited to 'src')
-rw-r--r--src/core.c6
-rw-r--r--src/rest.c69
-rw-r--r--src/wol.c50
-rw-r--r--src/wol.h14
4 files changed, 138 insertions, 1 deletions
diff --git a/src/core.c b/src/core.c
index fef00ea..a346e7b 100644
--- a/src/core.c
+++ b/src/core.c
@@ -11,6 +11,7 @@
#include "utils.h"
#include "list.h"
#include "rest.h"
+#include "wol.h"
#include "client.h"
#include "json.h"
#include "schedule.h"
@@ -326,6 +327,7 @@ void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events)
int on = 1, idle = OG_TCP_KEEPALIVE_IDLE;
struct sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
+ struct og_client_wol *cli_wol;
struct og_client *cli;
int client_sd;
@@ -343,6 +345,10 @@ void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events)
setsockopt(client_sd, IPPROTO_TCP, TCP_KEEPINTVL, &intl, sizeof(int));
setsockopt(client_sd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(int));
+ cli_wol = og_client_wol_find(&client_addr.sin_addr);
+ if (cli_wol)
+ og_client_wol_destroy(cli_wol);
+
cli = (struct og_client *)calloc(1, sizeof(struct og_client));
if (!cli) {
close(client_sd);
diff --git a/src/rest.c b/src/rest.c
index f78483e..9823b0f 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -11,6 +11,7 @@
#include "utils.h"
#include "list.h"
#include "rest.h"
+#include "wol.h"
#include "cfg.h"
#include "schedule.h"
#include <ev.h>
@@ -76,6 +77,7 @@ struct ev_loop *og_loop;
#define OG_REST_PARAM_CENTER (1UL << 43)
static LIST_HEAD(client_list);
+static LIST_HEAD(client_wol_list);
void og_client_add(struct og_client *cli)
{
@@ -391,19 +393,53 @@ static int og_json_client_append(json_t *array, struct og_client *client)
return 0;
}
+static int og_json_client_wol_append(json_t *array,
+ struct og_client_wol *cli_wol)
+{
+ json_t *addr, *state, *object;
+
+ object = json_object();
+ if (!object)
+ return -1;
+
+ addr = json_string(inet_ntoa(cli_wol->addr));
+ if (!addr) {
+ json_decref(object);
+ return -1;
+ }
+ json_object_set_new(object, "addr", addr);
+ state = json_string(og_client_wol_status(cli_wol));
+ if (!state) {
+ json_decref(object);
+ return -1;
+ }
+ json_object_set_new(object, "state", state);
+ json_array_append_new(array, object);
+
+ return 0;
+}
+
static int og_cmd_get_clients(json_t *element, struct og_msg_params *params,
char *buffer_reply)
{
- struct og_client *client;
struct og_buffer og_buffer = {
.data = buffer_reply,
};
+ struct og_client_wol *cli_wol;
+ struct og_client *client;
json_t *array, *root;
array = json_array();
if (!array)
return -1;
+ list_for_each_entry(cli_wol, &client_wol_list, list) {
+ if (og_json_client_wol_append(array, cli_wol) < 0) {
+ json_decref(array);
+ return -1;
+ }
+ }
+
list_for_each_entry(client, &client_list, list) {
if (!client->agent)
continue;
@@ -450,10 +486,24 @@ static int og_json_parse_type(json_t *element, struct og_msg_params *params)
return 0;
}
+struct og_client_wol *og_client_wol_find(const struct in_addr *addr)
+{
+ struct og_client_wol *cli_wol;
+
+ list_for_each_entry(cli_wol, &client_wol_list, list) {
+ if (cli_wol->addr.s_addr == addr->s_addr)
+ return cli_wol;
+ }
+
+ return NULL;
+}
+
static int og_cmd_wol(json_t *element, struct og_msg_params *params)
{
char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
+ struct og_client_wol *cli_wol;
int ips_str_len = 0;
+ struct in_addr addr;
const char *msglog;
struct og_dbi *dbi;
int err = 0, i = 0;
@@ -520,6 +570,23 @@ static int og_cmd_wol(json_t *element, struct og_msg_params *params)
if (i == 0)
return 0;
+ for (i = 0; i < params->ips_array_len; i++) {
+ if (inet_aton(params->ips_array[i], &addr) < 0)
+ return -1;
+
+ cli_wol = og_client_wol_find(&addr);
+ if (cli_wol) {
+ og_client_wol_refresh(cli_wol);
+ continue;
+ }
+
+ cli_wol = og_client_wol_create(&addr);
+ if (!cli_wol)
+ return -1;
+
+ list_add_tail(&cli_wol->list, &client_wol_list);
+ }
+
if (!Levanta((char **)params->ips_array, (char **)params->mac_array,
(char **)params->netmask_array, i,
(char *)params->wol_type))
diff --git a/src/wol.c b/src/wol.c
index 0ebf718..b0c9426 100644
--- a/src/wol.c
+++ b/src/wol.c
@@ -18,6 +18,7 @@
#include <sys/socket.h>
#include <fcntl.h>
#include "wol.h"
+#include "rest.h"
#include "cfg.h"
#include "ogAdmServer.h"
@@ -86,3 +87,52 @@ bool wake_up_broadcast(int sd, struct sockaddr_in *client,
return wake_up_send(sd, client, msg, &addr.sin_addr);
}
+
+#define OG_WOL_CLIENT_TIMEOUT 60
+
+static void og_client_wol_timer_cb(struct ev_loop *loop, ev_timer *timer,
+ int events)
+{
+ struct og_client_wol *cli_wol;
+
+ cli_wol = container_of(timer, struct og_client_wol, timer);
+
+ syslog(LOG_ERR, "timeout WakeOnLAN request for client %s\n",
+ inet_ntoa(cli_wol->addr));
+ list_del(&cli_wol->list);
+ free(cli_wol);
+}
+
+struct og_client_wol *og_client_wol_create(const struct in_addr *addr)
+{
+ struct og_client_wol *cli_wol;
+
+ cli_wol = calloc(1, sizeof(struct og_client_wol));
+ if (!cli_wol)
+ return NULL;
+
+ cli_wol->addr = *addr;
+
+ ev_timer_init(&cli_wol->timer, og_client_wol_timer_cb,
+ OG_WOL_CLIENT_TIMEOUT, 0.);
+ ev_timer_start(og_loop, &cli_wol->timer);
+
+ return cli_wol;
+}
+
+void og_client_wol_refresh(struct og_client_wol *cli_wol)
+{
+ ev_timer_again(og_loop, &cli_wol->timer);
+}
+
+void og_client_wol_destroy(struct og_client_wol *cli_wol)
+{
+ ev_timer_stop(og_loop, &cli_wol->timer);
+ list_del(&cli_wol->list);
+ free(cli_wol);
+}
+
+const char *og_client_wol_status(const struct og_client_wol *wol)
+{
+ return "WOL_SENT";
+}
diff --git a/src/wol.h b/src/wol.h
index 8682520..a245592 100644
--- a/src/wol.h
+++ b/src/wol.h
@@ -5,6 +5,8 @@
#define OG_WOL_MACADDR_LEN 6
#define OG_WOL_REPEAT 16
+#include "list.h"
+#include <ev.h>
#include <stdbool.h>
struct wol_msg {
@@ -18,4 +20,16 @@ bool wake_up_send(int sd, struct sockaddr_in *client,
bool wake_up_broadcast(int sd, struct sockaddr_in *client,
const struct wol_msg *msg);
+struct og_client_wol {
+ struct list_head list;
+ struct in_addr addr;
+ struct ev_timer timer;
+};
+
+struct og_client_wol *og_client_wol_create(const struct in_addr *addr);
+struct og_client_wol *og_client_wol_find(const struct in_addr *addr);
+void og_client_wol_refresh(struct og_client_wol *cli_wol);
+void og_client_wol_destroy(struct og_client_wol *cli_wol);
+const char *og_client_wol_status(const struct og_client_wol *wol);
+
#endif