github.com/ipfans/trojan-go@v0.11.0/url/option.go (about) 1 package url 2 3 import ( 4 "encoding/json" 5 "flag" 6 "net" 7 "strconv" 8 "strings" 9 10 "github.com/ipfans/trojan-go/common" 11 "github.com/ipfans/trojan-go/log" 12 "github.com/ipfans/trojan-go/option" 13 "github.com/ipfans/trojan-go/proxy" 14 ) 15 16 const Name = "URL" 17 18 type Websocket struct { 19 Enabled bool `json:"enabled"` 20 Host string `json:"host"` 21 Path string `json:"path"` 22 } 23 24 type TLS struct { 25 SNI string `json:"sni"` 26 } 27 28 type Shadowsocks struct { 29 Enabled bool `json:"enabled"` 30 Method string `json:"method"` 31 Password string `json:"password"` 32 } 33 34 type Mux struct { 35 Enabled bool `json:"enabled"` 36 } 37 38 type API struct { 39 Enabled bool `json:"enabled"` 40 APIHost string `json:"api_addr"` 41 APIPort int `json:"api_port"` 42 } 43 44 type UrlConfig struct { 45 RunType string `json:"run_type"` 46 LocalAddr string `json:"local_addr"` 47 LocalPort int `json:"local_port"` 48 RemoteAddr string `json:"remote_addr"` 49 RemotePort int `json:"remote_port"` 50 Password []string `json:"password"` 51 Websocket `json:"websocket"` 52 Shadowsocks `json:"shadowsocks"` 53 TLS `json:"ssl"` 54 Mux `json:"mux"` 55 API `json:"api"` 56 } 57 58 type url struct { 59 url *string 60 option *string 61 } 62 63 func (u *url) Name() string { 64 return Name 65 } 66 67 func (u *url) Handle() error { 68 if u.url == nil || *u.url == "" { 69 return common.NewError("") 70 } 71 info, err := NewShareInfoFromURL(*u.url) 72 if err != nil { 73 log.Fatal(err) 74 } 75 wsEnabled := false 76 if info.Type == ShareInfoTypeWebSocket { 77 wsEnabled = true 78 } 79 ssEnabled := false 80 ssPassword := "" 81 ssMethod := "" 82 if strings.HasPrefix(info.Encryption, "ss;") { 83 ssEnabled = true 84 ssConfig := strings.Split(info.Encryption[3:], ":") 85 if len(ssConfig) != 2 { 86 log.Fatalf("invalid shadowsocks config: %s", info.Encryption) 87 } 88 ssMethod = ssConfig[0] 89 ssPassword = ssConfig[1] 90 } 91 muxEnabled := false 92 listenHost := "127.0.0.1" 93 listenPort := 1080 94 95 apiEnabled := false 96 apiHost := "127.0.0.1" 97 apiPort := 10000 98 99 options := strings.Split(*u.option, ";") 100 for _, o := range options { 101 key := "" 102 val := "" 103 l := strings.Split(o, "=") 104 if len(l) != 2 { 105 log.Fatal("option format error, no \"key=value\" pair found:", o) 106 } 107 key = l[0] 108 val = l[1] 109 switch key { 110 case "mux": 111 muxEnabled, err = strconv.ParseBool(val) 112 if err != nil { 113 log.Fatal(err) 114 } 115 case "listen": 116 h, p, err := net.SplitHostPort(val) 117 if err != nil { 118 log.Fatal(err) 119 } 120 listenHost = h 121 lp, err := strconv.Atoi(p) 122 if err != nil { 123 log.Fatal(err) 124 } 125 listenPort = lp 126 case "api": 127 apiEnabled = true 128 h, p, err := net.SplitHostPort(val) 129 if err != nil { 130 log.Fatal(err) 131 } 132 apiHost = h 133 lp, err := strconv.Atoi(p) 134 if err != nil { 135 log.Fatal(err) 136 } 137 apiPort = lp 138 default: 139 log.Fatal("invalid option", o) 140 } 141 } 142 config := UrlConfig{ 143 RunType: "client", 144 LocalAddr: listenHost, 145 LocalPort: listenPort, 146 RemoteAddr: info.TrojanHost, 147 RemotePort: int(info.Port), 148 Password: []string{info.TrojanPassword}, 149 TLS: TLS{ 150 SNI: info.SNI, 151 }, 152 Websocket: Websocket{ 153 Enabled: wsEnabled, 154 Path: info.Path, 155 Host: info.Host, 156 }, 157 Mux: Mux{ 158 Enabled: muxEnabled, 159 }, 160 Shadowsocks: Shadowsocks{ 161 Enabled: ssEnabled, 162 Password: ssPassword, 163 Method: ssMethod, 164 }, 165 API: API{ 166 Enabled: apiEnabled, 167 APIHost: apiHost, 168 APIPort: apiPort, 169 }, 170 } 171 data, err := json.Marshal(&config) 172 if err != nil { 173 log.Fatal(err) 174 } 175 log.Debug(string(data)) 176 client, err := proxy.NewProxyFromConfigData(data, true) 177 if err != nil { 178 log.Fatal(err) 179 } 180 return client.Run() 181 } 182 183 func (u *url) Priority() int { 184 return 10 185 } 186 187 func init() { 188 option.RegisterHandler(&url{ 189 url: flag.String("url", "", "Setup trojan-go client with a url link"), 190 option: flag.String("url-option", "mux=true;listen=127.0.0.1:1080", "URL mode options"), 191 }) 192 }