github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/peer/peerinfo.go (about) 1 package peer 2 3 import ( 4 "context" 5 "fmt" 6 "strconv" 7 "strings" 8 "sync" 9 "sync/atomic" 10 "time" 11 12 "github.com/turingchain2020/turingchain/common/version" 13 "github.com/turingchain2020/turingchain/system/p2p/dht/protocol" 14 types2 "github.com/turingchain2020/turingchain/system/p2p/dht/types" 15 "github.com/turingchain2020/turingchain/types" 16 "github.com/libp2p/go-libp2p-core/network" 17 "github.com/libp2p/go-libp2p-core/peer" 18 "github.com/multiformats/go-multiaddr" 19 ) 20 21 const diffHeightValue = 512 22 23 func (p *Protocol) getLocalPeerInfo() *types.Peer { 24 msg := p.QueueClient.NewMessage(mempool, types.EventGetMempoolSize, nil) 25 err := p.QueueClient.Send(msg, true) 26 if err != nil { 27 return nil 28 } 29 resp, err := p.QueueClient.WaitTimeout(msg, time.Second*10) 30 if err != nil { 31 log.Error("getLocalPeerInfo", "mempool WaitTimeout", err) 32 return nil 33 } 34 var localPeer types.Peer 35 localPeer.MempoolSize = int32(resp.Data.(*types.MempoolSize).GetSize()) 36 37 msg = p.QueueClient.NewMessage(blockchain, types.EventGetLastHeader, nil) 38 err = p.QueueClient.Send(msg, true) 39 if err != nil { 40 return nil 41 } 42 resp, err = p.QueueClient.WaitTimeout(msg, time.Second*10) 43 if err != nil { 44 log.Error("getLocalPeerInfo", "blockchain WaitTimeout", err) 45 return nil 46 } 47 localPeer.Header = resp.Data.(*types.Header) 48 localPeer.Name = p.Host.ID().Pretty() 49 ip, port := parseIPAndPort(p.getExternalAddr()) 50 localPeer.Addr = ip 51 localPeer.Port = int32(port) 52 localPeer.Version = version.GetVersion() + "@" + version.GetAppVersion() 53 localPeer.StoreDBVersion = version.GetStoreDBVersion() 54 localPeer.LocalDBVersion = version.GetLocalDBVersion() 55 return &localPeer 56 } 57 58 func (p *Protocol) refreshPeerInfo() { 59 if !atomic.CompareAndSwapInt32(&p.refreshing, 0, 1) { 60 return 61 } 62 defer atomic.StoreInt32(&p.refreshing, 0) 63 var wg sync.WaitGroup 64 for _, remoteID := range p.ConnManager.FetchConnPeers() { 65 if p.checkDone() { 66 log.Warn("getPeerInfo", "process", "done+++++++") 67 return 68 } 69 if remoteID == p.Host.ID() { 70 continue 71 } 72 //修改为并发获取peerinfo信息 73 wg.Add(1) 74 go func(pid peer.ID) { 75 defer wg.Done() 76 pInfo, err := p.queryPeerInfoOld(pid) 77 if err != nil { 78 log.Error("refreshPeerInfo", "error", err, "pid", pid) 79 return 80 } 81 p.PeerInfoManager.Refresh(pInfo) 82 }(remoteID) 83 } 84 selfPeer := p.getLocalPeerInfo() 85 if selfPeer != nil { 86 selfPeer.Self = true 87 p.PeerInfoManager.Refresh(selfPeer) 88 p.checkOutBound(selfPeer.GetHeader().GetHeight()) 89 } 90 wg.Wait() 91 } 92 93 func (p *Protocol) checkOutBound(height int64) { 94 for _, pinfo := range p.PeerInfoManager.FetchAll() { 95 if pinfo.GetHeader().GetHeight()+diffHeightValue < height { 96 pid, err := peer.Decode(pinfo.GetName()) 97 if err != nil { 98 continue 99 } 100 // 断开向外的主动连接 101 for _, conn := range p.Host.Network().ConnsToPeer(pid) { 102 //判断是Inbound 还是Outbound 103 if conn.Stat().Direction == network.DirOutbound { 104 // 拉入连接黑名单 105 p.ConnBlackList.Add(pinfo.GetName(), 0) 106 _ = conn.Close() 107 } 108 } 109 } 110 } 111 } 112 113 func (p *Protocol) detectNodeAddr() { 114 115 // 通过bootstrap获取本节点公网ip 116 for _, bootstrap := range p.SubConfig.BootStraps { 117 if p.checkDone() { 118 break 119 } 120 addr, _ := multiaddr.NewMultiaddr(bootstrap) 121 peerInfo, err := peer.AddrInfoFromP2pAddr(addr) 122 if err != nil { 123 continue 124 } 125 err = p.queryVersionOld(peerInfo.ID) 126 if err != nil { 127 continue 128 } 129 } 130 var rangeCount int 131 for { 132 if p.checkDone() { 133 break 134 } 135 if p.RoutingTable.Size() == 0 { 136 time.Sleep(time.Second) 137 continue 138 } 139 //启动后间隔1分钟,以充分获得节点外网地址 140 rangeCount++ 141 if rangeCount > 2 { 142 time.Sleep(time.Minute) 143 } 144 for _, pid := range p.RoutingTable.ListPeers() { 145 if p.containsPublicIP(pid) { 146 continue 147 } 148 err := p.queryVersionOld(pid) 149 if err != nil { 150 log.Error("detectNodeAddr", "queryVersion error", err, "pid", pid) 151 continue 152 } 153 } 154 } 155 } 156 157 func (p *Protocol) queryPeerInfoOld(pid peer.ID) (*types.Peer, error) { 158 ctx, cancel := context.WithTimeout(p.Ctx, time.Second*3) 159 defer cancel() 160 stream, err := p.Host.NewStream(ctx, pid, peerInfoOld) 161 if err != nil { 162 log.Error("refreshPeerInfo", "new stream error", err, "peer id", pid) 163 return nil, err 164 } 165 defer protocol.CloseStream(stream) 166 err = protocol.WriteStream(&types.MessagePeerInfoReq{}, stream) 167 if err != nil { 168 return nil, err 169 } 170 var resp types.MessagePeerInfoResp 171 err = protocol.ReadStream(&resp, stream) 172 if err != nil { 173 return nil, err 174 } 175 if resp.Message == nil { 176 return nil, types2.ErrInvalidResponse 177 } 178 pInfo := types.Peer{ 179 Addr: resp.Message.Addr, 180 Port: resp.Message.Port, 181 Name: resp.Message.Name, 182 MempoolSize: resp.Message.MempoolSize, 183 Header: resp.Message.Header, 184 Version: resp.Message.Version, 185 LocalDBVersion: resp.Message.LocalDBVersion, 186 StoreDBVersion: resp.Message.StoreDBVersion, 187 } 188 return &pInfo, nil 189 } 190 191 func (p *Protocol) queryPeerInfo(pid peer.ID) (*types.Peer, error) { 192 ctx, cancel := context.WithTimeout(p.Ctx, time.Second*3) 193 defer cancel() 194 stream, err := p.Host.NewStream(ctx, pid, peerInfo) 195 if err != nil { 196 log.Error("refreshPeerInfo", "new stream error", err, "peer id", pid) 197 return nil, err 198 } 199 defer protocol.CloseStream(stream) 200 var resp types.Peer 201 err = protocol.ReadStream(&resp, stream) 202 if err != nil { 203 return nil, err 204 } 205 return &resp, nil 206 } 207 208 func (p *Protocol) queryVersionOld(pid peer.ID) error { 209 stream, err := p.Host.NewStream(p.Ctx, pid, peerVersionOld) 210 if err != nil { 211 log.Error("NewStream", "err", err, "remoteID", pid) 212 return err 213 } 214 defer protocol.CloseStream(stream) 215 216 req := types.MessageP2PVersionReq{ 217 Message: &types.P2PVersion{ 218 Version: p.SubConfig.Channel, 219 AddrFrom: fmt.Sprintf("/ip4/%v/tcp/%d", p.getPublicIP(), p.SubConfig.Port), 220 AddrRecv: stream.Conn().RemoteMultiaddr().String(), 221 }, 222 } 223 err = protocol.WriteStream(&req, stream) 224 if err != nil { 225 log.Error("queryVersion", "WriteStream err", err) 226 return err 227 } 228 var res types.MessageP2PVersionResp 229 err = protocol.ReadStream(&res, stream) 230 if err != nil { 231 log.Error("queryVersion", "ReadStream err", err) 232 return err 233 } 234 msg := res.Message 235 addr := msg.GetAddrRecv() 236 p.setExternalAddr(addr) 237 if !strings.Contains(msg.AddrFrom, "/ip4") { 238 _, port := parseIPAndPort(stream.Conn().RemoteMultiaddr().String()) 239 msg.AddrFrom = fmt.Sprintf("/ip4/%s/tcp/%d", msg.AddrFrom, port) 240 } 241 if ip, _ := parseIPAndPort(msg.GetAddrFrom()); isPublicIP(ip) { 242 remoteMAddr, err := multiaddr.NewMultiaddr(msg.GetAddrFrom()) 243 if err != nil { 244 return err 245 } 246 p.Host.Peerstore().AddAddr(pid, remoteMAddr, time.Hour*12) 247 } 248 return nil 249 } 250 251 func (p *Protocol) queryVersion(pid peer.ID) error { 252 stream, err := p.Host.NewStream(p.Ctx, pid, peerVersion) 253 if err != nil { 254 log.Error("NewStream", "err", err, "remoteID", pid) 255 return err 256 } 257 defer protocol.CloseStream(stream) 258 259 req := &types.P2PVersion{ 260 Version: p.SubConfig.Channel, 261 AddrFrom: fmt.Sprintf("/ip4/%v/tcp/%d", p.getPublicIP(), p.SubConfig.Port), 262 AddrRecv: stream.Conn().RemoteMultiaddr().String(), 263 } 264 err = protocol.WriteStream(req, stream) 265 if err != nil { 266 log.Error("queryVersion", "WriteStream err", err) 267 return err 268 } 269 var resp types.P2PVersion 270 err = protocol.ReadStream(&resp, stream) 271 if err != nil { 272 log.Error("queryVersion", "ReadStream err", err) 273 return err 274 } 275 addr := resp.GetAddrRecv() 276 p.setExternalAddr(addr) 277 278 if ip, _ := parseIPAndPort(resp.GetAddrFrom()); isPublicIP(ip) { 279 remoteMAddr, err := multiaddr.NewMultiaddr(resp.GetAddrFrom()) 280 if err != nil { 281 return err 282 } 283 p.Host.Peerstore().AddAddr(pid, remoteMAddr, time.Hour*12) 284 } 285 return nil 286 } 287 288 func (p *Protocol) setExternalAddr(addr string) { 289 ip, _ := parseIPAndPort(addr) 290 if isPublicIP(ip) { 291 p.mutex.Lock() 292 p.externalAddr = addr 293 p.mutex.Unlock() 294 ma, _ := multiaddr.NewMultiaddr(addr) 295 p.Host.Peerstore().AddAddr(p.Host.ID(), ma, time.Hour*24) 296 } 297 } 298 299 func (p *Protocol) getExternalAddr() string { 300 p.mutex.Lock() 301 defer p.mutex.Unlock() 302 return p.externalAddr 303 } 304 305 func (p *Protocol) getPublicIP() string { 306 ip, _ := parseIPAndPort(p.getExternalAddr()) 307 return ip 308 } 309 310 func (p *Protocol) containsPublicIP(pid peer.ID) bool { 311 for _, maddr := range p.Host.Peerstore().Addrs(pid) { 312 if ip, _ := parseIPAndPort(maddr.String()); isPublicIP(ip) { 313 return true 314 } 315 } 316 return false 317 } 318 319 func parseIPAndPort(multiAddr string) (ip string, port int) { 320 split := strings.Split(multiAddr, "/") 321 if len(split) < 5 { 322 return 323 } 324 port, err := strconv.Atoi(split[4]) 325 if err != nil { 326 return 327 } 328 ip = split[2] 329 return 330 }