server.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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().GetTaskByMd5Password(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. if p, err := beego.AppConfig.Int("p2pPort"); err == nil {
  73. go proxy.NewP2PServer(p).Start()
  74. }
  75. go DealBridgeTask()
  76. if svr := NewMode(Bridge, cnf); svr != nil {
  77. if err := svr.Start(); err != nil {
  78. logs.Error(err)
  79. }
  80. RunList[cnf.Id] = svr
  81. } else {
  82. logs.Error("Incorrect startup mode %s", cnf.Mode)
  83. }
  84. }
  85. //new a server by mode name
  86. func NewMode(Bridge *bridge.Bridge, c *file.Tunnel) proxy.Service {
  87. var service proxy.Service
  88. switch c.Mode {
  89. case "tcpServer":
  90. service = proxy.NewTunnelModeServer(proxy.ProcessTunnel, Bridge, c)
  91. case "socks5Server":
  92. service = proxy.NewSock5ModeServer(Bridge, c)
  93. case "httpProxyServer":
  94. service = proxy.NewTunnelModeServer(proxy.ProcessHttp, Bridge, c)
  95. case "udpServer":
  96. service = proxy.NewUdpModeServer(Bridge, c)
  97. case "webServer":
  98. InitFromCsv()
  99. t := &file.Tunnel{
  100. Port: 0,
  101. Mode: "httpHostServer",
  102. Target: "",
  103. Status: true,
  104. }
  105. AddTask(t)
  106. service = proxy.NewWebServer(Bridge)
  107. case "httpHostServer":
  108. service = proxy.NewHttp(Bridge, c)
  109. }
  110. return service
  111. }
  112. //stop server
  113. func StopServer(id int) error {
  114. if v, ok := RunList[id]; ok {
  115. if svr, ok := v.(proxy.Service); ok {
  116. if err := svr.Close(); err != nil {
  117. return err
  118. }
  119. }
  120. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  121. return err
  122. } else {
  123. t.Status = false
  124. file.GetCsvDb().UpdateTask(t)
  125. }
  126. delete(RunList, id)
  127. return nil
  128. }
  129. return errors.New("未在运行中")
  130. }
  131. //add task
  132. func AddTask(t *file.Tunnel) error {
  133. if t.Mode == "secretServer" {
  134. logs.Info("secret task %s start ", t.Remark)
  135. RunList[t.Id] = nil
  136. return nil
  137. }
  138. if b := tool.TestServerPort(t.Port, t.Mode); !b && t.Mode != "httpHostServer" {
  139. logs.Error("taskId %d start error port %d open failed", t.Id, t.Port)
  140. return errors.New("the port open error")
  141. }
  142. if minute, err := beego.AppConfig.Int("flowStoreInterval"); err == nil && minute > 0 {
  143. go flowSession(time.Minute * time.Duration(minute))
  144. }
  145. if svr := NewMode(Bridge, t); svr != nil {
  146. logs.Info("tunnel task %s start mode:%s port %d", t.Remark, t.Mode, t.Port)
  147. RunList[t.Id] = svr
  148. go func() {
  149. if err := svr.Start(); err != nil {
  150. logs.Error("clientId %d taskId %d start error %s", t.Client.Id, t.Id, err)
  151. delete(RunList, t.Id)
  152. return
  153. }
  154. }()
  155. } else {
  156. return errors.New("the mode is not correct")
  157. }
  158. return nil
  159. }
  160. //start task
  161. func StartTask(id int) error {
  162. if t, err := file.GetCsvDb().GetTask(id); err != nil {
  163. return err
  164. } else {
  165. AddTask(t)
  166. t.Status = true
  167. file.GetCsvDb().UpdateTask(t)
  168. }
  169. return nil
  170. }
  171. //delete task
  172. func DelTask(id int) error {
  173. if _, ok := RunList[id]; ok {
  174. if err := StopServer(id); err != nil {
  175. return err
  176. }
  177. }
  178. return file.GetCsvDb().DelTask(id)
  179. }
  180. //get task list by page num
  181. func GetTunnel(start, length int, typeVal string, clientId int) ([]*file.Tunnel, int) {
  182. list := make([]*file.Tunnel, 0)
  183. var cnt int
  184. for _, v := range file.GetCsvDb().Tasks {
  185. if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
  186. continue
  187. }
  188. cnt++
  189. if _, ok := Bridge.Client[v.Client.Id]; ok {
  190. v.Client.IsConnect = true
  191. } else {
  192. v.Client.IsConnect = false
  193. }
  194. if start--; start < 0 {
  195. if length--; length > 0 {
  196. if _, ok := RunList[v.Id]; ok {
  197. v.RunStatus = true
  198. } else {
  199. v.RunStatus = false
  200. }
  201. list = append(list, v)
  202. }
  203. }
  204. }
  205. return list, cnt
  206. }
  207. //获取客户端列表
  208. func GetClientList(start, length int) (list []*file.Client, cnt int) {
  209. list, cnt = file.GetCsvDb().GetClientList(start, length)
  210. dealClientData(list)
  211. return
  212. }
  213. func dealClientData(list []*file.Client) {
  214. for _, v := range list {
  215. if _, ok := Bridge.Client[v.Id]; ok {
  216. v.IsConnect = true
  217. } else {
  218. v.IsConnect = false
  219. }
  220. v.Flow.InletFlow = 0
  221. v.Flow.ExportFlow = 0
  222. for _, h := range file.GetCsvDb().Hosts {
  223. if h.Client.Id == v.Id {
  224. v.Flow.InletFlow += h.Flow.InletFlow
  225. v.Flow.ExportFlow += h.Flow.ExportFlow
  226. }
  227. }
  228. for _, t := range file.GetCsvDb().Tasks {
  229. if t.Client.Id == v.Id {
  230. v.Flow.InletFlow += t.Flow.InletFlow
  231. v.Flow.ExportFlow += t.Flow.ExportFlow
  232. }
  233. }
  234. }
  235. return
  236. }
  237. //根据客户端id删除其所属的所有隧道和域名
  238. func DelTunnelAndHostByClientId(clientId int) {
  239. var ids []int
  240. for _, v := range file.GetCsvDb().Tasks {
  241. if v.Client.Id == clientId {
  242. ids = append(ids, v.Id)
  243. }
  244. }
  245. for _, id := range ids {
  246. DelTask(id)
  247. }
  248. for _, v := range file.GetCsvDb().Hosts {
  249. if v.Client.Id == clientId {
  250. file.GetCsvDb().DelHost(v.Id)
  251. }
  252. }
  253. }
  254. //关闭客户端连接
  255. func DelClientConnect(clientId int) {
  256. Bridge.DelClient(clientId)
  257. }
  258. func GetDashboardData() map[string]int {
  259. data := make(map[string]int)
  260. data["hostCount"] = len(file.GetCsvDb().Hosts)
  261. data["clientCount"] = len(file.GetCsvDb().Clients) - 1 //Remove the public key client
  262. list := file.GetCsvDb().Clients
  263. dealClientData(list)
  264. c := 0
  265. var in, out int64
  266. for _, v := range list {
  267. if v.IsConnect {
  268. c += 1
  269. }
  270. in += v.Flow.InletFlow
  271. out += v.Flow.ExportFlow
  272. }
  273. data["clientOnlineCount"] = c
  274. data["inletFlowCount"] = int(in)
  275. data["exportFlowCount"] = int(out)
  276. for _, v := range file.GetCsvDb().Tasks {
  277. switch v.Mode {
  278. case "tcpServer":
  279. data["tcpServerCount"] += 1
  280. case "socks5Server":
  281. data["socks5ServerCount"] += 1
  282. case "httpProxyServer":
  283. data["httpProxyServerCount"] += 1
  284. case "udpServer":
  285. data["udpServerCount"] += 1
  286. }
  287. }
  288. tcpCount := 0
  289. for _, v := range file.GetCsvDb().Clients {
  290. tcpCount += v.NowConn
  291. }
  292. data["tcpCount"] = tcpCount
  293. return data
  294. }
  295. func flowSession(m time.Duration) {
  296. ticker := time.NewTicker(m)
  297. for {
  298. select {
  299. case <-ticker.C:
  300. file.GetCsvDb().StoreHostToCsv()
  301. file.GetCsvDb().StoreTasksToCsv()
  302. }
  303. }
  304. }