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

📄 lcr_mod.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 4 页
字号:
	lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int));	if (lcrs_ws_reload_counter == 0) {		LOG(L_ERR, "ERROR: lcr: mod_init(): "			"No memory for counter\n");		goto err;	}	*lcrs_ws_reload_counter = reload_counter = 0;	memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS);	/* First reload */	if (reload_gws() == -1) {		LOG(L_CRIT, "ERROR: lcr:mod_init():"		    " failed to reload gateways and routes\n");		goto err;	}	/* Assign parameter names */	if (str2int(&gw_uri_avp, &par) == 0) {	    gw_uri_name.n = par;	    gw_uri_avp_name_str = 0;	} else {	    gw_uri_name.s = gw_uri_avp;	    gw_uri_avp_name_str = AVP_NAME_STR;	}	if (str2int(&ruri_user_avp, &par) == 0) {	    ruri_user_name.n = par;	    ruri_user_avp_name_str = 0;	} else {	    ruri_user_name.s = ruri_user_avp;	    ruri_user_avp_name_str = AVP_NAME_STR;	}	if (str2int(&contact_avp, &par) == 0) {	    contact_name.n = par;	    contact_avp_name_str = 0;	} else {	    contact_name.s = contact_avp;	    contact_avp_name_str = AVP_NAME_STR;	}	if (str2int(&rpid_avp, &par) == 0) {	    rpid_name.n = par;	    rpid_avp_name_str = 0;	} else {	    rpid_name.s = rpid_avp;	    rpid_avp_name_str = AVP_NAME_STR;	}	inv_timer_name.s = inv_timer_avp;	return 0;err:	return -1;}static void destroy(void){	lcr_db_close();}/* * Sort lcr records by prefix_len and priority. */static int comp_lcrs(const void *m1, const void *m2){	int result = -1;	struct mi *mi1 = (struct mi *) m1;	struct mi *mi2 = (struct mi *) m2;	struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index];	struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index];	/* Sort by prefix. */	if (lcr_record1.prefix_len > lcr_record2.prefix_len) {		result = 1;	}	else if (lcr_record1.prefix_len == lcr_record2.prefix_len) {		/* Sort by priority. */		if (lcr_record1.priority < lcr_record2.priority) {			result = 1;		}		else if (lcr_record1.priority == lcr_record2.priority) {			/* Nothing to do. */			result = 0;		}	}	return result;}/* * Sort lcr records by rand table. */static int rand_lcrs(const void *m1, const void *m2){	int result = -1;	struct mi mi1 = *((struct mi *) m1);	struct mi mi2 = *((struct mi *) m2);	if (mi1.randomizer > mi2.randomizer) {		result = 1;	} else if (mi1.randomizer == mi2.randomizer) {		result = 0;	}	return result;}/* * regcomp each from_uri. */int load_from_uri_regex(){	int i, status, result = 0;	for (i = 0; i < MAX_NO_OF_LCRS; i++) {		if ((*lcrs)[i].end_record != 0) {			break;		}		if (from_uri_reg[i].valid) {			regfree(&(from_uri_reg[i].re));			from_uri_reg[i].valid = 0;		}		memset(&(from_uri_reg[i].re), 0, sizeof(regex_t));		if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){			LOG(L_ERR, "ERROR:lcr:load_regex: bad from_uri re %s\n", 					(*lcrs)[i].from_uri);			result = -1;			break;		}		from_uri_reg[i].valid = 1;	}	if (result != -1) {		reload_counter = *lcrs_ws_reload_counter;	}	return result;}/* * Reload gws to unused gw table and lcrs to unused lcr table, and, when done * make unused gw and lcr table the one in use. */int reload_gws ( void ){    int i;    unsigned int ip_addr, port, strip, prefix_len, from_uri_len, grp_id, priority;    uri_type scheme;    uri_transport transport;    db_con_t* dbh;    char *prefix, *from_uri;    db_res_t* res;    db_row_t* row;    db_key_t gw_cols[7];    db_key_t lcr_cols[4];    gw_cols[0] = ip_addr_col.s;    gw_cols[1] = port_col.s;    gw_cols[2] = uri_scheme_col.s;    gw_cols[3] = transport_col.s;    gw_cols[4] = strip_col.s;    gw_cols[5] = prefix_col.s;    /* FIXME: is this ok if we have different names for grp_id       in the two tables? (ge vw lcr) */    gw_cols[6] = grp_id_col.s;    lcr_cols[0] = prefix_col.s;    lcr_cols[1] = from_uri_col.s;    /* FIXME: is this ok if we have different names for grp_id       in the two tables? (ge vw lcr) */    lcr_cols[2] = grp_id_col.s;    lcr_cols[3] = priority_col.s;    if (lcr_dbf.init==0){	    LOG(L_CRIT, "ERROR: lcr_db_ver: unbound database\n");	    return -1;    }    dbh=lcr_dbf.init(db_url.s);    if (dbh==0){	    LOG(L_ERR, "ERROR: reload_gws: unable to open database connection\n");	    return -1;    }    if (lcr_dbf.use_table(dbh, gw_table.s) < 0) {	    LOG(L_ERR, "lcr_reload_gws(): Error while trying to use gw table\n");	    return -1;    }    if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 7, 0, &res) < 0) {	    LOG(L_ERR, "lcr_reload_gws(): Failed to query gw data\n");	    lcr_dbf.close(dbh);	    return -1;    }    if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) {	    LOG(L_ERR, "reload_gws(): Too many gateways\n");	    lcr_dbf.free_result(dbh, res);	    lcr_dbf.close(dbh);	    return -1;    }        for (i = 0; i < RES_ROW_N(res); i++) {	row = RES_ROWS(res) + i;	if (VAL_NULL(ROW_VALUES(row)) == 1) {		LOG(L_ERR, "reload_gws(): IP address of GW is NULL\n");		lcr_dbf.free_result(dbh, res);		lcr_dbf.close(dbh);		return -1;	}      	ip_addr = (unsigned int)VAL_INT(ROW_VALUES(row));	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {		port = 0;	} else {		port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1);	}	if (port > 65536) {	    LOG(L_ERR, "reload_gws(): Port of GW is too large: %u\n", port);	    lcr_dbf.free_result(dbh, res);	    lcr_dbf.close(dbh);	    return -1;	}	if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {	    scheme = SIP_URI_T;	} else {	    scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2);	    if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) {		LOG(L_ERR, "reload_gws(): Unknown or unsupported URI scheme: %u\n", (unsigned int)scheme);		lcr_dbf.free_result(dbh, res);		lcr_dbf.close(dbh);		return -1;	    }	}	if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {	    transport = PROTO_NONE;	} else {	    transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3);	    if ((transport != PROTO_UDP) && (transport != PROTO_TCP) &&		(transport != PROTO_TLS)) {		LOG(L_ERR, "reload_gws(): Unknown or unsupported transport: %u\n", (unsigned int)transport);		lcr_dbf.free_result(dbh, res);		lcr_dbf.close(dbh);		return -1;	    }	}	if (VAL_NULL(ROW_VALUES(row) + 4) == 1) {	    strip = 0;	} else {	    strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4);	}	if (VAL_NULL(ROW_VALUES(row) + 5) == 1) {	    prefix_len = 0;	    prefix = (char *)0;	} else {	    prefix = (char *)VAL_STRING(ROW_VALUES(row) + 5);	    prefix_len = strlen(prefix);	    if (prefix_len > MAX_PREFIX_LEN) {		LOG(L_ERR, "reload_gws(): too long gw prefix\n");		lcr_dbf.free_result(dbh, res);		lcr_dbf.close(dbh);		return -1;	    }	}	if (VAL_NULL(ROW_VALUES(row) + 6) == 1) {	    grp_id = 0;	} else {	    grp_id = VAL_INT(ROW_VALUES(row) + 6);	}	if (*gws == gws_1) {		gws_2[i].ip_addr = ip_addr;		gws_2[i].port = port;		gws_2[i].grp_id = grp_id;		gws_2[i].scheme = scheme;		gws_2[i].transport = transport;		gws_2[i].strip = strip;		gws_2[i].prefix_len = prefix_len;		if (prefix_len)		    memcpy(&(gws_2[i].prefix[0]), prefix, prefix_len);	} else {		gws_1[i].ip_addr = ip_addr;		gws_1[i].port = port;		gws_1[i].grp_id = grp_id;		gws_1[i].scheme = scheme;		gws_1[i].transport = transport;		gws_1[i].strip = strip;		gws_1[i].prefix_len = prefix_len;		if (prefix_len)		    memcpy(&(gws_1[i].prefix[0]), prefix, prefix_len);	}    }    lcr_dbf.free_result(dbh, res);    if (*gws == gws_1) {	    gws_2[i].ip_addr = 0;	    *gws = gws_2;    } else {	    gws_1[i].ip_addr = 0;	    *gws = gws_1;    }    if (lcr_dbf.use_table(dbh, lcr_table.s) < 0) {	    LOG(L_ERR, "lcr_reload_gws(): Error while trying to use lcr table\n");	    return -1;    }    if (lcr_dbf.query(dbh, NULL, 0, NULL, lcr_cols, 0, 4, 0, &res) < 0) {	    LOG(L_ERR, "lcr_reload_gws(): Failed to query lcr data\n");	    lcr_dbf.close(dbh);	    return -1;    }    if (RES_ROW_N(res) + 1 > MAX_NO_OF_LCRS) {	    LOG(L_ERR, "reload_gws(): Too many lcr entries\n");	    lcr_dbf.free_result(dbh, res);	    lcr_dbf.close(dbh);	    return -1;    }    for (i = 0; i < RES_ROW_N(res); i++) {	row = RES_ROWS(res) + i;	if (VAL_NULL(ROW_VALUES(row)) == 1) {	    prefix_len = 0;	    prefix = 0;	}	else {	    prefix = (char *)VAL_STRING(ROW_VALUES(row));	    prefix_len = strlen(prefix);	    if (prefix_len > MAX_PREFIX_LEN) {	      LOG(L_ERR, "reload_gws(): too long lcr prefix\n");	      lcr_dbf.free_result(dbh, res);	      lcr_dbf.close(dbh);	      return -1;	    }	}	if (VAL_NULL(ROW_VALUES(row) + 1) == 1) {	    from_uri_len = 0;		from_uri = 0;	}	else {	    from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1);	    from_uri_len = strlen(from_uri);	    if (from_uri_len > MAX_FROM_URI_LEN) {		LOG(L_ERR, "reload_gws(): too long from_uri\n");		lcr_dbf.free_result(dbh, res);		lcr_dbf.close(dbh);		return -1;	    }	}	if (VAL_NULL(ROW_VALUES(row) + 2) == 1) {	    LOG(L_ERR, "reload_gws(): route grp_id is NULL\n");	    lcr_dbf.free_result(dbh, res);	    lcr_dbf.close(dbh);	    return -1;	}	grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2);	if (VAL_NULL(ROW_VALUES(row) + 3) == 1) {	    LOG(L_ERR, "reload_gws(): route priority is NULL\n");	    lcr_dbf.free_result(dbh, res);	    lcr_dbf.close(dbh);	    return -1;	}	priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3);	if (*lcrs == lcrs_1) {		lcrs_2[i].prefix_len = prefix_len;		if (prefix_len)		    memcpy(&(lcrs_2[i].prefix[0]), prefix, prefix_len);		lcrs_2[i].from_uri_len = from_uri_len;		if (from_uri_len) {		    memcpy(&(lcrs_2[i].from_uri[0]), from_uri, from_uri_len);		    lcrs_2[i].from_uri[from_uri_len] = '\0';		}		lcrs_2[i].grp_id = grp_id;		lcrs_2[i].priority = priority;		lcrs_2[i].end_record = 0;	} else {		lcrs_1[i].prefix_len = prefix_len;		if (prefix_len)		    memcpy(&(lcrs_1[i].prefix[0]), prefix, prefix_len);		lcrs_1[i].from_uri_len = from_uri_len;                if (from_uri_len) {                    memcpy(&(lcrs_1[i].from_uri[0]), from_uri, from_uri_len);		    lcrs_1[i].from_uri[from_uri_len] = '\0';		}                lcrs_1[i].grp_id = grp_id;		lcrs_1[i].priority = priority;		lcrs_1[i].end_record = 0;	}    }    lcr_dbf.free_result(dbh, res);    lcr_dbf.close(dbh);    if (*lcrs == lcrs_1) {	lcrs_2[i].end_record = 1;	*lcrs = lcrs_2;    } else {	lcrs_1[i].end_record = 1;	*lcrs = lcrs_1;    }    (*lcrs_ws_reload_counter)++;    if (0 != load_from_uri_regex()) {	return -1;    }    return 1;}/* Print gateways stored in current gw table */void print_gws (FILE *reply_file){        unsigned int i, prefix_len;	uri_transport transport;	for (i = 0; i < MAX_NO_OF_GWS; i++) {		if ((*gws)[i].ip_addr == 0) {			break;		}		fprintf(reply_file, "%d => ", i);		fprintf(reply_file, "%d:", (*gws)[i].grp_id);		if ((*gws)[i].scheme == SIP_URI_T) {		    fprintf(reply_file, "sip:");		} else {		    fprintf(reply_file, "sips:");		}		if ((*gws)[i].port == 0) {			fprintf(reply_file, "%d.%d.%d.%d",				((*gws)[i].ip_addr << 24) >> 24,				(((*gws)[i].ip_addr >> 8) << 24) >> 24,				(((*gws)[i].ip_addr >> 16) << 24) >> 24,				(*gws)[i].ip_addr >> 24);		} else {			fprintf(reply_file, "%d.%d.%d.%d:%d",				((*gws)[i].ip_addr << 24) >> 24,				(((*gws)[i].ip_addr >> 8) << 24) >> 24,				(((*gws)[i].ip_addr >> 16) << 24) >> 24,				(*gws)[i].ip_addr >> 24,				(*gws)[i].port);		}                transport = (*gws)[i].transport;                if (transport == PROTO_UDP) {		    fprintf(reply_file, ":udp");                } else  if (transport == PROTO_TCP) {		    fprintf(reply_file, ":tcp");                } else  if (transport == PROTO_TLS) {		    fprintf(reply_file, ":tls");		} else {		    fprintf(reply_file, ":");		}		fprintf(reply_file, ":%d", (*gws)[i].strip);		prefix_len = (*gws)[i].prefix_len;		if (prefix_len) {			fprintf(reply_file, ":%.*s\n",				(int)prefix_len, (*gws)[i].prefix);		} else {		    fprintf(reply_file, ":\n");		}	}	for (i = 0; i < MAX_NO_OF_LCRS; i++) {	    if ((*lcrs)[i].end_record != 0) {		break;	    }	    fprintf(reply_file, "%d => ", i);	    fprintf(reply_file, "%.*s",	(*lcrs)[i].prefix_len, (*lcrs)[i].prefix);	    fprintf(reply_file, ":%.*s", (*lcrs)[i].from_uri_len, (*lcrs)[i].from_uri);	    fprintf(reply_file, ":%u", (*lcrs)[i].grp_id);	    fprintf(reply_file, ":%u\n", (*lcrs)[i].priority);	}}/* * Load info of matching GWs from database to gw_uri AVPs */static int do_load_gws(struct sip_msg* _m, int grp_id){    db_res_t* res;    db_row_t *row, *r;    unsigned int q_len;    str ruri_user, from_uri, value;    char from_uri_str[MAX_FROM_URI_LEN + 1];    char query[MAX_QUERY_SIZE];    char ruri[MAX_URI_SIZE];    unsigned int i, j, k, index;    unsigned int addr, port;    unsigned int strip, gw_index, duplicated_gw;

⌨️ 快捷键说明

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