Example #1
0
static inline int insert_siptrace_avp(struct usr_avp *avp,
		int_str *first_val,db_key_t *keys,db_val_t *vals)
{
	int_str        avp_value;

	if (avp == 0)
		return 0;

	if (!is_avp_str_val(avp)) {
		avp_value.s.s=int2str(first_val->n,&avp_value.s.len);
		LM_DBG("int val [%.*s]\n",avp_value.s.len,avp_value.s.s);
	} else {
		avp_value = *first_val;
		LM_DBG("str val [%.*s]\n",avp_value.s.len,avp_value.s.s);
	}
	db_vals[13].val.str_val.s = avp_value.s.s;
	db_vals[13].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info 14...\n");
	CON_PS_REFERENCE(db_con) = &siptrace_ps;
	if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 )
		CON_RESET_INSLIST(db_con);
	if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0) {
		LM_ERR("error storing trace\n");
		return -1;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		if (!is_avp_str_val(avp))
			avp_value.s.s=int2str(avp_value.n,&avp_value.s.len);
		db_vals[13].val.str_val.s = avp_value.s.s;
		db_vals[13].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info 14 \n");
		CON_PS_REFERENCE(db_con) = &siptrace_ps;
		if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 )
			CON_RESET_INSLIST(db_con);
		if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			return -1;
		}
		avp = search_next_avp( avp, &avp_value);
	}

	return 0;
}
Example #2
0
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    osp_dest* dest = NULL;
    osp_dest* lastused = NULL;
    struct usr_avp* destavp = NULL;
    int_str destval;
    struct search_state state;
    OSPTTRANHANDLE transaction = -1;
    int lastcode = 0;
    int errorcode;

    LOG(L_DBG, "osp: ospReportOrigSetupUsage\n");

    errorcode = OSPPTransactionNew(_osp_provider, &transaction);

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, &destval, &state);
        destavp != NULL;
        destavp = search_next_avp(&state, &destval)) 
    {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            if (dest->reported == 1) {
                LOG(L_DBG, "osp: orig setup already reported\n");
                break;
            } else {
                dest->reported = 1;
            }

            LOG(L_DBG, "osp: iterating through used destination\n");

            ospDumpDestination(dest);

            lastused = dest;

            errorcode = ospBuildUsageFromDestination(transaction, dest, lastcode);

            lastcode = dest->lastcode;
        } else {
            LOG(L_DBG, "osp: destination has not been used, breaking out\n");
            break;
        }
    }

    if (lastused) {
        LOG(L_INFO,
            "osp: report orig setup for call_id '%.*s' transaction_id '%llu'\n",
            lastused->callidsize,
            lastused->callid,
            lastused->transid);
        errorcode = ospReportUsageFromDestination(transaction, lastused);
    } else {
        /* If a Toolkit transaction handle was created, but we did not find
         * any destinations to report, we need to release the handle. Otherwise,
         * the ospReportUsageFromDestination will release it.
         */
        OSPPTransactionDelete(transaction);
    }
}
Example #3
0
File: avp.c Project: 2pac/kamailio
static int attr_equals_xl(struct sip_msg* msg, char* p1, char* format)
{
    avp_ident_t* avpid;
    avp_value_t avp_val;
    struct search_state st;
    str xl_val;
    avp_t* avp;
    
    avpid = &((fparam_t*)p1)->v.avp;

    if (xl_printstr(msg, (xl_elog_t*) format, &xl_val.s, &xl_val.len) > 0) {
	for (avp = search_avp(*avpid, &avp_val, &st); avp; avp = search_next_avp(&st, &avp_val)) {
	    if (avp->flags & AVP_VAL_STR) {
		if ((avp_val.s.len == xl_val.len) &&
		    !memcmp(avp_val.s.s, xl_val.s, avp_val.s.len)) return 1;
	    } else {
		if (avp_val.n == str2s(xl_val.s, xl_val.len, 0)) return 1;
	    }
	}
	return -1;
    }
    
    ERR("avp_equals_xl:Error while expanding xl_format\n");
    return -1;
}
Example #4
0
/*
 * Dump all destination information
 */
void ospDumpAllDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int count = 0;

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....originate '%d'....\n", count++);

        ospDumpDestination(dest);
    }
    if (count == 0) {
        LM_DBG("there is not originate destination AVP\n");
    }

    if (search_first_avp(AVP_VAL_STR, _osp_termdest_avpid, &destval, 0) != NULL) {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....terminate....\n");

        ospDumpDestination(dest);
    } else {
        LM_DBG("there is not terminate destination AVP\n");
    }
}
Example #5
0
/*
 * Retrieved the last used originate destination from an AVP
 *    name - OSP_ORIGDEST_NAME
 *    value - osp_dest wrapped in a string
 *    There can be 0, 1 or more destinations. 
 *    Find the last used destination (used==1) & supported (support==1),
 *    and return it.
 *    In normal condition, this one is the current destination. But it may
 *    be wrong for loop condition.
 *  return NULL on failure
 */
osp_dest* ospGetLastOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* lastdest = NULL;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            if (dest->supported == 1) {
                lastdest = dest;
                LM_DBG("curent destination '%s'\n", lastdest->host);
            }
        } else {
            break;
        }
    }

    return lastdest;
}
Example #6
0
int ds_next_dst(struct sip_msg *msg, int mode)
{
	struct socket_info *sock;
	struct usr_avp *avp;
	struct usr_avp *tmp_avp;
	struct usr_avp *attr_avp;
	int_str avp_value;
	int_str sock_avp_value;

	if(!(ds_flags&DS_FAILOVER_ON) || dst_avp_name < 0)
	{
		LM_WARN("failover support disabled\n");
		return -1;
	}

	tmp_avp = search_first_avp(dst_avp_type, dst_avp_name, NULL, 0);
	if(tmp_avp==NULL)
		return -1; /* used avp deleted -- strange */

	/* get AVP with next destination URI */
	avp = search_next_avp(tmp_avp, &avp_value);
	destroy_avp(tmp_avp);

	/* remove old attribute AVP (from prev destination) */
	if (attrs_avp_name >= 0) {
		attr_avp = search_first_avp(attrs_avp_type, attrs_avp_name, NULL, 0);
		if (attr_avp)
			destroy_avp(attr_avp);
	}

	if(avp==NULL || !(avp->flags&AVP_VAL_STR))
		return -1; /* no more avps or value is int */

	/* get AVP with next destination socket */
	tmp_avp = search_first_avp(sock_avp_type, sock_avp_name,
	&sock_avp_value, 0);
	if (tmp_avp) {
		/* this shuold not happen, it is a bogus state */
		sock = NULL;
	} else {
		if (sscanf( sock_avp_value.s.s, "%p", (void**)&sock ) != 1)
			sock = NULL;
	}

	if(ds_update_dst(msg, &avp_value.s, sock, mode)!=0)
	{
		LM_ERR("cannot set dst addr\n");
		return -1;
	}
	LM_DBG("using [%.*s]\n", avp_value.s.len, avp_value.s.s);

	return 1;
}
Example #7
0
int legs2strar( struct acc_extra *legs, struct sip_msg *rq, str *val_arr,
		int *int_arr, char *type_arr, int start)
{
	static struct usr_avp *avp[MAX_ACC_LEG];
	static struct search_state st[MAX_ACC_LEG];
	unsigned short name_type;
	int_str name;
	int_str value;
	int    n;
	int    found;
	int    r;

	found = 0;
	r = 0;

	for( n=0 ; legs ; legs=legs->next,n++ ) {
		/* search for the AVP */
		if (start) {
			if ( pv_get_avp_name( rq, &(legs->spec.pvp), &name, &name_type)<0 )
				goto exit;
			avp[n] = search_first_avp( name_type, name, &value, st + n);
		} else {
			avp[n] = search_next_avp(st + n, &value);
		}

		/* set new leg record */
		if (avp[n]) {
			found = 1;
			/* get its value */
			if(avp[n]->flags & AVP_VAL_STR) {
				val_arr[n] = value.s;
				type_arr[n] = TYPE_STR;
			} else {
				val_arr[n].s = int2bstr( value.n, int_buf+r*INT2STR_MAX_LEN,
					&val_arr[n].len);
				r++;
				int_arr[n] = value.n;
				type_arr[n] = TYPE_INT;
			}
		} else {
			val_arr[n].s = 0;
			val_arr[n].len = 0;
			type_arr[n] = TYPE_NULL;
		}

	}

	if (found || start)
		return n;
exit:
	return 0;
}
Example #8
0
int _cfgt_get_array_avp_vals(struct sip_msg *msg,
		pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobj,
		str *item_name)
{
	struct usr_avp *avp;
	unsigned short name_type;
	int_str avp_name;
	int_str avp_value;
	struct search_state state;
	srjson_t *jobjt;
	memset(&state, 0, sizeof(struct search_state));

	if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0)
	{
		LM_ERR("invalid name\n");
		return -1;
	}
	*jobj = srjson_CreateArray(jdoc);
	if(*jobj==NULL)
	{
		LM_ERR("cannot create json object\n");
		return -1;
	}
	if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0)
	{
		goto ok;
	}
	do
	{
		if(avp->flags & AVP_VAL_STR)
		{
			jobjt = srjson_CreateStr(jdoc, avp_value.s.s, avp_value.s.len);
			if(jobjt==NULL)
			{
				LM_ERR("cannot create json object\n");
				return -1;
			}
		} else {
			jobjt = srjson_CreateNumber(jdoc, avp_value.n);
			if(jobjt==NULL)
			{
				LM_ERR("cannot create json object\n");
				return -1;
			}
		}
		srjson_AddItemToArray(jdoc, *jobj, jobjt);
	} while ((avp=search_next_avp(&state, &avp_value))!=0);
ok:
	item_name->s = avp_name.s.s;
	item_name->len = avp_name.s.len;
	return 0;
}
Example #9
0
File: avp.c Project: 2pac/kamailio
static int del_attr(struct sip_msg* msg, char* p1, char* p2)
{
    fparam_t* fp;
    avp_t* avp;
    struct search_state st;	
    
    fp = (fparam_t*)p1;
    
    avp = search_avp(fp->v.avp, 0, &st);
    while (avp) {
	destroy_avp(avp);
	avp = search_next_avp(&st, 0);
    }
    return 1;
}
Example #10
0
/*
 *  Writes all avps with name avp_name to new str_list (shm mem)
 *  Be careful: returns NULL pointer if no avp present!
 *
 */
struct str_list* get_str_list(unsigned short avp_flags, int_str avp_name) {

	int_str avp_value;
	unsigned int len;
	struct str_list* list_first = 0;
	struct str_list* list_current = 0	;
	struct search_state st;

	if(!search_first_avp(avp_flags, avp_name, &avp_value, &st)) {
		return NULL;
	}

	do {

		LM_DBG("AVP found '%.*s'\n", avp_value.s.len, avp_value.s.s);

		len = sizeof(struct str_list) + avp_value.s.len;

		if(list_current) {
			list_current->next = (struct str_list*) shm_malloc( len);
			list_current=list_current->next;
		} else {
			list_current=list_first= (struct str_list*) shm_malloc( len);
		}

		if (list_current==0) {
			LM_ERR("no more shm mem (%d)\n",len);
			return 0;
		}

		memset( list_current, 0, len);

		list_current->s.s = (char*)( (void*) list_current + sizeof(struct str_list));
		list_current->s.len = avp_value.s.len;
		memcpy(list_current->s.s,avp_value.s.s,avp_value.s.len);



	} while(search_next_avp(&st, &avp_value));

	return list_first;

}
Example #11
0
/* 
 * Retrieved an unused and supported originate destination from an AVP
 *     name - OSP_ORIGDEST_NAME
 *     value - osp_dest wrapped in a string
 *     There can be 0, 1 or more originate destinations. 
 *     Find the 1st unused destination (used==0) & supported (support==1),
 *     return it, and mark it as used (used==1).
 * return NULL on failure
 */
osp_dest* ospGetNextOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* result = NULL;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest found\n");
                dest->used = 1;
                result = dest;
                break;
            } else {
                /* Make it looks like used */
                dest->used = 1;
                /* 111 means wrong protocol */
                dest->lastcode = 111;
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == NULL) {
        LM_DBG("there is not unused destination\n");
    }

    return result;
}
Example #12
0
/*
 * Check if there is an unused and supported originate destination from an AVP
 *     avpid - osp_origdest_avpid
 *     value - osp_dest wrapped in a string
 *     search unused (used==0) & supported (support==1)
 * return 0 success, -1 failure
 */
int ospCheckOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int result = -1;

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest exist\n");
                result = 0;
                break;
            } else {
                /* Make it looks like used */
                dest->used = 1;
                /* 111 means wrong protocol */
                dest->lastcode = 111;
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == -1) {
        LM_DBG("there is not unused destination\n");
        ospReportOrigSetupUsage();
    }

    return result;
}
Example #13
0
static void remove_avps(avp_t *avp)
{
	struct search_state ss;
	avp_name_t name;
	avp_t *a;
	str *s;
	
	if (avp->flags & AVP_NAME_STR) {
		s = get_avp_name(avp);
		if (s) name.s = *s;
		else {
			name.s.s = NULL;
			name.s.len = 0;
		}
	}
	else name.n = avp->id;
	
	a = search_first_avp(avp->flags, name, 0, &ss);
	while(a) {
		destroy_avp(a);
		a = search_next_avp(&ss, 0);
	}
}
Example #14
0
static int xl_get_avp(struct sip_msg *msg, str *res, str *hp, int hi, int hf)
{
	int_str name, val;
	struct usr_avp *avp, *lavp;
	struct search_state st;

	if(msg==NULL || res==NULL || hp==NULL)
	return -1;

	name.s=*hp;
if (0){
	lavp=NULL;
	for(avp=search_first_avp(AVP_NAME_STR, name, NULL, &st); avp; avp=search_next_avp(&st, NULL)) {
		lavp=avp;
		if (hi>0)
			hi--;
		else if (hi==0)
			break;
	}

	if (lavp && (hi<=0)) {
		get_avp_val(lavp, &val);
		*res=val.s;
		return 0;
	}
}
	if ((avp=search_avp_by_index(hf, name, &val, hi))) {
		if (avp->flags & AVP_VAL_STR) {
			*res=val.s;
		} else {
			res->s=int2str(val.n, &res->len);
		}
		return 0;
	}

	return xl_get_null(msg, res, hp, hi, hf);
}
Example #15
0
File: avp.c Project: 2pac/kamailio
/*
 *  returns 1 if msg contains an AVP with the given name and value,
 *  returns -1 otherwise
 */
static int attr_equals(struct sip_msg* msg, char* p1, char* p2)
{
    avp_ident_t avpid;
    int_str value, avp_value;
    avp_t* avp;
    struct search_state st;

    if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
	return -1;
    }

    if (p2 && get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) {
	ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig);
	return -1;
    }

    avp = search_avp(avpid, &avp_value, &st);
    if (avp == 0) return -1;

    if (!p2) return 1;
    
    while (avp != 0) {
	if (avp->flags & AVP_VAL_STR) {
	    if ((avp_value.s.len == value.s.len) &&
		!memcmp(avp_value.s.s, value.s.s, avp_value.s.len)) {
		return 1;
	    }
	} else {
	    if (avp_value.n == str2s(value.s.s, value.s.len, 0)) {
		return 1;
	    }
	}
	avp = search_next_avp(&st, &avp_value);
    }
    
    return -1;
}
Example #16
0
/* 
 * Check if there is an unused and supported originate destination from an AVP
 *     name - OSP_ORIGDEST_NAME
 *     value - osp_dest wrapped in a string
 *     search unused (used==0) & supported (support==1)
 * return 0 success, -1 failure
 */
int ospCheckOrigDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int result = -1;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destintaion is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 0) {
            if (dest->supported == 1) {
                LM_DBG("orig dest exist\n");
                result = 0;
                break;
            } else {
                LM_DBG("destination does not been supported\n");
            }
        } else {
            LM_DBG("destination has already been used\n");
        }
    }

    if (result == -1) {
        LM_DBG("there is not unused destination\n");
    }

    return result;
}
Example #17
0
static void build_used_uris_list(avp_value_t* used_dests, int* no_dests){
	struct search_state st;
	int_str val;
	*no_dests = 0;

	if (!search_first_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, &val, &st)) {
		//LM_DBG("no AVPs - we are done!\n");
		return;
	}

	used_dests[(*no_dests)++] = val;
	//LM_DBG("	used_dests[%d]=%.*s \n", (*no_dests)-1, used_dests[(*no_dests)-1].s.len, used_dests[(*no_dests)-1].s.s);

	while ( search_next_avp(&st, &val) ) {
		if ( MAX_DESTINATIONS == *no_dests ) {
			LM_ERR("Too many  AVPs - we are done!\n");
			return;
		}
		used_dests[(*no_dests)++] = val;
		//LM_DBG("	used_dests[%d]=%.*s \n", (*no_dests)-1, used_dests[(*no_dests)-1].s.len, used_dests[(*no_dests)-1].s.s);
	}

	//LM_DBG("successfully built used_uris list!\n");
}
Example #18
0
/*
 * Dump all destination information
 */
void ospDumpAllDestination(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    int count = 0;
	struct search_state st;

    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_NAME, NULL, &st);
        destavp != NULL;
		 destavp = search_next_avp(&st, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....originate '%d'....\n", count++);

        ospDumpDestination(dest);
    }
    if (count == 0) {
        LM_DBG("there is not originate destination AVP\n");
    }

    if (search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_TERMDEST_NAME, &destval, 0) != NULL) {
        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        LM_DBG("....terminate....\n");

        ospDumpDestination(dest);
    } else {
        LM_DBG("there is not terminate destination AVP\n");
    }
}
Example #19
0
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;
}
Example #20
0
/*
 * Report originate call setup usage
 */
void ospReportOrigSetupUsage(void)
{
    struct usr_avp* destavp = NULL;
    int_str destval;
    osp_dest* dest = NULL;
    osp_dest* lastused = NULL;
    OSPTTRANHANDLE trans = -1;
    int lastcode = 0;
    OSPE_ROLE_STATE rstate;
    int errcode;

    errcode = OSPPTransactionNew(_osp_provider, &trans);
    if (errcode != OSPC_ERR_NO_ERROR) {
        return;
    }

    for (destavp = search_first_avp(AVP_VAL_STR, _osp_origdest_avpid, NULL, 0);
        destavp != NULL;
        destavp = search_next_avp(destavp, NULL))
    {
        get_avp_val(destavp, &destval);

        /* OSP destination is wrapped in a string */
        dest = (osp_dest*)destval.s.s;

        if (dest->used == 1) {
            LM_DBG("iterating through used destination\n");

            if (dest->reported == 1) {
                LM_DBG("orig setup already reported\n");
                break;
            } else {
                dest->reported = 1;
                ospDumpDestination(dest);
                lastused = dest;
                if (dest->lastcode == 200) {
                    rstate = OSPC_RSTATE_START;
                } else if (dest->lastcode == 300) {
                    rstate = OSPC_RSTATE_REDIRECT;
                } else {
                    rstate = OSPC_RSTATE_STOP;
                }
                /* RoleInfo must be set before BuildUsageFromScratch */
                OSPPTransactionSetRoleInfo(trans, rstate, OSPC_RFORMAT_OSP, OSPC_RVENDOR_OPENSIPS);
                ospBuildUsageFromDestination(trans, dest, lastcode);
                OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);
                OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_DESTINATION, dest->protocol);
                lastcode = dest->lastcode;
            }
        } else {
            LM_DBG("destination has not been used, breaking out\n");
            break;
        }
    }

    if (lastused) {
        LM_INFO("report orig setup for call_id '%.*s' transaction_id '%llu'\n",
            lastused->callidsize,
            lastused->callid,
            lastused->transid);
        ospReportUsageFromDestination(trans, lastused);
    } else {
        /* If a Toolkit transaction handle was created, but we did not find
         * any destinations to report, we need to release the handle. Otherwise,
         * the ospReportUsageFromDestination will release it.
         */
        OSPPTransactionDelete(trans);
    }
}
Example #21
0
int do_lb_reset(struct sip_msg *req, struct lb_data *data)
{
	struct usr_avp *id_avp;
	struct usr_avp *res_avp, *del_res_avp;
	int_str id_val;
	int_str res_val;

	struct dlg_cell *dlg;
	struct lb_dst *it_d, *last_dst;
	struct lb_resource *it_r;

	if ( (dlg=lb_dlg_binds.get_dlg())==NULL ) {
		LM_ERR("no dialog found for this call, LB not started\n");
		return -1;
	}

	/* remove any saved AVPs */
	destroy_avps(0, group_avp_name, 0);
	destroy_avps(0, flags_avp_name, 0);
	destroy_avps(0, mask_avp_name, 0);

	/* get previous iteration destination, if any */
	last_dst = NULL;
	id_avp = search_first_avp(0, id_avp_name, &id_val, NULL);
	if( id_avp && (is_avp_str_val(id_avp) == 0) ) {
		for( it_d=data->dsts ; it_d ; it_d=it_d->next ) {
			if( it_d->id == id_val.n ) {
				last_dst = it_d;
				LM_DBG("reset LB - found previous dst %d [%.*s]\n",
					last_dst->id,
					last_dst->profile_id.len, last_dst->profile_id.s);
				break;
			}
		}
	}
	destroy_avps(0, id_avp_name, 0);

	/* any valid previous iteration ? */
	if(last_dst == NULL) {
		/* simply delete all possible resources */
		destroy_avps(0, res_avp_name, 1);
	} else {
		/* search and clean up previous iteration resources, if any */
		res_avp = search_first_avp(0, res_avp_name, &res_val, NULL);
		while (res_avp) {
			if ( (it_r=get_resource_by_name( data, &res_val.s))!=NULL ) {
				if( lb_dlg_binds.unset_profile(dlg, &last_dst->profile_id,
				it_r->profile) != 1 )
					LM_ERR("reset LB - failed to remove from profile [%.*s]->"
						"[%.*s]\n", res_val.s.len, res_val.s.s,
						last_dst->profile_id.len, last_dst->profile_id.s );
			} else {
					LM_WARN("reset LB - ignore unknown previous resource "
						"[%.*s]\n", res_val.s.len, res_val.s.s);
			}

			del_res_avp = res_avp;
			res_avp = search_next_avp(del_res_avp, &res_val);
			destroy_avp(del_res_avp);
		}
	}

	return 0;
}
Example #22
0
int lb_route(struct sip_msg *req, int group, struct lb_res_str_list *rl,
						unsigned int flags, struct lb_data *data, int reuse)
{
	/* resources for previous iteration */
	static struct lb_resource **res_prev = NULL;
	static unsigned int res_prev_size = 0;
	/* resources for new iteration */
	static struct lb_resource **res_new = NULL;
	static unsigned int res_new_size = 0;
	/* probed destinations bitmap */
	static unsigned int *dst_bitmap = NULL;
	static unsigned int bitmap_size = 0;
	/* selected destinations buffer */
	static struct lb_dst **dsts = NULL;
	static unsigned int dsts_size = 0;

	/* control vars */
	struct lb_resource **res_cur;
	int res_prev_n, res_new_n, res_cur_n;
	struct lb_dst **dsts_cur;
	struct lb_dst *last_dst, *dst;
	unsigned int dsts_size_cur, dsts_size_max;
	unsigned int *dst_bitmap_cur;
	unsigned int bitmap_size_cur;
	struct dlg_cell *dlg;

	/* AVP related vars */
	struct usr_avp *group_avp;
	struct usr_avp *flags_avp;
	struct usr_avp *mask_avp;
	struct usr_avp *id_avp;
	struct usr_avp *res_avp;
	int_str group_val;
	int_str flags_val;
	int_str mask_val;
	int_str id_val;
	int_str res_val;

	/* iterators, e.t.c. */
	struct lb_dst *it_d;
	struct lb_resource *it_r;
	int load, it_l;
	int i, j, cond;


	/* init control vars state */
	res_cur = NULL;
	res_cur_n = res_prev_n = res_new_n = 0;
	last_dst = dst = NULL;
	dst_bitmap_cur = NULL;

	/* search and fill new resources references if we should not reuse
	   previous iteration data */
	if( !reuse ) {
		res_new_n = rl->n;
		/* adjust size of statically allocated buffer */
		if( res_new_n > res_new_size ) {
			res_new = (struct lb_resource **)pkg_realloc
				(res_new, (res_new_n * sizeof(struct lb_resource *)));
			if( res_new == NULL ) {
				res_new_size = 0;
				LM_ERR("no more pkg mem - resources ptr buffer realloc "
					"failure\n");
				return -1;
			}
			res_new_size = res_new_n;
		}
		/* fill resource references */
		for( it_r=data->resources,i=0 ; it_r ; it_r=it_r->next ) {
			if( search_resource_str(rl, &it_r->name) ) {
				res_new[i++] = it_r;
				LM_DBG("initial call of LB - found requested %d/%d "
					"resource [%.*s]\n", i, res_new_n,
					it_r->name.len, it_r->name.s);
			}
		}
		if( i != res_new_n ) {
			LM_ERR("initial call of LB - unknown resource found in "
				"input string\n");
			return -1;
		}

		/* set 'res_new' as current iteration buffer */
		res_cur = res_new;
		res_cur_n = res_new_n;
	}

	/* always search for previous iteration data,
	   no matter if we will reuse it or not */
	group_avp = search_first_avp(0, group_avp_name, &group_val, NULL);
	flags_avp = search_first_avp(0, flags_avp_name, &flags_val, NULL);
	mask_avp  = search_first_avp(0, mask_avp_name,  &mask_val,  NULL);
	id_avp    = search_first_avp(0, id_avp_name,    &id_val,    NULL);
	/* sanity checks for fetched AVPs */
	if( group_avp && !(is_avp_str_val(group_avp) == 0) )
		{ destroy_avp(group_avp); group_avp = NULL; }
	if( flags_avp && !(is_avp_str_val(flags_avp) == 0) )
		{ destroy_avp(flags_avp); flags_avp = NULL; }
	if( mask_avp  && !(is_avp_str_val(mask_avp)  != 0) )
		{ destroy_avp(mask_avp);  mask_avp  = NULL; }
	if( id_avp    && !(is_avp_str_val(id_avp)    == 0) )
		{ destroy_avp(id_avp);    id_avp    = NULL; }

	/* get previous iteration destination, if any */
	if( id_avp ) {
		for( it_d=data->dsts ; it_d ; it_d=it_d->next ) {
			if( it_d->id == id_val.n ) {
				last_dst = it_d;
				LM_DBG("%s call of LB - found previous dst %d [%.*s]\n",
					(reuse ? "sequential" : "initial"), last_dst->id,
					last_dst->profile_id.len, last_dst->profile_id.s);
				break;
			}
		}
	}
	/* search and fill previous iteration resources references only if... */
	if(
		/* we should reuse previous resources list */
		reuse ||
		/* we have 'last_dst', i.e. previous iteration was successfull and
		 * we need to clean it up */
		(last_dst != NULL)
	) {
		do {
			cond = 0; /* use it here as a 'start loop again' flag */
			res_prev_n = 0;
			res_avp = search_first_avp(0, res_avp_name, &res_val, NULL);
			for( ; res_avp ; res_avp=search_next_avp(res_avp, &res_val) ) {
				/* ignore AVPs with invalid type */
				if( !(is_avp_str_val(res_avp) != 0) ) continue;

				if ( (it_r=get_resource_by_name( data, &res_val.s))==NULL ) {
					LM_WARN("%s call of LB - ignore unknown previous "
						"resource [%.*s]\n", (reuse?"sequential":"initial"),
						res_val.s.len, res_val.s.s);
					continue;
				}
				/* fill buffer only if buffer size not exeeded */
				if( res_prev_n < res_prev_size ) {
					res_prev[res_prev_n] = it_r;
					LM_DBG("%s call of LB - found previous resource [%.*s]\n",
						(reuse ? "sequential" : "initial"),
						it_r->name.len, it_r->name.s);
				}
				res_prev_n++;
			}
			/* adjust size of statically allocated buffer */
			if( res_prev_n > res_prev_size ) {
				/* small hack: if we need to adjust 'res_prev' buffer adjust
				 * it according to 'res_new' size to minimize 
				 * future pkg_realloc()'s */
				if( !reuse && (res_prev_n < res_new_n) )
					res_prev_n = res_new_n;

				res_prev = (struct lb_resource **)pkg_realloc
					(res_prev, (res_prev_n * sizeof(struct lb_resource *)));
				if( res_prev == NULL ) {
					res_prev_size = 0;
					LM_ERR("no more pkg mem - previous resources ptr "
						"buffer realloc failure\n");
					return -1;
				}
				res_prev_size = res_prev_n;
				cond = 1;
			}
		}
		while( cond );
	}

	/* reuse previous iteration resources, group and flags */
	if( reuse ) {
		/* set 'res_prev' as current iteration buffer */
		res_cur = res_prev;
		res_cur_n = res_prev_n;
		if( res_cur_n == 0 ) {
			LM_ERR("sequential call of LB - cannot find previous resources\n");
			return -1;
		}
		if( group_avp )
			group = group_val.n;
		else {
			LM_ERR("sequential call of LB - cannot find previous group\n");
			return -1;
		}
		if( flags_avp )
			flags = flags_val.n;
		else
			flags = LB_FLAGS_DEFAULT;

		LM_DBG("sequential call of LB - found previous group %d and "
			"flags 0x%x\n", group, flags);
	}

	/* sanity check - double check that we have a resource list to work with */
	if( (res_cur == NULL) || (res_cur_n == 0) ) {
		LM_ERR("%s call of LB - no resources list to work with\n",
			(reuse ? "sequential" : "initial"));
		return -1;
	}


	/* [re-]initialize/reuse destinations mask */

	/* sanity check - always calculate current iteration
	 * res_cur[]->bitmap_size */
	bitmap_size_cur=(unsigned int)(-1);
	for( i=0 ; i<res_cur_n ; i++ ) {
		if( bitmap_size_cur > res_cur[i]->bitmap_size )
			bitmap_size_cur = res_cur[i]->bitmap_size;
	}
	/* always try to reuse 'mask' buffer from AVP, even if we need 
	 * to reinitialize it to avoid un-neded AVP ops */
	if(mask_avp && (mask_val.s.len==(bitmap_size_cur*sizeof(unsigned int)))) {
		dst_bitmap_cur = (unsigned int *)mask_val.s.s;
	}
	/* ...or use our static buffer */
	if( dst_bitmap_cur == NULL ) {
		/* adjust size of statically allocated buffer */
		if( bitmap_size_cur > bitmap_size ) {
			dst_bitmap = (unsigned int *)pkg_realloc
				(dst_bitmap, (bitmap_size_cur * sizeof(unsigned int)));
			if( dst_bitmap == NULL ) {
				bitmap_size = 0;
				LM_ERR("no more pkg mem - dst bitmap buffer realloc failed\n");
				return -1;
			}
			bitmap_size = bitmap_size_cur;
		}
		dst_bitmap_cur = dst_bitmap;
	}
	/* reinitalize buffer if... */
	if(
		(dst_bitmap_cur == dst_bitmap) || /* it is our static buffer */
		!reuse /* should not reuse previous iteration data */
	) {
		if( reuse ) {
			LM_WARN("sequential call of LB - cannot %s previous mask, routing "
				"will be re-started", (mask_avp ? "reuse" : "find"));
		}

		memset(dst_bitmap_cur, 0xff, (bitmap_size_cur * sizeof(unsigned int)));
		for( i=0 ; i<res_cur_n ; i++ ) {
			for( j=0 ; j<bitmap_size_cur ; j++ )
				dst_bitmap_cur[j] &= res_cur[i]->dst_bitmap[j];
		}
	}

	/* init selected destinations buff */
	dsts_cur = NULL;
	dsts_size_max = (flags & LB_FLAGS_RANDOM) ? data->dst_no : 1;
	if( dsts_size_max > 1 ) {
		if( dsts_size_max > dsts_size ) {
			dsts = (struct lb_dst **)pkg_realloc
				(dsts, (dsts_size_max * sizeof(struct lb_dst *)));
			if( dsts == NULL ) {
				dsts_size_max = dsts_size = 0;
				LM_WARN("no more pkg mem - dsts buffer realloc failed\n");
			}
			else
				dsts_size = dsts_size_max;
		}
		dsts_cur = dsts;
	}
	if( dsts_cur == NULL ) {
		/* fallback to no-buffer / 'select first' scenario */
		dsts_cur = &dst;
		dsts_size_max = 1;
	}

	/* be sure the dialog is created */
	if ( (dlg=lb_dlg_binds.get_dlg())==NULL ) {
		if( lb_dlg_binds.create_dlg(req, 0) != 1 ) {
			LM_ERR("%s call of LB - failed to create dialog\n",
				(reuse ? "sequential" : "initial"));
			return -1;
		}
		/* get the dialog reference */
		dlg = lb_dlg_binds.get_dlg();
	}

	/* we're initialized from here and no errors could abort us */

	/* remove the dialog from previous profiles, if any */
	if ( (last_dst != NULL) && (res_prev_n > 0) ) {
		for( i=0 ; i<res_prev_n ; i++ ) {
			if( lb_dlg_binds.unset_profile(dlg, &last_dst->profile_id,
			res_prev[i]->profile) != 1 )
				LM_ERR("%s call of LB - failed to remove from profile [%.*s]"
					"->[%.*s]\n", (reuse ? "sequential" : "initial"),
					res_prev[i]->profile->name.len,
					res_prev[i]->profile->name.s, last_dst->profile_id.len,
					last_dst->profile_id.s );
		}
	}


	/* lock resources */
	for( i=0 ; i<res_cur_n ; i++ )
		lock_get(res_cur[i]->lock);

	/* do the load-balancing */

	/*  select destinations */
	cond = 0; /* use it here as a 'first iteration' flag */
	load = it_l = 0;
	dsts_size_cur = 0;
	for( it_d=data->dsts,i=0,j=0 ; it_d ; it_d=it_d->next ) {
		if( it_d->group == group ) {
			if( (dst_bitmap_cur[i] & (1 << j)) &&
			((it_d->flags & LB_DST_STAT_DSBL_FLAG) == 0) ) {
				/* valid destination (group & resources & status) */
				if( get_dst_load(res_cur, res_cur_n, it_d, flags, &it_l) ) {
					/* only valid load here */
					if( (it_l > 0) || (flags & LB_FLAGS_NEGATIVE) ) {
						/* only allowed load here */
						if( !cond/*first pass*/ || (it_l > load)/*new max*/ ) {
							cond = 1;
							/* restart buffer */
							dsts_size_cur = 0;
						} else if( it_l < load ) {
							/* lower availability -> new iteration */
							continue;
						}

						/* add destination to to selected destinations buffer,
						 * if we have a room for it */
						if( dsts_size_cur < dsts_size_max ) {
							load = it_l;
							dsts_cur[dsts_size_cur++] = it_d;

							LM_DBG("%s call of LB - destination %d <%.*s> "
								"selected for LB set with free=%d\n",
								(reuse ? "sequential" : "initial"),
								it_d->id, it_d->uri.len, it_d->uri.s, it_l
							);
						}
					}
				} else {
					LM_WARN("%s call of LB - skipping destination %d <%.*s> - "
						"unable to calculate free resources\n",
						(reuse ? "sequential" : "initial"),
						it_d->id, it_d->uri.len, it_d->uri.s
					);
				}
			}
			else {
				LM_DBG("%s call of LB - skipping destination %d <%.*s> "
					"(filtered=%d , disabled=%d)\n",
					(reuse ? "sequential" : "initial"),
					it_d->id, it_d->uri.len, it_d->uri.s,
					((dst_bitmap_cur[i] & (1 << j)) ? 0 : 1),
					((it_d->flags & LB_DST_STAT_DSBL_FLAG) ? 1 : 0)
				);
			}
		}
		if( ++j == (8 * sizeof(unsigned int)) ) { i++; j=0; }
	}
	/* choose one destination among selected */
	if( dsts_size_cur > 0 ) {
		if( (dsts_size_cur > 1) && (flags & LB_FLAGS_RANDOM) ) {
			dst = dsts_cur[rand() % dsts_size_cur];
		} else {
			dst = dsts_cur[0];
		}
	}


	if( dst != NULL ) {
		LM_DBG("%s call of LB - winning destination %d <%.*s> selected "
			"for LB set with free=%d\n",
			(reuse ? "sequential" : "initial"),
			dst->id, dst->uri.len, dst->uri.s, load );

		/* add to the profiles */
		for( i=0 ; i<res_cur_n ; i++ ) {
			if( lb_dlg_binds.set_profile(dlg, &dst->profile_id,
			res_cur[i]->profile, 0) != 0 )
				LM_ERR("%s call of LB - failed to add to profile [%.*s]->"
					"[%.*s]\n", (reuse ? "sequential" : "initial"),
					res_cur[i]->profile->name.len, res_cur[i]->profile->name.s,
					dst->profile_id.len, dst->profile_id.s);
		}

		/* set dst as used (not selected) */
		for( it_d=data->dsts,i=0,j=0 ; it_d ; it_d=it_d->next ) {
			if( it_d == dst ) { dst_bitmap_cur[i] &= ~(1 << j); break; }
			if( ++j == (8 * sizeof(unsigned int)) ) { i++; j=0; }
		}
	} else {
		LM_DBG("%s call of LB - no destination found\n",
			(reuse ? "sequential" : "initial"));
	}

	/* unlock resources */
	for( i=0 ; i<res_cur_n ; i++ )
		lock_release(res_cur[i]->lock);

	/* we're done with load-balancing, now save state */

	/* save state - group */
	if( group_avp == NULL ) {
		group_val.n = group;
		if( add_avp(0, group_avp_name, group_val) != 0 ) {
			LM_ERR("failed to add GROUP AVP\n");
		}
	} else if( group_val.n != group ) {
		group_avp->data = (void *)(long)group;
	}
	/* save state - flags, save only if they are set */
	if( flags_avp == NULL ) {
		if( flags != LB_FLAGS_DEFAULT ) {
			flags_val.n = flags;
			if( add_avp(0, flags_avp_name, flags_val) != 0 ) {
				LM_ERR("failed to add FLAGS AVP\n");
			}
		}
	} else if( flags_val.n != flags ) {
		flags_avp->data = (void *)(long)flags;
	}
	/* save state - dst_bitmap mask */
	if( (mask_avp!=NULL) && (dst_bitmap_cur!=(unsigned int *)mask_val.s.s) ) {
		destroy_avp(mask_avp);
		mask_avp = NULL;
	}
	if( mask_avp == NULL ) {
		mask_val.s.s = (char *)dst_bitmap_cur;
		mask_val.s.len = bitmap_size_cur * sizeof(unsigned int);
		if( add_avp(AVP_VAL_STR, mask_avp_name, mask_val) != 0 ) {
			LM_ERR("failed to add MASK AVP\n");
		}
	}
	/* save state - dst, save only if we have one */
	if( id_avp == NULL ) {
		if( dst != NULL ) {
			id_val.n = dst->id;
			if( add_avp(0, id_avp_name, id_val) != 0 ) {
				LM_ERR("failed to add ID AVP\n");
			}
		}
	} else {
		if( dst != NULL ) {
			id_avp->data = (void *)(long)dst->id;
		} else {
			destroy_avp(id_avp);
			id_avp = NULL;
		}
	}
	/* save state - res */
	/* iterate AVPs once and delete old resources */
	destroy_avps(0, res_avp_name, 1 /*all*/);
	/* add new resources */
	for( i=0 ; i<res_cur_n ; i++ ) {
		res_val.s = res_cur[i]->name;
		if( add_avp(AVP_VAL_STR, res_avp_name, res_val) != 0 )
			LM_ERR("failed to add RES AVP\n");
	}

	/* outcome: set dst uri */
	if( (dst != NULL) && (set_dst_uri(req, &dst->uri) != 0) ) {
		LM_ERR("failed to set duri\n");
		return -2;
	}

	return dst ? 0 : -2;
}
Example #23
0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, others error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int i, errcode;
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    osp_inbound inbound;
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char useragent[OSP_STRBUF_SIZE];
    struct usr_avp* avp = NULL;
    int_str avpval;
    unsigned int cinfonum = 0;
    char cinfo[OSP_DEF_CINFONUM][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    struct timeval ts, te, td;
    char datebuf[OSP_STRBUF_SIZE];
    unsigned int sdpfpnum = 0;
    char sdpfp[OSP_DEF_SDPFPNUM][OSP_STRBUF_SIZE];
    char* sdpfpstr[OSP_DEF_SDPFPNUM];
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    ospInitInboundInfo(&inbound);

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetFromUser(msg, inbound.calling, sizeof(inbound.calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUser(msg, inbound.called, sizeof(inbound.called)) != 0) && (ospGetToUser(msg, inbound.called, sizeof(inbound.called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetSource(msg, inbound.source, sizeof(inbound.source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSrcDev(msg, inbound.srcdev, sizeof(inbound.srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        inbound.authtime = time(NULL);

        if(msg->rcv.bind_address && msg->rcv.bind_address->address_str.s) {
            ospCopyStrToBuffer(&msg->rcv.bind_address->address_str, inbound.ingressaddr, sizeof(inbound.ingressaddr));
        }

        ospConvertToOutAddress(inbound.source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(inbound.srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
        case 2:
            OSPPTransactionSetServiceType(trans, (_osp_service_type == 1) ? OSPC_SERVICE_NPQUERY : OSPC_SERVICE_CNAMQUERY);

            ospGetToHost(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParam(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetFromDisplay(msg, inbound.fromdisplay, sizeof(inbound.fromdisplay)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_DISPLAYNAME, inbound.fromdisplay);
        }

        if (ospGetFromUri(msg, inbound.fromuri, sizeof(inbound.fromuri)) == 0) {
            OSPPTransactionSetFrom(trans, OSPC_NFORMAT_URL, inbound.fromuri);
        }

        if (ospGetToUri(msg, inbound.touri, sizeof(inbound.touri)) == 0) {
            OSPPTransactionSetTo(trans, OSPC_NFORMAT_URL, inbound.touri);
        }

        if (ospGetPaiUser(msg, inbound.paiuser, sizeof(inbound.paiuser)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, inbound.paiuser);
        }

        if (ospGetRpidUser(msg, inbound.rpiduser, sizeof(inbound.rpiduser)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, inbound.rpiduser);
        }

        if (ospGetPciUser(msg, inbound.pciuser, sizeof(inbound.pciuser)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, inbound.pciuser);
        }

        if (ospGetDiversion(msg, inbound.divuser, sizeof(inbound.divuser), inbound.divhost, sizeof(inbound.divhost)) == 0) {
            ospConvertToOutAddress(inbound.divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, inbound.divuser, divhostbuf);

        if (ospGetUserAgent(msg, useragent, sizeof(useragent)) == 0) {
            OSPPTransactionSetUserAgent(trans, useragent);
        }

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetAVP(_osp_snid_avpid, _osp_snid_avptype, inbound.snid, sizeof(inbound.snid)) == 0) {
            OSPPTransactionSetNetworkIds(trans, inbound.snid, "");
        } else {
            inbound.snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFONUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
        }

        if (ospGetAVP(_osp_srcmedia_avpid, _osp_srcmedia_avptype, inbound.srcmedia, sizeof(inbound.srcmedia)) == 0) {
            OSPPTransactionSetSrcAudioAddr(trans, inbound.srcmedia);
        } else {
            inbound.srcmedia[0] = '\0';
        }

        inbound.date = 0;
        if (ospGetAVP(_osp_reqdate_avpid, _osp_reqdate_avptype, datebuf, sizeof(datebuf)) == 0) {
            if (ospStrToTime(datebuf, &inbound.date) == 0) {
                OSPPTransactionSetRequestDate(trans, inbound.date);
            }
        }

        if (_osp_sdpfp_avpid >= 0) {
            for (i = 0, avp = search_first_avp(_osp_sdpfp_avptype, _osp_sdpfp_avpid, NULL, 0);
                ((i < OSP_DEF_SDPFPNUM) && (avp != NULL));
                i++, avp = search_next_avp(avp, NULL))
            {
                get_avp_val(avp, &avpval);
                if ((avp->flags & AVP_VAL_STR) && (avpval.s.s && avpval.s.len)) {
                    snprintf(sdpfp[i], sizeof(sdpfp[i]), "%.*s", avpval.s.len, avpval.s.s);
                } else {
                    sdpfp[i][0] = '\0';
                }
            }
            sdpfpnum = i;

            for (i = 0; i < sdpfpnum; i++) {
                sdpfpstr[i] = sdpfp[sdpfpnum - i - 1];
            }

            OSPPTransactionSetFingerPrint(trans, sdpfpnum, (const char**)sdpfpstr);
        }

        ospReportIdentity(trans);

        LM_INFO("request auth and routing for: "
            "service '%d' "
            "source '%s' "
            "srcdev '%s' "
            "snid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "fromdisplay '%s' "
            "paiuser '%s' "
            "rpiduser '%s' "
            "pciuser '%s' "
            "divuser '%s' "
            "divhost '%s' "
            "srcmedia '%s' "
            "callid '%.*s' "
            "destcount '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            inbound.snid,
            inbound.calling,
            inbound.called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            inbound.fromdisplay,
            inbound.paiuser,
            inbound.rpiduser,
            inbound.pciuser,
            inbound.divuser,
            divhostbuf,
            inbound.srcmedia,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        gettimeofday(&ts, NULL);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            inbound.calling,   /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            inbound.called,    /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        gettimeofday(&te, NULL);

        timersub(&te, &ts, &td);
        LM_INFO("authreq cost = %lu.%06lu for call-id '%.*s'\n", td.tv_sec, td.tv_usec, callids[0]->Length, callids[0]->Value);

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, &inbound) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_HTTP_BAD_REQUEST:
                    result = -4000;
                    break;
                case OSPC_ERR_TRAN_BAD_REQUEST:
                    result = -4001;
                    break;
                case OSPC_ERR_HTTP_UNAUTHORIZED:
                    result = -4010;
                    break;
                case OSPC_ERR_TRAN_UNAUTHORIZED:
                    result = -4011;
                    break;
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -4030;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -4040;
                    break;
                case OSPC_ERR_TRAN_MAY_NOT_ORIGINATE:
                    result = -4050;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -4280;
                    break;
                case OSPC_ERR_SOCK_CONNECT_FAILED:
                    result = -4800;
                    break;
                case OSPC_ERR_SOCK_SELECT_FAILED:
                    result = -4801;
                    break;
                case OSPC_ERR_HTTP_SERVER_NOT_READY:
                    result = -4802;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -4840;
                    break;
                case OSPC_ERR_HTTP_SERVICE_UNAVAILABLE:
                    result = -5030;
                    break;
                case OSPC_ERR_TRAN_DECLINE:
                    result = -6030;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}
Example #24
0
static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];

	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	struct sip_msg* msg;
	struct sip_msg* req;
	int_str        avp_value;
	struct usr_avp *avp;
	char statusbuf[8];
	
	if(t==NULL || t->uas.request==0 || ps==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}

	req = ps->req;
	msg = ps->rpl;
	if(msg==NULL || req==NULL)
	{
		LM_DBG("no reply\n");
		return;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) &&  trace_is_off(req))
	{
		LM_DBG("trace off...\n");
		return;
	}

	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	if(msg->len>0) {
		db_vals[0].val.blob_val.s   = msg->buf;
		db_vals[0].val.blob_val.len = msg->len;
	} else {
		db_vals[0].val.blob_val.s   = "No reply buffer";
		db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
	}

	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = t->method.s;
	db_vals[2].val.str_val.len = t->method.len;
		
	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(ps->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	siptrace_copy_proto(msg->rcv.proto, fromip_buff);
	strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
	strcat(fromip_buff,":");
	strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
	db_vals[4].val.string_val = fromip_buff;
	
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	// db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
	if(trace_local_ip)
		db_vals[5].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, toip_buff);
		strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
		strcat(toip_buff,":");
		strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "in";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(req) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("storing info ...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Example #25
0
/*
 * Request OSP authorization and routeing
 * param msg SIP message
 * param ignore1
 * param ignore2
 * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure, MODULE_RETURNCODE_ERROR error
 */
int ospRequestRouting(
    struct sip_msg* msg,
    char* ignore1,
    char* ignore2)
{
    int errcode;
    time_t authtime;
    char calling[OSP_STRBUF_SIZE];
    char called[OSP_STRBUF_SIZE];
    char rn[OSP_STRBUF_SIZE];
    char cic[OSP_STRBUF_SIZE];
    int npdi;
    OSPE_OPERATOR_NAME type;
    char opname[OSPC_OPNAME_NUMBER][OSP_STRBUF_SIZE];
    char source[OSP_STRBUF_SIZE];
    char sourcebuf[OSP_STRBUF_SIZE];
    char srcdev[OSP_STRBUF_SIZE];
    char srcdevbuf[OSP_STRBUF_SIZE];
    char rpid[OSP_STRBUF_SIZE];
    char pai[OSP_STRBUF_SIZE];
    char divuser[OSP_STRBUF_SIZE];
    char divhost[OSP_STRBUF_SIZE];
    char divhostbuf[OSP_STRBUF_SIZE];
    char pci[OSP_STRBUF_SIZE];
    struct usr_avp* snidavp = NULL;
    int_str snidval;
    char snid[OSP_STRBUF_SIZE];
    struct usr_avp* cinfoavp = NULL;
    int_str cinfoval;
    unsigned int cinfonum = 0, i;
    char cinfo[OSP_DEF_CINFOS][OSP_STRBUF_SIZE];
    char cinfostr[OSP_STRBUF_SIZE];
    unsigned int callidnumber = 1;
    OSPT_CALL_ID* callids[callidnumber];
    unsigned int logsize = 0;
    char* detaillog = NULL;
    char tohost[OSP_STRBUF_SIZE];
    char tohostbuf[OSP_STRBUF_SIZE];
    const char* preferred[2] = { NULL };
    unsigned int destcount;
    OSPTTRANHANDLE trans = -1;
    int result = MODULE_RETURNCODE_FALSE;

    if ((errcode = OSPPTransactionNew(_osp_provider, &trans)) != OSPC_ERR_NO_ERROR) {
        LM_ERR("failed to create new OSP transaction (%d)\n", errcode);
    } else if (ospGetFromUserpart(msg, calling, sizeof(calling)) != 0) {
        LM_ERR("failed to extract calling number\n");
    } else if ((ospGetUriUserpart(msg, called, sizeof(called)) != 0) && (ospGetToUserpart(msg, called, sizeof(called)) != 0)) {
        LM_ERR("failed to extract called number\n");
    } else if (ospGetCallId(msg, &(callids[0])) != 0) {
        LM_ERR("failed to extract call id\n");
    } else if (ospGetSource(msg, source, sizeof(source)) != 0) {
        LM_ERR("failed to extract source address\n");
    } else if (ospGetSourceDevice(msg, srcdev, sizeof(srcdev)) != 0) {
        LM_ERR("failed to extract source deivce address\n");
    } else {
        authtime = time(NULL);

        ospConvertToOutAddress(source, sourcebuf, sizeof(sourcebuf));
        ospConvertToOutAddress(srcdev, srcdevbuf, sizeof(srcdevbuf));

        switch (_osp_service_type) {
        case 1:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_NPQUERY);

            ospGetToHostpart(msg, tohost, sizeof(tohost));
            ospConvertToOutAddress(tohost, tohostbuf, sizeof(tohostbuf));
            preferred[0] = tohostbuf;

            destcount = 1;
            break;
        case 0:
        default:
            OSPPTransactionSetServiceType(trans, OSPC_SERVICE_VOICE);

            destcount = _osp_max_dests;
            break;
        }

        if (ospGetNpParameters(msg, rn, sizeof(rn), cic, sizeof(cic), &npdi) == 0) {
            OSPPTransactionSetNumberPortability(trans, rn, cic, npdi);
        }

        for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
            if (ospGetOperatorName(msg, type, opname[type], sizeof(opname[type])) == 0) {
                OSPPTransactionSetOperatorName(trans, type, opname[type]);
            }
        }

        if (ospGetRpidUserpart(msg, rpid, sizeof(rpid)) == 0) {
            OSPPTransactionSetRemotePartyId(trans, OSPC_NFORMAT_E164, rpid);
        }

        if (ospGetPaiUserpart(msg, pai, sizeof(pai)) == 0) {
            OSPPTransactionSetAssertedId(trans, OSPC_NFORMAT_E164, pai);
        }

        if (ospGetDiversion(msg, divuser, sizeof(divuser), divhost, sizeof(divhost)) == 0) {
            ospConvertToOutAddress(divhost, divhostbuf, sizeof(divhostbuf));
        } else {
            divhostbuf[0] = '\0';
        }
        OSPPTransactionSetDiversion(trans, divuser, divhostbuf);

        OSPPTransactionSetProtocol(trans, OSPC_PROTTYPE_SOURCE, OSPC_PROTNAME_SIP);

        if (ospGetPChargeInfoUserpart(msg, pci, sizeof(pci)) == 0) {
            OSPPTransactionSetChargeInfo(trans, OSPC_NFORMAT_E164, pci);
        }

        if ((_osp_snid_avpid >= 0) &&
            ((snidavp = search_first_avp(_osp_snid_avptype, _osp_snid_avpid, &snidval, 0)) != NULL) &&
            (snidavp->flags & AVP_VAL_STR) && (snidval.s.s && snidval.s.len))
        {
            snprintf(snid, sizeof(snid), "%.*s", snidval.s.len, snidval.s.s);
            snid[sizeof(snid) - 1] = '\0';
            OSPPTransactionSetNetworkIds(trans, snid, "");
        } else {
            snid[0] = '\0';
        }

        if (_osp_cinfo_avpid >= 0) {
            for (i = 0, cinfoavp = search_first_avp(_osp_cinfo_avptype, _osp_cinfo_avpid, NULL, 0);
                ((i < OSP_DEF_CINFOS) && (cinfoavp != NULL));
                i++, cinfoavp = search_next_avp(cinfoavp, NULL))
            {
                get_avp_val(cinfoavp, &cinfoval);
                if ((cinfoavp->flags & AVP_VAL_STR) && (cinfoval.s.s && cinfoval.s.len)) {
                    snprintf(cinfo[i], sizeof(cinfo[i]), "%.*s", cinfoval.s.len, cinfoval.s.s);
                    cinfo[i][sizeof(cinfo[i]) - 1] = '\0';
                } else {
                    cinfo[i][0] = '\0';
                }
            }
            cinfonum = i;

            cinfostr[0] = '\0';
            for (i = 0; i < cinfonum; i++) {
                if (cinfo[cinfonum - i - 1][0] != '\0') {
                    OSPPTransactionSetCustomInfo(trans, i, cinfo[cinfonum - i - 1]);
                    snprintf(cinfostr + strlen(cinfostr), sizeof(cinfostr) - strlen(cinfostr), "custom_info%d '%s' ", i + 1, cinfo[cinfonum - i - 1]);
                }
            }
            cinfostr[sizeof(cinfostr) - 1] = '\0';
        }

        LM_INFO("request auth and routing for: "
            "service_type '%d' "
            "source '%s' "
            "source_dev '%s' "
            "source_networkid '%s' "
            "calling '%s' "
            "called '%s' "
            "preferred '%s' "
            "nprn '%s' "
            "npcic '%s' "
            "npdi '%d' "
            /*
            "spid '%s' "
            "ocn '%s' "
            "spn '%s' "
            "altspn '%s' "
            "mcc '%s' "
            "mnc '%s' "
            */
            "rpid '%s' "
            "pai '%s' "
            "div_user '%s' "
            "div_host '%s' "
            "pci '%s' "
            "call_id '%.*s' "
            "dest_count '%d' "
            "%s\n",
            _osp_service_type,
            sourcebuf,
            srcdevbuf,
            snid,
            calling,
            called,
            (preferred[0] == NULL) ? "" : preferred[0],
            rn,
            cic,
            npdi,
            /*
            opname[OSPC_OPNAME_SPID],
            opname[OSPC_OPNAME_OCN],
            opname[OSPC_OPNAME_SPN],
            opname[OSPC_OPNAME_ALTSPN],
            opname[OSPC_OPNAME_MCC],
            opname[OSPC_OPNAME_MNC],
            */
            rpid,
            pai,
            divuser,
            divhostbuf,
            pci,
            callids[0]->Length,
            callids[0]->Value,
            destcount,
            cinfostr);

        /* try to request authorization */
        errcode = OSPPTransactionRequestAuthorisation(
            trans,             /* transaction handle */
            sourcebuf,         /* from the configuration file */
            srcdevbuf,         /* source device of call, protocol specific, in OSP format */
            calling,           /* calling number in nodotted e164 notation */
            OSPC_NFORMAT_E164, /* calling number format */
            called,            /* called number */
            OSPC_NFORMAT_E164, /* called number format */
            "",                /* optional username string, used if no number */
            callidnumber,      /* number of call ids, here always 1 */
            callids,           /* sized-1 array of call ids */
            preferred,         /* preferred destinations */
            &destcount,        /* max destinations, after call dest_count */
            &logsize,          /* size allocated for detaillog (next param) 0=no log */
            detaillog);        /* memory location for detaillog to be stored */

        if ((errcode == OSPC_ERR_NO_ERROR) &&
            (ospLoadRoutes(trans, destcount, source, srcdev, called, authtime, rpid, pai, divuser, divhostbuf, pci) == 0))
        {
            LM_INFO("there are '%d' OSP routes, call_id '%.*s'\n",
                destcount,
                callids[0]->Length,
                callids[0]->Value);
            result = MODULE_RETURNCODE_TRUE;
        } else {
            LM_ERR("failed to request auth and routing (%d), call_id '%.*s'\n",
                errcode,
                callids[0]->Length,
                callids[0]->Value);
            switch (errcode) {
                case OSPC_ERR_TRAN_ROUTE_BLOCKED:
                    result = -403;
                    break;
                case OSPC_ERR_TRAN_ROUTE_NOT_FOUND:
                    result = -404;
                    break;
                case OSPC_ERR_TRAN_CALLING_INVALID:
                    result = -428;
                    break;
                case OSPC_ERR_TRAN_CALLED_FILTERING:
                    result = -484;
                    break;
                case OSPC_ERR_NO_ERROR:
                    /* AuthRsp ok but ospLoadRoutes fails */
                    result = MODULE_RETURNCODE_ERROR;
                    break;
                default:
                    result = MODULE_RETURNCODE_FALSE;
                    break;
            }
        }
    }

    if (callids[0] != NULL) {
        OSPPCallIdDelete(&(callids[0]));
    }

    if (trans != -1) {
        OSPPTransactionDelete(trans);
    }

    return result;
}
Example #26
0
/*! \brief
 * Adds to request a destination set that includes all highest priority
 * class contacts in "serial_avp" AVP.   If called from a route block,
 * rewrites the request uri with first contact and adds the remaining
 * contacts as branches.  If called from failure route block, adds all
 * contacts as brances.  Removes added contacts from "serial_avp" AVP.
 */
int next_branches( struct sip_msg *msg)
{
	struct usr_avp *avp, *prev;
	int_str val;
	struct socket_info *sock_info;
	qvalue_t q;
	str uri, dst_uri, path;
	char *p;
	unsigned int flags;
	int rval;

	if (route_type != REQUEST_ROUTE && route_type != FAILURE_ROUTE ) {
		/* unsupported route type */
		LM_ERR("called from unsupported route type %d\n", route_type);
		goto error;
	}

	/* Find first avp  */
	avp = search_first_avp(0, serial_avp, &val, 0);

	if (!avp) {
		LM_DBG("no AVPs -- we are done!\n");
		goto error;
	}

	if (!val.s.s) {
		LM_ERR("invalid avp value\n");
		goto error;
	}

	/* *sock_info, flags, q, uri, 0, dst_uri, 0, path, 0,... */

	p = val.s.s;
	sock_info = (struct socket_info*) *((long*) p);
	p += sizeof(long);
	flags = (unsigned int) *((long*) p);
	p += sizeof(long);
	q = (unsigned int) *((long*) p);
	p += sizeof(long);
	uri.s = p;
	uri.len = strlen(p);
	p += uri.len + 1;
	dst_uri.s = p;
	dst_uri.len = strlen(p);
	p += dst_uri.len + 1;
	path.s = p;
	path.len = strlen(p);

	/* Set Request-URI */
	if ( set_ruri(msg, &uri) == -1
	|| set_dst_uri(msg, &dst_uri) == -1
	|| set_path_vector(msg, &path) == -1 )
		goto error1;

	msg->force_send_socket = sock_info;
	set_ruri_q( q );
	setb0flags( flags );

	LM_DBG("Msg information <%.*s,%.*s,%.*s,%d,%u> (avp flag=%u)\n",
				uri.len, uri.s,
				dst_uri.len, dst_uri.s,
				path.len, path.s,
				q, flags, avp->flags);


	if (avp->flags & Q_FLAG) {
		destroy_avp(avp);
		goto done;
	}

	prev = avp;
	avp = search_next_avp(prev, &val);
	destroy_avp(prev);

	/* Append branches until out of branches or Q_FLAG is set */
	while (avp != NULL) {

		if (!val.s.s) {
			LM_ERR("invalid avp value\n");
			continue;
		}

		p = val.s.s;
		sock_info = (struct socket_info*) *((long*) p);
		p += sizeof(long);
		flags = (unsigned int) *((long*) p);
		p += sizeof(long);
		q = (unsigned int) *((long*) p);
		p += sizeof(long);
		uri.s = p;
		uri.len = strlen(p);
		p += strlen(p) + 1;
		dst_uri.s = p;
		dst_uri.len = strlen(p);
		p += strlen(p) + 1;
		path.s = p;
		path.len = strlen(p);

		LM_DBG("Branch information <%.*s,%.*s,%.*s,%d,%u> (avp flag=%u)\n",
				uri.len, uri.s,
				dst_uri.len, dst_uri.s,
				path.len, path.s,
				q, flags, avp->flags);


		rval = append_branch(msg, &uri, &dst_uri, &path,
				q, flags, sock_info);

		if (rval == -1) {
			LM_ERR("append_branch failed\n");
			goto error1;
		}

		if (avp->flags & Q_FLAG) {
			destroy_avp(avp);
			goto done;
		}

		prev = avp;
		avp = search_next_avp(prev, &val);
		destroy_avp(prev);
	}

	return 2;
done:
	return (search_next_avp(avp, NULL)==NULL)?2:1;
error1:
	destroy_avp(avp);
error:
	return -1;
}
Example #27
0
static void trace_sl_onreply_out( unsigned int types, struct sip_msg* req,
									struct sl_cb_param *sl_param)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	int faked = 0;
	struct sip_msg* msg;
	int_str        avp_value;
	struct usr_avp *avp;
	struct ip_addr to_ip;
	int len;
	char statusbuf[5];

	if(req==NULL || sl_param==NULL)
	{
		LM_ERR("bad parameters\n");
		goto error;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) && trace_is_off(req))
	{
		LM_DBG("trace off...\n");
		return;
	}
	
	msg = req;
	faked = 1;
	
	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	db_vals[0].val.blob_val.s   = (sl_param->buffer)?sl_param->buffer->s:"";
	db_vals[0].val.blob_val.len = (sl_param->buffer)?sl_param->buffer->len:0;
	
	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
	db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	if(trace_local_ip)
		db_vals[4].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, fromip_buff);

		strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
		strcat(fromip_buff,":");
		strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
		db_vals[4].val.string_val = fromip_buff;
	}

	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(sl_param->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	memset(&to_ip, 0, sizeof(struct ip_addr));
	if(sl_param->dst==0)
	{
		db_vals[5].val.string_val = "any:255.255.255.255";
	} else {
		su2ip_addr(&to_ip, sl_param->dst);
		siptrace_copy_proto(req->rcv.proto, toip_buff);

		strcat(toip_buff, ip_addr2a(&to_ip));
		strcat(toip_buff, ":");
		strcat(toip_buff,
				int2str((unsigned long)su_getport(sl_param->dst), &len));
		LM_DBG("dest [%s]\n", toip_buff);
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "out";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(msg) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info (%d) ...\n", faked);
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Example #28
0
static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	int faked = 0;
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	struct sip_msg* msg;
	struct sip_msg* req;
	int_str        avp_value;
	struct usr_avp *avp;
	struct ip_addr to_ip;
	int len;
	char statusbuf[8];
	str *sbuf;
	struct dest_info *dst;

	if (t==NULL || t->uas.request==0 || ps==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) &&  trace_is_off(t->uas.request))
	{
		LM_DBG("trace off...\n");
		return;
	}
	
	req = ps->req;
	msg = ps->rpl;
	if(msg==NULL || msg==FAKED_REPLY)
	{
		msg = t->uas.request;
		faked = 1;
	}

	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	sbuf = (str*)ps->extra1;
	if(faked==0)
	{
		if(sbuf!=0 && sbuf->len>0) {
			db_vals[0].val.blob_val.s   = sbuf->s;
			db_vals[0].val.blob_val.len = sbuf->len;
		} else if(t->uas.response.buffer.s!=NULL) {
			db_vals[0].val.blob_val.s   = t->uas.response.buffer.s;
			db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
		} else if(msg->len>0) {
			db_vals[0].val.blob_val.s   = msg->buf;
			db_vals[0].val.blob_val.len = msg->len;
		} else {
			db_vals[0].val.blob_val.s   = "No reply buffer";
			db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
		}
	} else {
		if(sbuf!=0 && sbuf->len>0) {
			db_vals[0].val.blob_val.s   = sbuf->s;
			db_vals[0].val.blob_val.len = sbuf->len;
		} else if(t->uas.response.buffer.s==NULL) {
			db_vals[0].val.blob_val.s = "No reply buffer";
			db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
		} else {
			db_vals[0].val.blob_val.s = t->uas.response.buffer.s;
			db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
		}
	}
	
	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = t->method.s;
	db_vals[2].val.str_val.len = t->method.len;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	
	if(trace_local_ip)
		db_vals[4].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, fromip_buff);

		strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
		strcat(fromip_buff,":");
		strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
		db_vals[4].val.string_val = fromip_buff;
	}
	
	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(ps->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	memset(&to_ip, 0, sizeof(struct ip_addr));
	dst = (struct dest_info*)ps->extra2;
	if(dst==0)
	{
		db_vals[5].val.string_val = "any:255.255.255.255";
	} else {
		su2ip_addr(&to_ip, &dst->to);
		siptrace_copy_proto(dst->proto, toip_buff);
		strcat(toip_buff, ip_addr2a(&to_ip));
		strcat(toip_buff, ":");
		strcat(toip_buff,
				int2str((unsigned long)su_getport(&dst->to), &len));
		LM_DBG("dest [%s]\n", toip_buff);
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "out";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(req) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info (%d) ...\n", faked);
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Example #29
0
static int trace_dialog(struct sip_msg *msg)
{
	unsigned char n;
	struct dlg_cell* dlg;
	struct usr_avp *avp;
	static int_str avp_value;
	str *name;

	if (!msg) {
		LM_ERR("no msg specified\n");
		return -1;
	}

	if (trace_is_off()) {
		LM_DBG("Trace if off...\n");
		return -1;
	}

	/* any need to do tracing here ? check the triggers */
	avp = traced_user_avp<0 ? NULL : search_first_avp(traced_user_avp_type,
			traced_user_avp, &avp_value, 0);
	if (avp==NULL && (msg->flags&trace_flag)==0) {
		LM_DBG("Nothing to trace here\n");
		return -1;
	}

	if (dlgb.create_dlg(msg,0)<1) {
		LM_ERR("failed to create dialog\n");
		return -1;
	}

	dlg = dlgb.get_dlg();
	if (dlg==NULL) {
		LM_CRIT("BUG: no dialog found after create dialog\n");
		return -1;
	}

	if(dlgb.register_dlgcb(dlg, DLGCB_REQ_WITHIN|DLGCB_TERMINATED,
	trace_transaction,0,0)!=0) {
		LM_ERR("failed to register dialog callback\n");
		return -1;
	}

	/* store in dialog the user avps for tracing ; we will restore
	 them for each transactin from the dialog */
	if(traced_user_avp>=0) {
		n = 0;
		while(avp!=NULL) {
			/* generate a name */
			name = generate_val_name(n);
			if (!is_avp_str_val(avp))
				avp_value.s.s=int2str(avp_value.n,
						&avp_value.s.len);
			/* add the avp value as dialog var */
			dlgb.store_dlg_value( dlg, name, &avp_value.s);
			/* next avp */
			avp = search_next_avp( avp, &avp_value);
			n++;
		}
	}

	/* set the flag to trace the rest of the transaction */
	if (msg->flags&trace_flag) {
		avp_value.s.s = "1";
		avp_value.s.len = 1;
		dlgb.store_dlg_value( dlg, &st_flag_val, &avp_value.s);
	}

	/* trace current request */
	sip_trace(msg);

	/* we also want to catch the incoming cancel */
	if ( tmb.register_tmcb( msg, NULL,TMCB_TRANS_CANCELLED,
				siptrace_dlg_cancel, NULL, NULL)<0 ) {
		LM_ERR("failed to register trans cancelled TMCB\n");
	}

	return 1;
}
Example #30
0
static int sip_trace(struct sip_msg *msg, char *s1, char *s2)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+6];
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+6];
	int_str        avp_value;
	struct usr_avp *avp;
	
	if(msg==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return -1;
	}

	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) && (trace_on_flag==NULL || *trace_on_flag==0))
	{
		LM_DBG("trace off...\n");
		return -1;
	}
	
	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}
	
	if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL
			|| msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse call-id\n");
		goto error;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	db_vals[0].val.blob_val.s = msg->buf;
	db_vals[0].val.blob_val.len = msg->len;
	
	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	if(msg->first_line.type==SIP_REQUEST)
	{
		db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
		db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
	} else {
		db_vals[2].val.str_val.s = "";
		db_vals[2].val.str_val.len = 0;
	}
		
	db_keys[3] = status_column;
	db_vals[3].type = DB_STR;
	db_vals[3].nul = 0;
	if(msg->first_line.type==SIP_REPLY)
	{
		db_vals[3].val.str_val.s = msg->first_line.u.reply.status.s;
		db_vals[3].val.str_val.len = msg->first_line.u.reply.status.len;
	} else {
		db_vals[3].val.str_val.s = "";
		db_vals[3].val.str_val.len = 0;
	}
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	siptrace_copy_proto(msg->rcv.proto, fromip_buff);
	strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
	strcat(fromip_buff,":");
	strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
	db_vals[4].val.string_val = fromip_buff;
	
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	// db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
	siptrace_copy_proto(msg->rcv.proto, toip_buff);
	strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
	strcat(toip_buff,":");
	strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
	db_vals[5].val.string_val = toip_buff;
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "in";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());
	
	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if(trace_on_flag!=NULL && *trace_on_flag!=0) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		if(msg->first_line.type==SIP_REPLY)
		{
			update_stat(siptrace_rpl, 1);
		} else {
			update_stat(siptrace_req, 1);
		}
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}

done:
	return 1;
error:
	return -1;
}