Merge branch 'libuv_dhcpd_dev' of http://git.komect.net/ZNJK/vcpe into v1.2.0_dev

This commit is contained in:
dongwenze 2023-04-10 16:45:10 +08:00
commit e03b56e745
25 changed files with 1322 additions and 157 deletions

View File

@ -72,7 +72,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
ColumnLimit: 140
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
@ -135,7 +135,7 @@ ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 1000
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakFirstLessLess: 140
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000

View File

@ -131,9 +131,21 @@ ENDIF ()
IF (USED_SQLITE)
MESSAGE("Select Option USED_SQLITE")
LIST(APPEND COMMON_DEFINE "-DSQLITE_ON")
ENDIF ()
IF (USED_MYSQL)
MESSAGE("Select Option USED_MYSQL")
LIST(APPEND COMMON_DEFINE "-DUSED_MYSQL")
ENDIF ()
IF (USED_REDIS)
MESSAGE("Select Option USED_REDIS")
LIST(APPEND COMMON_DEFINE "-DUSED_REDIS")
ENDIF ()
IF (USED_SQLITE_CRYPTO)
LIST(APPEND COMMON_DEFINE "-DSQLITE_CRYPTO_ON")
MESSAGE("Select Option USED_SQLITE_CRYPTO")
ENDIF ()

View File

@ -40,8 +40,8 @@ application:
mysql_passwd = "AES@5/BQyUIfVxgV9BZAz/D3Rg=="; # mysql 数据库密码
mysql_database = "test"; # mysql 数据库名称
sqlite_dbname = "vcpe.db"; # sqlite3 数据库文件名
sqlite_passwd = "test123"; # sqlite3 数据库密码
sqlite_dbname = "/home/hx/vcpe.db"; # sqlite3 数据库文件名
sqlite_passwd = ""; # sqlite3 数据库密码
};
# MQ 相关配置
@ -101,7 +101,7 @@ application:
# mac_filter = ["00:01:02:03:04:07", "00:01:02:03:04:01"];
# IP地址池配置
range_set: (
{ dhcp_range = "192.168.101.2-192.168.101.4";
{ dhcp_range = "192.168.101.0-192.168.101.4";
subnet_mask = "255.255.255.0";
domain_server = "114.114.114.114,8.8.8.8";
gateway = "192.168.101.1";

View File

@ -9,6 +9,9 @@
extern "C" {
#endif
#define DHCP_SVR_PORT (67)
#define DHCP_CLI_PORT (68)
/**
* Message op code / message type
* Request Message
@ -21,6 +24,7 @@ extern "C" {
#define BOOTP_REPLY 2
#define DHCP_MSG_NONE 0
/**
* DHCP客户端在请求IP地址时并不知道DHCP服务器的位置
* DHCP客户端会在本地网络内以广播方式发送Discover请求报文DHCP服务器
@ -28,6 +32,7 @@ extern "C" {
* DHCP客户端据此可以知道网络中存在的DHCP服务器的位置
*/
#define DHCP_MSG_DISCOVER 1
/**
* DHCP服务器收到Discover报文后IP地址
* DNS服务器等Offer报文
@ -35,6 +40,7 @@ extern "C" {
* ARP来检测该IP地址是否重复
*/
#define DHCP_MSG_OFFER 2
/**
* DHCP客户端可能会收到很多Offer请求报文
* Offer应答报文的服务器作为自己的目标服务器
@ -44,28 +50,33 @@ extern "C" {
* ACK报文87.5%广Request请求报文以请求续延租约
*/
#define DHCP_MSG_REQUEST 3
/**
* DHCP客户端收到DHCP服务器ACK应答报文后
* 使
* DHCP服务器发送Decline请求报文IP地址不可用IP地址
*/
#define DHCP_MSG_DECLINE 4
/**
* DHCP服务器收到Request请求报文后Request报文中携带的用户MAC来查找有没有相应的租约记录
* ACK应答报文使IP地址
*/
#define DHCP_MSG_ACK 5
/**
* DHCP服务器收到Request请求报文后IP地址
* DHCP客户端发送NAK应答报文IP地址
*/
#define DHCP_MSG_NAK 6
/**
* DHCP客户端不再需要使用分配IP地址时线
* DHCP服务器发送RELEASE请求报文IP地址
* DHCP服务器释放对应的IP地址
*/
#define DHCP_MSG_RELEASE 7
/**
* DHCP客户端如果需要从DHCP服务器端获取更为详细的配置信息
* DHCP服务器发送Inform请求报文DHCP服务器在收到该报文后

View File

@ -10,13 +10,14 @@ IF (USED_SQLITE_CRYPTO)
ENDIF ()
INCLUDE_DIRECTORIES(include ../opendhcp183 mongoose
./ ./include ../lwip/src/include ../lwip/src/arch_linux/include ../include)
./ ./include ../lwip/src/include ../lwip/src/arch_linux/include ../include)
FILE(GLOB C_HEADS ./include/network/*.h include/*.h include/uthash/*.h include/s2j/*.h vector/*.h ${CMAKE_BINARY_DIR}/*.h ${PROJECT_BINARY_DIR}/*.h)
AUX_SOURCE_DIRECTORY(json C_SRC)
AUX_SOURCE_DIRECTORY(args C_SRC)
AUX_SOURCE_DIRECTORY(init C_SRC)
AUX_SOURCE_DIRECTORY(misc C_SRC)
AUX_SOURCE_DIRECTORY(bitset C_SRC)
AUX_SOURCE_DIRECTORY(banner C_SRC)
AUX_SOURCE_DIRECTORY(configure C_SRC)
AUX_SOURCE_DIRECTORY(network C_SRC)
@ -40,22 +41,13 @@ IF (USED_HTTP_SVR)
AUX_SOURCE_DIRECTORY(mongoose C_SRC)
ENDIF ()
IF (USED_REDIS)
ADD_DEFINITIONS(-DUSED_REDIS)
ENDIF ()
IF (USED_SQLITE)
ADD_DEFINITIONS(-DSQLITE_ON)
LIST(APPEND C_SRC database/database.c)
IF (SQLITE_CRYPTO_ON)
ADD_DEFINITIONS(-DSQLITE_CRYPTO_ON)
AUX_SOURCE_DIRECTORY(database/sqlite3 C_SRC)
ENDIF ()
ENDIF ()
IF (USED_MYSQL)
ADD_DEFINITIONS(-DUSED_MYSQL)
ENDIF ()
SET(CMAKE_C_STANDARD 99)
SET_SOURCE_FILES_PROPERTIES(misc/zvector.c PROPERTIES COMPILE_FLAGS "-Wall -Wextra -flto")
@ -63,7 +55,7 @@ SET_SOURCE_FILES_PROPERTIES(mongoose/mongoose.c PROPERTIES COMPILE_FLAGS "-Wall
IF (USED_SQLITE_CRYPTO)
SET_SOURCE_FILES_PROPERTIES(database/sqlite3/sqlite3.c PROPERTIES
COMPILE_FLAGS "-DSQLITE_HAS_CODEC \
COMPILE_FLAGS "-DSQLITE_HAS_CODEC \
-DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_OS_UNIX=1 \
-D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite -DNDEBUG -DSQLITE_THREADSAFE=1 \
-DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
@ -71,7 +63,11 @@ IF (USED_SQLITE_CRYPTO)
-DSQLITE_HAVE_ZLIB=1 -DSQLITE_TEMP_STORE=2")
ENDIF ()
ADD_DEFINITIONS(${COMMON_DEFINE} -DMG_ARCH=MG_ARCH_UNIX -DMG_ENABLE_OPENSSL=1)
ADD_DEFINITIONS(${COMMON_DEFINE})
IF (USED_HTTP_SVR)
ADD_DEFINITIONS(-DMG_ARCH=MG_ARCH_UNIX -DMG_ENABLE_OPENSSL=1)
ENDIF ()
ADD_LIBRARY(${LIB_PROJECT_TARGET} ${C_SRC} ${C_HEADS})

382
srcs/libs/bitset/bitset.c Normal file
View File

@ -0,0 +1,382 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "bitset/bitset.h"
/* Create a new bitset. Return NULL in case of failure. */
bitset_t *bitset_create() {
bitset_t *bitset = NULL;
/* Allocate the bitset itself. */
if ((bitset = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
bitset->array = NULL;
bitset->arraysize = 0;
bitset->capacity = 0;
return bitset;
}
/* Create a new bitset able to contain size bits. Return NULL in case of failure. */
bitset_t *bitset_create_with_capacity(size_t size) {
bitset_t *bitset = NULL;
/* Allocate the bitset itself. */
if ((bitset = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
bitset->arraysize = (size + sizeof(uint64_t) * 8 - 1) / (sizeof(uint64_t) * 8);
bitset->capacity = bitset->arraysize;
if ((bitset->array = (uint64_t *)calloc(bitset->arraysize, sizeof(uint64_t))) == NULL) {
free(bitset);
return NULL;
}
return bitset;
}
/* Create a copy */
bitset_t *bitset_copy(const bitset_t *bitset) {
bitset_t *copy = NULL;
/* Allocate the bitset itself. */
if ((copy = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
memcpy(copy, bitset, sizeof(bitset_t));
copy->capacity = copy->arraysize;
if ((copy->array = (uint64_t *)malloc(sizeof(uint64_t) * bitset->arraysize)) == NULL) {
free(copy);
return NULL;
}
memcpy(copy->array, bitset->array, sizeof(uint64_t) * bitset->arraysize);
return copy;
}
void bitset_clear(bitset_t *bitset) {
memset(bitset->array, 0, sizeof(uint64_t) * bitset->arraysize);
}
void bitset_shift_left(bitset_t *bitset, size_t s) {
size_t extra_words = s / 64;
int inword_shift = (int)(s % 64);
size_t as = bitset->arraysize;
if (inword_shift == 0) {
bitset_resize(bitset, as + extra_words, FALSE);
// could be done with a memmove
for (size_t i = as + extra_words; i > extra_words; i--) {
bitset->array[i - 1] = bitset->array[i - 1 - extra_words];
}
} else {
bitset_resize(bitset, as + extra_words + 1, TRUE);
bitset->array[as + extra_words] = bitset->array[as - 1] >> (64 - inword_shift);
for (size_t i = as + extra_words; i >= extra_words + 2; i--) {
bitset->array[i - 1] = (bitset->array[i - 1 - extra_words] << inword_shift) |
(bitset->array[i - 2 - extra_words] >> (64 - inword_shift));
}
bitset->array[extra_words] = bitset->array[0] << inword_shift;
}
for (size_t i = 0; i < extra_words; i++) {
bitset->array[i] = 0;
}
}
void bitset_shift_right(bitset_t *bitset, size_t s) {
size_t extra_words = s / 64;
int inword_shift = (int)(s % 64);
size_t as = bitset->arraysize;
if (inword_shift == 0) {
// could be done with a memmove
for (size_t i = 0; i < as - extra_words; i++) {
bitset->array[i] = bitset->array[i + extra_words];
}
bitset_resize(bitset, as - extra_words, FALSE);
} else {
for (size_t i = 0; i + extra_words + 1 < as; i++) {
bitset->array[i] = (bitset->array[i + extra_words] >> inword_shift) |
(bitset->array[i + extra_words + 1] << (64 - inword_shift));
}
bitset->array[as - extra_words - 1] = (bitset->array[as - 1] >> inword_shift);
bitset_resize(bitset, as - extra_words, FALSE);
}
}
/* Free memory. */
void bitset_free(bitset_t *bitset) {
free(bitset->array);
free(bitset);
}
/* Resize the bitset so that it can support newarraysize * 64 bits. Return TRUE in case of success, FALSE for failure. */
int bitset_resize(bitset_t *bitset, size_t newarraysize, int padwithzeroes) {
size_t smallest = newarraysize < bitset->arraysize ? newarraysize : bitset->arraysize;
if (bitset->capacity < newarraysize) {
uint64_t *newarray;
bitset->capacity = newarraysize * 2;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
}
if (padwithzeroes && (newarraysize > smallest)) {
memset(bitset->array + smallest, 0, sizeof(uint64_t) * (newarraysize - smallest));
}
bitset->arraysize = newarraysize;
return TRUE; // success!
}
size_t bitset_count(const bitset_t *bitset) {
size_t card = 0;
size_t k = 0;
// assumes that long long is 8 bytes
for (; k + 7 < bitset->arraysize; k += 8) {
card += __builtin_popcountll(bitset->array[k]);
card += __builtin_popcountll(bitset->array[k + 1]);
card += __builtin_popcountll(bitset->array[k + 2]);
card += __builtin_popcountll(bitset->array[k + 3]);
card += __builtin_popcountll(bitset->array[k + 4]);
card += __builtin_popcountll(bitset->array[k + 5]);
card += __builtin_popcountll(bitset->array[k + 6]);
card += __builtin_popcountll(bitset->array[k + 7]);
}
for (; k + 3 < bitset->arraysize; k += 4) {
card += __builtin_popcountll(bitset->array[k]);
card += __builtin_popcountll(bitset->array[k + 1]);
card += __builtin_popcountll(bitset->array[k + 2]);
card += __builtin_popcountll(bitset->array[k + 3]);
}
for (; k < bitset->arraysize; k++) {
card += __builtin_popcountll(bitset->array[k]);
}
return card;
}
int bitset_inplace_union(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; ++k) {
b1->array[k] |= b2->array[k];
}
if (b2->arraysize > b1->arraysize) {
size_t oldsize = b1->arraysize;
if (!bitset_resize(b1, b2->arraysize, FALSE)) {
return FALSE;
}
memcpy(b1->array + oldsize, b2->array + oldsize, (b2->arraysize - oldsize) * sizeof(uint64_t));
}
return TRUE;
}
size_t bitset_minimum(const bitset_t *bitset) {
for (size_t k = 0; k < bitset->arraysize; k++) {
uint64_t w = bitset->array[k];
if (w != 0) {
return __builtin_ctzll(w) + k * 64;
}
}
return 0;
}
size_t bitset_maximum(const bitset_t *bitset) {
for (size_t k = bitset->arraysize; k > 0; k--) {
uint64_t w = bitset->array[k - 1];
if (w != 0) {
return 63 - __builtin_clzll(w) + (k - 1) * 64;
}
}
return 0;
}
/* Returns TRUE if bitsets share no common elements, FALSE otherwise.
*
* Performs early-out if common element found. */
int bitsets_disjoint(const bitset_t *b1, const bitset_t *b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; k++) {
if ((b1->array[k] & b2->array[k]) != 0) {
return FALSE;
}
}
return TRUE;
}
/* Returns TRUE if bitsets contain at least 1 common element, FALSE if they are
* disjoint.
*
* Performs early-out if common element found. */
int bitsets_intersect(const bitset_t *b1, const bitset_t *b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; k++) {
if ((b1->array[k] & b2->array[k]) != 0) {
return TRUE;
}
}
return FALSE;
}
/* Returns TRUE if b has any bits set in or after b->array[starting_loc]. */
static int any_bits_set(const bitset_t *b, size_t starting_loc) {
if (starting_loc >= b->arraysize) {
return FALSE;
}
for (size_t k = starting_loc; k < b->arraysize; k++) {
if (b->array[k] != 0) {
return TRUE;
}
}
return FALSE;
}
/* Returns TRUE if b1 has all of b2's bits set.
*
* Performs early out if a bit is found in b2 that is not found in b1. */
int bitset_contains_all(const bitset_t *b1, const bitset_t *b2) {
for (size_t k = 0; k < b1->arraysize; k++) {
if ((b1->array[k] & b2->array[k]) != b2->array[k]) {
return FALSE;
}
}
if (b2->arraysize > b1->arraysize) {
/* Need to check if b2 has any bits set beyond b1's array */
return !any_bits_set(b2, b1->arraysize);
}
return TRUE;
}
size_t bitset_union_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t answer = 0;
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k + 3 < minlength; k += 4) {
answer += __builtin_popcountll(b1->array[k] | b2->array[k]);
answer += __builtin_popcountll(b1->array[k + 1] | b2->array[k + 1]);
answer += __builtin_popcountll(b1->array[k + 2] | b2->array[k + 2]);
answer += __builtin_popcountll(b1->array[k + 3] | b2->array[k + 3]);
}
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] | b2->array[k]);
}
if (b2->arraysize > b1->arraysize) {
//k = b1->arraysize;
for (; k + 3 < b2->arraysize; k += 4) {
answer += __builtin_popcountll(b2->array[k]);
answer += __builtin_popcountll(b2->array[k + 1]);
answer += __builtin_popcountll(b2->array[k + 2]);
answer += __builtin_popcountll(b2->array[k + 3]);
}
for (; k < b2->arraysize; ++k) {
answer += __builtin_popcountll(b2->array[k]);
}
} else {
//k = b2->arraysize;
for (; k + 3 < b1->arraysize; k += 4) {
answer += __builtin_popcountll(b1->array[k]);
answer += __builtin_popcountll(b1->array[k + 1]);
answer += __builtin_popcountll(b1->array[k + 2]);
answer += __builtin_popcountll(b1->array[k + 3]);
}
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
}
return answer;
}
void bitset_inplace_intersection(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] &= b2->array[k];
}
for (; k < b1->arraysize; ++k) {
b1->array[k] = 0; // memset could, maybe, be a tiny bit faster
}
}
size_t bitset_intersection_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t answer = 0;
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] & b2->array[k]);
}
return answer;
}
void bitset_inplace_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] &= ~(b2->array[k]);
}
}
size_t bitset_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
size_t answer = 0;
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] & ~(b2->array[k]));
}
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
return answer;
}
int bitset_inplace_symmetric_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] ^= b2->array[k];
}
if (b2->arraysize > b1->arraysize) {
size_t oldsize = b1->arraysize;
if (!bitset_resize(b1, b2->arraysize, FALSE)) {
return FALSE;
}
memcpy(b1->array + oldsize, b2->array + oldsize, (b2->arraysize - oldsize) * sizeof(uint64_t));
}
return TRUE;
}
size_t bitset_symmetric_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
size_t answer = 0;
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] ^ b2->array[k]);
}
if (b2->arraysize > b1->arraysize) {
for (; k < b2->arraysize; ++k) {
answer += __builtin_popcountll(b2->array[k]);
}
} else {
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
}
return answer;
}
int bitset_trim(bitset_t *bitset) {
size_t newsize = bitset->arraysize;
while (newsize > 0) {
if (bitset->array[newsize - 1] == 0) {
newsize -= 1;
} else {
break;
}
}
if (bitset->capacity == newsize) {
return TRUE; // nothing to do
}
bitset->capacity = newsize;
bitset->arraysize = newsize;
uint64_t *newarray;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
return TRUE;
}

View File

@ -0,0 +1,63 @@
//
// Created by xajhuang on 2023/3/29.
//
#ifdef SQLITE_ON
#include <sqlite3.h>
#include <string.h>
#include "zlog_module.h"
#include "user_errno.h"
#include "config.h"
#include "database.h"
static sqlite3 *g_pSqlHandle = NULL;
int db_sqlite3_init() {
int rc;
const char *pDbPath = cfg_get_sqlite_db_name();
if (pDbPath == NULL || strlen(pDbPath) == 0) {
return ERR_SUCCESS;
}
if (g_pSqlHandle == NULL) {
rc = sqlite3_open_v2(pDbPath, &g_pSqlHandle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (rc != SQLITE_OK) {
LOG_MOD(error, ZLOG_MOD_DB, "Create SQLite3 Database at %s error: %s(%d)\n", pDbPath, sqlite3_errstr(rc), rc);
return -ERR_DB_CONNECT;
}
}
LOG_MOD(info, ZLOG_MOD_DB, "Used SQLite3 database: %s\n", pDbPath);
return ERR_SUCCESS;
}
int db_sqlite3_sql_exec(const char *pSqlCmd, void *pCallback, void *pData, char **pErr) {
if (pSqlCmd == NULL || strlen(pSqlCmd) == 0) {
LOG_MOD(error, ZLOG_MOD_DB, "Input params pSqlCmd error\n");
return -ERR_INPUT_PARAMS;
}
if (g_pSqlHandle) {
int rc = sqlite3_exec(g_pSqlHandle, pSqlCmd, pCallback, pData, pErr);
if (rc != SQLITE_OK) {
LOG_MOD(error, ZLOG_MOD_DB, "Run {%s} SQL command error:\n%s\n", pSqlCmd, sqlite3_errmsg(g_pSqlHandle));
return -ERR_DB_SQL_EXEC;
}
return ERR_SUCCESS;
} else {
LOG_MOD(error, ZLOG_MOD_DB, "SQlite3 database uninit\n");
return -ERR_DB_UNINIT;
}
}
void db_sqlite3_uninit() {
if (g_pSqlHandle) {
sqlite3_close(g_pSqlHandle);
}
}
#endif

View File

@ -0,0 +1,271 @@
//
// Created by xajhuang on 2023/4/6.
//
#ifndef VCPE_BITSET_H
#define VCPE_BITSET_H
#include <common.h>
#ifdef __cplusplus
extern "C" {
#endif
// For compatibility with MSVC with the use of `restrict`
#if (__STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && defined(__STDC_VERSION__))
#define CBITSET_RESTRICT restrict
#else
#define CBITSET_RESTRICT
#endif // (__STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && defined(__STDC_VERSION__ ))
struct bitset_s {
uint64_t *CBITSET_RESTRICT array;
size_t arraysize;
size_t capacity;
};
typedef struct bitset_s bitset_t;
/* Create a new bitset. Return NULL in case of failure. */
bitset_t *bitset_create(void);
/* Create a new bitset able to contain size bits. Return NULL in case of failure. */
bitset_t *bitset_create_with_capacity(size_t size);
/* Free memory. */
void bitset_free(bitset_t *bitset);
/* Set all bits to zero. */
void bitset_clear(bitset_t *bitset);
/* Create a copy */
bitset_t *bitset_copy(const bitset_t *bitset);
/* Resize the bitset. Return TRUE in case of success, FALSE for failure. Pad with zeroes new buffer areas if requested. */
int bitset_resize(bitset_t *bitset, size_t newarraysize, int padwithzeroes);
/* returns how many bytes of memory the backend buffer uses */
static inline size_t bitset_size_in_bytes(const bitset_t *bitset) {
return bitset->arraysize * sizeof(uint64_t);
}
/* returns how many bits can be accessed */
static inline size_t bitset_size_in_bits(const bitset_t *bitset) {
return bitset->arraysize * 64;
}
/* returns how many words (64-bit) of memory the backend buffer uses */
static inline size_t bitset_size_in_words(const bitset_t *bitset) {
return bitset->arraysize;
}
/* Grow the bitset so that it can support newarraysize * 64 bits with padding. Return TRUE in case of success, FALSE for failure. */
static inline int bitset_grow(bitset_t *bitset, size_t newarraysize) {
if (bitset->capacity < newarraysize) {
uint64_t *newarray;
bitset->capacity = newarraysize * 2;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
}
memset(bitset->array + bitset->arraysize, 0, sizeof(uint64_t) * (newarraysize - bitset->arraysize));
bitset->arraysize = newarraysize;
return TRUE; // success!
}
/* attempts to recover unused memory, return FALSE in case of reallocation failure */
int bitset_trim(bitset_t *bitset);
/* shifts all bits by 's' positions so that the bitset representing values 1,2,10 would represent values 1+s, 2+s, 10+s */
void bitset_shift_left(bitset_t *bitset, size_t s);
/* shifts all bits by 's' positions so that the bitset representing values 1,2,10 would represent values 1-s, 2-s, 10-s, negative values are deleted */
void bitset_shift_right(bitset_t *bitset, size_t s);
/* Set the ith bit. Attempts to resize the bitset if needed (may silently fail) */
static inline void bitset_set(bitset_t *bitset, size_t i) {
size_t shiftedi = i >> 6;
if (shiftedi >= bitset->arraysize) {
if (!bitset_grow(bitset, shiftedi + 1)) {
return;
}
}
bitset->array[shiftedi] |= ((uint64_t)1) << (i % 64);
}
/* Set the ith bit to the specified value. Attempts to resize the bitset if needed (may silently fail) */
static inline void bitset_set_to_value(bitset_t *bitset, size_t i, int flag) {
size_t shiftedi = i >> 6;
uint64_t mask = ((uint64_t)1) << (i % 64);
uint64_t dynmask = ((uint64_t)flag) << (i % 64);
if (shiftedi >= bitset->arraysize) {
if (!bitset_grow(bitset, shiftedi + 1)) {
return;
}
}
uint64_t w = bitset->array[shiftedi];
w &= ~mask;
w |= dynmask;
bitset->array[shiftedi] = w;
}
static inline void bitset_cls_bit(bitset_t *bitset, size_t i) {
bitset_set_to_value(bitset, i, 0);
}
/* Get the value of the ith bit. */
static inline int bitset_get(const bitset_t *bitset, size_t i) {
size_t shiftedi = i >> 6;
if (shiftedi >= bitset->arraysize) {
return FALSE;
}
return (bitset->array[shiftedi] & (((uint64_t)1) << (i % 64))) != 0;
}
/* Count number of bits set. */
size_t bitset_count(const bitset_t *bitset);
/* Find the index of the first bit set. */
size_t bitset_minimum(const bitset_t *bitset);
/* Find the index of the last bit set. */
size_t bitset_maximum(const bitset_t *bitset);
/* compute the union in-place (to b1), returns TRUE if successful, to generate a new bitset first call bitset_copy */
int bitset_inplace_union(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* report the size of the union (without materializing it) */
size_t bitset_union_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the intersection in-place (to b1), to generate a new bitset first call bitset_copy */
void bitset_inplace_intersection(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* report the size of the intersection (without materializing it) */
size_t bitset_intersection_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* returns TRUE if the bitsets contain no common elements */
int bitsets_disjoint(const bitset_t *b1, const bitset_t *b2);
/* returns TRUE if the bitsets contain any common elements */
int bitsets_intersect(const bitset_t *b1, const bitset_t *b2);
/* returns TRUE if b1 contains all the set bits of b2 */
int bitset_contains_all(const bitset_t *b1, const bitset_t *b2);
/* compute the difference in-place (to b1), to generate a new bitset first call bitset_copy */
void bitset_inplace_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the size of the difference */
size_t bitset_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the symmetric difference in-place (to b1), return TRUE if successful, to generate a new bitset first call bitset_copy */
int bitset_inplace_symmetric_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the size of the symmetric difference */
size_t bitset_symmetric_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* iterate over the set bits
like so :
for(size_t i = 0; nextSetBit(b,&i) ; i++) {
//.....
}
*/
static inline int nextSetBit(const bitset_t *bitset, size_t *i) {
size_t x = *i >> 6;
if (x >= bitset->arraysize) {
return FALSE;
}
uint64_t w = bitset->array[x];
w >>= (*i & 63);
if (w != 0) {
*i += __builtin_ctzll(w);
return TRUE;
}
x++;
while (x < bitset->arraysize) {
w = bitset->array[x];
if (w != 0) {
*i = x * 64 + __builtin_ctzll(w);
return TRUE;
}
x++;
}
return FALSE;
}
/* Iterate over the set bits
like so :
size_t buffer[256];
size_t howmany = 0;
for(size_t startfrom = 0; (howmany = nextSetBits(b,buffer,256, &startfrom)) > 0 ; startfrom++) {
//.....
}
*/
static inline size_t nextSetBits(const bitset_t *bitset, size_t *buffer, size_t capacity, size_t *startfrom) {
if (capacity == 0) {
return 0; // sanity check
}
size_t x = *startfrom >> 6;
if (x >= bitset->arraysize) {
return 0; // nothing more to iterate over
}
uint64_t w = bitset->array[x];
w >>= (*startfrom & 63);
size_t howmany = 0;
size_t base = x << 6;
while (howmany < capacity) {
while (w != 0) {
uint64_t t = w & (~w + 1);
int r = __builtin_ctzll(w);
buffer[howmany++] = r + base;
if (howmany == capacity) {
goto end;
}
w ^= t;
}
x += 1;
if (x == bitset->arraysize) {
break;
}
base += 64;
w = bitset->array[x];
}
end:
if (howmany > 0) {
*startfrom = buffer[howmany - 1];
}
return howmany;
}
typedef int (*bitset_iterator)(size_t value, void *param);
// return TRUE if uninterrupted
static inline int bitset_for_each(const bitset_t *b, bitset_iterator iterator, void *ptr) {
size_t base = 0;
for (size_t i = 0; i < b->arraysize; ++i) {
uint64_t w = b->array[i];
while (w != 0) {
uint64_t t = w & (~w + 1);
int r = __builtin_ctzll(w);
if (!iterator(r + base, ptr)) {
return FALSE;
}
w ^= t;
}
base += 64;
}
return TRUE;
}
//static inline void bitset_print(const bitset_t *b) {
// printf("{");
// for (size_t i = 0; nextSetBit(b, &i); i++) {
// printf("%zu, ", i);
// }
// printf("}");
//}
#ifdef __cplusplus
}
#endif
#endif //VCPE_BITSET_H

View File

@ -11,6 +11,26 @@ extern "C" {
#define _STR(s) #s
#define STR(s) _STR(s)
#ifndef MIN
#define MIN(a, b) \
({ \
typeof(a) __min1__ = (a); \
typeof(b) __min2__ = (b); \
(void)(&__min1__ == &__min2__); \
__min1__ < __min2__ ? __min1__ : __min2__; \
})
#endif
#ifndef MAX
#define MAX(a, b) \
({ \
typeof(a) __max1__ = (a); \
typeof(b) __max2__ = (b); \
(void)(&__max1__ == &__max2__); \
__max1__ < __max2__ ? __max1__ : __max2__; \
})
#endif
#ifndef ARRAY_SIZE
//#ifdef __cplusplus
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
@ -48,11 +68,10 @@ typedef unsigned char U8;
typedef unsigned short U16;
typedef unsigned int U32;
typedef unsigned long long U64;
typedef char S8;
typedef short S16;
typedef int S32;
typedef long long S64;
typedef char S8;
typedef short S16;
typedef int S32;
typedef long long S64;
#ifdef __cplusplus
}

View File

@ -8,10 +8,9 @@
extern "C" {
#endif
int db_redis_init(void);
int db_mysql_init(void);
void *get_mysql_handle();
void db_mysql_uninit();
int db_sqlite3_init();
void db_sqlite3_uninit();
int db_sqlite3_sql_exec(const char *pSqlCmd, void *pCallback, void *pData, char **pErr);
#ifdef __cplusplus
}
#endif

View File

@ -4,10 +4,13 @@
#ifndef VCPE_IPADDR_H
#define VCPE_IPADDR_H
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
U32 ipv4_get_network_addr(U32 ipAddr, U32 netmask);
U32 ipv4_get_boardcast_addr(U32 ipAddr, U32 netmask);
U32 ipv4_network_total_addr(U32 netmask);
#ifdef __cplusplus
}
#endif

View File

@ -8,67 +8,71 @@
extern "C" {
#endif
#define DEF_ERR_CODE(ERR_CODE) \
ERR_CODE(ERR_SUCCESS, 0, "成功") \
ERR_CODE(ERR_INPUT_PARAMS, 1, "输入参数错误") \
ERR_CODE(ERR_UN_SUPPORT, 2, "不支持的操作") \
ERR_CODE(ERR_CALL_SHELL, 3, "调用Shell命令失败") \
ERR_CODE(ERR_ITEM_EXISTS, 4, "该内容已经存在") \
ERR_CODE(ERR_ITEM_UNEXISTS, 5, "该内容不存在") \
ERR_CODE(ERR_SYS_INIT, 6, "系统中断") \
ERR_CODE(ERR_SYS_CALL, 7, "系统调用") \
ERR_CODE(ERR_OPEN_FILE, 8, "打开文件失败") \
ERR_CODE(ERR_READ_FILE, 9, "读取文件失败") \
ERR_CODE(ERR_FILE_NOT_EXISTS, 10, "文件不存在") \
ERR_CODE(ERR_FILE_LOCKED, 11, "文件被锁定") \
ERR_CODE(ERR_GET_FILE_SIZE, 12, "获取文件大小失败") \
ERR_CODE(ERR_COPY_FILE, 13, "复制文件失败") \
ERR_CODE(ERR_MALLOC_MEMORY, 14, "分配内存失败") \
ERR_CODE(ERR_MMAP_MEMORY, 15, "共享内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, 16, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, 17, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, 18, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, 19, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, 20, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, 21, "初始化加解密失败") \
ERR_CODE(ERR_AES_KEYGEN, 22, "AES秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, 23, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, 24, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, 25, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, 26, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, 27, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, 28, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, 29, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, 30, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, 31, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, 32, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, 33, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, 34, "获取传感器信息失败") \
ERR_CODE(ERR_DB_CONNECT, 35, "数据库连接失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, 36, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, 37, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, 38, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, 39, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, 40, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, 41, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PARSE_OBJ, 42, "解析JSON对象失败") \
ERR_CODE(ERR_JSON_VALID_SCH, 43, "JSON数据验证失败") \
ERR_CODE(ERR_CREATE_NETIF, 44, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, 45, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, 46, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, 47, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, 48, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, 49, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, 50, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, 51, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, 52, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, 53, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, 54, "HTTP 协议解析失败") \
ERR_CODE(ERR_MSG_CONTENT, 55, "msgContent内容不正确") \
ERR_CODE(ERR_SOCK_CREATE, 56, "创建套接字失败") \
ERR_CODE(ERR_SOCK_SETOPT, 57, "设置套接字参数失败")
#define DEF_ERR_CODE(ERR_CODE) \
ERR_CODE(ERR_SUCCESS, "成功") \
ERR_CODE(ERR_INPUT_PARAMS, "输入参数错误") \
ERR_CODE(ERR_UN_SUPPORT, "不支持的操作") \
ERR_CODE(ERR_CALL_SHELL, "调用Shell命令失败") \
ERR_CODE(ERR_ITEM_EXISTS, "该内容已经存在") \
ERR_CODE(ERR_ITEM_UNEXISTS, "该内容不存在") \
ERR_CODE(ERR_SYS_INIT, "系统中断") \
ERR_CODE(ERR_SYS_CALL, "系统调用") \
ERR_CODE(ERR_OPEN_FILE, "打开文件失败") \
ERR_CODE(ERR_READ_FILE, "读取文件失败") \
ERR_CODE(ERR_FILE_NOT_EXISTS, "文件不存在") \
ERR_CODE(ERR_FILE_LOCKED, "文件被锁定") \
ERR_CODE(ERR_GET_FILE_SIZE, "获取文件大小失败") \
ERR_CODE(ERR_COPY_FILE, "复制文件失败") \
ERR_CODE(ERR_MALLOC_MEMORY, "分配内存失败") \
ERR_CODE(ERR_MMAP_MEMORY, "共享内存失败") \
ERR_CODE(ERR_EVP_KEY_SIZE, "秘钥大小不正确") \
ERR_CODE(ERR_UNSUP_EVP_TYPE, "不支持的加解密算法") \
ERR_CODE(ERR_EVP_INIT_KEY, "初始化秘钥失败") \
ERR_CODE(ERR_EVP_UPDATE, "加解密数据失败") \
ERR_CODE(ERR_EVP_FINALE, "错误的加解密结果") \
ERR_CODE(ERR_EVP_CREATE_CTX, "初始化加解密失败") \
ERR_CODE(ERR_AES_KEYGEN, "AES秘钥失败") \
ERR_CODE(ERR_EVP_ENCRYPTION, "加密失败") \
ERR_CODE(ERR_EVP_DECRYPTION, "解密失败") \
ERR_CODE(ERR_CONFIG_INIT, "配置文件初始化失败") \
ERR_CODE(ERR_UNCOMPATIBILITY_TYPE, "未兼容的类型") \
ERR_CODE(ERR_STRING_TO_NUMBER, "字符串转数字失败") \
ERR_CODE(ERR_UNKNOWN_CFG_ID, "未识别的配置项") \
ERR_CODE(ERR_ZLOG_INIT, "日志系统初始化失败") \
ERR_CODE(ERR_SYS_GET_CPU_INFO, "获取CPU信息失败") \
ERR_CODE(ERR_SYS_NOT_FOUND_CPU, "找不到CPU信息") \
ERR_CODE(ERR_SYS_DISK_GET_INFO, "获取磁盘空间占用信息失败") \
ERR_CODE(ERR_SYS_IPMI_UNSUP, "服务器IPMI接口不支持") \
ERR_CODE(ERR_SYS_SENSOR_GET_INFO, "获取传感器信息失败") \
ERR_CODE(ERR_DB_UNINIT, "数据库未连接") \
ERR_CODE(ERR_DB_CONNECT, "数据库连接失败") \
ERR_CODE(ERR_DB_SQL_EXEC, "数据库SQL命令执行失败") \
ERR_CODE(ERR_MQ_CREATE_MQ, "创建消息队列失败") \
ERR_CODE(ERR_MQ_CREATE_REP, "创建REP消息队列失败") \
ERR_CODE(ERR_MQ_BIND_SOCKET, "消息队列BIND Socket失败") \
ERR_CODE(ERR_MQ_CONN_SERVER, "消息队列连接服务器失败") \
ERR_CODE(ERR_MQ_SEND_MSG, "消息队列发送消息失败") \
ERR_CODE(ERR_JSON_CREAT_OBJ, "创建JSON对象失败") \
ERR_CODE(ERR_JSON_PARSE_OBJ, "解析JSON对象失败") \
ERR_CODE(ERR_JSON_VALID_SCH, "JSON数据验证失败") \
ERR_CODE(ERR_CREATE_NETIF, "创建网络接口失败") \
ERR_CODE(ERR_CREATE_PPPOE_NETIF, "创建PPPoE网络接口失败") \
ERR_CODE(ERR_CREATE_PPP_SESSION, "创建PPP连接失败") \
ERR_CODE(ERR_MISC_GET_IPADDR, "获取网卡IP地址失败") \
ERR_CODE(ERR_MISC_GET_NETMASK, "获取网卡子网掩码失败") \
ERR_CODE(ERR_MISC_GET_GATEWAY, "获取网卡网关地址失败") \
ERR_CODE(ERR_MISC_GET_MACADDR, "获取网卡MAC地址失败") \
ERR_CODE(ERR_MENU_EXIT, "菜单执行完后自动退出") \
ERR_CODE(ERR_HTTP_UNSUP_METHOD, "不支持的 HTTP 请求方法") \
ERR_CODE(ERR_HTTP_UNSUP_PAGE, "找不到 HTTP 服务") \
ERR_CODE(ERR_PROTO_DECODE, "HTTP 协议解析失败") \
ERR_CODE(ERR_MSG_CONTENT, "msgContent内容不正确") \
ERR_CODE(ERR_DHCP_NO_POOL, "找不到可用地址池") \
ERR_CODE(ERR_DHCP_NO_ADDR, "找不到可用IP地址") \
ERR_CODE(ERR_SOCK_CREATE, "创建套接字失败") \
ERR_CODE(ERR_SOCK_SETOPT, "设置套接字参数失败")
#define GENERATE_ENUM(ENUM, no, x) ENUM,
#define GENERATE_ENUM(ENUM, x) ENUM,
typedef enum {
DEF_ERR_CODE(GENERATE_ENUM)

View File

@ -7,6 +7,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <zlog.h>
enum {
@ -14,13 +15,13 @@ enum {
};
typedef enum {
trace = ZLOG_LEVEL_TRACE,
debug = ZLOG_LEVEL_DEBUG,
info = ZLOG_LEVEL_INFO,
trace = ZLOG_LEVEL_TRACE,
debug = ZLOG_LEVEL_DEBUG,
info = ZLOG_LEVEL_INFO,
notice = ZLOG_LEVEL_NOTICE,
warn = ZLOG_LEVEL_WARN,
error = ZLOG_LEVEL_ERROR,
fatal = ZLOG_LEVEL_FATAL
warn = ZLOG_LEVEL_WARN,
error = ZLOG_LEVEL_ERROR,
fatal = ZLOG_LEVEL_FATAL
} ZLOG_LV;
#define DEF_ZLOG_MOD(ZLOG_MOD) \
@ -30,6 +31,7 @@ typedef enum {
ZLOG_MOD(ZLOG_MOD_MISC, ZLOG_LEVEL_DEBUG, "MISC") \
ZLOG_MOD(ZLOG_MOD_WATCH, ZLOG_LEVEL_DEBUG, "WATCH") \
ZLOG_MOD(ZLOG_MOD_CONFIG, ZLOG_LEVEL_DEBUG, "CONFIG") \
ZLOG_MOD(ZLOG_MOD_DB, ZLOG_LEVEL_DEBUG, "DB") \
ZLOG_MOD(ZLOG_MOD_NET, ZLOG_LEVEL_DEBUG, "NET") \
ZLOG_MOD(ZLOG_MOD_CRYPTO, ZLOG_LEVEL_DEBUG, "CRYPTO") \
ZLOG_MOD(ZLOG_MOD_MQ, ZLOG_LEVEL_DEBUG, "MQ") \
@ -88,8 +90,11 @@ typedef enum {
} while (0)
zlog_category_t *zlog_get_mod_cat(ZLOG_MOD_NAME logMod);
int zlog_verify_level(int level, ZLOG_MOD_NAME logMod);
const char *zlog_vni_tag_get();
int zlog_verify_level(int level, ZLOG_MOD_NAME logMod);
const char *zlog_vni_tag_get();
#ifdef __cplusplus
}
#endif

View File

@ -19,6 +19,9 @@
#include "lib_config.h"
#include "prj_config.h"
#include "zlog_module.h"
#ifdef SQLITE_ON
#include "database.h"
#endif
#ifdef ZEROMQ_ON
#include "msg_queue.h"
#endif
@ -137,6 +140,10 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
if (cfg_get_hardware_watch_enable()) {
init_hardware();
}
#ifdef SQLITE_ON
db_sqlite3_init();
#endif
#ifdef ZEROMQ_ON
if ((ret = mq_init()) != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_INIT, "Message queue init error: %d\n", ret);
@ -157,6 +164,9 @@ int user_init(const char *pAppCfgFile, const char *pCfgDirectory, const char *pK
void user_uninit() {
if (g_isInited) {
task_manager_exit();
#ifdef SQLITE_ON
db_sqlite3_uninit();
#endif
#ifdef HTTPSERVER_ON
http_svr_uinit();
#endif

View File

@ -1,4 +1,16 @@
//
// Created by xajhuang on 2023/3/21.
//
#include "ipaddr.h"
#include "ipaddr.h"
U32 ipv4_get_network_addr(U32 ipAddr, U32 netmask) {
return (ipAddr & netmask);
}
U32 ipv4_get_boardcast_addr(U32 ipAddr, U32 netmask) {
return (ipAddr | netmask);
}
U32 ipv4_network_total_addr(U32 netmask) {
return (~netmask) + 1;
}

View File

@ -4,8 +4,8 @@
#include <user_errno.h>
#include "common.h"
#define MAX_DESC_LENGTH (256)
#define GENERATE_STRING(STRING, no, desc) {#STRING, desc},
#define MAX_DESC_LENGTH (256)
#define GENERATE_STRING(STRING, desc) {#STRING, desc},
static const char *g_enumStrVal[][MAX_DESC_LENGTH] = {
DEF_ERR_CODE(GENERATE_STRING) {"ERR_UNKNOWN", "未知错误"},

View File

@ -141,6 +141,24 @@ void dhcp_option_cfg_init() {
}
}
void dhcp_add_number_option(U8 *pBegin, int opt, U8 value, U8 nSize) {
*pBegin = opt;
pBegin++;
*pBegin = nSize;
pBegin++;
memcpy(pBegin, &value, nSize);
pBegin += nSize;
}
void dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize) {
*pBegin = opt;
pBegin++;
*pBegin = nSize;
pBegin++;
memcpy(pBegin, buf, nSize);
pBegin += nSize;
}
int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal) {
U8 *p = pOptData;

View File

@ -18,18 +18,26 @@
#include "network/vlan.h"
#include "dhcp_options.h"
#include "config.h"
#include "ip_pool.h"
#include "misc.h"
#include "user_mgr.h"
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
#define MAX_DHCP_PKG_SIZE (512)
#define MIN_IPADDR (0xC0A80202)
#define DHCP_NETMASK (0xFFFF0000)
#define GW_IPADDR (0xC0A80201)
#define MASTER_DNS (0x08080808)
#define SALVE_DNS (0x72727272)
#define MAC_TO_STR(mac, str) sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])
typedef struct {
U8 unicast;
U8 cliMac[ETH_ALEN];
U32 xid;
U32 reqIpAddr;
U32 leaseTime;
char clientId[256];
char vendorClassId[256];
char hostName[256];
} DHCP_REQ, *PDHCP_REQ;
typedef struct {
struct iovec *rd;
@ -37,6 +45,14 @@ typedef struct {
struct tpacket_req3 req;
} PACKET_MMAP_RING, *PPACKET_MMAP_RING;
typedef struct {
char *pIfName;
U32 ipAddr;
U32 netmask;
U8 macAddr[ETH_ALEN];
S8 hostname[MAX_PATH];
} NIC_INFO, *PNIC_INFO;
struct block_desc {
uint32_t version;
uint32_t offset_to_priv;
@ -63,6 +79,7 @@ typedef struct {
} PKG_MSG, *PPKG_MSG;
#pragma pack()
/*
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
@ -70,7 +87,8 @@ messages) originating within their racks to anycast VIPs, one DHCPv4 and one
for DHCPv6.
*/
static struct sock_filter g_filterCode[] = {
#ifdef UDP_DHCP_FILTER // create by: tcpdump "udp and port 67 and port 68" -dd
#ifdef UDP_DHCP_FILTER
// create by: tcpdump "udp and port 67 and port 68" -dd
{0x28, 0, 0, 0x0000000c},
{0x15, 0, 9, 0x000086dd},
{0x30, 0, 0, 0x00000014},
@ -99,13 +117,13 @@ static struct sock_filter g_filterCode[] = {
{0x6, 0, 0, 0x00000000},
#endif
#if 0
// create by: tcpdump "vxlan" -dd
{0x28, 0, 0, 0x0000000c},
{0x15, 2, 0, 0x00008100},
{0x15, 1, 0, 0x000088a8},
{0x15, 0, 1, 0x00009100},
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
// create by: tcpdump "vxlan" -dd
{0x28, 0, 0, 0x0000000c},
{0x15, 2, 0, 0x00008100},
{0x15, 1, 0, 0x000088a8},
{0x15, 0, 1, 0x00009100},
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
#endif
// region BPF code
// create by: tcpdump "vlan and udp and port 67 and port 68" -dd
@ -182,6 +200,7 @@ static struct sock_filter g_filterCode[] = {
};
static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
@ -191,17 +210,110 @@ static struct sock_fprog bpf = {
.filter = g_filterCode,
};
typedef struct {
U8 unicast;
U8 cliMac[ETH_ALEN];
U32 xid;
U32 reqIpAddr;
U32 leaseTime;
char *clientId;
char *vendorClassId;
} DHCP_REQ, *PDHCP_REQ;
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
PDHCP_PACKAGE pRsp = (PDHCP_PACKAGE)malloc(MAX_DHCP_PKG_SIZE);
U8 *pOpt = pRsp->dhcp.options;
if (pRsp == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
return -ERR_MALLOC_MEMORY;
}
memset(pRsp, 0, MAX_DHCP_PKG_SIZE);
// 二层头
// 目的IP地址
memset(pRsp->vlan_hdr.eth.h_dest, 0xFF, ETH_ALEN);
// 源 IP 地址
memcpy(pRsp->vlan_hdr.eth.h_source, g_nicInfo.macAddr, ETH_ALEN);
// protol
pRsp->vlan_hdr.eth.h_proto = pReq->vlan_hdr.eth.h_proto;
// QinQ 隧道
pRsp->vlan_hdr.vlan.id = pReq->vlan_hdr.vlan.id;
pRsp->vlan_hdr.vlan.type = pReq->vlan_hdr.vlan.type;
// TODO 可能的二层QinQ隧道
// IP 头
memcpy(&pRsp->vlan_hdr.ip, &pReq->vlan_hdr.ip, sizeof(struct iphdr));
// 更新源IP
pRsp->vlan_hdr.ip.saddr = htonl(g_nicInfo.ipAddr);
// 更新目的IP地址广播255.255.255.255
pRsp->vlan_hdr.ip.daddr = 0xFFFFFFFF;
// UDP 头
// 目的端口
pRsp->vlan_hdr.udp.dest = pReq->vlan_hdr.udp.source;
// 源端口
pRsp->vlan_hdr.udp.source = pReq->vlan_hdr.udp.dest;
//DHCP 协议
// 返回类型
pRsp->dhcp.op = BOOTP_REPLY;
// 地址类型长度
pRsp->dhcp.htype = pReq->dhcp.htype;
// 地址长度
pRsp->dhcp.hlen = pReq->dhcp.hlen;
// xid
pRsp->dhcp.xid = pReq->dhcp.xid;
// 分配的 IP 地址
pRsp->dhcp.yiaddr = htonl(ip);
// 客户端 MAC 地址
memcpy(pRsp->dhcp.chaddr, pReq->dhcp.chaddr, ETH_ALEN);
// DHCP服务端主机名
memcpy(pRsp->dhcp.sname, g_nicInfo.hostname, MIN(64, strlen(g_nicInfo.hostname)));
// Magic Cookie: DHCP
memcpy(&pRsp->dhcp.cookie, "DHCP", 4);
pRsp->dhcp.hops = 0;
pRsp->dhcp.secs = 0;
pRsp->dhcp.flags = 0;
pRsp->dhcp.ciaddr = 0;
pRsp->dhcp.siaddr = 0;
pRsp->dhcp.giaddr = 0;
// DHCP Options
// DHCP 消息类型
dhcp_add_number_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_OFFER, 1);
pOpt += 3;
// 子网掩码
dhcp_add_number_option(pOpt, OPT_NETMASK, pIpInfo->netMask, 4);
pOpt += 6;
// 租约
dhcp_add_number_option(pOpt, OPT_IPADDRLEASE, htonl(pIpInfo->leaseTime), 4);
pOpt += 6;
// DHCP Server
dhcp_add_number_option(pOpt, OPT_SERVERID, g_nicInfo.ipAddr, 4);
pOpt += 6;
// DNS
if (pIpInfo->primeDNS != 0) {
if (pIpInfo->salveDNS == 0) {
dhcp_add_number_option(pOpt, OPT_DNS, pIpInfo->primeDNS, 4);
pOpt += 6;
} else {
dhcp_add_buf_option(pOpt, OPT_DNS, (U8 *)&pIpInfo->primeDNS, 8);
pOpt += 10;
}
}
// 网关
if (pIpInfo->gwAddr != 0) {
dhcp_add_number_option(pOpt, OPT_ROUTER, pIpInfo->gwAddr, 4);
pOpt += 6;
}
// DHCP 主机名
dhcp_add_buf_option(pOpt, OPT_DOMAINNAME, (U8 *)g_nicInfo.hostname, strlen(g_nicInfo.hostname));
pOpt += strlen(g_nicInfo.hostname) + 2;
*pOpt = OPT_END;
LOG_MSG_HEX(debug, pRsp, 256);
return ERR_SUCCESS;
}
static void on_sock_recv(uv_work_t *req) {
char macStr[20] = {0};
U32 ip;
PIPPOOL_INFO pIpInfo;
DHCP_REQ reqDhcp;
DHCP_OPT optMsg, opt;
int ret;
@ -209,6 +321,8 @@ static void on_sock_recv(uv_work_t *req) {
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pWork->pPkgBase;
U32 optSize = pWork->nSize - sizeof(DHCP_PACKAGE);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macStr[0], macStr[1], macStr[2], macStr[3], macStr[4], macStr[5]);
// Check op flag
if (pkg->dhcp.op != BOOTP_REQUEST) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Error message op code %d\n", pkg->dhcp.op);
@ -241,12 +355,33 @@ static void on_sock_recv(uv_work_t *req) {
ret = dhcp_get_option(OPT_CLIENTID, pkg->dhcp.options, optSize, &opt);
if (ret == ERR_SUCCESS) {
reqDhcp.clientId = (char *)opt.pValue;
strncpy(reqDhcp.clientId, (char *)opt.pValue, MIN((int)opt.len, 256));
}
ret = dhcp_get_option(OPT_VENDORCLASSID, pkg->dhcp.options, optSize, &opt);
if (ret == ERR_SUCCESS) {
reqDhcp.vendorClassId = (char *)opt.pValue;
strncpy(reqDhcp.vendorClassId, (char *)opt.pValue, MIN((int)opt.len, 256));
}
ret = dhcp_get_option(OPT_HOSTNAME, pkg->dhcp.options, optSize, &opt);
if (ret == ERR_SUCCESS) {
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
}
MAC_TO_STR(reqDhcp.cliMac, macStr);
ret = pre_alloc_dhcp_res(VLAN_VNI_ID(pkg->vlan_hdr.vlan.id), macStr, &ip, &pIpInfo);
if (ret == ERR_SUCCESS) {
LOG_MOD(trace,
ZLOG_MOD_DHCPD,
"DHCP prepare assign ipaddress: [%s(%s)] --> %s\n",
macStr,
reqDhcp.hostName,
u32_to_str_ip(ntohl(ip)));
ret = dhcp_resp_offer(pkg, pIpInfo, ip);
} else {
//LOG_MOD(error, ZLOG_MOD_DHCPD, );
}
break;
case DHCP_MSG_REQUEST:
@ -417,7 +552,7 @@ static int create_udp_socket() {
#endif
// 6. bind socket
memset(&addr, 0, sizeof(addr));
addr.sll_ifindex = (int)if_nametoindex(config_get_dhcp_nic_name());
addr.sll_ifindex = (int)if_nametoindex(g_nicInfo.pIfName);
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_hatype = 0;
@ -435,8 +570,16 @@ static int create_udp_socket() {
int dhcpd_init() {
static uv_udp_t uvRaw;
static uv_poll_t uvSocket;
int sock;
size_t size = MAX_PATH;
int sock = create_udp_socket();
memset(&g_nicInfo, 0, sizeof(NIC_INFO));
g_nicInfo.pIfName = (char *)config_get_dhcp_nic_name();
uv_os_gethostname(g_nicInfo.hostname, &size);
get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr);
sock = create_udp_socket();
if (sock <= 0) {
return sock;
@ -444,6 +587,7 @@ int dhcpd_init() {
dhcp_user_mgr_init();
dhcp_option_cfg_init();
dhcp_lease_init();
uv_udp_init(get_task_manager(), &uvRaw);
uv_udp_open(&uvRaw, sock);

View File

@ -141,6 +141,8 @@ typedef struct {
U8 len;
} DHCP_OPT, *PDHCP_OPT;
void dhcp_add_number_option(U8 *pBegin, int opt, U8 value, U8 nSize);
void dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize);
int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal);
void dhcp_option_cfg_init();
#ifdef __cplusplus

View File

@ -6,6 +6,8 @@
#define VCPE_IP_POOL_H
#include <uthash/uthash.h>
#include <common.h>
#include <bitset/bitset.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -18,7 +20,7 @@ extern "C" {
#define MAX_POOL_HASH_KEY (18)
typedef struct {
S8 poolKey[MAX_POOL_HASH_KEY];
U32 poolKey;
U32 minAddr;
U32 maxAddr;
U32 netMask;
@ -26,6 +28,7 @@ typedef struct {
U32 primeDNS;
U32 salveDNS;
U32 leaseTime;
bitset_t *assignPool;
UT_hash_handle hh;
} IPPOOL_INFO, *PIPPOOL_INFO;

View File

@ -7,6 +7,7 @@
#include <uthash/uthash.h>
#include <linux/if_ether.h>
#include <common.h>
#include "ip_pool.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -24,6 +25,8 @@ typedef struct {
U32 express;
} LEASE_CACHE, *PLEASE_CACHE;
int dhcp_lease_init();
int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool);
#ifdef __cplusplus
}
#endif

View File

@ -20,8 +20,9 @@ typedef struct {
UT_hash_handle hh;
} DHCP_USER_INFO, *PDHCP_USER_INFO;
int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool);
int dhcp_user_mgr_init();
int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool);
int dhcp_user_mgr_init();
PIPPOOL_INFO user_get_pool(U32 uId);
#ifdef HTTPSERVER_ON
int user_init_httpd();
#endif

View File

@ -8,8 +8,7 @@
#include "user_errno.h"
#include "zlog_module.h"
#include "user_mgr.h"
#define GEN_IP_POOL_HASH_KEY(p) (sprintf((p)->poolKey, "%08X-%08X", (p)->minAddr, (p)->maxAddr))
#include "ipaddr.h"
static PIPPOOL_INFO g_defPool = NULL;
@ -34,6 +33,8 @@ void init_default_pool() {
continue;
}
memset(p, 0, sizeof(IPPOOL_INFO));
if (strlen(pRange->rangAddr) == 0) {
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Error ip pool configure of address\n");
free(p);
@ -61,7 +62,7 @@ void init_default_pool() {
free(p);
continue;
} else {
p->minAddr = addr.s_addr;
p->minAddr = ntohl(addr.s_addr);
}
if (inet_aton(pSecIp, &addr) == 0) {
@ -69,30 +70,48 @@ void init_default_pool() {
free(p);
continue;
} else {
p->maxAddr = addr.s_addr;
p->maxAddr = ntohl(addr.s_addr);
}
// 填充POOL Hash Key
GEN_IP_POOL_HASH_KEY(p);
} else {
LOG_MOD(error, ZLOG_MOD_DHCPD, "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, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->subnet);
} else {
p->netMask = ntohl(addr.s_addr);
}
} else {
// 当前网络默认IP地址池
if (inet_aton("255.255.255.0", &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->subnet);
} else {
p->netMask = ntohl(addr.s_addr);
}
}
// 填充POOL Hash Key
p->poolKey = ipv4_get_network_addr(p->minAddr, p->netMask);
p->assignPool = bitset_create_with_capacity(ipv4_network_total_addr(p->netMask));
if (!p->assignPool) {
LOG_MOD(error,
ZLOG_MOD_DHCPD,
"Create address pool bitset ERROR: 0x%08X total address %u\n",
htonl(p->netMask),
ipv4_network_total_addr(p->netMask));
free(p);
continue;
}
if (strlen(pRange->gateway) > 0) {
if (inet_aton(pRange->gateway, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->gateway);
} else {
p->gwAddr = addr.s_addr;
}
}
if (strlen(pRange->subnet) > 0) {
if (inet_aton(pRange->subnet, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s\n", pRange->subnet);
} else {
p->netMask = addr.s_addr;
p->gwAddr = ntohl(addr.s_addr);
}
}
@ -109,19 +128,19 @@ void init_default_pool() {
if (inet_aton(tmpStr, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else {
p->primeDNS = addr.s_addr;
p->primeDNS = ntohl(addr.s_addr);
}
if (inet_aton(pSecIp, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr);
} else {
p->salveDNS = addr.s_addr;
p->salveDNS = ntohl(addr.s_addr);
}
} else {
if (inet_aton(pRange->dnsSvr, &addr) == 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
} else {
p->primeDNS = addr.s_addr;
p->primeDNS = ntohl(addr.s_addr);
}
}
}

View File

@ -2,7 +2,162 @@
// 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"
static PMAC_FILTER g_allowTbl = NULL;
static PMAC_FILTER g_blackListTbl = NULL;
#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;
}

View File

@ -176,6 +176,7 @@ int user_init_httpd() {
return ERR_SUCCESS;
}
// endregion
#endif
@ -196,7 +197,30 @@ int user_alloc_addr(U32 uId, U8 mac[ETH_ALEN], U32 *pAddr) {
return ERR_SUCCESS;
}
PIPPOOL_INFO user_get_pool(U32 uId) {
PDHCP_USER_INFO pUser;
HASH_FIND_INT(g_dhcpUsrCfg, &uId, pUser);
if (pUser == NULL) {
U32 id = 0;
HASH_FIND_INT(g_dhcpUsrCfg, &id, pUser);
if (pUser == NULL) {
return NULL;
}
return pUser->pPoolMgr;
}
return NULL;
}
int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool) {
U32 k;
U32 begin;
U32 end;
PIPPOOL_INFO pPoolCfg;
PDHCP_USER_INFO pUserCfg, pTemp;
@ -207,15 +231,24 @@ int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool) {
return ERR_SUCCESS;
}
HASH_FIND_STR(pUserCfg->pPoolMgr, pPool->poolKey, pPoolCfg);
HASH_FIND_INT(pUserCfg->pPoolMgr, &pPool->poolKey, pPoolCfg);
// 改地址池已经存在,提示错误
if (pPoolCfg != NULL) {
return -ERR_ITEM_EXISTS;
free(pPool);
} else {
// 添加新地址池当前用户配置项中
HASH_ADD_INT(pUserCfg->pPoolMgr, poolKey, pPool);
pPoolCfg = pPool;
}
// 添加到当前用户配置项中
HASH_ADD_STR(pUserCfg->pPoolMgr, poolKey, pPool);
// 计算可用的IP
begin = ntohl(pPoolCfg->minAddr) & ntohl(~pPoolCfg->netMask);
end = ntohl(pPoolCfg->maxAddr) & ntohl(~pPoolCfg->netMask);
for (k = MAX(begin, 1U); k <= MIN(end, ntohl(~pPoolCfg->netMask) - 1); k++) {
bitset_set(pPoolCfg->assignPool, k);
}
return ERR_SUCCESS;
}