p2p.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package proxy
  2. import (
  3. "net"
  4. "strings"
  5. "time"
  6. "github.com/astaxie/beego/logs"
  7. "github.com/cnlh/nps/lib/common"
  8. "github.com/cnlh/nps/lib/pool"
  9. )
  10. type P2PServer struct {
  11. BaseServer
  12. p2pPort int
  13. p2p map[string]*p2p
  14. listener *net.UDPConn
  15. }
  16. type p2p struct {
  17. visitorAddr *net.UDPAddr
  18. providerAddr *net.UDPAddr
  19. }
  20. func NewP2PServer(p2pPort int) *P2PServer {
  21. return &P2PServer{
  22. p2pPort: p2pPort,
  23. p2p: make(map[string]*p2p),
  24. }
  25. }
  26. func (s *P2PServer) Start() error {
  27. logs.Info("start p2p server port", s.p2pPort)
  28. var err error
  29. s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.p2pPort, ""})
  30. if err != nil {
  31. return err
  32. }
  33. for {
  34. buf := pool.BufPoolUdp.Get().([]byte)
  35. n, addr, err := s.listener.ReadFromUDP(buf)
  36. if err != nil {
  37. if strings.Contains(err.Error(), "use of closed network connection") {
  38. break
  39. }
  40. continue
  41. }
  42. go s.handleP2P(addr, string(buf[:n]))
  43. }
  44. return nil
  45. }
  46. func (s *P2PServer) handleP2P(addr *net.UDPAddr, str string) {
  47. var (
  48. v *p2p
  49. ok bool
  50. )
  51. arr := strings.Split(str, common.CONN_DATA_SEQ)
  52. if len(arr) < 2 {
  53. return
  54. }
  55. if v, ok = s.p2p[arr[0]]; !ok {
  56. v = new(p2p)
  57. s.p2p[arr[0]] = v
  58. }
  59. logs.Trace("new p2p connection ,role %s , password %s ,local address %s", arr[1], arr[0], addr.String())
  60. if arr[1] == common.WORK_P2P_VISITOR {
  61. v.visitorAddr = addr
  62. for i := 20; i > 0; i-- {
  63. if v.providerAddr != nil {
  64. s.listener.WriteTo([]byte(v.providerAddr.String()), v.visitorAddr)
  65. s.listener.WriteTo([]byte(v.visitorAddr.String()), v.providerAddr)
  66. break
  67. }
  68. time.Sleep(time.Second)
  69. }
  70. delete(s.p2p, arr[0])
  71. } else {
  72. v.providerAddr = addr
  73. }
  74. }