Skip to content

Commit 515ff2a

Browse files
committed
packet_plugin_rjv3: Read echo key in case of DHCP failures, ...
* `rjv3_process_result_prop()` does not get called if DHCP fails, and no echo key will be set. Heartbeat will fail with wrong echo key. * Duplicate the frame and parse it when DHCP fails to get the correct echo key. * Also fix error on older compilers.
1 parent 24534be commit 515ff2a

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

include/packet_plugin.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ typedef struct _packet_plugin {
8484
* Called by main program when the a standard EAP(oL) frame is ready
8585
* to be sent.
8686
* The frame will be sent immediately when this function returns.
87-
* Can be used to append proprietary fields or change target address, etc.
87+
* Can be used to append proprietary fields or change destination address, etc.
8888
* This is where all the magic happens!
8989
*
90+
* You may need to check if we are in proxy mode and go different routines.
91+
*
9092
* Return: if the operation completed successfully
9193
*/
9294
RESULT (*prepare_frame)(struct _packet_plugin* this, ETH_EAP_FRAME* frame);
@@ -95,6 +97,8 @@ typedef struct _packet_plugin {
9597
* Called by main program on arrival of new frames.
9698
* Can be used to read proprietary fields and update internal state.
9799
*
100+
* You may need to check if we are in proxy mode and go different routines.
101+
*
98102
* Return: if the frame is processed successfully
99103
*/
100104
RESULT (*on_frame_received)(struct _packet_plugin* this, ETH_EAP_FRAME* frame);

packet_plugin/rjv3/packet_plugin_rjv3.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "sched_alarm.h"
1111
#include "config.h"
1212
#include "conf_parser.h"
13+
#include "packet_util.h"
1314

1415
#include <arpa/inet.h>
1516
#include <getopt.h>
@@ -216,7 +217,17 @@ static RESULT rjv3_process_success(struct _packet_plugin* this, ETH_EAP_FRAME* f
216217

217218
if (PRIV->dhcp_type == DHCP_DOUBLE_AUTH) {
218219
if (PRIV->succ_count < 2) {
220+
/* This requires fine-grained control of authentication progress,
221+
* so we can not use the logic of --auth-round.
222+
*/
219223
PR_INFO("首次认证成功,正在执行 DHCP 脚本以准备第二次认证");
224+
225+
/*
226+
* PRIV->last_recv_packet == `frame`, but `frame` will be freed
227+
* once the state transition is finished. We need to keep it
228+
* in case DHCP fails and we need to start heartbeating.
229+
*/
230+
PRIV->last_recv_packet = frame_duplicate(frame);
220231
system((get_program_config())->run_on_success); // TODO move this to plugin
221232

222233
/* Try right after the script ends */
@@ -292,7 +303,8 @@ static void rjv3_save_one_prop(void* prop, void* is_mod) {
292303
curr_pos += 2;
293304
*curr_pos++ = ':';
294305

295-
for (int i = 0; i < PROP_TO_CONTENT_SIZE(TO_RJ_PROP(prop)); i++) {
306+
int i;
307+
for (i = 0; i < PROP_TO_CONTENT_SIZE(TO_RJ_PROP(prop)); i++) {
296308
hex2char(TO_RJ_PROP(prop)->content[i], curr_pos);
297309
curr_pos += 2;
298310
}

packet_plugin/rjv3/packet_plugin_rjv3_priv.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,14 @@ static RESULT rjv3_override_priv_header(struct _packet_plugin* this) {
254254
if (IS_FAIL(obtain_iface_ip_mask(_ifname, &_ip_list))
255255
|| (_ipv4 = find_ip_with_family(_ip_list, AF_INET)) == NULL) {
256256

257-
PR_ERR("IPv4 地址获取错误,将不能在数据包中展示 IPv4 地址");
257+
PR_ERR("IPv4 地址获取错误");
258258
goto fail;
259259
}
260260

261261
IP_ADDR _gw;
262262
_gw.family = AF_INET;
263263
if (IS_FAIL(obtain_iface_ipv4_gateway(_ifname, _gw.ip))) {
264-
PR_ERR("IPv4 网关获取错误,将不能在数据包中展示 IPv4 网关地址");
264+
PR_ERR("IPv4 网关获取错误");
265265
goto fail;
266266
}
267267

@@ -480,7 +480,7 @@ RESULT rjv3_append_priv(struct _packet_plugin* this, ETH_EAP_FRAME* frame) {
480480
return SUCCESS;
481481
}
482482

483-
static int rjv3_find_echokey_prop(void* unused, void* prop) {
483+
static int rjv3_is_echokey_prop(void* unused, void* prop) {
484484
RJ_PROP* _prop = (RJ_PROP*)prop;
485485

486486
if (_prop->header2.type == 0x1 && PROP_TO_CONTENT_SIZE(_prop) != 0) {
@@ -526,7 +526,7 @@ RESULT rjv3_process_result_prop(ETH_EAP_FRAME* frame) {
526526
}
527527

528528
_msg = NULL;
529-
_msg = (RJ_PROP*)lookup_data(_srv_msg, NULL, rjv3_find_echokey_prop);
529+
_msg = (RJ_PROP*)lookup_data(_srv_msg, NULL, rjv3_is_echokey_prop);
530530
if (_msg == NULL) {
531531
PR_ERR("无法找到 echo key 的位置,将不能进行心跳");
532532
return FAILURE;
@@ -551,15 +551,18 @@ void rjv3_start_secondary_auth(void* vthis) {
551551
if (IS_FAIL(rjv3_override_priv_header(this))) {
552552
PRIV->dhcp_count++;
553553
if (PRIV->dhcp_count > PRIV->max_dhcp_count) {
554-
PR_ERR("无法获取 IP 地址等信息,将不会进行第二次认证");
554+
rjv3_process_result_prop(PRIV->last_recv_packet); // Loads of texts
555+
free_frame(&PRIV->last_recv_packet); // Duplicated in process_success
555556
schedule_alarm(1, rjv3_send_keepalive_timed, this);
557+
PR_ERR("无法获取 IPv4 地址等信息,将不会进行第二次认证而直接开始心跳");
556558
} else {
557559
PR_WARN("DHCP 可能尚未完成,将继续等待……");
558-
schedule_alarm(5, rjv3_start_secondary_auth, vthis);
560+
schedule_alarm(5, rjv3_start_secondary_auth, this);
559561
}
560562
return;
561563
} else {
562564
PR_INFO("DHCP 完成,正在开始第二次认证");
565+
free_frame(&PRIV->last_recv_packet); // Duplicated in process_success
563566
switch_to_state(EAP_STATE_START_SENT, NULL);
564567
return;
565568
}

0 commit comments

Comments
 (0)