int ops_print_avp(void) { struct usr_avp **avp_list; struct usr_avp *avp; int_str val; str *name; /* go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp->next) { LM_INFO("p=%p, flags=0x%04X\n",avp, avp->flags); name = get_avp_name(avp); LM_INFO("\t\t\tname=<%.*s>\n",name->len,name->s); LM_INFO("\t\t\tid=<%d>\n",avp->id); get_avp_val( avp, &val); if (avp->flags&AVP_VAL_STR) { LM_INFO("\t\t\tval_str=<%.*s / %d>\n",val.s.len,val.s.s, val.s.len); } else { LM_INFO("\t\t\tval_int=<%d>\n",val.n); } } return 1; }
int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap) { struct usr_avp **avp_list; struct usr_avp *avp; struct usr_avp *avp_next; unsigned short name_type; int avp_name; int n; n = 0; if ((ap->opd&AVPOPS_VAL_NONE)==0) { /* avp name is known ->search by name */ /* get avp name */ if(avpops_get_aname(msg, ap, &avp_name, &name_type)!=0) { LM_ERR("failed to get dst AVP name\n"); return -1; } n = destroy_avps( name_type, avp_name, ap->ops&AVPOPS_FLAG_ALL ); } else { /* avp name is not given - we have just flags */ /* -> go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp_next ) { avp_next = avp->next; /* check if type match */ if ( !( (ap->opd&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 || ((ap->opd&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) || ((ap->opd&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) ) ) continue; if((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)!=0 && ((ap->u.sval.pvp.pvn.u.isname.type&AVP_SCRIPT_MASK) &avp->flags)==0) continue; /* remove avp */ destroy_avp( avp ); n++; if ( !(ap->ops&AVPOPS_FLAG_ALL) ) break; } } LM_DBG("%d avps were removed\n",n); return n?1:-1; }
int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap) { struct usr_avp **avp_list; struct usr_avp *avp; struct usr_avp *avp_next; unsigned short name_type; int n; n = 0; if ( (ap->flags&AVPOPS_VAL_NONE)==0) { /* avp name is known ->search by name */ name_type = (((ap->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR); while ( (avp=search_first_avp( name_type, ap->val, 0))!=0 ) { destroy_avp( avp ); n++; if ( !(ap->flags&AVPOPS_FLAG_ALL) ) break; } } else { /* avp name is not given - we have just flags */ /* -> go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp_next ) { avp_next = avp->next; /* check if type match */ if ( !( (ap->flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 || ((ap->flags&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) || ((ap->flags&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) ) ) continue; /* remove avp */ destroy_avp( avp ); n++; if ( !(ap->flags&AVPOPS_FLAG_ALL) ) break; } } DBG("DEBUG:avpops:remove_avps: %d avps were removed\n",n); return n?1:-1; }
static int save_reg_avps_impl(struct ucontact *c) { int i; struct usr_avp *avp, *dup; avp_t *first, *last; static unsigned short lists[] = { AVP_CLASS_USER | AVP_TRACK_FROM, AVP_CLASS_USER | AVP_TRACK_TO, AVP_CLASS_URI | AVP_TRACK_FROM, AVP_CLASS_URI | AVP_TRACK_TO, 0 }; /* destroy old AVPs */ /* if (c->avps) db_delete_reg_avps(c); */ reg_destroy_avps(c->avps); last = NULL; first = NULL; for (i = 0; lists[i]; i++) { for (avp = get_avp_list(lists[i]); avp; avp = avp->next) { /* trace_avp("trying to save avp", avp); */ if ((avp->flags & reg_avp_flag) == 0) continue; /* trace_avp("saving avp", avp); */ dup = avp_dup(avp); if (dup) { /* add AVP into list */ if (last) last->next = dup; else first = dup; last = dup; } } } c->avps = first; /* if (c->avps) db_save_reg_avps(c); */ return 0; }
int ebr_resume_from_wait(int *fd, struct sip_msg *msg, void *param) { struct usr_avp *avps=(struct usr_avp *)param; struct usr_avp *last_avp; struct usr_avp **avp_head; if (param==NULL) return 1; /* the only thing to do here is to inject the AVPs */ for( last_avp=avps ; last_avp->next ; last_avp=last_avp->next ); avp_head = get_avp_list(); last_avp->next = *avp_head; *avp_head = avps; return 1; }
int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, struct db_param *dbp, int use_domain) { struct sip_uri uri; struct usr_avp **avp_list; struct usr_avp *avp; unsigned short name_type; int_str i_s; str uuid; int keys_off; int keys_nr; int n; if (sp->flags&AVPOPS_VAL_NONE) { /* get and parse uri */ if (parse_source_uri( msg, sp->flags, &uri)<0 ) { LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uri\n"); goto error; } /* set values for keys */ keys_off = 1; store_vals[4].val.str_val = (sp->flags&AVPOPS_FLAG_DOMAIN)?empty:uri.user; if (use_domain || sp->flags&AVPOPS_FLAG_DOMAIN) { store_vals[5].val.str_val = uri.host; keys_nr = 5; } else { keys_nr = 4; } } else if (sp->flags&AVPOPS_VAL_AVP) { /* get uuid from avp */ if (get_avp_as_str(sp, &uuid)<0) { LOG(L_ERR,"ERROR:avpops:store_avps: failed to get uuid\n"); goto error; } /* set values for keys */ keys_off = 0; keys_nr = 4; store_vals[0].val.str_val = uuid; } else if (sp->flags&AVPOPS_VAL_STR) { /* use the STR value as uuid */ /* set values for keys */ keys_off = 0; keys_nr = 4; store_vals[0].val.str_val = *sp->val.s; } else { LOG(L_CRIT,"BUG:avpops:store_avps: invalid flag combination (%d)\n", sp->flags); goto error; } /* set uuid/(username and domain) fields */ n =0 ; if ((dbp->a.flags&AVPOPS_VAL_NONE)==0) { /* avp name is known ->set it and its type */ name_type = (((dbp->a.flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR); store_vals[1].val.str_val = dbp->sa; /*attr name*/ avp = search_first_avp( name_type, dbp->a.val, &i_s); for( ; avp; avp=search_next_avp(avp,&i_s)) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* set type */ store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set value */ int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( store_keys+keys_off, store_vals+keys_off, keys_nr, dbp->table)==0 ) { avp->flags |= AVP_IS_IN_DB; n++; } } } else { /* avp name is unknown -> go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp->next ) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* check if type match */ if ( !( (dbp->a.flags&(AVPOPS_VAL_INT|AVPOPS_VAL_STR))==0 || ((dbp->a.flags&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) ||((dbp->a.flags&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)))) continue; /* set attribute name and type */ if ( (i_s.s=get_avp_name(avp))==0 ) i_s.n = avp->id; int_str2db_val( i_s, &store_vals[1].val.str_val, avp->flags&AVP_NAME_STR); store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set avp value */ get_avp_val( avp, &i_s); int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( store_keys+keys_off, store_vals+keys_off, keys_nr, dbp->table)==0) { avp->flags |= AVP_IS_IN_DB; n++; } } } DBG("DEBUG:avpops:store_avps: %d avps were stored\n",n); return n==0?-1:1; error: return -1; }
int ops_dbstore_avps (struct sip_msg* msg, struct fis_param *sp, struct db_param *dbp, struct db_url *url, int use_domain) { struct sip_uri uri; struct usr_avp **avp_list; struct usr_avp *avp; unsigned short name_type; int avp_name; int_str i_s; str uuid; int keys_nr; int n; pv_value_t xvalue; str *s0, *s1, *s2; str *sn; s0 = s1 = s2 = NULL; name_type = 0; if (!((sp->opd&AVPOPS_VAL_PVAR)||(sp->opd&AVPOPS_VAL_STR))) { LM_CRIT("invalid flag combination (%d/%d)\n", sp->opd, sp->ops); goto error; } keys_nr = 6; /* uuid, avp name, avp val, avp type, user, domain */ /* get uuid from avp */ if (sp->opd&AVPOPS_VAL_PVAR) { if(pv_get_spec_value(msg, &(sp->u.sval), &xvalue)!=0) { LM_CRIT("failed to get PVAR value (%d/%d)\n", sp->opd, sp->ops); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_ERR("no value for first param\n"); goto error; } uuid = xvalue.rs; } else { uuid.s = sp->u.s.s; uuid.len = sp->u.s.len; } if(sp->opd&AVPOPS_FLAG_UUID0) { s0 = &uuid; } else { /* parse uri */ if (parse_uri(uuid.s, uuid.len, &uri)<0) { LM_ERR("failed to parse uri\n"); goto error; } /* check uri */ if(!uri.user.s|| !uri.user.len|| !uri.host.len|| !uri.host.s) { LM_ERR("incomplet uri <%.*s>\n", uuid.len, uuid.s); goto error; } if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_USER0)) s1 = &uri.user; if((sp->opd&AVPOPS_FLAG_URI0)||(sp->opd&AVPOPS_FLAG_DOMAIN0)) s2 = &uri.host; } /* set values for keys */ store_vals[0].val.str_val = (s0)?*s0:empty; store_vals[4].val.str_val = (s1)?*s1:empty; if (use_domain || sp->opd&AVPOPS_FLAG_DOMAIN0) store_vals[5].val.str_val = (s2)?*s2:empty; avp_name = -1; /* is dynamic avp name ? */ if(dbp->a.type==AVPOPS_VAL_PVAR) { if(pv_has_dname(&dbp->a.u.sval)) { /* TODO change here to be aware of the int name */ if(pv_get_spec_name(msg, &(dbp->a.u.sval.pvp), &xvalue)!=0) { LM_CRIT("failed to get value for P2\n"); goto error; } if(xvalue.flags&(PV_VAL_NULL|PV_VAL_EMPTY)) { LM_INFO("no value for P2\n"); goto error; } if(xvalue.flags&PV_TYPE_INT) { name_type = 0; avp_name = xvalue.ri; } else { name_type = AVP_NAME_STR; avp_name = -1; } if(xvalue.flags&PV_VAL_STR) { if(xvalue.rs.len>=AVPOPS_ATTR_LEN) { LM_ERR("name too long [%d/%.*s...]\n", xvalue.rs.len, 16, xvalue.rs.s); goto error; } dbp->sa.s = avpops_attr_buf; memcpy(dbp->sa.s, xvalue.rs.s, xvalue.rs.len); dbp->sa.len = xvalue.rs.len; dbp->sa.s[dbp->sa.len] = '\0'; avp_name = get_avp_id(&dbp->sa); /* search for the id only once */ if (avp_name < 0) { LM_ERR("cannot find avp\n"); goto error; } } else { LM_INFO("no string value for p2\n"); goto error; } } else { name_type = dbp->a.u.sval.pvp.pvn.u.isname.type; avp_name = dbp->a.u.sval.pvp.pvn.u.isname.name.n; } } else { LM_WARN("TODO: avp is not a dynamic name <%.*s> name is %d\n", dbp->sa.len, dbp->sa.s, avp_name); avp_name = -1; } /* set the script flags */ if(dbp->a.type==AVPOPS_VAL_PVAR) name_type |= dbp->a.u.sval.pvp.pvn.u.isname.type&0xff00; /* set uuid/(username and domain) fields */ n =0 ; if ((dbp->a.opd&AVPOPS_VAL_NONE)==0) { /* if avp wasn't found yet */ if (avp_name < 0) { avp_name = get_avp_id(&dbp->sa); /* search for the id only once */ if (avp_name < 0) { LM_ERR("cannot find avp\n"); goto error; } } /* avp name is known ->set it and its type */ store_vals[1].val.str_val = dbp->sa; /*attr name*/ avp = search_first_avp( 0, avp_name, &i_s, 0); for( ; avp; avp=search_first_avp( 0, avp_name, &i_s, avp)) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* set type */ store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set value */ int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( url, store_keys, store_vals, keys_nr, &dbp->table)==0 ) { avp->flags |= AVP_IS_IN_DB; n++; } } } else { /* avp name is unknown -> go through all list */ avp_list = get_avp_list(); avp = *avp_list; for ( ; avp ; avp=avp->next ) { /* don't insert avps which were loaded */ if (avp->flags&AVP_IS_IN_DB) continue; /* set attribute name and type */ if ( (sn=get_avp_name(avp))==0 ) i_s.n = avp->id; else i_s.s = *sn; int_str2db_val( i_s, &store_vals[1].val.str_val, AVP_NAME_STR); store_vals[3].val.int_val = (avp->flags&AVP_NAME_STR?0:AVPOPS_DB_NAME_INT)| (avp->flags&AVP_VAL_STR?0:AVPOPS_DB_VAL_INT); /* set avp value */ get_avp_val( avp, &i_s); int_str2db_val( i_s, &store_vals[2].val.str_val, avp->flags&AVP_VAL_STR); /* save avp */ if (db_store_avp( url, store_keys, store_vals, keys_nr, &dbp->table)==0) { avp->flags |= AVP_IS_IN_DB; n++; } } } LM_DBG(" %d avps were stored\n",n); return n==0?-1:1; error: return -1; }
static int dump_attrs(struct sip_msg* m, char* x, char* y) { avp_list_t avp_list; unsigned long flags; if (x) { flags = (unsigned long)x; } else { flags = AVP_CLASS_ALL | AVP_TRACK_ALL; } if (flags & AVP_CLASS_GLOBAL) { avp_list = get_avp_list(AVP_CLASS_GLOBAL); INFO("class=GLOBAL\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_DOMAIN && flags & AVP_TRACK_FROM) { avp_list = get_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_FROM); INFO("track=FROM class=DOMAIN\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_DOMAIN && flags & AVP_TRACK_TO) { avp_list = get_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO); INFO("track=TO class=DOMAIN\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_USER && flags & AVP_TRACK_FROM) { avp_list = get_avp_list(AVP_CLASS_USER | AVP_TRACK_FROM); INFO("track=FROM class=USER\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_USER && flags & AVP_TRACK_TO) { avp_list = get_avp_list(AVP_CLASS_USER | AVP_TRACK_TO); INFO("track=TO class=USER\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_URI && flags & AVP_TRACK_FROM) { avp_list = get_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM); INFO("track=FROM class=URI\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } if (flags & AVP_CLASS_URI && flags & AVP_TRACK_TO) { avp_list = get_avp_list(AVP_CLASS_URI | AVP_TRACK_TO); INFO("track=TO class=URI\n"); if (!avp_list) { LOG(L_INFO,"INFO: No AVP present\n"); } else { dump_avp_reverse(avp_list); } } return 1; }
struct cell* build_cell( struct sip_msg* p_msg ) { struct cell* new_cell; int sip_msg_len; avp_list_t* old; /* allocs a new cell */ new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) ); if ( !new_cell ) { ser_error=E_OUT_OF_MEM; return NULL; } /* filling with 0 */ memset( new_cell, 0, sizeof( struct cell ) ); /* UAS */ new_cell->uas.response.my_T=new_cell; init_rb_timers(&new_cell->uas.response); /* timers */ init_cell_timers(new_cell); old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &new_cell->uri_avps_from ); new_cell->uri_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &new_cell->uri_avps_to ); new_cell->uri_avps_to = *old; *old = 0; old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &new_cell->user_avps_from ); new_cell->user_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &new_cell->user_avps_to ); new_cell->user_avps_to = *old; *old = 0; /* We can just store pointer to domain avps in the transaction context, * because they are read-only */ new_cell->domain_avps_from = get_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN); new_cell->domain_avps_to = get_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN); /* enter callback, which may potentially want to parse some stuff, * before the request is shmem-ized */ if ( p_msg && has_reqin_tmcbs() ) run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD); if (p_msg) { /* clean possible previous added vias/clen header or else they would * get propagated in the failure routes */ free_via_clen_lump(&p_msg->add_rm); new_cell->uas.request = sip_msg_cloner(p_msg,&sip_msg_len); if (!new_cell->uas.request) goto error; new_cell->uas.end_request=((char*)new_cell->uas.request)+sip_msg_len; } /* UAC */ init_branches(new_cell); new_cell->relayed_reply_branch = -1; /* new_cell->T_canceled = T_UNDEFINED; */ init_synonym_id(new_cell); init_cell_lock( new_cell ); return new_cell; error: destroy_avp_list(&new_cell->user_avps_from); destroy_avp_list(&new_cell->user_avps_to); destroy_avp_list(&new_cell->uri_avps_from); destroy_avp_list(&new_cell->uri_avps_to); shm_free(new_cell); /* unlink transaction AVP list and link back the global AVP list (bogdan)*/ reset_avps(); return NULL; }