file.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. package utils
  2. import (
  3. "easyProxy/utils"
  4. "encoding/csv"
  5. "errors"
  6. "github.com/astaxie/beego"
  7. "log"
  8. "os"
  9. "strconv"
  10. "sync"
  11. )
  12. var (
  13. CsvDb *Csv
  14. once sync.Once
  15. )
  16. type Flow struct {
  17. ExportFlow int64 //出口流量
  18. InletFlow int64 //入口流量
  19. }
  20. type Client struct {
  21. Cnf *Config
  22. Id int //id
  23. VerifyKey string //验证密钥
  24. Addr string //客户端ip地址
  25. Remark string //备注
  26. Status bool //是否开启
  27. IsConnect bool //是否连接
  28. Flow *Flow
  29. }
  30. type Tunnel struct {
  31. Id int //Id
  32. TcpPort int //服务端与客户端通信端口
  33. Mode string //启动方式
  34. Target string //目标
  35. Status bool //是否开启
  36. Client *Client //所属客户端id
  37. Flow *Flow
  38. Config *Config
  39. UseClientCnf bool //是否继承客户端配置
  40. Remark string //备注
  41. }
  42. type Config struct {
  43. U string //socks5验证用户名
  44. P string //socks5验证密码
  45. Compress string //压缩方式
  46. Crypt bool //是否加密
  47. Mux bool //是否加密
  48. CompressEncode int //加密方式
  49. CompressDecode int //解密方式
  50. }
  51. type Host struct {
  52. Host string //启动方式
  53. Target string //目标
  54. HeaderChange string //host修改
  55. HostChange string //host修改
  56. Flow *Flow
  57. Client *Client
  58. Remark string //备注
  59. }
  60. func NewCsv() *Csv {
  61. c := new(Csv)
  62. return c
  63. }
  64. type Csv struct {
  65. Tasks []*Tunnel
  66. Path string
  67. Hosts []*Host //域名列表
  68. Clients []*Client //客户端
  69. ClientIncreaseId int //客户端id
  70. TaskIncreaseId int //任务自增ID
  71. sync.Mutex
  72. }
  73. func (s *Csv) Init() {
  74. s.LoadClientFromCsv()
  75. s.LoadTaskFromCsv()
  76. s.LoadHostFromCsv()
  77. }
  78. func (s *Csv) StoreTasksToCsv() {
  79. // 创建文件
  80. csvFile, err := os.Create(beego.AppPath + "/conf/tasks.csv")
  81. if err != nil {
  82. log.Fatalf(err.Error())
  83. }
  84. defer csvFile.Close()
  85. writer := csv.NewWriter(csvFile)
  86. for _, task := range s.Tasks {
  87. record := []string{
  88. strconv.Itoa(task.TcpPort),
  89. task.Mode,
  90. task.Target,
  91. task.Config.U,
  92. task.Config.P,
  93. task.Config.Compress,
  94. utils.GetStrByBool(task.Status),
  95. GetStrByBool(task.Config.Crypt),
  96. GetStrByBool(task.Config.Mux),
  97. strconv.Itoa(task.Config.CompressEncode),
  98. strconv.Itoa(task.Config.CompressDecode),
  99. strconv.Itoa(task.Id),
  100. strconv.Itoa(task.Client.Id),
  101. strconv.FormatBool(task.UseClientCnf),
  102. task.Remark,
  103. }
  104. err := writer.Write(record)
  105. if err != nil {
  106. log.Fatalf(err.Error())
  107. }
  108. }
  109. writer.Flush()
  110. }
  111. func (s *Csv) openFile(path string) ([][]string, error) {
  112. // 打开文件
  113. file, err := os.Open(path)
  114. if err != nil {
  115. panic(err)
  116. }
  117. defer file.Close()
  118. // 获取csv的reader
  119. reader := csv.NewReader(file)
  120. // 设置FieldsPerRecord为-1
  121. reader.FieldsPerRecord = -1
  122. // 读取文件中所有行保存到slice中
  123. return reader.ReadAll()
  124. }
  125. func (s *Csv) LoadTaskFromCsv() {
  126. path := beego.AppPath + "/conf/tasks.csv"
  127. records, err := s.openFile(path)
  128. if err != nil {
  129. log.Fatal("配置文件打开错误:", path)
  130. }
  131. var tasks []*Tunnel
  132. // 将每一行数据保存到内存slice中
  133. for _, item := range records {
  134. post := &Tunnel{
  135. TcpPort: GetIntNoErrByStr(item[0]),
  136. Mode: item[1],
  137. Target: item[2],
  138. Config: &Config{
  139. U: item[3],
  140. P: item[4],
  141. Compress: item[5],
  142. Crypt: GetBoolByStr(item[7]),
  143. Mux: GetBoolByStr(item[8]),
  144. CompressEncode: GetIntNoErrByStr(item[9]),
  145. CompressDecode: GetIntNoErrByStr(item[10]),
  146. },
  147. Status: utils.GetBoolByStr(item[6]),
  148. Id: GetIntNoErrByStr(item[11]),
  149. UseClientCnf: GetBoolByStr(item[13]),
  150. Remark: item[14],
  151. }
  152. post.Flow = new(Flow)
  153. if post.Client, err = s.GetClient(GetIntNoErrByStr(item[12])); err != nil {
  154. continue
  155. }
  156. tasks = append(tasks, post)
  157. if post.Id > s.TaskIncreaseId {
  158. s.TaskIncreaseId = post.Id
  159. }
  160. }
  161. s.Tasks = tasks
  162. }
  163. func (s *Csv) GetTaskId() int {
  164. s.Lock()
  165. defer s.Unlock()
  166. s.TaskIncreaseId++
  167. return s.TaskIncreaseId
  168. }
  169. func (s *Csv) GetIdByVerifyKey(vKey string, addr string) (int, error) {
  170. s.Lock()
  171. defer s.Unlock()
  172. for _, v := range s.Clients {
  173. if utils.Getverifyval(v.VerifyKey) == vKey && v.Status {
  174. v.Addr = addr
  175. return v.Id, nil
  176. }
  177. }
  178. return 0, errors.New("not found")
  179. }
  180. func (s *Csv) NewTask(t *Tunnel) {
  181. t.Flow = new(Flow)
  182. s.Tasks = append(s.Tasks, t)
  183. s.StoreTasksToCsv()
  184. }
  185. func (s *Csv) UpdateTask(t *Tunnel) error {
  186. for k, v := range s.Tasks {
  187. if v.Id == t.Id {
  188. s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
  189. s.Tasks = append(s.Tasks, t)
  190. s.StoreTasksToCsv()
  191. return nil
  192. }
  193. }
  194. return errors.New("不存在")
  195. }
  196. func (s *Csv) DelTask(id int) error {
  197. for k, v := range s.Tasks {
  198. if v.Id == id {
  199. s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
  200. s.StoreTasksToCsv()
  201. return nil
  202. }
  203. }
  204. return errors.New("不存在")
  205. }
  206. func (s *Csv) GetTask(id int) (v *Tunnel, err error) {
  207. for _, v = range s.Tasks {
  208. if v.Id == id {
  209. return
  210. }
  211. }
  212. err = errors.New("未找到")
  213. return
  214. }
  215. func (s *Csv) StoreHostToCsv() {
  216. // 创建文件
  217. csvFile, err := os.Create(beego.AppPath + "/conf/hosts.csv")
  218. if err != nil {
  219. panic(err)
  220. }
  221. defer csvFile.Close()
  222. // 获取csv的Writer
  223. writer := csv.NewWriter(csvFile)
  224. // 将map中的Post转换成slice,因为csv的Write需要slice参数
  225. // 并写入csv文件
  226. for _, host := range s.Hosts {
  227. record := []string{
  228. host.Host,
  229. host.Target,
  230. strconv.Itoa(host.Client.Id),
  231. host.HeaderChange,
  232. host.HostChange,
  233. host.Remark,
  234. }
  235. err1 := writer.Write(record)
  236. if err1 != nil {
  237. panic(err1)
  238. }
  239. }
  240. // 确保所有内存数据刷到csv文件
  241. writer.Flush()
  242. }
  243. func (s *Csv) LoadClientFromCsv() {
  244. path := beego.AppPath + "/conf/clients.csv"
  245. records, err := s.openFile(path)
  246. if err != nil {
  247. log.Fatal("配置文件打开错误:", path)
  248. }
  249. var clients []*Client
  250. // 将每一行数据保存到内存slice中
  251. for _, item := range records {
  252. post := &Client{
  253. Id: GetIntNoErrByStr(item[0]),
  254. VerifyKey: item[1],
  255. Addr: item[2],
  256. Remark: item[3],
  257. Status: GetBoolByStr(item[4]),
  258. Cnf: &Config{
  259. U: item[5],
  260. P: item[6],
  261. Crypt: GetBoolByStr(item[7]),
  262. Mux: GetBoolByStr(item[8]),
  263. Compress: item[9],
  264. },
  265. }
  266. if post.Id > s.ClientIncreaseId {
  267. s.ClientIncreaseId = post.Id
  268. }
  269. post.Flow = new(Flow)
  270. clients = append(clients, post)
  271. }
  272. s.Clients = clients
  273. }
  274. func (s *Csv) LoadHostFromCsv() {
  275. path := beego.AppPath + "/conf/hosts.csv"
  276. records, err := s.openFile(path)
  277. if err != nil {
  278. log.Fatal("配置文件打开错误:", path)
  279. }
  280. var hosts []*Host
  281. // 将每一行数据保存到内存slice中
  282. for _, item := range records {
  283. post := &Host{
  284. Host: item[0],
  285. Target: item[1],
  286. HeaderChange: item[3],
  287. HostChange: item[4],
  288. Remark: item[5],
  289. }
  290. if post.Client, err = s.GetClient(GetIntNoErrByStr(item[2])); err != nil {
  291. continue
  292. }
  293. post.Flow = new(Flow)
  294. hosts = append(hosts, post)
  295. }
  296. s.Hosts = hosts
  297. }
  298. func (s *Csv) DelHost(host string) error {
  299. for k, v := range s.Hosts {
  300. if v.Host == host {
  301. s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
  302. s.StoreHostToCsv()
  303. return nil
  304. }
  305. }
  306. return errors.New("不存在")
  307. }
  308. func (s *Csv) NewHost(t *Host) {
  309. t.Flow = new(Flow)
  310. s.Hosts = append(s.Hosts, t)
  311. s.StoreHostToCsv()
  312. }
  313. func (s *Csv) UpdateHost(t *Host) error {
  314. for k, v := range s.Hosts {
  315. if v.Host == t.Host {
  316. s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
  317. s.Hosts = append(s.Hosts, t)
  318. s.StoreHostToCsv()
  319. return nil
  320. }
  321. }
  322. return errors.New("不存在")
  323. }
  324. func (s *Csv) GetHost(start, length int, id int) ([]*Host, int) {
  325. list := make([]*Host, 0)
  326. var cnt int
  327. for _, v := range s.Hosts {
  328. if id == 0 || v.Client.Id == id {
  329. cnt++
  330. if start--; start < 0 {
  331. if length--; length > 0 {
  332. list = append(list, v)
  333. }
  334. }
  335. }
  336. }
  337. return list, cnt
  338. }
  339. func (s *Csv) DelClient(id int) error {
  340. for k, v := range s.Clients {
  341. if v.Id == id {
  342. s.Clients = append(s.Clients[:k], s.Clients[k+1:]...)
  343. s.StoreClientsToCsv()
  344. return nil
  345. }
  346. }
  347. return errors.New("不存在")
  348. }
  349. func (s *Csv) NewClient(c *Client) {
  350. s.Lock()
  351. defer s.Unlock()
  352. c.Flow = new(Flow)
  353. s.Clients = append(s.Clients, c)
  354. s.StoreClientsToCsv()
  355. }
  356. func (s *Csv) GetClientId() int {
  357. s.Lock()
  358. defer s.Unlock()
  359. s.ClientIncreaseId++
  360. return s.ClientIncreaseId
  361. }
  362. func (s *Csv) UpdateClient(t *Client) error {
  363. s.Lock()
  364. defer s.Unlock()
  365. for k, v := range s.Clients {
  366. if v.Id == t.Id {
  367. s.Clients = append(s.Clients[:k], s.Clients[k+1:]...)
  368. s.Clients = append(s.Clients, t)
  369. s.StoreClientsToCsv()
  370. return nil
  371. }
  372. }
  373. return errors.New("不存在")
  374. }
  375. func (s *Csv) GetClientList(start, length int) ([]*Client, int) {
  376. list := make([]*Client, 0)
  377. var cnt int
  378. for _, v := range s.Clients {
  379. cnt++
  380. if start--; start < 0 {
  381. if length--; length > 0 {
  382. list = append(list, v)
  383. }
  384. }
  385. }
  386. return list, cnt
  387. }
  388. func (s *Csv) GetClient(id int) (v *Client, err error) {
  389. for _, v = range s.Clients {
  390. if v.Id == id {
  391. return
  392. }
  393. }
  394. err = errors.New("未找到")
  395. return
  396. }
  397. func (s *Csv) StoreClientsToCsv() {
  398. // 创建文件
  399. csvFile, err := os.Create(beego.AppPath + "/conf/clients.csv")
  400. if err != nil {
  401. log.Fatalf(err.Error())
  402. }
  403. defer csvFile.Close()
  404. writer := csv.NewWriter(csvFile)
  405. for _, client := range s.Clients {
  406. record := []string{
  407. strconv.Itoa(client.Id),
  408. client.VerifyKey,
  409. client.Addr,
  410. client.Remark,
  411. strconv.FormatBool(client.Status),
  412. client.Cnf.U,
  413. client.Cnf.P,
  414. utils.GetStrByBool(client.Cnf.Crypt),
  415. utils.GetStrByBool(client.Cnf.Mux),
  416. client.Cnf.Compress,
  417. }
  418. err := writer.Write(record)
  419. if err != nil {
  420. log.Fatalf(err.Error())
  421. }
  422. }
  423. writer.Flush()
  424. }
  425. //init csv from file
  426. func GetCsvDb() *Csv {
  427. once.Do(func() {
  428. CsvDb = NewCsv()
  429. CsvDb.Init()
  430. })
  431. return CsvDb
  432. }
  433. //深拷贝Tunnel
  434. func DeepCopyConfig(c *Config) *Config {
  435. return &Config{
  436. U: c.U,
  437. P: c.P,
  438. Compress: c.Compress,
  439. Crypt: c.Crypt,
  440. Mux: c.Mux,
  441. CompressEncode: c.CompressEncode,
  442. CompressDecode: c.CompressDecode,
  443. }
  444. }