From ce55165b6952f9325c34b0008b5116b16736c4cb Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 10 May 2024 19:49:06 +0200 Subject: server support for fragmented dir reply; fixed shadow reply messages accordingly --- ecp/server/acl.c | 10 ++++---- ecp/server/dir.c | 72 ++++++++++++++++++++++++++--------------------------- ecp/server/dir.h | 4 +-- ecp/server/server.c | 24 ++++++++++-------- ecp/server/server.h | 2 +- ecp/server/vlink.c | 4 +-- 6 files changed, 60 insertions(+), 56 deletions(-) (limited to 'ecp') diff --git a/ecp/server/acl.c b/ecp/server/acl.c index d8cdc6e..7561af8 100644 --- a/ecp/server/acl.c +++ b/ecp/server/acl.c @@ -50,18 +50,18 @@ void acl_destroy_list(ACLItem *head) { } } -static int _add_key(ecp_ecdh_public_t *public, uint8_t capabilities) { +static int _add_key(ecp_ecdh_public_t *public, uint8_t roles) { int rv; if ((acl_keys == NULL) || (acl_keys_dir == NULL)) return ECP_ERR; - if ((srv_config->capabilities & ECP_DIR_CAP_DIR) || (srv_config->capabilities & capabilities & ECP_DIR_CAP_VCONN)) { + if ((srv_config->roles & ECP_ROLE_DIR) || (srv_config->roles & roles & ECP_ROLE_VCONN)) { /* directory server accepts all connections vconn server accepts connections only from other vconn servers */ rv = ecp_ht_insert_uniq(acl_keys, public, &acl_mark); if (rv && (rv != ECP_ERR_DUP)) return rv; } - if (srv_config->capabilities & capabilities & ECP_DIR_CAP_DIR) { + if (srv_config->roles & roles & ECP_ROLE_DIR) { rv = ecp_ht_insert_uniq(acl_keys_dir, public, &acl_mark); if (rv && (rv != ECP_ERR_DUP)) return rv; } @@ -98,7 +98,7 @@ static int _li2ht(ACLItem *head, int is_dir) { while (head) { for (i=0; ikey_cnt; i++) { - rv = _add_key(&head->key[i], is_dir ? ECP_DIR_CAP_DIR : 0); + rv = _add_key(&head->key[i], is_dir ? ECP_ROLE_DIR : 0); if (rv) return rv; } head = head->next; @@ -111,7 +111,7 @@ int acl_add_key(ECPDirItem *dir_item) { int rv; pthread_rwlock_wrlock(&acl_ht_rwlock); - rv = _add_key(&dir_item->node.key_perma.public, dir_item->capabilities); + rv = _add_key(&dir_item->node.key_perma.public, dir_item->roles); pthread_rwlock_unlock(&acl_ht_rwlock); return rv; diff --git a/ecp/server/dir.c b/ecp/server/dir.c index 1dca021..738c787 100644 --- a/ecp/server/dir.c +++ b/ecp/server/dir.c @@ -58,18 +58,17 @@ ssize_t dir_send_online(ECPConnection *conn, uint8_t region) { ssize_t rv_snd; ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REP); + ecp_pld_set_frag(payload.buffer, payload.size, i, list->msg_count, 0); msg = ecp_pld_get_msg(payload.buffer, payload.size); msg_size = 0; - msg[0] = i; // frag_cnt - msg[1] = list->msg_count; // frag_tot - msg[2] = list->msg[i].count; // item_cnt - msg[3] = region; // region - msg[4] = dir_online->serial >> 8; // serial - msg[5] = dir_online->serial; + msg[0] = list->msg[i].count; // item_cnt + msg[1] = region; // region + msg[2] = dir_online->serial >> 8; // serial + msg[3] = dir_online->serial; - msg += 4 + sizeof(uint16_t); - msg_size += 4 + sizeof(uint16_t); + msg += 2 + sizeof(uint16_t); + msg_size += 2 + sizeof(uint16_t); memcpy(msg, list->msg[i].buffer, list->msg[i].count * ECP_SIZE_DIR_ITEM); msg_size += list->msg[i].count * ECP_SIZE_DIR_ITEM; @@ -125,7 +124,7 @@ ssize_t dir_send_ann(ECPConnection *conn) { ecp_pld_set_type(payload.buffer, payload.size, MTYPE_DIR_ANN); msg = ecp_pld_get_msg(payload.buffer, payload.size); msg[0] = srv_config->region; - msg[1] = srv_config->capabilities; + msg[1] = srv_config->roles; return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(2, MTYPE_DIR_ANN), 0); } @@ -157,16 +156,16 @@ ssize_t dir_send_shadow(ECPConnection *conn) { ecp_pld_set_type(payload.buffer, payload.size, MTYPE_DIR_SHADOW); msg = ecp_pld_get_msg(payload.buffer, payload.size); - memset(msg, 0, 4 + sizeof(uint16_t)); // frag_cnt, frag_tot, item_cnt, region, serial - pthread_rwlock_rdlock(&dir_shadow_rwlock); + count = 0; + msg_size = 0; if (ecp_ht_count(dir_shadow) > 0) { unsigned char *_msg; size_t _msg_size; int _rv; - _msg = msg + 4 + sizeof(uint16_t); + _msg = msg + 1; _msg_size = 0; ecp_ht_itr_create(&itr, dir_shadow); if (node_next) { @@ -178,7 +177,6 @@ ssize_t dir_send_shadow(ECPConnection *conn) { node_next = NULL; } - count = 0; do { node = ecp_ht_itr_value(&itr); @@ -200,20 +198,22 @@ ssize_t dir_send_shadow(ECPConnection *conn) { _rv = ecp_ht_itr_advance(&itr); } while (_rv == ECP_OK); - msg[2] = count; - msg_size = 4 + sizeof(uint16_t) + _msg_size; + msg[0] = count; + msg_size = 1 + _msg_size; } /* no need to copy node_next key, since announce is verified nodes will not be removed during online switch node removal */ pthread_rwlock_unlock(&dir_shadow_rwlock); - rv_snd = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, MTYPE_DIR_SHADOW), 0); - if (rv_snd < 0) { - rv = rv_snd; - break; + if (msg_size) { + rv_snd = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, MTYPE_DIR_SHADOW), 0); + if (rv_snd < 0) { + rv = rv_snd; + break; + } + rv += rv_snd; } - rv += rv_snd; } while (node_next); return rv; @@ -270,7 +270,7 @@ ssize_t dir_send_origin_rep(ECPConnection *conn, ecp_ecdh_public_t *public) { ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size) { ECPDirItem dir_item; uint8_t region; - uint8_t capabilities; + uint8_t roles; size_t rsize; ssize_t rv; int ann_enable; @@ -285,8 +285,8 @@ ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size) if (!ann_enable) return rsize; region = msg[0]; - capabilities = msg[1]; - if ((capabilities & ECP_DIR_CAP_DIR) && !acl_dir_inlist(&conn->remote.key_perma.public)) { + roles = msg[1]; + if ((roles & ECP_ROLE_DIR) && !acl_dir_inlist(&conn->remote.key_perma.public)) { LOG(LOG_ERR, "dir_handle_ann: not a directory server\n"); return ECP_ERR; } @@ -294,7 +294,7 @@ ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size) memset(&dir_item, 0, sizeof(ECPDirItem)); dir_item.node = conn->remote; dir_item.region = region; - dir_item.capabilities = capabilities; + dir_item.roles = roles; if (dir_item.region >= MAX_REGION) { LOG(LOG_ERR, "dir_handle_ann: bad region\n"); @@ -314,12 +314,12 @@ ssize_t dir_handle_shadow(ECPConnection *conn, unsigned char *msg, size_t msg_si size_t rsize; int i, ann_enable; - if (msg_size < 4 + sizeof(uint16_t)) return ECP_ERR_SIZE; + if (msg_size < 1) return ECP_ERR_SIZE; - count = msg[2]; - msg += 4 + sizeof(uint16_t); // frag_cnt, frag_tot, item_cnt, region, serial + count = msg[0]; // item_cnt + msg += 1; - rsize = 4 + sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM; + rsize = 1 + count * ECP_SIZE_DIR_ITEM; if (msg_size < rsize) return ECP_ERR_SIZE; pthread_rwlock_rdlock(&dir_timer_rwlock); @@ -364,7 +364,7 @@ ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char case MTYPE_DIR_ANN: { int is_dir; - is_dir = srv_config->capabilities & ECP_DIR_CAP_DIR; + is_dir = srv_config->roles & ECP_ROLE_DIR; if (!is_dir || ecp_conn_is_outb(conn)) return ECP_ERR; return dir_handle_ann(conn, msg, msg_size); @@ -379,7 +379,7 @@ ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char case MTYPE_DIR_ORIGIN_REQ: { int is_dir; - is_dir = srv_config->capabilities & ECP_DIR_CAP_DIR; + is_dir = srv_config->roles & ECP_ROLE_DIR; if (!is_dir || ecp_conn_is_outb(conn)) return ECP_ERR; return dir_handle_origin_req(conn, msg, msg_size); @@ -447,7 +447,7 @@ void dir_process_item(ECPDirItem *dir_item, ECPSocket *sock, ecp_ecdh_public_t * if (!key_ex) { unsigned int vkey_req; - if (node->dir_item.capabilities & ECP_DIR_CAP_DIR) { + if (node->dir_item.roles & ECP_ROLE_DIR) { vkey_req = vkey_req_dir; } else { vkey_req = MIN_VKEY_REQ; @@ -521,7 +521,7 @@ int dir_create_node(ECPDirItem *dir_item, ECPSocket *sock, DIRNode **node) { _node->is_new = 1; /* open connection to other directory servers */ - if ((dir_item->capabilities & ECP_DIR_CAP_DIR) && (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) { + if ((dir_item->roles & ECP_ROLE_DIR) && (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) { rv = dir_open_conn(_node, sock); if (rv) { pthread_mutex_destroy(&_node->mutex); @@ -615,7 +615,7 @@ void dir_online_switch(ECPSocket *sock, int inc_serial) { count[region]++; } } - if (node->dir_item.capabilities & ECP_DIR_CAP_DIR) { + if (node->dir_item.roles & ECP_ROLE_DIR) { dir_cnt++; } node_cnt++; @@ -727,7 +727,7 @@ void dir_online_switch(ECPSocket *sock, int inc_serial) { } } - if (srv_config->capabilities & ECP_DIR_CAP_DIR) acl_load_ht(); + if (srv_config->roles & ECP_ROLE_DIR) acl_load_ht(); LOG(LOG_DEBUG, "dir_online_switch: node:%d dir:%d serial:%d\n", node_cnt, dir_cnt, dir_online ? dir_online->serial : 0); } @@ -786,7 +786,7 @@ void dir_announce(ECPSocket *sock, int ann_period) { do { node = ecp_ht_itr_value(&itr); - if ((node->dir_item.capabilities & ECP_DIR_CAP_DIR) && (memcmp(&node->dir_item.node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) { + if ((node->dir_item.roles & ECP_ROLE_DIR) && (memcmp(&node->dir_item.node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) { if (announce_cnt < MAX_NODE_ANNOUNCE) { announce_node[announce_cnt] = node; announce_cnt++; @@ -954,7 +954,7 @@ int dir_init(ECPSocket *sock) { /* dir_process_enable and dir_online.serial will be set from timer */ dir_vkey_req = 1; srv_config = srv_get_config(); - is_dir = srv_config->capabilities & ECP_DIR_CAP_DIR; + is_dir = srv_config->roles & ECP_ROLE_DIR; rv = pthread_rwlock_init(&dir_shadow_rwlock, NULL); if (rv) { diff --git a/ecp/server/dir.h b/ecp/server/dir.h index f82454b..0871c33 100644 --- a/ecp/server/dir.h +++ b/ecp/server/dir.h @@ -1,4 +1,4 @@ -#define MAX_DIR_ITEM_IN_MSG ((ECP_MAX_PLD - (4 + sizeof(uint16_t))) / ECP_SIZE_DIR_ITEM) +#define MAX_DIR_ITEM_IN_MSG ((ECP_MAX_PLD - ECP_SIZE_PLD(0, ECP_MTYPE_DIR_REP) - (2 + sizeof(uint16_t))) / ECP_SIZE_DIR_ITEM) #define MAX_DIR_MSG 10 #define MAX_DIR_ITEM (MAX_DIR_MSG * MAX_DIR_ITEM_IN_MSG) @@ -11,7 +11,7 @@ #define MAX_NODE_ANNOUNCE 100 #define MAX_NODE_REMOVE 100 -#define CTYPE_DIR 0x00 +#define CTYPE_DIR 0x00 /* any node to directory server connection */ #define MTYPE_DIR_ANN 0x00 #define MTYPE_DIR_SHADOW 0x01 diff --git a/ecp/server/server.c b/ecp/server/server.c index eeb5f2d..5493762 100644 --- a/ecp/server/server.c +++ b/ecp/server/server.c @@ -33,7 +33,7 @@ SRVConfig *srv_get_config(void) { } static void usage(char *arg) { - fprintf(stderr, "Usage: %s [ ] [ ]\n", arg); + fprintf(stderr, "Usage: %s [ ] [ ]\n", arg); exit(1); } @@ -55,7 +55,7 @@ static ECPConnection *conn_new(ECPSocket *sock, ECPConnection *parent, unsigned switch (ctype) { case CTYPE_DIR: { - if (!(srv_config.capabilities & ECP_DIR_CAP_DIR)) return NULL; + if (!(srv_config.roles & ECP_ROLE_DIR)) return NULL; conn = malloc(sizeof(ECPConnection)); if (conn) { @@ -66,7 +66,7 @@ static ECPConnection *conn_new(ECPSocket *sock, ECPConnection *parent, unsigned } case ECP_CTYPE_DIR: { - if (!(srv_config.capabilities & ECP_DIR_CAP_DIR)) return NULL; + if (!(srv_config.roles & ECP_ROLE_DIR)) return NULL; conn = malloc(sizeof(ECPConnection)); if (conn) ecp_conn_init(conn, sock, ctype); @@ -76,7 +76,7 @@ static ECPConnection *conn_new(ECPSocket *sock, ECPConnection *parent, unsigned case ECP_CTYPE_VCONN: { ECPVConnInb *_conn; - if (!(srv_config.capabilities & ECP_DIR_CAP_VCONN)) return NULL; + if (!(srv_config.roles & ECP_ROLE_VCONN)) return NULL; _conn = malloc(sizeof(ECPVConnInb)); if (_conn) { @@ -87,7 +87,7 @@ static ECPConnection *conn_new(ECPSocket *sock, ECPConnection *parent, unsigned } case ECP_CTYPE_VLINK: { - if (!(srv_config.capabilities & ECP_DIR_CAP_VCONN)) return NULL; + if (!(srv_config.roles & ECP_ROLE_VCONN)) return NULL; conn = malloc(sizeof(ECPConnection)); if (conn) ecp_vlink_init(conn, sock); @@ -116,8 +116,12 @@ static int key_check(ECPSocket *sock, ECPConnection *parent, unsigned char ctype return 1; } - default: + case ECP_CTYPE_DIR: + case ECP_CTYPE_VCONN: return 1; + + default: + return 0; } } @@ -174,11 +178,11 @@ int main(int argc, char *argv[]) { if (srv_config.region >= MAX_REGION) fail("Bad region\n"); _argc++; - srv_config.capabilities = (uint8_t)strtol(argv[_argc], &endptr, 16); - if (endptr[0] != '\0') fail("Bad capabilities\n"); + srv_config.roles = (uint8_t)strtol(argv[_argc], &endptr, 16); + if (endptr[0] != '\0') fail("Bad roles\n"); _argc++; - if (srv_config.capabilities & ECP_DIR_CAP_DIR) { + if (srv_config.roles & ECP_ROLE_DIR) { if (argc < 7) usage(argv[0]); } else { if (argc < 5) usage(argv[0]); @@ -213,7 +217,7 @@ int main(int argc, char *argv[]) { rv = acl_init(); if (rv) fail("acl_init err:%d\n", rv); - if (srv_config.capabilities & ECP_DIR_CAP_DIR) { + if (srv_config.roles & ECP_ROLE_DIR) { srv_config.acl_fn_dir = strdup(argv[_argc]); _argc++; srv_config.acl_fn = strdup(argv[_argc]); diff --git a/ecp/server/server.h b/ecp/server/server.h index 21f2129..f8f8cac 100644 --- a/ecp/server/server.h +++ b/ecp/server/server.h @@ -13,7 +13,7 @@ typedef struct SRVConfig { char *acl_fn_dir; ecp_tr_addr_t my_addr; uint8_t region; - uint8_t capabilities; + uint8_t roles; } SRVConfig; SRVConfig *srv_get_config(void); diff --git a/ecp/server/vlink.c b/ecp/server/vlink.c index e18ec9f..17c84ad 100644 --- a/ecp/server/vlink.c +++ b/ecp/server/vlink.c @@ -42,7 +42,7 @@ void vlink_new_node(ECPSocket *sock, ECPDirItem *dir_item) { ECPConnection *conn; int rv; - if (!(dir_item->capabilities & ECP_DIR_CAP_VCONN) || (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) == 0)) return; + if (!(dir_item->roles & ECP_ROLE_VCONN) || (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) == 0)) return; pthread_rwlock_rdlock(&vlink_conn_rwlock); conn = ecp_ht_search(vlink_conn, &dir_item->node.key_perma.public); @@ -72,7 +72,7 @@ void vlink_new_node(ECPSocket *sock, ECPDirItem *dir_item) { void vlink_del_node(ECPDirItem *dir_item) { ECPConnection *conn; - if (!(dir_item->capabilities & ECP_DIR_CAP_VCONN) || (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) == 0)) return; + if (!(dir_item->roles & ECP_ROLE_VCONN) || (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) == 0)) return; pthread_rwlock_rdlock(&vlink_conn_rwlock); conn = ecp_ht_search(vlink_conn, &dir_item->node.key_perma.public); -- cgit v1.2.3