summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2024-05-10 19:49:06 +0200
committerUros Majstorovic <majstor@majstor.org>2024-05-10 19:49:06 +0200
commitce55165b6952f9325c34b0008b5116b16736c4cb (patch)
tree7c85cb58e0eff3c9a884c499ad87ba6069dbc6ce
parent3f814b6f30a9ae296805ebab49114fb24ab3b0d1 (diff)
server support for fragmented dir reply; fixed shadow reply messages accordingly
-rw-r--r--ecp/server/acl.c10
-rw-r--r--ecp/server/dir.c72
-rw-r--r--ecp/server/dir.h4
-rw-r--r--ecp/server/server.c24
-rw-r--r--ecp/server/server.h2
-rw-r--r--ecp/server/vlink.c4
6 files changed, 60 insertions, 56 deletions
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; i<head->key_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 <region> <capabilities> <private key> <addr> [ <dir acl> <vconn acl> ] [ <public key> <addr> ]\n", arg);
+ fprintf(stderr, "Usage: %s <region> <roles> <private key> <addr> [ <dir acl> <vconn acl> ] [ <public key> <addr> ]\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);