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; }
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; }
/* 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; }
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; }