bridge.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package bridge
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "github.com/cnlh/nps/lib/common"
  7. "github.com/cnlh/nps/lib/conn"
  8. "github.com/cnlh/nps/lib/crypt"
  9. "github.com/cnlh/nps/lib/file"
  10. "github.com/cnlh/nps/lib/mux"
  11. "github.com/cnlh/nps/lib/version"
  12. "github.com/cnlh/nps/server/tool"
  13. "github.com/cnlh/nps/vender/github.com/astaxie/beego"
  14. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  15. "github.com/cnlh/nps/vender/github.com/xtaci/kcp"
  16. "net"
  17. "strconv"
  18. "sync"
  19. "time"
  20. )
  21. type Client struct {
  22. tunnel *mux.Mux
  23. signal *conn.Conn
  24. sync.RWMutex
  25. }
  26. func NewClient(t *mux.Mux, s *conn.Conn) *Client {
  27. return &Client{
  28. signal: s,
  29. tunnel: t,
  30. }
  31. }
  32. type Bridge struct {
  33. TunnelPort int //通信隧道端口
  34. tcpListener *net.TCPListener //server端监听
  35. kcpListener *kcp.Listener //server端监听
  36. Client map[int]*Client
  37. tunnelType string //bridge type kcp or tcp
  38. OpenTask chan *file.Tunnel
  39. CloseClient chan int
  40. SecretChan chan *conn.Secret
  41. clientLock sync.RWMutex
  42. Register map[string]time.Time
  43. registerLock sync.RWMutex
  44. ipVerify bool
  45. runList map[int]interface{}
  46. }
  47. func NewTunnel(tunnelPort int, tunnelType string, ipVerify bool, runList map[int]interface{}) *Bridge {
  48. t := new(Bridge)
  49. t.TunnelPort = tunnelPort
  50. t.Client = make(map[int]*Client)
  51. t.tunnelType = tunnelType
  52. t.OpenTask = make(chan *file.Tunnel)
  53. t.CloseClient = make(chan int)
  54. t.Register = make(map[string]time.Time)
  55. t.ipVerify = ipVerify
  56. t.runList = runList
  57. t.SecretChan = make(chan *conn.Secret)
  58. return t
  59. }
  60. func (s *Bridge) StartTunnel() error {
  61. var err error
  62. if s.tunnelType == "kcp" {
  63. s.kcpListener, err = kcp.ListenWithOptions(":"+strconv.Itoa(s.TunnelPort), nil, 150, 3)
  64. if err != nil {
  65. return err
  66. }
  67. go func() {
  68. for {
  69. c, err := s.kcpListener.AcceptKCP()
  70. conn.SetUdpSession(c)
  71. if err != nil {
  72. logs.Warn(err)
  73. continue
  74. }
  75. go s.cliProcess(conn.NewConn(c))
  76. }
  77. }()
  78. } else {
  79. s.tcpListener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.TunnelPort, ""})
  80. if err != nil {
  81. return err
  82. }
  83. go func() {
  84. for {
  85. c, err := s.tcpListener.Accept()
  86. if err != nil {
  87. logs.Warn(err)
  88. continue
  89. }
  90. go s.cliProcess(conn.NewConn(c))
  91. }
  92. }()
  93. }
  94. return nil
  95. }
  96. //验证失败,返回错误验证flag,并且关闭连接
  97. func (s *Bridge) verifyError(c *conn.Conn) {
  98. c.Write([]byte(common.VERIFY_EER))
  99. c.Conn.Close()
  100. }
  101. func (s *Bridge) verifySuccess(c *conn.Conn) {
  102. c.Write([]byte(common.VERIFY_SUCCESS))
  103. }
  104. func (s *Bridge) cliProcess(c *conn.Conn) {
  105. //version check
  106. if b, err := c.GetShortContent(32); err != nil || string(b) != crypt.Md5(version.GetVersion()) {
  107. logs.Info("The client %s version does not match", c.Conn.RemoteAddr())
  108. c.Close()
  109. return
  110. }
  111. c.Write([]byte(crypt.Md5(version.GetVersion())))
  112. c.SetReadDeadline(5, s.tunnelType)
  113. var buf []byte
  114. var err error
  115. if buf, err = c.GetShortContent(32); err != nil {
  116. c.Close()
  117. return
  118. }
  119. //验证
  120. id, err := file.GetCsvDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
  121. if err != nil {
  122. logs.Info("Current client connection validation error, close this client:", c.Conn.RemoteAddr())
  123. s.verifyError(c)
  124. return
  125. } else {
  126. s.verifySuccess(c)
  127. }
  128. //做一个判断 添加到对应的channel里面以供使用
  129. if flag, err := c.ReadFlag(); err == nil {
  130. s.typeDeal(flag, c, id)
  131. } else {
  132. logs.Warn(err, flag)
  133. }
  134. return
  135. }
  136. func (s *Bridge) DelClient(id int, isOther bool) {
  137. s.clientLock.Lock()
  138. defer s.clientLock.Unlock()
  139. if v, ok := s.Client[id]; ok {
  140. if c, err := file.GetCsvDb().GetClient(id); err == nil && c.NoStore {
  141. s.CloseClient <- c.Id
  142. }
  143. v.signal.Close()
  144. delete(s.Client, id)
  145. }
  146. }
  147. //use different
  148. func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
  149. switch typeVal {
  150. case common.WORK_MAIN:
  151. //the vKey connect by another ,close the client of before
  152. s.clientLock.Lock()
  153. if v, ok := s.Client[id]; ok {
  154. s.clientLock.Unlock()
  155. if v.signal != nil {
  156. v.signal.WriteClose()
  157. }
  158. v.Lock()
  159. v.signal = c
  160. v.Unlock()
  161. } else {
  162. s.Client[id] = NewClient(nil, c)
  163. s.clientLock.Unlock()
  164. }
  165. go func(id int) {
  166. binary.Read(c, binary.LittleEndian, true)
  167. s.DelClient(id, false)
  168. }(id)
  169. logs.Info("clientId %d connection succeeded, address:%s ", id, c.Conn.RemoteAddr())
  170. case common.WORK_CHAN:
  171. s.clientLock.Lock()
  172. if v, ok := s.Client[id]; ok {
  173. s.clientLock.Unlock()
  174. v.Lock()
  175. v.tunnel = mux.NewMux(c.Conn)
  176. v.Unlock()
  177. } else {
  178. s.Client[id] = NewClient(mux.NewMux(c.Conn), nil)
  179. s.clientLock.Unlock()
  180. }
  181. case common.WORK_CONFIG:
  182. go s.getConfig(c)
  183. case common.WORK_REGISTER:
  184. go s.register(c)
  185. case common.WORK_SECRET:
  186. if b, err := c.GetShortContent(32); err == nil {
  187. s.SecretChan <- conn.NewSecret(string(b), c)
  188. }
  189. case common.WORK_P2P:
  190. //read md5 secret
  191. if b, err := c.GetShortContent(32); err != nil {
  192. return
  193. } else if t := file.GetCsvDb().GetTaskByMd5Password(string(b)); t == nil {
  194. return
  195. } else {
  196. s.clientLock.Lock()
  197. if v, ok := s.Client[t.Client.Id]; !ok {
  198. s.clientLock.Unlock()
  199. return
  200. } else {
  201. s.clientLock.Unlock()
  202. //向密钥对应的客户端发送与服务端udp建立连接信息,地址,密钥
  203. v.signal.Write([]byte(common.NEW_UDP_CONN))
  204. svrAddr := beego.AppConfig.String("serverIp") + ":" + beego.AppConfig.String("p2pPort")
  205. if err != nil {
  206. logs.Warn("get local udp addr error")
  207. return
  208. }
  209. v.signal.WriteLenContent([]byte(svrAddr))
  210. v.signal.WriteLenContent(b)
  211. //向该请求者发送建立连接请求,服务器地址
  212. c.WriteLenContent([]byte(svrAddr))
  213. }
  214. }
  215. }
  216. c.SetAlive(s.tunnelType)
  217. return
  218. }
  219. //register ip
  220. func (s *Bridge) register(c *conn.Conn) {
  221. var hour int32
  222. if err := binary.Read(c, binary.LittleEndian, &hour); err == nil {
  223. s.registerLock.Lock()
  224. s.Register[common.GetIpByAddr(c.Conn.RemoteAddr().String())] = time.Now().Add(time.Hour * time.Duration(hour))
  225. s.registerLock.Unlock()
  226. }
  227. }
  228. func (s *Bridge) SendLinkInfo(clientId int, link *conn.Link, linkAddr string) (target net.Conn, err error) {
  229. s.clientLock.Lock()
  230. if v, ok := s.Client[clientId]; ok {
  231. s.clientLock.Unlock()
  232. if s.ipVerify {
  233. s.registerLock.Lock()
  234. ip := common.GetIpByAddr(linkAddr)
  235. if v, ok := s.Register[ip]; !ok {
  236. s.registerLock.Unlock()
  237. return nil, errors.New(fmt.Sprintf("The ip %s is not in the validation list", ip))
  238. } else {
  239. if !v.After(time.Now()) {
  240. return nil, errors.New(fmt.Sprintf("The validity of the ip %s has expired", ip))
  241. }
  242. }
  243. s.registerLock.Unlock()
  244. }
  245. if v.tunnel == nil {
  246. err = errors.New("the client connect error")
  247. return
  248. }
  249. if target, err = v.tunnel.NewConn(); err != nil {
  250. return
  251. }
  252. if _, err = conn.NewConn(target).SendLinkInfo(link); err != nil {
  253. logs.Warn("new connect error ,the target %s refuse to connect", link.Host)
  254. return
  255. }
  256. } else {
  257. s.clientLock.Unlock()
  258. err = errors.New(fmt.Sprintf("the client %d is not connect", clientId))
  259. }
  260. return
  261. }
  262. //get config and add task from client config
  263. func (s *Bridge) getConfig(c *conn.Conn) {
  264. var client *file.Client
  265. var fail bool
  266. for {
  267. flag, err := c.ReadFlag()
  268. if err != nil {
  269. break
  270. }
  271. switch flag {
  272. case common.WORK_STATUS:
  273. if b, err := c.GetShortContent(32); err != nil {
  274. break
  275. } else {
  276. logs.Warn(string(b))
  277. var str string
  278. id, err := file.GetCsvDb().GetClientIdByVkey(string(b))
  279. if err != nil {
  280. break
  281. }
  282. for _, v := range file.GetCsvDb().Hosts {
  283. if v.Client.Id == id {
  284. str += v.Remark + common.CONN_DATA_SEQ
  285. }
  286. }
  287. for _, v := range file.GetCsvDb().Tasks {
  288. if _, ok := s.runList[v.Id]; ok && v.Client.Id == id {
  289. str += v.Remark + common.CONN_DATA_SEQ
  290. }
  291. }
  292. binary.Write(c, binary.LittleEndian, int32(len([]byte(str))))
  293. binary.Write(c, binary.LittleEndian, []byte(str))
  294. }
  295. case common.NEW_CONF:
  296. var err error
  297. if client, err = c.GetConfigInfo(); err != nil {
  298. fail = true
  299. c.WriteAddFail()
  300. break
  301. } else {
  302. if err = file.GetCsvDb().NewClient(client); err != nil {
  303. fail = true
  304. c.WriteAddFail()
  305. break
  306. }
  307. c.WriteAddOk()
  308. c.Write([]byte(client.VerifyKey))
  309. }
  310. case common.NEW_HOST:
  311. if h, err := c.GetHostInfo(); err != nil {
  312. fail = true
  313. c.WriteAddFail()
  314. break
  315. } else if file.GetCsvDb().IsHostExist(h) {
  316. fail = true
  317. c.WriteAddFail()
  318. break
  319. } else {
  320. h.Client = client
  321. file.GetCsvDb().NewHost(h)
  322. c.WriteAddOk()
  323. }
  324. case common.NEW_TASK:
  325. if t, err := c.GetTaskInfo(); err != nil {
  326. fail = true
  327. c.WriteAddFail()
  328. break
  329. } else {
  330. ports := common.GetPorts(t.Ports)
  331. targets := common.GetPorts(t.Target)
  332. if len(ports) > 1 && (t.Mode == "tcp" || t.Mode == "udp") && (len(ports) != len(targets)) {
  333. fail = true
  334. c.WriteAddFail()
  335. break
  336. } else if t.Mode == "secret" {
  337. ports = append(ports, 0)
  338. }
  339. if len(ports) == 0 {
  340. fail = true
  341. c.WriteAddFail()
  342. break
  343. }
  344. for i := 0; i < len(ports); i++ {
  345. tl := new(file.Tunnel)
  346. tl.Mode = t.Mode
  347. tl.Port = ports[i]
  348. if len(ports) == 1 {
  349. tl.Target = t.Target
  350. tl.Remark = t.Remark
  351. } else {
  352. tl.Remark = t.Remark + "_" + strconv.Itoa(tl.Port)
  353. if t.TargetAddr != "" {
  354. tl.Target = t.TargetAddr + ":" + strconv.Itoa(targets[i])
  355. } else {
  356. tl.Target = strconv.Itoa(targets[i])
  357. }
  358. }
  359. tl.Id = file.GetCsvDb().GetTaskId()
  360. tl.Status = true
  361. tl.Flow = new(file.Flow)
  362. tl.NoStore = true
  363. tl.Client = client
  364. tl.Password = t.Password
  365. if err := file.GetCsvDb().NewTask(tl); err != nil {
  366. logs.Notice("Add task error ", err.Error())
  367. fail = true
  368. c.WriteAddFail()
  369. break
  370. }
  371. if b := tool.TestServerPort(tl.Port, tl.Mode); !b && t.Mode != "secret" {
  372. fail = true
  373. c.WriteAddFail()
  374. break
  375. } else {
  376. s.OpenTask <- tl
  377. }
  378. c.WriteAddOk()
  379. }
  380. }
  381. }
  382. }
  383. if fail && client != nil {
  384. s.CloseClient <- client.Id
  385. }
  386. c.Close()
  387. }