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  }