Ejemplo n.º 1
0
void free_duped_lump_list(struct lump* l)
{
	struct lump *r, *foo,*crt;
	while(l){
		crt=l;
		l=l->next;

		r=crt->before;
		while(r){
			foo=r; r=r->before;
			/* (+): if a new item was introduced to the shallow-ly
			 * duped list, remove it completely, preserve it
			 * otherwise (it is still referred by original list)
			 */
			if (foo->flags!=LUMPFLAG_DUPED) 
					free_lump(foo);
			pkg_free(foo);
		}
		r=crt->after;
		while(r){
			foo=r; r=r->after;
			if (foo->flags!=LUMPFLAG_DUPED) /* (+) ... see above */
				free_lump(foo);
			pkg_free(foo);
		}
		
		/*clean current elem*/
		if (crt->flags!=LUMPFLAG_DUPED) /* (+) ... see above */
			free_lump(crt);
		pkg_free(crt);
	}
}
Ejemplo n.º 2
0
void free_lump_list(struct lump* l)
{
	struct lump* t, *r, *foo,*crt;
	t=l;
	while(t){
		crt=t;
		t=t->next;
	/*
		 dangerous recursive clean
		if (crt->before) free_lump_list(crt->before);
		if (crt->after)  free_lump_list(crt->after);
	*/
		/* no more recursion, clean after and before and that's it */
		r=crt->before;
		while(r){
			foo=r; r=r->before;
			free_lump(foo);
			pkg_free(foo);
		}
		r=crt->after;
		while(r){
			foo=r; r=r->after;
			free_lump(foo);
			pkg_free(foo);
		}
		
		/*clean current elem*/
		free_lump(crt);
		pkg_free(crt);
	}
}
Ejemplo n.º 3
0
void del_nonshm_lump( struct lump** lump_list )
{
	struct lump *r, *foo, *crt, **prev, *prev_r;

	prev = lump_list;
	crt = *lump_list;

	while (crt) {
		if (crt->flags!=LUMPFLAG_SHMEM) {
			/* unlink it */
			foo = crt;
			crt = crt->next;
			foo->next = 0;
			/* update the 'next' link of the previous lump */
			*prev = crt;
			/* entire before/after list must be removed */
			free_lump_list( foo );
		} else {
			/* check on before and prev list for non-shmem lumps */
			r = crt->after;
			prev_r = crt;
			while(r){
				foo=r; r=r->after;
				if (foo->flags!=LUMPFLAG_SHMEM) {
					prev_r->after = r;
					free_lump(foo);
					pkg_free(foo);
				} else {
					prev_r = foo;
				}
			}
			/* before */
			r = crt->before;
			prev_r = crt;
			while(r){
				foo=r; r=r->before;
				if (foo->flags!=LUMPFLAG_SHMEM) {
					prev_r->before = r;
					free_lump(foo);
					pkg_free(foo);
				} else {
					prev_r = foo;
				}
			}
			/* go to next lump */
			prev = &(crt->next);
			crt = crt->next;
		}
	}
}
Ejemplo n.º 4
0
static void free_rr_lump(struct lump **list)
{
	struct lump *prev_lump, *lump, *a, *foo, *next;
	int first_shmem;

	first_shmem=1;
	next=0;
	prev_lump=0;
	for(lump=*list;lump;lump=next) {
		next=lump->next;
		if (lump->type==HDR_RECORDROUTE_T) {
			/* may be called from railure_route */
			/* if (lump->flags & (LUMPFLAG_DUPED|LUMPFLAG_SHMEM)){
				LOG(L_CRIT, "BUG: free_rr_lmp: lump %p, flags %x\n",
						lump, lump->flags);
			*/	/* ty to continue */
			/*}*/
			a=lump->before;
			while(a) {
				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) {
				foo=a; a=a->after;
				if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(foo);
				if (!(foo->flags&LUMPFLAG_SHMEM))
					pkg_free(foo);
			}
			
			if (first_shmem && (lump->flags&LUMPFLAG_SHMEM)) {
				/* This is the first element of the
				shmemzied lump list, we can not unlink it!
				It wound corrupt the list otherwise if we
				are in failure_route. -- No problem, only the
				anchor is left in the list */
				
				LOG(L_DBG, "DEBUG: free_rr_lump: lump %p" \
						" is left in the list\n",
						lump);
				
				if (lump->len)
				    LOG(L_CRIT, "BUG: free_rr_lump: lump %p" \
						" can not be removed, but len=%d\n",
						lump, lump->len);
						
				prev_lump=lump;
			} else {
				if (prev_lump) prev_lump->next = lump->next;
				else *list = lump->next;
				if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)))
					free_lump(lump);
				if (!(lump->flags&LUMPFLAG_SHMEM))
					pkg_free(lump);
			}
		} else {
			/* store previous position */
			prev_lump=lump;
		}
		if (first_shmem && (lump->flags&LUMPFLAG_SHMEM))
			first_shmem=0;
	}
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
/* hide via, route sets and contacts */
static int topology_hiding(struct sip_msg *req,int extra_flags)
{
	struct dlg_cell *dlg;
	struct hdr_field *it;
	char* buf;
	struct lump* lump, *crt, *prev_crt =0, *a, *foo;
	struct cell* t;

	t = d_tmb.t_gett();
	if (t == T_UNDEFINED)
		t=NULL;
	dlg = get_current_dialog();
	if(!dlg) {
		if(dlg_create_dialog( t, req, 0) != 0) {
			LM_ERR("Failed to create dialog\n");
			return -1;
		}
		/* double check if the dialog can be retrieved */
		if (!(dlg = get_current_dialog())) {
			LM_ERR("failed to get dialog\n");
			return -1;
		}
	}

	dlg->flags |= DLG_FLAG_TOPHIDING;
	dlg->flags |= extra_flags;

	/* delete also the added record route and the did param */
	for(crt=req->add_rm; crt;) {
		lump = 0;
		if(crt->type != HDR_RECORDROUTE_T)
			/* check on before list for parameters */
			for( lump=crt->before ; lump ; lump=lump->before ) {
				/* we are looking for the lump that adds the
				 * suffix of the RR header */
				if ( lump->type==HDR_RECORDROUTE_T && lump->op==LUMP_ADD)
				{
					LM_DBG("lump before root %p\n", crt);
					LM_DBG("Found lump = %p, %.*s\n", lump, lump->len,lump->u.value);
					break;
				}
			}

		if((crt->type==HDR_RECORDROUTE_T) || lump) {
			/* lump found */
			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 == req->add_rm)
				req->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);
//				goto after_del_rr;
//			break;
			continue;
		}
		prev_crt = crt;
		crt= crt->next;
	}

	buf = req->buf;
	/* delete record-route headers */
	for (it=req->record_route;it;it=it->sibling) {
		if (del_lump(req,it->name.s - buf,it->len,HDR_RECORDROUTE_T) == 0) {
			LM_ERR("del_lump failed - while deleting record-route\n");
			return -1;
		}
	}

	/* delete via headers */
	if(dlg_del_vias(req) < 0) {
		LM_ERR("Failed to remove via headers\n");
		return -1;
	}

	/* replace contact*/
	if(dlg_replace_contact(req, dlg) < 0) {
		LM_ERR("Failed to replace contact\n");
		return -1;
	}

	return 1;
}
Ejemplo n.º 7
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;
}