proxy.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. // Copyright 2016 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package config
  15. import (
  16. "fmt"
  17. "reflect"
  18. "strconv"
  19. "strings"
  20. "github.com/fatedier/frp/models/consts"
  21. "github.com/fatedier/frp/models/msg"
  22. "github.com/fatedier/frp/utils/util"
  23. ini "github.com/vaughan0/go-ini"
  24. )
  25. var (
  26. proxyConfTypeMap map[string]reflect.Type
  27. )
  28. func init() {
  29. proxyConfTypeMap = make(map[string]reflect.Type)
  30. proxyConfTypeMap[consts.TcpProxy] = reflect.TypeOf(TcpProxyConf{})
  31. proxyConfTypeMap[consts.TcpMuxProxy] = reflect.TypeOf(TcpMuxProxyConf{})
  32. proxyConfTypeMap[consts.UdpProxy] = reflect.TypeOf(UdpProxyConf{})
  33. proxyConfTypeMap[consts.HttpProxy] = reflect.TypeOf(HttpProxyConf{})
  34. proxyConfTypeMap[consts.HttpsProxy] = reflect.TypeOf(HttpsProxyConf{})
  35. proxyConfTypeMap[consts.StcpProxy] = reflect.TypeOf(StcpProxyConf{})
  36. proxyConfTypeMap[consts.XtcpProxy] = reflect.TypeOf(XtcpProxyConf{})
  37. proxyConfTypeMap[consts.SudpProxy] = reflect.TypeOf(SudpProxyConf{})
  38. }
  39. // NewConfByType creates a empty ProxyConf object by proxyType.
  40. // If proxyType isn't exist, return nil.
  41. func NewConfByType(proxyType string) ProxyConf {
  42. v, ok := proxyConfTypeMap[proxyType]
  43. if !ok {
  44. return nil
  45. }
  46. cfg := reflect.New(v).Interface().(ProxyConf)
  47. return cfg
  48. }
  49. type ProxyConf interface {
  50. GetBaseInfo() *BaseProxyConf
  51. UnmarshalFromMsg(pMsg *msg.NewProxy)
  52. UnmarshalFromIni(prefix string, name string, conf ini.Section) error
  53. MarshalToMsg(pMsg *msg.NewProxy)
  54. CheckForCli() error
  55. CheckForSvr(serverCfg ServerCommonConf) error
  56. Compare(conf ProxyConf) bool
  57. }
  58. func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (cfg ProxyConf, err error) {
  59. if pMsg.ProxyType == "" {
  60. pMsg.ProxyType = consts.TcpProxy
  61. }
  62. cfg = NewConfByType(pMsg.ProxyType)
  63. if cfg == nil {
  64. err = fmt.Errorf("proxy [%s] type [%s] error", pMsg.ProxyName, pMsg.ProxyType)
  65. return
  66. }
  67. cfg.UnmarshalFromMsg(pMsg)
  68. err = cfg.CheckForSvr(serverCfg)
  69. return
  70. }
  71. func NewProxyConfFromIni(prefix string, name string, section ini.Section) (cfg ProxyConf, err error) {
  72. proxyType := section["type"]
  73. if proxyType == "" {
  74. proxyType = consts.TcpProxy
  75. section["type"] = consts.TcpProxy
  76. }
  77. cfg = NewConfByType(proxyType)
  78. if cfg == nil {
  79. err = fmt.Errorf("proxy [%s] type [%s] error", name, proxyType)
  80. return
  81. }
  82. if err = cfg.UnmarshalFromIni(prefix, name, section); err != nil {
  83. return
  84. }
  85. if err = cfg.CheckForCli(); err != nil {
  86. return
  87. }
  88. return
  89. }
  90. // BaseProxyConf provides configuration info that is common to all proxy types.
  91. type BaseProxyConf struct {
  92. // ProxyName is the name of this proxy.
  93. ProxyName string `json:"proxy_name"`
  94. // ProxyType specifies the type of this proxy. Valid values include "tcp",
  95. // "udp", "http", "https", "stcp", and "xtcp". By default, this value is
  96. // "tcp".
  97. ProxyType string `json:"proxy_type"`
  98. // UseEncryption controls whether or not communication with the server will
  99. // be encrypted. Encryption is done using the tokens supplied in the server
  100. // and client configuration. By default, this value is false.
  101. UseEncryption bool `json:"use_encryption"`
  102. // UseCompression controls whether or not communication with the server
  103. // will be compressed. By default, this value is false.
  104. UseCompression bool `json:"use_compression"`
  105. // Group specifies which group the proxy is a part of. The server will use
  106. // this information to load balance proxies in the same group. If the value
  107. // is "", this proxy will not be in a group. By default, this value is "".
  108. Group string `json:"group"`
  109. // GroupKey specifies a group key, which should be the same among proxies
  110. // of the same group. By default, this value is "".
  111. GroupKey string `json:"group_key"`
  112. // ProxyProtocolVersion specifies which protocol version to use. Valid
  113. // values include "v1", "v2", and "". If the value is "", a protocol
  114. // version will be automatically selected. By default, this value is "".
  115. ProxyProtocolVersion string `json:"proxy_protocol_version"`
  116. // BandwidthLimit limit the proxy bandwidth
  117. // 0 means no limit
  118. BandwidthLimit BandwidthQuantity `json:"bandwidth_limit"`
  119. // meta info for each proxy
  120. Metas map[string]string `json:"metas"`
  121. LocalSvrConf
  122. HealthCheckConf
  123. }
  124. func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf {
  125. return cfg
  126. }
  127. func (cfg *BaseProxyConf) compare(cmp *BaseProxyConf) bool {
  128. if cfg.ProxyName != cmp.ProxyName ||
  129. cfg.ProxyType != cmp.ProxyType ||
  130. cfg.UseEncryption != cmp.UseEncryption ||
  131. cfg.UseCompression != cmp.UseCompression ||
  132. cfg.Group != cmp.Group ||
  133. cfg.GroupKey != cmp.GroupKey ||
  134. cfg.ProxyProtocolVersion != cmp.ProxyProtocolVersion ||
  135. !cfg.BandwidthLimit.Equal(&cmp.BandwidthLimit) ||
  136. !reflect.DeepEqual(cfg.Metas, cmp.Metas) {
  137. return false
  138. }
  139. if !cfg.LocalSvrConf.compare(&cmp.LocalSvrConf) {
  140. return false
  141. }
  142. if !cfg.HealthCheckConf.compare(&cmp.HealthCheckConf) {
  143. return false
  144. }
  145. return true
  146. }
  147. func (cfg *BaseProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  148. cfg.ProxyName = pMsg.ProxyName
  149. cfg.ProxyType = pMsg.ProxyType
  150. cfg.UseEncryption = pMsg.UseEncryption
  151. cfg.UseCompression = pMsg.UseCompression
  152. cfg.Group = pMsg.Group
  153. cfg.GroupKey = pMsg.GroupKey
  154. cfg.Metas = pMsg.Metas
  155. }
  156. func (cfg *BaseProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) error {
  157. var (
  158. tmpStr string
  159. ok bool
  160. err error
  161. )
  162. cfg.ProxyName = prefix + name
  163. cfg.ProxyType = section["type"]
  164. tmpStr, ok = section["use_encryption"]
  165. if ok && tmpStr == "true" {
  166. cfg.UseEncryption = true
  167. }
  168. tmpStr, ok = section["use_compression"]
  169. if ok && tmpStr == "true" {
  170. cfg.UseCompression = true
  171. }
  172. cfg.Group = section["group"]
  173. cfg.GroupKey = section["group_key"]
  174. cfg.ProxyProtocolVersion = section["proxy_protocol_version"]
  175. if cfg.BandwidthLimit, err = NewBandwidthQuantity(section["bandwidth_limit"]); err != nil {
  176. return err
  177. }
  178. if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
  179. return err
  180. }
  181. if err = cfg.HealthCheckConf.UnmarshalFromIni(prefix, name, section); err != nil {
  182. return err
  183. }
  184. if cfg.HealthCheckType == "tcp" && cfg.Plugin == "" {
  185. cfg.HealthCheckAddr = cfg.LocalIp + fmt.Sprintf(":%d", cfg.LocalPort)
  186. }
  187. if cfg.HealthCheckType == "http" && cfg.Plugin == "" && cfg.HealthCheckUrl != "" {
  188. s := fmt.Sprintf("http://%s:%d", cfg.LocalIp, cfg.LocalPort)
  189. if !strings.HasPrefix(cfg.HealthCheckUrl, "/") {
  190. s += "/"
  191. }
  192. cfg.HealthCheckUrl = s + cfg.HealthCheckUrl
  193. }
  194. cfg.Metas = make(map[string]string)
  195. for k, v := range section {
  196. if strings.HasPrefix(k, "meta_") {
  197. cfg.Metas[strings.TrimPrefix(k, "meta_")] = v
  198. }
  199. }
  200. return nil
  201. }
  202. func (cfg *BaseProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  203. pMsg.ProxyName = cfg.ProxyName
  204. pMsg.ProxyType = cfg.ProxyType
  205. pMsg.UseEncryption = cfg.UseEncryption
  206. pMsg.UseCompression = cfg.UseCompression
  207. pMsg.Group = cfg.Group
  208. pMsg.GroupKey = cfg.GroupKey
  209. pMsg.Metas = cfg.Metas
  210. }
  211. func (cfg *BaseProxyConf) checkForCli() (err error) {
  212. if cfg.ProxyProtocolVersion != "" {
  213. if cfg.ProxyProtocolVersion != "v1" && cfg.ProxyProtocolVersion != "v2" {
  214. return fmt.Errorf("no support proxy protocol version: %s", cfg.ProxyProtocolVersion)
  215. }
  216. }
  217. if err = cfg.LocalSvrConf.checkForCli(); err != nil {
  218. return
  219. }
  220. if err = cfg.HealthCheckConf.checkForCli(); err != nil {
  221. return
  222. }
  223. return nil
  224. }
  225. // Bind info
  226. type BindInfoConf struct {
  227. RemotePort int `json:"remote_port"`
  228. }
  229. func (cfg *BindInfoConf) compare(cmp *BindInfoConf) bool {
  230. if cfg.RemotePort != cmp.RemotePort {
  231. return false
  232. }
  233. return true
  234. }
  235. func (cfg *BindInfoConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  236. cfg.RemotePort = pMsg.RemotePort
  237. }
  238. func (cfg *BindInfoConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  239. var (
  240. tmpStr string
  241. ok bool
  242. v int64
  243. )
  244. if tmpStr, ok = section["remote_port"]; ok {
  245. if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
  246. return fmt.Errorf("Parse conf error: proxy [%s] remote_port error", name)
  247. } else {
  248. cfg.RemotePort = int(v)
  249. }
  250. } else {
  251. return fmt.Errorf("Parse conf error: proxy [%s] remote_port not found", name)
  252. }
  253. return nil
  254. }
  255. func (cfg *BindInfoConf) MarshalToMsg(pMsg *msg.NewProxy) {
  256. pMsg.RemotePort = cfg.RemotePort
  257. }
  258. // Domain info
  259. type DomainConf struct {
  260. CustomDomains []string `json:"custom_domains"`
  261. SubDomain string `json:"sub_domain"`
  262. }
  263. func (cfg *DomainConf) compare(cmp *DomainConf) bool {
  264. if strings.Join(cfg.CustomDomains, " ") != strings.Join(cmp.CustomDomains, " ") ||
  265. cfg.SubDomain != cmp.SubDomain {
  266. return false
  267. }
  268. return true
  269. }
  270. func (cfg *DomainConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  271. cfg.CustomDomains = pMsg.CustomDomains
  272. cfg.SubDomain = pMsg.SubDomain
  273. }
  274. func (cfg *DomainConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  275. var (
  276. tmpStr string
  277. ok bool
  278. )
  279. if tmpStr, ok = section["custom_domains"]; ok {
  280. cfg.CustomDomains = strings.Split(tmpStr, ",")
  281. for i, domain := range cfg.CustomDomains {
  282. cfg.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
  283. }
  284. }
  285. if tmpStr, ok = section["subdomain"]; ok {
  286. cfg.SubDomain = tmpStr
  287. }
  288. return
  289. }
  290. func (cfg *DomainConf) MarshalToMsg(pMsg *msg.NewProxy) {
  291. pMsg.CustomDomains = cfg.CustomDomains
  292. pMsg.SubDomain = cfg.SubDomain
  293. }
  294. func (cfg *DomainConf) check() (err error) {
  295. if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" {
  296. err = fmt.Errorf("custom_domains and subdomain should set at least one of them")
  297. return
  298. }
  299. return
  300. }
  301. func (cfg *DomainConf) checkForCli() (err error) {
  302. if err = cfg.check(); err != nil {
  303. return
  304. }
  305. return
  306. }
  307. func (cfg *DomainConf) checkForSvr(serverCfg ServerCommonConf) (err error) {
  308. if err = cfg.check(); err != nil {
  309. return
  310. }
  311. for _, domain := range cfg.CustomDomains {
  312. if serverCfg.SubDomainHost != "" && len(strings.Split(serverCfg.SubDomainHost, ".")) < len(strings.Split(domain, ".")) {
  313. if strings.Contains(domain, serverCfg.SubDomainHost) {
  314. return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, serverCfg.SubDomainHost)
  315. }
  316. }
  317. }
  318. if cfg.SubDomain != "" {
  319. if serverCfg.SubDomainHost == "" {
  320. return fmt.Errorf("subdomain is not supported because this feature is not enabled in remote frps")
  321. }
  322. if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
  323. return fmt.Errorf("'.' and '*' is not supported in subdomain")
  324. }
  325. }
  326. return
  327. }
  328. // LocalSvrConf configures what location the client will proxy to, or what
  329. // plugin will be used.
  330. type LocalSvrConf struct {
  331. // LocalIp specifies the IP address or host name to proxy to.
  332. LocalIp string `json:"local_ip"`
  333. // LocalPort specifies the port to proxy to.
  334. LocalPort int `json:"local_port"`
  335. // Plugin specifies what plugin should be used for proxying. If this value
  336. // is set, the LocalIp and LocalPort values will be ignored. By default,
  337. // this value is "".
  338. Plugin string `json:"plugin"`
  339. // PluginParams specify parameters to be passed to the plugin, if one is
  340. // being used. By default, this value is an empty map.
  341. PluginParams map[string]string `json:"plugin_params"`
  342. }
  343. func (cfg *LocalSvrConf) compare(cmp *LocalSvrConf) bool {
  344. if cfg.LocalIp != cmp.LocalIp ||
  345. cfg.LocalPort != cmp.LocalPort {
  346. return false
  347. }
  348. if cfg.Plugin != cmp.Plugin ||
  349. len(cfg.PluginParams) != len(cmp.PluginParams) {
  350. return false
  351. }
  352. for k, v := range cfg.PluginParams {
  353. value, ok := cmp.PluginParams[k]
  354. if !ok || v != value {
  355. return false
  356. }
  357. }
  358. return true
  359. }
  360. func (cfg *LocalSvrConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  361. cfg.Plugin = section["plugin"]
  362. cfg.PluginParams = make(map[string]string)
  363. if cfg.Plugin != "" {
  364. // get params begin with "plugin_"
  365. for k, v := range section {
  366. if strings.HasPrefix(k, "plugin_") {
  367. cfg.PluginParams[k] = v
  368. }
  369. }
  370. } else {
  371. if cfg.LocalIp = section["local_ip"]; cfg.LocalIp == "" {
  372. cfg.LocalIp = "127.0.0.1"
  373. }
  374. if tmpStr, ok := section["local_port"]; ok {
  375. if cfg.LocalPort, err = strconv.Atoi(tmpStr); err != nil {
  376. return fmt.Errorf("Parse conf error: proxy [%s] local_port error", name)
  377. }
  378. } else {
  379. return fmt.Errorf("Parse conf error: proxy [%s] local_port not found", name)
  380. }
  381. }
  382. return
  383. }
  384. func (cfg *LocalSvrConf) checkForCli() (err error) {
  385. if cfg.Plugin == "" {
  386. if cfg.LocalIp == "" {
  387. err = fmt.Errorf("local ip or plugin is required")
  388. return
  389. }
  390. if cfg.LocalPort <= 0 {
  391. err = fmt.Errorf("error local_port")
  392. return
  393. }
  394. }
  395. return
  396. }
  397. // HealthCheckConf configures health checking. This can be useful for load
  398. // balancing purposes to detect and remove proxies to failing services.
  399. type HealthCheckConf struct {
  400. // HealthCheckType specifies what protocol to use for health checking.
  401. // Valid values include "tcp", "http", and "". If this value is "", health
  402. // checking will not be performed. By default, this value is "".
  403. //
  404. // If the type is "tcp", a connection will be attempted to the target
  405. // server. If a connection cannot be established, the health check fails.
  406. //
  407. // If the type is "http", a GET request will be made to the endpoint
  408. // specified by HealthCheckUrl. If the response is not a 200, the health
  409. // check fails.
  410. HealthCheckType string `json:"health_check_type"` // tcp | http
  411. // HealthCheckTimeoutS specifies the number of seconds to wait for a health
  412. // check attempt to connect. If the timeout is reached, this counts as a
  413. // health check failure. By default, this value is 3.
  414. HealthCheckTimeoutS int `json:"health_check_timeout_s"`
  415. // HealthCheckMaxFailed specifies the number of allowed failures before the
  416. // proxy is stopped. By default, this value is 1.
  417. HealthCheckMaxFailed int `json:"health_check_max_failed"`
  418. // HealthCheckIntervalS specifies the time in seconds between health
  419. // checks. By default, this value is 10.
  420. HealthCheckIntervalS int `json:"health_check_interval_s"`
  421. // HealthCheckUrl specifies the address to send health checks to if the
  422. // health check type is "http".
  423. HealthCheckUrl string `json:"health_check_url"`
  424. // HealthCheckAddr specifies the address to connect to if the health check
  425. // type is "tcp".
  426. HealthCheckAddr string `json:"-"`
  427. }
  428. func (cfg *HealthCheckConf) compare(cmp *HealthCheckConf) bool {
  429. if cfg.HealthCheckType != cmp.HealthCheckType ||
  430. cfg.HealthCheckTimeoutS != cmp.HealthCheckTimeoutS ||
  431. cfg.HealthCheckMaxFailed != cmp.HealthCheckMaxFailed ||
  432. cfg.HealthCheckIntervalS != cmp.HealthCheckIntervalS ||
  433. cfg.HealthCheckUrl != cmp.HealthCheckUrl {
  434. return false
  435. }
  436. return true
  437. }
  438. func (cfg *HealthCheckConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  439. cfg.HealthCheckType = section["health_check_type"]
  440. cfg.HealthCheckUrl = section["health_check_url"]
  441. if tmpStr, ok := section["health_check_timeout_s"]; ok {
  442. if cfg.HealthCheckTimeoutS, err = strconv.Atoi(tmpStr); err != nil {
  443. return fmt.Errorf("Parse conf error: proxy [%s] health_check_timeout_s error", name)
  444. }
  445. }
  446. if tmpStr, ok := section["health_check_max_failed"]; ok {
  447. if cfg.HealthCheckMaxFailed, err = strconv.Atoi(tmpStr); err != nil {
  448. return fmt.Errorf("Parse conf error: proxy [%s] health_check_max_failed error", name)
  449. }
  450. }
  451. if tmpStr, ok := section["health_check_interval_s"]; ok {
  452. if cfg.HealthCheckIntervalS, err = strconv.Atoi(tmpStr); err != nil {
  453. return fmt.Errorf("Parse conf error: proxy [%s] health_check_interval_s error", name)
  454. }
  455. }
  456. return
  457. }
  458. func (cfg *HealthCheckConf) checkForCli() error {
  459. if cfg.HealthCheckType != "" && cfg.HealthCheckType != "tcp" && cfg.HealthCheckType != "http" {
  460. return fmt.Errorf("unsupport health check type")
  461. }
  462. if cfg.HealthCheckType != "" {
  463. if cfg.HealthCheckType == "http" && cfg.HealthCheckUrl == "" {
  464. return fmt.Errorf("health_check_url is required for health check type 'http'")
  465. }
  466. }
  467. return nil
  468. }
  469. // TCP
  470. type TcpProxyConf struct {
  471. BaseProxyConf
  472. BindInfoConf
  473. }
  474. func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
  475. cmpConf, ok := cmp.(*TcpProxyConf)
  476. if !ok {
  477. return false
  478. }
  479. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  480. !cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) {
  481. return false
  482. }
  483. return true
  484. }
  485. func (cfg *TcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  486. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  487. cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
  488. }
  489. func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  490. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  491. return
  492. }
  493. if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
  494. return
  495. }
  496. return
  497. }
  498. func (cfg *TcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  499. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  500. cfg.BindInfoConf.MarshalToMsg(pMsg)
  501. }
  502. func (cfg *TcpProxyConf) CheckForCli() (err error) {
  503. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  504. return err
  505. }
  506. return
  507. }
  508. func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
  509. // TCP Multiplexer
  510. type TcpMuxProxyConf struct {
  511. BaseProxyConf
  512. DomainConf
  513. Multiplexer string `json:"multiplexer"`
  514. }
  515. func (cfg *TcpMuxProxyConf) Compare(cmp ProxyConf) bool {
  516. cmpConf, ok := cmp.(*TcpMuxProxyConf)
  517. if !ok {
  518. return false
  519. }
  520. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  521. !cfg.DomainConf.compare(&cmpConf.DomainConf) ||
  522. cfg.Multiplexer != cmpConf.Multiplexer {
  523. return false
  524. }
  525. return true
  526. }
  527. func (cfg *TcpMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  528. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  529. cfg.DomainConf.UnmarshalFromMsg(pMsg)
  530. cfg.Multiplexer = pMsg.Multiplexer
  531. }
  532. func (cfg *TcpMuxProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  533. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  534. return
  535. }
  536. if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
  537. return
  538. }
  539. cfg.Multiplexer = section["multiplexer"]
  540. if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
  541. return fmt.Errorf("parse conf error: proxy [%s] incorrect multiplexer [%s]", name, cfg.Multiplexer)
  542. }
  543. return
  544. }
  545. func (cfg *TcpMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  546. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  547. cfg.DomainConf.MarshalToMsg(pMsg)
  548. pMsg.Multiplexer = cfg.Multiplexer
  549. }
  550. func (cfg *TcpMuxProxyConf) CheckForCli() (err error) {
  551. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  552. return err
  553. }
  554. if err = cfg.DomainConf.checkForCli(); err != nil {
  555. return err
  556. }
  557. if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
  558. return fmt.Errorf("parse conf error: incorrect multiplexer [%s]", cfg.Multiplexer)
  559. }
  560. return
  561. }
  562. func (cfg *TcpMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  563. if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
  564. return fmt.Errorf("proxy [%s] incorrect multiplexer [%s]", cfg.ProxyName, cfg.Multiplexer)
  565. }
  566. if cfg.Multiplexer == consts.HttpConnectTcpMultiplexer && serverCfg.TcpMuxHttpConnectPort == 0 {
  567. return fmt.Errorf("proxy [%s] type [tcpmux] with multiplexer [httpconnect] requires tcpmux_httpconnect_port configuration", cfg.ProxyName)
  568. }
  569. if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  570. err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  571. return
  572. }
  573. return
  574. }
  575. // UDP
  576. type UdpProxyConf struct {
  577. BaseProxyConf
  578. BindInfoConf
  579. }
  580. func (cfg *UdpProxyConf) Compare(cmp ProxyConf) bool {
  581. cmpConf, ok := cmp.(*UdpProxyConf)
  582. if !ok {
  583. return false
  584. }
  585. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  586. !cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) {
  587. return false
  588. }
  589. return true
  590. }
  591. func (cfg *UdpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  592. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  593. cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
  594. }
  595. func (cfg *UdpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  596. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  597. return
  598. }
  599. if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
  600. return
  601. }
  602. return
  603. }
  604. func (cfg *UdpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  605. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  606. cfg.BindInfoConf.MarshalToMsg(pMsg)
  607. }
  608. func (cfg *UdpProxyConf) CheckForCli() (err error) {
  609. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  610. return
  611. }
  612. return
  613. }
  614. func (cfg *UdpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
  615. // HTTP
  616. type HttpProxyConf struct {
  617. BaseProxyConf
  618. DomainConf
  619. Locations []string `json:"locations"`
  620. HttpUser string `json:"http_user"`
  621. HttpPwd string `json:"http_pwd"`
  622. HostHeaderRewrite string `json:"host_header_rewrite"`
  623. Headers map[string]string `json:"headers"`
  624. }
  625. func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
  626. cmpConf, ok := cmp.(*HttpProxyConf)
  627. if !ok {
  628. return false
  629. }
  630. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  631. !cfg.DomainConf.compare(&cmpConf.DomainConf) ||
  632. strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") ||
  633. cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
  634. cfg.HttpUser != cmpConf.HttpUser ||
  635. cfg.HttpPwd != cmpConf.HttpPwd ||
  636. len(cfg.Headers) != len(cmpConf.Headers) {
  637. return false
  638. }
  639. for k, v := range cfg.Headers {
  640. if v2, ok := cmpConf.Headers[k]; !ok {
  641. return false
  642. } else {
  643. if v != v2 {
  644. return false
  645. }
  646. }
  647. }
  648. return true
  649. }
  650. func (cfg *HttpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  651. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  652. cfg.DomainConf.UnmarshalFromMsg(pMsg)
  653. cfg.Locations = pMsg.Locations
  654. cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
  655. cfg.HttpUser = pMsg.HttpUser
  656. cfg.HttpPwd = pMsg.HttpPwd
  657. cfg.Headers = pMsg.Headers
  658. }
  659. func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  660. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  661. return
  662. }
  663. if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
  664. return
  665. }
  666. var (
  667. tmpStr string
  668. ok bool
  669. )
  670. if tmpStr, ok = section["locations"]; ok {
  671. cfg.Locations = strings.Split(tmpStr, ",")
  672. } else {
  673. cfg.Locations = []string{""}
  674. }
  675. cfg.HostHeaderRewrite = section["host_header_rewrite"]
  676. cfg.HttpUser = section["http_user"]
  677. cfg.HttpPwd = section["http_pwd"]
  678. cfg.Headers = make(map[string]string)
  679. for k, v := range section {
  680. if strings.HasPrefix(k, "header_") {
  681. cfg.Headers[strings.TrimPrefix(k, "header_")] = v
  682. }
  683. }
  684. return
  685. }
  686. func (cfg *HttpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  687. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  688. cfg.DomainConf.MarshalToMsg(pMsg)
  689. pMsg.Locations = cfg.Locations
  690. pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
  691. pMsg.HttpUser = cfg.HttpUser
  692. pMsg.HttpPwd = cfg.HttpPwd
  693. pMsg.Headers = cfg.Headers
  694. }
  695. func (cfg *HttpProxyConf) CheckForCli() (err error) {
  696. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  697. return
  698. }
  699. if err = cfg.DomainConf.checkForCli(); err != nil {
  700. return
  701. }
  702. return
  703. }
  704. func (cfg *HttpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  705. if serverCfg.VhostHttpPort == 0 {
  706. return fmt.Errorf("type [http] not support when vhost_http_port is not set")
  707. }
  708. if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  709. err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  710. return
  711. }
  712. return
  713. }
  714. // HTTPS
  715. type HttpsProxyConf struct {
  716. BaseProxyConf
  717. DomainConf
  718. }
  719. func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
  720. cmpConf, ok := cmp.(*HttpsProxyConf)
  721. if !ok {
  722. return false
  723. }
  724. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  725. !cfg.DomainConf.compare(&cmpConf.DomainConf) {
  726. return false
  727. }
  728. return true
  729. }
  730. func (cfg *HttpsProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  731. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  732. cfg.DomainConf.UnmarshalFromMsg(pMsg)
  733. }
  734. func (cfg *HttpsProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  735. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  736. return
  737. }
  738. if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
  739. return
  740. }
  741. return
  742. }
  743. func (cfg *HttpsProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  744. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  745. cfg.DomainConf.MarshalToMsg(pMsg)
  746. }
  747. func (cfg *HttpsProxyConf) CheckForCli() (err error) {
  748. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  749. return
  750. }
  751. if err = cfg.DomainConf.checkForCli(); err != nil {
  752. return
  753. }
  754. return
  755. }
  756. func (cfg *HttpsProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  757. if serverCfg.VhostHttpsPort == 0 {
  758. return fmt.Errorf("type [https] not support when vhost_https_port is not set")
  759. }
  760. if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
  761. err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
  762. return
  763. }
  764. return
  765. }
  766. // SUDP
  767. type SudpProxyConf struct {
  768. BaseProxyConf
  769. Role string `json:"role"`
  770. Sk string `json:"sk"`
  771. }
  772. func (cfg *SudpProxyConf) Compare(cmp ProxyConf) bool {
  773. cmpConf, ok := cmp.(*SudpProxyConf)
  774. if !ok {
  775. return false
  776. }
  777. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  778. cfg.Role != cmpConf.Role ||
  779. cfg.Sk != cmpConf.Sk {
  780. return false
  781. }
  782. return true
  783. }
  784. func (cfg *SudpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  785. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  786. return
  787. }
  788. cfg.Role = section["role"]
  789. if cfg.Role != "server" {
  790. return fmt.Errorf("Parse conf error: proxy [%s] incorrect role [%s]", name, cfg.Role)
  791. }
  792. cfg.Sk = section["sk"]
  793. if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
  794. return
  795. }
  796. return
  797. }
  798. func (cfg *SudpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  799. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  800. pMsg.Sk = cfg.Sk
  801. }
  802. func (cfg *SudpProxyConf) CheckForCli() (err error) {
  803. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  804. return
  805. }
  806. if cfg.Role != "server" {
  807. err = fmt.Errorf("role should be 'server'")
  808. return
  809. }
  810. return
  811. }
  812. func (cfg *SudpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  813. return
  814. }
  815. // Only for role server.
  816. func (cfg *SudpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  817. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  818. cfg.Sk = pMsg.Sk
  819. }
  820. // STCP
  821. type StcpProxyConf struct {
  822. BaseProxyConf
  823. Role string `json:"role"`
  824. Sk string `json:"sk"`
  825. }
  826. func (cfg *StcpProxyConf) Compare(cmp ProxyConf) bool {
  827. cmpConf, ok := cmp.(*StcpProxyConf)
  828. if !ok {
  829. return false
  830. }
  831. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  832. cfg.Role != cmpConf.Role ||
  833. cfg.Sk != cmpConf.Sk {
  834. return false
  835. }
  836. return true
  837. }
  838. // Only for role server.
  839. func (cfg *StcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  840. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  841. cfg.Sk = pMsg.Sk
  842. }
  843. func (cfg *StcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  844. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  845. return
  846. }
  847. cfg.Role = section["role"]
  848. if cfg.Role != "server" {
  849. return fmt.Errorf("Parse conf error: proxy [%s] incorrect role [%s]", name, cfg.Role)
  850. }
  851. cfg.Sk = section["sk"]
  852. if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
  853. return
  854. }
  855. return
  856. }
  857. func (cfg *StcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  858. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  859. pMsg.Sk = cfg.Sk
  860. }
  861. func (cfg *StcpProxyConf) CheckForCli() (err error) {
  862. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  863. return
  864. }
  865. if cfg.Role != "server" {
  866. err = fmt.Errorf("role should be 'server'")
  867. return
  868. }
  869. return
  870. }
  871. func (cfg *StcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  872. return
  873. }
  874. // XTCP
  875. type XtcpProxyConf struct {
  876. BaseProxyConf
  877. Role string `json:"role"`
  878. Sk string `json:"sk"`
  879. }
  880. func (cfg *XtcpProxyConf) Compare(cmp ProxyConf) bool {
  881. cmpConf, ok := cmp.(*XtcpProxyConf)
  882. if !ok {
  883. return false
  884. }
  885. if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
  886. !cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
  887. cfg.Role != cmpConf.Role ||
  888. cfg.Sk != cmpConf.Sk {
  889. return false
  890. }
  891. return true
  892. }
  893. // Only for role server.
  894. func (cfg *XtcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
  895. cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
  896. cfg.Sk = pMsg.Sk
  897. }
  898. func (cfg *XtcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
  899. if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
  900. return
  901. }
  902. cfg.Role = section["role"]
  903. if cfg.Role != "server" {
  904. return fmt.Errorf("Parse conf error: proxy [%s] incorrect role [%s]", name, cfg.Role)
  905. }
  906. cfg.Sk = section["sk"]
  907. if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
  908. return
  909. }
  910. return
  911. }
  912. func (cfg *XtcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
  913. cfg.BaseProxyConf.MarshalToMsg(pMsg)
  914. pMsg.Sk = cfg.Sk
  915. }
  916. func (cfg *XtcpProxyConf) CheckForCli() (err error) {
  917. if err = cfg.BaseProxyConf.checkForCli(); err != nil {
  918. return
  919. }
  920. if cfg.Role != "server" {
  921. err = fmt.Errorf("role should be 'server'")
  922. return
  923. }
  924. return
  925. }
  926. func (cfg *XtcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
  927. return
  928. }
  929. func ParseRangeSection(name string, section ini.Section) (sections map[string]ini.Section, err error) {
  930. localPorts, errRet := util.ParseRangeNumbers(section["local_port"])
  931. if errRet != nil {
  932. err = fmt.Errorf("Parse conf error: range section [%s] local_port invalid, %v", name, errRet)
  933. return
  934. }
  935. remotePorts, errRet := util.ParseRangeNumbers(section["remote_port"])
  936. if errRet != nil {
  937. err = fmt.Errorf("Parse conf error: range section [%s] remote_port invalid, %v", name, errRet)
  938. return
  939. }
  940. if len(localPorts) != len(remotePorts) {
  941. err = fmt.Errorf("Parse conf error: range section [%s] local ports number should be same with remote ports number", name)
  942. return
  943. }
  944. if len(localPorts) == 0 {
  945. err = fmt.Errorf("Parse conf error: range section [%s] local_port and remote_port is necessary", name)
  946. return
  947. }
  948. sections = make(map[string]ini.Section)
  949. for i, port := range localPorts {
  950. subName := fmt.Sprintf("%s_%d", name, i)
  951. subSection := copySection(section)
  952. subSection["local_port"] = fmt.Sprintf("%d", port)
  953. subSection["remote_port"] = fmt.Sprintf("%d", remotePorts[i])
  954. sections[subName] = subSection
  955. }
  956. return
  957. }
  958. // if len(startProxy) is 0, start all
  959. // otherwise just start proxies in startProxy map
  960. func LoadAllConfFromIni(prefix string, content string, startProxy map[string]struct{}) (
  961. proxyConfs map[string]ProxyConf, visitorConfs map[string]VisitorConf, err error) {
  962. conf, errRet := ini.Load(strings.NewReader(content))
  963. if errRet != nil {
  964. err = errRet
  965. return
  966. }
  967. if prefix != "" {
  968. prefix += "."
  969. }
  970. startAll := true
  971. if len(startProxy) > 0 {
  972. startAll = false
  973. }
  974. proxyConfs = make(map[string]ProxyConf)
  975. visitorConfs = make(map[string]VisitorConf)
  976. for name, section := range conf {
  977. if name == "common" {
  978. continue
  979. }
  980. _, shouldStart := startProxy[name]
  981. if !startAll && !shouldStart {
  982. continue
  983. }
  984. subSections := make(map[string]ini.Section)
  985. if strings.HasPrefix(name, "range:") {
  986. // range section
  987. rangePrefix := strings.TrimSpace(strings.TrimPrefix(name, "range:"))
  988. subSections, err = ParseRangeSection(rangePrefix, section)
  989. if err != nil {
  990. return
  991. }
  992. } else {
  993. subSections[name] = section
  994. }
  995. for subName, subSection := range subSections {
  996. if subSection["role"] == "" {
  997. subSection["role"] = "server"
  998. }
  999. role := subSection["role"]
  1000. if role == "server" {
  1001. cfg, errRet := NewProxyConfFromIni(prefix, subName, subSection)
  1002. if errRet != nil {
  1003. err = errRet
  1004. return
  1005. }
  1006. proxyConfs[prefix+subName] = cfg
  1007. } else if role == "visitor" {
  1008. cfg, errRet := NewVisitorConfFromIni(prefix, subName, subSection)
  1009. if errRet != nil {
  1010. err = errRet
  1011. return
  1012. }
  1013. visitorConfs[prefix+subName] = cfg
  1014. } else {
  1015. err = fmt.Errorf("role should be 'server' or 'visitor'")
  1016. return
  1017. }
  1018. }
  1019. }
  1020. return
  1021. }
  1022. func copySection(section ini.Section) (out ini.Section) {
  1023. out = make(ini.Section)
  1024. for k, v := range section {
  1025. out[k] = v
  1026. }
  1027. return
  1028. }