OCT 1. 暂存开发过程代码

2. 当前预分配地址池管理初步完成
3. 支持本地数据库管理预分配IP
This commit is contained in:
黄昕 2023-04-25 17:06:34 +08:00
parent ae7e3b6d80
commit 47c3f0b4f6
19 changed files with 439 additions and 362 deletions

View File

@ -41,7 +41,7 @@ AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros: AttributeMacros:
- __capability - __capability
- __unused - __unused
BinPackArguments: false BinPackArguments: true
BinPackParameters: false BinPackParameters: false
BraceWrapping: BraceWrapping:
AfterCaseLabel: false AfterCaseLabel: false

View File

@ -165,21 +165,21 @@ static void on_dhcp_recv(uv_work_t *req) {
// Check op flag // Check op flag
if (pkg->dhcp.op != BOOTP_REPLY) { if (pkg->dhcp.op != BOOTP_REPLY) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Error message op code %d\n", pkg->dhcp.op); LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->dhcp.op);
return; return;
} }
// 获取消息类型 // 获取消息类型
ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg); ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Get \'message type\' option error %d\n", ret); LOG_MOD(error, ZM_DHCP_NET, "Get \'message type\' option error %d\n", ret);
return; return;
} }
pInfo = get_dhcp_info_by_id(DHCP_XID(pkg->dhcp.xid)); pInfo = get_dhcp_info_by_id(DHCP_XID(pkg->dhcp.xid));
if (pInfo == NULL) { if (pInfo == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Unknown Client %d\n", DHCP_XID(pkg->dhcp.xid) & 0xFFFFFF); LOG_MOD(error, ZM_DHCP_NET, "Unknown Client %d\n", DHCP_XID(pkg->dhcp.xid) & 0xFFFFFF);
return; return;
} }
@ -224,7 +224,6 @@ static void on_dhcp_recv(uv_work_t *req) {
ret = dhcp_get_option(OPT_DOMAINNAME, pkg->dhcp.options, optSize, &opt); ret = dhcp_get_option(OPT_DOMAINNAME, pkg->dhcp.options, optSize, &opt);
if (ret == ERR_SUCCESS) { if (ret == ERR_SUCCESS) {
strncpy(rspDhcp.domainName, (char *)opt.pValue, MIN((int)opt.len, 64)); strncpy(rspDhcp.domainName, (char *)opt.pValue, MIN((int)opt.len, 64));
DEBUG_CODE_LINE();
} }
pInfo->step = STEP_OFFER; pInfo->step = STEP_OFFER;
@ -260,7 +259,7 @@ int dhcp_tools_init_network(const char *pNicName) {
ret = create_udp_raw_socket(g_pNicName); ret = create_udp_raw_socket(g_pNicName);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret); LOG_MOD(error, ZM_DHCP_NET, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret);
return ret; return ret;
} }

View File

@ -162,7 +162,11 @@ typedef struct {
#pragma pack(pop) #pragma pack(pop)
int dhcpd_init(); typedef enum {
MODE_DHCP_CLIENT,
MODE_DHCP_SERVER
} DHCP_WORK_MODE;
int dhcpd_init(DHCP_WORK_MODE workMode);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -376,7 +376,7 @@ static void dhcpd_task(void *pArg) {
PDHCPD_SETUP p = (PDHCPD_SETUP)pArg; PDHCPD_SETUP p = (PDHCPD_SETUP)pArg;
if (p) { if (p) {
dhcpd_init(); dhcpd_init(MODE_DHCP_SERVER);
//dhcpd_main(p->mode, p->pIni, p->pStatus, p->pIfName); //dhcpd_main(p->mode, p->pIni, p->pStatus, p->pIfName);
if (p->pIni) { if (p->pIni) {

View File

@ -153,11 +153,8 @@ static const char *load_string_value(const char *pKeyName) {
unsigned char *pBuf = base64_decode(&pCfgVal[strlen(ENC_HEAD)], (unsigned int *)&bufSize); unsigned char *pBuf = base64_decode(&pCfgVal[strlen(ENC_HEAD)], (unsigned int *)&bufSize);
if (pBuf == NULL || bufSize <= 0) { if (pBuf == NULL || bufSize <= 0) {
LOG_MOD(error, LOG_MOD(error, ZLOG_MOD_CONFIG, "{%s} setting [%s] maybe a encryption message, base64 decode error.\n",
ZLOG_MOD_CONFIG, pKeyName, pCfgVal);
"{%s} setting [%s] maybe a encryption message, base64 decode error.\n",
pKeyName,
pCfgVal);
return NULL; return NULL;
} }
@ -290,6 +287,10 @@ static int load_array_obj(const char *pKeyName, PCONFIG_ITEM pValue) {
v.vni = 0; v.vni = 0;
} }
if (!config_setting_lookup_int(pObj, "gid", (int *)&v.gid)) {
v.gid = 0;
}
if (!vect_bsearch(pValue->value.array, &v, cmp_dhcp_obj, &idx)) { if (!vect_bsearch(pValue->value.array, &v, cmp_dhcp_obj, &idx)) {
memcpy(&k, &v, sizeof(OBJ_DHCP_RNG)); memcpy(&k, &v, sizeof(OBJ_DHCP_RNG));
vect_push(pValue->value.array, &k); vect_push(pValue->value.array, &k);
@ -402,12 +403,8 @@ static void refreshCfgFileCb() {
int cfgUpgrade = FALSE; int cfgUpgrade = FALSE;
if (!config_read_file(&g_cfgContent, g_cfgFilePath)) { if (!config_read_file(&g_cfgContent, g_cfgFilePath)) {
LOG_MOD(error, LOG_MOD(error, ZLOG_MOD_CONFIG, "%s:%d - %s\n", config_error_file(&g_cfgContent),
ZLOG_MOD_CONFIG, config_error_line(&g_cfgContent), config_error_text(&g_cfgContent));
"%s:%d - %s\n",
config_error_file(&g_cfgContent),
config_error_line(&g_cfgContent),
config_error_text(&g_cfgContent));
return; return;
} }
@ -520,27 +517,15 @@ const char *config_item_dump_fmt(const char *titleMessage) {
sprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId); sprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId);
switch (pItem->valType) { switch (pItem->valType) {
case VAL_BOOL: case VAL_BOOL:
s = sdscatprintf(s, s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
"|%4d | %-25s | %-45s | %-64s |\n",
pItem->cfgId,
tmp2,
pItem->pcfgKey,
CFG_BOOL_VALUE(pItem) ? "True" : "False"); CFG_BOOL_VALUE(pItem) ? "True" : "False");
break; break;
case VAL_INT: case VAL_INT:
s = sdscatprintf(s, s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64lld |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
"|%4d | %-25s | %-45s | %-64lld |\n",
pItem->cfgId,
tmp2,
pItem->pcfgKey,
CFG_INT_VALUE(pItem)); CFG_INT_VALUE(pItem));
break; break;
case VAL_FLOAT: case VAL_FLOAT:
s = sdscatprintf(s, s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64Lf |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
"|%4d | %-25s | %-45s | %-64Lf |\n",
pItem->cfgId,
tmp2,
pItem->pcfgKey,
CFG_FLOAT_VALUE(pItem)); CFG_FLOAT_VALUE(pItem));
break; break;
case VAL_STR: case VAL_STR:
@ -731,12 +716,8 @@ int init_config_system(const char *pCfgFile, const char *pKey) {
config_init(&g_cfgContent); config_init(&g_cfgContent);
for (i = 0; i < ARRAY_SIZE(g_cfgItem); i++) { for (i = 0; i < ARRAY_SIZE(g_cfgItem); i++) {
add_new_cfg_item(g_cfgItem[i].cfgId, add_new_cfg_item(g_cfgItem[i].cfgId, g_cfgItem[i].cfgPath, g_cfgItem[i].valType, g_cfgItem[i].defValue,
g_cfgItem[i].cfgPath, g_cfgItem[i].pStrId, g_cfgItem[i].readme);
g_cfgItem[i].valType,
g_cfgItem[i].defValue,
g_cfgItem[i].pStrId,
g_cfgItem[i].readme);
} }
// clang-format on // clang-format on

View File

@ -19,6 +19,7 @@ typedef struct {
char gateway[20]; char gateway[20];
unsigned int lease; unsigned int lease;
unsigned int vni; unsigned int vni;
unsigned int gid;
} OBJ_DHCP_RNG, *POBJ_DHCP_RNG; } OBJ_DHCP_RNG, *POBJ_DHCP_RNG;
typedef enum { typedef enum {

View File

@ -42,7 +42,12 @@ typedef enum {
ZLOG_MOD(ZLOG_MOD_PPPOE, ZLOG_LEVEL_DEBUG, "PPPOE") \ ZLOG_MOD(ZLOG_MOD_PPPOE, ZLOG_LEVEL_DEBUG, "PPPOE") \
ZLOG_MOD(ZLOG_MOD_VXLAN, ZLOG_LEVEL_DEBUG, "VXLAN") \ ZLOG_MOD(ZLOG_MOD_VXLAN, ZLOG_LEVEL_DEBUG, "VXLAN") \
ZLOG_MOD(ZLOG_MOD_LWIP, ZLOG_LEVEL_DEBUG, "LWIP") \ ZLOG_MOD(ZLOG_MOD_LWIP, ZLOG_LEVEL_DEBUG, "LWIP") \
ZLOG_MOD(ZLOG_MOD_DHCPD, ZLOG_LEVEL_DEBUG, "DHCPD") \ ZLOG_MOD(ZM_DHCP, ZLOG_LEVEL_DEBUG, "DHCP") \
ZLOG_MOD(ZM_DHCP_NET, ZLOG_LEVEL_DEBUG, "DHCP_N") \
ZLOG_MOD(ZM_DHCP_POOL, ZLOG_LEVEL_DEBUG, "DHCP_P") \
ZLOG_MOD(ZM_DHCP_USR, ZLOG_LEVEL_DEBUG, "DHCP_U") \
ZLOG_MOD(ZM_DHCP_LEASE, ZLOG_LEVEL_DEBUG, "DHCP_L") \
ZLOG_MOD(ZM_DHCP_DB, ZLOG_LEVEL_DEBUG, "DHCP_DB") \
ZLOG_MOD(ZLOG_MOD_OPENDHCPD, ZLOG_LEVEL_DEBUG, "ODHCPD") ZLOG_MOD(ZLOG_MOD_OPENDHCPD, ZLOG_LEVEL_DEBUG, "ODHCPD")
#define GENERATE_ZLOG_MOD_ENUM(ENUM, lv, x) ENUM, #define GENERATE_ZLOG_MOD_ENUM(ENUM, lv, x) ENUM,
@ -54,15 +59,8 @@ typedef enum {
#define hzlog_trace(cat, buf, buf_len) \ #define hzlog_trace(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_DEBUG, buf, buf_len) hzlog(cat, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_DEBUG, buf, buf_len)
#define zlog_trace(cat, format, ...) \ #define zlog_trace(cat, format, ...) \
zlog(cat, \ zlog(cat, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_TRACE, format, \
__FILE__, \
sizeof(__FILE__) - 1, \
__func__, \
sizeof(__func__) - 1, \
__LINE__, \
ZLOG_LEVEL_TRACE, \
format, \
##__VA_ARGS__) ##__VA_ARGS__)
#define LOG_MSG(level, format, ...) LOG_MOD(level, ZLOG_MOD_MAIN, format, ##__VA_ARGS__) #define LOG_MSG(level, format, ...) LOG_MOD(level, ZLOG_MOD_MAIN, format, ##__VA_ARGS__)

View File

@ -55,7 +55,7 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
signal(SIGTERM, catch_system_interupt); signal(SIGTERM, catch_system_interupt);
signal(SIGQUIT, catch_system_interupt); signal(SIGQUIT, catch_system_interupt);
signal(SIGTSTP, catch_system_interupt); signal(SIGTSTP, catch_system_interupt);
signal(SIGHUP, catch_system_interupt); signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, catch_system_interupt); signal(SIGPIPE, catch_system_interupt);
signal(SIGKILL, catch_system_interupt); signal(SIGKILL, catch_system_interupt);

View File

@ -11,8 +11,10 @@
#include "db_interface.h" #include "db_interface.h"
#include "misc.h" #include "misc.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "lease.h"
#define DCHP_STEP_TIMEOUT (120) // 10小时以上清理无效的预分配IP
#define DCHP_STEP_TIMEOUT (36000)
#define CREATE_LEASE_TABLE() \ #define CREATE_LEASE_TABLE() \
"CREATE TABLE IF NOT EXISTS lease " \ "CREATE TABLE IF NOT EXISTS lease " \
@ -46,15 +48,16 @@
" gateway CHAR(24)," \ " gateway CHAR(24)," \
" dns1 CHAR(24)," \ " dns1 CHAR(24)," \
" dns2 CHAR(24)," \ " dns2 CHAR(24)," \
" server CHAR(24) NOT NULL," \
" createTm TIMESTAMP DEFAULT (datetime('now', 'localtime')) NOT NULL" \ " createTm TIMESTAMP DEFAULT (datetime('now', 'localtime')) NOT NULL" \
"); CREATE INDEX IF NOT EXISTS pre_assign_index ON pre_assign(ip, uid);" "); CREATE INDEX IF NOT EXISTS pre_assign_index ON pre_assign(ip, uid);"
#define INSERT_PRE_ASSIGN_ROW_FMT \ #define INSERT_PRE_ASSIGN_ROW_FMT \
"INSERT INTO pre_assign (uid, xid, hostname, mac, ip, lease, netmask, gateway, dns1, dns2) " \ "INSERT INTO pre_assign (uid, xid, hostname, mac, ip, lease, netmask, gateway, dns1, dns2, server) " \
"VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s');" "VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s');"
#define GET_PRE_ASSIGN_EXISTS_ROW_FMT \ #define GET_PRE_ASSIGN_EXISTS_ROW_FMT \
"SELECT ip FROM pre_assign WHERE mac = '%s' AND hostname = '%s' AND uid = %d ORDER BY createTm DESC LIMIT 1;" "SELECT ip, id FROM pre_assign WHERE mac = '%s' AND hostname = '%s' AND uid = %d ORDER BY createTm DESC LIMIT 1;"
#define IP_IS_PRE_ASSIGN_NOT_TIMEOUT_FMT \ #define IP_IS_PRE_ASSIGN_NOT_TIMEOUT_FMT \
"SELECT (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) as tm FROM pre_assign WHERE ip = " \ "SELECT (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) as tm FROM pre_assign WHERE ip = " \
@ -66,11 +69,42 @@
"SELECT (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) as tm, id FROM pre_assign WHERE ip = " \ "SELECT (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) as tm, id FROM pre_assign WHERE ip = " \
"'%s' AND tm >= %d AND uid = %d ORDER BY tm DESC LIMIT 1;" "'%s' AND tm >= %d AND uid = %d ORDER BY tm DESC LIMIT 1;"
#define GET_PRE_ASSIGN_ROW_FMT \
"SELECT ip, uid FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) < %d;"
#define CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT \ #define CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT \
"DELETE FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - - strftime('%%s', createTm)) > %d" "DELETE FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - - strftime('%%s', createTm)) > %d"
#define UPDATE_CREATE_TIME_BY_ID_FMT "UPDATE pre_assign SET createTm = datetime('now', 'localtime') WHERE id = %s" #define UPDATE_CREATE_TIME_BY_ID_FMT "UPDATE pre_assign SET createTm = datetime('now', 'localtime') WHERE id = %s"
int lease_lock_pre_assign_ip() {
int rc;
char buf[1024] = {0};
char **dbResult;
int nRow = 0, nColumn = 0;
snprintf(buf, 1024, GET_PRE_ASSIGN_ROW_FMT, DCHP_STEP_TIMEOUT);
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
int i;
for (i = 1; i <= nRow; i++) {
U32 uid = strtoul(dbResult[i * nColumn + 1], NULL, 10);
U32 ip = ntohl(inet_addr(dbResult[i * nColumn]));
PDHCP_USER pUser = dhcp_user_create(uid);
if (pUser) {
usr_lease_lock_ip(pUser, ip);
LOG_MOD(debug, ZM_DHCP_DB, "Lock prepare assign ip %s for user %u\n", dbResult[i * nColumn], uid);
}
// printf("-- Row %d value %s, %s, %s\n", i, dbResult[i * nColumn], dbResult[i * nColumn + 1], dbResult[i * nColumn + 2]);
}
}
sqlite3_free_table(dbResult);
return ERR_SUCCESS;
}
int lease_clearup_timeout_pre_assign() { int lease_clearup_timeout_pre_assign() {
int rc; int rc;
char buf[1024] = {0}; char buf[1024] = {0};
@ -98,7 +132,7 @@ int lease_ip_is_pre_assign(U32 uid, U32 ip) {
sqlite3_free_table(dbResult); sqlite3_free_table(dbResult);
if (rc == ERR_SUCCESS && nRow == 0) { if (rc == ERR_SUCCESS && nRow == 0) {
// 数据库没有相关记录,直接返回 // 数据库没有相关记录,直接返回
LOG_MOD(debug, ZLOG_MOD_DHCPD, "New prepare assign ipaddr %s form user %u\n", u32_to_str_ip(htonl(ip)), uid); LOG_MOD(trace, ZM_DHCP_DB, "New prepare assign ipaddr %s form user %u\n", u32_to_str_ip(htonl(ip)), uid);
return FALSE; return FALSE;
} }
@ -110,7 +144,7 @@ int lease_ip_is_pre_assign(U32 uid, U32 ip) {
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) { if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
// 如果数据库存在记录说明该IP暂时不可以用 // 如果数据库存在记录说明该IP暂时不可以用
LOG_MOD(debug, ZLOG_MOD_DHCPD, "No free ip address form user %u\n", uid); LOG_MOD(trace, ZM_DHCP_DB, "No free ip address form user %u\n", uid);
return TRUE; return TRUE;
} }
@ -125,7 +159,8 @@ int lease_ip_is_pre_assign(U32 uid, U32 ip) {
snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]); snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);
db_sqlite3_sql_exec(buf, NULL, NULL, NULL); db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
sqlite3_free_table(dbResult); sqlite3_free_table(dbResult);
LOG_MOD(debug, ZLOG_MOD_DHCPD, "New prepare assign ipaddr %s form user %u by clearup resource\n", u32_to_str_ip(htonl(ip)), uid); LOG_MOD(trace, ZM_DHCP_DB, "New prepare assign ipaddr %s form user %u by clearup resource\n",
u32_to_str_ip(htonl(ip)), uid);
return FALSE; return FALSE;
} }
sqlite3_free_table(dbResult); sqlite3_free_table(dbResult);
@ -143,10 +178,14 @@ int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *pr
snprintf(buf, 1024, GET_PRE_ASSIGN_EXISTS_ROW_FMT, mac, hostname, uid); snprintf(buf, 1024, GET_PRE_ASSIGN_EXISTS_ROW_FMT, mac, hostname, uid);
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL); rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) { if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
if (preAssign) { if (preAssign) {
*preAssign = ntohl(inet_addr(dbResult[1])); *preAssign = ntohl(inet_addr(dbResult[2]));
printf("pre alloc [%s(%u)] --> %s\n", mac, uid, dbResult[2]);
// 更新时间戳
memset(buf, 0, 1024);
snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
} }
rc = ERR_ITEM_EXISTS; rc = ERR_ITEM_EXISTS;
} else { } else {
@ -157,7 +196,7 @@ int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *pr
return rc; return rc;
} }
int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PIPPOOL_INFO pPool) { int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool) {
int rc; int rc;
char buf[1024] = {0}; char buf[1024] = {0};
char macStr[20] = {0}; char macStr[20] = {0};
@ -166,27 +205,18 @@ int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PIPPOOL_INFO pPool) {
const char *pGw = u32_to_str_ip_safe(htonl(pPool->gwAddr)); const char *pGw = u32_to_str_ip_safe(htonl(pPool->gwAddr));
const char *pDns1 = u32_to_str_ip_safe(htonl(pPool->primeDNS)); const char *pDns1 = u32_to_str_ip_safe(htonl(pPool->primeDNS));
const char *pDns2 = u32_to_str_ip_safe(htonl(pPool->salveDNS)); const char *pDns2 = u32_to_str_ip_safe(htonl(pPool->salveDNS));
const char *pServer = u32_to_str_ip_safe(pReq->serverAddr);
MAC_TO_STR(pReq->cliMac, macStr); MAC_TO_STR(pReq->cliMac, macStr);
snprintf(buf, snprintf(buf, 1024, INSERT_PRE_ASSIGN_ROW_FMT, pReq->uid, pReq->xid, pReq->hostName, macStr, pIp, pPool->leaseTime,
1024, pMask, pGw, pDns1, pDns2, pServer);
INSERT_PRE_ASSIGN_ROW_FMT,
pReq->uid,
pReq->xid,
pReq->hostName,
macStr,
pIp,
pPool->leaseTime,
pMask,
pGw,
pDns1,
pDns2);
free((void *)pIp); free((void *)pIp);
free((void *)pMask); free((void *)pMask);
free((void *)pGw); free((void *)pGw);
free((void *)pDns1); free((void *)pDns1);
free((void *)pDns2); free((void *)pDns2);
free((void *)pServer);
rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL); rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL);

View File

@ -20,6 +20,7 @@
#include "user_mgr.h" #include "user_mgr.h"
#include "rfc2131.h" #include "rfc2131.h"
#include "dhcp_network.h" #include "dhcp_network.h"
#include "lease.h"
#define MAXIMUM_SNAPLEN (262144) #define MAXIMUM_SNAPLEN (262144)
@ -149,6 +150,11 @@ static struct sock_fprog bpf;
static PACKET_MMAP_RING g_pkgRing; static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo; static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq; static uv_udp_t g_uvRawSockReq;
static DHCP_WORK_MODE g_dhcpMode;
U32 dhcp_get_default_netmask() {
return g_nicInfo.netmask;
}
void *get_pkg_free_buf() { void *get_pkg_free_buf() {
int i; int i;
@ -177,14 +183,14 @@ U32 pkg_mmap_tx(U8 *pData, U32 nBytes) {
return hdr->tp_len; return hdr->tp_len;
} }
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) { static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo, U32 ip) {
U8 *pOpt; U8 *pOpt;
U16 csum; U16 csum;
int tolSize; int tolSize;
PDHCP_PACKAGE pRsp = get_pkg_free_buf(); PDHCP_PACKAGE pRsp = get_pkg_free_buf();
if (pRsp == NULL) { if (pRsp == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE); LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
return -ERR_MALLOC_MEMORY; return -ERR_MALLOC_MEMORY;
} }
@ -292,12 +298,12 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
csum = htons(udp_checksum(pRsp->vlan_hdr.ip.saddr, pRsp->vlan_hdr.ip.daddr, (unsigned char *)&pRsp->vlan_hdr.udp)); csum = htons(udp_checksum(pRsp->vlan_hdr.ip.saddr, pRsp->vlan_hdr.ip.daddr, (unsigned char *)&pRsp->vlan_hdr.udp));
pRsp->vlan_hdr.udp.check = htons(csum); pRsp->vlan_hdr.udp.check = htons(csum);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "OPTIONS size: %ld\n", (intptr_t)(pOpt - pRsp->dhcp.options) + 1); LOG_MOD(trace, ZM_DHCP_NET, "OPTIONS size: %ld\n", (intptr_t)(pOpt - pRsp->dhcp.options) + 1);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "Total size: %d\n", tolSize); LOG_MOD(trace, ZM_DHCP_NET, "Total size: %d\n", tolSize);
// 发送数据 // 发送数据
if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) { if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send package(%u bytes) error\n", tolSize); LOG_MOD(error, ZM_DHCP_NET, "Send package(%u bytes) error\n", tolSize);
return -ERR_SOCK_SEND; return -ERR_SOCK_SEND;
} }
@ -307,7 +313,7 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
static void on_sock_recv(uv_work_t *req) { static void on_sock_recv(uv_work_t *req) {
char macStr[20] = {0}; char macStr[20] = {0};
U32 ip; U32 ip;
PIPPOOL_INFO pIpInfo; PPOOL_CTX pIpInfo;
DHCP_REQ reqDhcp; DHCP_REQ reqDhcp;
DHCP_OPT optMsg, opt; DHCP_OPT optMsg, opt;
int ret; int ret;
@ -319,23 +325,27 @@ static void on_sock_recv(uv_work_t *req) {
// Check op flag // Check op flag
if (pkg->dhcp.op != BOOTP_REQUEST) { if (pkg->dhcp.op != BOOTP_REQUEST) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Error message op code %d\n", pkg->dhcp.op); LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->dhcp.op);
return; return;
} }
// 获取消息类型 // 获取消息类型
ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg); ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Get \'message type\' option error %d\n", ret); LOG_MOD(error, ZM_DHCP_NET, "Get \'message type\' option error %d\n", ret);
return; return;
} }
memset(&reqDhcp, 0, sizeof(DHCP_REQ)); memset(&reqDhcp, 0, sizeof(DHCP_REQ));
reqDhcp.unicast = pkg->dhcp.flags != 0 ? TRUE : FALSE; reqDhcp.unicast = pkg->dhcp.flags != 0 ? TRUE : FALSE;
reqDhcp.xid = DHCP_XID(pkg->dhcp.xid); reqDhcp.xid = DHCP_XID(pkg->dhcp.xid);
reqDhcp.uid = VLAN_VNI_ID(pkg->vlan_hdr.vlan.id); reqDhcp.uid = VLAN_VNI_ID(pkg->vlan_hdr.vlan.id);
reqDhcp.serverAddr = g_nicInfo.ipAddr;
memcpy(reqDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN); memcpy(reqDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN);
// LOG_MOD(trace, ZM_DHCP_NET, "<<< User %u xid %08X addr %p with user %u\n", reqDhcp.uid, reqDhcp.xid, pWork->pUser,
// pWork->pUser->uid);
switch (*optMsg.pValue) { switch (*optMsg.pValue) {
case DHCP_MSG_DISCOVER: case DHCP_MSG_DISCOVER:
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.options, optSize, &opt); ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.options, optSize, &opt);
@ -364,27 +374,20 @@ static void on_sock_recv(uv_work_t *req) {
} }
MAC_TO_STR(reqDhcp.cliMac, macStr); MAC_TO_STR(reqDhcp.cliMac, macStr);
ret = pre_alloc_dhcp_res(&reqDhcp, &ip, &pIpInfo); ret = pre_alloc_dhcp_res(&reqDhcp, pWork->pUser, &ip, &pIpInfo);
if (ret == ERR_SUCCESS) { if (ret == ERR_SUCCESS) {
LOG_MOD(debug, LOG_MOD(debug, ZM_DHCP_NET, "User %5u DHCP prepare assign ipaddress: [%s(%s)] --> %s\n", reqDhcp.uid,
ZLOG_MOD_DHCPD, macStr, reqDhcp.hostName, u32_to_str_ip(ntohl(ip)));
"DHCP prepare assign ipaddress: [%s(%s)] --> %s\n",
macStr,
reqDhcp.hostName,
u32_to_str_ip(ntohl(ip)));
ret = dhcp_resp_offer(pkg, pIpInfo, ip); ret = dhcp_resp_offer(pkg, pIpInfo, ip);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send Offer error: %d\n", ret); LOG_MOD(error, ZM_DHCP_NET, "Send Offer error: %d\n", ret);
} }
} else { } else {
LOG_MOD(error, LOG_MOD(error, ZM_DHCP_NET, "DHCP prepare assign ipaddress error: User %u [%s(%s)] resion %s\n",
ZLOG_MOD_DHCPD, reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(-ret));
"DHCP prepare assign ipaddress error: [%s(%s)]\n",
macStr,
reqDhcp.hostName);
} }
break; break;
case DHCP_MSG_REQUEST: case DHCP_MSG_REQUEST:
@ -396,18 +399,18 @@ static void on_sock_recv(uv_work_t *req) {
case DHCP_MSG_DECLINE: case DHCP_MSG_DECLINE:
break; break;
default: default:
LOG_MOD(error, ZLOG_MOD_DHCPD, "Unkonwn DHCP message type: %d\n", *optMsg.pValue); LOG_MOD(error, ZM_DHCP_NET, "Unkonwn DHCP message type: %d\n", *optMsg.pValue);
LOG_MSG_HEX(trace, pkg, pWork->nSize); LOG_MSG_HEX(trace, pkg, pWork->nSize);
break; break;
} }
//dhcp_option_prase(optMsg, pkg->dhcp.options, pWork->nSize - sizeof(DHCP_PACKAGE)); //dhcp_option_prase(optMsg, pkg->dhcp.options, pWork->nSize - sizeof(DHCP_PACKAGE));
//LOG_MSG_HEX(trace, pkg, pWork->nSize); //LOG_MSG_HEX(trace, pkg, pWork->nSize);
// LOG_MSG(info, "vni: %d, xid: 0x%08X\n", VLAN_VNI_ID(pkg->vlan_hdr.vlan.id), DHCP_XID(pkg->dhcp.xid)); // LOG_MSG(info, "vni: %d, xid: 0x%08X\n", VLAN_VNI_ID(pkg->vlan_hdr.vlan.id), DHCP_XID(pkg->dhcp.xid));
#if 0 #if 0
LOG_MOD(info, ZLOG_MOD_DHCPD, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->vlan_hdr.vlan.id)); LOG_MOD(info, ZM_DHCP_NET, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->vlan_hdr.vlan.id));
LOG_MSG(info, "xid: 0x%08X\n", ntohl(pkg->dhcp.xid)); LOG_MSG(info, "xid: 0x%08X\n", ntohl(pkg->dhcp.xid));
LOG_MSG(info, LOG_MSG(info,
"dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n", "dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
@ -434,7 +437,7 @@ static void after_msg_recv(uv_work_t *req, int status) {
pMsg->nf -= 1; pMsg->nf -= 1;
if (pMsg->nf == 0) { if (pMsg->nf == 0) {
LOG_MOD(trace, ZLOG_MOD_DHCPD, "---Free resources: %p\n", pMsg); LOG_MOD(trace, ZM_DHCP_NET, "---Free resources: %p\n", pMsg);
free(pMsg->pPkgInfo); free(pMsg->pPkgInfo);
free(pMsg); free(pMsg);
} }
@ -454,17 +457,15 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
PPKG_MSG pMsg = (PPKG_MSG)malloc(sizeof(PKG_MSG)); PPKG_MSG pMsg = (PPKG_MSG)malloc(sizeof(PKG_MSG));
if (pMsg == NULL) { if (pMsg == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %lu\n", sizeof(PKG_MSG)); LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %lu\n", sizeof(PKG_MSG));
return; return;
} }
LOG_MOD(trace, ZLOG_MOD_DHCPD, "++++Malloc resources: %p\n", pMsg);
memset(pMsg, 0, sizeof(PKG_MSG)); memset(pMsg, 0, sizeof(PKG_MSG));
pMsg->pPkgInfo = (PPKG_PROCESS_INFO)malloc(memSize); pMsg->pPkgInfo = (PPKG_PROCESS_INFO)malloc(memSize);
if (pMsg->pPkgInfo == NULL) { if (pMsg->pPkgInfo == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %u\n", memSize); LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", memSize);
free(pMsg); free(pMsg);
return; return;
} }
@ -474,14 +475,22 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
pMsg->nf = pbd->h1.num_pkts; pMsg->nf = pbd->h1.num_pkts;
ppd = (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->h1.offset_to_first_pkt); ppd = (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->h1.offset_to_first_pkt);
for (i = 0; i < pbd->h1.num_pkts; i++) { for (i = 0; i < pbd->h1.num_pkts; i++) {
PDHCP_PACKAGE pkg;
U32 uid;
pMsg->pPkgInfo[i].pPkgBase = ((uint8_t *)ppd + ppd->tp_mac); pMsg->pPkgInfo[i].pPkgBase = ((uint8_t *)ppd + ppd->tp_mac);
pMsg->pPkgInfo[i].nSize = ppd->tp_snaplen; pMsg->pPkgInfo[i].nSize = ppd->tp_snaplen;
pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i]; pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i];
pMsg->pPkgInfo[i].pData = pMsg; pMsg->pPkgInfo[i].pData = pMsg;
if (g_dhcpMode == MODE_DHCP_SERVER) {
pkg = (PDHCP_PACKAGE)pMsg->pPkgInfo[i].pPkgBase;
uid = VLAN_VNI_ID(pkg->vlan_hdr.vlan.id);
pMsg->pPkgInfo[i].pUser = dhcp_user_create(uid);
// LOG_MOD(trace, ZM_DHCP_NET, ">>> User %u xid %08X addr %p\n", uid, DHCP_XID(pkg->dhcp.xid),
// pMsg->pPkgInfo[i].pUser);
}
if (pCbData) { if (pCbData) {
uv_queue_work(get_task_manager(), uv_queue_work(get_task_manager(), &(pMsg->pPkgInfo[i].uvWork),
&(pMsg->pPkgInfo[i].uvWork),
pCbData->work_cb ? pCbData->work_cb : on_sock_recv, pCbData->work_cb ? pCbData->work_cb : on_sock_recv,
pCbData->after_work_cb ? pCbData->after_work_cb : after_msg_recv); pCbData->after_work_cb ? pCbData->after_work_cb : after_msg_recv);
} else { } else {
@ -507,19 +516,19 @@ int create_udp_raw_socket(const char *pNicName) {
// 1. create socket // 1. create socket
int sock_fd = socket(PF_PACKET, SOCK_RAW, 0); int sock_fd = socket(PF_PACKET, SOCK_RAW, 0);
if (sock_fd < 0) { if (sock_fd < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Socket created failure: %s --> %s\n", pNicName, strerror(errno)); LOG_MOD(error, ZM_DHCP_NET, "Socket created failure: %s --> %s\n", pNicName, strerror(errno));
return -ERR_SOCK_CREATE; return -ERR_SOCK_CREATE;
} }
// 2. attach filter (no need to call bind) // 2. attach filter (no need to call bind)
if ((err = setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))) < 0) { if ((err = setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Attaching filter failed: %d\n", err); LOG_MOD(error, ZM_DHCP_NET, "Attaching filter failed: %d\n", err);
return -ERR_SOCK_SETOPT; return -ERR_SOCK_SETOPT;
} }
// 3. set PACKET_MMAP version // 3. set PACKET_MMAP version
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v))) < 0) { if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_VERSION option failed: %d\n", err); LOG_MOD(error, ZM_DHCP_NET, "Set PACKET_VERSION option failed: %d\n", err);
return -ERR_SOCK_SETOPT; return -ERR_SOCK_SETOPT;
} }
@ -533,7 +542,7 @@ int create_udp_raw_socket(const char *pNicName) {
g_pkgRing.recv.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH; g_pkgRing.recv.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &g_pkgRing.recv, sizeof(g_pkgRing.recv))) < 0) { if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &g_pkgRing.recv, sizeof(g_pkgRing.recv))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_RX_RING option failed: %d\n", err); LOG_MOD(error, ZM_DHCP_NET, "Set PACKET_RX_RING option failed: %d\n", err);
return -ERR_SOCK_SETOPT; return -ERR_SOCK_SETOPT;
} }
@ -545,7 +554,7 @@ int create_udp_raw_socket(const char *pNicName) {
g_pkgRing.send.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ; g_pkgRing.send.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ;
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_TX_RING, &g_pkgRing.send, sizeof(g_pkgRing.recv))) < 0) { if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_TX_RING, &g_pkgRing.send, sizeof(g_pkgRing.recv))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_TX_RING option failed: %d\n", err); LOG_MOD(error, ZM_DHCP_NET, "Set PACKET_TX_RING option failed: %d\n", err);
return -ERR_SOCK_SETOPT; return -ERR_SOCK_SETOPT;
} }
@ -557,21 +566,18 @@ int create_udp_raw_socket(const char *pNicName) {
g_pkgRing.map_send = g_pkgRing.map_recv + g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr; g_pkgRing.map_send = g_pkgRing.map_recv + g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr;
if (g_pkgRing.map_recv == MAP_FAILED) { if (g_pkgRing.map_recv == MAP_FAILED) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "MMAP socket ring failed\n"); LOG_MOD(error, ZM_DHCP_NET, "MMAP socket ring failed\n");
perror("title"); perror("title");
return -ERR_MMAP_MEMORY; return -ERR_MMAP_MEMORY;
} }
LOG_MOD(trace, ZLOG_MOD_DHCPD, "size = %u\n", size); LOG_MOD(trace, ZM_DHCP_NET, "size = %u\n", size);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "MMAP address recv = %p, send = %p\n", g_pkgRing.map_recv, g_pkgRing.map_send); LOG_MOD(trace, ZM_DHCP_NET, "MMAP address recv = %p, send = %p\n", g_pkgRing.map_recv, g_pkgRing.map_send);
// 7. malloc read buffer // 7. malloc read buffer
g_pkgRing.rx = malloc(g_pkgRing.recv.tp_block_nr * sizeof(struct iovec)); g_pkgRing.rx = malloc(g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
if (g_pkgRing.rx == NULL) { if (g_pkgRing.rx == NULL) {
LOG_MOD(error, LOG_MOD(error, ZM_DHCP_NET, "Malloc memory failed: %lu\n", g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
ZLOG_MOD_DHCPD,
"Malloc memory failed: %lu\n",
g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
return -ERR_MMAP_MEMORY; return -ERR_MMAP_MEMORY;
} }
@ -584,10 +590,7 @@ int create_udp_raw_socket(const char *pNicName) {
// 8. malloc send buffer // 8. malloc send buffer
g_pkgRing.tx = malloc(g_pkgRing.send.tp_block_nr * sizeof(struct iovec)); g_pkgRing.tx = malloc(g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
if (g_pkgRing.tx == NULL) { if (g_pkgRing.tx == NULL) {
LOG_MOD(error, LOG_MOD(error, ZM_DHCP_NET, "Malloc memory failed: %lu\n", g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
ZLOG_MOD_DHCPD,
"Malloc memory failed: %lu\n",
g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
munmap(g_pkgRing.map_recv, size * 2); munmap(g_pkgRing.map_recv, size * 2);
return -ERR_MMAP_MEMORY; return -ERR_MMAP_MEMORY;
@ -609,7 +612,7 @@ int create_udp_raw_socket(const char *pNicName) {
addr.sll_halen = 0; addr.sll_halen = 0;
if ((err = bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll))) < 0) { if ((err = bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Bind raw socket failed: %d\n", err); LOG_MOD(error, ZM_DHCP_NET, "Bind raw socket failed: %d\n", err);
return -ERR_SOCK_SETOPT; return -ERR_SOCK_SETOPT;
} }
@ -628,7 +631,7 @@ void socket_send_task(uv_timer_t *UNUSED(pArg)) {
ssize_t ret = sendto(g_pkgRing.sock, NULL, 0, MSG_DONTWAIT, NULL, sizeof(struct sockaddr_ll)); ssize_t ret = sendto(g_pkgRing.sock, NULL, 0, MSG_DONTWAIT, NULL, sizeof(struct sockaddr_ll));
if (ret == -1) { if (ret == -1) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send packet error\n"); LOG_MOD(error, ZM_DHCP_NET, "Send packet error\n");
} }
break; break;
} }
@ -682,10 +685,12 @@ void init_raw_socket_poll(void *pRecv, void *pClean) {
uv_timer_start(&uvTm, socket_send_task, 3000, 100); uv_timer_start(&uvTm, socket_send_task, 3000, 100);
} }
int dhcpd_init() { int dhcpd_init(DHCP_WORK_MODE workMode) {
int ret; int ret;
size_t size = MAX_PATH; size_t size = MAX_PATH;
g_dhcpMode = workMode;
memset(&g_nicInfo, 0, sizeof(NIC_INFO)); memset(&g_nicInfo, 0, sizeof(NIC_INFO));
g_nicInfo.pIfName = (char *)config_get_dhcp_nic_name(); g_nicInfo.pIfName = (char *)config_get_dhcp_nic_name();
uv_os_gethostname(g_nicInfo.hostname, &size); uv_os_gethostname(g_nicInfo.hostname, &size);
@ -696,10 +701,11 @@ int dhcpd_init() {
ret = create_udp_raw_socket(g_nicInfo.pIfName); ret = create_udp_raw_socket(g_nicInfo.pIfName);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret); LOG_MOD(error, ZM_DHCP_NET, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret);
return ret; return ret;
} }
// 加载所有DHCP配置
ip_pool_init_from_config();
dhcp_user_mgr_init(); dhcp_user_mgr_init();
dhcp_option_cfg_init(); dhcp_option_cfg_init();
dhcp_lease_init(); dhcp_lease_init();

View File

@ -7,11 +7,12 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PIPPOOL_INFO pPool); int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool);
int lease_init_database(); int lease_init_database();
int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign); int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign);
int lease_ip_is_pre_assign(U32 uid, U32 ip); int lease_ip_is_pre_assign(U32 uid, U32 ip);
int lease_clearup_timeout_pre_assign(); int lease_clearup_timeout_pre_assign();
int lease_lock_pre_assign_ip();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -8,6 +8,7 @@
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include "network/vlan.h" #include "network/vlan.h"
#include "service/dhcpd.h" #include "service/dhcpd.h"
#include "user_mgr.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -60,6 +61,7 @@ typedef struct {
uv_work_t uvWork; uv_work_t uvWork;
unsigned short nSize; unsigned short nSize;
unsigned char *pPkgBase; unsigned char *pPkgBase;
PDHCP_USER pUser;
void *pData; void *pData;
} PKG_PROCESS_INFO, *PPKG_PROCESS_INFO; } PKG_PROCESS_INFO, *PPKG_PROCESS_INFO;
@ -76,6 +78,7 @@ void init_raw_socket_poll(void *pRecv, void *pClean);
int create_udp_raw_socket(const char *pNicName); int create_udp_raw_socket(const char *pNicName);
void init_filter(const char *pNetFilter); void init_filter(const char *pNetFilter);
void *get_pkg_free_buf(); void *get_pkg_free_buf();
U32 dhcp_get_default_netmask();
U32 pkg_mmap_tx(U8 *pData, U32 nBytes); U32 pkg_mmap_tx(U8 *pData, U32 nBytes);
int dhcp_uninit(); int dhcp_uninit();
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -12,13 +12,6 @@
extern "C" { extern "C" {
#endif #endif
/**
* key format FFFFFFF-FFFFFFF
* minAddr-maxAddr
* Hex format string
*/
#define MAX_POOL_HASH_KEY (18)
typedef struct POOL_CTX { typedef struct POOL_CTX {
U32 minAddr; U32 minAddr;
U32 maxAddr; U32 maxAddr;
@ -32,38 +25,14 @@ typedef struct POOL_CTX {
} POOL_CTX, *PPOOL_CTX; } POOL_CTX, *PPOOL_CTX;
typedef struct { typedef struct {
U32 poolKey; U32 id; ///< ID
U32 minAddr;
U32 maxAddr;
U32 netMask;
U32 gwAddr;
U32 primeDNS;
U32 salveDNS;
U32 leaseTime;
bitset_t *assignPool;
UT_hash_handle hh;
} IPPOOL_INFO, *PIPPOOL_INFO;
typedef struct POOL_INFO {
U32 minAddr;
U32 maxAddr;
U32 netMask;
U32 gwAddr;
U32 primeDNS;
U32 salveDNS;
U32 leaseTime;
struct POOL_INFO *next;
} POOL_INFO, *PPOOL_INFO;
typedef struct {
U32 uid; ///< 用户 ID
U32 gid; ///< 用户组 ID
PPOOL_CTX pCtx; ///< 用户配置信息 PPOOL_CTX pCtx; ///< 用户配置信息
UT_hash_handle hh; UT_hash_handle hh;
} POOL_CONFIG, *PPOOL_CONFIG; } POOL_CONFIG, *PPOOL_CONFIG;
void init_default_pool(); void ip_pool_init_from_config();
PPOOL_CTX get_pool_cfg(U32 uid, U32 gid);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -9,6 +9,8 @@
#include <common.h> #include <common.h>
#include "ip_pool.h" #include "ip_pool.h"
#include "rfc2131.h" #include "rfc2131.h"
#include "user_mgr.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -27,8 +29,8 @@ typedef struct {
} LEASE_CACHE, *PLEASE_CACHE; } LEASE_CACHE, *PLEASE_CACHE;
int dhcp_lease_init(); int dhcp_lease_init();
//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);
int pre_alloc_dhcp_res(PDHCP_REQ pReq, U32 *pOutIp, PIPPOOL_INFO *pOutPool); int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -27,6 +27,7 @@ typedef struct {
U32 leaseTime; U32 leaseTime;
char clientId[256]; char clientId[256];
char vendorClassId[256]; char vendorClassId[256];
U32 serverAddr;
char hostName[256]; char hostName[256];
} DHCP_REQ, *PDHCP_REQ; } DHCP_REQ, *PDHCP_REQ;

View File

@ -7,28 +7,26 @@
#include <uthash/uthash.h> #include <uthash/uthash.h>
#include <common.h> #include <common.h>
#include "ip_pool.h" #include "ip_pool.h"
#include "lease.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct {
unsigned int uid;
PIPPOOL_INFO pPoolMgr; typedef struct {
PMAC_FILTER pAllowTbl; U32 ip;
PMAC_FILTER pDenyTbl;
UT_hash_handle hh; UT_hash_handle hh;
} DHCP_USER_CFG, *PDHCP_USER_CFG; } LOCK_IP, *PLOCK_IP;
typedef struct { typedef struct {
unsigned int uid; U32 uid; ///< 用户ID
PDHCP_USER_CFG pCfg; PPOOL_CTX pUserPool; ///< 用户地址池
} DHCP_USER_INFO, *PDHCP_USER_INFO; PLOCK_IP plockIp;
UT_hash_handle hh;
} DHCP_USER, *PDHCP_USER;
int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool); //int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool);
int dhcp_user_mgr_init(); int dhcp_user_mgr_init();
PIPPOOL_INFO user_get_pool(U32 uId); PDHCP_USER dhcp_user_create(U32 uId);
#ifdef HTTPSERVER_ON #ifdef HTTPSERVER_ON
int user_init_httpd(); int user_init_httpd();
#endif #endif

View File

@ -2,6 +2,7 @@
// Created by xajhuang on 2023/3/23. // Created by xajhuang on 2023/3/23.
// //
#include <arpa/inet.h> #include <arpa/inet.h>
#include "misc.h"
#include "ip_pool.h" #include "ip_pool.h"
#include "zvector/zvector.h" #include "zvector/zvector.h"
#include "config.h" #include "config.h"
@ -10,43 +11,200 @@
#include "user_mgr.h" #include "user_mgr.h"
#include "ipaddr.h" #include "ipaddr.h"
#include "uthash/utlist.h" #include "uthash/utlist.h"
#include "dhcp_network.h"
static PIPPOOL_INFO g_defPool = NULL;
static PPOOL_CONFIG g_pUsrCommonCfg = NULL; static PPOOL_CONFIG g_pUsrCommonCfg = NULL;
static PPOOL_CONFIG g_pUsrGrpCfg = NULL; static PPOOL_CONFIG g_pUsrGrpCfg = NULL;
static PPOOL_CONFIG g_pUsrCfg = NULL; static PPOOL_CONFIG g_pUsrCfg = NULL;
U32 get_ip_pool_addr(U32 defAddr) { PPOOL_CTX get_pool_cfg(U32 uid, U32 gid) {
return 0; PPOOL_CONFIG pCfg;
if (gid != 0) {
HASH_FIND_INT(g_pUsrGrpCfg, &gid, pCfg);
if (pCfg) {
return pCfg->pCtx;
}
} else if (uid != 0) {
HASH_FIND_INT(g_pUsrCfg, &uid, pCfg);
if (pCfg) {
return pCfg->pCtx;
}
}
if (g_pUsrCommonCfg) {
return g_pUsrCommonCfg->pCtx;
} else {
return NULL;
}
} }
static void add_usr_pool_cfg(U32 id, PPOOL_CONFIG pPoolList, PIPPOOL_INFO pPool) { static void add_usr_pool_cfg(U32 id, PPOOL_CONFIG *pPoolList, PPOOL_CTX pCtx) {
PPOOL_CTX p, pTmp; PPOOL_CTX p, pTmp;
PPOOL_CONFIG pCfg; PPOOL_CONFIG pCfg;
// 判断当前用户组是否存在 // 判断当前用户组是否存在
HASH_FIND_INT(pPoolList, &id, pCfg); HASH_FIND_INT(*pPoolList, &id, pCfg);
// 不存在则新建一个配置并保存 // 不存在则新建一个配置并保存
if (pCfg == NULL) { if (pCfg == NULL) {
pCfg = (PPOOL_CONFIG)malloc(sizeof(POOL_CONFIG));
if (pCfg == NULL) {
LOG_MOD(error, ZM_DHCP_POOL, "Malloc memory %lu error\n", sizeof(POOL_CONFIG));
return;
}
memset(pCfg, 0, sizeof(POOL_CONFIG));
pCfg->id = id;
LL_APPEND(pCfg->pCtx, pCtx);
HASH_ADD_INT(*pPoolList, id, pCfg);
LOG_MOD(trace, ZM_DHCP_POOL, "%p Add user %u\n", *pPoolList, id);
return;
} }
// 如果存在则遍历当前所有IP地址池配置检查配置是否合法 // 如果存在则遍历当前所有IP地址池配置检查配置是否合法
LL_FOREACH_SAFE(pPoolList->pCtx, p, pTmp) { LL_FOREACH_SAFE((*pPoolList)->pCtx, p, pTmp) {
if (p->minAddr > pPool->minAddr && p->maxAddr < pPool->maxAddr) { if (p->minAddr >= pCtx->minAddr && p->maxAddr <= pCtx->maxAddr) {
LOG_MOD(error, LOG_MOD(error, ZM_DHCP_POOL, "Pool [%08X, %08X] conflict with [%08X, %08X]", pCtx->minAddr, pCtx->maxAddr,
ZLOG_MOD_DHCPD, p->minAddr, p->maxAddr);
"Pool [%08X, %08X] conflict with [%08X, %08X]",
pPool->minAddr,
pPool->maxAddr,
p->minAddr,
p->maxAddr);
return; return;
} }
} }
// 如果没有冲突,则将新的配置添加到链表中
LL_APPEND(pCfg->pCtx, pCtx);
}
void ip_pool_init_from_config() {
c_vector pool = (c_vector)config_get_dhcp_server_range_set();
for (int i = 0; (pool && i < vect_size(pool)); i++) {
POBJ_DHCP_RNG pRange = (POBJ_DHCP_RNG)vect_get_at(pool, i);
if (pRange && strlen(pRange->rangAddr) > 0) {
struct in_addr addr;
char *pConnChar;
char tmpStr[64];
PPOOL_CTX p = (PPOOL_CTX)malloc(sizeof(POOL_CTX));
if (!p) {
LOG_MOD(error, ZM_DHCP_POOL, "Error: size %lu of config %s\n", sizeof(POOL_CTX), pRange->rangAddr);
continue;
}
memset(p, 0, sizeof(POOL_CTX));
// 如果未配置租约,取默认值,否则使用地址池配置值
p->leaseTime = (pRange->lease == 0) ? config_get_dhcp_server_lease_time() : pRange->lease;
// 处理地址池字符串
memset(tmpStr, 0, 64);
strcpy(tmpStr, pRange->rangAddr);
pConnChar = strchr(tmpStr, '-');
// '-' 连接IP地址类型
if (pConnChar) {
char *pSecIp = pConnChar + 1;
pConnChar[0] = 0;
// 地址范围
if (inet_aton(tmpStr, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->rangAddr);
free(p);
continue;
} else {
p->minAddr = ntohl(addr.s_addr);
}
if (inet_aton(pSecIp, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->rangAddr);
free(p);
continue;
} else {
p->maxAddr = ntohl(addr.s_addr);
}
} else {
LOG_MOD(error, ZM_DHCP_POOL, "Bad DHCP range format: %s\n", tmpStr);
free(p);
continue;
}
// 子网掩码
if (strlen(pRange->subnet) > 0) {
if (inet_aton(pRange->subnet, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip %s ERROR, used default value %s\n", pRange->subnet,
u32_to_str_ip(dhcp_get_default_netmask()));
p->netMask = ntohl(dhcp_get_default_netmask());
} else {
p->netMask = ntohl(addr.s_addr);
}
} else {
// 当前网络默认IP地址池
p->netMask = ntohl(dhcp_get_default_netmask());
}
// 网关
if (strlen(pRange->gateway) > 0) {
if (inet_aton(pRange->gateway, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->gateway);
} else {
p->gwAddr = ntohl(addr.s_addr);
}
}
// DNS 配置
if (strlen(pRange->dnsSvr) > 0) {
memset(tmpStr, 0, 64);
strcpy(tmpStr, pRange->dnsSvr);
pConnChar = strchr(tmpStr, ',');
if (pConnChar) {
char *pSecIp = pConnChar + 1;
pConnChar[0] = 0;
if (inet_aton(tmpStr, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else {
p->primeDNS = ntohl(addr.s_addr);
}
if (inet_aton(pSecIp, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr);
} else {
p->salveDNS = ntohl(addr.s_addr);
}
} else {
if (inet_aton(pRange->dnsSvr, &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else {
p->primeDNS = ntohl(addr.s_addr);
}
}
}
// 当前配置为用户组配置
if (pRange->gid != 0) {
// 添加到Group配置表
add_usr_pool_cfg(pRange->gid, &g_pUsrGrpCfg, p);
LOG_MOD(debug, ZM_DHCP_POOL, "Load user group %d configure: %s\n", pRange->gid, pRange->rangAddr);
} else if (pRange->vni == 0) {
// VNI 为 0 时表示用户公共配置
add_usr_pool_cfg(pRange->vni, &g_pUsrCommonCfg, p);
LOG_MOD(debug, ZM_DHCP_POOL, "Load common user configure: %s\n", pRange->rangAddr);
} else {
// 添加到用户独立配置
add_usr_pool_cfg(pRange->vni, &g_pUsrCfg, p);
LOG_MOD(debug, ZM_DHCP_POOL, "Load user %d configure: %s\n", pRange->vni, pRange->rangAddr);
}
} else {
LOG_MOD(error, ZM_DHCP_POOL, "Error configure %p value \"%s\"\n", pRange, pRange ? pRange->rangAddr : "");
}
}
} }
#if 0
void init_default_pool() { void init_default_pool() {
c_vector pool = (c_vector)config_get_dhcp_server_range_set(); c_vector pool = (c_vector)config_get_dhcp_server_range_set();
@ -89,7 +247,7 @@ void init_default_pool() {
pConnChar[0] = 0; pConnChar[0] = 0;
if (inet_aton(tmpStr, &addr) == 0) { if (inet_aton(tmpStr, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->rangAddr); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->rangAddr);
free(p); free(p);
continue; continue;
} else { } else {
@ -97,28 +255,28 @@ void init_default_pool() {
} }
if (inet_aton(pSecIp, &addr) == 0) { if (inet_aton(pSecIp, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->rangAddr); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->rangAddr);
free(p); free(p);
continue; continue;
} else { } else {
p->maxAddr = ntohl(addr.s_addr); p->maxAddr = ntohl(addr.s_addr);
} }
} else { } else {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Bad DHCP range format: %s\n", tmpStr); LOG_MOD(error, ZM_DHCP_POOL, "Bad DHCP range format: %s\n", tmpStr);
free(p); free(p);
continue; continue;
} }
if (strlen(pRange->subnet) > 0) { if (strlen(pRange->subnet) > 0) {
if (inet_aton(pRange->subnet, &addr) == 0) { if (inet_aton(pRange->subnet, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->subnet); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->subnet);
} else { } else {
p->netMask = ntohl(addr.s_addr); p->netMask = ntohl(addr.s_addr);
} }
} else { } else {
// 当前网络默认IP地址池 // 当前网络默认IP地址池
if (inet_aton("255.255.255.0", &addr) == 0) { if (inet_aton("255.255.255.0", &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->subnet); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->subnet);
} else { } else {
p->netMask = ntohl(addr.s_addr); p->netMask = ntohl(addr.s_addr);
} }
@ -129,18 +287,15 @@ void init_default_pool() {
p->assignPool = bitset_create_with_capacity(ipv4_network_total_addr(p->netMask)); p->assignPool = bitset_create_with_capacity(ipv4_network_total_addr(p->netMask));
if (!p->assignPool) { if (!p->assignPool) {
LOG_MOD(error, LOG_MOD(error, ZM_DHCP_POOL, "Create address pool bitset ERROR: 0x%08X total address %u\n",
ZLOG_MOD_DHCPD, htonl(p->netMask), ipv4_network_total_addr(p->netMask));
"Create address pool bitset ERROR: 0x%08X total address %u\n",
htonl(p->netMask),
ipv4_network_total_addr(p->netMask));
free(p); free(p);
continue; continue;
} }
if (strlen(pRange->gateway) > 0) { if (strlen(pRange->gateway) > 0) {
if (inet_aton(pRange->gateway, &addr) == 0) { if (inet_aton(pRange->gateway, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->gateway); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->gateway);
} else { } else {
p->gwAddr = ntohl(addr.s_addr); p->gwAddr = ntohl(addr.s_addr);
} }
@ -157,19 +312,19 @@ void init_default_pool() {
pConnChar[0] = 0; pConnChar[0] = 0;
if (inet_aton(tmpStr, &addr) == 0) { if (inet_aton(tmpStr, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else { } else {
p->primeDNS = ntohl(addr.s_addr); p->primeDNS = ntohl(addr.s_addr);
} }
if (inet_aton(pSecIp, &addr) == 0) { if (inet_aton(pSecIp, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr);
} else { } else {
p->salveDNS = ntohl(addr.s_addr); p->salveDNS = ntohl(addr.s_addr);
} }
} else { } else {
if (inet_aton(pRange->dnsSvr, &addr) == 0) { if (inet_aton(pRange->dnsSvr, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr); LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else { } else {
p->primeDNS = ntohl(addr.s_addr); p->primeDNS = ntohl(addr.s_addr);
} }
@ -179,4 +334,5 @@ void init_default_pool() {
user_add_ip_pool(pRange->vni, p); user_add_ip_pool(pRange->vni, p);
} }
} }
} }
#endif

View File

@ -6,22 +6,9 @@
#include "lease.h" #include "lease.h"
#include "user_errno.h" #include "user_errno.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "database.h"
#include "user_mgr.h"
#include "rfc2131.h"
#include "dhcp_network.h" #include "dhcp_network.h"
#include "db_interface.h" #include "db_interface.h"
#include "uthash/utlist.h"
#define PREALLOC_IP_TIMEOUT (60)
typedef struct {
U32 ipAddr;
U8 macAddr[ETH_ALEN];
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_allowTbl = NULL;
//static PMAC_FILTER g_blackListTbl = NULL; //static PMAC_FILTER g_blackListTbl = NULL;
@ -39,25 +26,29 @@ U32 lease_is_pre_assign(PDHCP_REQ pReq) {
return 0; 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);
return ERR_SUCCESS;
}
return -ERR_MALLOC_MEMORY;
}
//int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) { //int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
int pre_alloc_dhcp_res(PDHCP_REQ pReq, U32 *pOutIp, PIPPOOL_INFO *pOutPool) { int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX *pOutPool) {
PIPPOOL_INFO pPool, pTemp; PPOOL_CTX pPool, pTemp;
PPRE_ALLOC_IP pNewIp, pTmp, pCache = NULL;
PIPPOOL_INFO pUserPool;
if (pReq == NULL || pOutIp == NULL || pOutPool == NULL) { if (pReq == NULL || pOutIp == NULL || pOutPool == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Input params error: %p, %p\n", pOutIp, pOutPool); LOG_MOD(error, ZM_DHCP_LEASE, "Input params error: %p, %p\n", pOutIp, pOutPool);
return -ERR_INPUT_PARAMS; return -ERR_INPUT_PARAMS;
} }
pUserPool = user_get_pool(pReq->uid); LL_FOREACH_SAFE(pUser->pUserPool, pPool, pTemp) {
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; U32 addr;
// 查看是否预分配过该设备 // 查看是否预分配过该设备
@ -67,44 +58,49 @@ int pre_alloc_dhcp_res(PDHCP_REQ pReq, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
return ERR_SUCCESS; return ERR_SUCCESS;
} }
while ((addr = bitset_minimum(pPool->assignPool)) > 0) { addr = pPool->minAddr;
U32 ipAddr = (pPool->minAddr & pPool->netMask) + addr; do {
PLOCK_IP pLock;
// 查找租约配置文件中是否记录了曾经分配的地址, 如果已经分配则获取下一个 HASH_FIND_INT(pUser->plockIp, &addr, pLock);
// TODO: add process
// if (FALSE) {
// bitset_set(pPool->assignPool, addr);
// continue;
// }
// 查找IP地址是否已经被预分配, 未分配直接分配IP地址 // 该 IP 可用
if (lease_ip_is_pre_assign(pReq->uid, ipAddr) == FALSE) { if (pLock == NULL) {
lease_db_add_pre_assign(pReq, ipAddr, pPool); #if 1
if (lease_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
usr_lease_lock_ip(pUser, addr);
*pOutIp = addr;
*pOutPool = pPool;
*pOutIp = ipAddr; lease_db_add_pre_assign(pReq, addr, pPool);
return ERR_SUCCESS;
}
#else
usr_lease_lock_ip(pUser, addr);
*pOutIp = addr;
*pOutPool = pPool; *pOutPool = pPool;
bitset_cls_bit(pPool->assignPool, addr); lease_db_add_pre_assign(pReq, addr, pPool);
// LOG_MOD(debug, ZM_DHCP_LEASE, "User %u(%u) prepar assign ipaddr %08X of %p\n", pReq->uid, pUser->uid,
LOG_MOD(trace, ZLOG_MOD_DHCPD, "Select ipaddr %08X at %d of %p\n", ipAddr, addr, pPool->assignPool); // addr, pPool);
return ERR_SUCCESS; return ERR_SUCCESS;
#endif
} }
}
addr++;
} while (addr <= pPool->maxAddr);
} }
// 清理所有超时的预分配IP // 清理所有超时的预分配IP
lease_clearup_timeout_pre_assign(); lease_clearup_timeout_pre_assign();
// 没有可预分配的IP报错 // 没有可预分配的IP报错
LOG_MOD(error, //LOG_MOD(error, ZM_DHCP_LEASE, "No free ipaddress in poll: uid = %u, pool = %p\n", pReq->uid, pUser->pUserPool);
ZLOG_MOD_DHCPD,
"No free ipaddress in poll: uid = %u, pool = 0x%08X\n",
pReq->uid,
pUserPool->poolKey);
return -ERR_DHCP_NO_ADDR; return -ERR_DHCP_NO_ADDR;
} }
int dhcp_lease_init() { int dhcp_lease_init() {
int rc = 0; int rc;
rc = lease_init_database(); rc = lease_init_database();
@ -112,5 +108,10 @@ int dhcp_lease_init() {
return rc; return rc;
} }
// 清理所有超时的预分配IP
lease_clearup_timeout_pre_assign();
// lock 预分配 IP
lease_lock_pre_assign_ip();
return ERR_SUCCESS; return ERR_SUCCESS;
} }

View File

@ -12,40 +12,8 @@
#include "misc.h" #include "misc.h"
#endif #endif
typedef struct {
U32 uid; ///< 用户ID
PPOOL_INFO pUserPool; ///< 用户地址池
UT_hash_handle hh;
} DHCP_USER, *PDHCP_USER;
static PDHCP_USER_CFG g_dhcpUsrCfg = NULL;
static PPOOL_INFO g_userCommonPool = NULL;
//static PPOOL_INFO g_userGrpPool = NULL;
// 当前用户列表,通过数据包自动发现 // 当前用户列表,通过数据包自动发现
static PDHCP_USER g_dhcpUserList = NULL; static PDHCP_USER g_dhcpUserList = NULL;
#define INIT_DHCP_USER(id) \
/* region INIT_DHCP_USER Macro define */ \
do { \
HASH_FIND_INT(g_dhcpUsrCfg, &(id), pUserCfg); \
if (pUserCfg == NULL) { \
pUserCfg = (PDHCP_USER_CFG)malloc(sizeof(DHCP_USER_CFG)); \
\
if (pUserCfg == NULL) { \
LOG_MOD(error, ZLOG_MOD_USER, "Malloc memory error: %lu\n", sizeof(DHCP_USER_CFG)); \
return -ERR_MALLOC_MEMORY; \
} \
memset(pUserCfg, 0, sizeof(DHCP_USER_CFG)); \
pUserCfg->uid = (id); \
HASH_ADD_INT(g_dhcpUsrCfg, uid, pUserCfg); \
} \
} while (0)
// endregion
#ifdef HTTPSERVER_ON #ifdef HTTPSERVER_ON
// region 用户管理接口 // region 用户管理接口
@ -54,16 +22,16 @@ static int get_user_pool_cfg(const char **pRsp, const char *pRequest) {
const char *pStrContent; const char *pStrContent;
cJSON *pRspRoot, *pRoot, *pUidSet, *pPoolCfgs; cJSON *pRspRoot, *pRoot, *pUidSet, *pPoolCfgs;
int i, errCode = 0; int i, errCode = 0;
#if 0
if (pRequest == NULL || strlen(pRequest) == 0) { if (pRequest == NULL || strlen(pRequest) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Misson POST json params\n"); LOG_MOD(error, ZM_DHCP, "Misson POST json params\n");
return ERR_INPUT_PARAMS; return ERR_INPUT_PARAMS;
} }
pStrContent = proto_decode_context(pRequest, NULL, NULL, &errCode); pStrContent = proto_decode_context(pRequest, NULL, NULL, &errCode);
if (pStrContent == NULL) { if (pStrContent == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Request Json error %s\n", pRequest); LOG_MOD(error, ZM_DHCP, "Request Json error %s\n", pRequest);
return ERR_PROTO_DECODE; return ERR_PROTO_DECODE;
} }
@ -166,7 +134,7 @@ static int get_user_pool_cfg(const char **pRsp, const char *pRequest) {
*pRsp = proto_create_new(pRspRoot, 200); *pRsp = proto_create_new(pRspRoot, 200);
cJSON_Delete(pRoot); cJSON_Delete(pRoot);
#endif
return ERR_SUCCESS; return ERR_SUCCESS;
} }
@ -200,6 +168,16 @@ int user_init_httpd() {
// endregion // endregion
#endif #endif
int dhcp_user_assign_pool(PDHCP_USER pUser, PPOOL_CTX pPool) {
if (pUser == NULL || pPool == NULL) {
return -ERR_INPUT_PARAMS;
}
LL_APPEND(pUser->pUserPool, pPool);
return ERR_SUCCESS;
}
PDHCP_USER dhcp_user_create(U32 uId) { PDHCP_USER dhcp_user_create(U32 uId) {
PDHCP_USER pUser; PDHCP_USER pUser;
@ -215,52 +193,35 @@ PDHCP_USER dhcp_user_create(U32 uId) {
// 创建一个新用户 // 创建一个新用户
if (pUser) { if (pUser) {
memset(pUser, 0, sizeof(DHCP_USER)); memset(pUser, 0, sizeof(DHCP_USER));
pUser->uid = uId; pUser->uid = uId;
// 管理地址池配置
pUser->pUserPool = get_pool_cfg(uId, 0);
if (pUser->pUserPool == NULL) {
LOG_MOD(error, ZM_DHCP_USR, "User %u get ipaddress pool error\n", uId);
free(pUser);
return NULL;
}
// 添加用户 // 添加用户
HASH_ADD_INT(g_dhcpUserList, uid, pUser); HASH_ADD_INT(g_dhcpUserList, uid, pUser);
LOG_MOD(trace, ZM_DHCP_USR, "Create User %u with Pool %08X - %08X of %p\n", uId, pUser->pUserPool->minAddr,
pUser->pUserPool->maxAddr, pUser->pUserPool);
return pUser; return pUser;
} }
return NULL; return NULL;
} }
int dhcp_user_assign_common_pool(PDHCP_USER pUser, PPOOL_INFO pPool) {
if (pUser == NULL || pPool == NULL) {
return -ERR_INPUT_PARAMS;
}
LL_APPEND(g_userCommonPool, pPool);
return ERR_SUCCESS;
}
int dhcp_user_assign_pool(PDHCP_USER pUser, PPOOL_INFO pPool) {
if (pUser == NULL || pPool == NULL) {
return -ERR_INPUT_PARAMS;
}
LL_APPEND(pUser->pUserPool, pPool);
return ERR_SUCCESS;
}
int dhcp_user_mgr_init() { int dhcp_user_mgr_init() {
#ifdef HTTPSERVER_ON #ifdef HTTPSERVER_ON
user_init_httpd(); user_init_httpd();
#endif #endif
init_default_pool();
return ERR_SUCCESS;
}
int user_alloc_addr(U32 uId, U8 mac[ETH_ALEN], U32 *pAddr) {
PDHCP_USER_CFG pUserCfg, pTemp;
INIT_DHCP_USER(uId);
return ERR_SUCCESS; return ERR_SUCCESS;
} }
#if 0
PIPPOOL_INFO user_get_pool(U32 uId) { PIPPOOL_INFO user_get_pool(U32 uId) {
PDHCP_USER_CFG pUser; PDHCP_USER_CFG pUser;
@ -280,38 +241,4 @@ PIPPOOL_INFO user_get_pool(U32 uId) {
return NULL; return NULL;
} }
#endif
int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool) {
U32 k;
U32 begin;
U32 end;
PIPPOOL_INFO pPoolCfg;
PDHCP_USER_CFG pUserCfg, pTemp;
INIT_DHCP_USER(uId);
// 该设备没有地址配置时,直接返回
if (pPool == NULL) {
return ERR_SUCCESS;
}
HASH_FIND_INT(pUserCfg->pPoolMgr, &pPool->poolKey, pPoolCfg);
// 改地址池已经存在,提示错误
if (pPoolCfg != NULL) {
free(pPool);
} else {
// 添加新地址池当前用户配置项中
HASH_ADD_INT(pUserCfg->pPoolMgr, poolKey, pPool);
pPoolCfg = pPool;
}
// 计算可用的IP
begin = pPoolCfg->minAddr & (~pPoolCfg->netMask);
end = pPoolCfg->maxAddr & (~pPoolCfg->netMask);
for (k = MAX(begin, 1U); k <= MIN(end, ntohl(~pPoolCfg->netMask) - 1); k++) {
bitset_set(pPoolCfg->assignPool, k);
}
return ERR_SUCCESS;
}