proxy.go 28 KB

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