server.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package server
  2. import (
  3. "errors"
  4. "github.com/cnlh/nps/bridge"
  5. "github.com/cnlh/nps/lib/file"
  6. "github.com/cnlh/nps/lib/lg"
  7. "reflect"
  8. "strings"
  9. )
  10. var (
  11. Bridge *bridge.Bridge
  12. RunList map[int]interface{} //运行中的任务
  13. )
  14. func init() {
  15. RunList = make(map[int]interface{})
  16. }
  17. //从csv文件中恢复任务
  18. func InitFromCsv() {
  19. for _, v := range file.GetCsvDb().Tasks {
  20. if v.Status {
  21. lg.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
  22. AddTask(v)
  23. }
  24. }
  25. }
  26. //start a new server
  27. func StartNewServer(bridgePort int, cnf *file.Tunnel, bridgeType string) {
  28. Bridge = bridge.NewTunnel(bridgePort, RunList, bridgeType)
  29. if err := Bridge.StartTunnel(); err != nil {
  30. lg.Fatalln("服务端开启失败", err)
  31. }
  32. if svr := NewMode(Bridge, cnf); svr != nil {
  33. RunList[cnf.Id] = svr
  34. err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
  35. if err.Interface() != nil {
  36. lg.Fatalln(err)
  37. }
  38. } else {
  39. lg.Fatalln("启动模式不正确")
  40. }
  41. }
  42. //new a server by mode name
  43. func NewMode(Bridge *bridge.Bridge, c *file.Tunnel) interface{} {
  44. switch c.Mode {
  45. case "tunnelServer":
  46. return NewTunnelModeServer(ProcessTunnel, Bridge, c)
  47. case "socks5Server":
  48. return NewSock5ModeServer(Bridge, c)
  49. case "httpProxyServer":
  50. return NewTunnelModeServer(ProcessHttp, Bridge, c)
  51. case "udpServer":
  52. return NewUdpModeServer(Bridge, c)
  53. case "webServer":
  54. InitFromCsv()
  55. t := &file.Tunnel{
  56. TcpPort: 0,
  57. Mode: "httpHostServer",
  58. Target: "",
  59. Config: &file.Config{},
  60. Status: true,
  61. }
  62. AddTask(t)
  63. return NewWebServer(Bridge)
  64. case "httpHostServer":
  65. return NewHttp(Bridge, c)
  66. }
  67. return nil
  68. }
  69. //stop server
  70. func StopServer(id int) error {
  71. if v, ok := RunList[id]; ok {
  72. reflect.ValueOf(v).MethodByName("Close").Call(nil)
  73. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  74. return err
  75. } else {
  76. t.Status = false
  77. file.GetCsvDb().UpdateTask(t)
  78. }
  79. return nil
  80. }
  81. return errors.New("未在运行中")
  82. }
  83. //add task
  84. func AddTask(t *file.Tunnel) error {
  85. if svr := NewMode(Bridge, t); svr != nil {
  86. RunList[t.Id] = svr
  87. go func() {
  88. err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
  89. if err.Interface() != nil {
  90. lg.Fatalln("客户端", t.Id, "启动失败,错误:", err)
  91. delete(RunList, t.Id)
  92. }
  93. }()
  94. } else {
  95. return errors.New("启动模式不正确")
  96. }
  97. return nil
  98. }
  99. //start task
  100. func StartTask(id int) error {
  101. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  102. return err
  103. } else {
  104. AddTask(t)
  105. t.Status = true
  106. file.GetCsvDb().UpdateTask(t)
  107. }
  108. return nil
  109. }
  110. //delete task
  111. func DelTask(id int) error {
  112. if err := StopServer(id); err != nil {
  113. return err
  114. }
  115. return file.GetCsvDb().DelTask(id)
  116. }
  117. //get key by host from x
  118. func GetInfoByHost(host string) (h *file.Host, err error) {
  119. for _, v := range file.GetCsvDb().Hosts {
  120. s := strings.Split(host, ":")
  121. if s[0] == v.Host {
  122. h = v
  123. return
  124. }
  125. }
  126. err = errors.New("未找到host对应的内网目标")
  127. return
  128. }
  129. //get task list by page num
  130. func GetTunnel(start, length int, typeVal string, clientId int) ([]*file.Tunnel, int) {
  131. list := make([]*file.Tunnel, 0)
  132. var cnt int
  133. for _, v := range file.GetCsvDb().Tasks {
  134. if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
  135. continue
  136. }
  137. cnt++
  138. if _, ok := Bridge.Client[v.Client.Id]; ok {
  139. v.Client.IsConnect = true
  140. } else {
  141. v.Client.IsConnect = false
  142. }
  143. if start--; start < 0 {
  144. if length--; length > 0 {
  145. if _, ok := RunList[v.Id]; ok {
  146. v.Client.Status = true
  147. } else {
  148. v.Client.Status = false
  149. }
  150. list = append(list, v)
  151. }
  152. }
  153. }
  154. return list, cnt
  155. }
  156. //获取客户端列表
  157. func GetClientList(start, length int) (list []*file.Client, cnt int) {
  158. list, cnt = file.GetCsvDb().GetClientList(start, length)
  159. dealClientData(list)
  160. return
  161. }
  162. func dealClientData(list []*file.Client) {
  163. for _, v := range list {
  164. if _, ok := Bridge.Client[v.Id]; ok {
  165. v.IsConnect = true
  166. } else {
  167. v.IsConnect = false
  168. }
  169. v.Flow.InletFlow = 0
  170. v.Flow.ExportFlow = 0
  171. for _, h := range file.GetCsvDb().Hosts {
  172. if h.Client.Id == v.Id {
  173. v.Flow.InletFlow += h.Flow.InletFlow
  174. v.Flow.ExportFlow += h.Flow.ExportFlow
  175. }
  176. }
  177. for _, t := range file.GetCsvDb().Tasks {
  178. if t.Client.Id == v.Id {
  179. v.Flow.InletFlow += t.Flow.InletFlow
  180. v.Flow.ExportFlow += t.Flow.ExportFlow
  181. }
  182. }
  183. }
  184. return
  185. }
  186. //根据客户端id删除其所属的所有隧道和域名
  187. func DelTunnelAndHostByClientId(clientId int) {
  188. for _, v := range file.GetCsvDb().Tasks {
  189. if v.Client.Id == clientId {
  190. DelTask(v.Id)
  191. }
  192. }
  193. for _, v := range file.GetCsvDb().Hosts {
  194. if v.Client.Id == clientId {
  195. file.GetCsvDb().DelHost(v.Host)
  196. }
  197. }
  198. }
  199. //关闭客户端连接
  200. func DelClientConnect(clientId int) {
  201. Bridge.DelClient(clientId)
  202. }
  203. func GetDashboardData() map[string]int {
  204. data := make(map[string]int)
  205. data["hostCount"] = len(file.GetCsvDb().Hosts)
  206. data["clientCount"] = len(file.GetCsvDb().Clients)
  207. list := file.GetCsvDb().Clients
  208. dealClientData(list)
  209. c := 0
  210. var in, out int64
  211. for _, v := range list {
  212. if v.IsConnect {
  213. c += 1
  214. }
  215. in += v.Flow.InletFlow
  216. out += v.Flow.ExportFlow
  217. }
  218. data["clientOnlineCount"] = c
  219. data["inletFlowCount"] = int(in)
  220. data["exportFlowCount"] = int(out)
  221. for _, v := range file.GetCsvDb().Tasks {
  222. switch v.Mode {
  223. case "tunnelServer":
  224. data["tunnelServerCount"] += 1
  225. case "socks5Server":
  226. data["socks5ServerCount"] += 1
  227. case "httpProxyServer":
  228. data["httpProxyServerCount"] += 1
  229. case "udpServer":
  230. data["udpServerCount"] += 1
  231. }
  232. }
  233. return data
  234. }