// // Created by xajhuang on 2023/3/23. // #include #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; U32 lease_is_pre_assign(PDHCP_REQ pReq) { char macStr[20] = {0}; U32 ipAddr; MAC_TO_STR(pReq->cliMac, macStr); if (lease_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 (lease_get_from_lease(pReq, pCtx) == ERR_SUCCESS) { return ERR_SUCCESS; } // 从预分配IP中获取信息 return lease_get_from_pre_assign(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; } addr = pPool->minAddr; do { PLOCK_IP pLock; HASH_FIND_INT(pUser->plockIp, &addr, pLock); // 该 IP 可用 if (pLock == NULL) { if (lease_ip_is_pre_assign(pReq->uid, addr) == FALSE) { usr_lease_lock_ip(pUser, addr); *pOutIp = addr; *pOutPool = pPool; lease_db_add_pre_assign(pReq, addr, pPool); return ERR_SUCCESS; } } addr++; } while (addr <= pPool->maxAddr); } // 清理所有超时的预分配IP lease_clearup_timeout_items(); // 没有可预分配的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; rc = lease_init_database(); if (rc != ERR_SUCCESS) { return rc; } // 清理所有超时的预分配IP lease_clearup_timeout_items(); // lock 预分配 IP lease_lock_pre_assign_ip(); return ERR_SUCCESS; }