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