tcpprox.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. accumulatedByteTransfered int64 //The total number of bytes transfered
  35. }
  36. type Options struct {
  37. Database *database.Database
  38. DefaultTimeout int
  39. }
  40. type Manager struct {
  41. //Config and stores
  42. Options *Options
  43. Configs []*ProxyRelayConfig
  44. //Realtime Statistics
  45. Connections int //currently connected connect counts
  46. }
  47. func NewTCProxy(options *Options) *Manager {
  48. options.Database.NewTable("tcprox")
  49. previousRules := []*ProxyRelayConfig{}
  50. if options.Database.KeyExists("tcprox", "rules") {
  51. options.Database.Read("tcprox", "rules", &previousRules)
  52. }
  53. return &Manager{
  54. Options: options,
  55. Configs: previousRules,
  56. Connections: 0,
  57. }
  58. }
  59. func (m *Manager) NewConfig(config *ProxyRelayOptions) string {
  60. //Generate a new config from options
  61. configUUID := uuid.NewV4().String()
  62. thisConfig := ProxyRelayConfig{
  63. UUID: configUUID,
  64. Name: config.Name,
  65. Running: false,
  66. PortA: config.PortA,
  67. PortB: config.PortB,
  68. Mode: config.Mode,
  69. Timeout: config.Timeout,
  70. stopChan: nil,
  71. accumulatedByteTransfered: 0,
  72. }
  73. m.Configs = append(m.Configs, &thisConfig)
  74. m.SaveConfigToDatabase()
  75. return configUUID
  76. }
  77. func (m *Manager) GetConfigByUUID(configUUID string) (*ProxyRelayConfig, error) {
  78. // Find and return the config with the specified UUID
  79. for _, config := range m.Configs {
  80. if config.UUID == configUUID {
  81. return config, nil
  82. }
  83. }
  84. return nil, errors.New("config not found")
  85. }
  86. // Edit the config based on config UUID, leave empty for unchange fields
  87. func (m *Manager) EditConfig(configUUID string, newName string, newPortA string, newPortB string, newMode int, newTimeout int) error {
  88. // Find the config with the specified UUID
  89. foundConfig, err := m.GetConfigByUUID(configUUID)
  90. if err != nil {
  91. return err
  92. }
  93. // Validate and update the fields
  94. if newName != "" {
  95. foundConfig.Name = newName
  96. }
  97. if newPortA != "" {
  98. if !isValidIP(newPortA) {
  99. return errors.New("PortA is not a valid IP")
  100. }
  101. foundConfig.PortA = newPortA
  102. }
  103. if newPortB != "" {
  104. if !isValidIP(newPortB) {
  105. return errors.New("PortB is not a valid IP")
  106. }
  107. foundConfig.PortB = newPortB
  108. }
  109. if newMode != 0 {
  110. if newMode > 2 || newMode < 0 {
  111. return errors.New("invalid mode given")
  112. }
  113. foundConfig.Mode = newMode
  114. }
  115. if newTimeout != 0 {
  116. foundConfig.Timeout = newTimeout
  117. }
  118. m.SaveConfigToDatabase()
  119. return nil
  120. }
  121. func (m *Manager) RemoveConfig(configUUID string) error {
  122. // Find and remove the config with the specified UUID
  123. for i, config := range m.Configs {
  124. if config.UUID == configUUID {
  125. m.Configs = append(m.Configs[:i], m.Configs[i+1:]...)
  126. m.SaveConfigToDatabase()
  127. return nil
  128. }
  129. }
  130. return errors.New("config not found")
  131. }
  132. func (m *Manager) SaveConfigToDatabase() {
  133. m.Options.Database.Write("tcprox", "rules", m.Configs)
  134. }