Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion back/services/grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class GrpcServerService {
const grpcPort = config.grpcPort;
const bindAsync = promisify(this.server.bindAsync).bind(this.server);
await bindAsync(
`0.0.0.0:${grpcPort}`,
`[::]:${grpcPort}`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

⚠️ gRPC 绑定到 [::]:port 同样可能在部分环境下不再接受 IPv4,建议增加回退/可配置绑定地址

与 HTTP 类似,gRPC 绑定到 [::]:port 是否同时接受 IPv4 取决于运行环境的 dual-stack 行为。当前仅尝试 IPv6 绑定,若环境不支持 IPv6 会直接抛错;若环境为 v6-only,也可能导致 IPv4 客户端无法连接。

建议: 建议优先尝试 [::]:port,失败则回退到 0.0.0.0:port;或增加配置项允许显式指定 bind address,并在日志中打印实际绑定地址,便于排障。

Suggested change
`[::]:${grpcPort}`,
const grpcPort = config.grpcPort;
const bindAsync = promisify(this.server.bindAsync).bind(this.server);
try {
await bindAsync(
`[::]:${grpcPort}`,
ServerCredentials.createInsecure(),
);
} catch (err) {
Logger.error('Failed to bind gRPC service on IPv6, falling back to IPv4:', err);
await bindAsync(
`0.0.0.0:${grpcPort}`,
ServerCredentials.createInsecure(),
);
}
Logger.debug(`✌️ gRPC service started successfully`);

ServerCredentials.createInsecure(),
);
Logger.debug(`✌️ gRPC service started successfully`);
Expand Down
2 changes: 1 addition & 1 deletion back/services/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class HttpServerService {
async initialize(expressApp: express.Application, port: number) {
try {
return new Promise((resolve, reject) => {
this.server = expressApp.listen(port, '0.0.0.0', () => {
this.server = expressApp.listen(port, '::', () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

⚠️ 仅绑定到 :: 可能在部分环境下不再接受 IPv4(取决于 OS 的 dual-stack 配置)

在不少现代 Linux 上,绑定到 :: 会通过 IPv4-mapped IPv6 支持 IPv4;但在某些系统/配置(如 sysctl net.ipv6.bindv6only=1、部分容器/发行版默认行为、或 Windows 的差异行为)下,绑定到 :: 可能只接受 IPv6,导致 IPv4 客户端无法访问。当前实现没有提供回退到 0.0.0.0 的逻辑,因此存在兼容性风险。

建议: 建议在绑定失败或检测到仅 IPv6 的环境时,增加一个明确的回退策略:优先尝试 '::',若监听错误(如 EADDRNOTAVAIL / EAFNOSUPPORT 等)则回退到 '0.0.0.0';或提供配置项允许用户选择绑定地址。

Suggested change
this.server = expressApp.listen(port, '::', () => {
async initialize(expressApp: express.Application, port: number) {
try {
return await new Promise((resolve, reject) => {
const start = (host: string, onError?: (err: any) => void) => {
this.server = expressApp.listen(port, host, () => {
Logger.debug(`✌️ HTTP service started successfully`);
metricsService.record('http_service_start', 1, {
port: port.toString(),
});
resolve(this.server);
});
this.server.on('error', (err: any) => {
if (onError) {
onError(err);
return;
}
Logger.error('Failed to start HTTP service:', err);
reject(err);
});
};
start('::', (err) => {
Logger.error('Failed to start HTTP service on IPv6, falling back to IPv4:', err);
start('0.0.0.0');
});
});
} catch (err) {
Logger.error('Failed to start HTTP service:', err);
throw err;
}
}

Logger.debug(`✌️ HTTP service started successfully`);
metricsService.record('http_service_start', 1, {
port: port.toString(),
Expand Down