Skip to content

Commit fa3c231

Browse files
authored
Merge pull request #600 from mfncooper/fix_agwpe_cleanup
Clean up AGWPE connection data upon termination
2 parents 23022d0 + c317511 commit fa3c231

File tree

1 file changed

+144
-64
lines changed

1 file changed

+144
-64
lines changed

src/ax25_link.c

Lines changed: 144 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This file is part of Dire Wolf, an amateur radio packet TNC.
33
//
4-
// Copyright (C) 2016, 2017, 2018, 2023, 2024 John Langner, WB2OSZ
4+
// Copyright (C) 2016, 2017, 2018, 2023, 2024, 2025 John Langner, WB2OSZ
55
//
66
// This program is free software: you can redistribute it and/or modify
77
// it under the terms of the GNU General Public License as published by
@@ -599,6 +599,8 @@ static int AX25MODULO(int n, int m, const char *file, const char *func, int line
599599
// TODO: add SELECT_T1_VALUE for debugging.
600600

601601

602+
static void dl_connection_cleanup (ax25_dlsm_t *S);
603+
static void dl_connection_terminated (ax25_dlsm_t *S);
602604
static void dl_data_indication (ax25_dlsm_t *S, int pid, char *data, int len);
603605

604606
static void i_frame (ax25_dlsm_t *S, cmdres_t cr, int p, int nr, int ns, int pid, char *info_ptr, int info_len);
@@ -1101,6 +1103,7 @@ void dl_disconnect_request (dlq_item_t *E)
11011103
text_color_set(DW_COLOR_INFO);
11021104
dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
11031105
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
1106+
dl_connection_terminated (S);
11041107
break;
11051108

11061109
case state_1_awaiting_connection:
@@ -1129,6 +1132,7 @@ void dl_disconnect_request (dlq_item_t *E)
11291132
STOP_T3; // probably don't need.
11301133
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
11311134
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
1135+
dl_connection_terminated (S);
11321136
break;
11331137

11341138
case state_2_awaiting_release:
@@ -1159,6 +1163,7 @@ void dl_disconnect_request (dlq_item_t *E)
11591163

11601164
STOP_T1;
11611165
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
1166+
dl_connection_terminated (S);
11621167
}
11631168
break;
11641169

@@ -1742,6 +1747,133 @@ void dl_outstanding_frames_request (dlq_item_t *E)
17421747

17431748

17441749

1750+
/*------------------------------------------------------------------------------
1751+
*
1752+
* Name: dl_connection_cleanup
1753+
*
1754+
* Purpose: Clean out a specific state machine and its references, freeing
1755+
* associated memory.
1756+
*
1757+
* Inputs: S - Data Link State Machine.
1758+
*
1759+
* Description: Clean out a specific state machine and anything related to it.
1760+
* Free the associated memory.
1761+
*
1762+
*------------------------------------------------------------------------------*/
1763+
1764+
static void dl_connection_cleanup (ax25_dlsm_t *S)
1765+
{
1766+
int n;
1767+
1768+
if (s_debug_stats) {
1769+
text_color_set(DW_COLOR_INFO);
1770+
dw_printf ("%d I frames received\n", S->count_recv_frame_type[frame_type_I]);
1771+
1772+
dw_printf ("%d RR frames received\n", S->count_recv_frame_type[frame_type_S_RR]);
1773+
dw_printf ("%d RNR frames received\n", S->count_recv_frame_type[frame_type_S_RNR]);
1774+
dw_printf ("%d REJ frames received\n", S->count_recv_frame_type[frame_type_S_REJ]);
1775+
dw_printf ("%d SREJ frames received\n", S->count_recv_frame_type[frame_type_S_SREJ]);
1776+
1777+
dw_printf ("%d SABME frames received\n", S->count_recv_frame_type[frame_type_U_SABME]);
1778+
dw_printf ("%d SABM frames received\n", S->count_recv_frame_type[frame_type_U_SABM]);
1779+
dw_printf ("%d DISC frames received\n", S->count_recv_frame_type[frame_type_U_DISC]);
1780+
dw_printf ("%d DM frames received\n", S->count_recv_frame_type[frame_type_U_DM]);
1781+
dw_printf ("%d UA frames received\n", S->count_recv_frame_type[frame_type_U_UA]);
1782+
dw_printf ("%d FRMR frames received\n", S->count_recv_frame_type[frame_type_U_FRMR]);
1783+
dw_printf ("%d UI frames received\n", S->count_recv_frame_type[frame_type_U_UI]);
1784+
dw_printf ("%d XID frames received\n", S->count_recv_frame_type[frame_type_U_XID]);
1785+
dw_printf ("%d TEST frames received\n", S->count_recv_frame_type[frame_type_U_TEST]);
1786+
1787+
dw_printf ("%d peak retry count\n", S->peak_rc_value);
1788+
}
1789+
1790+
if (s_debug_client_app) {
1791+
text_color_set(DW_COLOR_DEBUG);
1792+
dw_printf ("dl_connection_cleanup: remove %s>%s\n", S->addrs[AX25_SOURCE], S->addrs[AX25_DESTINATION]);
1793+
}
1794+
1795+
discard_i_queue (S);
1796+
1797+
for (n = 0; n < 128; n++) {
1798+
if (S->txdata_by_ns[n] != NULL) {
1799+
cdata_delete (S->txdata_by_ns[n]);
1800+
S->txdata_by_ns[n] = NULL;
1801+
}
1802+
}
1803+
1804+
for (n = 0; n < 128; n++) {
1805+
if (S->rxdata_by_ns[n] != NULL) {
1806+
cdata_delete (S->rxdata_by_ns[n]);
1807+
S->rxdata_by_ns[n] = NULL;
1808+
}
1809+
}
1810+
1811+
if (S->ra_buff != NULL) {
1812+
cdata_delete (S->ra_buff);
1813+
S->ra_buff = NULL;
1814+
}
1815+
1816+
// Put into disconnected state.
1817+
// If "connected" indicator (e.g. LED) was on, this will turn it off.
1818+
1819+
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
1820+
1821+
S->magic1 = 0;
1822+
S->magic2 = 0;
1823+
S->magic3 = 0;
1824+
1825+
free (S);
1826+
1827+
} /* end dl_connection_cleanup */
1828+
1829+
1830+
1831+
/*------------------------------------------------------------------------------
1832+
*
1833+
* Name: dl_connection_terminated
1834+
*
1835+
* Purpose: Connection has gone away. Clean up any data associated with it.
1836+
*
1837+
* Inputs: S - Data Link State Machine.
1838+
*
1839+
* Description: Clean out anything related to the specified connection, and
1840+
* remove the associated state machine from the list.
1841+
*
1842+
*------------------------------------------------------------------------------*/
1843+
1844+
static void dl_connection_terminated (ax25_dlsm_t *S)
1845+
{
1846+
ax25_dlsm_t *dlentry;
1847+
ax25_dlsm_t *dlprev;
1848+
1849+
// Look for corruption or double freeing.
1850+
1851+
assert (S->magic1 == MAGIC1);
1852+
assert (S->magic2 == MAGIC2);
1853+
assert (S->magic3 == MAGIC3);
1854+
1855+
// Remove from the list.
1856+
1857+
dlprev = NULL;
1858+
dlentry = list_head;
1859+
while (dlentry != S) {
1860+
dlprev = dlentry;
1861+
dlentry = dlentry->next;
1862+
}
1863+
if (!dlprev) {
1864+
list_head = dlentry->next;
1865+
} else {
1866+
dlprev->next = dlentry->next;
1867+
}
1868+
1869+
// Clean up the connection.
1870+
1871+
dl_connection_cleanup(S);
1872+
1873+
} /* end dl_connection_terminated */
1874+
1875+
1876+
17451877
/*------------------------------------------------------------------------------
17461878
*
17471879
* Name: dl_client_cleanup
@@ -1785,76 +1917,15 @@ void dl_client_cleanup (dlq_item_t *E)
17851917

17861918
if (S->client == E->client ) {
17871919

1788-
int n;
1789-
1790-
if (s_debug_stats) {
1791-
text_color_set(DW_COLOR_INFO);
1792-
dw_printf ("%d I frames received\n", S->count_recv_frame_type[frame_type_I]);
1793-
1794-
dw_printf ("%d RR frames received\n", S->count_recv_frame_type[frame_type_S_RR]);
1795-
dw_printf ("%d RNR frames received\n", S->count_recv_frame_type[frame_type_S_RNR]);
1796-
dw_printf ("%d REJ frames received\n", S->count_recv_frame_type[frame_type_S_REJ]);
1797-
dw_printf ("%d SREJ frames received\n", S->count_recv_frame_type[frame_type_S_SREJ]);
1798-
1799-
dw_printf ("%d SABME frames received\n", S->count_recv_frame_type[frame_type_U_SABME]);
1800-
dw_printf ("%d SABM frames received\n", S->count_recv_frame_type[frame_type_U_SABM]);
1801-
dw_printf ("%d DISC frames received\n", S->count_recv_frame_type[frame_type_U_DISC]);
1802-
dw_printf ("%d DM frames received\n", S->count_recv_frame_type[frame_type_U_DM]);
1803-
dw_printf ("%d UA frames received\n", S->count_recv_frame_type[frame_type_U_UA]);
1804-
dw_printf ("%d FRMR frames received\n", S->count_recv_frame_type[frame_type_U_FRMR]);
1805-
dw_printf ("%d UI frames received\n", S->count_recv_frame_type[frame_type_U_UI]);
1806-
dw_printf ("%d XID frames received\n", S->count_recv_frame_type[frame_type_U_XID]);
1807-
dw_printf ("%d TEST frames received\n", S->count_recv_frame_type[frame_type_U_TEST]);
1808-
1809-
dw_printf ("%d peak retry count\n", S->peak_rc_value);
1810-
}
1811-
1812-
if (s_debug_client_app) {
1813-
text_color_set(DW_COLOR_DEBUG);
1814-
dw_printf ("dl_client_cleanup: remove %s>%s\n", S->addrs[AX25_SOURCE], S->addrs[AX25_DESTINATION]);
1815-
}
1816-
1817-
discard_i_queue (S);
1818-
1819-
for (n = 0; n < 128; n++) {
1820-
if (S->txdata_by_ns[n] != NULL) {
1821-
cdata_delete (S->txdata_by_ns[n]);
1822-
S->txdata_by_ns[n] = NULL;
1823-
}
1824-
}
1825-
1826-
for (n = 0; n < 128; n++) {
1827-
if (S->rxdata_by_ns[n] != NULL) {
1828-
cdata_delete (S->rxdata_by_ns[n]);
1829-
S->rxdata_by_ns[n] = NULL;
1830-
}
1831-
}
1832-
1833-
if (S->ra_buff != NULL) {
1834-
cdata_delete (S->ra_buff);
1835-
S->ra_buff = NULL;
1836-
}
1837-
1838-
// Put into disconnected state.
1839-
// If "connected" indicator (e.g. LED) was on, this will turn it off.
1840-
1841-
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
1842-
1843-
// Take S out of list.
1844-
1845-
S->magic1 = 0;
1846-
S->magic2 = 0;
1847-
S->magic3 = 0;
1848-
18491920
if (S == list_head) { // first one on list.
18501921

18511922
list_head = S->next;
1852-
free (S);
1923+
dl_connection_cleanup (S);
18531924
S = list_head;
18541925
}
18551926
else { // not the first one.
18561927
dlprev->next = S->next;
1857-
free (S);
1928+
dl_connection_cleanup (S);
18581929
S = dlprev->next;
18591930
}
18601931
}
@@ -4504,6 +4575,7 @@ static void disc_frame (ax25_dlsm_t *S, int p)
45044575
STOP_T1;
45054576
STOP_T3;
45064577
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4578+
dl_connection_terminated (S);
45074579
}
45084580
break;
45094581
}
@@ -4591,6 +4663,7 @@ static void dm_frame (ax25_dlsm_t *S, int f)
45914663
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
45924664
STOP_T1;
45934665
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4666+
dl_connection_terminated (S);
45944667
}
45954668
else {
45964669
// keep current state.
@@ -4613,6 +4686,7 @@ static void dm_frame (ax25_dlsm_t *S, int f)
46134686
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
46144687
STOP_T1;
46154688
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4689+
dl_connection_terminated (S);
46164690
}
46174691
else {
46184692
// keep current state.
@@ -4634,6 +4708,7 @@ static void dm_frame (ax25_dlsm_t *S, int f)
46344708
STOP_T1;
46354709
STOP_T3;
46364710
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4711+
dl_connection_terminated (S);
46374712
break;
46384713

46394714
case state_5_awaiting_v22_connection:
@@ -4651,6 +4726,7 @@ static void dm_frame (ax25_dlsm_t *S, int f)
46514726
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
46524727
STOP_T1;
46534728
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4729+
dl_connection_terminated (S);
46544730
}
46554731
else {
46564732
// keep current state.
@@ -4858,6 +4934,7 @@ static void ua_frame (ax25_dlsm_t *S, int f)
48584934
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
48594935
STOP_T1;
48604936
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
4937+
dl_connection_terminated (S);
48614938
}
48624939
else {
48634940
if (s_debug_protocol_errors) {
@@ -5374,6 +5451,7 @@ static void t1_expiry (ax25_dlsm_t *S)
53745451
dw_printf ("Failed to connect to %s after %d tries.\n", S->addrs[PEERCALL], S->n2_retry);
53755452
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 1);
53765453
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5454+
dl_connection_terminated (S);
53775455
}
53785456
else {
53795457
cmdres_t cmd = cr_cmd;
@@ -5400,6 +5478,7 @@ static void t1_expiry (ax25_dlsm_t *S)
54005478
dw_printf ("Stream %d: Disconnected from %s.\n", S->stream_id, S->addrs[PEERCALL]);
54015479
server_link_terminated (S->chan, S->client, S->addrs[PEERCALL], S->addrs[OWNCALL], 0);
54025480
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5481+
dl_connection_terminated (S);
54035482
}
54045483
else {
54055484
cmdres_t cmd = cr_cmd;
@@ -5473,6 +5552,7 @@ static void t1_expiry (ax25_dlsm_t *S)
54735552
lm_data_request (S->chan, TQ_PRIO_1_LO, pp);
54745553

54755554
enter_new_state (S, state_0_disconnected, __func__, __LINE__);
5555+
dl_connection_terminated (S);
54765556
}
54775557
else {
54785558
SET_RC(S->rc+1);

0 commit comments

Comments
 (0)