//Adds a peer to the set of peers func (self *Peers) AddPeer(remaddr string) { if remaddr == self.this.Addr || !self.table.Fits(util.IpValue(remaddr)) { return } newpeer, err := NewPeer(self.this.IntAddr, self.this.Addr, remaddr) if err == nil && newpeer != nil { if self.table.Insert(newpeer) { go func() { for !newpeer.isDead() { self.peers <- newpeer } self.table.Delete(newpeer.Key()) }() } peeraddrs, err := self.GetPeers(newpeer, 4) if err == nil { for _, peeraddr := range peeraddrs { self.AddPeer(peeraddr) } } } return }
//initializes a new peer func NewPeer(intaddr, locaddr, remaddr string) (*Peer, error) { locip, _, _ := net.SplitHostPort(locaddr) remip, remport, _ := net.SplitHostPort(remaddr) var conn net.Conn var err error conn, err = net.Dial("tcp", remaddr) if err != nil { return nil, err } client := rpc.NewClient(conn) var description info.Info err = client.Call("Node.Greet", &locaddr, &description) if err != nil { return nil, err } if locip == remip { rintip, _, _ := net.SplitHostPort(description.IntAddr) conn2, err := net.Dial("tcp", fmt.Sprintf("%v:%v", rintip, remport)) if err == nil { client.Close() conn.Close() client = rpc.NewClient(conn2) conn = conn2 } } peer := &Peer{Addr: remaddr, Info: description, dead: 0, id: util.IpValue(remaddr), client: client, conn: conn, wg: &sync.WaitGroup{}} go func() { for !peer.isDead() { if !peer.livecheck() { peer.kill() } select { case <-time.After(30 * time.Second): } } }() return peer, err }
func ThisPeer(intaddr, addr string, description info.Info) *Peer { description.IntAddr = intaddr return &Peer{Addr: addr, Info: description, id: util.IpValue(addr), dead: 0} }