2023-12-05 17:13:36 +00:00
|
|
|
const Protocols = {
|
|
|
|
|
Freedom: "freedom",
|
|
|
|
|
Blackhole: "blackhole",
|
|
|
|
|
DNS: "dns",
|
|
|
|
|
VMess: "vmess",
|
|
|
|
|
VLESS: "vless",
|
|
|
|
|
Trojan: "trojan",
|
|
|
|
|
Shadowsocks: "shadowsocks",
|
2025-09-10 10:19:09 +00:00
|
|
|
Socks: "socks",
|
2023-12-05 17:13:36 +00:00
|
|
|
HTTP: "http",
|
2026-01-18 16:13:34 +00:00
|
|
|
Wireguard: "wireguard",
|
|
|
|
|
Hysteria: "hysteria"
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const SSMethods = {
|
|
|
|
|
AES_256_GCM: 'aes-256-gcm',
|
|
|
|
|
AES_128_GCM: 'aes-128-gcm',
|
|
|
|
|
CHACHA20_POLY1305: 'chacha20-poly1305',
|
|
|
|
|
CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305',
|
|
|
|
|
XCHACHA20_POLY1305: 'xchacha20-poly1305',
|
|
|
|
|
XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305',
|
|
|
|
|
BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm',
|
|
|
|
|
BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm',
|
|
|
|
|
BLAKE3_CHACHA20_POLY1305: '2022-blake3-chacha20-poly1305',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const TLS_FLOW_CONTROL = {
|
|
|
|
|
VISION: "xtls-rprx-vision",
|
|
|
|
|
VISION_UDP443: "xtls-rprx-vision-udp443",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const UTLS_FINGERPRINT = {
|
|
|
|
|
UTLS_CHROME: "chrome",
|
|
|
|
|
UTLS_FIREFOX: "firefox",
|
|
|
|
|
UTLS_SAFARI: "safari",
|
|
|
|
|
UTLS_IOS: "ios",
|
|
|
|
|
UTLS_android: "android",
|
|
|
|
|
UTLS_EDGE: "edge",
|
|
|
|
|
UTLS_360: "360",
|
|
|
|
|
UTLS_QQ: "qq",
|
|
|
|
|
UTLS_RANDOM: "random",
|
|
|
|
|
UTLS_RANDOMIZED: "randomized",
|
2025-03-03 09:20:52 +00:00
|
|
|
UTLS_RONDOMIZEDNOALPN: "randomizednoalpn",
|
2024-12-17 22:12:40 +00:00
|
|
|
UTLS_UNSAFE: "unsafe",
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const ALPN_OPTION = {
|
|
|
|
|
H3: "h3",
|
|
|
|
|
H2: "h2",
|
|
|
|
|
HTTP1: "http/1.1",
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-10 12:44:18 +00:00
|
|
|
const OutboundDomainStrategies = [
|
2023-12-05 17:13:36 +00:00
|
|
|
"AsIs",
|
|
|
|
|
"UseIP",
|
|
|
|
|
"UseIPv4",
|
2024-03-11 08:08:25 +00:00
|
|
|
"UseIPv6",
|
|
|
|
|
"UseIPv6v4",
|
|
|
|
|
"UseIPv4v6",
|
|
|
|
|
"ForceIP",
|
|
|
|
|
"ForceIPv6v4",
|
|
|
|
|
"ForceIPv6",
|
|
|
|
|
"ForceIPv4v6",
|
|
|
|
|
"ForceIPv4"
|
2024-01-10 12:44:18 +00:00
|
|
|
];
|
2023-12-05 17:13:36 +00:00
|
|
|
|
2024-01-01 13:03:43 +00:00
|
|
|
const WireguardDomainStrategy = [
|
|
|
|
|
"ForceIP",
|
|
|
|
|
"ForceIPv4",
|
|
|
|
|
"ForceIPv4v6",
|
|
|
|
|
"ForceIPv6",
|
|
|
|
|
"ForceIPv6v4"
|
|
|
|
|
];
|
|
|
|
|
|
2024-08-10 22:47:44 +00:00
|
|
|
const USERS_SECURITY = {
|
|
|
|
|
AES_128_GCM: "aes-128-gcm",
|
|
|
|
|
CHACHA20_POLY1305: "chacha20-poly1305",
|
|
|
|
|
AUTO: "auto",
|
|
|
|
|
NONE: "none",
|
|
|
|
|
ZERO: "zero",
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-14 09:39:51 +00:00
|
|
|
const MODE_OPTION = {
|
|
|
|
|
AUTO: "auto",
|
|
|
|
|
PACKET_UP: "packet-up",
|
|
|
|
|
STREAM_UP: "stream-up",
|
2024-12-03 20:57:44 +00:00
|
|
|
STREAM_ONE: "stream-one",
|
2024-11-14 09:39:51 +00:00
|
|
|
};
|
|
|
|
|
|
2025-03-05 12:14:17 +00:00
|
|
|
const Address_Port_Strategy = {
|
|
|
|
|
NONE: "none",
|
|
|
|
|
SrvPortOnly: "srvportonly",
|
|
|
|
|
SrvAddressOnly: "srvaddressonly",
|
|
|
|
|
SrvPortAndAddress: "srvportandaddress",
|
|
|
|
|
TxtPortOnly: "txtportonly",
|
|
|
|
|
TxtAddressOnly: "txtaddressonly",
|
|
|
|
|
TxtPortAndAddress: "txtportandaddress"
|
|
|
|
|
};
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
Object.freeze(Protocols);
|
|
|
|
|
Object.freeze(SSMethods);
|
|
|
|
|
Object.freeze(TLS_FLOW_CONTROL);
|
2024-08-06 15:06:39 +00:00
|
|
|
Object.freeze(UTLS_FINGERPRINT);
|
2023-12-05 17:13:36 +00:00
|
|
|
Object.freeze(ALPN_OPTION);
|
2024-01-10 12:44:18 +00:00
|
|
|
Object.freeze(OutboundDomainStrategies);
|
2024-01-01 13:03:43 +00:00
|
|
|
Object.freeze(WireguardDomainStrategy);
|
2024-08-10 22:47:44 +00:00
|
|
|
Object.freeze(USERS_SECURITY);
|
2024-11-14 09:39:51 +00:00
|
|
|
Object.freeze(MODE_OPTION);
|
2025-03-05 12:14:17 +00:00
|
|
|
Object.freeze(Address_Port_Strategy);
|
2024-08-06 15:06:39 +00:00
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
class CommonClass {
|
|
|
|
|
|
|
|
|
|
static toJsonArray(arr) {
|
|
|
|
|
return arr.map(obj => obj.toJson());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson() {
|
|
|
|
|
return new CommonClass();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
toString(format = true) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TcpStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(type = 'none', host, path) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.type = type;
|
|
|
|
|
this.host = host;
|
|
|
|
|
this.path = path;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
let header = json.header;
|
|
|
|
|
if (!header) return new TcpStreamSettings();
|
2024-08-06 15:06:39 +00:00
|
|
|
if (header.type == 'http' && header.request) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new TcpStreamSettings(
|
|
|
|
|
header.type,
|
|
|
|
|
header.request.headers.Host.join(','),
|
|
|
|
|
header.request.path.join(','),
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-08-06 15:06:39 +00:00
|
|
|
return new TcpStreamSettings(header.type, '', '');
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
header: {
|
|
|
|
|
type: this.type,
|
|
|
|
|
request: this.type === 'http' ? {
|
|
|
|
|
headers: {
|
|
|
|
|
Host: ObjectUtil.isEmpty(this.host) ? [] : this.host.split(',')
|
|
|
|
|
},
|
|
|
|
|
path: ObjectUtil.isEmpty(this.path) ? ["/"] : this.path.split(',')
|
|
|
|
|
} : undefined,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class KcpStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
mtu = 1250,
|
|
|
|
|
tti = 50,
|
2024-08-06 15:06:39 +00:00
|
|
|
uplinkCapacity = 5,
|
|
|
|
|
downlinkCapacity = 20,
|
|
|
|
|
congestion = false,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
readBufferSize = 2,
|
|
|
|
|
writeBufferSize = 2,
|
|
|
|
|
type = 'none',
|
|
|
|
|
seed = '',
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.mtu = mtu;
|
|
|
|
|
this.tti = tti;
|
|
|
|
|
this.upCap = uplinkCapacity;
|
|
|
|
|
this.downCap = downlinkCapacity;
|
|
|
|
|
this.congestion = congestion;
|
|
|
|
|
this.readBuffer = readBufferSize;
|
|
|
|
|
this.writeBuffer = writeBufferSize;
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
this.type = type;
|
|
|
|
|
this.seed = seed;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new KcpStreamSettings(
|
|
|
|
|
json.mtu,
|
|
|
|
|
json.tti,
|
|
|
|
|
json.uplinkCapacity,
|
|
|
|
|
json.downlinkCapacity,
|
|
|
|
|
json.congestion,
|
|
|
|
|
json.readBufferSize,
|
|
|
|
|
json.writeBufferSize,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,
|
|
|
|
|
json.seed,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
mtu: this.mtu,
|
|
|
|
|
tti: this.tti,
|
|
|
|
|
uplinkCapacity: this.upCap,
|
|
|
|
|
downlinkCapacity: this.downCap,
|
|
|
|
|
congestion: this.congestion,
|
|
|
|
|
readBufferSize: this.readBuffer,
|
|
|
|
|
writeBufferSize: this.writeBuffer,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
header: {
|
|
|
|
|
type: this.type,
|
|
|
|
|
},
|
|
|
|
|
seed: this.seed,
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class WsStreamSettings extends CommonClass {
|
2024-12-03 21:07:58 +00:00
|
|
|
constructor(
|
2025-09-16 11:41:05 +00:00
|
|
|
path = '/',
|
2024-12-03 21:07:58 +00:00
|
|
|
host = '',
|
|
|
|
|
heartbeatPeriod = 0,
|
|
|
|
|
|
|
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.path = path;
|
|
|
|
|
this.host = host;
|
2024-12-03 21:07:58 +00:00
|
|
|
this.heartbeatPeriod = heartbeatPeriod;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new WsStreamSettings(
|
|
|
|
|
json.path,
|
2024-06-18 10:49:20 +00:00
|
|
|
json.host,
|
2024-12-03 21:07:58 +00:00
|
|
|
json.heartbeatPeriod,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
path: this.path,
|
2024-04-01 12:32:02 +00:00
|
|
|
host: this.host,
|
2024-12-03 21:07:58 +00:00
|
|
|
heartbeatPeriod: this.heartbeatPeriod
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GrpcStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
serviceName = "",
|
|
|
|
|
authority = "",
|
2025-03-09 05:37:50 +00:00
|
|
|
multiMode = false
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.serviceName = serviceName;
|
2024-03-12 17:15:33 +00:00
|
|
|
this.authority = authority;
|
2024-06-07 12:16:55 +00:00
|
|
|
this.multiMode = multiMode;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2025-03-09 05:37:50 +00:00
|
|
|
return new GrpcStreamSettings(json.serviceName, json.authority, json.multiMode);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
serviceName: this.serviceName,
|
2024-06-07 12:16:55 +00:00
|
|
|
authority: this.authority,
|
2025-03-09 05:37:50 +00:00
|
|
|
multiMode: this.multiMode
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-11 07:36:33 +00:00
|
|
|
class HttpUpgradeStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(path = '/', host = '') {
|
2024-03-11 07:36:33 +00:00
|
|
|
super();
|
|
|
|
|
this.path = path;
|
|
|
|
|
this.host = host;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-03-11 07:36:33 +00:00
|
|
|
return new HttpUpgradeStreamSettings(
|
|
|
|
|
json.path,
|
2024-06-18 10:49:20 +00:00
|
|
|
json.host,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
path: this.path,
|
|
|
|
|
host: this.host,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-03 21:24:34 +00:00
|
|
|
class xHTTPStreamSettings extends CommonClass {
|
2024-11-14 09:39:51 +00:00
|
|
|
constructor(
|
|
|
|
|
path = '/',
|
|
|
|
|
host = '',
|
|
|
|
|
mode = '',
|
2024-12-16 20:21:29 +00:00
|
|
|
noGRPCHeader = false,
|
|
|
|
|
scMinPostsIntervalMs = "30",
|
|
|
|
|
xmux = {
|
|
|
|
|
maxConcurrency: "16-32",
|
|
|
|
|
maxConnections: 0,
|
2025-01-01 17:48:47 +00:00
|
|
|
cMaxReuseTimes: 0,
|
|
|
|
|
hMaxRequestTimes: "600-900",
|
|
|
|
|
hMaxReusableSecs: "1800-3000",
|
2024-12-16 20:21:29 +00:00
|
|
|
hKeepAlivePeriod: 0,
|
|
|
|
|
},
|
2024-11-14 09:39:51 +00:00
|
|
|
) {
|
2024-06-18 10:49:20 +00:00
|
|
|
super();
|
|
|
|
|
this.path = path;
|
|
|
|
|
this.host = host;
|
2024-11-14 09:39:51 +00:00
|
|
|
this.mode = mode;
|
2024-12-16 20:21:29 +00:00
|
|
|
this.noGRPCHeader = noGRPCHeader;
|
|
|
|
|
this.scMinPostsIntervalMs = scMinPostsIntervalMs;
|
|
|
|
|
this.xmux = xmux;
|
2024-06-18 10:49:20 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-12-03 21:24:34 +00:00
|
|
|
return new xHTTPStreamSettings(
|
2024-06-18 10:49:20 +00:00
|
|
|
json.path,
|
|
|
|
|
json.host,
|
2024-11-14 09:39:51 +00:00
|
|
|
json.mode,
|
2024-12-16 20:21:29 +00:00
|
|
|
json.noGRPCHeader,
|
|
|
|
|
json.scMinPostsIntervalMs,
|
|
|
|
|
json.xmux
|
2024-03-11 07:36:33 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
path: this.path,
|
|
|
|
|
host: this.host,
|
2024-11-14 09:39:51 +00:00
|
|
|
mode: this.mode,
|
2024-12-16 20:21:29 +00:00
|
|
|
noGRPCHeader: this.noGRPCHeader,
|
|
|
|
|
scMinPostsIntervalMs: this.scMinPostsIntervalMs,
|
|
|
|
|
xmux: {
|
|
|
|
|
maxConcurrency: this.xmux.maxConcurrency,
|
|
|
|
|
maxConnections: this.xmux.maxConnections,
|
|
|
|
|
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
|
|
|
|
|
hMaxRequestTimes: this.xmux.hMaxRequestTimes,
|
2025-01-01 17:48:47 +00:00
|
|
|
hMaxReusableSecs: this.xmux.hMaxReusableSecs,
|
2024-12-16 20:21:29 +00:00
|
|
|
hKeepAlivePeriod: this.xmux.hKeepAlivePeriod,
|
|
|
|
|
},
|
2024-03-11 07:36:33 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
class TlsStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
serverName = '',
|
|
|
|
|
alpn = [],
|
|
|
|
|
fingerprint = '',
|
2025-08-04 14:27:57 +00:00
|
|
|
allowInsecure = false,
|
|
|
|
|
echConfigList = '',
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.serverName = serverName;
|
|
|
|
|
this.alpn = alpn;
|
|
|
|
|
this.fingerprint = fingerprint;
|
|
|
|
|
this.allowInsecure = allowInsecure;
|
2025-08-04 14:27:57 +00:00
|
|
|
this.echConfigList = echConfigList;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new TlsStreamSettings(
|
|
|
|
|
json.serverName,
|
|
|
|
|
json.alpn,
|
|
|
|
|
json.fingerprint,
|
|
|
|
|
json.allowInsecure,
|
2025-08-04 14:27:57 +00:00
|
|
|
json.echConfigList,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
serverName: this.serverName,
|
|
|
|
|
alpn: this.alpn,
|
|
|
|
|
fingerprint: this.fingerprint,
|
|
|
|
|
allowInsecure: this.allowInsecure,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
echConfigList: this.echConfigList
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class RealityStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
publicKey = '',
|
|
|
|
|
fingerprint = '',
|
|
|
|
|
serverName = '',
|
|
|
|
|
shortId = '',
|
2025-08-03 10:09:37 +00:00
|
|
|
spiderX = '',
|
|
|
|
|
mldsa65Verify = ''
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.publicKey = publicKey;
|
|
|
|
|
this.fingerprint = fingerprint;
|
|
|
|
|
this.serverName = serverName;
|
|
|
|
|
this.shortId = shortId
|
|
|
|
|
this.spiderX = spiderX;
|
2025-08-03 10:09:37 +00:00
|
|
|
this.mldsa65Verify = mldsa65Verify;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
return new RealityStreamSettings(
|
|
|
|
|
json.publicKey,
|
|
|
|
|
json.fingerprint,
|
|
|
|
|
json.serverName,
|
|
|
|
|
json.shortId,
|
|
|
|
|
json.spiderX,
|
2025-08-03 10:09:37 +00:00
|
|
|
json.mldsa65Verify
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
publicKey: this.publicKey,
|
|
|
|
|
fingerprint: this.fingerprint,
|
|
|
|
|
serverName: this.serverName,
|
|
|
|
|
shortId: this.shortId,
|
|
|
|
|
spiderX: this.spiderX,
|
2025-08-03 10:09:37 +00:00
|
|
|
mldsa65Verify: this.mldsa65Verify
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-01-18 16:13:34 +00:00
|
|
|
|
|
|
|
|
class HysteriaStreamSettings extends CommonClass {
|
|
|
|
|
constructor(
|
|
|
|
|
version = 2,
|
|
|
|
|
auth = '',
|
2026-01-18 16:38:05 +00:00
|
|
|
congestion = '',
|
2026-01-18 16:13:34 +00:00
|
|
|
up = '0',
|
|
|
|
|
down = '0',
|
|
|
|
|
udphopPort = '',
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udphopInterval = 30,
|
2026-01-18 16:13:34 +00:00
|
|
|
initStreamReceiveWindow = 8388608,
|
|
|
|
|
maxStreamReceiveWindow = 8388608,
|
|
|
|
|
initConnectionReceiveWindow = 20971520,
|
|
|
|
|
maxConnectionReceiveWindow = 20971520,
|
|
|
|
|
maxIdleTimeout = 30,
|
|
|
|
|
keepAlivePeriod = 0,
|
|
|
|
|
disablePathMTUDiscovery = false
|
|
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
this.version = version;
|
|
|
|
|
this.auth = auth;
|
2026-01-18 16:38:05 +00:00
|
|
|
this.congestion = congestion;
|
2026-01-18 16:13:34 +00:00
|
|
|
this.up = up;
|
|
|
|
|
this.down = down;
|
|
|
|
|
this.udphopPort = udphopPort;
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
this.udphopInterval = udphopInterval;
|
2026-01-18 16:13:34 +00:00
|
|
|
this.initStreamReceiveWindow = initStreamReceiveWindow;
|
|
|
|
|
this.maxStreamReceiveWindow = maxStreamReceiveWindow;
|
|
|
|
|
this.initConnectionReceiveWindow = initConnectionReceiveWindow;
|
|
|
|
|
this.maxConnectionReceiveWindow = maxConnectionReceiveWindow;
|
|
|
|
|
this.maxIdleTimeout = maxIdleTimeout;
|
|
|
|
|
this.keepAlivePeriod = keepAlivePeriod;
|
|
|
|
|
this.disablePathMTUDiscovery = disablePathMTUDiscovery;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
let udphopPort = '';
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
let udphopInterval = 30;
|
2026-01-18 16:13:34 +00:00
|
|
|
if (json.udphop) {
|
|
|
|
|
udphopPort = json.udphop.port || '';
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udphopInterval = json.udphop.interval || 30;
|
2026-01-18 16:13:34 +00:00
|
|
|
}
|
|
|
|
|
return new HysteriaStreamSettings(
|
|
|
|
|
json.version,
|
|
|
|
|
json.auth,
|
2026-01-18 16:38:05 +00:00
|
|
|
json.congestion,
|
2026-01-18 16:13:34 +00:00
|
|
|
json.up,
|
|
|
|
|
json.down,
|
|
|
|
|
udphopPort,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udphopInterval,
|
2026-01-18 16:13:34 +00:00
|
|
|
json.initStreamReceiveWindow,
|
|
|
|
|
json.maxStreamReceiveWindow,
|
|
|
|
|
json.initConnectionReceiveWindow,
|
|
|
|
|
json.maxConnectionReceiveWindow,
|
|
|
|
|
json.maxIdleTimeout,
|
|
|
|
|
json.keepAlivePeriod,
|
|
|
|
|
json.disablePathMTUDiscovery
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
const result = {
|
|
|
|
|
version: this.version,
|
|
|
|
|
auth: this.auth,
|
2026-01-18 16:38:05 +00:00
|
|
|
congestion: this.congestion,
|
2026-01-18 16:13:34 +00:00
|
|
|
up: this.up,
|
|
|
|
|
down: this.down,
|
|
|
|
|
initStreamReceiveWindow: this.initStreamReceiveWindow,
|
|
|
|
|
maxStreamReceiveWindow: this.maxStreamReceiveWindow,
|
|
|
|
|
initConnectionReceiveWindow: this.initConnectionReceiveWindow,
|
|
|
|
|
maxConnectionReceiveWindow: this.maxConnectionReceiveWindow,
|
|
|
|
|
maxIdleTimeout: this.maxIdleTimeout,
|
|
|
|
|
keepAlivePeriod: this.keepAlivePeriod,
|
|
|
|
|
disablePathMTUDiscovery: this.disablePathMTUDiscovery
|
|
|
|
|
};
|
|
|
|
|
if (this.udphopPort) {
|
|
|
|
|
result.udphop = {
|
|
|
|
|
port: this.udphopPort,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
interval: this.udphopInterval
|
2026-01-18 16:13:34 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-03-11 08:37:52 +00:00
|
|
|
class SockoptStreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
dialerProxy = "",
|
|
|
|
|
tcpFastOpen = false,
|
|
|
|
|
tcpKeepAliveInterval = 0,
|
|
|
|
|
tcpMptcp = false,
|
2025-03-05 12:14:17 +00:00
|
|
|
penetrate = false,
|
|
|
|
|
addressPortStrategy = Address_Port_Strategy.NONE,
|
2026-01-03 04:26:00 +00:00
|
|
|
trustedXForwardedFor = [],
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2024-03-11 08:37:52 +00:00
|
|
|
super();
|
|
|
|
|
this.dialerProxy = dialerProxy;
|
|
|
|
|
this.tcpFastOpen = tcpFastOpen;
|
|
|
|
|
this.tcpKeepAliveInterval = tcpKeepAliveInterval;
|
2024-05-22 16:35:46 +00:00
|
|
|
this.tcpMptcp = tcpMptcp;
|
2025-01-01 17:42:50 +00:00
|
|
|
this.penetrate = penetrate;
|
2025-03-05 12:14:17 +00:00
|
|
|
this.addressPortStrategy = addressPortStrategy;
|
2026-01-03 04:26:00 +00:00
|
|
|
this.trustedXForwardedFor = trustedXForwardedFor;
|
2024-03-11 08:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
if (Object.keys(json).length === 0) return undefined;
|
|
|
|
|
return new SockoptStreamSettings(
|
|
|
|
|
json.dialerProxy,
|
|
|
|
|
json.tcpFastOpen,
|
|
|
|
|
json.tcpKeepAliveInterval,
|
2024-05-22 16:35:46 +00:00
|
|
|
json.tcpMptcp,
|
2025-01-01 17:42:50 +00:00
|
|
|
json.penetrate,
|
2026-01-03 04:26:00 +00:00
|
|
|
json.addressPortStrategy,
|
|
|
|
|
json.trustedXForwardedFor || []
|
2024-03-11 08:37:52 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
2026-01-03 04:26:00 +00:00
|
|
|
const result = {
|
2024-03-11 08:37:52 +00:00
|
|
|
dialerProxy: this.dialerProxy,
|
|
|
|
|
tcpFastOpen: this.tcpFastOpen,
|
|
|
|
|
tcpKeepAliveInterval: this.tcpKeepAliveInterval,
|
2024-05-22 16:35:46 +00:00
|
|
|
tcpMptcp: this.tcpMptcp,
|
2025-01-01 17:42:50 +00:00
|
|
|
penetrate: this.penetrate,
|
2025-03-05 12:14:17 +00:00
|
|
|
addressPortStrategy: this.addressPortStrategy
|
2024-03-11 08:37:52 +00:00
|
|
|
};
|
2026-01-03 04:26:00 +00:00
|
|
|
if (this.trustedXForwardedFor && this.trustedXForwardedFor.length > 0) {
|
|
|
|
|
result.trustedXForwardedFor = this.trustedXForwardedFor;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2024-03-11 08:37:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
2023-12-05 17:13:36 +00:00
|
|
|
|
2026-02-02 16:50:30 +00:00
|
|
|
class UdpMask extends CommonClass {
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
constructor(type = 'salamander', password = '') {
|
2026-01-18 16:38:05 +00:00
|
|
|
super();
|
|
|
|
|
this.type = type;
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
this.password = password;
|
2026-01-18 16:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
2026-02-02 16:50:30 +00:00
|
|
|
return new UdpMask(
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
json.type,
|
|
|
|
|
json.settings?.password || ''
|
2026-01-18 16:38:05 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
2026-02-02 16:50:30 +00:00
|
|
|
return {
|
|
|
|
|
type: this.type,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
settings: {
|
|
|
|
|
password: this.password
|
|
|
|
|
}
|
2026-02-02 16:50:30 +00:00
|
|
|
};
|
2026-01-18 16:38:05 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
class StreamSettings extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
network = 'tcp',
|
|
|
|
|
security = 'none',
|
|
|
|
|
tlsSettings = new TlsStreamSettings(),
|
|
|
|
|
realitySettings = new RealityStreamSettings(),
|
|
|
|
|
tcpSettings = new TcpStreamSettings(),
|
|
|
|
|
kcpSettings = new KcpStreamSettings(),
|
|
|
|
|
wsSettings = new WsStreamSettings(),
|
|
|
|
|
grpcSettings = new GrpcStreamSettings(),
|
|
|
|
|
httpupgradeSettings = new HttpUpgradeStreamSettings(),
|
2024-12-03 21:24:34 +00:00
|
|
|
xhttpSettings = new xHTTPStreamSettings(),
|
2026-01-18 16:13:34 +00:00
|
|
|
hysteriaSettings = new HysteriaStreamSettings(),
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udpmasks = [],
|
2024-08-06 15:06:39 +00:00
|
|
|
sockopt = undefined,
|
|
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.network = network;
|
|
|
|
|
this.security = security;
|
|
|
|
|
this.tls = tlsSettings;
|
|
|
|
|
this.reality = realitySettings;
|
|
|
|
|
this.tcp = tcpSettings;
|
|
|
|
|
this.kcp = kcpSettings;
|
|
|
|
|
this.ws = wsSettings;
|
|
|
|
|
this.grpc = grpcSettings;
|
2024-03-11 07:36:33 +00:00
|
|
|
this.httpupgrade = httpupgradeSettings;
|
2024-12-03 21:24:34 +00:00
|
|
|
this.xhttp = xhttpSettings;
|
2026-01-18 16:13:34 +00:00
|
|
|
this.hysteria = hysteriaSettings;
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
this.udpmasks = udpmasks;
|
2024-03-11 12:44:24 +00:00
|
|
|
this.sockopt = sockopt;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
2024-08-06 15:06:39 +00:00
|
|
|
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
addUdpMask() {
|
|
|
|
|
this.udpmasks.push(new UdpMask());
|
2026-01-18 16:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delUdpMask(index) {
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
this.udpmasks.splice(index, 1);
|
2026-02-02 16:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
get isTls() {
|
|
|
|
|
return this.security === 'tls';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get isReality() {
|
|
|
|
|
return this.security === "reality";
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-11 08:37:52 +00:00
|
|
|
get sockoptSwitch() {
|
|
|
|
|
return this.sockopt != undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set sockoptSwitch(value) {
|
|
|
|
|
this.sockopt = value ? new SockoptStreamSettings() : undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
const udpmasks = json.udpmasks ? json.udpmasks.map(mask => UdpMask.fromJson(mask)) : [];
|
2023-12-05 17:13:36 +00:00
|
|
|
return new StreamSettings(
|
|
|
|
|
json.network,
|
|
|
|
|
json.security,
|
|
|
|
|
TlsStreamSettings.fromJson(json.tlsSettings),
|
|
|
|
|
RealityStreamSettings.fromJson(json.realitySettings),
|
|
|
|
|
TcpStreamSettings.fromJson(json.tcpSettings),
|
|
|
|
|
KcpStreamSettings.fromJson(json.kcpSettings),
|
|
|
|
|
WsStreamSettings.fromJson(json.wsSettings),
|
|
|
|
|
GrpcStreamSettings.fromJson(json.grpcSettings),
|
2024-03-11 07:36:33 +00:00
|
|
|
HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
|
2024-12-03 21:24:34 +00:00
|
|
|
xHTTPStreamSettings.fromJson(json.xhttpSettings),
|
2026-01-18 16:13:34 +00:00
|
|
|
HysteriaStreamSettings.fromJson(json.hysteriaSettings),
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udpmasks,
|
2024-03-11 12:44:24 +00:00
|
|
|
SockoptStreamSettings.fromJson(json.sockopt),
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
const network = this.network;
|
|
|
|
|
return {
|
|
|
|
|
network: network,
|
|
|
|
|
security: this.security,
|
|
|
|
|
tlsSettings: this.security == 'tls' ? this.tls.toJson() : undefined,
|
|
|
|
|
realitySettings: this.security == 'reality' ? this.reality.toJson() : undefined,
|
|
|
|
|
tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,
|
|
|
|
|
kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined,
|
|
|
|
|
wsSettings: network === 'ws' ? this.ws.toJson() : undefined,
|
|
|
|
|
grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,
|
2024-03-11 07:36:33 +00:00
|
|
|
httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined,
|
2024-12-03 21:24:34 +00:00
|
|
|
xhttpSettings: network === 'xhttp' ? this.xhttp.toJson() : undefined,
|
2026-01-18 16:13:34 +00:00
|
|
|
hysteriaSettings: network === 'hysteria' ? this.hysteria.toJson() : undefined,
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
udpmasks: this.udpmasks.length > 0 ? this.udpmasks.map(mask => mask.toJson()) : undefined,
|
2024-03-11 08:37:52 +00:00
|
|
|
sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined,
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-11 18:18:33 +00:00
|
|
|
class Mux extends CommonClass {
|
|
|
|
|
constructor(enabled = false, concurrency = 8, xudpConcurrency = 16, xudpProxyUDP443 = "reject") {
|
|
|
|
|
super();
|
|
|
|
|
this.enabled = enabled;
|
|
|
|
|
this.concurrency = concurrency;
|
|
|
|
|
this.xudpConcurrency = xudpConcurrency;
|
|
|
|
|
this.xudpProxyUDP443 = xudpProxyUDP443;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
if (Object.keys(json).length === 0) return undefined;
|
2024-03-11 22:47:42 +00:00
|
|
|
return new Mux(
|
2024-03-11 18:18:33 +00:00
|
|
|
json.enabled,
|
|
|
|
|
json.concurrency,
|
|
|
|
|
json.xudpConcurrency,
|
|
|
|
|
json.xudpProxyUDP443,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
enabled: this.enabled,
|
|
|
|
|
concurrency: this.concurrency,
|
|
|
|
|
xudpConcurrency: this.xudpConcurrency,
|
|
|
|
|
xudpProxyUDP443: this.xudpProxyUDP443,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
class Outbound extends CommonClass {
|
|
|
|
|
constructor(
|
2024-08-06 15:06:39 +00:00
|
|
|
tag = '',
|
2024-12-04 12:27:29 +00:00
|
|
|
protocol = Protocols.VLESS,
|
2024-08-06 15:06:39 +00:00
|
|
|
settings = null,
|
2023-12-05 17:13:36 +00:00
|
|
|
streamSettings = new StreamSettings(),
|
2024-03-12 15:53:48 +00:00
|
|
|
sendThrough,
|
2024-03-11 18:18:33 +00:00
|
|
|
mux = new Mux(),
|
2023-12-05 17:13:36 +00:00
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
this.tag = tag;
|
|
|
|
|
this._protocol = protocol;
|
|
|
|
|
this.settings = settings == null ? Outbound.Settings.getSettings(protocol) : settings;
|
|
|
|
|
this.stream = streamSettings;
|
2024-03-12 15:53:48 +00:00
|
|
|
this.sendThrough = sendThrough;
|
2024-03-11 18:18:33 +00:00
|
|
|
this.mux = mux;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get protocol() {
|
|
|
|
|
return this._protocol;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set protocol(protocol) {
|
|
|
|
|
this._protocol = protocol;
|
|
|
|
|
this.settings = Outbound.Settings.getSettings(protocol);
|
|
|
|
|
this.stream = new StreamSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canEnableTls() {
|
2026-01-18 16:38:05 +00:00
|
|
|
if (![Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks, Protocols.Hysteria].includes(this.protocol)) return false;
|
|
|
|
|
if (this.protocol === Protocols.Hysteria) return this.stream.network === 'hysteria';
|
2024-12-03 21:24:34 +00:00
|
|
|
return ["tcp", "ws", "http", "grpc", "httpupgrade", "xhttp"].includes(this.stream.network);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//this is used for xtls-rprx-vision
|
|
|
|
|
canEnableTlsFlow() {
|
|
|
|
|
if ((this.stream.security != 'none') && (this.stream.network === "tcp")) {
|
|
|
|
|
return this.protocol === Protocols.VLESS;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-03 04:56:35 +00:00
|
|
|
// Vision seed applies only when vision flow is selected
|
|
|
|
|
canEnableVisionSeed() {
|
|
|
|
|
if (!this.canEnableTlsFlow()) return false;
|
|
|
|
|
const flow = this.settings?.flow;
|
|
|
|
|
return flow === TLS_FLOW_CONTROL.VISION || flow === TLS_FLOW_CONTROL.VISION_UDP443;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
canEnableReality() {
|
|
|
|
|
if (![Protocols.VLESS, Protocols.Trojan].includes(this.protocol)) return false;
|
2024-12-03 21:24:34 +00:00
|
|
|
return ["tcp", "http", "grpc", "xhttp"].includes(this.stream.network);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canEnableStream() {
|
2026-01-18 16:13:34 +00:00
|
|
|
return [Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks, Protocols.Hysteria].includes(this.protocol);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-03-12 19:34:11 +00:00
|
|
|
canEnableMux() {
|
2025-07-04 12:02:33 +00:00
|
|
|
// Disable Mux if flow is set
|
|
|
|
|
if (this.settings.flow && this.settings.flow !== '') {
|
2024-07-14 21:55:56 +00:00
|
|
|
this.mux.enabled = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-07-04 12:02:33 +00:00
|
|
|
|
|
|
|
|
// Disable Mux if network is xhttp
|
|
|
|
|
if (this.stream.network === 'xhttp') {
|
|
|
|
|
this.mux.enabled = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allow Mux only for these protocols
|
|
|
|
|
return [
|
|
|
|
|
Protocols.VMess,
|
|
|
|
|
Protocols.VLESS,
|
|
|
|
|
Protocols.Trojan,
|
|
|
|
|
Protocols.Shadowsocks,
|
|
|
|
|
Protocols.HTTP,
|
2025-09-10 10:19:09 +00:00
|
|
|
Protocols.Socks
|
2025-07-04 12:02:33 +00:00
|
|
|
].includes(this.protocol);
|
2024-03-12 19:34:11 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
hasServers() {
|
2025-09-10 10:19:09 +00:00
|
|
|
return [Protocols.Trojan, Protocols.Shadowsocks, Protocols.Socks, Protocols.HTTP].includes(this.protocol);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hasAddressPort() {
|
|
|
|
|
return [
|
|
|
|
|
Protocols.DNS,
|
|
|
|
|
Protocols.VMess,
|
|
|
|
|
Protocols.VLESS,
|
|
|
|
|
Protocols.Trojan,
|
|
|
|
|
Protocols.Shadowsocks,
|
2025-09-10 10:19:09 +00:00
|
|
|
Protocols.Socks,
|
2026-01-18 16:13:34 +00:00
|
|
|
Protocols.HTTP,
|
|
|
|
|
Protocols.Hysteria
|
2023-12-05 17:13:36 +00:00
|
|
|
].includes(this.protocol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hasUsername() {
|
2025-09-10 10:19:09 +00:00
|
|
|
return [Protocols.Socks, Protocols.HTTP].includes(this.protocol);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound(
|
|
|
|
|
json.tag,
|
|
|
|
|
json.protocol,
|
|
|
|
|
Outbound.Settings.fromJson(json.protocol, json.settings),
|
|
|
|
|
StreamSettings.fromJson(json.streamSettings),
|
2024-03-12 15:53:48 +00:00
|
|
|
json.sendThrough,
|
2024-03-11 18:18:33 +00:00
|
|
|
Mux.fromJson(json.mux),
|
2023-12-05 17:13:36 +00:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
2024-03-12 13:58:09 +00:00
|
|
|
var stream;
|
|
|
|
|
if (this.canEnableStream()) {
|
|
|
|
|
stream = this.stream.toJson();
|
|
|
|
|
} else {
|
|
|
|
|
if (this.stream?.sockopt)
|
|
|
|
|
stream = { sockopt: this.stream.sockopt.toJson() };
|
|
|
|
|
}
|
2025-09-16 11:41:05 +00:00
|
|
|
let settingsOut = this.settings instanceof CommonClass ? this.settings.toJson() : this.settings;
|
2023-12-05 17:13:36 +00:00
|
|
|
return {
|
|
|
|
|
protocol: this.protocol,
|
2025-09-16 11:41:05 +00:00
|
|
|
settings: settingsOut,
|
|
|
|
|
// Only include tag, streamSettings, sendThrough, mux if present and not empty
|
|
|
|
|
...(this.tag ? { tag: this.tag } : {}),
|
|
|
|
|
...(stream ? { streamSettings: stream } : {}),
|
|
|
|
|
...(this.sendThrough ? { sendThrough: this.sendThrough } : {}),
|
|
|
|
|
...(this.mux?.enabled ? { mux: this.mux } : {}),
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromLink(link) {
|
|
|
|
|
data = link.split('://');
|
2024-08-06 15:06:39 +00:00
|
|
|
if (data.length != 2) return null;
|
|
|
|
|
switch (data[0].toLowerCase()) {
|
2023-12-05 17:13:36 +00:00
|
|
|
case Protocols.VMess:
|
2023-12-13 15:57:36 +00:00
|
|
|
return this.fromVmessLink(JSON.parse(Base64.decode(data[1])));
|
2023-12-05 17:13:36 +00:00
|
|
|
case Protocols.VLESS:
|
|
|
|
|
case Protocols.Trojan:
|
|
|
|
|
case 'ss':
|
|
|
|
|
return this.fromParamLink(link);
|
2026-01-18 16:13:34 +00:00
|
|
|
case 'hysteria2':
|
|
|
|
|
case Protocols.Hysteria:
|
|
|
|
|
return this.fromHysteriaLink(link);
|
2023-12-05 17:13:36 +00:00
|
|
|
default:
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromVmessLink(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
let stream = new StreamSettings(json.net, json.tls);
|
|
|
|
|
|
|
|
|
|
let network = json.net;
|
|
|
|
|
if (network === 'tcp') {
|
|
|
|
|
stream.tcp = new TcpStreamSettings(
|
|
|
|
|
json.type,
|
2023-12-13 15:57:36 +00:00
|
|
|
json.host ?? '',
|
|
|
|
|
json.path ?? '');
|
2023-12-05 17:13:36 +00:00
|
|
|
} else if (network === 'kcp') {
|
|
|
|
|
stream.kcp = new KcpStreamSettings();
|
|
|
|
|
stream.type = json.type;
|
|
|
|
|
stream.seed = json.path;
|
|
|
|
|
} else if (network === 'ws') {
|
2024-08-06 15:06:39 +00:00
|
|
|
stream.ws = new WsStreamSettings(json.path, json.host);
|
2023-12-05 17:13:36 +00:00
|
|
|
} else if (network === 'grpc') {
|
2025-03-09 05:38:34 +00:00
|
|
|
stream.grpc = new GrpcStreamSettings(json.path, json.authority, json.type == 'multi');
|
2024-03-11 07:36:33 +00:00
|
|
|
} else if (network === 'httpupgrade') {
|
2024-08-06 15:06:39 +00:00
|
|
|
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
2024-12-03 21:24:34 +00:00
|
|
|
} else if (network === 'xhttp') {
|
|
|
|
|
stream.xhttp = new xHTTPStreamSettings(json.path, json.host, json.mode);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
if (json.tls && json.tls == 'tls') {
|
2023-12-05 17:13:36 +00:00
|
|
|
stream.tls = new TlsStreamSettings(
|
|
|
|
|
json.sni,
|
|
|
|
|
json.alpn ? json.alpn.split(',') : [],
|
|
|
|
|
json.fp,
|
|
|
|
|
json.allowInsecure);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-01 07:44:20 +00:00
|
|
|
const port = json.port * 1;
|
|
|
|
|
|
2024-08-10 22:47:44 +00:00
|
|
|
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromParamLink(link) {
|
2023-12-05 17:13:36 +00:00
|
|
|
const url = new URL(link);
|
2024-04-01 07:44:20 +00:00
|
|
|
let type = url.searchParams.get('type') ?? 'tcp';
|
2023-12-05 17:13:36 +00:00
|
|
|
let security = url.searchParams.get('security') ?? 'none';
|
|
|
|
|
let stream = new StreamSettings(type, security);
|
|
|
|
|
|
2024-04-01 07:44:20 +00:00
|
|
|
let headerType = url.searchParams.get('headerType') ?? undefined;
|
|
|
|
|
let host = url.searchParams.get('host') ?? undefined;
|
|
|
|
|
let path = url.searchParams.get('path') ?? undefined;
|
2024-12-27 20:30:51 +00:00
|
|
|
let mode = url.searchParams.get('mode') ?? undefined;
|
2023-12-05 17:13:36 +00:00
|
|
|
|
2024-04-01 07:44:20 +00:00
|
|
|
if (type === 'tcp' || type === 'none') {
|
2023-12-05 17:13:36 +00:00
|
|
|
stream.tcp = new TcpStreamSettings(headerType ?? 'none', host, path);
|
|
|
|
|
} else if (type === 'kcp') {
|
|
|
|
|
stream.kcp = new KcpStreamSettings();
|
|
|
|
|
stream.kcp.type = headerType ?? 'none';
|
|
|
|
|
stream.kcp.seed = path;
|
|
|
|
|
} else if (type === 'ws') {
|
2024-08-06 15:06:39 +00:00
|
|
|
stream.ws = new WsStreamSettings(path, host);
|
2024-04-20 18:45:36 +00:00
|
|
|
} else if (type === 'grpc') {
|
|
|
|
|
stream.grpc = new GrpcStreamSettings(
|
|
|
|
|
url.searchParams.get('serviceName') ?? '',
|
|
|
|
|
url.searchParams.get('authority') ?? '',
|
2025-03-09 05:38:34 +00:00
|
|
|
url.searchParams.get('mode') == 'multi');
|
2024-04-20 18:45:36 +00:00
|
|
|
} else if (type === 'httpupgrade') {
|
2024-08-06 15:06:39 +00:00
|
|
|
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
2024-12-03 21:24:34 +00:00
|
|
|
} else if (type === 'xhttp') {
|
|
|
|
|
stream.xhttp = new xHTTPStreamSettings(path, host, mode);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
if (security == 'tls') {
|
|
|
|
|
let fp = url.searchParams.get('fp') ?? 'none';
|
|
|
|
|
let alpn = url.searchParams.get('alpn');
|
|
|
|
|
let allowInsecure = url.searchParams.get('allowInsecure');
|
|
|
|
|
let sni = url.searchParams.get('sni') ?? '';
|
2025-08-04 14:27:57 +00:00
|
|
|
let ech = url.searchParams.get('ech') ?? '';
|
|
|
|
|
stream.tls = new TlsStreamSettings(sni, alpn ? alpn.split(',') : [], fp, allowInsecure == 1, ech);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
if (security == 'reality') {
|
|
|
|
|
let pbk = url.searchParams.get('pbk');
|
|
|
|
|
let fp = url.searchParams.get('fp');
|
|
|
|
|
let sni = url.searchParams.get('sni') ?? '';
|
|
|
|
|
let sid = url.searchParams.get('sid') ?? '';
|
|
|
|
|
let spx = url.searchParams.get('spx') ?? '';
|
2025-08-03 10:09:37 +00:00
|
|
|
let pqv = url.searchParams.get('pqv') ?? '';
|
|
|
|
|
stream.reality = new RealityStreamSettings(pbk, fp, sni, sid, spx, pqv);
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-04-01 07:44:20 +00:00
|
|
|
const regex = /([^@]+):\/\/([^@]+)@(.+):(\d+)(.*)$/;
|
2023-12-05 17:13:36 +00:00
|
|
|
const match = link.match(regex);
|
|
|
|
|
|
|
|
|
|
if (!match) return null;
|
2024-08-06 15:06:39 +00:00
|
|
|
let [, protocol, userData, address, port,] = match;
|
2023-12-05 17:13:36 +00:00
|
|
|
port *= 1;
|
2024-08-06 15:06:39 +00:00
|
|
|
if (protocol == 'ss') {
|
2023-12-05 17:13:36 +00:00
|
|
|
protocol = 'shadowsocks';
|
|
|
|
|
userData = atob(userData).split(':');
|
|
|
|
|
}
|
|
|
|
|
var settings;
|
2024-08-06 15:06:39 +00:00
|
|
|
switch (protocol) {
|
2023-12-05 17:13:36 +00:00
|
|
|
case Protocols.VLESS:
|
2025-09-07 20:35:38 +00:00
|
|
|
settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '', url.searchParams.get('encryption') ?? 'none');
|
2023-12-05 17:13:36 +00:00
|
|
|
break;
|
|
|
|
|
case Protocols.Trojan:
|
|
|
|
|
settings = new Outbound.TrojanSettings(address, port, userData);
|
|
|
|
|
break;
|
|
|
|
|
case Protocols.Shadowsocks:
|
2024-08-06 15:06:39 +00:00
|
|
|
let method = userData.splice(0, 1)[0];
|
2023-12-05 17:13:36 +00:00
|
|
|
settings = new Outbound.ShadowsocksSettings(address, port, userData.join(":"), method, true);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
let remark = decodeURIComponent(url.hash);
|
|
|
|
|
// Remove '#' from url.hash
|
|
|
|
|
remark = remark.length > 0 ? remark.substring(1) : 'out-' + protocol + '-' + port;
|
|
|
|
|
return new Outbound(remark, protocol, settings, stream);
|
|
|
|
|
}
|
2026-01-18 16:13:34 +00:00
|
|
|
|
|
|
|
|
static fromHysteriaLink(link) {
|
|
|
|
|
// Parse hysteria2://password@address:port[?param1=value1¶m2=value2...][#remarks]
|
|
|
|
|
const regex = /^hysteria2?:\/\/([^@]+)@([^:?#]+):(\d+)([^#]*)(#.*)?$/;
|
|
|
|
|
const match = link.match(regex);
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
if (!match) return null;
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
let [, password, address, port, params, hash] = match;
|
|
|
|
|
port = parseInt(port);
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Parse URL parameters if present
|
|
|
|
|
let urlParams = new URLSearchParams(params);
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Create stream settings with hysteria network
|
|
|
|
|
let stream = new StreamSettings('hysteria', 'none');
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Set hysteria stream settings
|
|
|
|
|
stream.hysteria.auth = password;
|
2026-01-18 16:38:05 +00:00
|
|
|
stream.hysteria.congestion = urlParams.get('congestion') ?? '';
|
2026-01-18 16:13:34 +00:00
|
|
|
stream.hysteria.up = urlParams.get('up') ?? '0';
|
|
|
|
|
stream.hysteria.down = urlParams.get('down') ?? '0';
|
|
|
|
|
stream.hysteria.udphopPort = urlParams.get('udphopPort') ?? '';
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
stream.hysteria.udphopInterval = parseInt(urlParams.get('udphopInterval') ?? '30');
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Optional QUIC parameters
|
|
|
|
|
if (urlParams.has('initStreamReceiveWindow')) {
|
|
|
|
|
stream.hysteria.initStreamReceiveWindow = parseInt(urlParams.get('initStreamReceiveWindow'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('maxStreamReceiveWindow')) {
|
|
|
|
|
stream.hysteria.maxStreamReceiveWindow = parseInt(urlParams.get('maxStreamReceiveWindow'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('initConnectionReceiveWindow')) {
|
|
|
|
|
stream.hysteria.initConnectionReceiveWindow = parseInt(urlParams.get('initConnectionReceiveWindow'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('maxConnectionReceiveWindow')) {
|
|
|
|
|
stream.hysteria.maxConnectionReceiveWindow = parseInt(urlParams.get('maxConnectionReceiveWindow'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('maxIdleTimeout')) {
|
|
|
|
|
stream.hysteria.maxIdleTimeout = parseInt(urlParams.get('maxIdleTimeout'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('keepAlivePeriod')) {
|
|
|
|
|
stream.hysteria.keepAlivePeriod = parseInt(urlParams.get('keepAlivePeriod'));
|
|
|
|
|
}
|
|
|
|
|
if (urlParams.has('disablePathMTUDiscovery')) {
|
|
|
|
|
stream.hysteria.disablePathMTUDiscovery = urlParams.get('disablePathMTUDiscovery') === 'true';
|
|
|
|
|
}
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Create settings
|
|
|
|
|
let settings = new Outbound.HysteriaSettings(address, port, 2);
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
// Extract remark from hash
|
|
|
|
|
let remark = hash ? decodeURIComponent(hash.substring(1)) : `out-hysteria-${port}`;
|
2026-01-18 16:38:05 +00:00
|
|
|
|
2026-01-18 16:13:34 +00:00
|
|
|
return new Outbound(remark, Protocols.Hysteria, settings, stream);
|
|
|
|
|
}
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Outbound.Settings = class extends CommonClass {
|
|
|
|
|
constructor(protocol) {
|
|
|
|
|
super();
|
|
|
|
|
this.protocol = protocol;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getSettings(protocol) {
|
|
|
|
|
switch (protocol) {
|
|
|
|
|
case Protocols.Freedom: return new Outbound.FreedomSettings();
|
|
|
|
|
case Protocols.Blackhole: return new Outbound.BlackholeSettings();
|
|
|
|
|
case Protocols.DNS: return new Outbound.DNSSettings();
|
|
|
|
|
case Protocols.VMess: return new Outbound.VmessSettings();
|
|
|
|
|
case Protocols.VLESS: return new Outbound.VLESSSettings();
|
|
|
|
|
case Protocols.Trojan: return new Outbound.TrojanSettings();
|
|
|
|
|
case Protocols.Shadowsocks: return new Outbound.ShadowsocksSettings();
|
2025-09-10 10:19:09 +00:00
|
|
|
case Protocols.Socks: return new Outbound.SocksSettings();
|
2023-12-05 17:13:36 +00:00
|
|
|
case Protocols.HTTP: return new Outbound.HttpSettings();
|
2024-01-01 13:03:43 +00:00
|
|
|
case Protocols.Wireguard: return new Outbound.WireguardSettings();
|
2026-01-18 16:13:34 +00:00
|
|
|
case Protocols.Hysteria: return new Outbound.HysteriaSettings();
|
2023-12-05 17:13:36 +00:00
|
|
|
default: return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(protocol, json) {
|
|
|
|
|
switch (protocol) {
|
|
|
|
|
case Protocols.Freedom: return Outbound.FreedomSettings.fromJson(json);
|
|
|
|
|
case Protocols.Blackhole: return Outbound.BlackholeSettings.fromJson(json);
|
|
|
|
|
case Protocols.DNS: return Outbound.DNSSettings.fromJson(json);
|
|
|
|
|
case Protocols.VMess: return Outbound.VmessSettings.fromJson(json);
|
|
|
|
|
case Protocols.VLESS: return Outbound.VLESSSettings.fromJson(json);
|
|
|
|
|
case Protocols.Trojan: return Outbound.TrojanSettings.fromJson(json);
|
|
|
|
|
case Protocols.Shadowsocks: return Outbound.ShadowsocksSettings.fromJson(json);
|
2025-09-10 10:19:09 +00:00
|
|
|
case Protocols.Socks: return Outbound.SocksSettings.fromJson(json);
|
2023-12-05 17:13:36 +00:00
|
|
|
case Protocols.HTTP: return Outbound.HttpSettings.fromJson(json);
|
2024-01-01 13:03:43 +00:00
|
|
|
case Protocols.Wireguard: return Outbound.WireguardSettings.fromJson(json);
|
2026-01-18 16:13:34 +00:00
|
|
|
case Protocols.Hysteria: return Outbound.HysteriaSettings.fromJson(json);
|
2023-12-05 17:13:36 +00:00
|
|
|
default: return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.FreedomSettings = class extends CommonClass {
|
2024-08-29 09:27:43 +00:00
|
|
|
constructor(
|
|
|
|
|
domainStrategy = '',
|
2024-09-02 08:23:10 +00:00
|
|
|
redirect = '',
|
2024-08-29 09:27:43 +00:00
|
|
|
fragment = {},
|
2024-09-24 09:38:10 +00:00
|
|
|
noises = []
|
2024-08-29 09:27:43 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.domainStrategy = domainStrategy;
|
2024-09-02 08:23:10 +00:00
|
|
|
this.redirect = redirect;
|
2023-12-05 17:13:36 +00:00
|
|
|
this.fragment = fragment;
|
2024-09-17 07:33:44 +00:00
|
|
|
this.noises = noises;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-24 09:38:10 +00:00
|
|
|
addNoise() {
|
|
|
|
|
this.noises.push(new Outbound.FreedomSettings.Noise());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delNoise(index) {
|
|
|
|
|
this.noises.splice(index, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.FreedomSettings(
|
|
|
|
|
json.domainStrategy,
|
2024-09-02 08:23:10 +00:00
|
|
|
json.redirect,
|
2023-12-05 17:13:36 +00:00
|
|
|
json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : undefined,
|
2024-10-21 08:40:29 +00:00
|
|
|
json.noises ? json.noises.map(noise => Outbound.FreedomSettings.Noise.fromJson(noise)) : undefined,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy,
|
2025-09-16 11:41:05 +00:00
|
|
|
redirect: ObjectUtil.isEmpty(this.redirect) ? undefined : this.redirect,
|
2023-12-05 17:13:36 +00:00
|
|
|
fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment,
|
2024-10-21 08:40:29 +00:00
|
|
|
noises: this.noises.length === 0 ? undefined : Outbound.FreedomSettings.Noise.toJsonArray(this.noises),
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-09-24 09:38:10 +00:00
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
Outbound.FreedomSettings.Fragment = class extends CommonClass {
|
2024-10-17 08:36:05 +00:00
|
|
|
constructor(
|
|
|
|
|
packets = '1-3',
|
|
|
|
|
length = '',
|
2025-08-14 16:38:56 +00:00
|
|
|
interval = '',
|
|
|
|
|
maxSplit = ''
|
2024-10-17 08:36:05 +00:00
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.packets = packets;
|
|
|
|
|
this.length = length;
|
|
|
|
|
this.interval = interval;
|
2025-08-14 16:38:56 +00:00
|
|
|
this.maxSplit = maxSplit;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.FreedomSettings.Fragment(
|
|
|
|
|
json.packets,
|
|
|
|
|
json.length,
|
|
|
|
|
json.interval,
|
2025-08-14 16:38:56 +00:00
|
|
|
json.maxSplit
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-09-24 09:38:10 +00:00
|
|
|
|
|
|
|
|
Outbound.FreedomSettings.Noise = class extends CommonClass {
|
2024-09-17 07:33:44 +00:00
|
|
|
constructor(
|
|
|
|
|
type = 'rand',
|
|
|
|
|
packet = '10-20',
|
2025-08-14 16:38:56 +00:00
|
|
|
delay = '10-16',
|
|
|
|
|
applyTo = 'ip'
|
2024-09-17 07:33:44 +00:00
|
|
|
) {
|
2024-08-29 09:27:43 +00:00
|
|
|
super();
|
2024-09-17 07:33:44 +00:00
|
|
|
this.type = type;
|
2024-08-30 07:28:44 +00:00
|
|
|
this.packet = packet;
|
2024-08-29 09:27:43 +00:00
|
|
|
this.delay = delay;
|
2025-08-14 16:38:56 +00:00
|
|
|
this.applyTo = applyTo;
|
2024-08-29 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
2024-09-24 09:38:10 +00:00
|
|
|
return new Outbound.FreedomSettings.Noise(
|
2024-09-17 07:33:44 +00:00
|
|
|
json.type,
|
2024-08-30 07:28:44 +00:00
|
|
|
json.packet,
|
2024-08-29 09:27:43 +00:00
|
|
|
json.delay,
|
2025-08-14 16:38:56 +00:00
|
|
|
json.applyTo
|
2024-08-29 09:27:43 +00:00
|
|
|
);
|
|
|
|
|
}
|
2024-09-24 09:38:10 +00:00
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
type: this.type,
|
|
|
|
|
packet: this.packet,
|
|
|
|
|
delay: this.delay,
|
2025-08-14 16:38:56 +00:00
|
|
|
applyTo: this.applyTo
|
2024-09-24 09:38:10 +00:00
|
|
|
};
|
|
|
|
|
}
|
2024-08-29 09:27:43 +00:00
|
|
|
};
|
|
|
|
|
|
2023-12-05 17:13:36 +00:00
|
|
|
Outbound.BlackholeSettings = class extends CommonClass {
|
|
|
|
|
constructor(type) {
|
|
|
|
|
super();
|
2024-04-17 05:33:22 +00:00
|
|
|
this.type = type;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.BlackholeSettings(
|
|
|
|
|
json.response ? json.response.type : undefined,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
2024-08-06 15:06:39 +00:00
|
|
|
response: ObjectUtil.isEmpty(this.type) ? undefined : { type: this.type },
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.DNSSettings = class extends CommonClass {
|
2024-09-16 08:30:51 +00:00
|
|
|
constructor(
|
|
|
|
|
network = 'udp',
|
2024-11-03 09:51:53 +00:00
|
|
|
address = '',
|
2024-09-16 08:30:51 +00:00
|
|
|
port = 53,
|
2025-08-17 10:22:33 +00:00
|
|
|
nonIPQuery = 'reject',
|
2024-09-16 08:30:51 +00:00
|
|
|
blockTypes = []
|
|
|
|
|
) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.network = network;
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
2024-09-16 08:30:51 +00:00
|
|
|
this.nonIPQuery = nonIPQuery;
|
|
|
|
|
this.blockTypes = blockTypes;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.DNSSettings(
|
|
|
|
|
json.network,
|
|
|
|
|
json.address,
|
|
|
|
|
json.port,
|
2024-09-16 08:30:51 +00:00
|
|
|
json.nonIPQuery,
|
|
|
|
|
json.blockTypes,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.VmessSettings = class extends CommonClass {
|
2024-08-10 22:47:44 +00:00
|
|
|
constructor(address, port, id, security) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.id = id;
|
2024-08-10 22:47:44 +00:00
|
|
|
this.security = security;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2025-09-20 09:11:30 +00:00
|
|
|
if (!ObjectUtil.isArrEmpty(json.vnext)) {
|
|
|
|
|
const v = json.vnext[0] || {};
|
|
|
|
|
const u = ObjectUtil.isArrEmpty(v.users) ? {} : v.users[0];
|
|
|
|
|
return new Outbound.VmessSettings(
|
|
|
|
|
v.address,
|
|
|
|
|
v.port,
|
|
|
|
|
u.id,
|
|
|
|
|
u.security,
|
|
|
|
|
);
|
|
|
|
|
}
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
2025-09-20 09:11:30 +00:00
|
|
|
vnext: [{
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
|
|
|
|
users: [{
|
|
|
|
|
id: this.id,
|
|
|
|
|
security: this.security
|
|
|
|
|
}]
|
|
|
|
|
}]
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.VLESSSettings = class extends CommonClass {
|
2026-01-03 04:26:00 +00:00
|
|
|
constructor(address, port, id, flow, encryption, testpre = 0, testseed = [900, 500, 900, 256]) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.id = id;
|
|
|
|
|
this.flow = flow;
|
2025-09-07 20:35:38 +00:00
|
|
|
this.encryption = encryption;
|
2026-01-03 04:26:00 +00:00
|
|
|
this.testpre = testpre;
|
|
|
|
|
this.testseed = testseed;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2025-09-16 11:41:05 +00:00
|
|
|
if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VLESSSettings();
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.VLESSSettings(
|
2025-09-16 11:41:05 +00:00
|
|
|
json.address,
|
|
|
|
|
json.port,
|
|
|
|
|
json.id,
|
|
|
|
|
json.flow,
|
2026-01-03 04:26:00 +00:00
|
|
|
json.encryption,
|
|
|
|
|
json.testpre || 0,
|
|
|
|
|
json.testseed && json.testseed.length >= 4 ? json.testseed : [900, 500, 900, 256]
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
2026-01-03 04:26:00 +00:00
|
|
|
const result = {
|
2025-09-16 11:41:05 +00:00
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
|
|
|
|
id: this.id,
|
|
|
|
|
flow: this.flow,
|
|
|
|
|
encryption: this.encryption,
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
if (this.testpre > 0) {
|
|
|
|
|
result.testpre = this.testpre;
|
|
|
|
|
}
|
|
|
|
|
if (this.testseed && this.testseed.length >= 4) {
|
|
|
|
|
result.testseed = this.testseed;
|
2026-01-03 04:26:00 +00:00
|
|
|
}
|
|
|
|
|
return result;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.TrojanSettings = class extends CommonClass {
|
|
|
|
|
constructor(address, port, password) {
|
|
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.password = password;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
if (ObjectUtil.isArrEmpty(json.servers)) return new Outbound.TrojanSettings();
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.TrojanSettings(
|
|
|
|
|
json.servers[0].address,
|
|
|
|
|
json.servers[0].port,
|
|
|
|
|
json.servers[0].password,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
servers: [{
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
|
|
|
|
password: this.password,
|
|
|
|
|
}],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.ShadowsocksSettings = class extends CommonClass {
|
2024-06-12 20:33:33 +00:00
|
|
|
constructor(address, port, password, method, uot, UoTVersion) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.password = password;
|
|
|
|
|
this.method = method;
|
|
|
|
|
this.uot = uot;
|
2024-06-12 20:33:33 +00:00
|
|
|
this.UoTVersion = UoTVersion;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2023-12-05 17:13:36 +00:00
|
|
|
let servers = json.servers;
|
2024-08-06 15:06:39 +00:00
|
|
|
if (ObjectUtil.isArrEmpty(servers)) servers = [{}];
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.ShadowsocksSettings(
|
|
|
|
|
servers[0].address,
|
|
|
|
|
servers[0].port,
|
|
|
|
|
servers[0].password,
|
|
|
|
|
servers[0].method,
|
|
|
|
|
servers[0].uot,
|
2024-06-12 20:33:33 +00:00
|
|
|
servers[0].UoTVersion,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
servers: [{
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
|
|
|
|
password: this.password,
|
|
|
|
|
method: this.method,
|
|
|
|
|
uot: this.uot,
|
2024-06-12 20:33:33 +00:00
|
|
|
UoTVersion: this.UoTVersion,
|
2023-12-05 17:13:36 +00:00
|
|
|
}],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-01-01 13:03:43 +00:00
|
|
|
|
2025-09-10 10:19:09 +00:00
|
|
|
Outbound.SocksSettings = class extends CommonClass {
|
2023-12-23 13:07:32 +00:00
|
|
|
constructor(address, port, user, pass) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.user = user;
|
2023-12-23 13:07:32 +00:00
|
|
|
this.pass = pass;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-01-29 20:32:58 +00:00
|
|
|
let servers = json.servers;
|
2024-08-06 15:06:39 +00:00
|
|
|
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
|
2025-09-10 10:19:09 +00:00
|
|
|
return new Outbound.SocksSettings(
|
2023-12-05 17:13:36 +00:00
|
|
|
servers[0].address,
|
|
|
|
|
servers[0].port,
|
|
|
|
|
ObjectUtil.isArrEmpty(servers[0].users) ? '' : servers[0].users[0].user,
|
2024-01-29 20:32:58 +00:00
|
|
|
ObjectUtil.isArrEmpty(servers[0].users) ? '' : servers[0].users[0].pass,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
servers: [{
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
2024-08-06 15:06:39 +00:00
|
|
|
users: ObjectUtil.isEmpty(this.user) ? [] : [{ user: this.user, pass: this.pass }],
|
2023-12-05 17:13:36 +00:00
|
|
|
}],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Outbound.HttpSettings = class extends CommonClass {
|
2023-12-23 13:07:32 +00:00
|
|
|
constructor(address, port, user, pass) {
|
2023-12-05 17:13:36 +00:00
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.user = user;
|
2023-12-23 13:07:32 +00:00
|
|
|
this.pass = pass;
|
2023-12-05 17:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-01-29 20:32:58 +00:00
|
|
|
let servers = json.servers;
|
2024-08-06 15:06:39 +00:00
|
|
|
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
|
2023-12-05 17:13:36 +00:00
|
|
|
return new Outbound.HttpSettings(
|
|
|
|
|
servers[0].address,
|
|
|
|
|
servers[0].port,
|
|
|
|
|
ObjectUtil.isArrEmpty(servers[0].users) ? '' : servers[0].users[0].user,
|
2024-01-29 20:32:58 +00:00
|
|
|
ObjectUtil.isArrEmpty(servers[0].users) ? '' : servers[0].users[0].pass,
|
2023-12-05 17:13:36 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
servers: [{
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
2024-08-06 15:06:39 +00:00
|
|
|
users: ObjectUtil.isEmpty(this.user) ? [] : [{ user: this.user, pass: this.pass }],
|
2023-12-05 17:13:36 +00:00
|
|
|
}],
|
|
|
|
|
};
|
|
|
|
|
}
|
2024-01-10 12:44:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Outbound.WireguardSettings = class extends CommonClass {
|
|
|
|
|
constructor(
|
# Pull Request: Connection Reporting System & Improvements for Restricted Networks
## Description
This PR introduces a comprehensive **Connection Reporting System** designed to improve the reliability and monitoring of connections, specifically tailored for environments with restricted internet access (e.g., active censorship, GFW).
### Key Changes
1. **New Reporting API (`/report`)**:
* Added `ReportController` and `ReportService` to handle incoming connection reports.
* Endpoint receives data such as `Latency`, `Success` status, `Protocol`, and Client Interface details.
* Data is persisted to the database via the new `ConnectionReport` model.
2. **Subscription Link Updates**:
* Modified `subService` to append a `reportUrl` parameter to generated subscription links (VLESS, VMess, etc.).
* This allows compatible clients to automatically discover the reporting endpoint and send feedback.
3. **Database Integration**:
* Added `ConnectionReport` schema to `database/model` and registered it in `database/db.go` for auto-migration.
## Why is this helpful for Restricted Internet Locations?
In regions with heavy internet censorship, connection stability is volatile.
* **Dynamic Reporting Endpoint**: The `reportUrl` parameter embedded in the subscription link explicitly tells the client *where* to send connection data.
* **Bypassing Blocking**: By decoupling the reporting URL from the node address, clients can ensure diagnostic data reaches the panel even if specific node IPs are being interfered with (assuming the panel itself is reachable).
* **Real-time Network Intelligence**: This mechanism enables the panel to aggregate "ground truth" data from clients inside the restricted network (e.g., latency, accessibility of specific protocols), allowing admins to react faster to blocking events.
* **Protocol Performance Tracking**: Allows comparison of different protocols (Reality vs. VLESS+TLS vs. Trojan) based on real-world latency and success rates from actual users.
* **Rapid Troubleshooting**: Administrators can see connection quality trends and rotate IPs/domains proactively when success rates drop, minimizing downtime for users.
## Technical Details
* **API Endpoint**: `POST /report`
* **Payload Format**: JSON containing `SystemInfo` (Interface), `ConnectionQuality` (Latency, Success), and `ProtocolInfo`.
* **Security**: Reports are tied to valid client request contexts (implementation detail: ensure endpoint is rate-limited or authenticated if necessary, though currently designed for open reporting from valid sub links).
## How to Test
1. Update the panel.
2. Generate a subscription link.
3. Observe the `reportUrl` parameter in the link.
4. Simulate a client POST to the report URL and verify the entry in the `ConnectionReports` table.
2026-02-04 10:00:00 +00:00
|
|
|
mtu = 1250,
|
2024-08-06 15:06:39 +00:00
|
|
|
secretKey = '',
|
|
|
|
|
address = [''],
|
|
|
|
|
workers = 2,
|
|
|
|
|
domainStrategy = '',
|
|
|
|
|
reserved = '',
|
|
|
|
|
peers = [new Outbound.WireguardSettings.Peer()],
|
2024-10-20 10:01:55 +00:00
|
|
|
noKernelTun = false,
|
2024-08-06 15:06:39 +00:00
|
|
|
) {
|
2024-01-10 12:44:18 +00:00
|
|
|
super();
|
|
|
|
|
this.mtu = mtu;
|
|
|
|
|
this.secretKey = secretKey;
|
2024-08-06 15:06:39 +00:00
|
|
|
this.pubKey = secretKey.length > 0 ? Wireguard.generateKeypair(secretKey).publicKey : '';
|
|
|
|
|
this.address = Array.isArray(address) ? address.join(',') : address;
|
2024-01-10 12:44:18 +00:00
|
|
|
this.workers = workers;
|
|
|
|
|
this.domainStrategy = domainStrategy;
|
2024-08-06 15:06:39 +00:00
|
|
|
this.reserved = Array.isArray(reserved) ? reserved.join(',') : reserved;
|
2024-01-10 12:44:18 +00:00
|
|
|
this.peers = peers;
|
2024-10-20 10:01:55 +00:00
|
|
|
this.noKernelTun = noKernelTun;
|
2024-01-10 12:44:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addPeer() {
|
|
|
|
|
this.peers.push(new Outbound.WireguardSettings.Peer());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delPeer(index) {
|
|
|
|
|
this.peers.splice(index, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-01-10 12:44:18 +00:00
|
|
|
return new Outbound.WireguardSettings(
|
|
|
|
|
json.mtu,
|
|
|
|
|
json.secretKey,
|
|
|
|
|
json.address,
|
|
|
|
|
json.workers,
|
|
|
|
|
json.domainStrategy,
|
|
|
|
|
json.reserved,
|
|
|
|
|
json.peers.map(peer => Outbound.WireguardSettings.Peer.fromJson(peer)),
|
2024-10-20 10:01:55 +00:00
|
|
|
json.noKernelTun,
|
2024-01-10 12:44:18 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
2024-08-06 15:06:39 +00:00
|
|
|
mtu: this.mtu ?? undefined,
|
2024-01-10 12:44:18 +00:00
|
|
|
secretKey: this.secretKey,
|
|
|
|
|
address: this.address ? this.address.split(",") : [],
|
2024-08-06 15:06:39 +00:00
|
|
|
workers: this.workers ?? undefined,
|
2024-01-10 12:44:18 +00:00
|
|
|
domainStrategy: WireguardDomainStrategy.includes(this.domainStrategy) ? this.domainStrategy : undefined,
|
2024-02-22 19:10:25 +00:00
|
|
|
reserved: this.reserved ? this.reserved.split(",").map(Number) : undefined,
|
2024-01-10 12:44:18 +00:00
|
|
|
peers: Outbound.WireguardSettings.Peer.toJsonArray(this.peers),
|
2024-10-20 10:01:55 +00:00
|
|
|
noKernelTun: this.noKernelTun,
|
2024-01-10 12:44:18 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Outbound.WireguardSettings.Peer = class extends CommonClass {
|
2024-08-06 15:06:39 +00:00
|
|
|
constructor(
|
|
|
|
|
publicKey = '',
|
|
|
|
|
psk = '',
|
|
|
|
|
allowedIPs = ['0.0.0.0/0', '::/0'],
|
|
|
|
|
endpoint = '',
|
|
|
|
|
keepAlive = 0
|
|
|
|
|
) {
|
2024-01-10 12:44:18 +00:00
|
|
|
super();
|
|
|
|
|
this.publicKey = publicKey;
|
|
|
|
|
this.psk = psk;
|
|
|
|
|
this.allowedIPs = allowedIPs;
|
|
|
|
|
this.endpoint = endpoint;
|
|
|
|
|
this.keepAlive = keepAlive;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 15:06:39 +00:00
|
|
|
static fromJson(json = {}) {
|
2024-01-10 12:44:18 +00:00
|
|
|
return new Outbound.WireguardSettings.Peer(
|
|
|
|
|
json.publicKey,
|
|
|
|
|
json.preSharedKey,
|
|
|
|
|
json.allowedIPs,
|
|
|
|
|
json.endpoint,
|
|
|
|
|
json.keepAlive
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
publicKey: this.publicKey,
|
2024-08-06 15:06:39 +00:00
|
|
|
preSharedKey: this.psk.length > 0 ? this.psk : undefined,
|
2024-01-11 06:27:21 +00:00
|
|
|
allowedIPs: this.allowedIPs ? this.allowedIPs : undefined,
|
2024-01-10 12:44:18 +00:00
|
|
|
endpoint: this.endpoint,
|
2024-08-06 15:06:39 +00:00
|
|
|
keepAlive: this.keepAlive ?? undefined,
|
2024-01-10 12:44:18 +00:00
|
|
|
};
|
|
|
|
|
}
|
2026-01-18 16:13:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Outbound.HysteriaSettings = class extends CommonClass {
|
|
|
|
|
constructor(address = '', port = 443, version = 2) {
|
|
|
|
|
super();
|
|
|
|
|
this.address = address;
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.version = version;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromJson(json = {}) {
|
|
|
|
|
if (Object.keys(json).length === 0) return new Outbound.HysteriaSettings();
|
|
|
|
|
return new Outbound.HysteriaSettings(
|
|
|
|
|
json.address,
|
|
|
|
|
json.port,
|
|
|
|
|
json.version
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toJson() {
|
|
|
|
|
return {
|
|
|
|
|
address: this.address,
|
|
|
|
|
port: this.port,
|
|
|
|
|
version: this.version
|
|
|
|
|
};
|
|
|
|
|
}
|
2023-12-05 17:13:36 +00:00
|
|
|
};
|