vcpe/srcs/service/dhcpd/lease.c

141 lines
3.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by xajhuang on 2023/3/23.
//
#include <time.h>
#include "lease.h"
#include "misc.h"
#include "user_errno.h"
#include "zlog_module.h"
#include "dhcp_network.h"
#include "db_interface.h"
#include "uthash/utlist.h"
//static PMAC_FILTER g_allowTbl = NULL;
//static PMAC_FILTER g_blackListTbl = NULL;
//static PPRE_ALLOC_IP g_pPreAllocIp = NULL;
static uv_mutex_t g_uvLock;
U32 lease_is_pre_assign(PDHCP_REQ pReq) {
char macStr[20] = {0};
U32 ipAddr;
MAC_TO_STR(pReq->cliMac, macStr);
if (db_get_pre_assign(pReq->uid, macStr, pReq->hostName, &ipAddr) == ERR_ITEM_EXISTS) {
return ipAddr;
}
return 0;
}
int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip) {
PLOCK_IP pLock = (PLOCK_IP)malloc(sizeof(LOCK_IP));
if (pLock) {
memset(pLock, 0, sizeof(LOCK_IP));
pLock->ip = ip;
HASH_ADD_INT(pUser->plockIp, ip, pLock);
LOG_MOD(trace, ZM_DHCP_LEASE, "User %u lock ip %s\n", pUser->uid, u32_to_str_ip(ip));
return ERR_SUCCESS;
}
return -ERR_MALLOC_MEMORY;
}
int lease_add_host(PDHCP_REQ pReq) {
PDHCP_USER pUser = dhcp_user_create(pReq->uid);
if (pUser) {
PPOOL_CTX pPool, pTemp;
// 查找对应的地址池
LL_FOREACH_SAFE(pUser->pUserPool, pPool, pTemp) {
// 比较 IP 范围
if (pPool->minAddr <= pReq->cliAddr && pPool->maxAddr >= pReq->cliAddr) {
// 添加记录到数据库
db_add_lease(pReq, pPool);
return ERR_SUCCESS;
}
}
}
return ERR_SUCCESS;
}
int is_pre_assigned(PDHCP_REQ pReq, PPOOL_CTX pCtx) {
// 首先从租约信息中获取数据
if (db_get_lease(pReq, pCtx) == ERR_SUCCESS) {
return ERR_SUCCESS;
}
// 从预分配IP中获取信息
return db_get_pre_lease(pReq, pCtx);
}
int lease_release(PDHCP_REQ pReq) {
return db_release_lease(pReq);
}
//int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX *pOutPool) {
PPOOL_CTX pPool, pTemp;
if (pReq == NULL || pOutIp == NULL || pOutPool == NULL) {
LOG_MOD(error, ZM_DHCP_LEASE, "Input params error: %p, %p\n", pOutIp, pOutPool);
return -ERR_INPUT_PARAMS;
}
LL_FOREACH_SAFE(pUser->pUserPool, pPool, pTemp) {
U32 addr;
// 查看是否预分配过该设备
if ((addr = lease_is_pre_assign(pReq)) != 0) {
*pOutIp = addr;
*pOutPool = pPool;
return ERR_SUCCESS;
}
uv_mutex_lock(&g_uvLock);
addr = pPool->minAddr;
do {
PLOCK_IP pLock;
HASH_FIND_INT(pUser->plockIp, &addr, pLock);
// 该 IP 可用
if (pLock == NULL) {
if (db_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
usr_lease_lock_ip(pUser, addr);
*pOutIp = addr;
*pOutPool = pPool;
db_add_pre_assign(pReq, addr, pPool);
uv_mutex_unlock(&g_uvLock);
return ERR_SUCCESS;
}
}
addr++;
} while (addr <= pPool->maxAddr);
uv_mutex_unlock(&g_uvLock);
}
// 清理所有超时的预分配IP
db_clearup_timeout_lease();
// 没有可预分配的IP报错
//LOG_MOD(error, ZM_DHCP_LEASE, "No free ipaddress in poll: uid = %u, pool = %p\n", pReq->uid, pUser->pUserPool);
return -ERR_DHCP_NO_ADDR;
}
int dhcp_lease_init() {
int rc;
uv_mutex_init(&g_uvLock);
rc = db_init_lease_database();
if (rc != ERR_SUCCESS) {
return rc;
}
// 清理所有超时的预分配IP
db_clearup_timeout_lease();
// lock 预分配 IP
db_lock_pre_assign_ip();
return ERR_SUCCESS;
}