github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/p2p/discover/udp.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package discover 18 19 import ( 20 "bytes" 21 "container/list" 22 "crypto/ecdsa" 23 "errors" 24 "fmt" 25 "net" 26 "strconv" 27 "time" 28 29 "github.com/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/qmanager/global" 31 "github.com/ethereum/go-ethereum/qmanager/utils" 32 33 "github.com/ethereum/go-ethereum/crypto" 34 "github.com/ethereum/go-ethereum/log" 35 "github.com/ethereum/go-ethereum/p2p/nat" 36 "github.com/ethereum/go-ethereum/p2p/netutil" 37 "github.com/ethereum/go-ethereum/rlp" 38 ) 39 40 const Version = 4 41 const ReapChainFlag = 65 42 43 //const boot_node_port = 30301 44 //var boot_node_port int //temp , 30301, or 30391 45 46 // Errors 47 var ( 48 errPacketTooSmall = errors.New("too small") 49 errBadHash = errors.New("bad hash") 50 errExpired = errors.New("expired") 51 errUnsolicitedReply = errors.New("unsolicited reply") 52 errUnknownNode = errors.New("unknown node") 53 errTimeout = errors.New("RPC timeout") 54 errClockWarp = errors.New("reply deadline too far in the future") 55 errClosed = errors.New("socket closed") 56 //QManagerStorage *leveldb.DB 57 58 ) 59 60 // Timeouts 61 const ( 62 respTimeout = 500 * time.Millisecond 63 sendTimeout = 500 * time.Millisecond 64 expiration = 20 * time.Second 65 66 ntpFailureThreshold = 32 // Continuous timeouts after which to check NTP 67 ntpWarningCooldown = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning 68 driftThreshold = 10 * time.Second // Allowed clock drift before warning user 69 ) 70 71 // RPC packet types 72 const ( 73 pingPacket = iota + 1 // zero is 'reserved' //1 74 pongPacket // 2 75 findnodePacket 76 neighborsPacket 77 ) 78 79 // RPC request structures 80 type ( 81 ping struct { 82 Version uint 83 From, To rpcEndpoint 84 Expiration uint64 85 // Ignore additional fields (for forward compatibility). 86 Rest []rlp.RawValue `rlp:"tail"` 87 } 88 // pong is the reply to ping. 89 pong struct { 90 // This field should mirror the UDP envelope address 91 // of the ping packet, which provides a way to discover the 92 // the external address (after NAT). 93 To rpcEndpoint 94 95 ReplyTok []byte // This contains the hash of the ping packet. 96 Expiration uint64 // Absolute timestamp at which the packet becomes invalid. 97 // Ignore additional fields (for forward compatibility). 98 Rest []rlp.RawValue `rlp:"tail"` 99 } 100 101 // findnode is a query for nodes close to the given target. 102 findnode struct { 103 Target NodeID // doesn't need to be an actual public key 104 Expiration uint64 105 // Ignore additional fields (for forward compatibility). 106 Rest []rlp.RawValue `rlp:"tail"` 107 } 108 109 // reply to findnode 110 neighbors struct { 111 Nodes []rpcNode 112 Expiration uint64 113 // Ignore additional fields (for forward compatibility). 114 Rest []rlp.RawValue `rlp:"tail"` 115 } 116 117 rpcNode struct { 118 IP net.IP // len 4 for IPv4 or 16 for IPv6 119 UDP uint16 // for discovery protocol 120 TCP uint16 // for RLPx protocol 121 ID NodeID 122 } 123 124 rpcEndpoint struct { 125 IP net.IP // len 4 for IPv4 or 16 for IPv6 126 UDP uint16 // for discovery protocol 127 TCP uint16 // for RLPx protocol 128 Flag uint16 129 } 130 131 //QManDBStruct struct { 132 // ID NodeID 133 // PubKey *ecdsa.PublicKey 134 // Address common.Address 135 // QRND uint64 136 //} 137 ) 138 139 func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint { 140 ip := addr.IP.To4() 141 if ip == nil { 142 ip = addr.IP.To16() 143 } 144 return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort, Flag: uint16(ReapChainFlag)} 145 } 146 147 func (t *udp) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*Node, error) { 148 if rn.UDP <= 1024 { 149 return nil, errors.New("low port") 150 } 151 if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil { 152 return nil, err 153 } 154 if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) { 155 return nil, errors.New("not contained in netrestrict whitelist") 156 } 157 n := NewNode(rn.ID, rn.IP, rn.UDP, rn.TCP) 158 err := n.validateComplete() 159 return n, err 160 } 161 162 func nodeToRPC(n *Node) rpcNode { 163 return rpcNode{ID: n.ID, IP: n.IP, UDP: n.UDP, TCP: n.TCP} 164 } 165 166 type packet interface { 167 handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error 168 name() string 169 } 170 171 type conn interface { 172 ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) 173 WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error) 174 Close() error 175 LocalAddr() net.Addr 176 } 177 178 // udp implements the RPC protocol. 179 type udp struct { 180 conn conn 181 netrestrict *netutil.Netlist 182 priv *ecdsa.PrivateKey 183 ourEndpoint rpcEndpoint 184 185 addpending chan *pending 186 gotreply chan reply 187 188 closing chan struct{} 189 nat nat.Interface 190 191 *Table 192 } 193 194 // pending represents a pending reply. 195 // 196 // some implementations of the protocol wish to send more than one 197 // reply packet to findnode. in general, any neighbors packet cannot 198 // be matched up with a specific findnode packet. 199 // 200 // our implementation handles this by storing a callback function for 201 // each pending reply. incoming packets from a node are dispatched 202 // to all the callback functions for that node. 203 type pending struct { 204 // these fields must match in the reply. 205 from NodeID 206 ptype byte 207 208 // time when the request must complete 209 deadline time.Time 210 211 // callback is called when a matching reply arrives. if it returns 212 // true, the callback is removed from the pending reply queue. 213 // if it returns false, the reply is considered incomplete and 214 // the callback will be invoked again for the next matching reply. 215 callback func(resp interface{}) (done bool) 216 217 // errc receives nil when the callback indicates completion or an 218 // error if no further reply is received within the timeout. 219 errc chan<- error 220 } 221 222 type reply struct { 223 from NodeID 224 ptype byte 225 data interface{} 226 // loop indicates whether there was 227 // a matching request by sending on this channel. 228 matched chan<- bool 229 } 230 231 // ListenUDP returns a new table that listens for UDP packets on laddr. 232 func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist) (*Table, error) { 233 addr, err := net.ResolveUDPAddr("udp", laddr) 234 // log.Info(fmt.Sprintf("ResolveUDPAddr result: %v, %v, %v ", addr.IP , addr.Port, addr.Zone )) 235 if err != nil { 236 return nil, err 237 } 238 conn, err := net.ListenUDP("udp", addr) //socket setup ? 239 if global.IsBootNode { 240 global.BootNodePort = addr.Port 241 global.BootNodeID = PubkeyID(&priv.PublicKey).String() 242 } 243 log.Info("net.ListenUDP up: addr ", "self", laddr) 244 if err != nil { 245 return nil, err 246 } 247 tab, _, err := newUDP(priv, conn, natm, nodeDBPath, netrestrict) 248 if err != nil { 249 return nil, err 250 } 251 log.Info("UDP listener up", "self", tab.self) 252 253 return tab, nil 254 255 } 256 257 func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist) (*Table, *udp, error) { 258 udp := &udp{ 259 conn: c, 260 priv: priv, 261 netrestrict: netrestrict, 262 closing: make(chan struct{}), 263 gotreply: make(chan reply), 264 addpending: make(chan *pending), 265 } 266 realaddr := c.LocalAddr().(*net.UDPAddr) //? local ip or upnp public ip c는 discover pkg , cast연산자,, ? 267 268 //fmt.Printf("======================> realaddr <======================= %s", realaddr ) 269 if natm != nil { //doit=any, none, extip , etc 270 if !realaddr.IP.IsLoopback() { 271 go nat.Map(natm, udp.closing, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") 272 } else { 273 log.Info("newUDP loopback : ") 274 } 275 // TODO: react to external IP changes over time. 276 if ext, err := natm.ExternalIP(); err == nil { 277 realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port} 278 } 279 280 } 281 // TODO: separate TCP port 282 udp.ourEndpoint = makeEndpoint(realaddr, uint16(realaddr.Port)) 283 tab, err := newTable(udp, PubkeyID(&priv.PublicKey), realaddr, nodeDBPath) 284 if err != nil { 285 return nil, nil, err 286 } 287 udp.Table = tab 288 289 go udp.loop() 290 go udp.readLoop() 291 return udp.Table, udp, nil 292 } 293 294 func (t *udp) close() { 295 close(t.closing) 296 t.conn.Close() 297 // TODO: wait for the loops to end. 298 } 299 300 // ping sends a ping message to the given node and waits for a reply. 301 func (t *udp) ping(toid NodeID, toaddr *net.UDPAddr) error { 302 // TODO: maybe check for ReplyTo field in callback to measure RTT 303 errc := t.pending(toid, pongPacket, func(interface{}) bool { return true }) 304 t.send(toaddr, pingPacket, &ping{ 305 Version: Version, 306 From: t.ourEndpoint, 307 To: makeEndpoint(toaddr, 0), // TODO: maybe use known TCP port from DB 308 Expiration: uint64(time.Now().Add(expiration).Unix()), 309 //Flag: "Reapchain", 310 }) 311 return <-errc 312 } 313 314 func (t *udp) waitping(from NodeID) error { 315 return <-t.pending(from, pingPacket, func(interface{}) bool { return true }) 316 } 317 318 // findnode sends a findnode request to the given node and waits until 319 // the node has sent up to k neighbors. 320 func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node, error) { 321 //fmt.Printf("toid NodeID = %s, toaddr =%s, target= %s\n", toid, toaddr.IP.String(), target ) 322 nodes := make([]*Node, 0, bucketSize) 323 nreceived := 0 324 errc := t.pending(toid, neighborsPacket, func(r interface{}) bool { 325 reply := r.(*neighbors) 326 for _, rn := range reply.Nodes { 327 nreceived++ 328 n, err := t.nodeFromRPC(toaddr, rn) 329 if err != nil { 330 log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err) 331 continue 332 } 333 nodes = append(nodes, n) 334 } 335 return nreceived >= bucketSize 336 }) 337 t.send(toaddr, findnodePacket, &findnode{ 338 Target: target, 339 Expiration: uint64(time.Now().Add(expiration).Unix()), 340 }) 341 err := <-errc 342 return nodes, err 343 } 344 345 // pending adds a reply callback to the pending reply queue. 346 // see the documentation of type pending for a detailed explanation. 347 func (t *udp) pending(id NodeID, ptype byte, callback func(interface{}) bool) <-chan error { 348 ch := make(chan error, 1) 349 p := &pending{from: id, ptype: ptype, callback: callback, errc: ch} 350 select { 351 case t.addpending <- p: 352 // loop will handle it 353 case <-t.closing: 354 ch <- errClosed 355 } 356 return ch 357 } 358 359 func (t *udp) handleReply(from NodeID, ptype byte, req packet) bool { 360 matched := make(chan bool, 1) 361 select { 362 case t.gotreply <- reply{from, ptype, req, matched}: 363 // loop will handle it 364 return <-matched 365 case <-t.closing: 366 return false 367 } 368 } 369 370 // loop runs in its own goroutine. it keeps track of 371 // the refresh timer and the pending reply queue. 372 func (t *udp) loop() { 373 var ( 374 plist = list.New() 375 timeout = time.NewTimer(0) 376 nextTimeout *pending // head of plist when timeout was last reset 377 contTimeouts = 0 // number of continuous timeouts to do NTP checks 378 ntpWarnTime = time.Unix(0, 0) 379 ) 380 <-timeout.C // ignore first timeout 381 defer timeout.Stop() 382 383 resetTimeout := func() { 384 if plist.Front() == nil || nextTimeout == plist.Front().Value { 385 return 386 } 387 // Start the timer so it fires when the next pending reply has expired. 388 now := time.Now() 389 for el := plist.Front(); el != nil; el = el.Next() { 390 nextTimeout = el.Value.(*pending) 391 if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout { 392 timeout.Reset(dist) 393 return 394 } 395 // Remove pending replies whose deadline is too far in the 396 // future. These can occur if the system clock jumped 397 // backwards after the deadline was assigned. 398 nextTimeout.errc <- errClockWarp 399 plist.Remove(el) 400 } 401 nextTimeout = nil 402 timeout.Stop() 403 } 404 405 for { 406 resetTimeout() 407 408 select { 409 case <-t.closing: 410 for el := plist.Front(); el != nil; el = el.Next() { 411 el.Value.(*pending).errc <- errClosed 412 } 413 return 414 415 case p := <-t.addpending: 416 p.deadline = time.Now().Add(respTimeout) 417 plist.PushBack(p) 418 419 case r := <-t.gotreply: 420 var matched bool 421 for el := plist.Front(); el != nil; el = el.Next() { 422 p := el.Value.(*pending) 423 if p.from == r.from && p.ptype == r.ptype { 424 matched = true 425 // Remove the matcher if its callback indicates 426 // that all replies have been received. This is 427 // required for packet types that expect multiple 428 // reply packets. 429 if p.callback(r.data) { 430 p.errc <- nil 431 plist.Remove(el) 432 } 433 // Reset the continuous timeout counter (time drift detection) 434 contTimeouts = 0 435 } 436 } 437 r.matched <- matched 438 439 case now := <-timeout.C: 440 nextTimeout = nil 441 442 // Notify and remove callbacks whose deadline is in the past. 443 for el := plist.Front(); el != nil; el = el.Next() { 444 p := el.Value.(*pending) 445 if now.After(p.deadline) || now.Equal(p.deadline) { 446 p.errc <- errTimeout 447 plist.Remove(el) 448 contTimeouts++ 449 } 450 } 451 // If we've accumulated too many timeouts, do an NTP time sync check 452 if contTimeouts > ntpFailureThreshold { 453 if time.Since(ntpWarnTime) >= ntpWarningCooldown { 454 ntpWarnTime = time.Now() 455 go checkClockDrift() 456 } 457 contTimeouts = 0 458 } 459 } 460 } 461 } 462 463 const ( 464 macSize = 256 / 8 465 sigSize = 520 / 8 466 headSize = macSize + sigSize // space of packet frame data 467 ) 468 469 var ( 470 headSpace = make([]byte, headSize) 471 472 // Neighbors replies are sent across multiple packets to 473 // stay below the 1280 byte limit. We compute the maximum number 474 // of entries by stuffing a packet until it grows too large. 475 maxNeighbors int 476 ) 477 478 func init() { 479 p := neighbors{Expiration: ^uint64(0)} 480 maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)} 481 for n := 0; ; n++ { 482 p.Nodes = append(p.Nodes, maxSizeNode) 483 size, _, err := rlp.EncodeToReader(p) 484 if err != nil { 485 // If this ever happens, it will be caught by the unit tests. 486 panic("cannot encode: " + err.Error()) 487 } 488 if headSize+size+1 >= 1280 { 489 maxNeighbors = n 490 break 491 } 492 } 493 } 494 495 func (t *udp) send(toaddr *net.UDPAddr, ptype byte, req packet) error { 496 packet, err := encodePacket(t.priv, ptype, req) 497 if err != nil { 498 return err 499 } 500 _, err = t.conn.WriteToUDP(packet, toaddr) 501 log.Trace(">> "+req.name(), "addr", toaddr, "err", err) 502 return err 503 } 504 505 func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte, error) { 506 b := new(bytes.Buffer) 507 b.Write(headSpace) 508 b.WriteByte(ptype) 509 if err := rlp.Encode(b, req); err != nil { 510 log.Error("Can't encode discv4 packet", "err", err) 511 return nil, err 512 } 513 packet := b.Bytes() 514 sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv) 515 if err != nil { 516 log.Error("Can't sign discv4 packet", "err", err) 517 return nil, err 518 } 519 copy(packet[macSize:], sig) 520 // add the hash to the front. Note: this doesn't protect the 521 // packet in any way. Our public key will be part of this hash in 522 // The future. 523 copy(packet, crypto.Keccak256(packet[macSize:])) 524 return packet, nil 525 } 526 527 // readLoop runs in its own goroutine. it handles incoming UDP packets. 528 func (t *udp) readLoop() { 529 defer t.conn.Close() 530 // Discovery packets are defined to be no larger than 1280 bytes. 531 // Packets larger than this size will be cut at the end and treated 532 // as invalid because their hash won't match. 533 buf := make([]byte, 1280) 534 for { 535 nbytes, from, err := t.conn.ReadFromUDP(buf) 536 if netutil.IsTemporaryError(err) { 537 // Ignore temporary read errors. 538 log.Debug("Temporary UDP read error", "err", err) 539 continue 540 } else if err != nil { 541 // Shut down the loop for permament errors. 542 log.Debug("UDP read error", "err", err) 543 return 544 } 545 t.handlePacket(from, buf[:nbytes]) 546 } 547 } 548 549 func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error { 550 packet, fromID, hash, err := decodePacket(buf) 551 if err != nil { 552 //temp : log.Debug("Bad discv4 packet", "addr", from, "err", err) 553 return err 554 } 555 err = packet.handle(t, from, fromID, hash) 556 log.Trace("<< "+packet.name(), "addr", from, "err", err) 557 return err 558 } 559 560 func decodePacket(buf []byte) (packet, NodeID, []byte, error) { 561 if len(buf) < headSize+1 { 562 return nil, NodeID{}, nil, errPacketTooSmall 563 } 564 hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:] 565 shouldhash := crypto.Keccak256(buf[macSize:]) 566 if !bytes.Equal(hash, shouldhash) { 567 return nil, NodeID{}, nil, errBadHash 568 } 569 fromID, err := recoverNodeID(crypto.Keccak256(buf[headSize:]), sig) 570 if err != nil { 571 return nil, NodeID{}, hash, err 572 } 573 var req packet 574 switch ptype := sigdata[0]; ptype { 575 case pingPacket: 576 req = new(ping) 577 case pongPacket: 578 req = new(pong) 579 case findnodePacket: 580 req = new(findnode) 581 case neighborsPacket: 582 req = new(neighbors) 583 584 default: 585 return nil, fromID, hash, fmt.Errorf("unknown type: %d", ptype) 586 } 587 s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0) 588 err = s.Decode(req) 589 return req, fromID, hash, err 590 } 591 592 func (req *ping) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 593 if expired(req.Expiration) { 594 return errExpired 595 } 596 597 if req.From.Flag == uint16(ReapChainFlag) { 598 t.send(from, pongPacket, &pong{ 599 To: makeEndpoint(from, req.From.TCP), 600 ReplyTok: mac, 601 Expiration: uint64(time.Now().Add(expiration).Unix()), 602 }) 603 if !t.handleReply(fromID, pingPacket, req) { 604 // Note: we're ignoring the provided IP address right now 605 go t.bond(true, fromID, from, req.From.TCP) 606 } 607 } 608 609 return nil 610 } 611 612 func (req *ping) name() string { return "PING/v4" } 613 614 func (req *pong) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 615 if expired(req.Expiration) { 616 return errExpired 617 } 618 if !t.handleReply(fromID, pongPacket, req) { 619 return errUnsolicitedReply 620 } 621 622 //if t.conn.LocalAddr().(*net.UDPAddr).Port == qManager.BootNodePort { 623 // fmt.Println("Pong From:", fromID) 624 //} 625 626 return nil 627 } 628 629 func (req *pong) name() string { return "PONG/v4" } 630 631 func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 632 if expired(req.Expiration) { 633 return errExpired 634 } 635 if t.db.node(fromID) == nil { 636 // No bond exists, we don't process the packet. This prevents 637 // an attack vector where the discovery protocol could be used 638 // to amplify traffic in a DDOS attack. A malicious actor 639 // would send a findnode request with the IP address and UDP 640 // port of the target as the source address. The recipient of 641 // the findnode packet would then send a neighbors packet 642 // (which is a much bigger packet than findnode) to the victim. 643 return errUnknownNode 644 } 645 646 target := crypto.Keccak256Hash(req.Target[:]) 647 t.mutex.Lock() 648 closest := t.closest(target, bucketSize).entries 649 t.mutex.Unlock() 650 651 p := neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())} 652 // Send neighbors in chunks with at most maxNeighbors per packet 653 // to stay below the 1280 byte limit. 654 for i, n := range closest { 655 if netutil.CheckRelayIP(from.IP, n.IP) != nil { 656 continue 657 } 658 p.Nodes = append(p.Nodes, nodeToRPC(n)) 659 if len(p.Nodes) == maxNeighbors || i == len(closest)-1 { 660 t.send(from, neighborsPacket, &p) 661 p.Nodes = p.Nodes[:0] 662 663 } 664 } 665 666 if global.CheckBootNodePortAndID(t.self.ID.String(), int(t.self.UDP)) { 667 go func() { 668 node_pubKey, _ := fromID.Pubkey() 669 pubBytes := crypto.FromECDSAPub(node_pubKey) 670 nodeAddress := common.BytesToAddress(crypto.Keccak256(pubBytes[1:])[12:]) 671 timestamp := time.Now().Format("2006-01-02 15:04:05") 672 qNode := global.QManDBStruct{ID: fromID.String(), Address: nodeAddress.String(), Timestamp: timestamp, Tag: strconv.Itoa(3)} 673 err := utils.BootNodeToQmanager(qNode) 674 if err != nil { 675 log.Error("Bootnode to Qman Failure", "Error", err.Error()) 676 } 677 }() 678 } 679 680 return nil 681 } 682 683 func (req *findnode) name() string { return "FINDNODE/v4" } 684 685 func (req *neighbors) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 686 if expired(req.Expiration) { 687 return errExpired 688 } 689 if !t.handleReply(fromID, neighborsPacket, req) { 690 return errUnsolicitedReply 691 } 692 return nil 693 } 694 695 func (req *neighbors) name() string { return "NEIGHBORS/v4" } 696 697 func expired(ts uint64) bool { 698 return time.Unix(int64(ts), 0).Before(time.Now()) 699 } 700 701 // 702 // 703 //func (req *qmanager) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 704 // if expired(req.Expiration) { 705 // return errExpired 706 // } 707 // 708 // node_pubKey, _ := req.Node.Pubkey() 709 // pubBytes := crypto.FromECDSAPub(node_pubKey) 710 // nodeAddress := common.BytesToAddress(crypto.Keccak256(pubBytes[1:])[12:]) 711 // timestamp := time.Now().Format("2006-01-02 15:04:05") 712 // 713 // 714 // qNode := podc_global.QManDBStruct{ID: req.Node.String(), Address: nodeAddress.String(), Timestamp: timestamp, Tag: 2 } 715 // podc_global.BootNodeSendData(qNode) 716 // //nodeFound := qManager.FindNode(nodeAddress.String()) 717 // // 718 // //if !nodeFound { 719 // // log.Info("Qmanager New Entry", "ID = ", req.Node.String()) 720 // // saveError := qManager.Save(qNode) 721 // // if !saveError { 722 // // //fmt.Println("Save Error") 723 // // log.Info("Save ERR", "err = ", saveError) 724 // // } 725 // //} 726 // 727 // return nil 728 //} 729 // 730 //func (req qmanager) name() string { 731 // return "QMANAGER/v4" 732 //} 733 // 734 // 735 // 736 //func (req *requestQman) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 737 // if expired(req.Expiration) { 738 // return errExpired 739 // } 740 // 741 // log.Info("Bootnode Requesting Reply", "Node ID = ", t.self.ID.String()) 742 // 743 // 744 // if podc_global.QManConnected { 745 // fmt.Println("Qman Sending Address") 746 // ps := receiveQman{Node: fromID, Expiration: uint64(time.Now().Add(expiration).Unix())} 747 // fmt.Println(fromID) 748 // t.send(from , receiveQmanPacket, &ps) 749 // 750 // 751 // } 752 // return nil 753 //} 754 // 755 //func (req requestQman) name() string { 756 // return "QManager Request/v4" 757 //} 758 // 759 // 760 //func (req *receiveQman) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error { 761 // if expired(req.Expiration) { 762 // return errExpired 763 // } 764 // 765 // 766 // if podc_global.CheckBootNodePortAndID(t.self.ID.String(), int(t.self.UDP)){ 767 // //if t.conn.LocalAddr().(*net.UDPAddr).Port == podc_global.BootNodePort { 768 // fmt.Println("Recieved Qman Address") 769 // //ps := recieveQman{Node: fromID, Expiration: uint64(time.Now().Add(expiration).Unix())} 770 // //fmt.Println(fromID) 771 // //t.send(from , recieveQmanPacket, &ps) 772 // 773 // podc_global.QManagerAddress = from 774 // podc_global.BootNodeReady = true 775 // 776 // 777 // } 778 // return nil 779 //} 780 // 781 //func (req receiveQman) name() string { 782 // return "QManager Receive/v4" 783 //}