vcpe/srcs/service/dhcpd/lease.c

163 lines
5.2 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 "user_errno.h"
#include "zlog_module.h"
#include "database.h"
#include "user_mgr.h"
#define LEASE_DB_NAME ("lease")
#define PREALLOC_IP_TIMEOUT (60)
typedef struct {
U32 ipAddr;
char macAddr[20];
U32 bitset;
PIPPOOL_INFO pCtx;
U32 timeStamp;
UT_hash_handle hh;
} PRE_ALLOC_IP, *PPRE_ALLOC_IP;
//static PMAC_FILTER g_allowTbl = NULL;
//static PMAC_FILTER g_blackListTbl = NULL;
static PPRE_ALLOC_IP g_pPreAllocIp = NULL;
#define CREATE_LEASE_TABLE(name) \
"CREATE TABLE IF NOT EXISTS " #name \
" ( id INTEGER PRIMARY KEY AUTOINCREMENT," \
" uid INTEGER NOT NULL," \
" mac CHAR(20) NOT NULL," \
" ip INTEGER NOT NULL," \
" lease INTEGER NOT NULL," \
" createTm INTEGER NOT NULL," \
" netmask INTEGER," \
" gateway INTEGER," \
" dns1 INTEGER," \
" dns2 INTEGER," \
" server INTEGER NOT NULL," \
" hostname CHAR(64) DEFAULT '' NOT NULL," \
" keyType INTEGER NOT NULL" \
");" \
"CREATE INDEX IF NOT EXISTS " #name "_index ON " #name " (uid, mac);"
int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
PIPPOOL_INFO pPool, pTemp;
PPRE_ALLOC_IP pNewIp, pTmp, pCache = NULL;
PIPPOOL_INFO pUserPool;
if (pOutIp == NULL || pOutPool == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Input params error: %p, %p\n", pOutIp, pOutPool);
return -ERR_INPUT_PARAMS;
}
pUserPool = user_get_pool(uid);
if (pUserPool == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Can't found avaliable address pool\n");
return -ERR_DHCP_NO_POOL;
}
// 遍历当前用户所有IP地址池
HASH_ITER(hh, pUserPool, pPool, pTemp) {
U32 addr;
// 查看是否预分配过该设备
if (pMac && strlen(pMac) > 0) {
HASH_ITER(hh, g_pPreAllocIp, pNewIp, pTmp) {
if (strcmp(pNewIp->macAddr, pMac) == 0) {
*pOutIp = pNewIp->ipAddr;
*pOutPool = pPool;
return ERR_SUCCESS;
}
}
}
while ((addr = bitset_minimum(pPool->assignPool)) > 0) {
U32 ipAddr = (pPool->minAddr & pPool->netMask) + addr;
// 查找租约配置文件中是否记录了曾经分配的地址, 如果已经分配则获取下一个
// TODO: add process
// if (FALSE) {
// bitset_set(pPool->assignPool, addr);
// continue;
// }
// 查找IP地址是否已经被预分配
HASH_FIND_INT(g_pPreAllocIp, &ipAddr, pNewIp);
if (pNewIp == NULL) {
pNewIp = (PPRE_ALLOC_IP)malloc(sizeof(PRE_ALLOC_IP));
if (!pNewIp) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %lu\n", sizeof(PRE_ALLOC_IP));
continue;
}
memset(pNewIp, 0, sizeof(PRE_ALLOC_IP));
pNewIp->timeStamp = time(NULL);
pNewIp->pCtx = pPool;
pNewIp->ipAddr = ipAddr;
pNewIp->bitset = addr;
if (pMac) {
strcpy(pNewIp->macAddr, pMac);
}
HASH_ADD_INT(g_pPreAllocIp, ipAddr, pNewIp);
*pOutIp = ipAddr;
*pOutPool = pPool;
bitset_cls_bit(pPool->assignPool, addr);
return ERR_SUCCESS;
} else {
if (time(NULL) - pNewIp->timeStamp < PREALLOC_IP_TIMEOUT) {
continue;
}
*pOutIp = pNewIp->ipAddr;
*pOutPool = pPool;
return ERR_SUCCESS;
}
}
}
// 如果没有分配到IP清理过期的预分配IP
HASH_ITER(hh, g_pPreAllocIp, pNewIp, pTmp) {
if (time(NULL) - pNewIp->timeStamp > PREALLOC_IP_TIMEOUT) {
if (pCache == NULL) {
pCache = pNewIp;
} else {
HASH_DEL(g_pPreAllocIp, pNewIp);
free(pNewIp);
bitset_cls_bit(pNewIp->pCtx->assignPool, pNewIp->bitset);
}
}
}
if (pCache) {
*pOutIp = pCache->ipAddr;
*pOutPool = pPool;
return ERR_SUCCESS;
}
// 没有可预分配的IP报错
LOG_MOD(error, ZLOG_MOD_DHCPD, "No free ipaddress in poll: uid = %u, pool = 0x%08X\n", uid, pUserPool->poolKey);
return -ERR_DHCP_NO_ADDR;
}
int dhcp_lease_init() {
int rc = 0;
rc = db_sqlite3_sql_exec(CREATE_LEASE_TABLE(LEASE_DB_NAME), NULL, NULL, NULL);
if (rc != ERR_SUCCESS) {
return rc;
}
return ERR_SUCCESS;
}