client.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package client
  2. import (
  3. "errors"
  4. "github.com/cnlh/nps/lib/common"
  5. "github.com/cnlh/nps/lib/config"
  6. "github.com/cnlh/nps/lib/conn"
  7. "github.com/cnlh/nps/lib/kcp"
  8. "github.com/cnlh/nps/lib/lg"
  9. "github.com/cnlh/nps/lib/pool"
  10. "io/ioutil"
  11. "net"
  12. "path/filepath"
  13. "sync"
  14. "time"
  15. )
  16. type TRPClient struct {
  17. svrAddr string
  18. linkMap map[int]*conn.Link
  19. tunnel *conn.Conn
  20. bridgeConnType string
  21. stop chan bool
  22. sync.Mutex
  23. vKey string
  24. }
  25. //new client
  26. func NewRPClient(svraddr string, vKey string, bridgeConnType string) *TRPClient {
  27. return &TRPClient{
  28. svrAddr: svraddr,
  29. linkMap: make(map[int]*conn.Link),
  30. Mutex: sync.Mutex{},
  31. vKey: vKey,
  32. bridgeConnType: bridgeConnType,
  33. stop: make(chan bool),
  34. }
  35. }
  36. //start
  37. func (s *TRPClient) Start() {
  38. retry:
  39. c, err := NewConn(s.bridgeConnType, s.vKey, s.svrAddr, common.WORK_MAIN)
  40. if err != nil {
  41. lg.Println("The connection server failed and will be reconnected in five seconds")
  42. time.Sleep(time.Second * 5)
  43. goto retry
  44. }
  45. lg.Printf("Successful connection with server %s", s.svrAddr)
  46. s.processor(c)
  47. }
  48. func (s *TRPClient) Close() {
  49. s.tunnel.Close()
  50. s.stop <- true
  51. for _, v := range s.linkMap {
  52. if v.Conn != nil {
  53. v.Conn.Close()
  54. }
  55. }
  56. }
  57. //处理
  58. func (s *TRPClient) processor(c *conn.Conn) {
  59. go s.dealChan()
  60. for {
  61. flags, err := c.ReadFlag()
  62. if err != nil {
  63. lg.Printf("Accept server data error %s, end this service", err.Error())
  64. break
  65. }
  66. switch flags {
  67. case common.VERIFY_EER:
  68. lg.Fatalf("VKey:%s is incorrect, the server refuses to connect, please check", s.vKey)
  69. case common.NEW_CONN:
  70. if link, err := c.GetLinkInfo(); err != nil {
  71. break
  72. } else {
  73. s.Lock()
  74. s.linkMap[link.Id] = link
  75. s.Unlock()
  76. go s.linkProcess(link, c)
  77. }
  78. case common.RES_CLOSE:
  79. lg.Fatalln("The authentication key is connected by another client or the server closes the client.")
  80. case common.RES_MSG:
  81. lg.Println("Server-side return error")
  82. break
  83. default:
  84. lg.Println("The error could not be resolved")
  85. break
  86. }
  87. }
  88. c.Close()
  89. s.Close()
  90. }
  91. func (s *TRPClient) linkProcess(link *conn.Link, c *conn.Conn) {
  92. link.Host = common.FormatAddress(link.Host)
  93. //与目标建立连接
  94. server, err := net.DialTimeout(link.ConnType, link.Host, time.Second*3)
  95. if err != nil {
  96. c.WriteFail(link.Id)
  97. lg.Println("connect to ", link.Host, "error:", err)
  98. return
  99. }
  100. c.WriteSuccess(link.Id)
  101. link.Conn = conn.NewConn(server)
  102. buf := pool.BufPoolCopy.Get().([]byte)
  103. for {
  104. if n, err := server.Read(buf); err != nil {
  105. s.tunnel.SendMsg([]byte(common.IO_EOF), link)
  106. break
  107. } else {
  108. if _, err := s.tunnel.SendMsg(buf[:n], link); err != nil {
  109. c.Close()
  110. break
  111. }
  112. }
  113. }
  114. pool.PutBufPoolCopy(buf)
  115. s.Lock()
  116. delete(s.linkMap, link.Id)
  117. s.Unlock()
  118. }
  119. //隧道模式处理
  120. func (s *TRPClient) dealChan() {
  121. var err error
  122. s.tunnel, err = NewConn(s.bridgeConnType, s.vKey, s.svrAddr, common.WORK_CHAN)
  123. if err != nil {
  124. lg.Println("connect to ", s.svrAddr, "error:", err)
  125. return
  126. }
  127. go func() {
  128. for {
  129. if id, err := s.tunnel.GetLen(); err != nil {
  130. break
  131. } else {
  132. s.Lock()
  133. if v, ok := s.linkMap[id]; ok {
  134. s.Unlock()
  135. if content, err := s.tunnel.GetMsgContent(v); err != nil {
  136. lg.Println("get msg content error:", err, id)
  137. pool.PutBufPoolCopy(content)
  138. break
  139. } else {
  140. if len(content) == len(common.IO_EOF) && string(content) == common.IO_EOF {
  141. v.Conn.Close()
  142. } else if v.Conn != nil {
  143. v.Conn.Write(content)
  144. }
  145. pool.PutBufPoolCopy(content)
  146. }
  147. } else {
  148. s.Unlock()
  149. }
  150. }
  151. }
  152. }()
  153. <-s.stop
  154. }
  155. var errAdd = errors.New("The server returned an error, which port or host may have been occupied or not allowed to open.")
  156. func StartFromFile(path string) {
  157. first := true
  158. cnf, err := config.NewConfig(path)
  159. if err != nil {
  160. lg.Fatalln(err)
  161. }
  162. lg.Printf("Loading configuration file %s successfully", path)
  163. re:
  164. if first || cnf.CommonConfig.AutoReconnection {
  165. if !first {
  166. lg.Println("Reconnecting...")
  167. time.Sleep(time.Second * 5)
  168. }
  169. } else {
  170. return
  171. }
  172. first = false
  173. c, err := NewConn(cnf.CommonConfig.Tp, cnf.CommonConfig.VKey, cnf.CommonConfig.Server, common.WORK_CONFIG)
  174. if err != nil {
  175. lg.Println(err)
  176. goto re
  177. }
  178. if _, err := c.SendConfigInfo(cnf.CommonConfig.Cnf); err != nil {
  179. lg.Println(err)
  180. goto re
  181. }
  182. var b []byte
  183. if b, err = c.ReadLen(16); err != nil {
  184. lg.Println(err)
  185. goto re
  186. } else {
  187. ioutil.WriteFile(filepath.Join(common.GetTmpPath(), "npc_vkey.txt"), []byte(string(b)), 0600)
  188. }
  189. if !c.GetAddStatus() {
  190. lg.Println(errAdd)
  191. goto re
  192. }
  193. for _, v := range cnf.Hosts {
  194. if _, err := c.SendHostInfo(v); err != nil {
  195. lg.Println(err)
  196. goto re
  197. }
  198. if !c.GetAddStatus() {
  199. lg.Println(errAdd, v.Host)
  200. goto re
  201. }
  202. }
  203. for _, v := range cnf.Tasks {
  204. if _, err := c.SendTaskInfo(v); err != nil {
  205. lg.Println(err)
  206. goto re
  207. }
  208. if !c.GetAddStatus() {
  209. lg.Println(errAdd, v.Port)
  210. goto re
  211. }
  212. }
  213. c.Close()
  214. NewRPClient(cnf.CommonConfig.Server, string(b), cnf.CommonConfig.Tp).Start()
  215. goto re
  216. }
  217. //Create a new connection with the server and verify it
  218. func NewConn(tp string, vkey string, server string, connType string) (*conn.Conn, error) {
  219. var err error
  220. var connection net.Conn
  221. var sess *kcp.UDPSession
  222. if tp == "tcp" {
  223. connection, err = net.Dial("tcp", server)
  224. } else {
  225. sess, err = kcp.DialWithOptions(server, nil, 10, 3)
  226. conn.SetUdpSession(sess)
  227. connection = sess
  228. }
  229. if err != nil {
  230. return nil, err
  231. }
  232. c := conn.NewConn(connection)
  233. if _, err := c.Write([]byte(common.Getverifyval(vkey))); err != nil {
  234. lg.Println(err)
  235. }
  236. if s, err := c.ReadFlag(); err != nil {
  237. lg.Println(err)
  238. } else if s == common.VERIFY_EER {
  239. lg.Fatalf("Validation key %s incorrect", vkey)
  240. }
  241. if _, err := c.Write([]byte(connType)); err != nil {
  242. lg.Println(err)
  243. }
  244. c.SetAlive(tp)
  245. return c, nil
  246. }