Beispiel #1
0
// Fetch a given number of best (most recenty seen) peers.
// Set unconnected to true to only get those that we are not connected to.
func GetBestPeers(limit uint, unconnected bool) (res manyPeers) {
	if proxyPeer != nil {
		if !unconnected || !ConnectionActive(proxyPeer) {
			return manyPeers{proxyPeer}
		}
		return manyPeers{}
	}
	peerdb_mutex.Lock()
	tmp := make(manyPeers, 0)
	PeerDB.Browse(func(k qdb.KeyType, v []byte) uint32 {
		ad := NewPeer(v)
		if ad.Banned == 0 && utils.ValidIp4(ad.Ip4[:]) && !common.IsIPBlocked(ad.Ip4[:]) {
			if !unconnected || !ConnectionActive(ad) {
				tmp = append(tmp, ad)
			}
		}
		return 0
	})
	peerdb_mutex.Unlock()
	// Copy the top rows to the result buffer
	if len(tmp) > 0 {
		sort.Sort(tmp)
		if uint(len(tmp)) < limit {
			limit = uint(len(tmp))
		}
		res = make(manyPeers, limit)
		copy(res, tmp[:limit])
	}
	return
}
Beispiel #2
0
// Parese network's "addr" message
func ParseAddr(pl []byte) {
	b := bytes.NewBuffer(pl)
	cnt, _ := btc.ReadVLen(b)
	for i := 0; i < int(cnt); i++ {
		var buf [30]byte
		n, e := b.Read(buf[:])
		if n != len(buf) || e != nil {
			common.CountSafe("AddrError")
			//println("ParseAddr:", n, e)
			break
		}
		a := NewPeer(buf[:])
		if !utils.ValidIp4(a.Ip4[:]) {
			common.CountSafe("AddrInvalid")
		} else if time.Unix(int64(a.Time), 0).Before(time.Now().Add(time.Minute)) {
			if time.Now().Before(time.Unix(int64(a.Time), 0).Add(ExpirePeerAfter)) {
				k := qdb.KeyType(a.UniqID())
				v := PeerDB.Get(k)
				if v != nil {
					a.Banned = NewPeer(v[:]).Banned
				}
				PeerDB.Put(k, a.Bytes())
			} else {
				common.CountSafe("AddrStale")
			}
		} else {
			common.CountSafe("AddrInFuture")
		}
	}
}
Beispiel #3
0
func main() {
	var dir string

	if len(os.Args) > 1 {
		dir = os.Args[1]
	} else {
		dir = utils.BitcoinHome() + "gocoin" + string(os.PathSeparator) + "btcnet" + string(os.PathSeparator) + "peers3"
	}

	db, er := qdb.NewDB(dir, true)

	if er != nil {
		println(er.Error())
		os.Exit(1)
	}

	println(db.Count(), "peers in databse", dir)
	if db.Count() == 0 {
		return
	}

	tmp := make(manyPeers, db.Count())
	cnt := 0
	db.Browse(func(k qdb.KeyType, v []byte) uint32 {
		np := utils.NewPeer(v)
		if !utils.ValidIp4(np.Ip4[:]) {
			return 0
		}
		if cnt < len(tmp) {
			tmp[cnt] = np
			cnt++
		}
		return 0
	})

	sort.Sort(tmp[:cnt])
	for cnt = 0; cnt < len(tmp) && cnt < 25; cnt++ {
		ad := tmp[cnt]
		fmt.Printf("%3d) %16s   %5d  - seen %5d min ago\n", cnt+1,
			fmt.Sprintf("%d.%d.%d.%d", ad.Ip4[0], ad.Ip4[1], ad.Ip4[2], ad.Ip4[3]),
			ad.Port, (time.Now().Unix()-int64(ad.Time))/60)
	}
}
Beispiel #4
0
func (c *OneConnection) HandleVersion(pl []byte) error {
	if len(pl) >= 80 /*Up to, includiong, the nonce */ {
		c.Mutex.Lock()
		c.Node.Version = binary.LittleEndian.Uint32(pl[0:4])
		if bytes.Equal(pl[72:80], nonce[:]) {
			c.Mutex.Unlock()
			return errors.New("Connecting to ourselves")
		}
		if c.Node.Version < MIN_PROTO_VERSION {
			c.Mutex.Unlock()
			return errors.New("Client version too low")
		}
		c.Node.Services = binary.LittleEndian.Uint64(pl[4:12])
		c.Node.Timestamp = binary.LittleEndian.Uint64(pl[12:20])
		c.Mutex.Unlock()
		if utils.ValidIp4(pl[40:44]) {
			ExternalIpMutex.Lock()
			c.Node.ReportedIp4 = binary.BigEndian.Uint32(pl[40:44])
			ExternalIp4[c.Node.ReportedIp4] = [2]uint{ExternalIp4[c.Node.ReportedIp4][0] + 1, uint(time.Now().Unix())}
			ExternalIpMutex.Unlock()
		}
		if len(pl) >= 86 {
			c.Mutex.Lock()
			le, of := btc.VLen(pl[80:])
			of += 80
			c.Node.Agent = string(pl[of : of+le])
			of += le
			if len(pl) >= of+4 {
				c.Node.Height = binary.LittleEndian.Uint32(pl[of : of+4])
				of += 4
				if len(pl) > of && pl[of] == 0 {
					c.Node.DoNotRelayTxs = true
				}
			}
			c.Mutex.Unlock()
		}
	} else {
		return errors.New("common.Version message too short")
	}
	c.SendRawMsg("verack", []byte{})
	return nil
}