Exemplo n.º 1
0
void p2p_get_peers_get_nodes(BEN * nodes, UCHAR * node_id, ITEM * ti,
			     BEN * token, IP * from)
{

	LOOKUP *l = tdb_ldb(ti);
	UCHAR *target = NULL;
	UCHAR *id = NULL;
	UCHAR *p = NULL;
	long int i = 0;
	IP sin;

	if (l == NULL) {
		return;
	} else {
		target = l->target;
	}

	ldb_update(l, node_id, token, from);

	p = ben_str_s(nodes);
	for (i = 0; i < ben_str_i(nodes); i += IP_SIZE_META_TRIPLE) {

		/* ID */
		id = p;
		p += SHA1_SIZE;

		/* IP + Port */
		p = ip_tuple_to_sin(&sin, p);

		/* Ignore myself */
		if (node_me(id)) {
			continue;
		}

		/* Ignore link-local address */
		if (ip_is_linklocal(&sin)) {
			continue;
		}

		nbhd_put(id, &sin);

		/* Node known. Do not send requests twice. Stop here. */
		if (ldb_find(l, id) != NULL) {
			continue;
		}

		/* Add this node to a sorted list. And only send a new lookup request
		 * to this node if it gets inserted on top of the sorted list. */
		if (ldb_put(l, id, (IP *) & sin) >= 8) {
			continue;
		}

		/* Send a new lookup request. */
		send_get_peers_request((IP *) & sin, target, tdb_tid(ti));
	}
}
Exemplo n.º 2
0
void p2p_cron_lookup(UCHAR * target, int type)
{
	UCHAR nodes_compact_list[IP_SIZE_META_TRIPLE8];
	int nodes_compact_size = 0;
	LOOKUP *l = NULL;
	UCHAR *p = NULL;
	UCHAR *id = NULL;
	ITEM *ti = NULL;
	int j = 0;
	IP sin;

	/* Start the incremental remote search program */
	nodes_compact_size = bckt_compact_list(_main->nbhd->bucket,
					       nodes_compact_list, target);

	/* Create tid and get the lookup table */
	ti = tdb_put(type);
	l = ldb_init(target, NULL, NULL);
	tdb_link_ldb(ti, l);

	p = nodes_compact_list;
	for (j = 0; j < nodes_compact_size; j += IP_SIZE_META_TRIPLE) {

		/* ID */
		id = p;
		p += SHA1_SIZE;

		/* IP + Port */
		p = ip_tuple_to_sin(&sin, p);

		/* Remember queried node */
		ldb_put(l, id, &sin);

		/* Query node */
		send_get_peers_request(&sin, target, tdb_tid(ti));
	}
}
Exemplo n.º 3
0
int ctl_cmd_parse(struct data_node *p_node)
{
    int ret = 0;
    unsigned int loop = 0;
    int ok = 0;
    unsigned int i, j = 0;
    int offset = 0;
    size_t mlen = 0;
    char *p_new = NULL;
    char *p_old = NULL;
    char *result = NULL;
    char ret_number[16] = { 0 };
    int size = 0;
    int sum = 0;

    if (p_node->status == X_MALLOC_FAILED) {
        add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY));
        return X_MALLOC_FAILED;
    }
    if (p_node->gtlen > MAX_CMD_LEN) {
        add_send_node(p_node, OPT_DATA_TOO_LARGE, strlen(OPT_DATA_TOO_LARGE));
        return X_DATA_TOO_LARGE;
    }
    /* parse cmd */
    char *data = p_node->svbf;
    log_debug("%s", data);
    if (data[0] == '*') {
        // 1. read the arg count:
        if (p_node->kvs == 0) {
            p_new = p_old = &data[1];
            CHECK_BUFFER(p_new, 0);
            p_node->kvs = atoi(p_old);
            p_node->doptr = p_new - data;
        }
        // 2. read the request name
        if (p_node->cmd == 0) {
            if (data[p_node->doptr] != '$') {
                goto E_OUT_PUT;
            }
            p_new = p_old = &data[p_node->doptr + 1];
            CHECK_BUFFER(p_new, 0);
            mlen = atoi(p_old);
            p_old = p_new;
            CHECK_BUFFER(p_new, mlen);
            for (i = 0; i < mlen; i++) {
                if (*(p_old + i) > 'Z') {
                    *(p_old + i) -= 32;/* 'A' - 'a' */
                }
                p_node->cmd = p_node->cmd * 26 + (*(p_old + i) - 'A');/* A~Z is 26 numbers */
            }
            p_node->doptr = p_new - data;
        }log_debug("%d", p_node->cmd);
        // 3. read a arg
        switch (p_node->cmd) {
        case LDB_SET:
            if (LDB_READONLY_SWITCH == 1 || p_node->kvs != LDB_SET_CNT) {
                goto E_OUT_PUT;
            }
            PARSE_LEN(p_node->klen);
            PARSE_MEMBER(p_node->key, p_node->klen);
            PARSE_LEN(p_node->vlen);
            PARSE_MEMBER(p_node->val, p_node->vlen);
            // x_out_time(&g_dbg_time);
            ok = ldb_put(g_ldb, &data[p_node->key], p_node->klen,
                    &data[p_node->val], p_node->vlen);
            // x_out_time(&g_dbg_time);
            goto W_OUT_PUT;

        case LDB_DEL:
            if (LDB_READONLY_SWITCH == 1 || p_node->kvs < LDB_DEL_MIN) {
                goto E_OUT_PUT;
            }
            loop = p_node->kvs - 1;
            sum = 0;
            for (j = 0; j < loop; ++j) {
                PARSE_LEN(p_node->klen);
                PARSE_MEMBER(p_node->key, p_node->klen);
                ok = ldb_delete(g_ldb, &data[p_node->key], p_node->klen);
                if (ok < 0) {
                    goto E_OUT_PUT;
                }
                sum += ok;
                p_node->kvs -= 1;
                p_node->key = 0;
                p_node->klen = 0;
            }
            goto NUM_OUT_PUT;

        case LDB_MSET:/* use one thread to write, otherwise (one thread should use one leveldb_writebatch_t) or (add a mutex lock) */
            if (LDB_READONLY_SWITCH == 1) {
                goto E_OUT_PUT;
            }
            loop = (p_node->kvs - 1) / 2;
            if (loop < 1) {
                goto E_OUT_PUT;
            }
            for (j = 0; j < loop; ++j) {
                PARSE_LEN(p_node->klen);
                PARSE_MEMBER(p_node->key, p_node->klen);
                PARSE_LEN(p_node->vlen);
                PARSE_MEMBER(p_node->val, p_node->vlen);
                ldb_batch_put(g_ldb, &data[p_node->key], p_node->klen,
                        &data[p_node->val], p_node->vlen);
                p_node->kvs -= 2;
                p_node->klen = 0;
                p_node->key = 0;
                p_node->vlen = 0;
                p_node->val = 0;
            }
            ok = ldb_batch_commit(g_ldb);
            goto W_OUT_PUT;

        case LDB_GET:
            if (p_node->kvs != LDB_GET_CNT) {
                goto E_OUT_PUT;
            }
            PARSE_LEN(p_node->klen);
            PARSE_MEMBER(p_node->key, p_node->klen);
            log_debug("key = %s", &data[ p_node->key ]);
            result = ldb_get(g_ldb, &data[p_node->key], p_node->klen, &size);
            log_debug("val = %s", result);
            goto R_BULK_OUT_PUT;

        case LDB_LRANGE:
            if (p_node->kvs != LDB_LRANGE_CNT) {
                goto E_OUT_PUT;
            }
            PARSE_LEN(p_node->klen);
            PARSE_MEMBER(p_node->key, p_node->klen);
            /* look as prefix key */
            PARSE_LEN(p_node->vlen);
            PARSE_MEMBER(p_node->val, p_node->vlen);
            /* look as start time */
            PARSE_LEN(p_node->vlen2);
            PARSE_MEMBER(p_node->val2, p_node->vlen2);
            /* look as end time */
            log_debug("prefix key = %s", &data[ p_node->key ]);
            log_debug("start = %s", &data[ p_node->val ]);
            log_debug("end = %s", &data[ p_node->val2 ]);
            result = ldb_lrangeget(g_ldb, &data[p_node->key], p_node->klen,
                    &data[p_node->val], p_node->vlen, &data[p_node->val2],
                    p_node->vlen2, &size);
            goto R_MULTI_OUT_PUT;

        case LDB_KEYS:
            if (p_node->kvs != LDB_KEYS_CNT) {
                goto E_OUT_PUT;
            }
            PARSE_LEN(p_node->klen);
            PARSE_MEMBER(p_node->key, p_node->klen);
            result = ldb_keys(g_ldb, &data[p_node->key], p_node->klen, &size);
            log_debug("size = %d", size);
            goto R_MULTI_OUT_PUT;

        case LDB_INFO:
            if (p_node->kvs != LDB_INFO_CNT) {
                goto E_OUT_PUT;
            }
            result = ldb_info(g_ldb, &size);
            log_debug("size = %d\n", size);
            goto R_MULTI_OUT_PUT;

        case LDB_PING:
            if (p_node->kvs != LDB_PING_CNT) {
                goto E_OUT_PUT;
            }
            add_send_node(p_node, OPT_PONG, strlen(OPT_PONG));
            return X_DATA_IS_ALL;

        case LDB_EXISTS:
            if (p_node->kvs != LDB_EXISTS_CNT) {
                goto E_OUT_PUT;
            }
            PARSE_LEN(p_node->klen);
            PARSE_MEMBER(p_node->key, p_node->klen);
            ok = ldb_exists(g_ldb, &data[p_node->key], p_node->klen);
            if (ok == -1) {
                goto E_OUT_PUT;
            }
            sum = ok;
            goto NUM_OUT_PUT;

        case LDB_QUIT:
            log_debug("-----------------------------------------------------");
            return X_CLIENT_QUIT;

        default:
            goto E_OUT_PUT;
        }
E_OUT_PUT:
        add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR));
        return X_ERROR_CMD;

W_OUT_PUT:
        if (ok == 0) {
            log_debug("------------------------------------------");
            add_send_node(p_node, OPT_OK, strlen(OPT_OK));
            return X_DATA_IS_ALL;
        } else {
            add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR));
            return X_ERROR_LDB;
        }

NUM_OUT_PUT:
        sprintf(ret_number, OPT_NUMBER, sum);
        log_debug("%s", ret_number);
        add_send_node(p_node, ret_number, strlen(ret_number));
        return X_DATA_IS_ALL;

R_BULK_OUT_PUT:
        if (result) {
            char tmp[32] = { 0 };
            sprintf(tmp, "$%d\r\n", size);
            ret = add_send_node(p_node, tmp, strlen(tmp));
            ret = add_send_node(p_node, result, size);
            leveldb_free(result);
            if (ret == X_MALLOC_FAILED) {
                clean_send_node(p_node);
                add_send_node(p_node, OPT_NO_MEMORY, strlen(OPT_NO_MEMORY));
                return X_MALLOC_FAILED;
            }
            ret = add_send_node(p_node, "\r\n", 2);
            return X_DATA_IS_ALL;
        } else {
            if (size == 0) {
                add_send_node(p_node, OPT_NULL, strlen(OPT_NULL));
                return X_DATA_IS_ALL;
            } else {
                add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR));
                return X_ERROR_LDB;
            }
        }

R_MULTI_OUT_PUT:
        if (result) {
            set_send_node(p_node, result, size);
            return X_DATA_IS_ALL;
        } else {
            if (size == 0) {
                add_send_node(p_node, OPT_NULL, strlen(OPT_NULL));
                return X_DATA_IS_ALL;
            } else {
                add_send_node(p_node, OPT_LDB_ERROR, strlen(OPT_LDB_ERROR));
                return X_ERROR_LDB;
            }
        }
    } else if (data[0] == '$') {
#if 0
        // 1. read the request name
        if (p_node->cmd == 0) {
            p_new = p_old = &data[1];
            CHECK_BUFFER(p_new, 0);
            mlen = atoi( p_old );
            p_old = p_new;
            CHECK_BUFFER(p_new, mlen);
            for (i = 0; i < mlen; i++) {
                p_node->cmd = p_node->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */
            }
            p_node->doptr = p_new - data;
        }
        log_debug("%d\n", p_node->cmd);
        // 2. read a arg
        switch (p_node->cmd) {
            case LDB_QUIT:
            return CLIENT_QUIT;
            default:
            log_debug("-----------------------------------------------------\n");
            return -1;
        }

        //TODO
#endif
        add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR));
        return X_ERROR_CMD;
    } else {
        add_send_node(p_node, OPT_CMD_ERROR, strlen(OPT_CMD_ERROR));
        return X_ERROR_CMD;
    }
    return X_DATA_IS_ALL;
}