github.com/yaling888/clash@v1.53.0/adapter/parser.go (about) 1 package adapter 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/yaling888/clash/adapter/outbound" 8 "github.com/yaling888/clash/common/structure" 9 "github.com/yaling888/clash/common/util" 10 C "github.com/yaling888/clash/constant" 11 ) 12 13 type ProxyOption struct { 14 ForceCertVerify bool 15 ForceUDP bool 16 DisableUDP bool 17 DisableDNS bool 18 AutoCipher bool 19 RandomHost bool 20 PrefixName string 21 } 22 23 func ParseProxy(mapping map[string]any, option ProxyOption) (C.Proxy, error) { 24 decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true}) 25 proxyType, existType := mapping["type"].(string) 26 if !existType { 27 return nil, fmt.Errorf("missing type") 28 } 29 30 var ( 31 proxy C.ProxyAdapter 32 err error 33 ) 34 switch proxyType { 35 case "ss": 36 ssOption := &outbound.ShadowSocksOption{RemoteDnsResolve: true} 37 err = decoder.Decode(mapping, ssOption) 38 if err != nil { 39 break 40 } 41 if option.ForceUDP { 42 ssOption.UDP = true 43 } 44 if option.DisableUDP { 45 ssOption.UDP = false 46 } 47 if option.RandomHost { 48 ssOption.RandomHost = true 49 } 50 if option.DisableDNS { 51 ssOption.RemoteDnsResolve = false 52 } 53 proxy, err = outbound.NewShadowSocks(*ssOption) 54 case "ssr": 55 ssrOption := &outbound.ShadowSocksROption{RemoteDnsResolve: true} 56 err = decoder.Decode(mapping, ssrOption) 57 if err != nil { 58 break 59 } 60 if option.ForceUDP { 61 ssrOption.UDP = true 62 } 63 if option.DisableUDP { 64 ssrOption.UDP = false 65 } 66 if option.RandomHost { 67 ssrOption.RandomHost = true 68 } 69 if option.DisableDNS { 70 ssrOption.RemoteDnsResolve = false 71 } 72 proxy, err = outbound.NewShadowSocksR(*ssrOption) 73 case "socks5": 74 socksOption := &outbound.Socks5Option{RemoteDnsResolve: true} 75 err = decoder.Decode(mapping, socksOption) 76 if err != nil { 77 break 78 } 79 if option.ForceCertVerify { 80 socksOption.SkipCertVerify = false 81 } 82 if option.ForceUDP { 83 socksOption.UDP = true 84 } 85 if option.DisableDNS { 86 socksOption.RemoteDnsResolve = false 87 } 88 proxy = outbound.NewSocks5(*socksOption) 89 case "http": 90 httpOption := &outbound.HttpOption{RemoteDnsResolve: true} 91 err = decoder.Decode(mapping, httpOption) 92 if err != nil { 93 break 94 } 95 if option.ForceCertVerify { 96 httpOption.SkipCertVerify = false 97 } 98 if option.DisableDNS { 99 httpOption.RemoteDnsResolve = false 100 } 101 proxy = outbound.NewHttp(*httpOption) 102 case "vmess": 103 vmessOption := &outbound.VmessOption{ 104 HTTPOpts: outbound.HTTPOptions{ 105 Method: "GET", 106 Path: []string{"/"}, 107 Headers: make(map[string][]string), 108 }, 109 RemoteDnsResolve: true, 110 } 111 err = decoder.Decode(mapping, vmessOption) 112 if err != nil { 113 break 114 } 115 vmessOption.HTTPOpts.Method = util.EmptyOr(strings.ToUpper(vmessOption.HTTPOpts.Method), "GET") 116 if option.ForceCertVerify { 117 vmessOption.SkipCertVerify = false 118 } 119 if option.ForceUDP { 120 vmessOption.UDP = true 121 } 122 if option.DisableUDP { 123 vmessOption.UDP = false 124 } 125 if option.AutoCipher { 126 vmessOption.Cipher = "auto" 127 } 128 if option.RandomHost { 129 vmessOption.RandomHost = true 130 } 131 if option.DisableDNS { 132 vmessOption.RemoteDnsResolve = false 133 } 134 proxy, err = outbound.NewVmess(*vmessOption) 135 case "vless": 136 vlessOption := &outbound.VlessOption{ 137 HTTPOpts: outbound.HTTPOptions{ 138 Method: "GET", 139 Path: []string{"/"}, 140 Headers: make(map[string][]string), 141 }, 142 RemoteDnsResolve: true, 143 } 144 err = decoder.Decode(mapping, vlessOption) 145 if err != nil { 146 break 147 } 148 vlessOption.HTTPOpts.Method = util.EmptyOr(strings.ToUpper(vlessOption.HTTPOpts.Method), "GET") 149 if option.ForceCertVerify { 150 vlessOption.SkipCertVerify = false 151 } 152 if option.ForceUDP { 153 vlessOption.UDP = true 154 } 155 if option.DisableUDP { 156 vlessOption.UDP = false 157 } 158 if option.DisableDNS { 159 vlessOption.RemoteDnsResolve = false 160 } 161 if option.RandomHost { 162 vlessOption.RandomHost = true 163 } 164 proxy, err = outbound.NewVless(*vlessOption) 165 case "snell": 166 snellOption := &outbound.SnellOption{RemoteDnsResolve: true} 167 err = decoder.Decode(mapping, snellOption) 168 if err != nil { 169 break 170 } 171 if option.ForceUDP { 172 snellOption.UDP = true 173 } 174 if option.DisableUDP { 175 snellOption.UDP = false 176 } 177 if option.RandomHost { 178 snellOption.RandomHost = true 179 } 180 if option.DisableDNS { 181 snellOption.RemoteDnsResolve = false 182 } 183 proxy, err = outbound.NewSnell(*snellOption) 184 case "trojan": 185 trojanOption := &outbound.TrojanOption{RemoteDnsResolve: true} 186 err = decoder.Decode(mapping, trojanOption) 187 if err != nil { 188 break 189 } 190 if option.ForceCertVerify { 191 trojanOption.SkipCertVerify = false 192 } 193 if option.ForceUDP { 194 trojanOption.UDP = true 195 } 196 if option.DisableUDP { 197 trojanOption.UDP = false 198 } 199 if option.DisableDNS { 200 trojanOption.RemoteDnsResolve = false 201 } 202 proxy, err = outbound.NewTrojan(*trojanOption) 203 case "wireguard": 204 wireguardOption := &outbound.WireGuardOption{ 205 RemoteDnsResolve: true, 206 } 207 err = decoder.Decode(mapping, wireguardOption) 208 if err != nil { 209 break 210 } 211 if option.ForceUDP { 212 wireguardOption.UDP = true 213 } 214 proxy, err = outbound.NewWireGuard(*wireguardOption) 215 default: 216 return nil, fmt.Errorf("unsupport proxy type: %s", proxyType) 217 } 218 219 if err != nil { 220 return nil, err 221 } 222 223 return NewProxy(proxy), nil 224 }