UNIX socket UPDATE configurable with YANG data
Implemented the ability to create a UNIX socket server with YANG
data. Additionally all new tests timeouts are now unified.
diff --git a/src/config_server.c b/src/config_server.c
index 2c41ee0..50e3c1b 100644
--- a/src/config_server.c
+++ b/src/config_server.c
@@ -479,6 +479,35 @@
}
void
+nc_server_del_unix_socket(struct nc_bind *bind, struct nc_server_unix_opts *opts)
+{
+ if (bind->sock > -1) {
+ close(bind->sock);
+ }
+
+ free(bind->address);
+ free(opts->address);
+
+ free(opts);
+ opts = NULL;
+}
+
+void
+nc_server_del_endpt_unix_socket(struct nc_endpt *endpt, struct nc_bind *bind)
+{
+ nc_server_del_endpt_name(endpt);
+ nc_server_del_unix_socket(bind, endpt->opts.unixsock);
+
+ server_opts.endpt_count--;
+ if (!server_opts.endpt_count) {
+ free(server_opts.endpts);
+ free(server_opts.binds);
+ server_opts.endpts = NULL;
+ server_opts.binds = NULL;
+ }
+}
+
+void
nc_server_config_del_keystore(void)
{
int i, j;
@@ -520,7 +549,13 @@
if (op == NC_OP_DELETE) {
for (i = 0; i < server_opts.endpt_count; i++) {
- nc_server_del_endpt_ssh(&server_opts.endpts[i], &server_opts.binds[i]);
+ if (server_opts.endpts[i].ti == NC_TI_LIBSSH) {
+ nc_server_del_endpt_ssh(&server_opts.endpts[i], &server_opts.binds[i]);
+ } else if (server_opts.endpts[i].ti == NC_TI_OPENSSL) {
+ /* todo */
+ } else {
+ nc_server_del_endpt_unix_socket(&server_opts.endpts[i], &server_opts.binds[i]);
+ }
}
}
@@ -676,7 +711,7 @@
{
int sock = -1, set_addr, ret = 0;
- assert((address && !port) || (!address && port));
+ assert((address && !port) || (!address && port) || (endpt->ti == NC_TI_UNIX));
if (address) {
set_addr = 1;
@@ -690,15 +725,15 @@
address = bind->address;
}
- if (!set_addr && (endpt->ti == NC_TI_UNIX)) {
- ret = 1;
- goto cleanup;
- }
-
/* we have all the information we need to create a listening socket */
- if (address && port) {
+ if ((address && port) || (endpt->ti == NC_TI_UNIX)) {
/* create new socket, close the old one */
- sock = nc_sock_listen_inet(address, port, &endpt->ka);
+ if (endpt->ti == NC_TI_UNIX) {
+ sock = nc_sock_listen_unix(endpt->opts.unixsock);
+ } else {
+ sock = nc_sock_listen_inet(address, port, &endpt->ka);
+ }
+
if (sock == -1) {
ret = 1;
goto cleanup;
@@ -712,6 +747,9 @@
if (sock > -1) {
switch (endpt->ti) {
+ case NC_TI_UNIX:
+ VRB(NULL, "Listening on %s for UNIX connections.", endpt->opts.unixsock->address);
+ break;
#ifdef NC_ENABLED_SSH
case NC_TI_LIBSSH:
VRB(NULL, "Listening on %s:%u for SSH connections.", address, port);
@@ -1911,6 +1949,92 @@
}
static int
+nc_server_create_unix_socket(struct nc_endpt *endpt)
+{
+ endpt->ti = NC_TI_UNIX;
+ endpt->opts.unixsock = calloc(1, sizeof *endpt->opts.unixsock);
+ if (!endpt->opts.unixsock) {
+ ERRMEM;
+ return 1;
+ }
+
+ /* set default values */
+ endpt->opts.unixsock->mode = -1;
+ endpt->opts.unixsock->uid = -1;
+ endpt->opts.unixsock->gid = -1;
+
+ return 0;
+}
+
+static int
+nc_server_configure_unix_socket(const struct lyd_node *node, NC_OPERATION op)
+{
+ int ret = 0;
+ uint32_t prev_lo;
+ struct nc_endpt *endpt;
+ struct nc_bind *bind;
+ struct nc_server_unix_opts *opts;
+ struct lyd_node *data = NULL;
+
+ assert(!strcmp(LYD_NAME(node), "unix-socket"));
+
+ if (nc_server_get_endpt(node, &endpt, &bind)) {
+ ret = 1;
+ goto cleanup;
+ }
+
+ if (op == NC_OP_CREATE) {
+ if (nc_server_create_unix_socket(endpt)) {
+ ret = 1;
+ goto cleanup;
+ }
+
+ opts = endpt->opts.unixsock;
+
+ lyd_find_path(node, "path", 0, &data);
+ assert(data);
+
+ opts->address = strdup(lyd_get_value(data));
+ bind->address = strdup(lyd_get_value(data));
+ if (!opts->address || !bind->address) {
+ ERRMEM;
+ ret = 1;
+ goto cleanup;
+ }
+
+ /* silently search for non-mandatory parameters */
+ prev_lo = ly_log_options(0);
+ ret = lyd_find_path(node, "mode", 0, &data);
+ if (!ret) {
+ opts->mode = strtol(lyd_get_value(data), NULL, 8);
+ }
+
+ ret = lyd_find_path(node, "uid", 0, &data);
+ if (!ret) {
+ opts->uid = strtol(lyd_get_value(data), NULL, 10);
+ }
+
+ ret = lyd_find_path(node, "gid", 0, &data);
+ if (!ret) {
+ opts->gid = strtol(lyd_get_value(data), NULL, 10);
+ }
+
+ /* reset the logging options */
+ ly_log_options(prev_lo);
+
+ ret = nc_server_config_set_address_port(endpt, bind, NULL, 0);
+ if (ret) {
+ goto cleanup;
+ }
+ } else if (op == NC_OP_DELETE) {
+ nc_server_del_unix_socket(bind, endpt->opts.unixsock);
+ }
+
+cleanup:
+ return ret;
+}
+
+static int
nc_server_configure(const struct lyd_node *node, NC_OPERATION op)
{
const char *name = LYD_NAME(node);
@@ -2027,6 +2151,10 @@
if (nc_server_configure_mac_alg(node, op)) {
goto error;
}
+ } else if (!strcmp(name, "unix-socket")) {
+ if (nc_server_configure_unix_socket(node, op)) {
+ goto error;
+ }
} else if (!strcmp(name, "cert-data")) {} else if (!strcmp(name, "expiration-date")) {} else if (!strcmp(name, "asymmetric-key")) {} else if (!strcmp(name, "certificate")) {} else if (!strcmp(name, "key-format")) {} else if (!strcmp(name,
"cleartext-key")) {} else if (!strcmp(name, "hidden-key")) {} else if (!strcmp(name, "id_hint")) {} else if (!strcmp(name, "external-identity")) {} else if (!strcmp(name, "hash")) {} else if (!strcmp(name, "context")) {} else if (!strcmp(name,
"target-protocol")) {} else if (!strcmp(name, "target-kdf")) {} else if (!strcmp(name, "client-authentication")) {} else if (!strcmp(name, "ca-certs")) {} else if (!strcmp(name, "ee-certs")) {} else if (!strcmp(name,