client.go 6.3 KB

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