@@ -1,4 +1,5 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = -std=gnu99 -W -Wall -Wno-unused-parameter \
+ -Wmissing-prototypes \
${LIBNFTABLES_CFLAGS} ${LIBJSON_CFLAGS} -lev
@@ -32,129 +32,128 @@
#define CONFIG_MAXBUF 4096
-void config_json(json_t *element, int level);
-void config_json_object(json_t *element, int level);
-void config_json_array(json_t *element, int level);
-void config_json_string(json_t *element, int level);
-int config_key(const char *key);
-int jump_config_value(int level, int key);
-void init_pair(struct configpair *cfgp);
-void config_value(const char *value);
-int config_value_family(const char *value);
-int config_value_mode(const char *value);
-int config_value_proto(const char *value);
-int config_value_sched(const char *value);
-int config_value_state(const char *value);
-int config_value_action(const char *value);
-
+static void config_json(json_t *element, int level);
struct configpair cfgp;
-int config_file(const char *file)
+static void init_pair(struct configpair *cfgp)
{
- FILE *fd;
- json_error_t error;
- json_t *root;
- int ret = EXIT_SUCCESS;
-
- fd = fopen(file, "r");
- if (fd == NULL) {
- fprintf(stderr, "Error open configuration file %s\n", file);
- syslog(LOG_ERR, "Error open configuration file %s", file);
- return EXIT_FAILURE;
- }
-
- root = json_loadf(fd, JSON_ALLOW_NUL, &error);
-
- if (root) {
- config_json(root, MODEL_LEVEL_INIT);
- json_decref(root);
- } else {
- syslog(LOG_ERR, "Configuration file error on line %d: %s", error.line, error.text);
- ret = EXIT_FAILURE;
- }
-
- fclose(fd);
- return ret;
+ cfgp->level = -1;
+ cfgp->key = -1;
+ cfgp->str_value = NULL;
+ cfgp->int_value = -1;
}
-int config_buffer(const char *buf)
+static int config_value_family(const char *value)
{
- json_error_t error;
- json_t *root;
- int ret = EXIT_SUCCESS;
+ if (strcmp(value, CONFIG_VALUE_FAMILY_IPV4) == 0)
+ return MODEL_VALUE_FAMILY_IPV4;
+ if (strcmp(value, CONFIG_VALUE_FAMILY_IPV6) == 0)
+ return MODEL_VALUE_FAMILY_IPV6;
+ if (strcmp(value, CONFIG_VALUE_FAMILY_INET) == 0)
+ return MODEL_VALUE_FAMILY_INET;
- root = json_loadb(buf, strlen(buf), JSON_ALLOW_NUL, &error);
+ return EXIT_FAILURE;
+}
- if (root) {
- config_json(root, MODEL_LEVEL_INIT);
- json_decref(root);
- } else {
- syslog(LOG_ERR, "Configuration error on line %d: %s", error.line, error.text);
- ret = EXIT_FAILURE;
- }
+static int config_value_mode(const char *value)
+{
+ if (strcmp(value, CONFIG_VALUE_MODE_SNAT) == 0)
+ return MODEL_VALUE_MODE_SNAT;
+ if (strcmp(value, CONFIG_VALUE_MODE_DNAT) == 0)
+ return MODEL_VALUE_MODE_DNAT;
+ if (strcmp(value, CONFIG_VALUE_MODE_DSR) == 0)
+ return MODEL_VALUE_MODE_DSR;
- return ret;
+ return EXIT_FAILURE;
}
-void config_json(json_t *element, int level)
+static int config_value_proto(const char *value)
{
- switch (json_typeof(element)) {
- case JSON_OBJECT:
- config_json_object(element, level);
- break;
- case JSON_ARRAY:
- level++;
- config_json_array(element, level);
- break;
- case JSON_STRING:
- config_json_string(element, level);
- break;
- default:
- fprintf(stderr, "Configuration file unknown element type %d\n", json_typeof(element));
- syslog(LOG_ERR, "Configuration file unknown element type %d", json_typeof(element));
- }
+ if (strcmp(value, CONFIG_VALUE_PROTO_TCP) == 0)
+ return MODEL_VALUE_PROTO_TCP;
+ if (strcmp(value, CONFIG_VALUE_PROTO_UDP) == 0)
+ return MODEL_VALUE_PROTO_UDP;
+ if (strcmp(value, CONFIG_VALUE_PROTO_SCTP) == 0)
+ return MODEL_VALUE_PROTO_SCTP;
+ if (strcmp(value, CONFIG_VALUE_PROTO_ALL) == 0)
+ return MODEL_VALUE_PROTO_ALL;
+
+ return EXIT_FAILURE;
}
-void config_json_object(json_t *element, int level)
+static int config_value_sched(const char *value)
{
- const char *key;
- json_t *value;
-
- json_object_foreach(element, key, value) {
- cfgp.level = level;
- cfgp.key = config_key(key);
+ if (strcmp(value, CONFIG_VALUE_SCHED_RR) == 0)
+ return MODEL_VALUE_SCHED_RR;
+ if (strcmp(value, CONFIG_VALUE_SCHED_WEIGHT) == 0)
+ return MODEL_VALUE_SCHED_WEIGHT;
+ if (strcmp(value, CONFIG_VALUE_SCHED_HASH) == 0)
+ return MODEL_VALUE_SCHED_HASH;
+ if (strcmp(value, CONFIG_VALUE_SCHED_SYMHASH) == 0)
+ return MODEL_VALUE_SCHED_SYMHASH;
- if (jump_config_value(level, cfgp.key) == EXIT_SUCCESS)
- config_json(value, level);
- }
+ return EXIT_FAILURE;
}
-void config_json_array(json_t *element, int level)
+static int config_value_state(const char *value)
{
- size_t i;
- size_t size = json_array_size(element);
+ if (strcmp(value, CONFIG_VALUE_STATE_UP) == 0)
+ return MODEL_VALUE_STATE_UP;
+ if (strcmp(value, CONFIG_VALUE_STATE_DOWN) == 0)
+ return MODEL_VALUE_STATE_DOWN;
+ if (strcmp(value, CONFIG_VALUE_STATE_OFF) == 0)
+ return MODEL_VALUE_STATE_OFF;
- for (i = 0; i < size; i++)
- config_json(json_array_get(element, i), level);
+ return EXIT_FAILURE;
}
-void config_json_string(json_t *element, int level)
+static int config_value_action(const char *value)
{
- config_value(json_string_value(element));
- model_set_obj_attribute(&cfgp);
- init_pair(&cfgp);
+ if (strcmp(value, CONFIG_VALUE_ACTION_STOP) == 0)
+ return MODEL_ACTION_STOP;
+ if (strcmp(value, CONFIG_VALUE_ACTION_DELETE) == 0)
+ return MODEL_ACTION_DELETE;
+ if (strcmp(value, CONFIG_VALUE_ACTION_START) == 0)
+ return MODEL_ACTION_START;
+ if (strcmp(value, CONFIG_VALUE_ACTION_RELOAD) == 0)
+ return MODEL_ACTION_RELOAD;
+
+ return MODEL_ACTION_NONE;
}
-void init_pair(struct configpair *cfgp)
+static void config_value(const char *value)
{
- cfgp->level = -1;
- cfgp->key = -1;
- cfgp->str_value = NULL;
- cfgp->int_value = -1;
+ switch(cfgp.key) {
+ case MODEL_KEY_FAMILY:
+ cfgp.int_value = config_value_family(value);
+ break;
+ case MODEL_KEY_MODE:
+ cfgp.int_value = config_value_mode(value);
+ break;
+ case MODEL_KEY_PROTO:
+ cfgp.int_value = config_value_proto(value);
+ break;
+ case MODEL_KEY_SCHED:
+ cfgp.int_value = config_value_sched(value);
+ break;
+ case MODEL_KEY_STATE:
+ cfgp.int_value = config_value_state(value);
+ break;
+ case MODEL_KEY_WEIGHT:
+ case MODEL_KEY_PRIORITY:
+ cfgp.int_value = atoi(value);
+ break;
+ case MODEL_KEY_ACTION:
+ cfgp.int_value = config_value_action(value);
+ break;
+ break;
+ default:
+ cfgp.str_value = (char *)value;
+ }
}
-int config_key(const char *key)
+static int config_key(const char *key)
{
if (strcmp(key, CONFIG_KEY_FARMS) == 0)
return MODEL_KEY_FARMS;
@@ -198,7 +197,7 @@ int config_key(const char *key)
return EXIT_FAILURE;
}
-int jump_config_value(int level, int key)
+static int jump_config_value(int level, int key)
{
if ((level == MODEL_LEVEL_INIT && key != MODEL_KEY_FARMS) ||
(key == MODEL_KEY_BCKS && level != MODEL_LEVEL_FARMS))
@@ -207,102 +206,103 @@ int jump_config_value(int level, int key)
return EXIT_SUCCESS;
}
-void config_value(const char *value)
+static void config_json_object(json_t *element, int level)
{
- switch(cfgp.key) {
- case MODEL_KEY_FAMILY:
- cfgp.int_value = config_value_family(value);
- break;
- case MODEL_KEY_MODE:
- cfgp.int_value = config_value_mode(value);
- break;
- case MODEL_KEY_PROTO:
- cfgp.int_value = config_value_proto(value);
- break;
- case MODEL_KEY_SCHED:
- cfgp.int_value = config_value_sched(value);
- break;
- case MODEL_KEY_STATE:
- cfgp.int_value = config_value_state(value);
- break;
- case MODEL_KEY_WEIGHT:
- case MODEL_KEY_PRIORITY:
- cfgp.int_value = atoi(value);
- break;
- case MODEL_KEY_ACTION:
- cfgp.int_value = config_value_action(value);
- break;
- break;
- default:
- cfgp.str_value = (char *)value;
+ const char *key;
+ json_t *value;
+
+ json_object_foreach(element, key, value) {
+ cfgp.level = level;
+ cfgp.key = config_key(key);
+
+ if (jump_config_value(level, cfgp.key) == EXIT_SUCCESS)
+ config_json(value, level);
}
}
-int config_value_family(const char *value)
+static void config_json_array(json_t *element, int level)
{
- if (strcmp(value, CONFIG_VALUE_FAMILY_IPV4) == 0)
- return MODEL_VALUE_FAMILY_IPV4;
- if (strcmp(value, CONFIG_VALUE_FAMILY_IPV6) == 0)
- return MODEL_VALUE_FAMILY_IPV6;
- if (strcmp(value, CONFIG_VALUE_FAMILY_INET) == 0)
- return MODEL_VALUE_FAMILY_INET;
+ size_t size = json_array_size(element);
+ size_t i;
- return EXIT_FAILURE;
+ for (i = 0; i < size; i++)
+ config_json(json_array_get(element, i), level);
}
-int config_value_mode(const char *value)
+static void config_json_string(json_t *element, int level)
{
- if (strcmp(value, CONFIG_VALUE_MODE_SNAT) == 0)
- return MODEL_VALUE_MODE_SNAT;
- if (strcmp(value, CONFIG_VALUE_MODE_DNAT) == 0)
- return MODEL_VALUE_MODE_DNAT;
- if (strcmp(value, CONFIG_VALUE_MODE_DSR) == 0)
- return MODEL_VALUE_MODE_DSR;
-
- return EXIT_FAILURE;
+ config_value(json_string_value(element));
+ model_set_obj_attribute(&cfgp);
+ init_pair(&cfgp);
}
-int config_value_proto(const char *value)
+static void config_json(json_t *element, int level)
{
- if (strcmp(value, CONFIG_VALUE_PROTO_TCP) == 0)
- return MODEL_VALUE_PROTO_TCP;
- if (strcmp(value, CONFIG_VALUE_PROTO_UDP) == 0)
- return MODEL_VALUE_PROTO_UDP;
- if (strcmp(value, CONFIG_VALUE_PROTO_SCTP) == 0)
- return MODEL_VALUE_PROTO_SCTP;
- if (strcmp(value, CONFIG_VALUE_PROTO_ALL) == 0)
- return MODEL_VALUE_PROTO_ALL;
-
- return EXIT_FAILURE;
+ switch (json_typeof(element)) {
+ case JSON_OBJECT:
+ config_json_object(element, level);
+ break;
+ case JSON_ARRAY:
+ level++;
+ config_json_array(element, level);
+ break;
+ case JSON_STRING:
+ config_json_string(element, level);
+ break;
+ default:
+ fprintf(stderr, "Configuration file unknown element type %d\n", json_typeof(element));
+ syslog(LOG_ERR, "Configuration file unknown element type %d", json_typeof(element));
+ }
}
-int config_value_sched(const char *value)
+int config_file(const char *file)
{
- if (strcmp(value, CONFIG_VALUE_SCHED_RR) == 0)
- return MODEL_VALUE_SCHED_RR;
- if (strcmp(value, CONFIG_VALUE_SCHED_WEIGHT) == 0)
- return MODEL_VALUE_SCHED_WEIGHT;
- if (strcmp(value, CONFIG_VALUE_SCHED_HASH) == 0)
- return MODEL_VALUE_SCHED_HASH;
- if (strcmp(value, CONFIG_VALUE_SCHED_SYMHASH) == 0)
- return MODEL_VALUE_SCHED_SYMHASH;
+ FILE *fd;
+ json_error_t error;
+ json_t *root;
+ int ret = EXIT_SUCCESS;
- return EXIT_FAILURE;
+ fd = fopen(file, "r");
+ if (fd == NULL) {
+ fprintf(stderr, "Error open configuration file %s\n", file);
+ syslog(LOG_ERR, "Error open configuration file %s", file);
+ return EXIT_FAILURE;
+ }
+
+ root = json_loadf(fd, JSON_ALLOW_NUL, &error);
+
+ if (root) {
+ config_json(root, MODEL_LEVEL_INIT);
+ json_decref(root);
+ } else {
+ syslog(LOG_ERR, "Configuration file error on line %d: %s", error.line, error.text);
+ ret = EXIT_FAILURE;
+ }
+
+ fclose(fd);
+ return ret;
}
-int config_value_state(const char *value)
+int config_buffer(const char *buf)
{
- if (strcmp(value, CONFIG_VALUE_STATE_UP) == 0)
- return MODEL_VALUE_STATE_UP;
- if (strcmp(value, CONFIG_VALUE_STATE_DOWN) == 0)
- return MODEL_VALUE_STATE_DOWN;
- if (strcmp(value, CONFIG_VALUE_STATE_OFF) == 0)
- return MODEL_VALUE_STATE_OFF;
+ json_error_t error;
+ json_t *root;
+ int ret = EXIT_SUCCESS;
- return EXIT_FAILURE;
+ root = json_loadb(buf, strlen(buf), JSON_ALLOW_NUL, &error);
+
+ if (root) {
+ config_json(root, MODEL_LEVEL_INIT);
+ json_decref(root);
+ } else {
+ syslog(LOG_ERR, "Configuration error on line %d: %s", error.line, error.text);
+ ret = EXIT_FAILURE;
+ }
+
+ return ret;
}
-void add_dump_obj(json_t *obj, const char *name, char *value)
+static void add_dump_obj(json_t *obj, const char *name, char *value)
{
if (value == NULL)
return;
@@ -310,7 +310,8 @@ void add_dump_obj(json_t *obj, const char *name, char *value)
json_object_set_new(obj, name, json_string(value));
}
-void add_dump_list(json_t *obj, const char *objname, int model, struct list_head *head, char *name)
+static void add_dump_list(json_t *obj, const char *objname, int model,
+ struct list_head *head, char *name)
{
struct farm *f;
struct backend *b;
@@ -383,20 +384,6 @@ int config_print_farms(char **buf, char *name)
return EXIT_SUCCESS;
}
-int config_value_action(const char *value)
-{
- if (strcmp(value, CONFIG_VALUE_ACTION_STOP) == 0)
- return MODEL_ACTION_STOP;
- if (strcmp(value, CONFIG_VALUE_ACTION_DELETE) == 0)
- return MODEL_ACTION_DELETE;
- if (strcmp(value, CONFIG_VALUE_ACTION_START) == 0)
- return MODEL_ACTION_START;
- if (strcmp(value, CONFIG_VALUE_ACTION_RELOAD) == 0)
- return MODEL_ACTION_RELOAD;
-
- return MODEL_ACTION_NONE;
-}
-
int config_set_farm_action(const char *name, const char *value)
{
struct farm *f;
@@ -62,25 +62,6 @@ struct model_obj current_obj;
struct list_head farms;
int total_farms = 0;
-struct farm * model_create_farm(char *fname);
-struct backend * model_create_backend(struct farm *f, char *name);
-int delete_farm(struct farm *f);
-int delete_backends(struct farm *f);
-int delete_backend(struct farm *f, struct backend *b);
-int del_bck(struct backend *b);
-void model_print_backends(struct farm *f);
-int set_farm_attribute(struct configpair *cfgp);
-int set_backend_attribute(struct configpair *cfgp);
-int set_f_attribute(struct configpair *cfgp, struct farm *pf);
-int set_b_attribute(struct configpair *cfgp, struct backend *pb);
-int set_attr_string(char *src, char **dst);
-int bck_weight_update(struct configpair *cfgp, struct backend *b);
-int bck_priority_update(struct configpair *cfgp, struct backend *b);
-int bck_state_update(struct configpair *cfgp, struct backend *b);
-int farm_state_update(struct configpair *cfgp, struct farm *f);
-int is_srv_change(struct configpair *cfgp);
-
-
void model_init(void)
{
init_list_head(&farms);
@@ -96,7 +77,21 @@ int model_get_totalfarms(void)
return total_farms;
}
-struct farm * model_create_farm(char *name)
+static int set_attr_string(char *src, char **dst)
+{
+ *dst = (char *)malloc(strlen(src));
+
+ if (!*dst) {
+ syslog(LOG_ERR, "Attribute memory allocation error");
+ return EXIT_FAILURE;
+ }
+
+ sprintf(*dst, "%s", src);
+
+ return EXIT_SUCCESS;
+}
+
+static struct farm * model_create_farm(char *name)
{
struct farm *pfarm = (struct farm *)malloc(sizeof(struct farm));
if (!pfarm) {
@@ -132,7 +127,7 @@ struct farm * model_create_farm(char *name)
return pfarm;
}
-struct backend * model_create_backend(struct farm *f, char *name)
+static struct backend * model_create_backend(struct farm *f, char *name)
{
struct backend *pbck = (struct backend *)malloc(sizeof(struct backend));
if (!pbck) {
@@ -160,7 +155,40 @@ struct backend * model_create_backend(struct farm *f, char *name)
return pbck;
}
-int delete_farm(struct farm *pfarm)
+static int del_bck(struct backend *b)
+{
+ list_del(&b->list);
+ if (b->name)
+ free(b->name);
+ if (b->fqdn && strcmp(b->fqdn, "") != 0)
+ free(b->fqdn);
+ if (b->ipaddr && strcmp(b->ipaddr, "") != 0)
+ free(b->ipaddr);
+ if (b->ethaddr && strcmp(b->ethaddr, "") != 0)
+ free(b->ethaddr);
+ if (b->ports && strcmp(b->ports, "") != 0)
+ free(b->ports);
+
+ free(b);
+
+ return EXIT_SUCCESS;
+}
+
+static int delete_backends(struct farm *f)
+{
+ struct backend *pbck, *next;
+
+ list_for_each_entry_safe(pbck, next, &f->backends, list)
+ del_bck(pbck);
+
+ f->total_bcks = 0;
+ f->bcks_available = 0;
+ f->total_weight = 0;
+
+ return EXIT_SUCCESS;
+}
+
+static int delete_farm(struct farm *pfarm)
{
delete_backends(pfarm);
list_del(&pfarm->list);
@@ -186,21 +214,7 @@ int delete_farm(struct farm *pfarm)
return EXIT_SUCCESS;
}
-int delete_backends(struct farm *f)
-{
- struct backend *pbck, *next;
-
- list_for_each_entry_safe(pbck, next, &f->backends, list)
- del_bck(pbck);
-
- f->total_bcks = 0;
- f->bcks_available = 0;
- f->total_weight = 0;
-
- return EXIT_SUCCESS;
-}
-
-int delete_backend(struct farm *f, struct backend *pbck)
+static int delete_backend(struct farm *f, struct backend *pbck)
{
if (model_bck_is_available(f, pbck)) {
f->bcks_available--;
@@ -214,23 +228,30 @@ int delete_backend(struct farm *f, struct backend *pbck)
return EXIT_SUCCESS;
}
-int del_bck(struct backend *b)
+static void model_print_backends(struct farm *f)
{
- list_del(&b->list);
- if (b->name)
- free(b->name);
- if (b->fqdn && strcmp(b->fqdn, "") != 0)
- free(b->fqdn);
- if (b->ipaddr && strcmp(b->ipaddr, "") != 0)
- free(b->ipaddr);
- if (b->ethaddr && strcmp(b->ethaddr, "") != 0)
- free(b->ethaddr);
- if (b->ports && strcmp(b->ports, "") != 0)
- free(b->ports);
+ struct backend *b;
- free(b);
+ list_for_each_entry(b, &f->backends, list) {
+ syslog(LOG_DEBUG,"Model dump [backend] ");
+ syslog(LOG_DEBUG,"Model dump [name] %s", b->name);
- return EXIT_SUCCESS;
+ if (b->fqdn)
+ syslog(LOG_DEBUG,"Model dump [fqdn] %s", b->fqdn);
+
+ if (b->ipaddr)
+ syslog(LOG_DEBUG,"Model dump [iface] %s", b->ipaddr);
+
+ if (b->ethaddr)
+ syslog(LOG_DEBUG,"Model dump [ethaddr] %s", b->ethaddr);
+
+ if (b->ports)
+ syslog(LOG_DEBUG,"Model dump [ports] %s", b->ports);
+
+ syslog(LOG_DEBUG,"Model dump [weight] %d", b->weight);
+ syslog(LOG_DEBUG,"Model dump [priority] %d", b->priority);
+ syslog(LOG_DEBUG,"Model dump [state] %s", model_print_state(b->state));
+ }
}
void model_print_farms(void)
@@ -276,32 +297,6 @@ void model_print_farms(void)
}
}
-void model_print_backends(struct farm *f)
-{
- struct backend *b;
-
- list_for_each_entry(b, &f->backends, list) {
- syslog(LOG_DEBUG,"Model dump [backend] ");
- syslog(LOG_DEBUG,"Model dump [name] %s", b->name);
-
- if (b->fqdn)
- syslog(LOG_DEBUG,"Model dump [fqdn] %s", b->fqdn);
-
- if (b->ipaddr)
- syslog(LOG_DEBUG,"Model dump [iface] %s", b->ipaddr);
-
- if (b->ethaddr)
- syslog(LOG_DEBUG,"Model dump [ethaddr] %s", b->ethaddr);
-
- if (b->ports)
- syslog(LOG_DEBUG,"Model dump [ports] %s", b->ports);
-
- syslog(LOG_DEBUG,"Model dump [weight] %d", b->weight);
- syslog(LOG_DEBUG,"Model dump [priority] %d", b->priority);
- syslog(LOG_DEBUG,"Model dump [state] %s", model_print_state(b->state));
- }
-}
-
struct farm * model_lookup_farm(const char *name)
{
struct farm *f;
@@ -331,60 +326,95 @@ void print_pair(struct configpair *cfgp)
syslog(LOG_DEBUG,"pair: %d(level) %d(key) %s(value) %d(value)", cfgp->level, cfgp->key, cfgp->str_value, cfgp->int_value);
}
-int model_set_obj_attribute(struct configpair *cfgp)
+static int bck_weight_update(struct configpair *cfgp, struct backend *b)
{
- print_pair(cfgp);
+ int oldw = b->weight;
- switch (cfgp->level) {
- case MODEL_LEVEL_FARMS:
- set_farm_attribute(cfgp);
- break;
- case MODEL_LEVEL_BCKS:
- set_backend_attribute(cfgp);
- farm_action_update(current_obj.fptr, MODEL_ACTION_RELOAD);
- break;
- default:
- return EXIT_FAILURE;
+ b->weight = cfgp->int_value;
+
+ if (model_bck_is_available(current_obj.fptr, b))
+ current_obj.fptr->total_weight += (b->weight-oldw);
+
+ return EXIT_SUCCESS;
+}
+
+static int bck_priority_update(struct configpair *cfgp, struct backend *b)
+{
+ int oldp = b->priority;
+
+ if (model_bck_is_available(current_obj.fptr, b) &&
+ cfgp->int_value > current_obj.fptr->priority) {
+ current_obj.fptr->bcks_available--;
+ current_obj.fptr->total_weight -= b->weight;
+ }
+
+ else if (oldp > current_obj.fptr->priority &&
+ model_bck_is_available(current_obj.fptr, b)) {
+ current_obj.fptr->bcks_available++;
+ current_obj.fptr->total_weight += b->weight;
}
+ b->priority = cfgp->int_value;
+
return EXIT_SUCCESS;
}
-int set_farm_attribute(struct configpair *cfgp)
+static int bck_state_update(struct configpair *cfgp, struct backend *b)
{
- struct farm *pf;
- int restart;
+ int oldst = b->state;
- switch (cfgp->key) {
- case MODEL_KEY_NAME:
- pf = model_lookup_farm(cfgp->str_value);
- if (!pf) {
- pf = model_create_farm(cfgp->str_value);
- if (!pf)
- return EXIT_FAILURE;
- }
- current_obj.fptr = pf;
- break;
- default:
- if (!current_obj.fptr)
- return EXIT_FAILURE;
+ if (model_bck_is_available(current_obj.fptr, b) &&
+ cfgp->int_value != MODEL_VALUE_STATE_UP) {
+ current_obj.fptr->total_weight -= b->weight;
+ current_obj.fptr->bcks_available--;
+ }
- restart = is_srv_change(cfgp);
- if (restart && farm_action_update(current_obj.fptr, MODEL_ACTION_STOP))
- nft_rulerize();
+ else if (oldst != MODEL_VALUE_STATE_UP &&
+ model_bck_is_available(current_obj.fptr, b)) {
+ current_obj.fptr->total_weight += b->weight;
+ current_obj.fptr->bcks_available++;
+ }
- set_f_attribute(cfgp, current_obj.fptr);
+ b->state = cfgp->int_value;
- if (restart)
- farm_action_update(current_obj.fptr, MODEL_ACTION_START);
- else
- farm_action_update(current_obj.fptr, MODEL_ACTION_RELOAD);
+ return EXIT_SUCCESS;
+}
+
+static int set_b_attribute(struct configpair *cfgp, struct backend *pb)
+{
+ switch (cfgp->key) {
+ case MODEL_KEY_FQDN:
+ set_attr_string(cfgp->str_value, &pb->fqdn);
+ break;
+ case MODEL_KEY_IPADDR:
+ set_attr_string(cfgp->str_value, &pb->ipaddr);
+ break;
+ case MODEL_KEY_ETHADDR:
+ set_attr_string(cfgp->str_value, &pb->ethaddr);
+ break;
+ case MODEL_KEY_PORTS:
+ set_attr_string(cfgp->str_value, &pb->ports);
+ break;
+ case MODEL_KEY_WEIGHT:
+ bck_weight_update(cfgp, pb);
+ break;
+ case MODEL_KEY_PRIORITY:
+ bck_priority_update(cfgp, pb);
+ break;
+ case MODEL_KEY_STATE:
+ bck_state_update(cfgp, pb);
+ break;
+ case MODEL_KEY_ACTION:
+ bck_action_update(pb, cfgp->int_value);
+ break;
+ default:
+ return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-int set_backend_attribute(struct configpair *cfgp)
+static int set_backend_attribute(struct configpair *cfgp)
{
struct backend *pb;
@@ -411,7 +441,45 @@ int set_backend_attribute(struct configpair *cfgp)
return EXIT_SUCCESS;
}
-int set_f_attribute(struct configpair *cfgp, struct farm *pf)
+static int is_srv_change(struct configpair *cfgp)
+{
+ int key = cfgp->key;
+
+ switch (key) {
+ case MODEL_KEY_IFACE:
+ case MODEL_KEY_OFACE:
+ case MODEL_KEY_FAMILY:
+ case MODEL_KEY_ETHADDR:
+ case MODEL_KEY_VIRTADDR:
+ case MODEL_KEY_VIRTPORTS:
+ case MODEL_KEY_PROTO:
+ case MODEL_KEY_STATE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int farm_state_update(struct configpair *cfgp, struct farm *f)
+{
+ int oldst = f->state;
+
+ if (oldst != MODEL_VALUE_STATE_UP &&
+ cfgp->int_value == MODEL_VALUE_STATE_UP) {
+ farm_action_update(current_obj.fptr, MODEL_ACTION_START);
+ }
+
+ if (oldst == MODEL_VALUE_STATE_UP &&
+ cfgp->int_value != MODEL_VALUE_STATE_UP) {
+ farm_action_update(current_obj.fptr, MODEL_ACTION_STOP);
+ }
+
+ f->state = cfgp->int_value;
+
+ return EXIT_SUCCESS;
+}
+
+static int set_f_attribute(struct configpair *cfgp, struct farm *pf)
{
switch (cfgp->key) {
case MODEL_KEY_FQDN:
@@ -457,50 +525,56 @@ int set_f_attribute(struct configpair *cfgp, struct farm *pf)
return EXIT_SUCCESS;
}
-int set_b_attribute(struct configpair *cfgp, struct backend *pb)
+static int set_farm_attribute(struct configpair *cfgp)
{
+ struct farm *pf;
+ int restart;
+
switch (cfgp->key) {
- case MODEL_KEY_FQDN:
- set_attr_string(cfgp->str_value, &pb->fqdn);
- break;
- case MODEL_KEY_IPADDR:
- set_attr_string(cfgp->str_value, &pb->ipaddr);
- break;
- case MODEL_KEY_ETHADDR:
- set_attr_string(cfgp->str_value, &pb->ethaddr);
- break;
- case MODEL_KEY_PORTS:
- set_attr_string(cfgp->str_value, &pb->ports);
- break;
- case MODEL_KEY_WEIGHT:
- bck_weight_update(cfgp, pb);
- break;
- case MODEL_KEY_PRIORITY:
- bck_priority_update(cfgp, pb);
- break;
- case MODEL_KEY_STATE:
- bck_state_update(cfgp, pb);
- break;
- case MODEL_KEY_ACTION:
- bck_action_update(pb, cfgp->int_value);
+ case MODEL_KEY_NAME:
+ pf = model_lookup_farm(cfgp->str_value);
+ if (!pf) {
+ pf = model_create_farm(cfgp->str_value);
+ if (!pf)
+ return EXIT_FAILURE;
+ }
+ current_obj.fptr = pf;
break;
default:
- return EXIT_FAILURE;
+ if (!current_obj.fptr)
+ return EXIT_FAILURE;
+
+ restart = is_srv_change(cfgp);
+ if (restart && farm_action_update(current_obj.fptr, MODEL_ACTION_STOP))
+ nft_rulerize();
+
+ set_f_attribute(cfgp, current_obj.fptr);
+
+ if (restart)
+ farm_action_update(current_obj.fptr, MODEL_ACTION_START);
+ else
+ farm_action_update(current_obj.fptr, MODEL_ACTION_RELOAD);
}
return EXIT_SUCCESS;
}
-int set_attr_string(char *src, char **dst)
+int model_set_obj_attribute(struct configpair *cfgp)
{
- *dst = (char *)malloc(strlen(src));
+ print_pair(cfgp);
- if (!*dst) {
- syslog(LOG_ERR, "Attribute memory allocation error");
+ switch (cfgp->level) {
+ case MODEL_LEVEL_FARMS:
+ set_farm_attribute(cfgp);
+ break;
+ case MODEL_LEVEL_BCKS:
+ set_backend_attribute(cfgp);
+ farm_action_update(current_obj.fptr, MODEL_ACTION_RELOAD);
+ break;
+ default:
return EXIT_FAILURE;
}
- sprintf(*dst, "%s", src);
return EXIT_SUCCESS;
}
@@ -583,79 +657,6 @@ char * model_print_state(int state)
}
}
-int bck_weight_update(struct configpair *cfgp, struct backend *b)
-{
- int oldw = b->weight;
-
- b->weight = cfgp->int_value;
-
- if (model_bck_is_available(current_obj.fptr, b))
- current_obj.fptr->total_weight += (b->weight-oldw);
-
- return EXIT_SUCCESS;
-}
-
-int bck_priority_update(struct configpair *cfgp, struct backend *b)
-{
- int oldp = b->priority;
-
- if (model_bck_is_available(current_obj.fptr, b) &&
- cfgp->int_value > current_obj.fptr->priority) {
- current_obj.fptr->bcks_available--;
- current_obj.fptr->total_weight -= b->weight;
- }
-
- else if (oldp > current_obj.fptr->priority &&
- model_bck_is_available(current_obj.fptr, b)) {
- current_obj.fptr->bcks_available++;
- current_obj.fptr->total_weight += b->weight;
- }
-
- b->priority = cfgp->int_value;
-
- return EXIT_SUCCESS;
-}
-
-int bck_state_update(struct configpair *cfgp, struct backend *b)
-{
- int oldst = b->state;
-
- if (model_bck_is_available(current_obj.fptr, b) &&
- cfgp->int_value != MODEL_VALUE_STATE_UP) {
- current_obj.fptr->total_weight -= b->weight;
- current_obj.fptr->bcks_available--;
- }
-
- else if (oldst != MODEL_VALUE_STATE_UP &&
- model_bck_is_available(current_obj.fptr, b)) {
- current_obj.fptr->total_weight += b->weight;
- current_obj.fptr->bcks_available++;
- }
-
- b->state = cfgp->int_value;
-
- return EXIT_SUCCESS;
-}
-
-int farm_state_update(struct configpair *cfgp, struct farm *f)
-{
- int oldst = f->state;
-
- if (oldst != MODEL_VALUE_STATE_UP &&
- cfgp->int_value == MODEL_VALUE_STATE_UP) {
- farm_action_update(current_obj.fptr, MODEL_ACTION_START);
- }
-
- if (oldst == MODEL_VALUE_STATE_UP &&
- cfgp->int_value != MODEL_VALUE_STATE_UP) {
- farm_action_update(current_obj.fptr, MODEL_ACTION_STOP);
- }
-
- f->state = cfgp->int_value;
-
- return EXIT_SUCCESS;
-}
-
int model_bck_is_available(struct farm *f, struct backend *b)
{
return (b->state == MODEL_VALUE_STATE_UP) && (b->priority <= f->priority);
@@ -709,24 +710,3 @@ int backends_action_update(struct farm *f, int action)
return EXIT_SUCCESS;
}
-
-int is_srv_change(struct configpair *cfgp)
-{
- int key = cfgp->key;
-
- switch (key) {
- case MODEL_KEY_IFACE:
- case MODEL_KEY_OFACE:
- case MODEL_KEY_FAMILY:
- case MODEL_KEY_ETHADDR:
- case MODEL_KEY_VIRTADDR:
- case MODEL_KEY_VIRTPORTS:
- case MODEL_KEY_PROTO:
- case MODEL_KEY_STATE:
- return 1;
- default:
- return 0;
- }
-}
-
-
@@ -88,21 +88,18 @@ struct if_base_rule * ndv_base_rules[NFTLB_MAX_IFACES];
unsigned int n_ndv_base_rules = 0;
unsigned int nat_base_rules = 0;
-int exec_cmd(struct nft_ctx *ctx, char *cmd);
-int run_base(struct nft_ctx *ctx);
-void get_ports(const char *ptr, int *first, int *last);
-
-int isempty_buf(char *buf){
+static int isempty_buf(char *buf)
+{
return (buf[0] == 0);
}
-int exec_cmd(struct nft_ctx *ctx, char *cmd)
+static int exec_cmd(struct nft_ctx *ctx, char *cmd)
{
syslog(LOG_INFO, "Executing: nft << %s", cmd);
return nft_run_cmd_from_buffer(ctx, cmd, strlen(cmd));
}
-char * print_nft_service(int family, int proto)
+static char * print_nft_service(int family, int proto)
{
if (family == MODEL_VALUE_FAMILY_IPV6) {
switch (proto) {
@@ -129,7 +126,7 @@ char * print_nft_service(int family, int proto)
}
}
-char * print_nft_family(int family)
+static char * print_nft_family(int family)
{
switch (family) {
case MODEL_VALUE_FAMILY_IPV6:
@@ -139,7 +136,7 @@ char * print_nft_family(int family)
}
}
-char * print_nft_table_family(int family, int mode)
+static char * print_nft_table_family(int family, int mode)
{
if (mode == MODEL_VALUE_MODE_DSR)
return NFTLB_NETDEV_FAMILY;
@@ -149,7 +146,7 @@ char * print_nft_table_family(int family, int mode)
return NFTLB_IPV4_FAMILY;
}
-char * print_nft_protocol(int protocol)
+static char * print_nft_protocol(int protocol)
{
switch (protocol) {
case MODEL_VALUE_PROTO_UDP:
@@ -161,12 +158,12 @@ char * print_nft_protocol(int protocol)
}
}
-void get_ports(const char *ptr, int *first, int *last)
+static void get_ports(const char *ptr, int *first, int *last)
{
sscanf(ptr, "%d-%d[^,]", first, last);
}
-struct if_base_rule * get_ndv_base(char *ifname)
+static struct if_base_rule * get_ndv_base(char *ifname)
{
unsigned int i;
@@ -178,7 +175,7 @@ struct if_base_rule * get_ndv_base(char *ifname)
return NULL;
}
-struct if_base_rule * add_ndv_base(char *ifname)
+static struct if_base_rule * add_ndv_base(char *ifname)
{
struct if_base_rule *ifentry;
@@ -202,7 +199,7 @@ struct if_base_rule * add_ndv_base(char *ifname)
return ifentry;
}
-unsigned int get_rules_needed(int family, int protocol)
+static unsigned int get_rules_needed(int family, int protocol)
{
unsigned int ret = 0;
@@ -243,7 +240,7 @@ unsigned int get_rules_needed(int family, int protocol)
return ret;
}
-int run_base_ndv(struct nft_ctx *ctx, struct farm *f)
+static int run_base_ndv(struct nft_ctx *ctx, struct farm *f)
{
char buf[NFTLB_MAX_CMD] = { 0 };
struct if_base_rule *if_base;
@@ -317,7 +314,7 @@ int run_base_ndv(struct nft_ctx *ctx, struct farm *f)
return EXIT_SUCCESS;
}
-int run_base_nat(struct nft_ctx *ctx, struct farm *f)
+static int run_base_nat(struct nft_ctx *ctx, struct farm *f)
{
char buf[NFTLB_MAX_CMD] = { 0 };
unsigned int rules_needed = get_rules_needed(f->family, f->protocol);
@@ -392,7 +389,8 @@ int run_base_nat(struct nft_ctx *ctx, struct farm *f)
return EXIT_SUCCESS;
}
-int run_farm_rules(struct nft_ctx *ctx, struct farm *f, int family, int action)
+static int run_farm_rules(struct nft_ctx *ctx, struct farm *f, int family,
+ int action)
{
char buf[NFTLB_MAX_CMD] = { 0 };
struct backend *b;
@@ -485,7 +483,7 @@ next:
return EXIT_SUCCESS;
}
-int run_farm_snat(struct nft_ctx *ctx, struct farm *f, int family)
+static int run_farm_snat(struct nft_ctx *ctx, struct farm *f, int family)
{
char buf[NFTLB_MAX_CMD];
@@ -496,7 +494,7 @@ int run_farm_snat(struct nft_ctx *ctx, struct farm *f, int family)
}
-int run_farm(struct nft_ctx *ctx, struct farm *f, int action)
+static int run_farm(struct nft_ctx *ctx, struct farm *f, int action)
{
int ret = EXIT_SUCCESS;
@@ -522,7 +520,7 @@ int run_farm(struct nft_ctx *ctx, struct farm *f, int action)
return ret;
}
-int del_farm_rules(struct nft_ctx *ctx, struct farm *f, int family)
+static int del_farm_rules(struct nft_ctx *ctx, struct farm *f, int family)
{
char buf[NFTLB_MAX_CMD] = { 0 };
int ret = EXIT_SUCCESS;
@@ -557,7 +555,7 @@ next:
return ret;
}
-int del_farm(struct nft_ctx *ctx, struct farm *f)
+static int del_farm(struct nft_ctx *ctx, struct farm *f)
{
int ret = EXIT_SUCCESS;
@@ -75,14 +75,6 @@ const char * ws_str_responses[] = {
HTTP_PROTO "200 OK" HTTP_LINE_END,
};
-void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
-void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
-int get_request(char *buf, int *action, char **uri, char **content);
-int send_response(char **buf, int action, char *uri, char *content);
-int send_get_response(char **buf, char *uri);
-int send_post_response(char **buf, char *uri, char *content);
-int send_delete_response(char **buf, char *uri, char *content);
-
struct nftlb_server {
int clients;
char *key;
@@ -97,118 +89,158 @@ struct nftlb_server nftserver = {
.port = SRV_PORT_DEF,
};
-int server_init(void)
+static int auth_key(const char *recvkey)
{
- struct ev_loop *loop = ev_default_loop(0);
- int sd;
- struct sockaddr_storage addr;
- socklen_t addrlen = sizeof(addr);
- struct ev_io w_accept;
+ return (strcmp(nftserver.key, recvkey) == 0);
+}
- if (!nftserver.key)
- server_set_key(NULL);
+static int get_request(char *buf, int *action, char **uri, char **content)
+{
+ char straction[SRV_MAX_IDENT] = {0};
+ char strkey[SRV_MAX_IDENT] = {0};
+ char *ptr;
- printf("Key: %s\n", nftserver.key);
+ if ((ptr = strstr(buf, "Key: ")) == NULL)
+ return WS_HTTP_401;
- if ( (sd = socket(nftserver.family, SOCK_STREAM, 0)) < 0 ) {
- fprintf(stderr, "Server socket error\n");
- syslog(LOG_ERR, "Server socket error");
- return EXIT_FAILURE;
- }
+ sscanf(ptr, "Key: %199[^\r\n]", strkey);
- bzero(&addr, addrlen);
- addr.ss_family = nftserver.family;
- ((struct sockaddr_in *) &addr)->sin_port = htons(nftserver.port);
- if (nftserver.host == NULL)
- ((struct sockaddr_in *) &addr)->sin_addr.s_addr = SRV_HOST_DEF;
- else
- inet_aton(nftserver.host, &((struct sockaddr_in *) &addr)->sin_addr);
+ if (!auth_key(strkey))
+ return WS_HTTP_401;
- if (bind(sd, (struct sockaddr *) &addr, addrlen) != 0) {
- fprintf(stderr, "Server bind error\n");
- syslog(LOG_ERR, "Server bind error");
- return EXIT_FAILURE;
- }
+ sscanf(buf, "%199[^ ] %199[^ ] ", straction, *uri);
- if (listen(sd, 2) < 0) {
- fprintf(stderr, "Server listen error\n");
- syslog(LOG_ERR, "Server listen error");
- return EXIT_FAILURE;
+ if (strncmp(straction, STR_GET_ACTION, 3) == 0) {
+ *action = WS_GET_ACTION;
+ } else if (strncmp(straction, STR_POST_ACTION, 4) == 0) {
+ *action = WS_POST_ACTION;
+ } else if (strncmp(straction, STR_PUT_ACTION, 5) == 0) {
+ *action = WS_PUT_ACTION;
+ } else if (strncmp(straction, STR_DELETE_ACTION, 6) == 0) {
+ *action = WS_DELETE_ACTION;
+ } else {
+ return WS_HTTP_500;
}
- ev_io_init(&w_accept, accept_cb, sd, EV_READ);
- ev_io_start(loop, &w_accept);
+ if ((*action != WS_POST_ACTION) && (*action != WS_PUT_ACTION))
+ return HTTP_MIN_CONTINUE;
- while (1)
- ev_loop(loop, 0);
+ if ((*content = strstr(buf, "\r\n\r\n")))
+ *content += 4;
- return EXIT_SUCCESS;
+ return HTTP_MIN_CONTINUE;
}
-void server_set_host(char *host)
+static int send_get_response(char **buf, char *uri)
{
- nftserver.host = malloc(strlen(host));
- sprintf(nftserver.host, "%s", host);
-}
+ char farm[SRV_MAX_IDENT] = {0};
+ char farms[SRV_MAX_IDENT] = {0};
-void server_set_port(int port)
-{
- nftserver.port = port;
+ sscanf(uri, "/%199[^/]/%199[^/\n]", farms, farm);
+
+ if (strcmp(farms, CONFIG_KEY_FARMS) != 0)
+ return WS_HTTP_500;
+
+ if (config_print_farms(buf, farm) == EXIT_SUCCESS)
+ return WS_HTTP_200;
+ else
+ return WS_HTTP_500;
}
-void server_set_key(char *key)
+static int send_delete_response(char **buf, char *uri, char *content)
{
- int i;
+ char farm[SRV_MAX_IDENT] = {0};
+ char bck[SRV_MAX_IDENT] = {0};
+ char farms[SRV_MAX_IDENT] = {0};
+ char bcks[SRV_MAX_IDENT] = {0};
+ int ret;
- if (!nftserver.key)
- nftserver.key = (char *)malloc(SRV_MAX_IDENT);
+ sscanf(uri, "/%199[^/]/%199[^/]/%199[^/]/%199[^\n]", farms, farm, bcks, bck);
- if (!key) {
- srand((unsigned int) time(0) + getpid());
- for (i = 0; i < SRV_KEY_LENGTH; ++i)
- nftserver.key[i] = rand() % 94 + 33;
- nftserver.key[i] = '\0';
- } else
- snprintf(nftserver.key, SRV_MAX_IDENT, "%s", key);
-}
+ if (strcmp(farms, CONFIG_KEY_FARMS) != 0)
+ return WS_HTTP_500;
-void server_set_ipv6(void)
-{
- nftserver.family = AF_INET6;
-}
+ *buf = (char *)malloc(SRV_MAX_IDENT);
-int auth_key(const char *recvkey)
-{
- return (strcmp(nftserver.key, recvkey) == 0);
+ if (strcmp(bcks,CONFIG_KEY_BCKS) == 0) {
+ ret = config_set_backend_action(farm, bck, CONFIG_VALUE_ACTION_DELETE);
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error deleting backend");
+ goto delete_end;
+ }
+ ret = config_set_farm_action(farm, CONFIG_VALUE_ACTION_RELOAD);
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error reloading farm");
+ goto delete_end;
+ }
+ ret = nft_rulerize();
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error generating rules");
+ goto delete_end;
+ }
+ } else {
+ ret = config_set_farm_action(farm, CONFIG_VALUE_ACTION_STOP);
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error stopping farm");
+ goto delete_end;
+ }
+ ret = nft_rulerize();
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error generating rules");
+ goto delete_end;
+ }
+ config_set_farm_action(farm, CONFIG_VALUE_ACTION_DELETE);
+ if (ret != EXIT_SUCCESS) {
+ config_print_response(buf, "error deleting farm");
+ goto delete_end;
+ }
+ }
+
+ config_print_response(buf, "success");
+
+delete_end:
+ return WS_HTTP_200;
}
-void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
+static int send_post_response(char **buf, char *uri, char *content)
{
- struct sockaddr_storage client_addr;
- socklen_t addrlen = sizeof(client_addr);
- int client_sd;
- struct ev_io *w_client = (struct ev_io*) malloc(sizeof(struct ev_io));
+ if (strncmp(uri, "/farms", 6) != 0)
+ return WS_HTTP_500;
- if(EV_ERROR & revents) {
- syslog(LOG_ERR, "Server got an invalid event from client");
- return;
- }
+ *buf = (char *)malloc(SRV_MAX_IDENT);
- client_sd = accept(watcher->fd, (struct sockaddr *)&client_addr,
- &addrlen);
+ if (config_buffer(content) != EXIT_SUCCESS) {
+ config_print_response(buf, "error parsing buffer");
+ goto post_end;
+ }
- if (client_sd < 0) {
- syslog(LOG_ERR, "Server accept error");
- return;
+ if (nft_rulerize() != EXIT_SUCCESS) {
+ config_print_response(buf, "error generating rules");
+ goto post_end;
}
- syslog(LOG_DEBUG, "%d client(s) connected", ++nftserver.clients);
+ config_print_response(buf, "success");
- ev_io_init(w_client, read_cb, client_sd, EV_READ);
- ev_io_start(loop, w_client);
+post_end:
+ return WS_HTTP_200;
}
-void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
+static int send_response(char **buf, int action, char *uri, char *content)
+{
+ switch (action) {
+ case WS_GET_ACTION:
+ return send_get_response(buf, uri);
+ case WS_POST_ACTION:
+ case WS_PUT_ACTION:
+ return send_post_response(buf, uri, content);
+ case WS_DELETE_ACTION:
+ return send_delete_response(buf, uri, content);
+ default:
+ return -1;
+ }
+}
+
+static void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
char buffer[SRV_MAX_BUF] = {0};
char resheader[SRV_MAX_HEADER];
@@ -275,150 +307,108 @@ end:
return;
}
-int get_request(char *buf, int *action, char **uri, char **content)
+static void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
- char straction[SRV_MAX_IDENT] = {0};
- char strkey[SRV_MAX_IDENT] = {0};
- char *ptr;
-
- if ((ptr = strstr(buf, "Key: ")) == NULL)
- return WS_HTTP_401;
-
- sscanf(ptr, "Key: %199[^\r\n]", strkey);
+ struct sockaddr_storage client_addr;
+ socklen_t addrlen = sizeof(client_addr);
+ int client_sd;
+ struct ev_io *w_client = (struct ev_io*) malloc(sizeof(struct ev_io));
- if (!auth_key(strkey))
- return WS_HTTP_401;
+ if(EV_ERROR & revents) {
+ syslog(LOG_ERR, "Server got an invalid event from client");
+ return;
+ }
- sscanf(buf, "%199[^ ] %199[^ ] ", straction, *uri);
+ client_sd = accept(watcher->fd, (struct sockaddr *)&client_addr,
+ &addrlen);
- if (strncmp(straction, STR_GET_ACTION, 3) == 0) {
- *action = WS_GET_ACTION;
- } else if (strncmp(straction, STR_POST_ACTION, 4) == 0) {
- *action = WS_POST_ACTION;
- } else if (strncmp(straction, STR_PUT_ACTION, 5) == 0) {
- *action = WS_PUT_ACTION;
- } else if (strncmp(straction, STR_DELETE_ACTION, 6) == 0) {
- *action = WS_DELETE_ACTION;
- } else {
- return WS_HTTP_500;
+ if (client_sd < 0) {
+ syslog(LOG_ERR, "Server accept error");
+ return;
}
- if ((*action != WS_POST_ACTION) && (*action != WS_PUT_ACTION))
- return HTTP_MIN_CONTINUE;
-
- if ((*content = strstr(buf, "\r\n\r\n")))
- *content += 4;
+ syslog(LOG_DEBUG, "%d client(s) connected", ++nftserver.clients);
- return HTTP_MIN_CONTINUE;
+ ev_io_init(w_client, read_cb, client_sd, EV_READ);
+ ev_io_start(loop, w_client);
}
-int send_response(char **buf, int action, char *uri, char *content)
+int server_init(void)
{
- switch (action) {
- case WS_GET_ACTION:
- return send_get_response(buf, uri);
- case WS_POST_ACTION:
- case WS_PUT_ACTION:
- return send_post_response(buf, uri, content);
- case WS_DELETE_ACTION:
- return send_delete_response(buf, uri, content);
- default:
- return -1;
- }
-}
+ struct ev_loop *loop = ev_default_loop(0);
+ int sd;
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ struct ev_io w_accept;
-int send_get_response(char **buf, char *uri)
-{
- char farm[SRV_MAX_IDENT] = {0};
- char farms[SRV_MAX_IDENT] = {0};
+ if (!nftserver.key)
+ server_set_key(NULL);
- sscanf(uri, "/%199[^/]/%199[^/\n]", farms, farm);
+ printf("Key: %s\n", nftserver.key);
- if (strcmp(farms, CONFIG_KEY_FARMS) != 0)
- return WS_HTTP_500;
+ if ( (sd = socket(nftserver.family, SOCK_STREAM, 0)) < 0 ) {
+ fprintf(stderr, "Server socket error\n");
+ syslog(LOG_ERR, "Server socket error");
+ return EXIT_FAILURE;
+ }
- if (config_print_farms(buf, farm) == EXIT_SUCCESS)
- return WS_HTTP_200;
+ bzero(&addr, addrlen);
+ addr.ss_family = nftserver.family;
+ ((struct sockaddr_in *) &addr)->sin_port = htons(nftserver.port);
+ if (nftserver.host == NULL)
+ ((struct sockaddr_in *) &addr)->sin_addr.s_addr = SRV_HOST_DEF;
else
- return WS_HTTP_500;
-}
-
-int send_post_response(char **buf, char *uri, char *content)
-{
- if (strncmp(uri, "/farms", 6) != 0)
- return WS_HTTP_500;
-
- *buf = (char *)malloc(SRV_MAX_IDENT);
+ inet_aton(nftserver.host, &((struct sockaddr_in *) &addr)->sin_addr);
- if (config_buffer(content) != EXIT_SUCCESS) {
- config_print_response(buf, "error parsing buffer");
- goto post_end;
+ if (bind(sd, (struct sockaddr *) &addr, addrlen) != 0) {
+ fprintf(stderr, "Server bind error\n");
+ syslog(LOG_ERR, "Server bind error");
+ return EXIT_FAILURE;
}
- if (nft_rulerize() != EXIT_SUCCESS) {
- config_print_response(buf, "error generating rules");
- goto post_end;
+ if (listen(sd, 2) < 0) {
+ fprintf(stderr, "Server listen error\n");
+ syslog(LOG_ERR, "Server listen error");
+ return EXIT_FAILURE;
}
- config_print_response(buf, "success");
+ ev_io_init(&w_accept, accept_cb, sd, EV_READ);
+ ev_io_start(loop, &w_accept);
-post_end:
- return WS_HTTP_200;
+ while (1)
+ ev_loop(loop, 0);
+
+ return EXIT_SUCCESS;
}
-int send_delete_response(char **buf, char *uri, char *content)
+void server_set_host(char *host)
{
- char farm[SRV_MAX_IDENT] = {0};
- char bck[SRV_MAX_IDENT] = {0};
- char farms[SRV_MAX_IDENT] = {0};
- char bcks[SRV_MAX_IDENT] = {0};
- int ret;
-
- sscanf(uri, "/%199[^/]/%199[^/]/%199[^/]/%199[^\n]", farms, farm, bcks, bck);
-
- if (strcmp(farms, CONFIG_KEY_FARMS) != 0)
- return WS_HTTP_500;
+ nftserver.host = malloc(strlen(host));
+ sprintf(nftserver.host, "%s", host);
+}
- *buf = (char *)malloc(SRV_MAX_IDENT);
+void server_set_port(int port)
+{
+ nftserver.port = port;
+}
- if (strcmp(bcks,CONFIG_KEY_BCKS) == 0) {
- ret = config_set_backend_action(farm, bck, CONFIG_VALUE_ACTION_DELETE);
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error deleting backend");
- goto delete_end;
- }
- ret = config_set_farm_action(farm, CONFIG_VALUE_ACTION_RELOAD);
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error reloading farm");
- goto delete_end;
- }
- ret = nft_rulerize();
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error generating rules");
- goto delete_end;
- }
- } else {
- ret = config_set_farm_action(farm, CONFIG_VALUE_ACTION_STOP);
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error stopping farm");
- goto delete_end;
- }
- ret = nft_rulerize();
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error generating rules");
- goto delete_end;
- }
- config_set_farm_action(farm, CONFIG_VALUE_ACTION_DELETE);
- if (ret != EXIT_SUCCESS) {
- config_print_response(buf, "error deleting farm");
- goto delete_end;
- }
- }
+void server_set_key(char *key)
+{
+ int i;
- config_print_response(buf, "success");
+ if (!nftserver.key)
+ nftserver.key = (char *)malloc(SRV_MAX_IDENT);
-delete_end:
- return WS_HTTP_200;
+ if (!key) {
+ srand((unsigned int) time(0) + getpid());
+ for (i = 0; i < SRV_KEY_LENGTH; ++i)
+ nftserver.key[i] = rand() % 94 + 33;
+ nftserver.key[i] = '\0';
+ } else
+ snprintf(nftserver.key, SRV_MAX_IDENT, "%s", key);
}
-
+void server_set_ipv6(void)
+{
+ nftserver.family = AF_INET6;
+}
Remove all forward declarations, they are unnecessary and they are also missing the static keyword. Enable -Wmissing-prototypes to spot functions that should be declared static. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- Make_global.am | 1 + src/config.c | 355 +++++++++++++++++++++----------------------- src/model.c | 458 +++++++++++++++++++++++++++------------------------------ src/nft.c | 40 +++-- src/server.c | 398 ++++++++++++++++++++++++------------------------- 5 files changed, 604 insertions(+), 648 deletions(-)