Esempio n. 1
0
/*!
 * \brief Appends a new Record-Route parameter
 * \param msg SIP message
 * \param rr_param RR parameter
 * \return 0 on success, -1 on failure
 */
int add_rr_param(struct sip_msg* msg, str* rr_param)
{
    struct lump *last_param;
    struct lump *root;

    root = msg->add_rm;
    last_param = get_rr_param_lump( &root );
    if (last_param) {
        /* RR was already done -> have to add a new lump before this one */
        if (insert_rr_param_lump( last_param, rr_param->s, rr_param->len)==0) {
            LM_ERR("failed to add lump\n");
            goto error;
        }
        /* double routing enabled? */
        if (enable_double_rr) {
            if (root==0 || (last_param=get_rr_param_lump(&root))==0) {
                LM_CRIT("failed to locate double RR lump\n");
                goto error;
            }
            if (insert_rr_param_lump(last_param,rr_param->s,rr_param->len)==0) {
                LM_ERR("failed to add 2nd lump\n");
                goto error;
            }
        }
    } else {
        /* RR not done yet -> store the param in the static buffer */
        if (rr_param_msg!=msg->id) {
            /* it's about a different message -> reset buffer */
            rr_param_buf.len = 0;
            rr_param_msg = msg->id;
        }
        if (rr_param_buf.len+rr_param->len>RR_PARAM_BUF_SIZE) {
            LM_ERR("maximum size of rr_param_buf exceeded\n");
            goto error;
        }
        memcpy( rr_param_buf.s+rr_param_buf.len, rr_param->s, rr_param->len);
        rr_param_buf.len += rr_param->len;
        LM_DBG("rr_param_buf=<%.*s>\n",rr_param_buf.len, rr_param_buf.s);
    }
    return 0;

error:
    return -1;
}
Esempio n. 2
0
/*! \brief
 * Appends a new Record-Route parameter
 */
int add_rr_param(struct sip_msg* msg, str* rr_param)
{
	struct lump *l;
	struct lump *crt;
	int rr_found=0;

	LM_DBG("adding (%.*s)\n",rr_param->len,rr_param->s);

	for( crt=msg->add_rm ; crt ; crt=crt->next ) {

		if (crt->type!=HDR_RECORDROUTE_T || crt->op!=LUMP_NOP)
			continue;

		/* found a RR-related anchor; we are looking for the
		 * "second RR lump" (having data on "before") or for the
		 * "buffering lump" (having also data on "before") */

		if (!crt->before)
			continue;

		if (!rr_found && crt->before->op==LUMP_ADD_OPT
		&& crt->before->u.cond==COND_FALSE ) {
			LM_DBG("buffering lump was found\n");
			/* this is the "buffering lump" */
			/* RR not done, but some RR params are already buffered -> 
			   add a before lump to the existing buffering one */

			/* get the last param attached on the anchor */
			for( l=crt->before->before ; l && l->before ; l=l->before);
			/* add the param */
			if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) {
				LM_ERR("failed to add buffered lump\n");
				goto error;
			}

			return 0;
		}

		/* this is a "second RR lump" */
		LM_DBG("second RR lump found\n");
		/* RR was already done -> have to add a new lump before last param */
		for (l=crt->before ; l && l->op!=LUMP_ADD ; l=l->before );
		if (l==NULL) {
			LM_CRIT("BUG - second RR anchor has no ADD on before\n");
			return -1;
		}
		if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) {
			LM_ERR("failed to add lump\n");
			goto error;
		}
		/* double routing enabled? */
		if (!enable_double_rr)
			/* done */
			return 0;

		/* continue looking for more RR headers */
		rr_found = 1;
	}

	/* param already added to existing RR headers ? */
	if (rr_found)
		return 0;

	/* RR not done, no other RR param added so far ->
	   create the phony anchor and add the lump to it */
	crt = anchor_lump(msg, msg->headers->name.s-msg->buf, HDR_RECORDROUTE_T);
	if (crt==NULL) {
		LM_ERR("cannot create phony lump for buffering params\n");
		goto error;
	}
	l = insert_cond_lump_before( crt, COND_FALSE, 0);
	if (l==NULL) {
		LM_ERR("cannot create conditional lump for buffering params\n");
		goto error;
	}
	if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) {
		LM_ERR("failed to add buffered lump\n");
		goto error;
	}

	return 0;
error:
	return -1;
}
Esempio n. 3
0
static inline int build_advertised_rr(struct lump* _l, struct lump* _l2, str *_data,
                                      str* user, str *tag, int _inbound, int _sips)
{
    char *p;
    char *hdr, *trans, *r2, *suffix, *term;
    int hdr_len, suffix_len;
    char *rr_prefix;
    int rr_prefix_len;

    if(_sips==0) {
        rr_prefix = RR_PREFIX_SIP;
        rr_prefix_len = RR_PREFIX_SIP_LEN;
    } else {
        rr_prefix = RR_PREFIX_SIPS;
        rr_prefix_len = RR_PREFIX_SIPS_LEN;
    }

    hdr_len = rr_prefix_len;
    if (user && user->len)
        hdr_len += user->len + 1; /* @ */
    hdr_len += _data->len;

    suffix_len = 0;
    if (tag && tag->len) {
        suffix_len += RR_FROMTAG_LEN + tag->len;
    }

    if (enable_full_lr) {
        suffix_len += RR_LR_FULL_LEN;
    } else {
        suffix_len += RR_LR_LEN;
    }

    hdr = pkg_malloc(hdr_len);
    trans = pkg_malloc(RR_TRANS_LEN);
    suffix = pkg_malloc(suffix_len);
    r2 = pkg_malloc(RR_R2_LEN);
    term = pkg_malloc(RR_TERM_LEN);
    if (!hdr || !trans || !suffix || !term || !r2) {
        LM_ERR("no pkg memory left\n");
        if (hdr) pkg_free(hdr);
        if (trans) pkg_free(trans);
        if (suffix) pkg_free(suffix);
        if (r2) pkg_free(r2);
        if (term) pkg_free(term);
        return -1;
    }

    p = hdr;
    memcpy(p, rr_prefix, rr_prefix_len);
    p += rr_prefix_len;

    if (user && user->len) {
        memcpy(p, user->s, user->len);
        p += user->len;
        *p = '@';
        p++;
    }

    memcpy(p, _data->s, _data->len);

    p = suffix;
    if (tag && tag->len) {
        memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
        p += RR_FROMTAG_LEN;
        memcpy(p, tag->s, tag->len);
        p += tag->len;
    }

    if (enable_full_lr) {
        memcpy(p, RR_LR_FULL, RR_LR_FULL_LEN);
        p += RR_LR_FULL_LEN;
    } else {
        memcpy(p, RR_LR, RR_LR_LEN);
        p += RR_LR_LEN;
    }

    memcpy(trans, RR_TRANS, RR_TRANS_LEN);
    memcpy(term, RR_TERM, RR_TERM_LEN);
    memcpy(r2, RR_R2, RR_R2_LEN);

    if (!(_l = insert_new_lump_after(_l, hdr, hdr_len, 0))) {
        LM_ERR("failed to insert new lump\n");
        goto lump_err;
    }
    hdr = NULL;
    if (!(_l = insert_cond_lump_after(_l,
                                      (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0)))
        goto lump_err;
    if (!(_l = insert_new_lump_after(_l, trans, RR_TRANS_LEN, 0)))
        goto lump_err;
    if (!(_l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_PROTO:SUBST_SND_PROTO, 0)))
        goto lump_err;
    if (enable_double_rr) {
        if (!(_l = insert_cond_lump_after(_l,
                                          (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0)))
            goto lump_err;
        if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0)))
            goto lump_err;
        r2 = 0;
    } else {
        pkg_free(r2);
        r2 = 0;
    }
    if (!(_l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T)))
        goto lump_err;
    suffix = NULL;
    if (rr_param_buf.len) {
        if (!(_l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len)))
            goto lump_err;
    }
    if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0)))
        goto lump_err;
    return 1;
lump_err:
    if (hdr) pkg_free(hdr);
    if (trans) pkg_free(trans);
    if (suffix) pkg_free(suffix);
    if (term) pkg_free(term);
    if (r2) pkg_free(r2);
    return -7;
}
Esempio n. 4
0
/*!
 * \brief Build a Record-Route header field
 *
* Build a Record-Route header field, allocates new private memory for this.
 * \param _l first lump
 * \param _l2 second lump
 * \param user user parameter
 * \param tag tag parameter
 * \param params parameter
 * \param _inbound inbound request
 * \return 0 on success, negative on failure
 */
static inline int build_rr(struct lump* _l, struct lump* _l2, str* user,
                           str *tag, str *params, int _inbound, int _sips)
{
    char* prefix, *suffix, *term, *r2;
    int suffix_len, prefix_len;
    char *p;
    char *rr_prefix;
    int rr_prefix_len;

    if(_sips==0) {
        rr_prefix = RR_PREFIX_SIP;
        rr_prefix_len = RR_PREFIX_SIP_LEN;
    } else {
        rr_prefix = RR_PREFIX_SIPS;
        rr_prefix_len = RR_PREFIX_SIPS_LEN;
    }

    prefix_len = rr_prefix_len + (user->len ? (user->len + 1) : 0);
    if (enable_full_lr) {
        suffix_len = RR_LR_FULL_LEN + (params?params->len:0) +
                     ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
    } else {
        suffix_len = RR_LR_LEN + (params?params->len:0) +
                     ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
    }

    prefix = pkg_malloc(prefix_len);
    suffix = pkg_malloc(suffix_len);
    term = pkg_malloc(RR_TERM_LEN);
    r2 = pkg_malloc(RR_R2_LEN);

    if (!prefix || !suffix || !term || !r2) {
        LM_ERR("No more pkg memory\n");
        if (suffix) pkg_free(suffix);
        if (prefix) pkg_free(prefix);
        if (term) pkg_free(term);
        if (r2) pkg_free(r2);
        return -3;
    }

    memcpy(prefix, rr_prefix, rr_prefix_len);
    if (user->len) {
        memcpy(prefix + rr_prefix_len, user->s, user->len);
#ifdef ENABLE_USER_CHECK
        /* don't add the ignored user into a RR */
        if(i_user.len && i_user.len == user->len &&
                !strncmp(i_user.s, user->s, i_user.len))
        {
            if(prefix[rr_prefix_len]=='x')
                prefix[rr_prefix_len]='y';
            else
                prefix[rr_prefix_len]='x';
        }
#endif
        prefix[rr_prefix_len + user->len] = '@';
    }

    p = suffix;
    if (enable_full_lr) {
        memcpy( p, RR_LR_FULL, RR_LR_FULL_LEN);
        p += RR_LR_FULL_LEN;
    } else {
        memcpy( p, RR_LR, RR_LR_LEN);
        p += RR_LR_LEN;
    }
    if (tag && tag->len) {
        memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
        p += RR_FROMTAG_LEN;
        memcpy(p, tag->s, tag->len);
        p += tag->len;
    }
    if (params && params->len) {
        memcpy(p, params->s, params->len);
        p += params->len;
    }

    memcpy(term, RR_TERM, RR_TERM_LEN);
    memcpy(r2, RR_R2, RR_R2_LEN);

    if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0)))
        goto lump_err;
    prefix = 0;
    _l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_ALL:SUBST_SND_ALL, 0);
    if (_l ==0 )
        goto lump_err;
    if (enable_double_rr) {
        if (!(_l = insert_cond_lump_after(_l,
                                          (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0)))
            goto lump_err;
        if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0)))
            goto lump_err;
        r2 = 0;
    } else {
        pkg_free(r2);
        r2 = 0;
    }
    _l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T);
    if (_l2 == 0)
        goto lump_err;
    if (rr_param_buf.len) {
        _l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len);
        if (_l2 == 0)
            goto lump_err;
    }
    suffix = 0;
    if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0)))
        goto lump_err;
    term = 0;
    return 0;

lump_err:
    LM_ERR("failed to insert lumps\n");
    if (prefix) pkg_free(prefix);
    if (suffix) pkg_free(suffix);
    if (r2) pkg_free(r2);
    if (term) pkg_free(term);
    return -4;
}