tcpprox.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package tcpprox
  2. import (
  3. "errors"
  4. uuid "github.com/satori/go.uuid"
  5. "imuslab.com/zoraxy/mod/database"
  6. )
  7. /*
  8. TCP Proxy
  9. Forward port from one port to another
  10. Also accept active connection and passive
  11. connection
  12. */
  13. const (
  14. ProxyMode_Listen = 0
  15. ProxyMode_Transport = 1
  16. ProxyMode_Starter = 2
  17. )
  18. type ProxyRelayOptions struct {
  19. Name string
  20. PortA string
  21. PortB string
  22. Timeout int
  23. Mode int
  24. }
  25. type ProxyRelayConfig struct {
  26. UUID string //A UUIDv4 representing this config
  27. Name string //Name of the config
  28. Running bool //If the service is running
  29. PortA string //Ports A (config depends on mode)
  30. PortB string //Ports B (config depends on mode)
  31. Mode int //Operation Mode
  32. Timeout int //Timeout for connection in sec
  33. stopChan chan bool //Stop channel to stop the listener
  34. aTobAccumulatedByteTransfer int64 //Accumulated byte transfer from A to B
  35. bToaAccumulatedByteTransfer int64 //Accumulated byte transfer from B to A
  36. }
  37. type Options struct {
  38. Database *database.Database
  39. DefaultTimeout int
  40. }
  41. type Manager struct {
  42. //Config and stores
  43. Options *Options
  44. Configs []*ProxyRelayConfig
  45. //Realtime Statistics
  46. Connections int //currently connected connect counts
  47. }
  48. func NewTCProxy(options *Options) *Manager {
  49. options.Database.NewTable("tcprox")
  50. previousRules := []*ProxyRelayConfig{}
  51. if options.Database.KeyExists("tcprox", "rules") {
  52. options.Database.Read("tcprox", "rules", &previousRules)
  53. }
  54. return &Manager{
  55. Options: options,
  56. Configs: previousRules,
  57. Connections: 0,
  58. }
  59. }
  60. func (m *Manager) NewConfig(config *ProxyRelayOptions) string {
  61. //Generate a new config from options
  62. configUUID := uuid.NewV4().String()
  63. thisConfig := ProxyRelayConfig{
  64. UUID: configUUID,
  65. Name: config.Name,
  66. Running: false,
  67. PortA: config.PortA,
  68. PortB: config.PortB,
  69. Mode: config.Mode,
  70. Timeout: config.Timeout,
  71. stopChan: nil,
  72. aTobAccumulatedByteTransfer: 0,
  73. bToaAccumulatedByteTransfer: 0,
  74. }
  75. m.Configs = append(m.Configs, &thisConfig)
  76. m.SaveConfigToDatabase()
  77. return configUUID
  78. }
  79. func (m *Manager) GetConfigByUUID(configUUID string) (*ProxyRelayConfig, error) {
  80. // Find and return the config with the specified UUID
  81. for _, config := range m.Configs {
  82. if config.UUID == configUUID {
  83. return config, nil
  84. }
  85. }
  86. return nil, errors.New("config not found")
  87. }
  88. // Edit the config based on config UUID, leave empty for unchange fields
  89. func (m *Manager) EditConfig(configUUID string, newName string, newPortA string, newPortB string, newMode int, newTimeout int) error {
  90. // Find the config with the specified UUID
  91. foundConfig, err := m.GetConfigByUUID(configUUID)
  92. if err != nil {
  93. return err
  94. }
  95. // Validate and update the fields
  96. if newName != "" {
  97. foundConfig.Name = newName
  98. }
  99. if newPortA != "" {
  100. foundConfig.PortA = newPortA
  101. }
  102. if newPortB != "" {
  103. foundConfig.PortB = newPortB
  104. }
  105. if newMode != -1 {
  106. if newMode > 2 || newMode < 0 {
  107. return errors.New("invalid mode given")
  108. }
  109. foundConfig.Mode = newMode
  110. }
  111. if newTimeout != -1 {
  112. if newTimeout < 0 {
  113. return errors.New("invalid timeout value given")
  114. }
  115. foundConfig.Timeout = newTimeout
  116. }
  117. /*
  118. err = foundConfig.ValidateConfigs()
  119. if err != nil {
  120. return err
  121. }
  122. */
  123. m.SaveConfigToDatabase()
  124. return nil
  125. }
  126. func (m *Manager) RemoveConfig(configUUID string) error {
  127. // Find and remove the config with the specified UUID
  128. for i, config := range m.Configs {
  129. if config.UUID == configUUID {
  130. m.Configs = append(m.Configs[:i], m.Configs[i+1:]...)
  131. m.SaveConfigToDatabase()
  132. return nil
  133. }
  134. }
  135. return errors.New("config not found")
  136. }
  137. func (m *Manager) SaveConfigToDatabase() {
  138. m.Options.Database.Write("tcprox", "rules", m.Configs)
  139. }