⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcr_mod.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 4 页
字号:
	new_ruri.len = gw_uri_val.s.len + _m->parsed_uri.user.len + 1;	new_ruri.s = pkg_malloc(new_ruri.len);	if (!new_ruri.s) {	    LOG(L_ERR, "next_gw(): No memory for new R-URI.\n");	    return -1;	}	at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);	if (!at_char) {	    pkg_free(new_ruri.s);	    LOG(L_ERR, "next_gw(): No @ in gateway URI.\n");	    return -1;	}	strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);	if (!strip_char || strip_char > at_char) {	    pkg_free(new_ruri.s);	    LOG(L_ERR, "next_gw(): No strip character | "		"before @ in gateway URI.\n");	    return -1;	}	at = new_ruri.s;	memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);	sscanf(strip_char+1,"%d",&strip);	at = at + (strip_char - gw_uri_val.s.s);	if (_m->parsed_uri.user.len - strip > 0) {	    memcpy(at, _m->parsed_uri.user.s + strip,		   _m->parsed_uri.user.len - strip);	    at = at + _m->parsed_uri.user.len - strip;	}	if (*(at - 1) != ':') {	    memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));	    at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);	} else {	    memcpy(at, at_char + 1, gw_uri_val.s.len -		   (at_char + 1 - gw_uri_val.s.s));	    at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);	}	*at = '\0';	/* Save Request-URI user for use in FAILURE_ROUTE */	val.s = _m->parsed_uri.user;	add_avp(ruri_user_avp_name_str|AVP_VAL_STR, ruri_user_name, val);	DBG("load_gws(): DEBUG: Added ruri_user_avp <%.*s>\n",	    val.s.len, val.s.s);	/* Rewrite Request URI */	act.type = SET_URI_T;	act.p1_type = STRING_ST;	act.p1.string = new_ruri.s;	rval = do_action(&act, _m);	pkg_free(new_ruri.s);	destroy_avp(gw_uri_avp);	if (rval != 1) {	    LOG(L_ERR, "next_gw(): ERROR: do_action failed with return "		"value <%d>\n", rval);	    return -1;	}	return 1;    } else if (route_type == FAILURE_ROUTE) {	/* Create new Request-URI taking URI user from ruri_user AVP	   and other parts of from gateway URI AVP. */	ruri_user_avp = search_first_avp(ruri_user_avp_name_str,					 ruri_user_name, &ruri_user_val, 0);	if (!ruri_user_avp) {	    LOG(L_ERR, "next_gw(): No ruri_user AVP\n");	    return -1;	}	new_ruri.len = gw_uri_val.s.len + ruri_user_val.s.len + 1;	new_ruri.s = pkg_malloc(new_ruri.len);	if (!new_ruri.s) {	    LOG(L_ERR, "next_gw(): No memory for new R-URI.\n");	    return -1;	}	at_char = memchr(gw_uri_val.s.s, '@', gw_uri_val.s.len);	if (!at_char) {	    pkg_free(new_ruri.s);	    LOG(L_ERR, "next_gw(): No @ in gateway URI.\n");	    return -1;	}	strip_char = memchr(gw_uri_val.s.s, '|', gw_uri_val.s.len);	if (!strip_char || strip_char > at_char) {	    pkg_free(new_ruri.s);	    LOG(L_ERR, "next_gw(): No strip character | "		"before @ in gateway URI.\n");	    return -1;	}	at = new_ruri.s;	memcpy(at, gw_uri_val.s.s, strip_char - gw_uri_val.s.s);	sscanf(strip_char+1,"%d",&strip);	at = at + (strip_char - gw_uri_val.s.s);	if (ruri_user_val.s.len - strip > 0) {	    memcpy(at, ruri_user_val.s.s + strip,		   ruri_user_val.s.len - strip);	    at = at + ruri_user_val.s.len - strip;	}	if (*(at - 1) != ':') {	    memcpy(at, at_char, gw_uri_val.s.len - (at_char - gw_uri_val.s.s));	    at = at + gw_uri_val.s.len - (at_char - gw_uri_val.s.s);	} else {	    memcpy(at, at_char + 1, gw_uri_val.s.len -		   (at_char + 1 - gw_uri_val.s.s));	    at = at + gw_uri_val.s.len - (at_char + 1 - gw_uri_val.s.s);	}	*at = '\0';	act.type = APPEND_BRANCH_T;	act.p1_type = STRING_ST;	act.p1.string = new_ruri.s;	act.p2_type = NUMBER_ST;	act.p2.number = 0;	rval = do_action(&act, _m);	pkg_free(new_ruri.s);	destroy_avp(gw_uri_avp);	if (rval != 1) {	    LOG(L_ERR, "next_gw(): ERROR: do_action failed with return "		"value <%d>\n", rval);	    return -1;	}	return 1;    }    /* unsupported route type */    return -1;}/* * Checks if request comes from a gateway */static int do_from_gw(struct sip_msg* _m, int grp_id){    int i;    unsigned int src_addr;    src_addr = _m->rcv.src_ip.u.addr32[0];    for (i = 0; i < MAX_NO_OF_GWS; i++) {	    if ((*gws)[i].ip_addr == 0) {		    return -1;	    }	    if ((*gws)[i].ip_addr == src_addr && 		    (grp_id < 0 || (*gws)[i].grp_id == grp_id)) {		    return 1;	    }    }    return -1;}/* * Checks if request comes from a gateway, taking * into account the group id. */int from_gw_grp(struct sip_msg* _m, char* _s1, char* _s2){	int grp_id;	grp_id = (int)(long)_s1;	return do_from_gw(_m, grp_id);}/* * Checks if request comes from a gateway, ignoring * the group id. */int from_gw(struct sip_msg* _m, char* _s1, char* _s2){	return do_from_gw(_m, -1);}/* * Checks if in-dialog request goes to gateway */static int do_to_gw(struct sip_msg* _m, int grp_id){    char host[16];    struct in_addr addr;    unsigned int i;    if((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {	LOG(L_ERR, "LCR: to_gw: ERROR while parsing the R-URI\n");	return -1;    }    if (_m->parsed_uri.host.len > 15) {	return -1;    }    memcpy(host, _m->parsed_uri.host.s, _m->parsed_uri.host.len);    host[_m->parsed_uri.host.len] = 0;        if (!inet_aton(host, &addr)) {	return -1;    }    for (i = 0; i < MAX_NO_OF_GWS; i++) {	if ((*gws)[i].ip_addr == 0) {	    return -1;	}	if ((*gws)[i].ip_addr == addr.s_addr && 		(grp_id < 0 || (*gws)[i].grp_id == grp_id)) {	    return 1;	}    }    return -1;}/* * Checks if in-dialog request goes to gateway, taking * into account the group id. */int to_gw_grp(struct sip_msg* _m, char* _s1, char* _s2){	int grp_id;	grp_id = (int)(long)_s1;	return do_to_gw(_m, grp_id);}/* * Checks if in-dialog request goes to gateway, ignoring * the group id. */int to_gw(struct sip_msg* _m, char* _s1, char* _s2){	return do_to_gw(_m, -1);}/*  * Frees contact list used by load_contacts function */static inline void free_contact_list(struct contact *curr) {    struct contact *prev;    while (curr) {	prev = curr;	curr = curr->next;	pkg_free(prev);    }}/*  * Loads contacts in destination set into "lcr_contact" AVP in reverse * priority order and associated each contact with Q_FLAG telling if * contact is the last one in its priority class.  Finally, removes * all branches from destination set. */int load_contacts(struct sip_msg* msg, char* key, char* value){	str branch, *ruri;	qvalue_t q, ruri_q;	struct contact *contacts, *next, *prev, *curr;	int_str val;	int idx;	/* Check if anything needs to be done */	if (nr_branches == 0) {	    DBG("load_contacts(): DEBUG: Nothing to do - no branches!\n");	    return 1;	}	ruri = GET_RURI(msg);	if (!ruri) {	    LOG(L_ERR, "ERROR: load_contacts(): No Request-URI found\n");	    return -1;	}	ruri_q = get_ruri_q();	for( idx=0 ; (branch.s=get_branch(idx,&branch.len,&q,0,0,0,0))!=0 ; idx++ ) {	    if (q != ruri_q) {		goto rest;	    }	}	DBG("load_contacts(): DEBUG: Nothing to do - all same q!\n");	return 1;rest:	/* Insert Request-URI to contact list */	contacts = (struct contact *)pkg_malloc(sizeof(struct contact));	if (!contacts) {	    LOG(L_ERR, "ERROR: load_contacts(): No memory for Request-URI\n");	    return -1;	}	contacts->uri.s = ruri->s;	contacts->uri.len = ruri->len;	contacts->q = ruri_q;	contacts->next = (struct contact *)0;	/* Insert branch URIs to contact list in increasing q order */	for( idx=0 ; (branch.s=get_branch(idx,&branch.len,&q,0,0,0,0))!=0 ; idx++ ) {	    next = (struct contact *)pkg_malloc(sizeof(struct contact));	    if (!next) {		LOG(L_ERR, "ERROR: load_contacts(): No memory for branch URI\n");		free_contact_list(contacts);		return -1;	    }	    next->uri = branch;	    next->q = q;	    prev = (struct contact *)0;	    curr = contacts;	    while (curr && (curr->q < q)) {		prev = curr;		curr = curr->next;	    }	    if (!curr) {		next->next = (struct contact *)0;		prev->next = next;	    } else {		next->next = curr;		if (prev) {		    prev->next = next;		} else {		    contacts = next;		}	    }		    	}	/* Assign values for q_flags */	curr = contacts;	curr->q_flag = 0;	while (curr->next) {	    if (curr->q < curr->next->q) {		curr->next->q_flag = Q_FLAG;	    } else {		curr->next->q_flag = 0;	    }	    curr = curr->next;	}	/* Add contacts to "contacts" AVP */	curr = contacts;	while (curr) {	    val.s = curr->uri;	    add_avp(contact_avp_name_str|AVP_VAL_STR|(curr->q_flag),		    contact_name, val);	    DBG("load_contacts(): DEBUG: Loaded <%s>, q_flag <%d>\n",		val.s.s, curr->q_flag);	    	    curr = curr->next;	}	/* Clear all branches */	clear_branches();	/* Free contacts list */	free_contact_list(contacts);	return 1;}/* * Adds to request a destination set that includes all highest priority * class contacts in "lcr_contact" 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 "lcr_contact" AVP. */int next_contacts(struct sip_msg* msg, char* key, char* value){    struct usr_avp *avp, *prev;    int_str val;    struct action act;    int rval;	if ( route_type == REQUEST_ROUTE) {		/* Find first lcr_contact_avp value */		avp = search_first_avp(contact_avp_name_str, contact_name, &val, 0);		if (!avp) {			DBG("next_contacts(): DEBUG: No AVPs -- we are done!\n");			return 1;		}		/* Set Request-URI */		act.type = SET_URI_T;		act.p1_type = STRING_ST;		act.p1.string = val.s.s;		rval = do_action(&act, msg);		if (rval != 1) {			destroy_avp(avp);			return rval;		}		DBG("next_contacts(): DEBUG: R-URI is <%s>\n", val.s.s);		if (avp->flags & Q_FLAG) {			destroy_avp(avp);			/* Set fr_inv_timer */			val.n = inv_timer_next;			if (add_avp(AVP_NAME_STR, inv_timer_name, val) != 0) {				LOG(L_ERR, "next_contacts(): ERROR: setting of "					"fr_inv_timer_avp failed\n");				return -1;			}			return 1;		}		/* Append branches until out of branches or Q_FLAG is set */		prev = avp;		while ((avp = search_next_avp(avp, &val))) {			destroy_avp(prev);			act.type = APPEND_BRANCH_T;			act.p1_type = STRING_ST;			act.p1.string = val.s.s;			act.p2_type = NUMBER_ST;			act.p2.number = 0;			rval = do_action(&act, msg);			if (rval != 1) {				destroy_avp(avp);				LOG(L_ERR, "next_contacts(): ERROR: do_action failed "					"with return value <%d>\n", rval);				return -1;			}			DBG("next_contacts(): DEBUG: Branch is <%s>\n", val.s.s);			if (avp->flags & Q_FLAG) {				destroy_avp(avp);				val.n = inv_timer_next;				if (add_avp(AVP_NAME_STR, inv_timer_name, val) != 0) {					LOG(L_ERR, "next_contacts(): ERROR: setting of "						"fr_inv_timer_avp failed\n");					return -1;				}				return 1;			}			prev = avp;		}	} else if ( route_type == FAILURE_ROUTE) {		avp = search_first_avp(contact_avp_name_str, contact_name, &val, 0);		if (!avp) return -1;		prev = avp;		do {			act.type = APPEND_BRANCH_T;			act.p1_type = STRING_ST;			act.p1.string = val.s.s;			act.p2_type = NUMBER_ST;			act.p2.number = 0;			rval = do_action(&act, msg);			if (rval != 1) {				destroy_avp(avp);				return rval;			}			DBG("next_contacts(): DEBUG: New branch is <%s>\n", val.s.s);			if (avp->flags & Q_FLAG) {				destroy_avp(avp);				return 1;			}			prev = avp;			avp = search_next_avp(avp, &val);			destroy_avp(prev);		} while (avp);		/* Restore fr_inv_timer */		val.n = inv_timer;		if (add_avp(AVP_NAME_STR, inv_timer_name, val) != 0) {			LOG(L_ERR, "next_contacts(): ERROR: setting of "				"fr_inv_timer_avp failed\n");			return -1;		}	} else {		/* unsupported rout type */		return -1;	}	return 1;}/*  * Convert string parameter to integer for functions that expect an integer. * Taken from mediaproxy module. */static int fixstring2int(void **param, int param_count){	unsigned long number;	int err;	if (param_count == 1) {		number = str2s(*param, strlen(*param), &err);		if (err == 0) {			pkg_free(*param);			*param = (void*)number;			return 0;		} else {			LOG(L_ERR, "lcr/fixstring2int(): ERROR: bad number `%s'\n",				(char*)(*param));			return E_CFG;		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -