client.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. lg.Println("send ok", link.Id)
  117. }
  118. }
  119. pool.PutBufPoolCopy(buf)
  120. s.Lock()
  121. delete(s.linkMap, link.Id)
  122. s.Unlock()
  123. }
  124. //隧道模式处理
  125. func (s *TRPClient) dealChan() {
  126. var err error
  127. s.tunnel, err = NewConn(s.bridgeConnType, s.vKey, s.svrAddr, common.WORK_CHAN, s.proxyUrl)
  128. if err != nil {
  129. lg.Println("connect to ", s.svrAddr, "error:", err)
  130. return
  131. }
  132. go func() {
  133. for {
  134. if id, err := s.tunnel.GetLen(); err != nil {
  135. break
  136. } else {
  137. s.Lock()
  138. if v, ok := s.linkMap[id]; ok {
  139. s.Unlock()
  140. if content, err := s.tunnel.GetMsgContent(v); err != nil {
  141. lg.Println("get msg content error:", err, id)
  142. pool.PutBufPoolCopy(content)
  143. break
  144. } else {
  145. if len(content) == len(common.IO_EOF) && string(content) == common.IO_EOF {
  146. v.Conn.Close()
  147. } else if v.Conn != nil {
  148. v.Conn.Write(content)
  149. }
  150. pool.PutBufPoolCopy(content)
  151. }
  152. } else {
  153. s.Unlock()
  154. }
  155. }
  156. }
  157. }()
  158. <-s.stop
  159. }
  160. var errAdd = errors.New("The server returned an error, which port or host may have been occupied or not allowed to open.")
  161. func StartFromFile(path string) {
  162. first := true
  163. cnf, err := config.NewConfig(path)
  164. if err != nil {
  165. lg.Fatalln(err)
  166. }
  167. lg.Printf("Loading configuration file %s successfully", path)
  168. re:
  169. if first || cnf.CommonConfig.AutoReconnection {
  170. if !first {
  171. lg.Println("Reconnecting...")
  172. time.Sleep(time.Second * 5)
  173. }
  174. } else {
  175. return
  176. }
  177. first = false
  178. c, err := NewConn(cnf.CommonConfig.Tp, cnf.CommonConfig.VKey, cnf.CommonConfig.Server, common.WORK_CONFIG, cnf.CommonConfig.ProxyUrl)
  179. if err != nil {
  180. lg.Println(err)
  181. goto re
  182. }
  183. if _, err := c.SendConfigInfo(cnf.CommonConfig.Cnf); err != nil {
  184. lg.Println(err)
  185. goto re
  186. }
  187. var b []byte
  188. if b, err = c.ReadLen(16); err != nil {
  189. lg.Println(err)
  190. goto re
  191. } else {
  192. ioutil.WriteFile(filepath.Join(common.GetTmpPath(), "npc_vkey.txt"), []byte(string(b)), 0600)
  193. }
  194. if !c.GetAddStatus() {
  195. lg.Println(errAdd)
  196. goto re
  197. }
  198. for _, v := range cnf.Hosts {
  199. if _, err := c.SendHostInfo(v); err != nil {
  200. lg.Println(err)
  201. goto re
  202. }
  203. if !c.GetAddStatus() {
  204. lg.Println(errAdd, v.Host)
  205. goto re
  206. }
  207. }
  208. for _, v := range cnf.Tasks {
  209. if _, err := c.SendTaskInfo(v); err != nil {
  210. lg.Println(err)
  211. goto re
  212. }
  213. if !c.GetAddStatus() {
  214. lg.Println(errAdd, v.Ports)
  215. goto re
  216. }
  217. }
  218. c.Close()
  219. NewRPClient(cnf.CommonConfig.Server, string(b), cnf.CommonConfig.Tp, cnf.CommonConfig.ProxyUrl).Start()
  220. goto re
  221. }
  222. //Create a new connection with the server and verify it
  223. func NewConn(tp string, vkey string, server string, connType string, proxyUrl string) (*conn.Conn, error) {
  224. var err error
  225. var connection net.Conn
  226. var sess *kcp.UDPSession
  227. if tp == "tcp" {
  228. if proxyUrl != "" {
  229. u, er := url.Parse(proxyUrl)
  230. if er != nil {
  231. return nil, er
  232. }
  233. n, er := proxy.FromURL(u, nil)
  234. if er != nil {
  235. return nil, er
  236. }
  237. connection, err = n.Dial("tcp", server)
  238. } else {
  239. connection, err = net.Dial("tcp", server)
  240. }
  241. } else {
  242. sess, err = kcp.DialWithOptions(server, nil, 10, 3)
  243. conn.SetUdpSession(sess)
  244. connection = sess
  245. }
  246. if err != nil {
  247. return nil, err
  248. }
  249. c := conn.NewConn(connection)
  250. if _, err := c.Write([]byte(common.Getverifyval(vkey))); err != nil {
  251. lg.Println(err)
  252. }
  253. if s, err := c.ReadFlag(); err != nil {
  254. lg.Println(err)
  255. } else if s == common.VERIFY_EER {
  256. lg.Fatalf("Validation key %s incorrect", vkey)
  257. }
  258. if _, err := c.Write([]byte(connType)); err != nil {
  259. lg.Println(err)
  260. }
  261. c.SetAlive(tp)
  262. return c, nil
  263. }