mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
Routing config: Add processName (#5489)
This commit is contained in:
@@ -2,6 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -305,3 +306,41 @@ func (m *AttributeMatcher) Apply(ctx routing.Context) bool {
|
||||
}
|
||||
return m.Match(attributes)
|
||||
}
|
||||
|
||||
type ProcessNameMatcher struct {
|
||||
names []string
|
||||
}
|
||||
|
||||
func (m *ProcessNameMatcher) Apply(ctx routing.Context) bool {
|
||||
srcPort := ctx.GetSourcePort().String()
|
||||
srcIP := ctx.GetSourceIPs()[0].String()
|
||||
var network string
|
||||
switch ctx.GetNetwork() {
|
||||
case net.Network_TCP:
|
||||
network = "tcp"
|
||||
case net.Network_UDP:
|
||||
network = "udp"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
src, err := net.ParseDestination(strings.Join([]string{network, srcIP, srcPort}, ":"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pid, name, err := net.FindProcess(src)
|
||||
if err != nil {
|
||||
if err != net.ErrNotLocal {
|
||||
errors.LogError(context.Background(), "Unables to find local process name: ", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
for _, n := range m.names {
|
||||
if name == "/self" && pid == os.Getpid() {
|
||||
return true
|
||||
}
|
||||
if n == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -106,6 +106,14 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
|
||||
conds.Add(matcher)
|
||||
}
|
||||
|
||||
if len(rr.ProcessName) > 0 {
|
||||
refinedNames := make([]string, 0, len(rr.ProcessName))
|
||||
for _, name := range rr.ProcessName {
|
||||
refinedNames = append(refinedNames, strings.TrimSuffix(name, ".exe"))
|
||||
}
|
||||
conds.Add(&ProcessNameMatcher{refinedNames})
|
||||
}
|
||||
|
||||
if conds.Len() == 0 {
|
||||
return nil, errors.New("this rule has no effective fields").AtWarning()
|
||||
}
|
||||
|
||||
@@ -490,6 +490,7 @@ type RoutingRule struct {
|
||||
LocalGeoip []*GeoIP `protobuf:"bytes,17,rep,name=local_geoip,json=localGeoip,proto3" json:"local_geoip,omitempty"`
|
||||
LocalPortList *net.PortList `protobuf:"bytes,18,opt,name=local_port_list,json=localPortList,proto3" json:"local_port_list,omitempty"`
|
||||
VlessRouteList *net.PortList `protobuf:"bytes,20,opt,name=vless_route_list,json=vlessRouteList,proto3" json:"vless_route_list,omitempty"`
|
||||
ProcessName []string `protobuf:"bytes,21,rep,name=process_name,json=processName,proto3" json:"process_name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RoutingRule) Reset() {
|
||||
@@ -641,6 +642,13 @@ func (x *RoutingRule) GetVlessRouteList() *net.PortList {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RoutingRule) GetProcessName() []string {
|
||||
if x != nil {
|
||||
return x.ProcessName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isRoutingRule_TargetTag interface {
|
||||
isRoutingRule_TargetTag()
|
||||
}
|
||||
@@ -1081,7 +1089,7 @@ var file_app_router_config_proto_rawDesc = []byte{
|
||||
0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
|
||||
0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69,
|
||||
0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xe8, 0x06, 0x0a, 0x0b, 0x52, 0x6f,
|
||||
0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x8b, 0x07, 0x0a, 0x0b, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a,
|
||||
0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c,
|
||||
@@ -1131,66 +1139,68 @@ var file_app_router_config_proto_rawDesc = []byte{
|
||||
0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78,
|
||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50,
|
||||
0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69,
|
||||
0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x5f, 0x74, 0x61, 0x67, 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69,
|
||||
0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62,
|
||||
0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c,
|
||||
0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
|
||||
0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
|
||||
0x79, 0x12, 0x4d, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x5f, 0x73, 0x65,
|
||||
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78,
|
||||
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61,
|
||||
0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10,
|
||||
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x61, 0x67,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
|
||||
0x54, 0x61, 0x67, 0x22, 0x54, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61,
|
||||
0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x17, 0x53, 0x74,
|
||||
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57,
|
||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52,
|
||||
0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78,
|
||||
0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78,
|
||||
0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x90, 0x02, 0x0a,
|
||||
0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69,
|
||||
0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
|
||||
0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
||||
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
|
||||
0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61,
|
||||
0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75,
|
||||
0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c,
|
||||
0x65, 0x22, 0x3c, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74,
|
||||
0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x10, 0x0a,
|
||||
0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12,
|
||||
0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42,
|
||||
0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
|
||||
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02,
|
||||
0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x75, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65,
|
||||
0x73, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70,
|
||||
0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74,
|
||||
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72,
|
||||
0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61,
|
||||
0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f,
|
||||
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x61,
|
||||
0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x61,
|
||||
0x74, 0x65, 0x67, 0x79, 0x12, 0x4d, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
|
||||
0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x52, 0x10, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69,
|
||||
0x6e, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f,
|
||||
0x74, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x61, 0x6c, 0x6c, 0x62,
|
||||
0x61, 0x63, 0x6b, 0x54, 0x61, 0x67, 0x22, 0x54, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
|
||||
0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65,
|
||||
0x78, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc0, 0x01, 0x0a,
|
||||
0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f,
|
||||
0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
|
||||
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
|
||||
0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78,
|
||||
0x52, 0x54, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54,
|
||||
0x54, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x22,
|
||||
0x90, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f,
|
||||
0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72,
|
||||
0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79,
|
||||
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a,
|
||||
0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
|
||||
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e,
|
||||
0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x22, 0x3c, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74,
|
||||
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00,
|
||||
0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68,
|
||||
0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64,
|
||||
0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
|
||||
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
|
||||
0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -113,6 +113,7 @@ message RoutingRule {
|
||||
xray.common.net.PortList local_port_list = 18;
|
||||
|
||||
xray.common.net.PortList vless_route_list = 20;
|
||||
repeated string process_name = 21;
|
||||
}
|
||||
|
||||
message BalancingRule {
|
||||
|
||||
178
common/net/find_process_linux.go
Normal file
178
common/net/find_process_linux.go
Normal file
@@ -0,0 +1,178 @@
|
||||
//go:build linux
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
func FindProcess(dest Destination) (int, string, error) {
|
||||
isLocal, err := IsLocal(dest.Address.IP())
|
||||
if err != nil {
|
||||
return 0, "", errors.New("failed to determine if address is local: ", err)
|
||||
}
|
||||
if !isLocal {
|
||||
return 0, "", ErrNotLocal
|
||||
}
|
||||
if dest.Network != Network_TCP && dest.Network != Network_UDP {
|
||||
panic("Unsupported network type for process lookup.")
|
||||
}
|
||||
// the core should never has a domain as source(?
|
||||
if dest.Address.Family() == AddressFamilyDomain {
|
||||
panic("Domain addresses are not supported for process lookup.")
|
||||
}
|
||||
var procFile string
|
||||
|
||||
switch dest.Network {
|
||||
case Network_TCP:
|
||||
if dest.Address.Family() == AddressFamilyIPv4 {
|
||||
procFile = "/proc/net/tcp"
|
||||
}
|
||||
if dest.Address.Family() == AddressFamilyIPv6 {
|
||||
procFile = "/proc/net/tcp6"
|
||||
}
|
||||
case Network_UDP:
|
||||
if dest.Address.Family() == AddressFamilyIPv4 {
|
||||
procFile = "/proc/net/udp"
|
||||
}
|
||||
if dest.Address.Family() == AddressFamilyIPv6 {
|
||||
procFile = "/proc/net/udp6"
|
||||
}
|
||||
default:
|
||||
panic("Unsupported network type for process lookup.")
|
||||
}
|
||||
|
||||
targetHexAddr, err := formatLittleEndianString(dest.Address, dest.Port)
|
||||
if err != nil {
|
||||
return 0, "", errors.New("failed to format address: ", err)
|
||||
}
|
||||
|
||||
inode, err := findInodeInFile(procFile, targetHexAddr)
|
||||
if err != nil {
|
||||
return 0, "", errors.New("could not search in ", procFile).Base(err)
|
||||
}
|
||||
if inode == "" {
|
||||
return 0, "", errors.New("connection for ", dest.Address, ":", dest.Port, " not found in ", procFile)
|
||||
}
|
||||
|
||||
pidStr, err := findPidByInode(inode)
|
||||
if err != nil {
|
||||
return 0, "", errors.New("could not find PID for inode ", inode, ": ", err)
|
||||
}
|
||||
if pidStr == "" {
|
||||
return 0, "", errors.New("no process found for inode ", inode)
|
||||
}
|
||||
|
||||
procName, err := getProcessName(pidStr)
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("could not get process name for PID %s: %w", pidStr, err)
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
if err != nil {
|
||||
return 0, "", errors.New("failed to parse PID: ", err)
|
||||
}
|
||||
|
||||
return pid, procName, nil
|
||||
}
|
||||
|
||||
func formatLittleEndianString(addr Address, port Port) (string, error) {
|
||||
ip := addr.IP()
|
||||
var ipBytes []byte
|
||||
if addr.Family() == AddressFamilyIPv4 {
|
||||
ipBytes = ip.To4()
|
||||
} else {
|
||||
ipBytes = ip.To16()
|
||||
}
|
||||
if ipBytes == nil {
|
||||
return "", errors.New("invalid IP format for ", addr.Family(), ": ", ip)
|
||||
}
|
||||
|
||||
for i, j := 0, len(ipBytes)-1; i < j; i, j = i+1, j-1 {
|
||||
ipBytes[i], ipBytes[j] = ipBytes[j], ipBytes[i]
|
||||
}
|
||||
portHex := fmt.Sprintf("%04X", uint16(port))
|
||||
ipHex := strings.ToUpper(hex.EncodeToString(ipBytes))
|
||||
return fmt.Sprintf("%s:%s", ipHex, portHex), nil
|
||||
}
|
||||
|
||||
func findInodeInFile(filePath, targetHexAddr string) (string, error) {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
fields := strings.Fields(line)
|
||||
|
||||
if len(fields) < 10 {
|
||||
continue
|
||||
}
|
||||
|
||||
localAddress := fields[1]
|
||||
if localAddress == targetHexAddr {
|
||||
inode := fields[9]
|
||||
return inode, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", scanner.Err()
|
||||
}
|
||||
|
||||
func findPidByInode(inode string) (string, error) {
|
||||
procDir, err := os.ReadDir("/proc")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
targetLink := "socket:[" + inode + "]"
|
||||
|
||||
for _, entry := range procDir {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
pid := entry.Name()
|
||||
if _, err := strconv.Atoi(pid); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
fdPath := fmt.Sprintf("/proc/%s/fd", pid)
|
||||
fdDir, err := os.ReadDir(fdPath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, fdEntry := range fdDir {
|
||||
linkPath := fmt.Sprintf("%s/%s", fdPath, fdEntry.Name())
|
||||
linkTarget, err := os.Readlink(linkPath)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if linkTarget == targetLink {
|
||||
return pid, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func getProcessName(pid string) (string, error) {
|
||||
path := fmt.Sprintf("/proc/%s/comm", pid)
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// remove trailing \n
|
||||
return strings.TrimSpace(string(content)), nil
|
||||
}
|
||||
11
common/net/find_process_others.go
Normal file
11
common/net/find_process_others.go
Normal file
@@ -0,0 +1,11 @@
|
||||
//go:build !windows && !linux
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
func FindProcess(dest Destination) (int, string, error) {
|
||||
return 0, "", errors.New("process lookup is not supported on this platform")
|
||||
}
|
||||
243
common/net/find_process_windows.go
Normal file
243
common/net/find_process_windows.go
Normal file
@@ -0,0 +1,243 @@
|
||||
//go:build windows
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
tcpTableFunc = "GetExtendedTcpTable"
|
||||
tcpTablePidConn = 4
|
||||
udpTableFunc = "GetExtendedUdpTable"
|
||||
udpTablePid = 1
|
||||
)
|
||||
|
||||
var (
|
||||
getExTCPTable uintptr
|
||||
getExUDPTable uintptr
|
||||
|
||||
once sync.Once
|
||||
initErr error
|
||||
)
|
||||
|
||||
func initWin32API() error {
|
||||
h, err := windows.LoadLibrary("iphlpapi.dll")
|
||||
if err != nil {
|
||||
return errors.New("LoadLibrary iphlpapi.dll failed").Base(err)
|
||||
}
|
||||
|
||||
getExTCPTable, err = windows.GetProcAddress(h, tcpTableFunc)
|
||||
if err != nil {
|
||||
return errors.New("GetProcAddress of ", tcpTableFunc, " failed").Base(err)
|
||||
}
|
||||
|
||||
getExUDPTable, err = windows.GetProcAddress(h, udpTableFunc)
|
||||
if err != nil {
|
||||
return errors.New("GetProcAddress of ", udpTableFunc, " failed").Base(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindProcess(dest Destination) (int, string, error) {
|
||||
once.Do(func() {
|
||||
initErr = initWin32API()
|
||||
})
|
||||
if initErr != nil {
|
||||
return 0, "", initErr
|
||||
}
|
||||
isLocal, err := IsLocal(dest.Address.IP())
|
||||
if err != nil {
|
||||
return 0, "", errors.New("failed to determine if address is local: ", err)
|
||||
}
|
||||
if !isLocal {
|
||||
return 0, "", ErrNotLocal
|
||||
}
|
||||
if dest.Network != Network_TCP && dest.Network != Network_UDP {
|
||||
panic("Unsupported network type for process lookup.")
|
||||
}
|
||||
// the core should never has a domain as source(?
|
||||
if dest.Address.Family() == AddressFamilyDomain {
|
||||
panic("Domain addresses are not supported for process lookup.")
|
||||
}
|
||||
var class int
|
||||
var fn uintptr
|
||||
switch dest.Network {
|
||||
case Network_TCP:
|
||||
fn = getExTCPTable
|
||||
class = tcpTablePidConn
|
||||
case Network_UDP:
|
||||
fn = getExUDPTable
|
||||
class = udpTablePid
|
||||
default:
|
||||
panic("Unsupported network type for process lookup.")
|
||||
}
|
||||
ip := dest.Address.IP()
|
||||
port := int(dest.Port)
|
||||
|
||||
addr, ok := netip.AddrFromSlice(ip)
|
||||
if !ok {
|
||||
return 0, "", errors.New("invalid IP address")
|
||||
}
|
||||
addr = addr.Unmap()
|
||||
|
||||
family := windows.AF_INET
|
||||
if addr.Is6() {
|
||||
family = windows.AF_INET6
|
||||
}
|
||||
|
||||
buf, err := getTransportTable(fn, family, class)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
s := newSearcher(dest.Network, dest.Address.Family())
|
||||
|
||||
pid, err := s.Search(buf, addr, uint16(port))
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
name, err := getExecPathFromPID(pid)
|
||||
// drop .exe
|
||||
name = strings.TrimSuffix(name, ".exe")
|
||||
return int(pid), name, err
|
||||
}
|
||||
|
||||
type searcher struct {
|
||||
itemSize int
|
||||
port int
|
||||
ip int
|
||||
ipSize int
|
||||
pid int
|
||||
tcpState int
|
||||
}
|
||||
|
||||
func (s *searcher) Search(b []byte, ip netip.Addr, port uint16) (uint32, error) {
|
||||
n := int(readNativeUint32(b[:4]))
|
||||
itemSize := s.itemSize
|
||||
for i := range n {
|
||||
row := b[4+itemSize*i : 4+itemSize*(i+1)]
|
||||
|
||||
if s.tcpState >= 0 {
|
||||
tcpState := readNativeUint32(row[s.tcpState : s.tcpState+4])
|
||||
// MIB_TCP_STATE_ESTAB, only check established connections for TCP
|
||||
if tcpState != 5 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// according to MSDN, only the lower 16 bits of dwLocalPort are used and the port number is in network endian.
|
||||
// this field can be illustrated as follows depends on different machine endianess:
|
||||
// little endian: [ MSB LSB 0 0 ] interpret as native uint32 is ((LSB<<8)|MSB)
|
||||
// big endian: [ 0 0 MSB LSB ] interpret as native uint32 is ((MSB<<8)|LSB)
|
||||
// so we need an syscall.Ntohs on the lower 16 bits after read the port as native uint32
|
||||
srcPort := syscall.Ntohs(uint16(readNativeUint32(row[s.port : s.port+4])))
|
||||
if srcPort != port {
|
||||
continue
|
||||
}
|
||||
|
||||
srcIP, _ := netip.AddrFromSlice(row[s.ip : s.ip+s.ipSize])
|
||||
srcIP = srcIP.Unmap()
|
||||
// windows binds an unbound udp socket to 0.0.0.0/[::] while first sendto
|
||||
if ip != srcIP && (!srcIP.IsUnspecified() || s.tcpState != -1) {
|
||||
continue
|
||||
}
|
||||
|
||||
pid := readNativeUint32(row[s.pid : s.pid+4])
|
||||
return pid, nil
|
||||
}
|
||||
return 0, errors.New("not found")
|
||||
}
|
||||
|
||||
func newSearcher(network Network, family AddressFamily) *searcher {
|
||||
var itemSize, port, ip, ipSize, pid int
|
||||
tcpState := -1
|
||||
switch network {
|
||||
case Network_TCP:
|
||||
if family == AddressFamilyIPv4 {
|
||||
// struct MIB_TCPROW_OWNER_PID
|
||||
itemSize, port, ip, ipSize, pid, tcpState = 24, 8, 4, 4, 20, 0
|
||||
}
|
||||
if family == AddressFamilyIPv6 {
|
||||
// struct MIB_TCP6ROW_OWNER_PID
|
||||
itemSize, port, ip, ipSize, pid, tcpState = 56, 20, 0, 16, 52, 48
|
||||
}
|
||||
case Network_UDP:
|
||||
if family == AddressFamilyIPv4 {
|
||||
// struct MIB_UDPROW_OWNER_PID
|
||||
itemSize, port, ip, ipSize, pid = 12, 4, 0, 4, 8
|
||||
}
|
||||
if family == AddressFamilyIPv6 {
|
||||
// struct MIB_UDP6ROW_OWNER_PID
|
||||
itemSize, port, ip, ipSize, pid = 28, 20, 0, 16, 24
|
||||
}
|
||||
}
|
||||
|
||||
return &searcher{
|
||||
itemSize: itemSize,
|
||||
port: port,
|
||||
ip: ip,
|
||||
ipSize: ipSize,
|
||||
pid: pid,
|
||||
tcpState: tcpState,
|
||||
}
|
||||
}
|
||||
|
||||
func getTransportTable(fn uintptr, family int, class int) ([]byte, error) {
|
||||
for size, buf := uint32(8), make([]byte, 8); ; {
|
||||
ptr := unsafe.Pointer(&buf[0])
|
||||
err, _, _ := syscall.Syscall6(fn, 6, uintptr(ptr), uintptr(unsafe.Pointer(&size)), 0, uintptr(family), uintptr(class), 0)
|
||||
|
||||
switch err {
|
||||
case 0:
|
||||
return buf, nil
|
||||
case uintptr(syscall.ERROR_INSUFFICIENT_BUFFER):
|
||||
buf = make([]byte, size)
|
||||
default:
|
||||
return nil, errors.New("syscall error: ", int(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readNativeUint32(b []byte) uint32 {
|
||||
return *(*uint32)(unsafe.Pointer(&b[0]))
|
||||
}
|
||||
|
||||
func getExecPathFromPID(pid uint32) (string, error) {
|
||||
// kernel process starts with a colon in order to distinguish with normal processes
|
||||
switch pid {
|
||||
case 0:
|
||||
// reserved pid for system idle process
|
||||
return ":System Idle Process", nil
|
||||
case 4:
|
||||
// reserved pid for windows kernel image
|
||||
return ":System", nil
|
||||
}
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer windows.CloseHandle(h)
|
||||
|
||||
buf := make([]uint16, syscall.MAX_LONG_PATH)
|
||||
size := uint32(len(buf))
|
||||
err = windows.QueryFullProcessImageName(h, 0, &buf[0], &size)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// full path will like: C:\Windows\System32\curl.exe
|
||||
// we only need the executable name
|
||||
fullPathName := syscall.UTF16ToString(buf[:size])
|
||||
nameSplit := strings.Split(fullPathName, "\\")
|
||||
name := nameSplit[len(nameSplit)-1]
|
||||
return name, nil
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
// Package net is a drop-in replacement to Golang's net package, with some more functionalities.
|
||||
package net // import "github.com/xtls/xray-core/common/net"
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"net"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
// defines the maximum time an idle TCP session can survive in the tunnel, so
|
||||
// it should be consistent across HTTP versions and with other transports.
|
||||
@@ -12,3 +18,37 @@ const QuicgoH3KeepAlivePeriod = 10 * time.Second
|
||||
|
||||
// consistent with chrome
|
||||
const ChromeH2KeepAlivePeriod = 45 * time.Second
|
||||
|
||||
var ErrNotLocal = errors.New("the source address is not from local machine.")
|
||||
|
||||
type localIPCahceEntry struct {
|
||||
addrs []net.Addr
|
||||
lastUpdate time.Time
|
||||
}
|
||||
|
||||
var localIPCahce = atomic.Pointer[localIPCahceEntry]{}
|
||||
|
||||
func IsLocal(ip net.IP) (bool, error) {
|
||||
var addrs []net.Addr
|
||||
if entry := localIPCahce.Load(); entry == nil || time.Since(entry.lastUpdate) > time.Minute {
|
||||
var err error
|
||||
addrs, err = net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
localIPCahce.Store(&localIPCahceEntry{
|
||||
addrs: addrs,
|
||||
lastUpdate: time.Now(),
|
||||
})
|
||||
} else {
|
||||
addrs = entry.addrs
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||
if ipnet.IP.Equal(ip) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -520,21 +520,22 @@ func ToCidrList(ips StringList) ([]*router.GeoIP, error) {
|
||||
func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
||||
type RawFieldRule struct {
|
||||
RouterRule
|
||||
Domain *StringList `json:"domain"`
|
||||
Domains *StringList `json:"domains"`
|
||||
IP *StringList `json:"ip"`
|
||||
Port *PortList `json:"port"`
|
||||
Network *NetworkList `json:"network"`
|
||||
SourceIP *StringList `json:"sourceIP"`
|
||||
Source *StringList `json:"source"`
|
||||
SourcePort *PortList `json:"sourcePort"`
|
||||
User *StringList `json:"user"`
|
||||
VlessRoute *PortList `json:"vlessRoute"`
|
||||
InboundTag *StringList `json:"inboundTag"`
|
||||
Protocols *StringList `json:"protocol"`
|
||||
Attributes map[string]string `json:"attrs"`
|
||||
LocalIP *StringList `json:"localIP"`
|
||||
LocalPort *PortList `json:"localPort"`
|
||||
Domain *StringList `json:"domain"`
|
||||
Domains *StringList `json:"domains"`
|
||||
IP *StringList `json:"ip"`
|
||||
Port *PortList `json:"port"`
|
||||
Network *NetworkList `json:"network"`
|
||||
SourceIP *StringList `json:"sourceIP"`
|
||||
Source *StringList `json:"source"`
|
||||
SourcePort *PortList `json:"sourcePort"`
|
||||
User *StringList `json:"user"`
|
||||
VlessRoute *PortList `json:"vlessRoute"`
|
||||
InboundTag *StringList `json:"inboundTag"`
|
||||
Protocols *StringList `json:"protocol"`
|
||||
Attributes map[string]string `json:"attrs"`
|
||||
LocalIP *StringList `json:"localIP"`
|
||||
LocalPort *PortList `json:"localPort"`
|
||||
ProcessName *StringList `json:"processName"`
|
||||
}
|
||||
rawFieldRule := new(RawFieldRule)
|
||||
err := json.Unmarshal(msg, rawFieldRule)
|
||||
@@ -647,6 +648,12 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
|
||||
rule.Attributes = rawFieldRule.Attributes
|
||||
}
|
||||
|
||||
if rawFieldRule.ProcessName != nil {
|
||||
for _, s := range *rawFieldRule.ProcessName {
|
||||
rule.ProcessName = append(rule.ProcessName, s)
|
||||
}
|
||||
}
|
||||
|
||||
return rule, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user