Esempio n. 1
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;
}
Esempio n. 2
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. 3
0
int dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg)
{
	struct lump* lump, *crt, *prev_crt =0, *a, *foo;
	int offset;
	int len,n;
	char *prefix=NULL,*suffix=NULL,*p,*p_init,*ct_username=NULL;
	int prefix_len,suffix_len,ct_username_len=0;
	struct sip_uri ctu;
	str contact;

	if(!msg->contact)
	{
		if(parse_headers(msg, HDR_CONTACT_F, 0)< 0)
		{
			LM_ERR("Failed to parse headers\n");
			return -1;
		}
		if(!msg->contact)
			return 0;
	}

	prefix_len = 5; /* <sip: */

	if (dlg->flags & DLG_FLAG_TOPH_KEEP_USER) {
		if ( parse_contact(msg->contact)<0 ||
			((contact_body_t *)msg->contact->parsed)->contacts==NULL ||
			((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL ) {
				LM_ERR("bad Contact HDR\n");
		} else {
			contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri;
			if(parse_uri(contact.s, contact.len, &ctu) < 0) {
				LM_ERR("Bad Contact URI\n");
			} else {
				ct_username = ctu.user.s;
				ct_username_len = ctu.user.len;
				LM_DBG("Trying to propagate username [%.*s]\n",ct_username_len,
									ct_username);
				if (ct_username_len > 0)
					prefix_len += 1 + /* @ */ + ct_username_len;
			}
		}
	}

	prefix = pkg_malloc(prefix_len);
	if (!prefix) {
		LM_ERR("no more pkg\n");
		goto error;
	}

	suffix_len = RR_DLG_PARAM_SIZE+1; /* > */
	suffix = pkg_malloc(suffix_len);
	if (!suffix) {
		LM_ERR("no more pkg\n");
		goto error;
	}

	memcpy(prefix,"<sip:",prefix_len);
	if (dlg->flags & DLG_FLAG_TOPH_KEEP_USER && ct_username_len > 0) {
		memcpy(prefix+5,ct_username,ct_username_len);
		prefix[prefix_len-1] = '@';
	}

	p_init = p = suffix;
	*p++ = ';';
	memcpy(p,rr_param.s,rr_param.len);
	p+=rr_param.len;
	*p++ = '=';

	n = RR_DLG_PARAM_SIZE - (p-p_init);
	if (int2reverse_hex( &p, &n, dlg->h_entry)==-1)
		return -1;

	*(p++) = DLG_SEPARATOR;

	n = RR_DLG_PARAM_SIZE - (p-p_init);
	if (int2reverse_hex( &p, &n, dlg->h_id)==-1)
		return -1;

	*p++ = '>';
	suffix_len = p - p_init;

	offset = msg->contact->body.s - msg->buf;
	len = msg->contact->body.len;

	for (crt = msg->add_rm;crt;) {
		if (crt->type == HDR_CONTACT_T && crt->op == LUMP_DEL &&
				crt->u.offset >= offset && crt->u.offset <= offset + len) {
			lump = crt;
			crt = crt->next;
			a=lump->before;
			while(a) {
				LM_DBG("before [%p], op=%d\n", a, a->op);
				if(a->op == LUMP_ADD)
					LM_DBG("value= %.*s\n", a->len, a->u.value);
				foo=a; a=a->before;
				if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(foo);
				if (!(foo->flags&LUMPFLAG_SHMEM))
					pkg_free(foo);
			}

			a=lump->after;
			while(a) {
				LM_DBG("after [%p], op=%d\n", a, a->op);
				if(a->op == LUMP_ADD)
					LM_DBG("value= %.*s\n", a->len, a->u.value);
				foo=a; a=a->after;
				if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(foo);
				if (!(foo->flags&LUMPFLAG_SHMEM))
					pkg_free(foo);
			}
			if(lump == msg->add_rm)
				msg->add_rm = lump->next;
			else
				prev_crt->next = lump->next;
			if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
				free_lump(lump);
			if (!(lump->flags&LUMPFLAG_SHMEM))
				pkg_free(lump);
			continue;
		}
		prev_crt = crt;
		crt= crt->next;
	}

	if ((lump = del_lump(msg, msg->contact->body.s - msg->buf, msg->contact->body.len,HDR_CONTACT_T)) == 0) {
		LM_ERR("del_lump failed\n");
		goto error;
	}

	if ((lump = insert_new_lump_after(lump,prefix,prefix_len,HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting '<sip:'\n");
		goto error;
	}
	/* make sure we do not free this string in case of a further error */
	prefix = NULL;

	if ((lump = insert_subst_lump_after(lump, SUBST_SND_ALL, HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting SUBST_SND buf\n");
		goto error;
	}

	if ((lump = insert_new_lump_after(lump,suffix,suffix_len,HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting '<sip:'\n");
		goto error;
	}


	return 0;
error:
	if (prefix) pkg_free(prefix);
	if (suffix) pkg_free(suffix);
	return -1;
}
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;
}
Esempio n. 5
0
int dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg)
{
//	str local_contact;
	struct lump* lump, *crt, *prev_crt =0, *a, *foo;
	int offset;
	int len,n;
	char *prefix=NULL,*suffix=NULL,*p,*p_init;
	int prefix_len,suffix_len;

	if(!msg->contact)
	{
		if(parse_headers(msg, HDR_CONTACT_F, 0)< 0)
		{
			LM_ERR("Failed to parse headers\n");
			return -1;
		}
		if(!msg->contact)
			return 0;
	}

	prefix_len = 5; /* <sip: */
	prefix = pkg_malloc(prefix_len);
	if (!prefix) {
		LM_ERR("no more pkg\n");
		goto error;
	}

	suffix_len = RR_DLG_PARAM_SIZE+1; /* > */
	suffix = pkg_malloc(suffix_len);
	if (!suffix) {
		LM_ERR("no more pkg\n");
		goto error;
	}

	memcpy(prefix,"<sip:",prefix_len);
	
	p_init = p = suffix;
	*p++ = ';';
	memcpy(p,"did",3);
	p+=3;
	*p++ = '=';

	n = RR_DLG_PARAM_SIZE - (p-p_init);
	if (int2reverse_hex( &p, &n, dlg->h_entry)==-1)
		return -1;

	*(p++) = DLG_SEPARATOR;

	n = RR_DLG_PARAM_SIZE - (p-p_init);
	if (int2reverse_hex( &p, &n, dlg->h_id)==-1)
		return -1;

	*p++ = '>';
	suffix_len = p - p_init;

	offset = msg->contact->body.s - msg->buf;
	len = msg->contact->body.len;

	for (crt = msg->add_rm;crt;) {
		if (crt->type == HDR_CONTACT_T && crt->op == LUMP_DEL &&
				crt->u.offset >= offset && crt->u.offset <= offset + len) {
			lump = crt;
			crt = crt->next;
			a=lump->before;
			while(a) {
				LM_DBG("before [%p], op=%d\n", a, a->op);
				if(a->op == LUMP_ADD)
					LM_DBG("value= %.*s\n", a->len, a->u.value);
				foo=a; a=a->before;
				if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(foo);
				if (!(foo->flags&LUMPFLAG_SHMEM))
					pkg_free(foo);
			}

			a=lump->after;
			while(a) {
				LM_DBG("after [%p], op=%d\n", a, a->op);
				if(a->op == LUMP_ADD)
					LM_DBG("value= %.*s\n", a->len, a->u.value);
				foo=a; a=a->after;
				if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(foo);
				if (!(foo->flags&LUMPFLAG_SHMEM))
					pkg_free(foo);
			}
			if(lump == msg->add_rm)
				msg->add_rm = lump->next;
			else
				prev_crt->next = lump->next;
			if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
				free_lump(lump);
			if (!(lump->flags&LUMPFLAG_SHMEM))
				pkg_free(lump);
			continue;
		}
		prev_crt = crt;
		crt= crt->next;
	}

	if ((lump = del_lump(msg, msg->contact->body.s - msg->buf, msg->contact->body.len,HDR_CONTACT_T)) == 0) {
		LM_ERR("del_lump failed \n");
		goto error;
	}

	if ((lump = insert_new_lump_after(lump,prefix,prefix_len,HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting '<sip:'\n");
		goto error;
	}

	if ((lump = insert_subst_lump_after(lump, SUBST_SND_ALL, HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting SUBST_SND buf\n");
		goto error;
	}

	if ((lump = insert_new_lump_after(lump,suffix,suffix_len,HDR_CONTACT_T)) == 0) {
		LM_ERR("failed inserting '<sip:'\n");
		goto error;
	}
	
//	LM_DBG("Replaced contact with [%.*s]\n", local_contact.len, local_contact.s);

	return 0;
error:
	if (prefix) pkg_free(prefix);
	if (suffix) pkg_free(suffix);
	return -1;
}