示例#1
0
void rmq_destroy(evi_reply_sock *sock)
{
	if (!sock)
		return;
	if ((sock->flags & EVI_ADDRESS) && sock->address.s)
		shm_free(sock->address.s);
	if ((sock->flags & EVI_PARAMS) && sock->params) {
		rmq_free_param((rmq_params_t *)sock->params);
		rmq_destroy_param((rmq_params_t *)sock->params);
	}
	shm_free(sock);
}
示例#2
0
/*
 * This is the parsing function
 * The socket grammar should be:
 * 		 [user [':' password] '@'] ip [':' port] '/' exchange
 */
static evi_reply_sock* rmq_parse(str socket)
{
    evi_reply_sock *sock = NULL;
    rmq_params_t *param;
    unsigned int len, i;
    const char* begin;
    str prev_token;

    enum state {
        ST_USER_HOST,	/* Username or hostname */
        ST_PASS_PORT,	/* Password or port part */
        ST_HOST,		/* Hostname part */
        ST_PORT,		/* Port part */
    } st;

    if (!socket.len || !socket.s) {
        LM_ERR("no socket specified\n");
        return NULL;
    }

    sock = shm_malloc(sizeof(evi_reply_sock) + sizeof(rmq_params_t));
    if (!sock) {
        LM_ERR("no more memory for socket\n");
        return NULL;
    }
    memset(sock, 0, sizeof(evi_reply_sock) + sizeof(rmq_params_t));
    param = (rmq_params_t*)(sock + 1);

    prev_token.s = 0;
    prev_token.len = 0;

    /* Initialize all attributes to 0 */
    st = ST_USER_HOST;
    begin = socket.s;
    len = socket.len;

    for(i = 0; i < len; i++) {
        switch(st) {
        case ST_USER_HOST:
            switch(socket.s[i]) {
            case '@':
                st = ST_HOST;
                if (dupl_string(&param->user, begin, socket.s + i)) goto err;
                begin = socket.s + i + 1;
                param->flags |= RMQ_PARAM_USER;
                break;

            case ':':
                st = ST_PASS_PORT;
                if (dupl_string(&prev_token, begin, socket.s + i) < 0) goto err;
                begin = socket.s + i + 1;
                break;

            case '/':
                if (dupl_string(&sock->address, begin, socket.s + i) < 0)
                    goto err;
                sock->flags |= EVI_ADDRESS;
                if (dupl_string(&param->exchange, socket.s + i + 1,
                                socket.s + len) < 0)
                    goto err;
                param->flags |= RMQ_PARAM_EXCH;
                goto success;
            }
            break;

        case ST_PASS_PORT:
            switch(socket.s[i]) {
            case '@':
                st = ST_HOST;
                param->user.len = prev_token.len;
                param->user.s = prev_token.s;
                param->flags |= RMQ_PARAM_USER;
                prev_token.s = 0;
                if (dupl_string(&param->pass, begin, socket.s + i) < 0)
                    goto err;
                param->flags |= RMQ_PARAM_PASS;
                begin = socket.s + i + 1;
                break;

            case '/':
                sock->address.len = prev_token.len;
                sock->address.s = prev_token.s;
                prev_token.s = 0;
                sock->flags |= EVI_ADDRESS;

                sock->port = str2s(begin, socket.s + i - begin, 0);
                if (!sock->port) {
                    LM_DBG("malformed port: %.*s\n",
                           (int)(socket.s + i - begin), begin);
                    goto err;
                }
                sock->flags |= EVI_PORT;
                if (dupl_string(&param->exchange, socket.s + i + 1,
                                socket.s + len) < 0)
                    goto err;
                param->flags |= RMQ_PARAM_EXCH;
                goto success;
            }
            break;

        case ST_HOST:
            switch(socket.s[i]) {
            case ':':
                st = ST_PORT;
                if (dupl_string(&sock->address, begin, socket.s + i) < 0)
                    goto err;
                sock->flags |= EVI_ADDRESS;
                begin = socket.s + i + 1;
                break;

            case '/':
                if (dupl_string(&sock->address, begin, socket.s + i) < 0)
                    goto err;
                sock->flags |= EVI_ADDRESS;

                if (dupl_string(&param->exchange, socket.s + i + 1,
                                socket.s + len) < 0)
                    goto err;
                param->flags |= RMQ_PARAM_EXCH;
                goto success;
            }
            break;

        case ST_PORT:
            switch(socket.s[i]) {
            case '/':
                sock->port = str2s(begin, socket.s + i - begin, 0);
                if (!sock->port) {
                    LM_DBG("malformed port: %.*s\n",
                           (int)(socket.s + i - begin), begin);
                    goto err;
                }
                sock->flags |= EVI_PORT;

                if (dupl_string(&param->exchange, socket.s + i + 1,
                                socket.s + len) < 0)
                    goto err;
                param->flags |= RMQ_PARAM_EXCH;
                goto success;
            }
            break;
        }
    }
    LM_WARN("not implemented %.*s\n", socket.len, socket.s);
    goto err;

success:
    if (!(sock->flags & EVI_PORT) || !sock->port) {
        sock->port = RMQ_DEFAULT_PORT;
        sock->flags |= EVI_PORT;
    }
    if (!(param->flags & RMQ_PARAM_USER) || !param->user.s) {
        param->user.s = param->pass.s = RMQ_DEFAULT_UP;
        param->user.len = param->pass.len = RMQ_DEFAULT_UP_LEN;
        param->flags |= RMQ_PARAM_USER|RMQ_PARAM_PASS;
    }

    sock->params = param;
    sock->flags |= EVI_PARAMS | RMQ_FLAG;

    return sock;
err:
    LM_ERR("error while parsing socket %.*s\n", socket.len, socket.s);
    if (prev_token.s)
        shm_free(prev_token.s);
    rmq_free_param(param);
    if (sock->address.s)
        shm_free(sock->address.s);
    shm_free(sock);
    return NULL;
}