p2p.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. v.visitorAddr = c.Conn.RemoteAddr().String()
  63. v.visitorNatType = natType
  64. v.visitor = c
  65. for i := 20; i > 0; i-- {
  66. if v.provider != nil {
  67. v.provider.WriteLenContent([]byte(v.visitorAddr))
  68. binary.Write(v.provider, binary.LittleEndian, v.visitorNatType)
  69. break
  70. }
  71. time.Sleep(time.Second)
  72. }
  73. v.provider = nil
  74. } else {
  75. v.providerAddr = c.Conn.RemoteAddr().String()
  76. v.providerNatType = natType
  77. v.provider = c
  78. for i := 20; i > 0; i-- {
  79. if v.visitor != nil {
  80. v.visitor.WriteLenContent([]byte(v.providerAddr))
  81. binary.Write(v.visitor, binary.LittleEndian, v.providerNatType)
  82. break
  83. }
  84. time.Sleep(time.Second)
  85. }
  86. v.visitor = nil
  87. }
  88. }