p2p.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package proxy
  2. import (
  3. "encoding/binary"
  4. "github.com/cnlh/nps/lib/common"
  5. "github.com/cnlh/nps/lib/conn"
  6. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  7. "net"
  8. "strconv"
  9. "time"
  10. )
  11. type P2PServer struct {
  12. BaseServer
  13. p2pPort int
  14. p2p map[string]*p2p
  15. }
  16. type p2p struct {
  17. provider *conn.Conn
  18. visitor *conn.Conn
  19. visitorAddr string
  20. providerAddr string
  21. providerNatType int32
  22. visitorNatType int32
  23. }
  24. func NewP2PServer(p2pPort int) *P2PServer {
  25. return &P2PServer{
  26. p2pPort: p2pPort,
  27. p2p: make(map[string]*p2p),
  28. }
  29. }
  30. func (s *P2PServer) Start() error {
  31. return conn.NewKcpListenerAndProcess(":"+strconv.Itoa(s.p2pPort), func(c net.Conn) {
  32. s.p2pProcess(conn.NewConn(c))
  33. })
  34. }
  35. func (s *P2PServer) p2pProcess(c *conn.Conn) {
  36. var (
  37. f string
  38. b []byte
  39. err error
  40. v *p2p
  41. ok bool
  42. natType int32
  43. )
  44. if b, err = c.GetShortContent(32); err != nil {
  45. return
  46. }
  47. //get role
  48. if f, err = c.ReadFlag(); err != nil {
  49. return
  50. }
  51. //get nat type
  52. if err := binary.Read(c, binary.LittleEndian, &natType); err != nil {
  53. return
  54. }
  55. if v, ok = s.p2p[string(b)]; !ok {
  56. v = new(p2p)
  57. s.p2p[string(b)] = v
  58. }
  59. logs.Trace("new p2p connection ,role %s , password %s, nat type %s ,local address %s", f, string(b), strconv.Itoa(int(natType)), c.RemoteAddr().String())
  60. //存储
  61. if f == common.WORK_P2P_VISITOR {
  62. logs.Warn("try visitor")
  63. v.visitorAddr = c.Conn.RemoteAddr().String()
  64. v.visitorNatType = natType
  65. v.visitor = c
  66. for i := 20; i > 0; i-- {
  67. if v.provider != nil {
  68. v.provider.WriteLenContent([]byte(v.visitorAddr))
  69. binary.Write(v.provider, binary.LittleEndian, v.visitorNatType)
  70. break
  71. }
  72. time.Sleep(time.Second)
  73. }
  74. v.provider = nil
  75. } else {
  76. v.providerAddr = c.Conn.RemoteAddr().String()
  77. v.providerNatType = natType
  78. v.provider = c
  79. for i := 20; i > 0; i-- {
  80. if v.visitor != nil {
  81. v.visitor.WriteLenContent([]byte(v.providerAddr))
  82. binary.Write(v.visitor, binary.LittleEndian, v.providerNatType)
  83. break
  84. }
  85. time.Sleep(time.Second)
  86. }
  87. v.visitor = nil
  88. }
  89. }