diff --git a/adapters/shadowsocks.go b/adapters/shadowsocks.go index 555abef3..2e3dd987 100644 --- a/adapters/shadowsocks.go +++ b/adapters/shadowsocks.go @@ -34,31 +34,32 @@ func (ss *ShadowsocksAdapter) Conn() net.Conn { } type ShadowSocks struct { - server string - cipher string - password string + server string + cipher core.Cipher } func (ss *ShadowSocks) Generator(addr *C.Addr) (adapter C.ProxyAdapter, err error) { - var key []byte - ciph, _ := core.PickCipher(ss.cipher, key, ss.password) c, err := net.Dial("tcp", ss.server) if err != nil { return nil, fmt.Errorf("%s connect error", ss.server) } c.(*net.TCPConn).SetKeepAlive(true) - c = ciph.StreamConn(c) + c = ss.cipher.StreamConn(c) _, err = c.Write(serializesSocksAddr(addr)) return &ShadowsocksAdapter{conn: c}, err } -func NewShadowSocks(ssURL string) *ShadowSocks { +func NewShadowSocks(ssURL string) (*ShadowSocks, error) { + var key []byte server, cipher, password, _ := parseURL(ssURL) - return &ShadowSocks{ - server: server, - cipher: cipher, - password: password, + ciph, err := core.PickCipher(cipher, key, password) + if err != nil { + return nil, fmt.Errorf("ss %s initialize error: %s", server, err.Error()) } + return &ShadowSocks{ + server: server, + cipher: ciph, + }, nil } func parseURL(s string) (addr, cipher, password string, err error) { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index f68096b2..69c90162 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -32,23 +32,20 @@ func (t *Tunnel) Add(req C.ServerAdapter) { } func (t *Tunnel) UpdateConfig() (err error) { - t.configLock.Lock() - defer t.configLock.Unlock() - cfg, err := C.GetConfig() if err != nil { return } // clear proxys and rules - t.proxys = make(map[string]C.Proxy) - t.rules = []C.Rule{} + proxys := make(map[string]C.Proxy) + rules := []C.Rule{} - proxys := cfg.Section("Proxy") - rules := cfg.Section("Rule") + proxysConfig := cfg.Section("Proxy") + rulesConfig := cfg.Section("Rule") // parse proxy - for _, key := range proxys.Keys() { + for _, key := range proxysConfig.Keys() { proxy := strings.Split(key.Value(), ",") if len(proxy) == 0 { continue @@ -61,16 +58,20 @@ func (t *Tunnel) UpdateConfig() (err error) { continue } ssURL := fmt.Sprintf("ss://%s:%s@%s:%s", proxy[3], proxy[4], proxy[1], proxy[2]) - t.proxys[key.Name()] = adapters.NewShadowSocks(ssURL) + ss, err := adapters.NewShadowSocks(ssURL) + if err != nil { + return err + } + proxys[key.Name()] = ss } } // init proxy - t.proxys["DIRECT"] = adapters.NewDirect() - t.proxys["REJECT"] = adapters.NewReject() + proxys["DIRECT"] = adapters.NewDirect() + proxys["REJECT"] = adapters.NewReject() // parse rules - for _, key := range rules.Keys() { + for _, key := range rulesConfig.Keys() { rule := strings.Split(key.Name(), ",") if len(rule) < 3 { continue @@ -78,18 +79,24 @@ func (t *Tunnel) UpdateConfig() (err error) { rule = trimArr(rule) switch rule[0] { case "DOMAIN-SUFFIX": - t.rules = append(t.rules, R.NewDomainSuffix(rule[1], rule[2])) + rules = append(rules, R.NewDomainSuffix(rule[1], rule[2])) case "DOMAIN-KEYWORD": - t.rules = append(t.rules, R.NewDomainKeyword(rule[1], rule[2])) + rules = append(rules, R.NewDomainKeyword(rule[1], rule[2])) case "GEOIP": - t.rules = append(t.rules, R.NewGEOIP(rule[1], rule[2])) + rules = append(rules, R.NewGEOIP(rule[1], rule[2])) case "IP-CIDR", "IP-CIDR6": - t.rules = append(t.rules, R.NewIPCIDR(rule[1], rule[2])) + rules = append(rules, R.NewIPCIDR(rule[1], rule[2])) case "FINAL": - t.rules = append(t.rules, R.NewFinal(rule[2])) + rules = append(rules, R.NewFinal(rule[2])) } } + t.configLock.Lock() + defer t.configLock.Unlock() + + t.proxys = proxys + t.rules = rules + return nil }