增加中国IP缓存

This commit is contained in:
2025-01-21 17:06:12 +08:00
parent 5028d24a32
commit 685b29a045
6 changed files with 241 additions and 100 deletions

148
cap.c
View File

@@ -2,6 +2,8 @@
#include "common.h"
#include "libipset.h"
#include "libcurl.h"
#include "cache.h"
pcap_if_t *alldevs, *device;
pcap_t *handle; // 会话句柄
@@ -29,100 +31,6 @@ struct ip_cache_node {
struct ip_cache_node *next; // 指向下一个节点
};
#define MAXIPSET_ 100
#define MAXIPLEN 32
char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 };
// 添加一个 IP 到集合(如果已存在则不添加)
int add_cn_ip(char cn_ip[MAXIPSET_][MAXIPLEN], char *ip)
{
if (ip == NULL || strlen(ip) >= MAXIPLEN) {
return -1; // 错误:无效的 IP 地址或过长
}
// 检查是否已存在
for (int i = 0; i < MAXIPSET_; i++) {
if (cn_ip[i][0] != '\0' && strcmp(cn_ip[i], ip) == 0) {
return 1; // IP 已存在,返回特殊代码
}
}
// 查找空位并添加
for (int i = 0; i < MAXIPSET_; i++) {
if (cn_ip[i][0] == '\0') { // 检查是否为空
strcpy(cn_ip[i], ip);
return 0; // 成功添加
}
}
return -1; // 错误:集合已满
}
// 判断给定的IP地址是否在集合中
int is_ip_in_set(char cn_ip[MAXIPSET_][MAXIPLEN], const char *ip)
{
if (ip == NULL) {
return 0; // 错误无效的IP地址指针
}
for (int i = 0; i < MAXIPSET_; i++) {
if (cn_ip[i][0] != '\0' && strcmp(cn_ip[i], ip) == 0) {
return 1; // 找到匹配的IP地址
}
}
return 0; // 没有找到匹配的IP地址
}
// 计算集合中非空IP的数量
int cn_ip_len(char cn_ip[MAXIPSET_][MAXIPLEN])
{
int count = 0; // 用于计数非空IP
for (int i = 0; i < MAXIPSET_; i++) {
if (cn_ip[i][0] != '\0') {
count++; // 非空IP计数
}
}
return count;
}
// 安全的清理IP地址集合将所有位置置为空字符串
void clear_ip_set(char cn_ip[MAXIPSET_][MAXIPLEN])
{
if (cn_ip == NULL) {
return; // 如果指针无效,则直接返回
}
for (int i = 0; i < MAXIPSET_; i++) {
memset(cn_ip[i], '\0', MAXIPLEN);
}
}
// 检查 IP 是否已在缓存中并是否过期
int is_ip_in_cache(const char *ip)
{
time_t now = time(NULL); // 获取当前时间
struct ip_cache_node *current = ip_cache_head;
struct ip_cache_node *prev = NULL;
while (current != NULL) {
// 如果 IP 匹配并且未过期
if (strcmp(current->ip, ip) == 0) {
if (now - current->timestamp <= CACHE_TTL) {
return 1; // IP 在缓存中,且未过期
} else {
// 如果过期,从链表中移除这个节点
if (prev == NULL) {
ip_cache_head = current->next;
} else {
prev->next = current->next;
}
free(current);
cache_size--;
return 0; // IP 过期,不再缓存
}
}
prev = current;
current = current->next;
}
return 0; // IP 不在缓存中
}
// 将新 IP 添加到缓存,若缓存过大则移除最早的 IP
void add_ip_to_cache(const char *ip)
@@ -161,6 +69,38 @@ void add_ip_to_cache(const char *ip)
cache_size++;
}
// 检查 IP 是否已在缓存中并是否过期
int is_ip_in_cache(const char *ip)
{
time_t now = time(NULL); // 获取当前时间
struct ip_cache_node *current = ip_cache_head;
struct ip_cache_node *prev = NULL;
while (current != NULL) {
// 如果 IP 匹配并且未过期
if (strcmp(current->ip, ip) == 0) {
if (now - current->timestamp <= CACHE_TTL) {
return 1; // IP 在缓存中,且未过期
} else {
// 如果过期,从链表中移除这个节点
if (prev == NULL) {
ip_cache_head = current->next;
} else {
prev->next = current->next;
}
free(current);
cache_size--;
return 0; // IP 过期,不再缓存
}
}
prev = current;
current = current->next;
}
return 0; // IP 不在缓存中
}
// 清理缓存链表,释放所有节点的内存
void free_ip_cache()
{
@@ -175,6 +115,7 @@ void free_ip_cache()
cache_size = 0;
}
// 回调函数,在捕获到每个数据包时调用
void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
@@ -264,6 +205,10 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char
} else { // 这时是国内IP
add_cn_ip(cn_ip, src_ip); // 添加国内IP到缓存
_printf("IP: %s 离线库为国外, API 判断为国内, 标记为已处理!!!\n", src_ip);
if (append_string_to_file("cn.txt", src_ip) != 0) {
_printf("append_string_to_file() Error!!!\n");
}
}
} else {
@@ -427,6 +372,21 @@ int main(int argc, char **argv)
exit(1);
}
// 读取缓存
if (1 == file_exists_access("cn.txt")) {
int line_count = 0;
int result = read_file_to_array("cn.txt", cn_ip, &line_count);
if (result != 0) {
fprintf(stderr, "Failed to read file with error code: %d\n", result);
return 1;
}
printf("Read %d lines from file:\n", line_count);
for (int i = 0; i < line_count; i++) {
printf("Line %d: %s\n", i + 1, cn_ip[i]);
}
}
pid = fork(); // 创建子进程
if (pid == 0) // 子进程
{