From 312880d1eadd3ec450dd479098de4e185d698892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=98=95?= Date: Wed, 10 May 2023 15:58:37 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=20DHCP=20=E6=B5=8B=E8=AF=95=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=A2=9E=E5=8A=A0NACK=E5=A4=84=E7=90=86=202.=20DHCP?= =?UTF-8?q?=20=E6=B5=8B=E8=AF=95=E5=B7=A5=E5=85=B7=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=B5=81=E7=A8=8B=E5=92=8C=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dhcp_tools/detail_wnd.c | 9 +- dhcp_tools/main.h | 2 + dhcp_tools/main_wnd.c | 167 ++++++++++++++++++----------- dhcp_tools/uv_rawsocket.c | 8 +- srcs/service/dhcpd/dhcpd_network.c | 1 + 5 files changed, 115 insertions(+), 72 deletions(-) diff --git a/dhcp_tools/detail_wnd.c b/dhcp_tools/detail_wnd.c index 0b6305f..b653af6 100644 --- a/dhcp_tools/detail_wnd.c +++ b/dhcp_tools/detail_wnd.c @@ -318,6 +318,7 @@ static gboolean upgrade_statusbar_proc(gpointer user_data) { } } + sprintf(buf, "Offer %d.%03ds | ACK %d.%03ds | ip: %s | netmask: %s | gateway: %s | dns1: %s | dns2: %s |", tmOffer / 1000000, (tmOffer % 1000000) / 1000, tmAck / 1000000, (tmAck % 1000000) / 1000, SAFETY_STR_STRING(pIp, ""), SAFETY_STR_STRING(pNetmask, ""), SAFETY_STR_STRING(pGw, ""), @@ -354,7 +355,6 @@ void details_wnd_show(PDHCP_INFO pInfo) { GtkTextIter iter, iter1; if (pInfo) { - if (pInfo != g_preInfo) { g_preInfo = pInfo; @@ -428,7 +428,6 @@ void details_wnd_show(PDHCP_INFO pInfo) { upgrade_statusbar_proc(pInfo); } - upgrade_statusbar_proc(NULL); gtk_widget_show_all(g_detailWnd); } @@ -466,8 +465,8 @@ static gboolean button_release_event(GtkWidget *self, GdkEventButton UNUSED(even //printf("Select at(%d, %d), %d, %d, %d of %d\n", row, col, k, (k + 1) / 3, id, g_curPage); memcpy(valBuf, &g_HexBuf[g_curPage]->p[id], MIN(8, g_HexBuf[g_curPage]->buf_size - id)); - printf("%d, %d, %s, %s\n", valBuf[0] >> 4, valBuf[0] & 0x0F, binTbl[(valBuf[0] >> 4) & 0xF], - binTbl[valBuf[0] & 0x0F]); +// printf("%d, %d, %s, %s\n", valBuf[0] >> 4, valBuf[0] & 0x0F, binTbl[(valBuf[0] >> 4) & 0xF], +// binTbl[valBuf[0] & 0x0F]); sprintf(s, "%s%s", binTbl[(valBuf[0] >> 4) & 0xF], binTbl[valBuf[0] & 0x0F]); gtk_list_store_append(store, &it); @@ -548,7 +547,7 @@ void details_wnd_create(GtkBuilder *builder) { for (int i = 0; i < 4; i++) { GtkTreeIter iter; - const char *pTabName[] = {"Discover", "Offer", "Request", "Ack"}; + const char *pTabName[] = {"Discover", "Offer", "Request", "ACK/NACK"}; // 第一个页面 GtkWidget *label = gtk_label_new(pTabName[i]); diff --git a/dhcp_tools/main.h b/dhcp_tools/main.h index 39aaa7a..4a72ce9 100644 --- a/dhcp_tools/main.h +++ b/dhcp_tools/main.h @@ -51,6 +51,7 @@ typedef enum { STA_WAIT_START = 0, STA_SEND_REQ, STA_RECV_RSP, + STA_RECV_NACK, STA_ERROR } DHCP_STATUS; @@ -75,6 +76,7 @@ typedef struct { DHCP_RSP offerRsp; DHCP_RSP ackRsp; S8 treeId[32]; + U8 close; UT_hash_handle hh; } DHCP_INFO, *PDHCP_INFO; diff --git a/dhcp_tools/main_wnd.c b/dhcp_tools/main_wnd.c index 46b58ca..e1c81fb 100644 --- a/dhcp_tools/main_wnd.c +++ b/dhcp_tools/main_wnd.c @@ -11,8 +11,9 @@ #include "dhcp_network.h" #include "dhcp_options.h" #include "ipaddr.h" +#include "zvector/zvector.h" -#define DHCP_STEP_TIMEOUT (5) +#define DHCP_STEP_TIMEOUT (30) #define DHCP_PKG_RETRY (3) #define MAIN_WND_WIDTH (1024) @@ -24,10 +25,9 @@ static GtkBuilder *g_mainBuilder = NULL; static PDHCP_INFO g_pDhcpInfo = NULL; static GThread *g_pEvLoopThread = NULL; static int g_runTask = FALSE; -static U32 g_totalTask = 0; -static U32 g_finshTask = 0; -static U32 g_errTask = 0; static U32 g_endTask = 0; +static c_vector g_pFinishTask = NULL; +static c_vector g_pErrTask = NULL; static struct timeval g_StartTm; const char *dhcp_step_to_string(DHCP_STEP step) { @@ -259,13 +259,13 @@ static void tree_view_data_store_create() { gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, - &iter, - COL_INDEX, idx, - COL_RESULT, "", - COL_STATUS, calc_total_progress(pInfo), - COL_ATTR_EDITABLE, FALSE, - COL_ATTR_VISIABLE, FALSE, - -1); + &iter, + COL_INDEX, idx, + COL_RESULT, "", + COL_STATUS, calc_total_progress(pInfo), + COL_ATTR_EDITABLE, FALSE, + COL_ATTR_VISIABLE, FALSE, + -1); // clang-format on isCreateRoot = TRUE; } @@ -277,19 +277,19 @@ static void tree_view_data_store_create() { memset(idx, 0, 64); sprintf(idx, "%u", pInfo->index); gtk_tree_store_set(store, - &iter_child, - COL_INDEX, idx, - COL_MAC, mac, - COL_HOSTNAME, pInfo->hostname, - COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), - COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), - COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), - COL_ACK, calc_step_progress(pInfo, STEP_ACK), - COL_RESULT, "", - COL_STATUS, calc_total_progress(pInfo), - COL_ATTR_EDITABLE, FALSE, - COL_ATTR_VISIABLE, TRUE, - -1); + &iter_child, + COL_INDEX, idx, + COL_MAC, mac, + COL_HOSTNAME, pInfo->hostname, + COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), + COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), + COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), + COL_ACK, calc_step_progress(pInfo, STEP_ACK), + COL_RESULT, "", + COL_STATUS, calc_total_progress(pInfo), + COL_ATTR_EDITABLE, FALSE, + COL_ATTR_VISIABLE, TRUE, + -1); // clang-format on memset(pInfo->treeId, 0, 32); sprintf(pInfo->treeId, "%d:%d", i, j++); @@ -355,11 +355,12 @@ static void tree_view_data_store_create() { } static gboolean upgrade_status_bar_msg(gpointer UNUSED(pInfo)) { + int tolTask = HASH_COUNT(g_pDhcpInfo); char buf[1024] = {0}; static S32 tmdiff = 0; GtkWidget *statusBar = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "labMsg")); GtkWidget *prgBar = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "prgTotal")); - double percnt = g_errTask + g_finshTask; + double percnt = vect_size(g_pErrTask) + vect_size(g_pFinishTask); if (g_runTask) { struct timeval tvNow; @@ -367,54 +368,61 @@ static gboolean upgrade_status_bar_msg(gpointer UNUSED(pInfo)) { tmdiff = MAX(0, (tvNow.tv_sec * 1000000 + tvNow.tv_usec) - (g_StartTm.tv_sec * 1000000 + g_StartTm.tv_usec)); } - sprintf(buf, "Statistics: total %d | successed %d | error %d | total time %d.%03d(seconds)", g_totalTask, - MIN(g_finshTask, g_totalTask), g_errTask, tmdiff / 1000000, (tmdiff % 1000000) / 1000); + sprintf(buf, "Statistics: total %d | successed %d | error %d | total time %d.%03d(seconds)", tolTask, + MIN(vect_size(g_pFinishTask), tolTask), vect_size(g_pErrTask), tmdiff / 1000000, (tmdiff % 1000000) / 1000); gtk_label_set_text(GTK_LABEL(statusBar), buf); - if (g_totalTask > 0) { - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prgBar), percnt / g_totalTask); + if (tolTask > 0) { + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prgBar), percnt / tolTask); } else { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prgBar), 0.0); } - return TRUE; + return FALSE; } -static gboolean tree_view_data_store_upgade(gpointer pInfo) { +static gboolean upgade_task(gpointer pInfo) { + return FALSE; +} + +static void tree_view_data_store_upgade(gpointer pInfo) { GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkTreeModel *model; + PDHCP_INFO p = (PDHCP_INFO)pInfo; if (!pInfo || !store || !g_runTask) { - return FALSE; + return; } model = GTK_TREE_MODEL(store); - if (model && gtk_tree_model_get_iter_from_string(model, &iter, ((PDHCP_INFO)pInfo)->treeId)) { + if (model && gtk_tree_model_get_iter_from_string(model, &iter, p->treeId)) { char info[256] = {0}; - get_task_result(pInfo, info, 256); + get_task_result(p, info, 256); + // clang-format off gtk_tree_store_set(store, &iter, - COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), - COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), - COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), - COL_ACK, calc_step_progress(pInfo, STEP_ACK), - COL_RESULT, info, - COL_STATUS, calc_total_progress(pInfo), - COL_ATTR_EDITABLE, FALSE, - COL_ATTR_VISIABLE, TRUE, + COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), + COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), + COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), + COL_ACK, calc_step_progress(pInfo, STEP_ACK), + COL_RESULT, info, + COL_STATUS, calc_total_progress(pInfo), + COL_ATTR_EDITABLE, FALSE, + COL_ATTR_VISIABLE, TRUE, -1); // clang-format on - if (strlen(info) > 0) { + if (strlen(info) > 0 && p->close == FALSE) { + p->close = TRUE; g_endTask++; } } - if (g_finshTask + g_errTask == g_totalTask && g_endTask >= g_totalTask) { + if (g_endTask == HASH_COUNT(g_pDhcpInfo)) { GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); GtkWidget *stoptButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); @@ -426,10 +434,9 @@ static gboolean tree_view_data_store_upgade(gpointer pInfo) { gtk_widget_set_sensitive(nicSelect, TRUE); g_object_set(G_OBJECT(tbExpand), "stock_id", "gtk-indent", NULL); upgrade_status_bar_msg(NULL); - ADD_LOG_MSG(ZLOG_LEVEL_INFO, 0, " Finish test, successed %d, error %d\n", g_finshTask, g_errTask); + ADD_LOG_MSG(ZLOG_LEVEL_INFO, 0, "Finish test, successed %d, error %d\n", vect_size(g_pFinishTask), + vect_size(g_pErrTask)); } - - return TRUE; } static void mainWnd_on_destroy(GObject *UNUSED(object), gpointer UNUSED(user_data)) { @@ -472,8 +479,6 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { continue; } - g_idle_add(upgrade_status_bar_msg, NULL); - HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { switch (pInfo->step) { case STEP_BEGIN: @@ -483,7 +488,7 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->pDiscBuf.buf_size = size; pInfo->step = STEP_DISCOVER; pInfo->status = STA_WAIT_START; - g_idle_add(tree_view_data_store_upgade, pInfo); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); } break; case STEP_DISCOVER: @@ -497,7 +502,8 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pDiscBuf.tm, NULL); pInfo->pDiscBuf.snd += 1; - g_idle_add(tree_view_data_store_upgade, pInfo); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, + tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host send DHCP Discover\n", pInfo->vni, pInfo->hostname); } @@ -515,12 +521,19 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->vni, pInfo->hostname, pInfo->pDiscBuf.snd); } else { pInfo->status = STA_ERROR; - g_errTask++; + vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); ADD_LOG_MSG(ZLOG_LEVEL_ERROR, 1, "User %u host receive DHCP Offer error, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pDiscBuf.snd); } } + } else if (pInfo->status == STA_RECV_NACK) { + pInfo->status = STA_ERROR; + vect_push(g_pErrTask, &pInfo->index); + g_idle_add(upgrade_status_bar_msg, NULL); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); + ADD_LOG_MSG(ZLOG_LEVEL_ERROR, 1, "User %u host receive DHCP NACK error, retry %d\n", pInfo->vni, + pInfo->hostname, pInfo->pDiscBuf.snd); } break; case STEP_OFFER: @@ -530,7 +543,7 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->pReqBuf.buf_size = size; pInfo->step = STEP_REQUEST; pInfo->status = STA_WAIT_START; - g_idle_add(tree_view_data_store_upgade, pInfo); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host receive DHCP Offer information\n", pInfo->vni, pInfo->hostname); } @@ -547,7 +560,8 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pReqBuf.tm, NULL); pInfo->pReqBuf.snd += 1; - g_idle_add(tree_view_data_store_upgade, pInfo); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, + tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host send DHCP Request\n", pInfo->vni, pInfo->hostname); } @@ -565,22 +579,35 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } else { pInfo->status = STA_ERROR; - g_errTask++; + vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, + tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP ACK timeout, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } } + } else if (pInfo->status == STA_RECV_NACK) { + pInfo->status = STA_ERROR; + vect_push(g_pErrTask, &pInfo->index); + g_idle_add(upgrade_status_bar_msg, NULL); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); + ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP NACK timeout, retry %d\n", + pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } break; case STEP_ACK: - pInfo->step = STEP_END; - g_finshTask++; - g_idle_add(upgrade_status_bar_msg, NULL); - ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host receive DHCP ACK, finished.\n", pInfo->vni, - pInfo->hostname); + if (pInfo->status == STA_RECV_RSP) { + pInfo->step = STEP_END; + pInfo->status = STA_RECV_RSP; + vect_push(g_pFinishTask, &pInfo->index); + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); + g_idle_add(upgrade_status_bar_msg, NULL); + ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host receive DHCP ACK, finished.\n", pInfo->vni, + pInfo->hostname); + } break; - case STEP_END: + default: break; } } @@ -637,13 +664,24 @@ static void mainWnd_on_tb_start(GObject *object, gpointer UNUSED(user_data)) { U32 nVni = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); U32 nVniCnt = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numVniCli)); - g_totalTask = g_finshTask = g_errTask = g_endTask = 0; - string_mac_to_bytes(strMacBegin, mac); macVal = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; cleanupDHCPInfo(); + g_endTask = 0; + + if (g_pFinishTask) { + vect_clear(g_pFinishTask); + } + + if (g_pErrTask) { + vect_clear(g_pErrTask); + } + + g_pFinishTask = vect_create(nRequest * nVniCnt, sizeof(U32), ZV_SEC_WIPE); + g_pErrTask = vect_create(nRequest * nVniCnt, sizeof(U32), ZV_SEC_WIPE); + for (i = 0; i < nRequest; i++) { for (j = 0; j < nVniCnt; j++) { U32 macAddr = macVal + index; @@ -667,10 +705,9 @@ static void mainWnd_on_tb_start(GObject *object, gpointer UNUSED(user_data)) { sprintf(pInfo->hostname, "%s_%u", strPreHostname, pInfo->vni + index); pInfo->step = STEP_BEGIN; pInfo->status = STA_WAIT_START; - + pInfo->close = FALSE; HASH_ADD_INT(g_pDhcpInfo, index, pInfo); index++; - g_totalTask++; } } diff --git a/dhcp_tools/uv_rawsocket.c b/dhcp_tools/uv_rawsocket.c index be5aecf..3a2df91 100644 --- a/dhcp_tools/uv_rawsocket.c +++ b/dhcp_tools/uv_rawsocket.c @@ -77,11 +77,11 @@ static void cacl_package_checksum(PDHCP_PACKAGE p, int tolSize) { p->hdr.udp.len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr)); // 计算 IP 校验和 - csum = htons(ip_checksum((unsigned char *)&p->hdr.ip)); + csum = htons(ip_checksum((unsigned char *)&p->hdr.ip)); p->hdr.ip.check = htons(csum); // 计算 UDP 校验和 - csum = htons(udp_checksum(p->hdr.ip.saddr, p->hdr.ip.daddr, (unsigned char *)&p->hdr.udp)); + csum = htons(udp_checksum(p->hdr.ip.saddr, p->hdr.ip.daddr, (unsigned char *)&p->hdr.udp)); p->hdr.udp.check = htons(csum); } @@ -249,6 +249,10 @@ static void on_dhcp_recv(uv_work_t *req) { gettimeofday(&pInfo->pAckBuf.tm, NULL); break; case DHCP_MSG_NAK: + pInfo->status = STA_RECV_NACK; + cacheDhcpAckBuffer(pInfo, pWork->pPkgBase, pWork->nSize); + memcpy(&pInfo->ackRsp, &rspDhcp, sizeof(DHCP_RSP)); + gettimeofday(&pInfo->pAckBuf.tm, NULL); break; } } diff --git a/srcs/service/dhcpd/dhcpd_network.c b/srcs/service/dhcpd/dhcpd_network.c index 07d104e..4759492 100644 --- a/srcs/service/dhcpd/dhcpd_network.c +++ b/srcs/service/dhcpd/dhcpd_network.c @@ -412,6 +412,7 @@ static void on_sock_recv(uv_work_t *req) { // Check op flag if (pkg->dhcp.op != BOOTP_REQUEST) { LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->dhcp.op); + LOG_MSG_HEX(error, pkg, pWork->nSize); return; }