Beispiel #1
0
int dlg_th_onroute(struct dlg_cell *dlg, struct sip_msg *req, int dir)
{
	struct hdr_field *it;
	char* buf = req->buf;

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

	/* delete record route */
	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\n");
			return -1;
		}
		LM_DBG("Delete record route: [%.*s]\n", it->len, it->name.s);
	}

	/* add route headers */
	fix_route_dialog(req, dlg);

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

	/* register tm callback for response in  */
	ref_dlg( dlg , 1);
	if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_FWDED,
			(dir==DLG_DIR_UPSTREAM)?dlg_th_down_onreply:dlg_th_up_onreply,
			(void*)dlg, unreference_dialog)<0 ) {
		LM_ERR("failed to register TMCB\n");
		unref_dlg( dlg , 1);
	}

	if (dir == DLG_DIR_UPSTREAM) {
		/* destination leg is the caller - force the send socket
		 * as the one the caller was inited from */
		req->force_send_socket = dlg->legs[DLG_CALLER_LEG].bind_addr;
		LM_DBG("forcing send socket for req going to caller\n");
	} else {
		/* destination leg is the callee - force the send socket
		 * as the one the callee was inited from */
		req->force_send_socket = dlg->legs[callee_idx(dlg)].bind_addr;
		LM_DBG("forcing send socket for req going to callee\n");
	}

	return 0;
}
Beispiel #2
0
int dlg_th_onroute(struct dlg_cell *dlg, struct sip_msg *req, int dir)
{
	struct hdr_field *it;
	char* buf = req->buf;
	int leg_id;

	if(dir == DLG_DIR_UPSTREAM)
		leg_id = callee_idx(dlg);
	else
		leg_id = DLG_CALLER_LEG;

	/* delete vias */
	if(dlg_save_del_vias(req, &dlg->legs[leg_id]) < 0) {
		LM_ERR("Failed to save and remove via headers\n");
		return -1;
	}

	/* delete record route */
	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 \n");
			return -1;
		}
		LM_DBG("Delete record route: [%.*s]\n", it->len, it->name.s);
	}

	/* add route headers */
	fix_route_dialog(req, dlg);

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

	/* register tm callback for response in  */
	ref_dlg( dlg , 1);
	if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_FWDED,
			(dir==DLG_DIR_UPSTREAM)?dlg_th_down_onreply:dlg_th_up_onreply,
			(void*)dlg, unreference_dialog)<0 ) {
		LM_ERR("failed to register TMCB\n");
		unref_dlg( dlg , 1);
	}

	return 0;
}
Beispiel #3
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;
}
Beispiel #4
0
int dlg_th_onreply(struct dlg_cell *dlg, struct sip_msg *rpl, struct sip_msg *req,
		int init_req, int dir)
{
	struct hdr_field *it;
	char* buf = rpl->buf;
	int peer_leg;
	struct lump* lmp;
	int size;
	char* route,*p;
	str via_str;
	struct dlg_leg* leg;

	/* parse all headers to be sure that all RR and Contact hdrs are found */
	if (parse_headers(rpl, HDR_EOH_F, 0)< 0) {
		LM_ERR("Failed to parse reply\n");
		return -1;
	}

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

	if(dir == DLG_DIR_UPSTREAM)
		peer_leg = DLG_CALLER_LEG;
	else
		peer_leg = callee_idx(dlg);
	leg = &dlg->legs[peer_leg];

	LM_DBG("peer_leg = %d\n", peer_leg);
	LM_DBG("first RR hdr = %p\n", rpl->record_route);
	/* delete record route */
	for (it=rpl->record_route; it; it=it->sibling) { /* changed here for contact - it was & it->sibling */
		/* skip the one added by this proxy */
		if ((lmp = del_lump(rpl, it->name.s - buf, it->len,HDR_RECORDROUTE_T)) == 0) {
			LM_ERR("del_lump failed\n");
			return -1;
		}
		LM_DBG("Delete record route: [%.*s]\n", it->len, it->name.s);
	}

	LM_DBG("deleted rr stuff\n");
	/* add Via headers */
	lmp = anchor_lump(rpl,rpl->headers->name.s - buf,0);
	if (lmp == 0)
	{
		LM_ERR("failed anchoring new lump\n");
		return -1;
	}

	it = req->h_via1;
	via_str.len = 0;
	while (it) {
		via_str.len += it->len;
		it = it->sibling;
	}

	LM_DBG("via len = %d\n",via_str.len);

	if (via_str.len == 0)
		goto restore_rr;

	via_str.s = pkg_malloc(via_str.len);
	if (!via_str.s) {
		LM_ERR("no more pkg mem\n");
		return -1;
	}

	LM_DBG("allocated via_str %p\n",via_str.s);

	it = req->h_via1;
	p = via_str.s;
	while (it) {
		memcpy(p,it->name.s,it->len);
		p+=it->len;
		it = it->sibling;
	}

	LM_DBG("inserting via headers - [%.*s]\n",via_str.len,via_str.s);

	if ((lmp = insert_new_lump_after(lmp, via_str.s, via_str.len, 0)) == 0) {
		LM_ERR("failed inserting new old vias\n");
		pkg_free(via_str.s);
		return -1;
	}

restore_rr:
	/* if dialog not confirmed and 200OK for Invite */
	/* pass the record route headers for this leg */
	if(init_req && dir == DLG_DIR_UPSTREAM && leg->route_set.s) {

		/* changed here for contact ( take care to insert the routes after own) */

		/* pass record route headers */
		size = leg->route_set.len + RECORD_ROUTE_LEN + CRLF_LEN;
		route = pkg_malloc(size);
		if (route == NULL) {
			LM_ERR("no more pkg memory\n");
			return -1;
		}

		memcpy(route, RECORD_ROUTE, RECORD_ROUTE_LEN);
		memcpy(route+RECORD_ROUTE_LEN, leg->route_set.s, leg->route_set.len);
		memcpy(route+RECORD_ROUTE_LEN+leg->route_set.len, CRLF, CRLF_LEN);

		/* put after Via */
		if ((lmp = insert_new_lump_after(lmp, route, size, HDR_RECORDROUTE_T)) == 0) {
			LM_ERR("failed inserting new route set\n");
			pkg_free(route);
			return -1;
		}
		LM_DBG("Added record route [%.*s]\n", size, route);
	}

	return 0;
}