OCT 1. 支持DHCP OPTION60选项检测IPTV设备
2. 增加查询IPTV设备接口 3. 修正部分接口报错是内存泄漏问题
This commit is contained in:
parent
470921dde3
commit
c3be7eafe2
|
@ -158,7 +158,7 @@ const data4 opData[] = {
|
||||||
{"DHCPMaxMsgSize", 57, 5, false},
|
{"DHCPMaxMsgSize", 57, 5, false},
|
||||||
{"RenewalTime", 58, 4, true },
|
{"RenewalTime", 58, 4, true },
|
||||||
{"RebindingTime", 59, 4, true },
|
{"RebindingTime", 59, 4, true },
|
||||||
{"ClassId", 60, 1, false},
|
{"ClassId", 60, 1, true },
|
||||||
{"ClientId", 61, 2, false},
|
{"ClientId", 61, 2, false},
|
||||||
{"NetWareIPDomain", 62, 1, true },
|
{"NetWareIPDomain", 62, 1, true },
|
||||||
{"NetWareIPOption", 63, 2, true },
|
{"NetWareIPOption", 63, 2, true },
|
||||||
|
@ -5195,6 +5195,11 @@ MYWORD gdmess(data9 *req, MYBYTE sockInd) {
|
||||||
|
|
||||||
case DHCP_OPTION_VENDORCLASSID:
|
case DHCP_OPTION_VENDORCLASSID:
|
||||||
memcpy(&req->vendClass, op, op->size + 2);
|
memcpy(&req->vendClass, op, op->size + 2);
|
||||||
|
if (op->size > 16) {
|
||||||
|
if (process_iptv_multicast(op->value, op->size, req->chaddr) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCP_OPTION_USERCLASS:
|
case DHCP_OPTION_USERCLASS:
|
||||||
|
|
|
@ -643,6 +643,7 @@ void opendhcp_init_http_server();
|
||||||
void opendhcp_set_replication_svr();
|
void opendhcp_set_replication_svr();
|
||||||
void opendhcp_add_ip_pool_set();
|
void opendhcp_add_ip_pool_set();
|
||||||
void opendhcp_add_mac_filter();
|
void opendhcp_add_mac_filter();
|
||||||
|
int process_iptv_multicast(const unsigned char *p, int size, const char *mac);
|
||||||
int opendhcp_add_listener();
|
int opendhcp_add_listener();
|
||||||
unsigned int opendhcp_set_lease_time();
|
unsigned int opendhcp_set_lease_time();
|
||||||
void sendUserList(data19 *req, const char *pRequest, dhcpMap *dhcpCache, data2 *cfig, time_t t);
|
void sendUserList(data19 *req, const char *pRequest, dhcpMap *dhcpCache, data2 *cfig, time_t t);
|
||||||
|
|
|
@ -20,6 +20,7 @@ using namespace std;
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
#include <libconfig.h>
|
#include <libconfig.h>
|
||||||
#include <zlog.h>
|
#include <zlog.h>
|
||||||
|
#include <uv.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "user_errno.h"
|
#include "user_errno.h"
|
||||||
|
@ -32,6 +33,17 @@ extern dhcpMap dhcpCache;
|
||||||
extern time_t t;
|
extern time_t t;
|
||||||
extern data71 lump;
|
extern data71 lump;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char iptvMAC[64];
|
||||||
|
unsigned int vni;
|
||||||
|
int isReport;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
} IPTV_DEV_SET, *PIPTV_DEV_SET;
|
||||||
|
|
||||||
|
static PIPTV_DEV_SET g_iptvNewDevs = nullptr;
|
||||||
|
static PIPTV_DEV_SET g_iptvCacheDevs = nullptr;
|
||||||
|
static uv_rwlock_t g_uvCacheLock;
|
||||||
|
|
||||||
static int dhcp_get_user_info(data19 *req, const char *pRequest) {
|
static int dhcp_get_user_info(data19 *req, const char *pRequest) {
|
||||||
char logBuff[512];
|
char logBuff[512];
|
||||||
const char *pStrContent;
|
const char *pStrContent;
|
||||||
|
@ -133,6 +145,47 @@ static int dhcp_get_user_info(data19 *req, const char *pRequest) {
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dchp_get_all_iptv_devs(data19 *req) {
|
||||||
|
char logBuff[512];
|
||||||
|
PIPTV_DEV_SET pDev, pTemp;
|
||||||
|
|
||||||
|
cJSON *pRspMsg = cJSON_CreateObject();
|
||||||
|
cJSON *pMsgArray = cJSON_CreateArray();
|
||||||
|
|
||||||
|
cJSON_AddItemToObject(pRspMsg, "iptvDevs", pMsgArray);
|
||||||
|
|
||||||
|
uv_rwlock_wrlock(&g_uvCacheLock);
|
||||||
|
HASH_ITER(hh, g_iptvCacheDevs, pDev, pTemp) {
|
||||||
|
cJSON *pRspItem = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(pRspItem, "mac", pDev->iptvMAC);
|
||||||
|
cJSON_AddNumberToObject(pRspItem, "vni", pDev->vni);
|
||||||
|
cJSON_AddBoolToObject(pRspItem, "reported", pDev->isReport);
|
||||||
|
cJSON_AddItemToArray(pMsgArray, pRspItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
HASH_ITER(hh, g_iptvNewDevs, pDev, pTemp) {
|
||||||
|
cJSON *pRspItem = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(pRspItem, "mac", pDev->iptvMAC);
|
||||||
|
cJSON_AddNumberToObject(pRspItem, "vni", pDev->vni);
|
||||||
|
cJSON_AddBoolToObject(pRspItem, "reported", pDev->isReport);
|
||||||
|
cJSON_AddItemToArray(pMsgArray, pRspItem);
|
||||||
|
}
|
||||||
|
uv_rwlock_wrunlock(&g_uvCacheLock);
|
||||||
|
|
||||||
|
cJSON_AddNumberToObject(pRspMsg, "status", ERR_SUCCESS);
|
||||||
|
cJSON_AddStringToObject(pRspMsg, "message", getErrorEnumDesc(ERR_SUCCESS));
|
||||||
|
|
||||||
|
const char *pStrPro = proto_create_new(pRspMsg, 200);
|
||||||
|
|
||||||
|
req->memSize = (int)strlen(pStrPro);
|
||||||
|
req->dp = strdup(pStrPro);
|
||||||
|
req->bytes = (int)strlen(pStrPro);
|
||||||
|
|
||||||
|
free((void *)pStrPro);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int dhcp_get_all_user(data19 *req) {
|
static int dhcp_get_all_user(data19 *req) {
|
||||||
char logBuff[512];
|
char logBuff[512];
|
||||||
data7 *dhcpEntry;
|
data7 *dhcpEntry;
|
||||||
|
@ -524,7 +577,7 @@ static int delete_dhcpd_rangeset(data19 *req, const char *pRequest) {
|
||||||
//输入参数不存在的情况
|
//输入参数不存在的情况
|
||||||
if (resCount > cfig.rangeCount - cJSON_GetArraySize(pdhcp_range)) {
|
if (resCount > cfig.rangeCount - cJSON_GetArraySize(pdhcp_range)) {
|
||||||
cJSON *pdel_Item = cJSON_CreateObject();
|
cJSON *pdel_Item = cJSON_CreateObject();
|
||||||
hash_map *s = (struct hash_map *)malloc(sizeof(struct hash_map));
|
auto *s = (struct hash_map *)malloc(sizeof(struct hash_map));
|
||||||
hash_map *tmp;
|
hash_map *tmp;
|
||||||
char saddr[128];
|
char saddr[128];
|
||||||
char eaddr[128];
|
char eaddr[128];
|
||||||
|
@ -775,6 +828,7 @@ static void opendhcp_http_info(http_request *request, hw_http_response *response
|
||||||
|
|
||||||
if (request->method != HW_HTTP_GET) {
|
if (request->method != HW_HTTP_GET) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +873,7 @@ static void opendhcp_http_get_userinfo(http_request *request, hw_http_response *
|
||||||
|
|
||||||
if (request->method != HW_HTTP_POST) {
|
if (request->method != HW_HTTP_POST) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,6 +887,7 @@ static void opendhcp_http_get_userinfo(http_request *request, hw_http_response *
|
||||||
ret = dhcp_get_user_info(req, request->body->value);
|
ret = dhcp_get_user_info(req, request->body->value);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SETSTRING(body, req->dp);
|
SETSTRING(body, req->dp);
|
||||||
|
@ -866,6 +922,7 @@ static void opendhcp_http_get_alluser(http_request *request, hw_http_response *r
|
||||||
|
|
||||||
if (request->method != HW_HTTP_GET) {
|
if (request->method != HW_HTTP_GET) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,6 +936,7 @@ static void opendhcp_http_get_alluser(http_request *request, hw_http_response *r
|
||||||
ret = dhcp_get_all_user(req);
|
ret = dhcp_get_all_user(req);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SETSTRING(body, req->dp);
|
SETSTRING(body, req->dp);
|
||||||
|
@ -913,6 +971,7 @@ static void opendhcp_http_add_rangeset(http_request *request, hw_http_response *
|
||||||
|
|
||||||
if (request->method != HW_HTTP_POST) {
|
if (request->method != HW_HTTP_POST) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,6 +984,7 @@ static void opendhcp_http_add_rangeset(http_request *request, hw_http_response *
|
||||||
ret = add_dhcpd_rangeset(req, request->body->value);
|
ret = add_dhcpd_rangeset(req, request->body->value);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,6 +1020,7 @@ static void opendhcp_http_delete_rangeset(http_request *request, hw_http_respons
|
||||||
|
|
||||||
if (request->method != HW_HTTP_POST) {
|
if (request->method != HW_HTTP_POST) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,6 +1033,7 @@ static void opendhcp_http_delete_rangeset(http_request *request, hw_http_respons
|
||||||
ret = delete_dhcpd_rangeset(req, request->body->value);
|
ret = delete_dhcpd_rangeset(req, request->body->value);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,6 +1052,55 @@ static void opendhcp_http_delete_rangeset(http_request *request, hw_http_respons
|
||||||
hw_http_response_send(response, req, response_complete);
|
hw_http_response_send(response, req, response_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void opendhcp_http_query_iptv_devs(http_request *request, hw_http_response *response, void *UNUSED(user_data)) {
|
||||||
|
hw_string status_code;
|
||||||
|
hw_string content_type_name;
|
||||||
|
hw_string content_type_value;
|
||||||
|
hw_string body;
|
||||||
|
hw_string keep_alive_name;
|
||||||
|
hw_string keep_alive_value;
|
||||||
|
int ret;
|
||||||
|
auto *req = (data19 *)malloc(sizeof(struct data19));
|
||||||
|
|
||||||
|
if (req == nullptr) {
|
||||||
|
proto_response_error(response, 500, HTTP_STATUS_500, ERR_MALLOC_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->method != HW_HTTP_GET) {
|
||||||
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
response_complete(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(req, 0, sizeof(struct data19));
|
||||||
|
|
||||||
|
SETSTRING(content_type_name, "Content-Type");
|
||||||
|
SETSTRING(content_type_value, "application/json");
|
||||||
|
hw_set_response_header(response, &content_type_name, &content_type_value);
|
||||||
|
|
||||||
|
SETSTRING(status_code, HTTP_STATUS_200);
|
||||||
|
ret = dchp_get_all_iptv_devs(req);
|
||||||
|
if (ret != ERR_SUCCESS) {
|
||||||
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
response_complete(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SETSTRING(body, req->dp);
|
||||||
|
hw_set_body(response, &body);
|
||||||
|
hw_set_response_status_code(response, &status_code);
|
||||||
|
|
||||||
|
if (request->keep_alive) {
|
||||||
|
SETSTRING(keep_alive_name, "Connection");
|
||||||
|
SETSTRING(keep_alive_value, "close");
|
||||||
|
hw_set_response_header(response, &keep_alive_name, &keep_alive_value);
|
||||||
|
} else {
|
||||||
|
hw_set_http_version(response, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hw_http_response_send(response, req, response_complete);
|
||||||
|
}
|
||||||
|
|
||||||
static void opendhcp_http_query_rangeset(http_request *request, hw_http_response *response, void *UNUSED(user_data)) {
|
static void opendhcp_http_query_rangeset(http_request *request, hw_http_response *response, void *UNUSED(user_data)) {
|
||||||
hw_string status_code;
|
hw_string status_code;
|
||||||
hw_string content_type_name;
|
hw_string content_type_name;
|
||||||
|
@ -1007,6 +1118,7 @@ static void opendhcp_http_query_rangeset(http_request *request, hw_http_response
|
||||||
|
|
||||||
if (request->method != HW_HTTP_GET) {
|
if (request->method != HW_HTTP_GET) {
|
||||||
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
proto_response_error(response, 405, HTTP_STATUS_405, ERR_HTTP_UNSUP_METHOD);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,6 +1131,7 @@ static void opendhcp_http_query_rangeset(http_request *request, hw_http_response
|
||||||
ret = query_dhcpd_rangeset(req);
|
ret = query_dhcpd_rangeset(req);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
proto_response_error(response, 500, HTTP_STATUS_500, ret);
|
||||||
|
free(req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,11 +1173,40 @@ int opendhcp_add_listener() {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iptvCacheCb(void *UNUSED(pArg)) {
|
||||||
|
do {
|
||||||
|
PIPTV_DEV_SET pDev, pTmp = nullptr;
|
||||||
|
uv_rwlock_wrlock(&g_uvCacheLock);
|
||||||
|
HASH_ITER(hh, g_iptvNewDevs, pDev, pTmp) {
|
||||||
|
PIPTV_DEV_SET pTemp;
|
||||||
|
const char *pDevMac = strdup(pDev->iptvMAC);
|
||||||
|
HASH_FIND_STR(g_iptvCacheDevs, pDevMac, pTemp);
|
||||||
|
// 新发现设备没有被上报过
|
||||||
|
if (!pTemp) {
|
||||||
|
auto pCacheDev = (PIPTV_DEV_SET)malloc(sizeof(IPTV_DEV_SET));
|
||||||
|
memcpy(pCacheDev, pDev, sizeof(IPTV_DEV_SET));
|
||||||
|
// Report new IPTV device MAC
|
||||||
|
pCacheDev->isReport = 1;
|
||||||
|
// 添加到缓存列表供后续查询
|
||||||
|
HASH_ADD_STR(g_iptvCacheDevs, iptvMAC, pCacheDev);
|
||||||
|
dzlog_debug("Add IPTV device %s vni %d to cache\n", pCacheDev->iptvMAC, pCacheDev->vni);
|
||||||
|
}
|
||||||
|
|
||||||
|
HASH_DEL(g_iptvNewDevs, pDev);
|
||||||
|
free(pDev);
|
||||||
|
free((void *)pDevMac);
|
||||||
|
}
|
||||||
|
uv_rwlock_wrunlock(&g_uvCacheLock);
|
||||||
|
uv_sleep(10);
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加 DHCP Server HTTP服务接口
|
* 增加 DHCP Server HTTP服务接口
|
||||||
*/
|
*/
|
||||||
void opendhcp_init_http_server() {
|
void opendhcp_init_http_server() {
|
||||||
static int added = FALSE;
|
static int added = FALSE;
|
||||||
|
static uv_thread_t uvThread;
|
||||||
|
|
||||||
if (!added) {
|
if (!added) {
|
||||||
hw_http_add_route("/", opendhcp_http_info, nullptr);
|
hw_http_add_route("/", opendhcp_http_info, nullptr);
|
||||||
|
@ -1073,6 +1215,11 @@ void opendhcp_init_http_server() {
|
||||||
hw_http_add_route("dhcp/config/rangeset", opendhcp_http_add_rangeset, nullptr);
|
hw_http_add_route("dhcp/config/rangeset", opendhcp_http_add_rangeset, nullptr);
|
||||||
hw_http_add_route("dhcp/delete/rangeset", opendhcp_http_delete_rangeset, nullptr);
|
hw_http_add_route("dhcp/delete/rangeset", opendhcp_http_delete_rangeset, nullptr);
|
||||||
hw_http_add_route("dhcp/query/rangeset", opendhcp_http_query_rangeset, nullptr);
|
hw_http_add_route("dhcp/query/rangeset", opendhcp_http_query_rangeset, nullptr);
|
||||||
|
hw_http_add_route("dhcp/query/iptvdevice", opendhcp_http_query_iptv_devs, nullptr);
|
||||||
|
|
||||||
|
uv_rwlock_init(&g_uvCacheLock);
|
||||||
|
uv_thread_create(&uvThread, iptvCacheCb, nullptr);
|
||||||
|
|
||||||
added = TRUE;
|
added = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1106,6 +1253,35 @@ void opendhcp_add_ip_pool_set() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int process_iptv_multicast(const unsigned char *p, int size, const char *mac) {
|
||||||
|
char ipTvId[16] = {0};
|
||||||
|
memcpy(ipTvId, &p[4], 10);
|
||||||
|
|
||||||
|
if (strcmp(ipTvId, "JSCMCC-OTT") == 0) {
|
||||||
|
PIPTV_DEV_SET pTmp;
|
||||||
|
HASH_FIND_STR(g_iptvNewDevs, mac, pTmp);
|
||||||
|
if (!pTmp) {
|
||||||
|
auto pDev = (PIPTV_DEV_SET)malloc(sizeof(IPTV_DEV_SET));
|
||||||
|
|
||||||
|
if (pDev) {
|
||||||
|
memset(pDev, 0, sizeof(IPTV_DEV_SET));
|
||||||
|
|
||||||
|
strcpy(pDev->iptvMAC, mac);
|
||||||
|
pDev->vni = 0;
|
||||||
|
pDev->isReport = 0;
|
||||||
|
uv_rwlock_wrlock(&g_uvCacheLock);
|
||||||
|
HASH_ADD_STR(g_iptvNewDevs, iptvMAC, pDev);
|
||||||
|
uv_rwlock_wrunlock(&g_uvCacheLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dzlog_debug("Found IPTV %s\n", mac);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加MAC地址黑名单
|
* 增加MAC地址黑名单
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue