server.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package server
  2. import (
  3. "errors"
  4. "github.com/cnlh/nps/bridge"
  5. "github.com/cnlh/nps/lib/common"
  6. "github.com/cnlh/nps/lib/file"
  7. "github.com/cnlh/nps/server/proxy"
  8. "github.com/cnlh/nps/server/tool"
  9. "github.com/cnlh/nps/vender/github.com/astaxie/beego"
  10. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  11. "os"
  12. "time"
  13. )
  14. var (
  15. Bridge *bridge.Bridge
  16. RunList map[int]interface{} //运行中的任务
  17. )
  18. func init() {
  19. RunList = make(map[int]interface{})
  20. }
  21. //从csv文件中恢复任务
  22. func InitFromCsv() {
  23. //Add a public password
  24. if vkey := beego.AppConfig.String("publicVkey"); vkey != "" {
  25. c := file.NewClient(vkey, true, true)
  26. file.GetCsvDb().NewClient(c)
  27. RunList[c.Id] = nil
  28. }
  29. //Initialize services in server-side files
  30. for _, v := range file.GetCsvDb().Tasks {
  31. if v.Status {
  32. AddTask(v)
  33. }
  34. }
  35. }
  36. func DealBridgeTask() {
  37. for {
  38. select {
  39. case t := <-Bridge.OpenTask:
  40. AddTask(t)
  41. case id := <-Bridge.CloseClient:
  42. DelTunnelAndHostByClientId(id)
  43. file.GetCsvDb().DelClient(id)
  44. case s := <-Bridge.SecretChan:
  45. logs.Trace("New secret connection, addr", s.Conn.Conn.RemoteAddr())
  46. if t := file.GetCsvDb().GetSecretTask(s.Password); t != nil {
  47. if !t.Client.GetConn() {
  48. logs.Info("Connections exceed the current client %d limit", t.Client.Id)
  49. s.Conn.Close()
  50. } else if t.Status {
  51. go proxy.NewBaseServer(Bridge, t).DealClient(s.Conn, t.Target, nil)
  52. } else {
  53. s.Conn.Close()
  54. logs.Trace("This key %s cannot be processed,status is close", s.Password)
  55. }
  56. } else {
  57. logs.Trace("This key %s cannot be processed", s.Password)
  58. s.Conn.Close()
  59. }
  60. }
  61. }
  62. }
  63. //start a new server
  64. func StartNewServer(bridgePort int, cnf *file.Tunnel, bridgeType string) {
  65. Bridge = bridge.NewTunnel(bridgePort, bridgeType, common.GetBoolByStr(beego.AppConfig.String("ipLimit")), RunList)
  66. if err := Bridge.StartTunnel(); err != nil {
  67. logs.Error("服务端开启失败", err)
  68. os.Exit(0)
  69. } else {
  70. logs.Info("Server startup, the bridge type is %s, the bridge port is %d", bridgeType, bridgePort)
  71. }
  72. go DealBridgeTask()
  73. if svr := NewMode(Bridge, cnf); svr != nil {
  74. if err := svr.Start(); err != nil {
  75. logs.Error(err)
  76. }
  77. RunList[cnf.Id] = svr
  78. } else {
  79. logs.Error("Incorrect startup mode %s", cnf.Mode)
  80. }
  81. }
  82. //new a server by mode name
  83. func NewMode(Bridge *bridge.Bridge, c *file.Tunnel) proxy.Service {
  84. var service proxy.Service
  85. switch c.Mode {
  86. case "tcpServer":
  87. service = proxy.NewTunnelModeServer(proxy.ProcessTunnel, Bridge, c)
  88. case "socks5Server":
  89. service = proxy.NewSock5ModeServer(Bridge, c)
  90. case "httpProxyServer":
  91. service = proxy.NewTunnelModeServer(proxy.ProcessHttp, Bridge, c)
  92. case "udpServer":
  93. service = proxy.NewUdpModeServer(Bridge, c)
  94. case "webServer":
  95. InitFromCsv()
  96. t := &file.Tunnel{
  97. Port: 0,
  98. Mode: "httpHostServer",
  99. Target: "",
  100. Status: true,
  101. }
  102. AddTask(t)
  103. service = proxy.NewWebServer(Bridge)
  104. case "httpHostServer":
  105. service = proxy.NewHttp(Bridge, c)
  106. }
  107. return service
  108. }
  109. //stop server
  110. func StopServer(id int) error {
  111. if v, ok := RunList[id]; ok {
  112. if svr, ok := v.(proxy.Service); ok {
  113. if err := svr.Close(); err != nil {
  114. return err
  115. }
  116. }
  117. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  118. return err
  119. } else {
  120. t.Status = false
  121. file.GetCsvDb().UpdateTask(t)
  122. }
  123. delete(RunList, id)
  124. return nil
  125. }
  126. return errors.New("未在运行中")
  127. }
  128. //add task
  129. func AddTask(t *file.Tunnel) error {
  130. if t.Mode == "secretServer" {
  131. logs.Info("secret task %s start ", t.Remark)
  132. RunList[t.Id] = nil
  133. return nil
  134. }
  135. if b := tool.TestServerPort(t.Port, t.Mode); !b && t.Mode != "httpHostServer" {
  136. logs.Error("taskId %d start error port %d open failed", t.Id, t.Port)
  137. return errors.New("the port open error")
  138. }
  139. if minute, err := beego.AppConfig.Int("flowStoreInterval"); err == nil && minute > 0 {
  140. go flowSession(time.Minute * time.Duration(minute))
  141. }
  142. if svr := NewMode(Bridge, t); svr != nil {
  143. logs.Info("tunnel task %s start mode:%s port %d", t.Remark, t.Mode, t.Port)
  144. RunList[t.Id] = svr
  145. go func() {
  146. if err := svr.Start(); err != nil {
  147. logs.Error("clientId %d taskId %d start error %s", t.Client.Id, t.Id, err)
  148. delete(RunList, t.Id)
  149. return
  150. }
  151. }()
  152. } else {
  153. return errors.New("the mode is not correct")
  154. }
  155. return nil
  156. }
  157. //start task
  158. func StartTask(id int) error {
  159. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  160. return err
  161. } else {
  162. AddTask(t)
  163. t.Status = true
  164. file.GetCsvDb().UpdateTask(t)
  165. }
  166. return nil
  167. }
  168. //delete task
  169. func DelTask(id int) error {
  170. if _, ok := RunList[id]; ok {
  171. if err := StopServer(id); err != nil {
  172. return err
  173. }
  174. }
  175. return file.GetCsvDb().DelTask(id)
  176. }
  177. //get task list by page num
  178. func GetTunnel(start, length int, typeVal string, clientId int) ([]*file.Tunnel, int) {
  179. list := make([]*file.Tunnel, 0)
  180. var cnt int
  181. for _, v := range file.GetCsvDb().Tasks {
  182. if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
  183. continue
  184. }
  185. cnt++
  186. if _, ok := Bridge.Client[v.Client.Id]; ok {
  187. v.Client.IsConnect = true
  188. } else {
  189. v.Client.IsConnect = false
  190. }
  191. if start--; start < 0 {
  192. if length--; length > 0 {
  193. if _, ok := RunList[v.Id]; ok {
  194. v.RunStatus = true
  195. } else {
  196. v.RunStatus = false
  197. }
  198. list = append(list, v)
  199. }
  200. }
  201. }
  202. return list, cnt
  203. }
  204. //获取客户端列表
  205. func GetClientList(start, length int) (list []*file.Client, cnt int) {
  206. list, cnt = file.GetCsvDb().GetClientList(start, length)
  207. dealClientData(list)
  208. return
  209. }
  210. func dealClientData(list []*file.Client) {
  211. for _, v := range list {
  212. if _, ok := Bridge.Client[v.Id]; ok {
  213. v.IsConnect = true
  214. } else {
  215. v.IsConnect = false
  216. }
  217. v.Flow.InletFlow = 0
  218. v.Flow.ExportFlow = 0
  219. for _, h := range file.GetCsvDb().Hosts {
  220. if h.Client.Id == v.Id {
  221. v.Flow.InletFlow += h.Flow.InletFlow
  222. v.Flow.ExportFlow += h.Flow.ExportFlow
  223. }
  224. }
  225. for _, t := range file.GetCsvDb().Tasks {
  226. if t.Client.Id == v.Id {
  227. v.Flow.InletFlow += t.Flow.InletFlow
  228. v.Flow.ExportFlow += t.Flow.ExportFlow
  229. }
  230. }
  231. }
  232. return
  233. }
  234. //根据客户端id删除其所属的所有隧道和域名
  235. func DelTunnelAndHostByClientId(clientId int) {
  236. var ids []int
  237. for _, v := range file.GetCsvDb().Tasks {
  238. if v.Client.Id == clientId {
  239. ids = append(ids, v.Id)
  240. }
  241. }
  242. for _, id := range ids {
  243. DelTask(id)
  244. }
  245. for _, v := range file.GetCsvDb().Hosts {
  246. if v.Client.Id == clientId {
  247. file.GetCsvDb().DelHost(v.Id)
  248. }
  249. }
  250. }
  251. //关闭客户端连接
  252. func DelClientConnect(clientId int) {
  253. Bridge.DelClient(clientId)
  254. }
  255. func GetDashboardData() map[string]int {
  256. data := make(map[string]int)
  257. data["hostCount"] = len(file.GetCsvDb().Hosts)
  258. data["clientCount"] = len(file.GetCsvDb().Clients) - 1 //Remove the public key client
  259. list := file.GetCsvDb().Clients
  260. dealClientData(list)
  261. c := 0
  262. var in, out int64
  263. for _, v := range list {
  264. if v.IsConnect {
  265. c += 1
  266. }
  267. in += v.Flow.InletFlow
  268. out += v.Flow.ExportFlow
  269. }
  270. data["clientOnlineCount"] = c
  271. data["inletFlowCount"] = int(in)
  272. data["exportFlowCount"] = int(out)
  273. for _, v := range file.GetCsvDb().Tasks {
  274. switch v.Mode {
  275. case "tcpServer":
  276. data["tcpServerCount"] += 1
  277. case "socks5Server":
  278. data["socks5ServerCount"] += 1
  279. case "httpProxyServer":
  280. data["httpProxyServerCount"] += 1
  281. case "udpServer":
  282. data["udpServerCount"] += 1
  283. }
  284. }
  285. tcpCount := 0
  286. for _, v := range file.GetCsvDb().Clients {
  287. tcpCount += v.NowConn
  288. }
  289. data["tcpCount"] = tcpCount
  290. return data
  291. }
  292. func flowSession(m time.Duration) {
  293. ticker := time.NewTicker(m)
  294. for {
  295. select {
  296. case <-ticker.C:
  297. file.GetCsvDb().StoreHostToCsv()
  298. file.GetCsvDb().StoreTasksToCsv()
  299. }
  300. }
  301. }