Beispiel #1
0
/*! \brief
 * Insert a new Record-Route header field
 * And also 2nd one if it is enabled and realm changed so
 * the 2nd record-route header will be necessary
 */
int record_route(struct sip_msg* _m, str *params)
{
	struct lump* l, *l2, *lp, *lp2, *ap;
	str user;
	struct to_body* from;
	str* tag;

	from = 0; /* Makes gcc happy */
	user.len = 0;
	lp = lp2 = NULL;

	if (add_username) {
		if (get_username(_m, &user) < 0) {
			LM_ERR("failed to extract username\n");
			return -1;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		from = (struct to_body*)_m->from->parsed;
		tag = &from->tag_value;
	} else {
		tag = 0;
	}

	l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	if (!l || !l2) {
		LM_ERR("failed to create an anchor\n");
		return -3;
	}

	/* look for pending RR params */
	for( lp2=NULL,lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) {
		if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP
		&& ap->before && ap->before->op==LUMP_ADD_OPT
		&& ap->before->u.cond==COND_FALSE) {
			/* found our phony anchor lump */
			/* jump over the anchor and conditional lumps */
			lp = ap->before->before;
			/* unlink it */
			ap->before->before = NULL;
			ap->type = 0;
			/* if double routing, make a copy of the buffered lumps for the
			   second route hdr. */
			if (enable_double_rr)
				lp2 = dup_lump_list(lp);
			break;
		}
	}

	if (build_rr(l, l2, &user, tag, params, lp, OUTBOUND) < 0) {
		LM_ERR("failed to insert inbound Record-Route\n");
		return -4;
	}

	if (enable_double_rr) {
		l = anchor_lump(_m, _m->headers->name.s - _m->buf,HDR_RECORDROUTE_T);
		l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
		if (!l || !l2) {
			LM_ERR("failed to create an anchor\n");
			return -5;
		}
		l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0);
		l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0);
		if (!l || !l2) {
			LM_ERR("failed to insert conditional lump\n");
			return -6;
		}
		if (build_rr(l, l2, &user, tag, params, lp2, INBOUND) < 0) {
			LM_ERR("failed to insert outbound Record-Route\n");
			return -7;
		}
	}

	return 0;
}
Beispiel #2
0
int record_route_advertised_address(struct sip_msg* _m, str* _data)
{
    str user = {NULL, 0};
    str *tag = NULL;
    struct lump* l;
    struct lump* l2;
    int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
    int sips;
    int ret = 0;

    user.len = 0;
    user.s = 0;

    if (add_username) {
        if (get_username(_m, &user) < 0) {
            LM_ERR("failed to extract username\n");
            return -1;
        }
    } else if (use_ob == 1) {
        if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
            LM_ERR("encoding outbound flow-token\n");
            return -1;
        }
    } else if (use_ob == 2) {
        if (copy_flow_token(&user, _m) != 0) {
            LM_ERR("copying outbound flow-token\n");
            return -1;
        }
    }

    if (append_fromtag) {
        if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) {
            if (parse_to_header(_m) < 0) {
                LM_ERR("To parsing failed\n");
                ret = -2;
                goto error;
            }
            tag = &((struct to_body*)_m->to->parsed)->tag_value;
        } else {
            if (parse_from_header(_m) < 0) {
                LM_ERR("From parsing failed\n");
                ret = -2;
                goto error;
            }
            tag = &((struct to_body*)_m->from->parsed)->tag_value;
        }
    } else {
        tag = 0;
    }

    sips = rr_is_sips(_m);

    if (enable_double_rr) {
        l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
        l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
        if (!l || !l2) {
            LM_ERR("failed to create an anchor\n");
            ret = -3;
            goto error;
        }
        l = insert_cond_lump_after(l,
                                   (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0);
        l2 = insert_cond_lump_before(l2,
                                     (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0);
        if (!l || !l2) {
            LM_ERR("failed to insert conditional lump\n");
            ret = -4;
            goto error;
        }
        if (build_advertised_rr(l, l2, _data, &user, tag, OUTBOUND,
                                sips) < 0) {
            LM_ERR("failed to insert outbound Record-Route\n");
            ret = -5;
            goto error;
        }
    }

    l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
    l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
    if (!l || !l2) {
        LM_ERR("failed to create an anchor\n");
        ret = -6;
        goto error;
    }

    if (build_advertised_rr(l, l2, _data, &user, tag, INBOUND, sips) < 0) {
        LM_ERR("failed to insert outbound Record-Route\n");
        ret = -7;
        goto error;
    }
    ret = 1;
error:
    if ((use_ob == 1) || (use_ob == 2))
        if (user.s != NULL)
            pkg_free(user.s);
    return ret;
}
Beispiel #3
0
/*! \brief
 * build a Record-Route header field
 */
static inline int build_rr(struct lump* _l, struct lump* _l2, str* user,
						str *tag, str *params, struct lump *lp, int _inbound)
{
	char* prefix, *suffix, *term, *r2;
	int suffix_len, prefix_len;
	char *p;

	prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0);
	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;
	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, 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, 0);
	if (_l2 == 0)
		goto lump_err;
	suffix = 0;
	if ( lp ) {
		/* link the pending buffered params and go at the end of the list */
		for ( _l2->before = lp ; _l2 && _l2->before ; _l2=_l2->before);
	}
	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;
}
Beispiel #4
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;
}
Beispiel #5
0
/*!
 * \brief Insert a new Record-Route header field with lr parameter
 *
 * Insert a new Record-Route header field and also 2nd one if it is enabled
 * and the realm changed so the 2nd record-route header will be necessary.
 * \param _m SIP message
 * \param params RR parameter
 * \return 0 on success, negative on failure
 */
int record_route(struct sip_msg* _m, str *params)
{
    struct lump* l, *l2;
    str user = {NULL, 0};
    str* tag;
    int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
    int sips;
    int ret = 0;

    user.len = 0;

    if (add_username) {
        /* check if there is a custom user set */
        if (get_custom_user(_m, &user) < 0) {
            if (get_username(_m, &user) < 0) {
                LM_ERR("failed to extract username\n");
                return -1;
            }
        }
    } else if (use_ob == 1) {
        if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
            LM_ERR("encoding outbound flow-token\n");
            return -1;
        }
    } else if (use_ob == 2) {
        if (copy_flow_token(&user, _m) != 0) {
            LM_ERR("copying outbound flow-token\n");
            return -1;
        }
    }

    if (append_fromtag) {
        if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) {
            if (parse_to_header(_m) < 0) {
                LM_ERR("To parsing failed\n");
                ret = -2;
                goto error;
            }
            tag = &((struct to_body*)_m->to->parsed)->tag_value;
        } else {
            if (parse_from_header(_m) < 0) {
                LM_ERR("From parsing failed\n");
                ret = -2;
                goto error;
            }
            tag = &((struct to_body*)_m->from->parsed)->tag_value;
        }
    } else {
        tag = 0;
    }

    if (rr_param_buf.len && rr_param_msg!=_m->id) {
        /* rr_params were set for a different message -> reset buffer */
        rr_param_buf.len = 0;
    }

    sips = rr_is_sips(_m);

    if (enable_double_rr) {
        l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
        l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
        if (!l || !l2) {
            LM_ERR("failed to create an anchor\n");
            ret = -5;
            goto error;
        }
        l = insert_cond_lump_after(l,
                                   (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0);
        l2 = insert_cond_lump_before(l2,
                                     (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0);
        if (!l || !l2) {
            LM_ERR("failed to insert conditional lump\n");
            ret = -6;
            goto error;
        }
        if (build_rr(l, l2, &user, tag, params, OUTBOUND, sips) < 0) {
            LM_ERR("failed to insert outbound Record-Route\n");
            ret = -7;
            goto error;
        }
    }

    l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
    l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
    if (!l || !l2) {
        LM_ERR("failed to create an anchor\n");
        ret = -3;
        goto error;
    }

    if (build_rr(l, l2, &user, tag, params, INBOUND, sips) < 0) {
        LM_ERR("failed to insert inbound Record-Route\n");
        ret = -4;
        goto error;
    }

    /* reset the rr_param buffer */
    rr_param_buf.len = 0;
    ret = 0;
error:
    if ((use_ob == 1) || (use_ob == 2))
        if (user.s != NULL)
            pkg_free(user.s);
    return ret;
}
Beispiel #6
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;
}
Beispiel #7
0
int record_route_advertised_address(struct sip_msg* _m, str* _data)
{
	str user;
	str *tag = NULL;
	struct lump* l;
	struct lump* l2;
	int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
	int sips;
	
	user.len = 0;
	user.s = 0;

	if (add_username) {
		if (get_username(_m, &user) < 0) {
			LM_ERR("failed to extract username\n");
			return -1;
		}
	} else if (use_ob == 1) {
		if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
			LM_ERR("encoding outbound flow-token\n");
			return -1;
		}
	} else if (use_ob == 2) {
		if (copy_flow_token(&user, _m) != 0) {
			LM_ERR("copying outbound flow-token\n");
			return -1;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		tag = &((struct to_body*)_m->from->parsed)->tag_value;
	}

	sips = rr_is_sips(_m);

	if (enable_double_rr) {
		l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
		l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
		if (!l || !l2) {
			LM_ERR("failed to create an anchor\n");
			return -3;
		}
		l = insert_cond_lump_after(l, COND_IF_DIFF_PROTO, 0);
		l2 = insert_cond_lump_before(l2, COND_IF_DIFF_PROTO, 0);
		if (!l || !l2) {
			LM_ERR("failed to insert conditional lump\n");
			return -4;
		}
		if (build_advertised_rr(l, l2, _data, &user, tag, OUTBOUND,
					sips) < 0) {
			LM_ERR("failed to insert outbound Record-Route\n");
			return -5;
		}
	}
	
	l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
	if (!l || !l2) {
		LM_ERR("failed to create an anchor\n");
		return -6;
	}
	
	if (build_advertised_rr(l, l2, _data, &user, tag, INBOUND, sips) < 0) {
		LM_ERR("failed to insert outbound Record-Route\n");
		return -7;
	}
	return 1;
}
Beispiel #8
0
/*!
 * \brief Insert a new Record-Route header field with lr parameter
 *
 * Insert a new Record-Route header field and also 2nd one if it is enabled
 * and the realm changed so the 2nd record-route header will be necessary.
 * \param _m SIP message
 * \param params RR parameter
 * \return 0 on success, negative on failure
 */
int record_route(struct sip_msg* _m, str *params)
{
	struct lump* l, *l2;
	str user;
	struct to_body* from = NULL;
	str* tag;
	int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
	int sips;
	
	user.len = 0;
	
	if (add_username) {
		/* check if there is a custom user set */
		if (get_custom_user(_m, &user) < 0) {
			if (get_username(_m, &user) < 0) {
				LM_ERR("failed to extract username\n");
				return -1;
			}
		}
	} else if (use_ob == 1) {
		if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
			LM_ERR("encoding outbound flow-token\n");
			return -1;
		}
	} else if (use_ob == 2) {
		if (copy_flow_token(&user, _m) != 0) {
			LM_ERR("copying outbound flow-token\n");
			return -1;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		from = (struct to_body*)_m->from->parsed;
		tag = &from->tag_value;
	} else {
		tag = 0;
	}

	if (rr_param_buf.len && rr_param_msg!=_m->id) {
		/* rr_params were set for a different message -> reset buffer */
		rr_param_buf.len = 0;
	}

	sips = rr_is_sips(_m);

	if (enable_double_rr) {
		l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
		l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
		if (!l || !l2) {
			LM_ERR("failed to create an anchor\n");
			return -5;
		}
		l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0);
		l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0);
		if (!l || !l2) {
			LM_ERR("failed to insert conditional lump\n");
			return -6;
		}
		if (build_rr(l, l2, &user, tag, params, OUTBOUND, sips) < 0) {
			LM_ERR("failed to insert outbound Record-Route\n");
			return -7;
		}
	}
	
	l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
	if (!l || !l2) {
		LM_ERR("failed to create an anchor\n");
		return -3;
	}
	
	if (build_rr(l, l2, &user, tag, params, INBOUND, sips) < 0) {
		LM_ERR("failed to insert inbound Record-Route\n");
		return -4;
	}

	/* reset the rr_param buffer */
	rr_param_buf.len = 0;
	return 0;
}