diff --git a/PasarGuardNodeBridge/abstract_node.py b/PasarGuardNodeBridge/abstract_node.py index 772660f..a0762b0 100644 --- a/PasarGuardNodeBridge/abstract_node.py +++ b/PasarGuardNodeBridge/abstract_node.py @@ -16,6 +16,11 @@ async def start( keep_alive: int, exclude_inbounds: list[str], timeout: int | None, + # Limit enforcer configuration (optional) + node_id: int = 0, + panel_api_url: str = "", + limit_check_interval: int = 30, + limit_refresh_interval: int = 60, ) -> service.BaseInfoResponse | None: raise NotImplementedError diff --git a/PasarGuardNodeBridge/common/service.proto b/PasarGuardNodeBridge/common/service.proto index 82b7608..f001176 100644 --- a/PasarGuardNodeBridge/common/service.proto +++ b/PasarGuardNodeBridge/common/service.proto @@ -23,6 +23,12 @@ message Backend { repeated User users = 3; uint64 keep_alive = 4; repeated string exclude_inbounds = 5; + + // Limit enforcer configuration (sent from panel) + int32 node_id = 6; + string panel_api_url = 7; + int32 limit_check_interval = 8; // seconds, default 30 + int32 limit_refresh_interval = 9; // seconds, default 60 } // log diff --git a/PasarGuardNodeBridge/common/service_pb2.py b/PasarGuardNodeBridge/common/service_pb2.py index 60897a3..ff8ca78 100644 --- a/PasarGuardNodeBridge/common/service_pb2.py +++ b/PasarGuardNodeBridge/common/service_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)PasarGuardNodeBridge/common/service.proto\x12\x07service\"\x07\n\x05\x45mpty\"O\n\x10\x42\x61seInfoResponse\x12\x0f\n\x07started\x18\x01 \x01(\x08\x12\x14\n\x0c\x63ore_version\x18\x02 \x01(\t\x12\x14\n\x0cnode_version\x18\x03 \x01(\t\"\x89\x01\n\x07\x42\x61\x63kend\x12\"\n\x04type\x18\x01 \x01(\x0e\x32\x14.service.BackendType\x12\x0e\n\x06\x63onfig\x18\x02 \x01(\t\x12\x1c\n\x05users\x18\x03 \x03(\x0b\x32\r.service.User\x12\x12\n\nkeep_alive\x18\x04 \x01(\x04\x12\x18\n\x10\x65xclude_inbounds\x18\x05 \x03(\t\"\x15\n\x03Log\x12\x0e\n\x06\x64\x65tail\x18\x01 \x01(\t\"?\n\x04Stat\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04link\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\x03\",\n\x0cStatResponse\x12\x1c\n\x05stats\x18\x01 \x03(\x0b\x32\r.service.Stat\"K\n\x0bStatRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05reset\x18\x02 \x01(\x08\x12\x1f\n\x04type\x18\x03 \x01(\x0e\x32\x11.service.StatType\"1\n\x12OnlineStatResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03\"\x8f\x01\n\x19StatsOnlineIpListResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x03ips\x18\x02 \x03(\x0b\x32+.service.StatsOnlineIpListResponse.IpsEntry\x1a*\n\x08IpsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\"\xcc\x01\n\x14\x42\x61\x63kendStatsResponse\x12\x15\n\rnum_goroutine\x18\x01 \x01(\r\x12\x0e\n\x06num_gc\x18\x02 \x01(\r\x12\r\n\x05\x61lloc\x18\x03 \x01(\x04\x12\x13\n\x0btotal_alloc\x18\x04 \x01(\x04\x12\x0b\n\x03sys\x18\x05 \x01(\x04\x12\x0f\n\x07mallocs\x18\x06 \x01(\x04\x12\r\n\x05\x66rees\x18\x07 \x01(\x04\x12\x14\n\x0clive_objects\x18\x08 \x01(\x04\x12\x16\n\x0epause_total_ns\x18\t \x01(\x04\x12\x0e\n\x06uptime\x18\n \x01(\r\"\xa4\x01\n\x13SystemStatsResponse\x12\x11\n\tmem_total\x18\x01 \x01(\x04\x12\x10\n\x08mem_used\x18\x02 \x01(\x04\x12\x11\n\tcpu_cores\x18\x03 \x01(\x04\x12\x11\n\tcpu_usage\x18\x04 \x01(\x01\x12 \n\x18incoming_bandwidth_speed\x18\x05 \x01(\x04\x12 \n\x18outgoing_bandwidth_speed\x18\x06 \x01(\x04\"\x13\n\x05Vmess\x12\n\n\x02id\x18\x01 \x01(\t\"!\n\x05Vless\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x66low\x18\x02 \x01(\t\"\x1a\n\x06Trojan\x12\x10\n\x08password\x18\x01 \x01(\t\"/\n\x0bShadowsocks\x12\x10\n\x08password\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\"\x91\x01\n\x05Proxy\x12\x1d\n\x05vmess\x18\x01 \x01(\x0b\x32\x0e.service.Vmess\x12\x1d\n\x05vless\x18\x02 \x01(\x0b\x32\x0e.service.Vless\x12\x1f\n\x06trojan\x18\x03 \x01(\x0b\x32\x0f.service.Trojan\x12)\n\x0bshadowsocks\x18\x04 \x01(\x0b\x32\x14.service.Shadowsocks\"H\n\x04User\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x1f\n\x07proxies\x18\x02 \x01(\x0b\x32\x0e.service.Proxy\x12\x10\n\x08inbounds\x18\x03 \x03(\t\"%\n\x05Users\x12\x1c\n\x05users\x18\x01 \x03(\x0b\x32\r.service.User\"G\n\nUsersChunk\x12\x1c\n\x05users\x18\x01 \x03(\x0b\x32\r.service.User\x12\r\n\x05index\x18\x02 \x01(\x04\x12\x0c\n\x04last\x18\x03 \x01(\x08*\x17\n\x0b\x42\x61\x63kendType\x12\x08\n\x04XRAY\x10\x00*_\n\x08StatType\x12\r\n\tOutbounds\x10\x00\x12\x0c\n\x08Outbound\x10\x01\x12\x0c\n\x08Inbounds\x10\x02\x12\x0b\n\x07Inbound\x10\x03\x12\r\n\tUsersStat\x10\x04\x12\x0c\n\x08UserStat\x10\x05\x32\xd7\x05\n\x0bNodeService\x12\x36\n\x05Start\x12\x10.service.Backend\x1a\x19.service.BaseInfoResponse\"\x00\x12(\n\x04Stop\x12\x0e.service.Empty\x1a\x0e.service.Empty\"\x00\x12:\n\x0bGetBaseInfo\x12\x0e.service.Empty\x1a\x19.service.BaseInfoResponse\"\x00\x12+\n\x07GetLogs\x12\x0e.service.Empty\x1a\x0c.service.Log\"\x00\x30\x01\x12@\n\x0eGetSystemStats\x12\x0e.service.Empty\x1a\x1c.service.SystemStatsResponse\"\x00\x12\x42\n\x0fGetBackendStats\x12\x0e.service.Empty\x1a\x1d.service.BackendStatsResponse\"\x00\x12\x39\n\x08GetStats\x12\x14.service.StatRequest\x1a\x15.service.StatResponse\"\x00\x12I\n\x12GetUserOnlineStats\x12\x14.service.StatRequest\x1a\x1b.service.OnlineStatResponse\"\x00\x12V\n\x18GetUserOnlineIpListStats\x12\x14.service.StatRequest\x1a\".service.StatsOnlineIpListResponse\"\x00\x12-\n\x08SyncUser\x12\r.service.User\x1a\x0e.service.Empty\"\x00(\x01\x12-\n\tSyncUsers\x12\x0e.service.Users\x1a\x0e.service.Empty\"\x00\x12;\n\x10SyncUsersChunked\x12\x13.service.UsersChunk\x1a\x0e.service.Empty\"\x00(\x01\x42#Z!github.com/pasarguard/node/commonb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)PasarGuardNodeBridge/common/service.proto\x12\x07service\"\x07\n\x05\x45mpty\"O\n\x10\x42\x61seInfoResponse\x12\x0f\n\x07started\x18\x01 \x01(\x08\x12\x14\n\x0c\x63ore_version\x18\x02 \x01(\t\x12\x14\n\x0cnode_version\x18\x03 \x01(\t\"\xef\x01\n\x07\x42\x61\x63kend\x12\"\n\x04type\x18\x01 \x01(\x0e\x32\x14.service.BackendType\x12\x0e\n\x06\x63onfig\x18\x02 \x01(\t\x12\x1c\n\x05users\x18\x03 \x03(\x0b\x32\r.service.User\x12\x12\n\nkeep_alive\x18\x04 \x01(\x04\x12\x18\n\x10\x65xclude_inbounds\x18\x05 \x03(\t\x12\x0f\n\x07node_id\x18\x06 \x01(\x05\x12\x15\n\rpanel_api_url\x18\x07 \x01(\t\x12\x1c\n\x14limit_check_interval\x18\x08 \x01(\x05\x12\x1e\n\x16limit_refresh_interval\x18\t \x01(\x05\"\x15\n\x03Log\x12\x0e\n\x06\x64\x65tail\x18\x01 \x01(\t\"?\n\x04Stat\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04link\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\x03\",\n\x0cStatResponse\x12\x1c\n\x05stats\x18\x01 \x03(\x0b\x32\r.service.Stat\"K\n\x0bStatRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05reset\x18\x02 \x01(\x08\x12\x1f\n\x04type\x18\x03 \x01(\x0e\x32\x11.service.StatType\"1\n\x12OnlineStatResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03\"\x8f\x01\n\x19StatsOnlineIpListResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x03ips\x18\x02 \x03(\x0b\x32+.service.StatsOnlineIpListResponse.IpsEntry\x1a*\n\x08IpsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\"\xcc\x01\n\x14\x42\x61\x63kendStatsResponse\x12\x15\n\rnum_goroutine\x18\x01 \x01(\r\x12\x0e\n\x06num_gc\x18\x02 \x01(\r\x12\r\n\x05\x61lloc\x18\x03 \x01(\x04\x12\x13\n\x0btotal_alloc\x18\x04 \x01(\x04\x12\x0b\n\x03sys\x18\x05 \x01(\x04\x12\x0f\n\x07mallocs\x18\x06 \x01(\x04\x12\r\n\x05\x66rees\x18\x07 \x01(\x04\x12\x14\n\x0clive_objects\x18\x08 \x01(\x04\x12\x16\n\x0epause_total_ns\x18\t \x01(\x04\x12\x0e\n\x06uptime\x18\n \x01(\r\"\xa4\x01\n\x13SystemStatsResponse\x12\x11\n\tmem_total\x18\x01 \x01(\x04\x12\x10\n\x08mem_used\x18\x02 \x01(\x04\x12\x11\n\tcpu_cores\x18\x03 \x01(\x04\x12\x11\n\tcpu_usage\x18\x04 \x01(\x01\x12 \n\x18incoming_bandwidth_speed\x18\x05 \x01(\x04\x12 \n\x18outgoing_bandwidth_speed\x18\x06 \x01(\x04\"\x13\n\x05Vmess\x12\n\n\x02id\x18\x01 \x01(\t\"!\n\x05Vless\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x66low\x18\x02 \x01(\t\"\x1a\n\x06Trojan\x12\x10\n\x08password\x18\x01 \x01(\t\"/\n\x0bShadowsocks\x12\x10\n\x08password\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\"\x91\x01\n\x05Proxy\x12\x1d\n\x05vmess\x18\x01 \x01(\x0b\x32\x0e.service.Vmess\x12\x1d\n\x05vless\x18\x02 \x01(\x0b\x32\x0e.service.Vless\x12\x1f\n\x06trojan\x18\x03 \x01(\x0b\x32\x0f.service.Trojan\x12)\n\x0bshadowsocks\x18\x04 \x01(\x0b\x32\x14.service.Shadowsocks\"H\n\x04User\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x1f\n\x07proxies\x18\x02 \x01(\x0b\x32\x0e.service.Proxy\x12\x10\n\x08inbounds\x18\x03 \x03(\t\"%\n\x05Users\x12\x1c\n\x05users\x18\x01 \x03(\x0b\x32\r.service.User\"G\n\nUsersChunk\x12\x1c\n\x05users\x18\x01 \x03(\x0b\x32\r.service.User\x12\r\n\x05index\x18\x02 \x01(\x04\x12\x0c\n\x04last\x18\x03 \x01(\x08*\x17\n\x0b\x42\x61\x63kendType\x12\x08\n\x04XRAY\x10\x00*_\n\x08StatType\x12\r\n\tOutbounds\x10\x00\x12\x0c\n\x08Outbound\x10\x01\x12\x0c\n\x08Inbounds\x10\x02\x12\x0b\n\x07Inbound\x10\x03\x12\r\n\tUsersStat\x10\x04\x12\x0c\n\x08UserStat\x10\x05\x32\xd7\x05\n\x0bNodeService\x12\x36\n\x05Start\x12\x10.service.Backend\x1a\x19.service.BaseInfoResponse\"\x00\x12(\n\x04Stop\x12\x0e.service.Empty\x1a\x0e.service.Empty\"\x00\x12:\n\x0bGetBaseInfo\x12\x0e.service.Empty\x1a\x19.service.BaseInfoResponse\"\x00\x12+\n\x07GetLogs\x12\x0e.service.Empty\x1a\x0c.service.Log\"\x00\x30\x01\x12@\n\x0eGetSystemStats\x12\x0e.service.Empty\x1a\x1c.service.SystemStatsResponse\"\x00\x12\x42\n\x0fGetBackendStats\x12\x0e.service.Empty\x1a\x1d.service.BackendStatsResponse\"\x00\x12\x39\n\x08GetStats\x12\x14.service.StatRequest\x1a\x15.service.StatResponse\"\x00\x12I\n\x12GetUserOnlineStats\x12\x14.service.StatRequest\x1a\x1b.service.OnlineStatResponse\"\x00\x12V\n\x18GetUserOnlineIpListStats\x12\x14.service.StatRequest\x1a\".service.StatsOnlineIpListResponse\"\x00\x12-\n\x08SyncUser\x12\r.service.User\x1a\x0e.service.Empty\"\x00(\x01\x12-\n\tSyncUsers\x12\x0e.service.Users\x1a\x0e.service.Empty\"\x00\x12;\n\x10SyncUsersChunked\x12\x13.service.UsersChunk\x1a\x0e.service.Empty\"\x00(\x01\x42#Z!github.com/pasarguard/node/commonb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -34,50 +34,50 @@ _globals['DESCRIPTOR']._serialized_options = b'Z!github.com/pasarguard/node/common' _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._loaded_options = None _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._serialized_options = b'8\001' - _globals['_BACKENDTYPE']._serialized_start=1533 - _globals['_BACKENDTYPE']._serialized_end=1556 - _globals['_STATTYPE']._serialized_start=1558 - _globals['_STATTYPE']._serialized_end=1653 + _globals['_BACKENDTYPE']._serialized_start=1635 + _globals['_BACKENDTYPE']._serialized_end=1658 + _globals['_STATTYPE']._serialized_start=1660 + _globals['_STATTYPE']._serialized_end=1755 _globals['_EMPTY']._serialized_start=54 _globals['_EMPTY']._serialized_end=61 _globals['_BASEINFORESPONSE']._serialized_start=63 _globals['_BASEINFORESPONSE']._serialized_end=142 _globals['_BACKEND']._serialized_start=145 - _globals['_BACKEND']._serialized_end=282 - _globals['_LOG']._serialized_start=284 - _globals['_LOG']._serialized_end=305 - _globals['_STAT']._serialized_start=307 - _globals['_STAT']._serialized_end=370 - _globals['_STATRESPONSE']._serialized_start=372 - _globals['_STATRESPONSE']._serialized_end=416 - _globals['_STATREQUEST']._serialized_start=418 - _globals['_STATREQUEST']._serialized_end=493 - _globals['_ONLINESTATRESPONSE']._serialized_start=495 - _globals['_ONLINESTATRESPONSE']._serialized_end=544 - _globals['_STATSONLINEIPLISTRESPONSE']._serialized_start=547 - _globals['_STATSONLINEIPLISTRESPONSE']._serialized_end=690 - _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._serialized_start=648 - _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._serialized_end=690 - _globals['_BACKENDSTATSRESPONSE']._serialized_start=693 - _globals['_BACKENDSTATSRESPONSE']._serialized_end=897 - _globals['_SYSTEMSTATSRESPONSE']._serialized_start=900 - _globals['_SYSTEMSTATSRESPONSE']._serialized_end=1064 - _globals['_VMESS']._serialized_start=1066 - _globals['_VMESS']._serialized_end=1085 - _globals['_VLESS']._serialized_start=1087 - _globals['_VLESS']._serialized_end=1120 - _globals['_TROJAN']._serialized_start=1122 - _globals['_TROJAN']._serialized_end=1148 - _globals['_SHADOWSOCKS']._serialized_start=1150 - _globals['_SHADOWSOCKS']._serialized_end=1197 - _globals['_PROXY']._serialized_start=1200 - _globals['_PROXY']._serialized_end=1345 - _globals['_USER']._serialized_start=1347 - _globals['_USER']._serialized_end=1419 - _globals['_USERS']._serialized_start=1421 - _globals['_USERS']._serialized_end=1458 - _globals['_USERSCHUNK']._serialized_start=1460 - _globals['_USERSCHUNK']._serialized_end=1531 - _globals['_NODESERVICE']._serialized_start=1656 - _globals['_NODESERVICE']._serialized_end=2383 + _globals['_BACKEND']._serialized_end=384 + _globals['_LOG']._serialized_start=386 + _globals['_LOG']._serialized_end=407 + _globals['_STAT']._serialized_start=409 + _globals['_STAT']._serialized_end=472 + _globals['_STATRESPONSE']._serialized_start=474 + _globals['_STATRESPONSE']._serialized_end=518 + _globals['_STATREQUEST']._serialized_start=520 + _globals['_STATREQUEST']._serialized_end=595 + _globals['_ONLINESTATRESPONSE']._serialized_start=597 + _globals['_ONLINESTATRESPONSE']._serialized_end=646 + _globals['_STATSONLINEIPLISTRESPONSE']._serialized_start=649 + _globals['_STATSONLINEIPLISTRESPONSE']._serialized_end=792 + _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._serialized_start=750 + _globals['_STATSONLINEIPLISTRESPONSE_IPSENTRY']._serialized_end=792 + _globals['_BACKENDSTATSRESPONSE']._serialized_start=795 + _globals['_BACKENDSTATSRESPONSE']._serialized_end=999 + _globals['_SYSTEMSTATSRESPONSE']._serialized_start=1002 + _globals['_SYSTEMSTATSRESPONSE']._serialized_end=1166 + _globals['_VMESS']._serialized_start=1168 + _globals['_VMESS']._serialized_end=1187 + _globals['_VLESS']._serialized_start=1189 + _globals['_VLESS']._serialized_end=1222 + _globals['_TROJAN']._serialized_start=1224 + _globals['_TROJAN']._serialized_end=1250 + _globals['_SHADOWSOCKS']._serialized_start=1252 + _globals['_SHADOWSOCKS']._serialized_end=1299 + _globals['_PROXY']._serialized_start=1302 + _globals['_PROXY']._serialized_end=1447 + _globals['_USER']._serialized_start=1449 + _globals['_USER']._serialized_end=1521 + _globals['_USERS']._serialized_start=1523 + _globals['_USERS']._serialized_end=1560 + _globals['_USERSCHUNK']._serialized_start=1562 + _globals['_USERSCHUNK']._serialized_end=1633 + _globals['_NODESERVICE']._serialized_start=1758 + _globals['_NODESERVICE']._serialized_end=2485 # @@protoc_insertion_point(module_scope) diff --git a/PasarGuardNodeBridge/common/service_pb2.pyi b/PasarGuardNodeBridge/common/service_pb2.pyi index 10fecdf..b295ca5 100644 --- a/PasarGuardNodeBridge/common/service_pb2.pyi +++ b/PasarGuardNodeBridge/common/service_pb2.pyi @@ -42,18 +42,26 @@ class BaseInfoResponse(_message.Message): def __init__(self, started: bool = ..., core_version: _Optional[str] = ..., node_version: _Optional[str] = ...) -> None: ... class Backend(_message.Message): - __slots__ = ("type", "config", "users", "keep_alive", "exclude_inbounds") + __slots__ = ("type", "config", "users", "keep_alive", "exclude_inbounds", "node_id", "panel_api_url", "limit_check_interval", "limit_refresh_interval") TYPE_FIELD_NUMBER: _ClassVar[int] CONFIG_FIELD_NUMBER: _ClassVar[int] USERS_FIELD_NUMBER: _ClassVar[int] KEEP_ALIVE_FIELD_NUMBER: _ClassVar[int] EXCLUDE_INBOUNDS_FIELD_NUMBER: _ClassVar[int] + NODE_ID_FIELD_NUMBER: _ClassVar[int] + PANEL_API_URL_FIELD_NUMBER: _ClassVar[int] + LIMIT_CHECK_INTERVAL_FIELD_NUMBER: _ClassVar[int] + LIMIT_REFRESH_INTERVAL_FIELD_NUMBER: _ClassVar[int] type: BackendType config: str users: _containers.RepeatedCompositeFieldContainer[User] keep_alive: int exclude_inbounds: _containers.RepeatedScalarFieldContainer[str] - def __init__(self, type: _Optional[_Union[BackendType, str]] = ..., config: _Optional[str] = ..., users: _Optional[_Iterable[_Union[User, _Mapping]]] = ..., keep_alive: _Optional[int] = ..., exclude_inbounds: _Optional[_Iterable[str]] = ...) -> None: ... + node_id: int + panel_api_url: str + limit_check_interval: int + limit_refresh_interval: int + def __init__(self, type: _Optional[_Union[BackendType, str]] = ..., config: _Optional[str] = ..., users: _Optional[_Iterable[_Union[User, _Mapping]]] = ..., keep_alive: _Optional[int] = ..., exclude_inbounds: _Optional[_Iterable[str]] = ..., node_id: _Optional[int] = ..., panel_api_url: _Optional[str] = ..., limit_check_interval: _Optional[int] = ..., limit_refresh_interval: _Optional[int] = ...) -> None: ... class Log(_message.Message): __slots__ = ("detail",) diff --git a/PasarGuardNodeBridge/grpclib.py b/PasarGuardNodeBridge/grpclib.py index f2ebc03..65680a4 100644 --- a/PasarGuardNodeBridge/grpclib.py +++ b/PasarGuardNodeBridge/grpclib.py @@ -105,6 +105,11 @@ async def start( keep_alive: int = 0, exclude_inbounds: list[str] = [], timeout: int | None = None, + # Limit enforcer configuration (optional - sent to node for real-time enforcement) + node_id: int = 0, + panel_api_url: str = "", + limit_check_interval: int = 30, + limit_refresh_interval: int = 60, ) -> service.BaseInfoResponse | None: """Start the node with proper task management""" timeout = timeout or self._default_timeout @@ -113,7 +118,15 @@ async def start( raise NodeAPIError(code=-4, detail="Invalid node") req = service.Backend( - type=backend_type, config=config, users=users, keep_alive=keep_alive, exclude_inbounds=exclude_inbounds + type=backend_type, + config=config, + users=users, + keep_alive=keep_alive, + exclude_inbounds=exclude_inbounds, + node_id=node_id, + panel_api_url=panel_api_url, + limit_check_interval=limit_check_interval, + limit_refresh_interval=limit_refresh_interval, ) async with self._node_lock: diff --git a/PasarGuardNodeBridge/rest.py b/PasarGuardNodeBridge/rest.py index 69e3bb7..1d8a9de 100644 --- a/PasarGuardNodeBridge/rest.py +++ b/PasarGuardNodeBridge/rest.py @@ -120,6 +120,11 @@ async def start( keep_alive: int = 0, exclude_inbounds: list[str] = [], timeout: int | None = None, + # Limit enforcer configuration (optional - sent to node for real-time enforcement) + node_id: int = 0, + panel_api_url: str = "", + limit_check_interval: int = 30, + limit_refresh_interval: int = 60, ): """Start the node with proper task management""" timeout = timeout or self._default_timeout @@ -138,6 +143,10 @@ async def start( users=users, keep_alive=keep_alive, exclude_inbounds=exclude_inbounds, + node_id=node_id, + panel_api_url=panel_api_url, + limit_check_interval=limit_check_interval, + limit_refresh_interval=limit_refresh_interval, ), proto_response_class=service.BaseInfoResponse, )