proxy.go 28 KB

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