summaryrefslogtreecommitdiff
path: root/ecp/server/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecp/server/server.c')
-rw-r--r--ecp/server/server.c270
1 files changed, 172 insertions, 98 deletions
diff --git a/ecp/server/server.c b/ecp/server/server.c
index d34fb19..890d468 100644
--- a/ecp/server/server.c
+++ b/ecp/server/server.c
@@ -1,41 +1,81 @@
#include <stdlib.h>
-#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
#include <sys/stat.h>
#include <ecp/core.h>
-#include <ecp/dir/dir.h>
#include <ecp/vconn/vconn.h>
+#include <util.h>
+
#include "dir.h"
#include "vlink.h"
#include "ht.h"
+#include "acl.h"
#include "server.h"
static SRVConfig srv_config;
+static const char *srv_llevel_str[] = {
+ "DEBUG",
+ "INFO",
+ "ERROR"
+};
SRVConfig *srv_get_config(void) {
return &srv_config;
}
static void usage(char *arg) {
- fprintf(stderr, "Usage: %s <capabilities> <priv> <addr> [ <pub> <addr> ]\n", arg);
+ fprintf(stderr, "Usage: %s <region> <capabilities> <private key> <addr> [ <dir acl> <vconn acl> ] [ <public key> <addr> ]\n", arg);
+ exit(1);
+}
+
+static void fail(char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
exit(1);
}
static void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
- if (conn->type == ECP_CTYPE_VLINK) vlink_handle_err(conn, mtype, err);
- LOG(LOG_ERR, "handle error ctype:%d mtype:%d err:%d\n", conn->type, mtype, err);
+ LOG(LOG_ERR, "handle_err: ctype:%d mtype:%d err:%d\n", conn->type, mtype, err);
}
-static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) {
+static ECPConnection *conn_new(ECPSocket *sock, ECPConnection *parent, unsigned char ctype) {
ECPConnection *conn = NULL;
- switch (type) {
+ switch (ctype) {
+ case CTYPE_DIR: {
+ if (!(srv_config.capabilities & ECP_DIR_CAP_DIR)) return NULL;
+
+ conn = malloc(sizeof(ECPConnection));
+ if (conn) {
+ ecp_conn_init(conn, sock, ctype);
+ ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX);
+ }
+ break;
+ }
+
+ case ECP_CTYPE_DIR: {
+ if (!(srv_config.capabilities & ECP_DIR_CAP_DIR)) return NULL;
+
+ conn = malloc(sizeof(ECPConnection));
+ if (conn) ecp_conn_init(conn, sock, ctype);
+ break;
+ }
+
case ECP_CTYPE_VCONN: {
ECPVConnInb *_conn;
+ if (!(srv_config.capabilities & ECP_DIR_CAP_VCONN)) return NULL;
+
_conn = malloc(sizeof(ECPVConnInb));
if (_conn) {
ecp_vconn_init_inb(_conn, sock);
@@ -45,29 +85,61 @@ static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) {
}
case ECP_CTYPE_VLINK: {
- conn = malloc(sizeof(ECPConnection));
- if (conn) ecp_vlink_init(conn, sock);
- break;
- }
+ if (!(srv_config.capabilities & ECP_DIR_CAP_VCONN)) return NULL;
- default: {
conn = malloc(sizeof(ECPConnection));
- if (conn) ecp_conn_init(conn, sock, type);
+ if (conn) ecp_vlink_init(conn, sock);
break;
}
}
+ if (conn) ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC);
return conn;
}
+static int key_check(ECPSocket *sock, ECPConnection *parent, unsigned char ctype, ecp_ecdh_public_t *public) {
+ switch (ctype) {
+ case CTYPE_DIR: {
+ if (public == NULL) return 0;
+ return acl_inlist(public);
+ }
+
+ case ECP_CTYPE_VLINK: {
+ if (public == NULL) return 0;
+ if (parent == NULL) return acl_inlist(public);
+ return 1;
+ }
+
+ default:
+ return 1;
+ }
+}
+
static void conn_free(ECPConnection *conn) {
free(conn);
}
+void log_print(int level, char *format, ...) {
+ va_list args;
+ time_t t;
+ char buf[26];
+
+ if (level >= (sizeof(srv_llevel_str) / sizeof(char *))) return;
+
+ t = time(NULL);
+ ctime_r(&t, buf);
+ buf[24] = '\0';
+ fprintf(stderr, "%s [%s]: ", buf, srv_llevel_str[level]);
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) {
int rv;
- rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free, NULL);
+ rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free, key_check);
if (rv) return rv;
rv = ecp_vconn_handler_init(ctx, vconn_handler);
@@ -86,118 +158,120 @@ int main(int argc, char *argv[]) {
ECPConnHandler vconn_handler;
ECPConnHandler vlink_handler;
char *endptr;
- int fd;
+ char *debug_init_str;
+ int _argc, fd;
int rv;
- if ((argc < 4) || (argc > 6)) usage(argv[0]);
+ memset(&srv_config, 0, sizeof(srv_config));
- srv_config.capabilities = (uint16_t)strtol(argv[1], &endptr, 16);
- if (endptr[0] != '\0') {
- fprintf(stderr, "Bad capabilities\n");
- exit(1);
- }
+ if (argc < 3) usage(argv[0]);
- if ((fd = open(argv[2], O_RDONLY)) < 0) {
- fprintf(stderr, "Unable to open %s\n", argv[2]);
- exit(1);
- }
- if (read(fd, &srv_config.key_perma.public, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) {
- close(fd);
- fprintf(stderr, "Unable to read public key from %s\n", argv[2]);
- exit(1);
- }
- if (read(fd, &srv_config.key_perma.private, sizeof(ecp_ecdh_private_t)) != sizeof(ecp_ecdh_private_t)) {
- close(fd);
- fprintf(stderr, "Unable to read private key from %s\n", argv[2]);
- exit(1);
+ _argc = 1;
+ srv_config.region = (uint8_t)strtol(argv[_argc], &endptr, 16);
+ if (endptr[0] != '\0') fail("Bad region\n");
+ 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");
+ _argc++;
+
+ if (srv_config.capabilities & ECP_DIR_CAP_DIR) {
+ if (argc < 7) usage(argv[0]);
+ } else {
+ if (argc < 5) usage(argv[0]);
}
+
+ fd = open(argv[_argc], O_RDONLY);
+ if (fd < 0) fail("Unable to open %s\n", argv[_argc]);
+
+ rv = ecp_util_read_key(fd, &srv_config.key_perma.public, &srv_config.key_perma.private);
close(fd);
+ if (rv) fail("Unable to read key from %s\n", argv[_argc]);
srv_config.key_perma.valid = 1;
+ _argc++;
rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
- if (rv) {
- fprintf(stderr, "ecp_init RV:%d\n", rv);
- exit(1);
- }
+ if (rv) fail("ecp_init err:%d\n", rv);
+
rv = ecp_sock_create(&sock, &ctx, &srv_config.key_perma);
- if (rv) {
- fprintf(stderr, "ecp_sock_create RV:%d\n", rv);
- exit(1);
- }
+ if (rv) fail("ecp_sock_create err:%d\n", rv);
- rv = ecp_addr_init(&addr, argv[3]);
- if (rv) {
- fprintf(stderr, "ecp_addr_init RV:%d\n", rv);
- exit(1);
- }
+ rv = ecp_vconn_sock_create(&sock);
+ if (rv) fail("ecp_vconn_sock_create err:%d\n", rv);
+
+ rv = ecp_addr_init(&addr, argv[_argc]);
+ if (rv) fail("ecp_addr_init err:%d\n", rv);
+ _argc++;
rv = ecp_sock_open(&sock, &addr);
- if (rv) {
- fprintf(stderr, "ecp_sock_open RV:%d\n", rv);
- exit(1);
- }
+ if (rv) fail("ecp_sock_open err:%d\n", rv);
+ srv_config.my_addr = addr;
- rv = dir_init(&ctx);
- if (rv) {
- fprintf(stderr, "dir_init RV:%d\n", rv);
- exit(1);
- }
+ rv = acl_init();
+ if (rv) fail("acl_init err:%d\n", rv);
- rv = vlink_init(&ctx);
- if (rv) {
- fprintf(stderr, "vlink_init RV:%d\n", rv);
- exit(1);
- }
+ if (srv_config.capabilities & ECP_DIR_CAP_DIR) {
+ srv_config.acl_fn_dir = strdup(argv[_argc]);
+ _argc++;
+ srv_config.acl_fn = strdup(argv[_argc]);
+ _argc++;
- rv = dir_start_announce(&sock);
- if (rv) {
- fprintf(stderr, "dir_start_announce RV:%d\n", rv);
- exit(1);
+ rv = acl_load();
+ if (rv) fail("acl_load err:%d\n", rv);
}
- rv = vlink_start_open(&sock);
- if (rv) {
- fprintf(stderr, "vlink_start_open RV:%d\n", rv);
- exit(1);
- }
+ rv = dir_init(&sock);
+ if (rv) fail("dir_init err:%d\n", rv);
- rv = vlink_start_keyx();
- if (rv) {
- fprintf(stderr, "vlink_start_keyx RV:%d\n", rv);
- exit(1);
- }
+ rv = vlink_init(&sock);
+ if (rv) fail("vlink_init err:%d\n", rv);
- if (argc == 6) {
+ rv = ecp_start_receiver(&sock);
+ if (rv) fail("ecp_start_receiver err:%d\n", rv);
+
+ if (argc == _argc + 2) {
ECPNode node;
ecp_ecdh_public_t node_pub;
ecp_tr_addr_t node_addr;
- if ((fd = open(argv[4], O_RDONLY)) < 0) {
- fprintf(stderr, "Unable to open %s\n", argv[4]);
- exit(1);
- }
- if (read(fd, &node_pub, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) {
- close(fd);
- fprintf(stderr, "Unable to read public key from %s\n", argv[4]);
- exit(1);
- }
- close(fd);
+ fd = open(argv[_argc], O_RDONLY);
+ if (fd < 0) fail("Unable to open %s\n", argv[_argc]);
- int rv;
+ rv = ecp_util_read_key(fd, &node_pub, NULL);
+ close(fd);
+ if (rv) fail("Unable to read public key from %s\n", argv[_argc]);
+ _argc++;
ecp_node_init(&node, &node_pub, NULL);
- rv = ecp_node_set_addr(&node, argv[5]);
- if (rv) {
- fprintf(stderr, "ecp_node_set_addr RV:%d\n", rv);
- exit(1);
- }
- rv = dir_open_conn(&sock, &node);
- if (rv) {
- fprintf(stderr, "dir_open_conn RV:%d\n", rv);
- exit(1);
+ rv = ecp_node_set_addr(&node, argv[_argc]);
+ if (rv) fail("ecp_node_set_addr err:%d\n", rv);
+ _argc++;
+
+ rv = dir_init_ann(&sock, &node);
+ if (rv) fail("dir_init_ann err:%d\n", rv);
+ }
+
+ if (_argc != argc) usage(argv[0]);
+
+ debug_init_str = getenv("ECP_DBG_INIT");
+ if (debug_init_str) {
+ int init_ann;
+
+ init_ann = (int)strtol(debug_init_str, &endptr, 10);
+ if (endptr[0] == '\0') {
+ LOG(LOG_DEBUG, "init switch start - number of announces:%d\n", init_ann);
+ dir_init_switch(&sock, init_ann);
+ LOG(LOG_DEBUG, "init switch done\n");
}
}
- ecp_receiver(&sock);
-} \ No newline at end of file
+ rv = dir_start_announce(&sock);
+ if (rv) fail("dir_start_announce err:%d\n", rv);
+
+ rv = vlink_start_keyx(&sock);
+ if (rv) fail("vlink_start_keyx err:%d\n", rv);
+
+ while(1) pause();
+}