Skip to content

Commit 236d742

Browse files
sharpenteethGitTensor Minerautofix-ci[bot]
authored
fix: improve RADIUS client error handling and socket cleanup (#6783)
Co-authored-by: GitTensor Miner <miner@gittensor.io> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent a38c6de commit 236d742

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

server/radius-client.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,47 @@ class RadiusClient {
6767
let attempts = 0;
6868
let responseReceived = false;
6969
let timeoutHandle;
70+
let socketClosed = false;
71+
72+
/**
73+
* Safely close socket and clear timeout
74+
* @returns {void}
75+
*/
76+
const cleanup = () => {
77+
if (timeoutHandle) {
78+
clearTimeout(timeoutHandle);
79+
timeoutHandle = null;
80+
}
81+
if (!socketClosed) {
82+
socketClosed = true;
83+
try {
84+
socket.close();
85+
} catch (err) {
86+
// Ignore errors during cleanup
87+
}
88+
}
89+
};
7090

7191
/**
7292
* Send RADIUS request with retry logic
7393
* @returns {void}
7494
*/
7595
const sendRequest = () => {
96+
if (responseReceived || socketClosed) {
97+
return;
98+
}
99+
76100
attempts++;
77101

78102
socket.send(encodedPacket, 0, encodedPacket.length, this.port, this.host, (err) => {
79103
if (err) {
80-
socket.close();
104+
cleanup();
81105
return reject(new Error(`Failed to send RADIUS request: ${err.message}`));
82106
}
83107

84108
// Set timeout for this attempt
85109
timeoutHandle = setTimeout(() => {
86-
if (responseReceived) {
110+
if (responseReceived || socketClosed) {
87111
return;
88112
}
89113

@@ -92,7 +116,7 @@ class RadiusClient {
92116
sendRequest();
93117
} else {
94118
// All retries exhausted
95-
socket.close();
119+
cleanup();
96120
reject(new Error(`RADIUS request timeout after ${attempts} attempts`));
97121
}
98122
}, this.timeout);
@@ -101,23 +125,20 @@ class RadiusClient {
101125

102126
// Handle response
103127
socket.on("message", (msg) => {
104-
if (responseReceived) {
128+
if (responseReceived || socketClosed) {
105129
return;
106130
}
107131

108132
responseReceived = true;
109-
clearTimeout(timeoutHandle);
133+
cleanup();
110134

111135
let response;
112136
try {
113137
response = radius.decode({ packet: msg, secret: secret });
114138
} catch (error) {
115-
socket.close();
116139
return reject(new Error(`RADIUS response decoding failed: ${error.message}`));
117140
}
118141

119-
socket.close();
120-
121142
// Map response code to match node-radius-client format
122143
const responseCode = response.code;
123144

@@ -140,10 +161,9 @@ class RadiusClient {
140161

141162
// Handle socket errors
142163
socket.on("error", (err) => {
143-
if (!responseReceived) {
164+
if (!responseReceived && !socketClosed) {
144165
responseReceived = true;
145-
clearTimeout(timeoutHandle);
146-
socket.close();
166+
cleanup();
147167
reject(new Error(`RADIUS socket error: ${err.message}`));
148168
}
149169
});

server/util-server.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,20 @@ exports.radius = function (
356356
],
357357
})
358358
.catch((error) => {
359+
// Preserve error stack trace and provide better context
359360
if (error.response?.code) {
360-
throw Error(error.response.code);
361+
const radiusError = new Error(`RADIUS ${error.response.code} from ${hostname}:${port}`);
362+
radiusError.response = error.response;
363+
radiusError.originalError = error;
364+
throw radiusError;
361365
} else {
362-
throw Error(error.message);
366+
// Preserve original error message and stack trace
367+
const enhancedError = new Error(
368+
`RADIUS authentication failed for ${hostname}:${port}: ${error.message}`
369+
);
370+
enhancedError.originalError = error;
371+
enhancedError.stack = error.stack || enhancedError.stack;
372+
throw enhancedError;
363373
}
364374
});
365375
};

0 commit comments

Comments
 (0)