github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/cmd/android/fake.go (about) 1 package yuhaiin 2 3 import ( 4 "bufio" 5 "bytes" 6 "context" 7 "encoding/json" 8 "errors" 9 "fmt" 10 "io" 11 "path/filepath" 12 "strings" 13 14 "github.com/Asutorufa/yuhaiin/pkg/components/config" 15 "github.com/Asutorufa/yuhaiin/pkg/log" 16 pc "github.com/Asutorufa/yuhaiin/pkg/protos/config" 17 "github.com/Asutorufa/yuhaiin/pkg/protos/config/bypass" 18 "github.com/Asutorufa/yuhaiin/pkg/protos/config/dns" 19 gc "github.com/Asutorufa/yuhaiin/pkg/protos/config/grpc" 20 "github.com/Asutorufa/yuhaiin/pkg/protos/config/listener" 21 pl "github.com/Asutorufa/yuhaiin/pkg/protos/config/log" 22 "google.golang.org/protobuf/types/known/emptypb" 23 ) 24 25 func fakeSetting(opt *Opts, path string) config.Setting { 26 opts, _ := json.Marshal(opt) 27 log.Info("fake setting config", "data", string(opts)) 28 settings := &pc.Setting{ 29 Ipv6: opt.IPv6, 30 Dns: &dns.DnsConfig{ 31 Server: opt.DNS.Server, 32 Fakedns: opt.DNS.Fakedns, 33 FakednsIpRange: opt.DNS.FakednsIpRange, 34 FakednsIpv6Range: opt.DNS.FakednsIpv6Range, 35 ResolveRemoteDomain: opt.DNS.ResolveRemoteDomain, 36 Hosts: make(map[string]string), 37 Remote: &dns.Dns{ 38 Host: opt.DNS.Remote.Host, 39 Type: dns.Type(opt.DNS.Remote.Type), 40 Subnet: opt.DNS.Remote.Subnet, 41 TlsServername: opt.DNS.Remote.TlsServername, 42 }, 43 Local: &dns.Dns{ 44 Host: opt.DNS.Local.Host, 45 Type: dns.Type(opt.DNS.Local.Type), 46 Subnet: opt.DNS.Local.Subnet, 47 TlsServername: opt.DNS.Local.TlsServername, 48 }, 49 Bootstrap: &dns.Dns{ 50 Host: opt.DNS.Bootstrap.Host, 51 Type: dns.Type(opt.DNS.Bootstrap.Type), 52 Subnet: opt.DNS.Bootstrap.Subnet, 53 TlsServername: opt.DNS.Bootstrap.TlsServername, 54 }, 55 }, 56 SystemProxy: &pc.SystemProxy{}, 57 Server: &listener.InboundConfig{ 58 HijackDns: opt.TUN.DNSHijacking, 59 HijackDnsFakeip: opt.DNS.Fakedns, 60 Inbounds: map[string]*listener.Inbound{ 61 "mix": { 62 Name: "mix", 63 Enabled: opt.Http != "", 64 Network: &listener.Inbound_Tcpudp{ 65 Tcpudp: &listener.Tcpudp{ 66 Host: opt.Http, 67 Control: listener.TcpUdpControl_tcp_udp_control_all, 68 }, 69 }, 70 Protocol: &listener.Inbound_Mix{ 71 Mix: &listener.Mixed{}, 72 }, 73 }, 74 "tun": { 75 Name: "tun", 76 Enabled: true, 77 Network: &listener.Inbound_Empty{Empty: &listener.Empty{}}, 78 Protocol: &listener.Inbound_Tun{ 79 Tun: &listener.Tun{ 80 Name: fmt.Sprintf("fd://%d", opt.TUN.FD), 81 Mtu: opt.TUN.MTU, 82 Portal: opt.TUN.Portal, 83 PortalV6: opt.TUN.PortalV6, 84 SkipMulticast: true, 85 Route: &listener.Route{}, 86 Driver: listener.TunEndpointDriver(opt.TUN.Driver), 87 }, 88 }, 89 }, 90 }, 91 }, 92 93 Bypass: &bypass.BypassConfig{ 94 Tcp: bypass.Mode(opt.Bypass.TCP), 95 Udp: bypass.Mode(opt.Bypass.UDP), 96 BypassFile: filepath.Join(filepath.Dir(path), "yuhaiin.conf"), 97 CustomRuleV3: []*bypass.ModeConfig{}, 98 }, 99 100 Logcat: &pl.Logcat{ 101 Level: pl.LogLevel(opt.Log.LogLevel), 102 Save: opt.Log.SaveLogcat, 103 }, 104 } 105 106 if err := json.Unmarshal(opt.DNS.Hosts, &settings.Dns.Hosts); err != nil { 107 log.Warn("unmarshal hosts failed", "err", err) 108 } 109 110 applyRule(settings, opt.Bypass.Proxy, bypass.Mode_proxy) 111 applyRule(settings, opt.Bypass.Block, bypass.Mode_block) 112 applyRule(settings, opt.Bypass.Direct, bypass.Mode_direct) 113 return newFakeSetting(settings) 114 } 115 116 func applyRule(settings *pc.Setting, ruls string, mode bypass.Mode) { 117 cache := map[string]*bypass.ModeConfig{} 118 119 r := bufio.NewReader(strings.NewReader(ruls)) 120 for { 121 line, _, err := r.ReadLine() 122 if err != nil { 123 if errors.Is(err, io.EOF) { 124 break 125 } 126 127 continue 128 } 129 130 z := bytes.FieldsFunc(line, func(r rune) bool { return r == ',' }) 131 if len(z) == 0 { 132 continue 133 } 134 135 xx := &bypass.ModeConfig{Mode: mode} 136 137 xx.StoreKV(z[1:]) 138 139 var key string 140 if xx.GetMode() == bypass.Mode_proxy { 141 key = xx.GetMode().String() + xx.GetTag() 142 } else { 143 key = xx.GetMode().String() 144 } 145 146 zz, ok := cache[key] 147 if ok { 148 xx = zz 149 } else { 150 cache[key] = xx 151 settings.Bypass.CustomRuleV3 = append(settings.Bypass.CustomRuleV3, xx) 152 } 153 154 xx.Hostname = append(xx.Hostname, string(z[0])) 155 } 156 } 157 158 type fakeSettings struct { 159 gc.UnimplementedConfigServiceServer 160 setting *pc.Setting 161 } 162 163 func newFakeSetting(setting *pc.Setting) *fakeSettings { 164 return &fakeSettings{setting: setting} 165 } 166 167 func (w *fakeSettings) Load(ctx context.Context, in *emptypb.Empty) (*pc.Setting, error) { 168 return w.setting, nil 169 } 170 func (w *fakeSettings) Save(ctx context.Context, in *pc.Setting) (*emptypb.Empty, error) { 171 return &emptypb.Empty{}, nil 172 } 173 func (c *fakeSettings) Info(context.Context, *emptypb.Empty) (*pc.Info, error) { 174 return config.Info(), nil 175 } 176 177 func (w *fakeSettings) AddObserver(o config.Observer) { 178 if o != nil { 179 o.Update(w.setting) 180 } 181 }