使用 ip2region 地址定位库判断Ip地域

This commit is contained in:
aixiao 2023-01-30 15:55:22 +08:00
parent c2024e15f5
commit 72bd738a1d
6 changed files with 74 additions and 33 deletions

4
conf.c
View File

@ -174,6 +174,10 @@ static void parse_global_module(char *content, conf * conf)
val_begin_len = val_end - val_begin; val_begin_len = val_end - val_begin;
conf->REGION = atoi(val_begin); conf->REGION = atoi(val_begin);
} }
if (strcasecmp(var, "IP2REGION") == 0) {
val_begin_len = val_end - val_begin;
conf->IP2REGION = atoi(val_begin);
}
if (strcasecmp(var, "REGION_URL") == 0) { if (strcasecmp(var, "REGION_URL") == 0) {
val_begin_len = val_end - val_begin; val_begin_len = val_end - val_begin;
conf->REGION_URL_LEN = val_begin_len; conf->REGION_URL_LEN = val_begin_len;

1
conf.h
View File

@ -32,6 +32,7 @@ typedef struct CONF
// 地域白名单 // 地域白名单
int REGION; int REGION;
int IP2REGION;
char *REGION_URL; char *REGION_URL;
int REGION_URL_LEN; int REGION_URL_LEN;
char *REGION_LIST; char *REGION_LIST;

View File

@ -2,12 +2,12 @@
#include "xdb_searcher.h" #include "xdb_searcher.h"
#include "ip2region.h" #include "ip2region.h"
int ip2region(char *xdb_file, char *ip) char *ip2region(char *xdb_file, char *ip)
{ {
char *db_path = xdb_file; char *db_path = xdb_file;
xdb_vector_index_t *v_index; xdb_vector_index_t *v_index;
xdb_searcher_t searcher; xdb_searcher_t searcher;
char region_buffer[256], ip_buffer[16]; char region_buffer[256];
long s_time; long s_time;
// 1、从 db_path 加载 VectorIndex 索引。 // 1、从 db_path 加载 VectorIndex 索引。
@ -16,14 +16,14 @@ int ip2region(char *xdb_file, char *ip)
v_index = xdb_load_vector_index_from_file(db_path); v_index = xdb_load_vector_index_from_file(db_path);
if (v_index == NULL) { if (v_index == NULL) {
printf("failed to load vector index from `%s`\n", db_path); printf("failed to load vector index from `%s`\n", db_path);
return 1; return NULL;
} }
// 2、使用全局的 VectorIndex 变量创建带 VectorIndex 缓存的 xdb 查询对象 // 2、使用全局的 VectorIndex 变量创建带 VectorIndex 缓存的 xdb 查询对象
int err = xdb_new_with_vector_index(&searcher, db_path, v_index); int err = xdb_new_with_vector_index(&searcher, db_path, v_index);
if (err != 0) { if (err != 0) {
printf("failed to create vector index cached searcher with errcode=%d\n", err); printf("failed to create vector index cached searcher with errcode=%d\n", err);
return 2; return NULL;
} }
// 3、调用 search API 查询 // 3、调用 search API 查询
@ -32,8 +32,10 @@ int ip2region(char *xdb_file, char *ip)
err = xdb_search_by_string(&searcher, ip, region_buffer, sizeof(region_buffer)); err = xdb_search_by_string(&searcher, ip, region_buffer, sizeof(region_buffer));
if (err != 0) { if (err != 0) {
printf("failed search(%s) with errno=%d\n", ip, err); printf("failed search(%s) with errno=%d\n", ip, err);
return NULL;
} else { } else {
printf("{region: %s, took: %d μs}", region_buffer, (int)(xdb_now() - s_time)); ;
//printf("{region: %s, took: %dμs}", region_buffer, (int)(xdb_now() - s_time));
} }
// 备注:并发使用,没一个线程需要单独定义并且初始化一个 searcher 查询对象。 // 备注:并发使用,没一个线程需要单独定义并且初始化一个 searcher 查询对象。
@ -41,5 +43,6 @@ int ip2region(char *xdb_file, char *ip)
// 4、关闭 xdb 查询器,如果是要关闭服务,也需要释放 v_index 的内存。 // 4、关闭 xdb 查询器,如果是要关闭服务,也需要释放 v_index 的内存。
xdb_close(&searcher); xdb_close(&searcher);
xdb_close_vector_index(v_index); xdb_close_vector_index(v_index);
return 0;
return strdup(region_buffer);
} }

View File

@ -2,7 +2,7 @@
#define IP2REGION_H #define IP2REGION_H
int ip2region(char *xdb_file, char *ip); char *ip2region(char *xdb_file, char *ip);
#endif #endif

84
rhost.c
View File

@ -430,23 +430,24 @@ char *remove_space(const char *str)
return strRet; return strRet;
} }
// 磁盘使用率
int disk_waring(int threshold) int disk_waring(int threshold)
{ {
FILE *fp = NULL; FILE *fp = NULL;
char buffer[1024]; char buffer[BUFFER];
char command[1024]; char command[BUFFER];
int is = 0; int is = 0;
#define DF "for u in `df -mh | grep -E -e \".:.\" -e \"^/dev\" | awk '{print $5}' | sed 's|%%||g'`; do if test \"$u\" -ge %d; then echo \"$u\"; fi done" #define DF "for u in `df -mh | grep -E -e \".:.\" -e \"^/dev\" | awk '{print $5}' | sed 's|%%||g'`; do if test \"$u\" -ge %d; then echo \"$u\"; fi done"
memset(buffer, 0, 1024); memset(buffer, 0, BUFFER);
memset(command, 0, 1024); memset(command, 0, BUFFER);
sprintf(command, DF, threshold); sprintf(command, DF, threshold);
//printf("%s\n", command); //printf("%s\n", command);
fp = popen(command, "r"); fp = popen(command, "r");
while(fgets(buffer, 1024, fp) != NULL) while(fgets(buffer, BUFFER, fp) != NULL)
{ {
printf("%s", buffer); printf("%s", buffer);
is = 1; is = 1;
@ -620,33 +621,56 @@ int rule(conf * conf)
} }
} }
if (0 != show_all_rule(buffer)) // libiptc库判断否存在规则 if (0 != show_all_rule(buffer)) // libiptc库判断否存在规则
{ {
char *location_json = NULL; char *location_json = NULL;
char *area = NULL; char *area = NULL;
char URL[conf->REGION_URL_LEN + 32]; char URL[conf->REGION_URL_LEN + 32];
char *xdb_path = "ip2region.xdb";
memset(URL, 0, conf->REGION_URL_LEN + 32);
sprintf(URL, conf->REGION_URL, buffer);
location_json = GET_PUBLIC_IP(URL);
if (location_json == NULL) {
printf("获取地域错误\n");
goto BLOCKED;
}
area = process_json(location_json, conf->REGION_URL);
if (area == NULL) {
printf("解析地域错误\n");
goto BLOCKED;
}
// 地域白名单 // 地域白名单
if (conf->REGION == 1) if (conf->REGION == 1)
{ {
if (isregion(area, region_list) == 1) memset(URL, 0, conf->REGION_URL_LEN + 32);
{ sprintf(URL, conf->REGION_URL, buffer);
location_json = GET_PUBLIC_IP(URL);
if (location_json == NULL) {
printf("获取地域错误\n");
goto BLOCKED;
}
if (conf->IP2REGION == 1) { // ip2region 地址定位库
printf("使用ip2region\n");
if (-1 == access(xdb_path, F_OK)) // 判断 ip2region 地址定位库是否存在
{
xdb_path = "ip2region/ip2region.xdb";
if (-1 == access(xdb_path, F_OK)) {
printf("ip2region.xdb DOESN'T EXISIT!\n");
goto AREA;
}
}
area = ip2region(xdb_path, buffer);
if (area == NULL) {
printf("ip2region解析地域错误\n");
goto BLOCKED;
}
} else {
AREA:
area = process_json(location_json, conf->REGION_URL);
if (area == NULL) {
printf("解析地域错误\n");
goto BLOCKED;
}
}
if (isregion(area, region_list) == 1) {
printf("地域白名单: %s\n", area); printf("地域白名单: %s\n", area);
continue; continue;
} }
@ -913,8 +937,14 @@ int main(int argc, char *argv[], char **env)
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号 signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
/*
// ip2region 离线IP地址定位库 // ip2region 离线IP地址定位库
//ip2region("ip2region/ip2region.xdb", "1.1.1.1"); char *area = NULL;
area = ip2region("ip2region/ip2region.xdb", "1.1.1.1");
printf("%s\n", area);
free(area);
exit(0);
*/
int pid; int pid;
@ -1040,13 +1070,15 @@ int main(int argc, char *argv[], char **env)
{ {
goto_daemon: goto_daemon:
/*
if (daemon(1, 1)) // 守护进程 if (daemon(1, 1)) // 守护进程
{ {
perror("daemon"); perror("daemon");
return -1; return -1;
} }
*/
/*
// 守护进程 // 守护进程
if ((pid = fork()) < 0) { if ((pid = fork()) < 0) {
return 0; return 0;
@ -1082,7 +1114,7 @@ goto_daemon:
free(public_ip); free(public_ip);
exit(0); exit(0);
} }
*/
if (-1 == (nice(-20))) // 进程优先级 if (-1 == (nice(-20))) // 进程优先级
perror("nice"); perror("nice");

View File

@ -22,6 +22,7 @@ global {
REGION = 1; // 是否启用地域白名单(1开启,非1关闭) REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
IP2REGION = 0; // 是否使用 ip2region 地址定位库(1使用,非1不使用)
//REGION_URL = "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8"; // 获取IP地域 //REGION_URL = "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8"; // 获取IP地域
REGION_URL = "https://api01.aliyun.venuscn.com/ip?ip=%s -H Authorization:APPCODE a1d842b8afda418c8ea24271a4e16b1f"; REGION_URL = "https://api01.aliyun.venuscn.com/ip?ip=%s -H Authorization:APPCODE a1d842b8afda418c8ea24271a4e16b1f";
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开) REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)