reports quorum status at every legion changes

This commit is contained in:
Roberto De Ioris
2012-12-29 18:18:39 +01:00
parent 35557de982
commit badeafef59
+258 -231
View File
@@ -39,7 +39,7 @@ extern struct uwsgi_server uwsgi;
struct uwsgi_legion *uwsgi_legion_get_by_socket(int fd) {
struct uwsgi_legion *ul = uwsgi.legions;
while(ul) {
while (ul) {
if (ul->socket == fd) {
return ul;
}
@@ -50,15 +50,15 @@ struct uwsgi_legion *uwsgi_legion_get_by_socket(int fd) {
}
struct uwsgi_legion *uwsgi_legion_get_by_name(char *name) {
struct uwsgi_legion *ul = uwsgi.legions;
while(ul) {
if (!strcmp(name, ul->legion)) {
return ul;
}
ul = ul->next;
}
struct uwsgi_legion *ul = uwsgi.legions;
while (ul) {
if (!strcmp(name, ul->legion)) {
return ul;
}
ul = ul->next;
}
return NULL;
return NULL;
}
@@ -68,16 +68,16 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen
if (!uwsgi_strncmp(key, keylen, "legion", 6)) {
ul->legion = value;
ul->legion_len = vallen;
}
}
else if (!uwsgi_strncmp(key, keylen, "valor", 5)) {
ul->valor = uwsgi_str_num(value, vallen);
}
else if (!uwsgi_strncmp(key, keylen, "name", 4)) {
ul->name = value;
ul->name = value;
ul->name_len = vallen;
}
else if (!uwsgi_strncmp(key, keylen, "pid", 3)) {
ul->pid = uwsgi_str_num(value, vallen);
ul->pid = uwsgi_str_num(value, vallen);
}
else if (!uwsgi_strncmp(key, keylen, "uuid", 4)) {
if (vallen == 36) {
@@ -85,7 +85,7 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen
}
}
else if (!uwsgi_strncmp(key, keylen, "lord_valor", 10)) {
ul->lord_valor = uwsgi_str_num(value, vallen);
ul->lord_valor = uwsgi_str_num(value, vallen);
}
else if (!uwsgi_strncmp(key, keylen, "lord_uuid", 9)) {
if (vallen == 36) {
@@ -97,8 +97,9 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen
struct uwsgi_legion_node *uwsgi_legion_add_node(struct uwsgi_legion *ul, uint16_t valor, char *name, uint16_t name_len, char *uuid) {
struct uwsgi_legion_node *node = uwsgi_calloc(sizeof(struct uwsgi_legion_node));
if (!name_len) goto error;
node->name = uwsgi_calloc(name_len);
if (!name_len)
goto error;
node->name = uwsgi_calloc(name_len);
node->name_len = name_len;
memcpy(node->name, name, name_len);
node->valor = valor;
@@ -117,7 +118,7 @@ struct uwsgi_legion_node *uwsgi_legion_add_node(struct uwsgi_legion *ul, uint16_
return node;
error:
free(node);
return NULL;
@@ -141,7 +142,7 @@ void uwsgi_legion_remove_node(struct uwsgi_legion *ul, struct uwsgi_legion_node
if (node->next) {
node->next->prev = node->prev;
}
if (node->name_len) {
free(node->name);
}
@@ -155,11 +156,15 @@ void uwsgi_legion_remove_node(struct uwsgi_legion *ul, struct uwsgi_legion_node
struct uwsgi_legion_node *uwsgi_legion_get_node(struct uwsgi_legion *ul, uint64_t valor, char *name, uint16_t name_len, char *uuid) {
struct uwsgi_legion_node *nodes = ul->nodes_head;
while(nodes) {
if (valor != nodes->valor) goto next;
if (name_len != nodes->name_len) goto next;
if (memcmp(nodes->name, name, name_len)) goto next;
if (memcmp(nodes->uuid, uuid, 36)) goto next;
while (nodes) {
if (valor != nodes->valor)
goto next;
if (name_len != nodes->name_len)
goto next;
if (memcmp(nodes->name, name, name_len))
goto next;
if (memcmp(nodes->uuid, uuid, 36))
goto next;
return nodes;
next:
nodes = nodes->next;
@@ -170,11 +175,11 @@ next:
static void legions_check_nodes() {
struct uwsgi_legion *legion = uwsgi.legions;
while(legion) {
while (legion) {
time_t now = uwsgi_now();
struct uwsgi_legion_node *node = legion->nodes_head;
while(node) {
while (node) {
if (now - node->last_seen > uwsgi.legion_tolerance) {
struct uwsgi_legion_node *tmp_node = node;
@@ -192,86 +197,92 @@ static void legions_check_nodes() {
struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *);
static void legions_report_quorum(struct uwsgi_legion *ul, uint64_t best_valor, char *best_uuid) {
struct uwsgi_legion_node *nodes = ul->nodes_head;
uwsgi_log("\n[uwsgi-legion] --- WE HAVE QUORUM FOR LEGION %s !!! (valor: %llu uuid: %.*s) ---\n", ul->legion, best_valor, 36, best_uuid);
while (nodes) {
uwsgi_log("[uwsgi-legion-node] node: %.*s valor: %llu uuid: %.*s last_seen: %d vote_valor: %llu vote_uuid: %.*s\n", nodes->name_len, nodes->name, nodes->valor, 36, nodes->uuid, nodes->last_seen, nodes->lord_valor, 36, nodes->lord_uuid);
nodes = nodes->next;
}
uwsgi_log("[uwsgi-legion] --- END OF QUORUM REPORT ---\n\n");
}
static void legions_check_nodes_step2() {
struct uwsgi_legion *ul = uwsgi.legions;
while(ul) {
while (ul) {
// ok now we can check the status of the lord
int i_am_the_best = 0;
uint64_t best_valor = 0;
char best_uuid[36];
struct uwsgi_legion_node *node = uwsgi_legion_get_lord(ul);
if (node) {
// a node is the best candidate
best_valor = node->valor;
memcpy(best_uuid, node->uuid, 36);
}
else {
// no potential Lord is available, i will propose myself
best_valor = ul->valor;
memcpy(best_uuid, ul->uuid, 36);
i_am_the_best = 1;
}
int i_am_the_best = 0;
uint64_t best_valor = 0;
char best_uuid[36];
struct uwsgi_legion_node *node = uwsgi_legion_get_lord(ul);
if (node) {
// a node is the best candidate
best_valor = node->valor;
memcpy(best_uuid, node->uuid, 36);
}
else {
// no potential Lord is available, i will propose myself
best_valor = ul->valor;
memcpy(best_uuid, ul->uuid, 36);
i_am_the_best = 1;
}
uwsgi_log("best NODE: %llu %.*s\n", best_valor, 36, best_uuid);
// ... ok let's see if all of the nodes agree on the lord
// ... but first check if i am not alone...
int have_quorum = 0;
if (!ul->nodes_head) {
have_quorum = 1;
}
else {
struct uwsgi_legion_node *nodes = ul->nodes_head;
uwsgi_log("\n--- legion nodes ---\n");
while(nodes) {
uwsgi_log("%llu %.*s %.*s %d\n", nodes->valor, nodes->name_len, nodes->name, 36, nodes->uuid, nodes->last_seen);
if (nodes->lord_valor != best_valor) {
have_quorum = 0;
break;
}
if (memcmp(nodes->lord_uuid, best_uuid, 36)) {
have_quorum = 0;
break;
}
have_quorum++;
nodes = nodes->next;
}
uwsgi_log("--- end of legion nodes ---\n\n");
}
if (have_quorum) {
uwsgi_log("WE HAVE QUORUM FOR LEGION %s %llu !!!!\n", ul->legion, best_valor);
if (i_am_the_best) {
if (!ul->i_am_the_lord) {
uwsgi_log("[uwsgi-legion] i am now the Lord of the Legion %s\n", ul->legion);
// triggering lord hooks
struct uwsgi_string_list *usl = ul->lord_hooks;
while(usl) {
int ret = uwsgi_legion_action_call("lord", ul, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, lord hook returned: %d\n", ret);
}
usl = usl->next;
}
ul->i_am_the_lord = uwsgi_now();
}
// ... ok let's see if all of the nodes agree on the lord
// ... but first check if i am not alone...
int have_quorum = 0;
if (!ul->nodes_head) {
have_quorum = 1;
}
else {
struct uwsgi_legion_node *nodes = ul->nodes_head;
while (nodes) {
if (nodes->lord_valor != best_valor) {
have_quorum = 0;
break;
}
else {
if (ul->i_am_the_lord) {
uwsgi_log("[uwsgi-legion] a new Lord (valor: %llu uuid: %.*s) raised for Legion %s...\n", ul->lord_valor, 36, ul->lord_uuid, ul->legion);
// no more lord, trigger unlord hooks
struct uwsgi_string_list *usl = ul->unlord_hooks;
while(usl) {
int ret = uwsgi_legion_action_call("unlord", ul, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, unlord hook returned: %d\n", ret);
}
usl = usl->next;
}
ul->i_am_the_lord = 0;
}
if (memcmp(nodes->lord_uuid, best_uuid, 36)) {
have_quorum = 0;
break;
}
}
have_quorum++;
nodes = nodes->next;
}
}
if (have_quorum) {
if (i_am_the_best) {
if (!ul->i_am_the_lord) {
legions_report_quorum(ul, best_valor, best_uuid);
uwsgi_log("[uwsgi-legion] i am now the Lord of the Legion %s\n", ul->legion);
// triggering lord hooks
struct uwsgi_string_list *usl = ul->lord_hooks;
while (usl) {
int ret = uwsgi_legion_action_call("lord", ul, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, lord hook returned: %d\n", ret);
}
usl = usl->next;
}
ul->i_am_the_lord = uwsgi_now();
}
}
else {
if (ul->i_am_the_lord) {
legions_report_quorum(ul, best_valor, best_uuid);
uwsgi_log("[uwsgi-legion] a new Lord (valor: %llu uuid: %.*s) raised for Legion %s...\n", ul->lord_valor, 36, ul->lord_uuid, ul->legion);
// no more lord, trigger unlord hooks
struct uwsgi_string_list *usl = ul->unlord_hooks;
while (usl) {
int ret = uwsgi_legion_action_call("unlord", ul, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, unlord hook returned: %d\n", ret);
}
usl = usl->next;
}
ul->i_am_the_lord = 0;
}
}
}
ul = ul->next;
}
@@ -288,7 +299,7 @@ struct uwsgi_legion_node *uwsgi_legion_get_lord(struct uwsgi_legion *ul) {
struct uwsgi_legion_node *best_node = NULL;
struct uwsgi_legion_node *nodes = ul->nodes_head;
while(nodes) {
while (nodes) {
if (nodes->valor > best_valor) {
best_node = nodes;
best_valor = nodes->valor;
@@ -316,15 +327,17 @@ static void *legion_loop(void *foobar) {
time_t last_round = uwsgi_now();
unsigned char *crypted_buf = uwsgi_malloc(UMAX16-EVP_MAX_BLOCK_LENGTH-4);
unsigned char *crypted_buf = uwsgi_malloc(UMAX16 - EVP_MAX_BLOCK_LENGTH - 4);
unsigned char *clear_buf = uwsgi_malloc(UMAX16);
struct uwsgi_legion legion_msg;
if (!uwsgi.legion_freq) uwsgi.legion_freq = 3;
if (!uwsgi.legion_tolerance) uwsgi.legion_tolerance = 15;
if (!uwsgi.legion_freq)
uwsgi.legion_freq = 3;
if (!uwsgi.legion_tolerance)
uwsgi.legion_tolerance = 15;
for(;;) {
for (;;) {
int timeout = uwsgi.legion_freq;
time_t now = uwsgi_now();
if (now > last_round) {
@@ -336,12 +349,12 @@ static void *legion_loop(void *foobar) {
last_round = now;
// wait for event
int interesting_fd = -1;
int rlen = event_queue_wait(uwsgi.legion_queue, timeout, &interesting_fd);
int rlen = event_queue_wait(uwsgi.legion_queue, timeout, &interesting_fd);
now = uwsgi_now();
if (timeout == 0 || rlen == 0 || (now - last_round) >= timeout) {
struct uwsgi_legion *legions = uwsgi.legions;
while(legions) {
while (legions) {
uwsgi_legion_announce(legions);
legions = legions->next;
}
@@ -353,9 +366,10 @@ static void *legion_loop(void *foobar) {
if (rlen > 0) {
struct uwsgi_legion *ul = uwsgi_legion_get_by_socket(interesting_fd);
if (!ul) continue;
if (!ul)
continue;
// ensure the first 4 bytes are valid
ssize_t len = read(ul->socket, crypted_buf, (UMAX16-EVP_MAX_BLOCK_LENGTH-4));
ssize_t len = read(ul->socket, crypted_buf, (UMAX16 - EVP_MAX_BLOCK_LENGTH - 4));
if (len < 0) {
uwsgi_error("[uwsgi-legion] read()");
continue;
@@ -369,7 +383,7 @@ static void *legion_loop(void *foobar) {
if (uh->modifier1 != 109) {
uwsgi_log("[uwsgi-legion] invalid modifier1");
continue;
continue;
}
int d_len = 0;
@@ -378,18 +392,18 @@ static void *legion_loop(void *foobar) {
if (EVP_DecryptInit_ex(ul->decrypt_ctx, NULL, NULL, NULL, NULL) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_DecryptInit_ex()");
continue;
}
}
if (EVP_DecryptUpdate(ul->decrypt_ctx, clear_buf, &d_len, crypted_buf+4, len-4) <= 0) {
if (EVP_DecryptUpdate(ul->decrypt_ctx, clear_buf, &d_len, crypted_buf + 4, len - 4) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_DecryptUpdate()");
continue;
}
if (EVP_DecryptFinal_ex(ul->decrypt_ctx, clear_buf + d_len, &d2_len) <= 0) {
ERR_print_errors_fp(stderr);
uwsgi_log("[uwsgi-legion] EVP_DecryptFinal_ex()\n");
continue;
}
uwsgi_log("[uwsgi-legion] EVP_DecryptFinal_ex()\n");
continue;
}
d_len += d2_len;
@@ -400,7 +414,7 @@ static void *legion_loop(void *foobar) {
// parse packet
memset(&legion_msg, 0, sizeof(struct uwsgi_legion));
if (uwsgi_hooked_parse((char *)clear_buf, d_len, uwsgi_parse_legion, &legion_msg)) {
if (uwsgi_hooked_parse((char *) clear_buf, d_len, uwsgi_parse_legion, &legion_msg)) {
uwsgi_log("[uwsgi-legion] invalid packet\n");
continue;
}
@@ -426,6 +440,7 @@ static void *legion_loop(void *foobar) {
if (!node) {
// add the new node
node = uwsgi_legion_add_node(ul, legion_msg.valor, legion_msg.name, legion_msg.name_len, legion_msg.uuid);
uwsgi_log("[uwsgi-legion] node: %.*s valor: %llu uuid: %.*s joined Legion %s\n", node->name_len, node->name, node->valor, 36, node->uuid, ul->legion);
}
node->last_seen = uwsgi_now();
@@ -470,13 +485,13 @@ static void *legion_loop(void *foobar) {
int uwsgi_legion_action_call(char *phase, struct uwsgi_legion *ul, struct uwsgi_string_list *usl) {
struct uwsgi_legion_action *ula = uwsgi_legion_action_get(usl->custom_ptr);
if (!ula) {
if (!ula) {
uwsgi_log("[uwsgi-legion] ERROR unable to find legion_action \"%s\"\n", (char *) usl->custom_ptr);
return -1;
}
uwsgi_log("[uwsgi-legion] (phase: %s legion: %s) calling %s\n", phase, ul->legion, usl->value);
return ula->func(ul, usl->value+usl->custom);
return ula->func(ul, usl->value + usl->custom);
}
static int legion_action_cmd(struct uwsgi_legion *ul, char *arg) {
@@ -486,14 +501,15 @@ static int legion_action_cmd(struct uwsgi_legion *ul, char *arg) {
void uwsgi_start_legions() {
pthread_t legion_loop_t;
if (!uwsgi.legions) return;
if (!uwsgi.legions)
return;
// register embedded actions
uwsgi_legion_action_register("cmd", legion_action_cmd);
uwsgi.legion_queue = event_queue_init();
struct uwsgi_legion *legion = uwsgi.legions;
while(legion) {
while (legion) {
char *colon = strchr(legion->addr, ':');
if (colon) {
legion->socket = bind_to_udp(legion->addr, 0, 0);
@@ -509,7 +525,7 @@ void uwsgi_start_legions() {
legion->pid = uwsgi.mypid;
uwsgi_uuid(legion->uuid);
struct uwsgi_string_list *usl = legion->setup_hooks;
while(usl) {
while (usl) {
int ret = uwsgi_legion_action_call("setup", legion, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, setup hook returned: %d\n", ret);
@@ -519,19 +535,19 @@ void uwsgi_start_legions() {
legion = legion->next;
}
if (pthread_create(&legion_loop_t, NULL, legion_loop, NULL)) {
uwsgi_error("pthread_create()");
uwsgi_log("unable to run the legion server !!!\n");
}
else {
uwsgi_log("legion manager thread enabled\n");
}
if (pthread_create(&legion_loop_t, NULL, legion_loop, NULL)) {
uwsgi_error("pthread_create()");
uwsgi_log("unable to run the legion server !!!\n");
}
else {
uwsgi_log("legion manager thread enabled\n");
}
}
void uwsgi_legion_add(struct uwsgi_legion *ul) {
struct uwsgi_legion *old_legion=NULL,*legion = uwsgi.legions;
while(legion) {
struct uwsgi_legion *old_legion = NULL, *legion = uwsgi.legions;
while (legion) {
old_legion = legion;
legion = legion->next;
}
@@ -547,46 +563,55 @@ void uwsgi_legion_add(struct uwsgi_legion *ul) {
int uwsgi_legion_announce(struct uwsgi_legion *ul) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
if (uwsgi_buffer_append_keyval(ub, "legion", 6, ul->legion, ul->legion_len)) goto err;
if (uwsgi_buffer_append_keynum(ub, "valor", 5, ul->valor)) goto err;
if (uwsgi_buffer_append_keynum(ub, "unix", 4, uwsgi_now())) goto err;
if (uwsgi_buffer_append_keynum(ub, "lord", 4, ul->i_am_the_lord ? ul->i_am_the_lord : 0)) goto err;
if (uwsgi_buffer_append_keyval(ub, "name", 4, uwsgi.hostname, uwsgi.hostname_len)) goto err;
if (uwsgi_buffer_append_keynum(ub, "pid", 3, ul->pid)) goto err;
if (uwsgi_buffer_append_keyval(ub, "uuid", 4, ul->uuid, 36)) goto err;
if (uwsgi_buffer_append_keynum(ub, "lord_valor", 10, ul->lord_valor)) goto err;
if (uwsgi_buffer_append_keyval(ub, "lord_uuid", 9, ul->lord_uuid, 36)) goto err;
if (uwsgi_buffer_append_keyval(ub, "legion", 6, ul->legion, ul->legion_len))
goto err;
if (uwsgi_buffer_append_keynum(ub, "valor", 5, ul->valor))
goto err;
if (uwsgi_buffer_append_keynum(ub, "unix", 4, uwsgi_now()))
goto err;
if (uwsgi_buffer_append_keynum(ub, "lord", 4, ul->i_am_the_lord ? ul->i_am_the_lord : 0))
goto err;
if (uwsgi_buffer_append_keyval(ub, "name", 4, uwsgi.hostname, uwsgi.hostname_len))
goto err;
if (uwsgi_buffer_append_keynum(ub, "pid", 3, ul->pid))
goto err;
if (uwsgi_buffer_append_keyval(ub, "uuid", 4, ul->uuid, 36))
goto err;
if (uwsgi_buffer_append_keynum(ub, "lord_valor", 10, ul->lord_valor))
goto err;
if (uwsgi_buffer_append_keyval(ub, "lord_uuid", 9, ul->lord_uuid, 36))
goto err;
#ifdef UWSGI_UUID
#endif
unsigned char *encrypted = uwsgi_malloc(ub->pos + 4 + EVP_MAX_BLOCK_LENGTH);
if (EVP_EncryptInit_ex(ul->encrypt_ctx, NULL, NULL, NULL, NULL) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_EncryptInit_ex()");
uwsgi_error("[uwsgi-legion] EVP_EncryptInit_ex()");
goto err;
}
int e_len = 0;
if (EVP_EncryptUpdate(ul->encrypt_ctx, encrypted+4, &e_len, (unsigned char *)ub->buf, ub->pos) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_EncryptUpdate()");
if (EVP_EncryptUpdate(ul->encrypt_ctx, encrypted + 4, &e_len, (unsigned char *) ub->buf, ub->pos) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_EncryptUpdate()");
goto err;
}
int tmplen = 0;
if (EVP_EncryptFinal_ex(ul->encrypt_ctx, encrypted+4+e_len, &tmplen) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_EncryptFinal_ex()");
goto err;
}
int tmplen = 0;
if (EVP_EncryptFinal_ex(ul->encrypt_ctx, encrypted + 4 + e_len, &tmplen) <= 0) {
uwsgi_error("[uwsgi-legion] EVP_EncryptFinal_ex()");
goto err;
}
e_len += tmplen;
uint16_t pktsize = ub->pos;
encrypted[0] = 109;
encrypted[1] = (unsigned char) (pktsize & 0xff);
encrypted[2] = (unsigned char) ((pktsize >> 8) & 0xff);
encrypted[2] = (unsigned char) ((pktsize >> 8) & 0xff);
encrypted[3] = 0;
struct uwsgi_string_list *usl = ul->nodes;
while(usl) {
while (usl) {
if (sendto(ul->socket, encrypted, e_len + 4, 0, usl->custom_ptr, usl->custom) != e_len + 4) {
uwsgi_error("[uwsgi-legion] sendto()");
}
@@ -606,11 +631,11 @@ void uwsgi_opt_legion_node(char *opt, char *value, void *foobar) {
char *legion = uwsgi_str(value);
char *space = strchr(legion, ' ');
if (!space) {
uwsgi_log("invalid legion-node syntax, must be <legion> <addr>\n");
exit(1);
}
*space = 0;
if (!space) {
uwsgi_log("invalid legion-node syntax, must be <legion> <addr>\n");
exit(1);
}
*space = 0;
struct uwsgi_legion *ul = uwsgi_legion_get_by_name(legion);
if (!ul) {
@@ -618,117 +643,118 @@ void uwsgi_opt_legion_node(char *opt, char *value, void *foobar) {
exit(1);
}
struct uwsgi_string_list *usl = uwsgi_string_new_list(&ul->nodes, space+1);
struct uwsgi_string_list *usl = uwsgi_string_new_list(&ul->nodes, space + 1);
char *port = strchr(usl->value, ':');
if (!port) {
uwsgi_log("[uwsgi-legion] invalid udp address: %s\n", usl->value);
exit(1);
}
// no need to zero the memory, socket_to_in_addr will do that
struct sockaddr_in *sin = uwsgi_malloc(sizeof(struct sockaddr_in));
usl->custom = socket_to_in_addr(usl->value, port, 0, sin);
usl->custom_ptr = sin;
if (!port) {
uwsgi_log("[uwsgi-legion] invalid udp address: %s\n", usl->value);
exit(1);
}
// no need to zero the memory, socket_to_in_addr will do that
struct sockaddr_in *sin = uwsgi_malloc(sizeof(struct sockaddr_in));
usl->custom = socket_to_in_addr(usl->value, port, 0, sin);
usl->custom_ptr = sin;
}
void uwsgi_opt_legion_hook(char *opt, char *value, void *foobar) {
char *legion = uwsgi_str(value);
char *legion = uwsgi_str(value);
char *space = strchr(legion, ' ');
if (!space) {
uwsgi_log("invalid %s syntax, must be <legion> <action>\n", opt);
exit(1);
}
*space = 0;
char *space = strchr(legion, ' ');
if (!space) {
uwsgi_log("invalid %s syntax, must be <legion> <action>\n", opt);
exit(1);
}
*space = 0;
struct uwsgi_legion *ul = uwsgi_legion_get_by_name(legion);
if (!ul) {
uwsgi_log("unknown legion: %s\n", legion);
exit(1);
}
struct uwsgi_legion *ul = uwsgi_legion_get_by_name(legion);
if (!ul) {
uwsgi_log("unknown legion: %s\n", legion);
exit(1);
}
struct uwsgi_string_list *usl = NULL;
struct uwsgi_string_list *usl = NULL;
if (!strcmp(opt, "legion-lord")) {
usl = uwsgi_string_new_list(&ul->lord_hooks, space+1);
usl = uwsgi_string_new_list(&ul->lord_hooks, space + 1);
}
else if (!strcmp(opt, "legion-unlord")) {
usl = uwsgi_string_new_list(&ul->unlord_hooks, space+1);
usl = uwsgi_string_new_list(&ul->unlord_hooks, space + 1);
}
else if (!strcmp(opt, "legion-setup")) {
usl = uwsgi_string_new_list(&ul->setup_hooks, space+1);
usl = uwsgi_string_new_list(&ul->setup_hooks, space + 1);
}
else if (!strcmp(opt, "legion-death")) {
usl = uwsgi_string_new_list(&ul->death_hooks, space+1);
usl = uwsgi_string_new_list(&ul->death_hooks, space + 1);
}
if (!usl) return;
if (!usl)
return;
char *port = strchr(usl->value, ':');
if (!port) {
uwsgi_log("[uwsgi-legion] invalid %s action: %s\n", opt, usl->value);
exit(1);
}
char *port = strchr(usl->value, ':');
if (!port) {
uwsgi_log("[uwsgi-legion] invalid %s action: %s\n", opt, usl->value);
exit(1);
}
// pointer to action plugin
usl->custom_ptr = uwsgi_concat2n(usl->value, port-usl->value, "", 0);
usl->custom_ptr = uwsgi_concat2n(usl->value, port - usl->value, "", 0);
// add that to check the plugin value
usl->custom = port-usl->value+1;
usl->custom = port - usl->value + 1;
}
void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
// legion addr valor algo:secret
char *legion = uwsgi_str(value);
char *legion = uwsgi_str(value);
char *space = strchr(legion, ' ');
if (!space) {
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
*space = 0;
char *addr = space+1;
char *addr = space + 1;
space = strchr(addr, ' ');
if (!space) {
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
*space = 0;
char *valor = space+1;
char *valor = space + 1;
space = strchr(valor, ' ');
if (!space) {
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
*space = 0;
char *algo_secret = space+1;
char *algo_secret = space + 1;
char *colon = strchr(algo_secret, ':');
if (!colon) {
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
uwsgi_log("invalid legion syntax, must be <legion> <addr> <valor> <algo:secret>\n");
exit(1);
}
*colon = 0;
char *secret = colon+1;
char *secret = colon + 1;
if (!uwsgi.ssl_initialized) {
uwsgi_ssl_init();
}
uwsgi_ssl_init();
}
EVP_CIPHER_CTX *ctx = uwsgi_malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(ctx);
EVP_CIPHER_CTX_init(ctx);
const EVP_CIPHER *cipher = EVP_get_cipherbyname(algo_secret);
const EVP_CIPHER *cipher = EVP_get_cipherbyname(algo_secret);
if (!cipher) {
uwsgi_log("[uwsgi-legion] unable to find algorithm/cipher %s\n", algo_secret);
uwsgi_log("[uwsgi-legion] unable to find algorithm/cipher %s\n", algo_secret);
exit(1);
}
int cipher_len = EVP_CIPHER_key_length(cipher);
size_t s_len = strlen(secret);
if ((unsigned int)cipher_len > s_len) {
if ((unsigned int) cipher_len > s_len) {
char *secret_tmp = uwsgi_malloc(cipher_len);
memcpy(secret_tmp, secret, s_len);
memset(secret_tmp + s_len, 0, cipher_len - s_len);
@@ -744,18 +770,18 @@ void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
}
*/
if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const unsigned char *)secret, (const unsigned char *) "12345678") <= 0) {// (const unsigned char *) iv) <= 0) {
uwsgi_error("EVP_EncryptInit_ex()");
if (EVP_EncryptInit_ex(ctx, cipher, NULL, (const unsigned char *) secret, (const unsigned char *) "12345678") <= 0) { // (const unsigned char *) iv) <= 0) {
uwsgi_error("EVP_EncryptInit_ex()");
exit(1);
}
EVP_CIPHER_CTX *ctx2 = uwsgi_malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(ctx2);
EVP_CIPHER_CTX_init(ctx2);
if (EVP_DecryptInit_ex(ctx2, cipher, NULL, (const unsigned char *)secret, (const unsigned char *) "12345678") <= 0) {
uwsgi_error("EVP_DecryptInit_ex()");
exit(1);
}
if (EVP_DecryptInit_ex(ctx2, cipher, NULL, (const unsigned char *) secret, (const unsigned char *) "12345678") <= 0) {
uwsgi_error("EVP_DecryptInit_ex()");
exit(1);
}
// we use shared memory, as we want to export legion status to the api
struct uwsgi_legion *ul = uwsgi_calloc_shared(sizeof(struct uwsgi_legion));
@@ -764,7 +790,7 @@ void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
ul->valor = strtol(valor, (char **) NULL, 10);
ul->addr = addr;
ul->encrypt_ctx = ctx;
ul->decrypt_ctx = ctx2;
@@ -773,7 +799,7 @@ void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
struct uwsgi_legion_action *uwsgi_legion_action_get(char *name) {
struct uwsgi_legion_action *ula = uwsgi.legion_actions;
while(ula) {
while (ula) {
if (!strcmp(name, ula->name)) {
return ula;
}
@@ -782,14 +808,14 @@ struct uwsgi_legion_action *uwsgi_legion_action_get(char *name) {
return NULL;
}
void uwsgi_legion_action_register(char *name, int (*func)(struct uwsgi_legion *, char *)) {
void uwsgi_legion_action_register(char *name, int (*func) (struct uwsgi_legion *, char *)) {
if (uwsgi_legion_action_get(name)) {
uwsgi_log("[uwsgi-legion] action \"%s\" is already registered !!!\n", name);
return;
}
struct uwsgi_legion_action *old_ula = NULL,*ula = uwsgi.legion_actions;
while(ula) {
struct uwsgi_legion_action *old_ula = NULL, *ula = uwsgi.legion_actions;
while (ula) {
old_ula = ula;
ula = ula->next;
}
@@ -809,18 +835,19 @@ void uwsgi_legion_action_register(char *name, int (*func)(struct uwsgi_legion *,
void uwsgi_legion_atexit(void) {
struct uwsgi_legion *legion = uwsgi.legions;
while(legion) {
if (getpid() != legion->pid) goto next;
struct uwsgi_string_list *usl = legion->death_hooks;
while(usl) {
int ret = uwsgi_legion_action_call("death", legion, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, death hook returned: %d\n", ret);
}
usl = usl->next;
}
while (legion) {
if (getpid() != legion->pid)
goto next;
struct uwsgi_string_list *usl = legion->death_hooks;
while (usl) {
int ret = uwsgi_legion_action_call("death", legion, usl);
if (ret) {
uwsgi_log("[uwsgi-legion] ERROR, death hook returned: %d\n", ret);
}
usl = usl->next;
}
next:
legion = legion->next;
}
legion = legion->next;
}
}