Skip to content

Commit 9597e5c

Browse files
committedDec 22, 2024
fix: memory leak
1 parent 00f3b1c commit 9597e5c

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed
 

‎src/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { MinecraftProxy } from './proxy'
66
import { fromError } from 'zod-validation-error'
77
import { PluginLoader } from './plugins'
88
import { getGitCommitHash } from './macros/getGitCommitHash' with { type: 'macro' }
9-
import { generateHeapSnapshot } from 'bun'
9+
import { heapStats } from 'bun:jsc'
1010

1111
export type TransitLogger = Logger<'packet', boolean>
1212

@@ -31,6 +31,10 @@ async function main() {
3131
}),
3232
)
3333

34+
// setInterval(() => {
35+
// logger.info(heapStats())
36+
// }, 5000)
37+
3438
const minecraftProxy = new MinecraftProxy()
3539

3640
logger.info(`Transit Proxy by Ikaleio (build: ${await getGitCommitHash()})`)

‎src/proxy.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ export type C2RSocketData = {
4747
originIP: IP | null // 客户端 IP 地址(若开启 ProxyProtocol 入站,从其中解析)
4848
proxyProtocol: boolean | null // 是否启用 Proxy Protocol v2 出站
4949
FML: 0 | 1 | 2 | null // 是否为 Forge Mod Loader (2) 客户端,0 代表非 FML
50+
timeouts: NodeJS.Timer[] // 存储所有的 timeout
5051
}
5152

5253
// Relay to server socket data
5354
type R2SSocketData = {
5455
client: Bun.Socket<C2RSocketData> | null // 客户端连接
5556
sendBuffer: ArrayBufferSink // 发送缓冲区
57+
timeouts: NodeJS.Timer[] // 存储所有的 timeout
5658
}
5759

5860
const writeToBuffer = (
@@ -77,6 +79,10 @@ const sendBuffer = (
7779
}
7880
}
7981

82+
const clearAllTimeouts = (timeouts: NodeJS.Timer[]) => {
83+
timeouts.forEach(timeout => clearTimeout(timeout))
84+
}
85+
8086
export const InboundSchema = z
8187
.object({
8288
bind: z.string().default('0.0.0.0:25565'),
@@ -142,6 +148,7 @@ export class MinecraftProxy {
142148
remoteSocket.data = {
143149
client: clientSocket,
144150
sendBuffer: new ArrayBufferSink(),
151+
timeouts: [],
145152
}
146153
remoteSocket.data.sendBuffer.start({
147154
asUint8Array: true,
@@ -162,6 +169,7 @@ export class MinecraftProxy {
162169
writeToBuffer(clientSocket.data.remote, initPacket)
163170
},
164171
close: remoteSocket => {
172+
remoteSocket.data.sendBuffer.end()
165173
clientSocket.end()
166174
},
167175
end: remoteSocket => {
@@ -229,6 +237,7 @@ export class MinecraftProxy {
229237
originIP: null,
230238
proxyProtocol: null,
231239
FML: null,
240+
timeouts: [],
232241
}
233242

234243
logger.debug(
@@ -246,16 +255,19 @@ export class MinecraftProxy {
246255
clientSocket.data.originIP = IP.parse(clientSocket.remoteAddress)
247256

248257
// 若 3 秒内未成功读取握手包,则断开连接
249-
setTimeout(() => {
258+
const handshakeTimeout = setTimeout(() => {
250259
if (clientSocket.data.state === null) {
251260
logger.warn(
252261
`${colorHash(clientSocket.data.connId)} Handshake timeout`,
253262
)
254263
clientSocket.end()
255264
}
256265
}, 3000)
266+
clientSocket.data.timeouts.push(handshakeTimeout)
257267
},
258268
close: async clientSocket => {
269+
clientSocket.data.sendBuffer.end()
270+
clearAllTimeouts(clientSocket.data.timeouts)
259271
if (clientSocket.data.username) {
260272
this.onlinePlayers.delete(clientSocket.data.username)
261273
}
@@ -417,14 +429,15 @@ export class MinecraftProxy {
417429

418430
if (nextState === State.Login) {
419431
// 若 3 秒内未成功读取登录包,则断开连接
420-
setTimeout(() => {
432+
const loginTimeout = setTimeout(() => {
421433
if (clientSocket.data.state !== State.Play) {
422434
logger.warn(
423435
`${colorHash(clientSocket.data.connId)} Login timeout`,
424436
)
425437
clientSocket.end()
426438
}
427439
}, 3000)
440+
clientSocket.data.timeouts.push(loginTimeout)
428441
}
429442
}
430443
} // 考虑一次发送两个数据包,应当直接在后面处理登录

0 commit comments

Comments
 (0)
Please sign in to comment.