Ejemplo n.º 1
0
static
int dslink_init_responder(Responder *responder) {
    responder->super_root = dslink_node_create(NULL, "/", "node");
    if (!responder->super_root) {
        goto cleanup;
    }

    DSLINK_RESPONDER_MAP_INIT(open_streams, uint32)
    DSLINK_RESPONDER_MAP_INIT(list_subs, str)
    DSLINK_RESPONDER_MAP_INIT(value_path_subs, str)
    DSLINK_RESPONDER_MAP_INIT(value_sid_subs, uint32)
    return 0;
cleanup:
    if (responder->open_streams) {
        DSLINK_MAP_FREE(responder->open_streams, {});
    }
    if (responder->list_subs) {
        DSLINK_MAP_FREE(responder->list_subs, {});
    }
    if (responder->value_path_subs) {
        DSLINK_MAP_FREE(responder->value_path_subs, {});
    }
    if (responder->value_sid_subs) {
        DSLINK_MAP_FREE(responder->value_sid_subs, {});
    }
    if (responder->super_root) {
        dslink_node_tree_free(NULL, responder->super_root);
    }
    return DSLINK_ALLOC_ERR;
}
Ejemplo n.º 2
0
void responder_init_serialization(DSLink *link, DSNode *root) {
    DSNode *node = dslink_node_create(root, "saved", "node");

    // data for serialization testing
    dslink_node_set_meta_new(link, node, "$$$password", json_string_nocheck("Test1234"));
    // load the data after set password to test if the deserialization is correct
    load_node(link, node);
    dslink_node_set_meta_new(link, node, "$writable", json_string_nocheck("write"));
    dslink_node_set_meta_new(link, node, "$type", json_string_nocheck("string"));
    if (dslink_node_add_child(link, node) != 0) {
        log_warn("Failed to add the serialization node to the root\n");
        dslink_node_tree_free(link, node);
    }

    node->on_data_changed = on_node_changed;
}
Ejemplo n.º 3
0
int dslink_init(int argc, char **argv,
                const char *name, uint8_t isRequester,
                uint8_t isResponder, DSLinkCallbacks *cbs) {
    mbedtls_ecdh_context ctx;
    DSLinkConfig config;

    Url *url = NULL;
    json_t *handshake = NULL;
    char *dsId = NULL;
    Socket *sock = NULL;

    DSLink link;
    memset(&link, 0, sizeof(DSLink));

    int ret = 0;
    config.name = name;
    if ((ret = dslink_parse_opts(argc, argv, &config)) != 0) {
        if (ret == DSLINK_ALLOC_ERR) {
            log_fatal("Failed to allocate memory during argument parsing\n");
        }
        return 1;
    }

    // TODO: move .key as a parameter
    if ((ret = dslink_handshake_key_pair_fs(&ctx, ".key")) != 0) {
        if (ret == DSLINK_CRYPT_KEY_DECODE_ERR) {
            log_fatal("Failed to decode existing key\n");
        } else if (ret == DSLINK_OPEN_FILE_ERR) {
            log_fatal("Failed to write generated key to disk\n");
        } else if (ret == DSLINK_CRYPT_KEY_PAIR_GEN_ERR) {
            log_fatal("Failed to generated key\n");
        } else {
            log_fatal("Unknown error occurred during key handling: %d\n", ret);
        }
        ret = 1;
        goto exit;
    }

    url = dslink_url_parse(config.broker_url);
    if (!url) {
        log_fatal("Failed to parse url: %s\n", config.broker_url);
        ret = 1;
        goto exit;
    }

    if (isResponder) {
        link.responder = calloc(1, sizeof(Responder));
        if (!link.responder) {
            log_fatal("Failed to create responder\n");
            goto exit;
        }

        if (dslink_init_responder(link.responder) != 0) {
            log_fatal("Failed to initialize responder\n");
            goto exit;
        }
    }

    if (cbs->init_cb) {
        cbs->init_cb(&link);
    }

    if ((ret = dslink_handshake_generate(url, &ctx, config.name,
                                         isRequester, isResponder,
                                         &handshake, &dsId)) != 0) {
        log_fatal("Handshake failed: %d\n", ret);
        ret = 1;
        goto exit;
    }

    const char *uri = json_string_value(json_object_get(handshake, "wsUri"));
    const char *tKey = json_string_value(json_object_get(handshake, "tempKey"));
    const char *salt = json_string_value(json_object_get(handshake, "salt"));

    if (!(uri && tKey && salt)) {
        log_fatal("Handshake didn't return the "
                  "necessary parameters to complete\n");
        ret = 1;
        goto exit;
    }

    if ((ret = dslink_handshake_connect_ws(url, &ctx, uri,
                                           tKey, salt, dsId, &sock)) != 0) {
        log_fatal("Failed to connect to the broker: %d\n", ret);
        ret = 1;
        goto exit;
    } else {
        log_info("Successfully connected to the broker\n");
    }

    if (cbs->on_connected_cb) {
        cbs->on_connected_cb(&link);
    }

    link._socket = sock;
    dslink_handshake_handle_ws(&link);

    // TODO: automatic reconnecting
    log_warn("Disconnected from the broker\n")
    if (cbs->on_disconnected_cb) {
        cbs->on_disconnected_cb(&link);
    }

exit:
    mbedtls_ecdh_free(&ctx);
    DSLINK_CHECKED_EXEC(dslink_socket_close, sock);
    if (link.responder) {
        if (link.responder->super_root) {
            dslink_node_tree_free(NULL, link.responder->super_root);
        }
        if (link.responder->open_streams) {
            DSLINK_MAP_FREE(link.responder->open_streams, {
                free(entry->key);
                free(entry->value);
            });