OCT 1. DHCP 测试工具增加NACK处理

2. DHCP 测试工具完善测试流程和统计信息
This commit is contained in:
黄昕 2023-05-10 15:58:37 +08:00
parent 6d59ecacfa
commit 312880d1ea
5 changed files with 115 additions and 72 deletions

View File

@ -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]);

View File

@ -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;

View File

@ -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++;
}
}

View File

@ -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;
}
}

View File

@ -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;
}