示例#1
0
文件: p2p.go 项目: rwcarlsen/gobitmsg
// GetData retrieves requests objects with the specified hashes from the
// peer node that sent us ver.  It returns the number of objects
// successfully received and an error if n < len(hashes).
func (nd *Node) GetData(ver *payload.Version, hashes [][]byte) (n int, err error) {
	conn, err := net.DialTimeout("tcp", ver.FromAddr.Addr(), defaultTimeout)
	if err != nil {
		return n, err
	}
	defer conn.Close()
	pay, err := payload.GetDataEncode(ver.Protocol(), hashes)
	if err != nil {
		panic(err)
	}
	m := msg.New(msg.Cgetdata, pay)
	conn.Write(m.Encode())

	for i := 0; i < len(hashes); i++ {
		m, err := msg.Decode(conn)
		if err != nil {
			return n, err
		}
		switch m.Cmd() {
		case msg.Cversion, msg.Cverack, msg.Caddr, msg.Cinv, msg.Cgetdata:
			return n, fmt.Errorf("getdata resp contains invalid msg type %v", m.Cmd())
		}
		nd.ObjectsIn <- m
		n++
	}
	return n, nil
}
示例#2
0
文件: p2p.go 项目: rwcarlsen/gobitmsg
func (n *Node) sendInvAndAddr(conn net.Conn, proto uint32) {
	pay, err := payload.AddrEncode(proto, n.MyPeers...)
	if err != nil {
		panic(err)
	}
	am := msg.New(msg.Caddr, pay)
	if _, err := conn.Write(am.Encode()); err != nil {
		panic(err)
	}

	pay, err = payload.InventoryEncode(proto, n.invList())
	if err != nil {
		panic(err)
	}
	im := msg.New(msg.Cinv, pay)
	if _, err := conn.Write(im.Encode()); err != nil {
		panic(err)
	}
}
示例#3
0
文件: p2p.go 项目: rwcarlsen/gobitmsg
func (n *Node) verOutVerackIn(conn net.Conn, to *payload.AddressInfo, proto uint32) {
	vcopy := *n.MyVer
	vcopy.Timestamp = time.Now()
	vcopy.ToAddr = to
	pay, err := vcopy.Encode(proto)
	if err != nil {
		panic(err)
	}
	m := msg.New(msg.Cversion, pay)
	if _, err := conn.Write(m.Encode()); err != nil {
		panic(err)
	}
	msg.Must(msg.ReadKind(conn, msg.Cverack))
}
示例#4
0
文件: p2p.go 项目: rwcarlsen/gobitmsg
func (n *Node) versionExchange(addr *payload.AddressInfo) {
	resp := &VerDat{}
	defer func() { n.VerIn <- resp }()
	defer func() {
		if r := recover(); r != nil {
			resp.Err = fmt.Errorf("[ERR] version exchange did not complete (%v)", r)
			n.Log.Print(resp.Err)
		}
	}()

	n.Log.Printf("[INFO] version exchange with %v", addr.Addr())
	conn, err := net.DialTimeout("tcp", addr.Addr(), defaultTimeout)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	n.verOutVerackIn(conn, addr, payload.ProtocolVersion)

	// wait for version message and send verack
	m := msg.Must(msg.ReadKind(conn, msg.Cversion))
	resp.Ver, err = payload.VersionDecode(m.Payload())
	if err != nil {
		panic(err)
	}
	if _, err := conn.Write(msg.New(msg.Cverack, []byte{}).Encode()); err != nil {
		panic(err)
	}

	n.sendInvAndAddr(conn, resp.Ver.Protocol())

	// wait for addr and inv messages
	m = msg.Must(msg.ReadKind(conn, msg.Caddr))
	resp.Peers, err = payload.AddrDecode(resp.Ver.Protocol(), m.Payload())
	if err != nil {
		panic(err)
	}

	m = msg.Must(msg.ReadKind(conn, msg.Cinv))
	resp.Inv, err = payload.InventoryDecode(resp.Ver.Protocol(), m.Payload())
	if err != nil {
		panic(err)
	}

	n.Log.Printf("[INFO] version exchange with %v successful", addr.Addr())
}
示例#5
0
文件: p2p.go 项目: rwcarlsen/gobitmsg
func (n *Node) versionSequence(m *msg.Msg, conn net.Conn) {
	resp := &VerDat{}
	defer func() {
		if r := recover(); r != nil {
			resp.Err = fmt.Errorf("[ERR] version sequence did not complete (%v)", r)
			n.Log.Print(resp.Err)
		}
	}()

	var err error
	n.Log.Printf("[INFO] version sequence with %v", conn.RemoteAddr())

	resp.Ver, err = payload.VersionDecode(m.Payload())
	if err != nil {
		panic(err)
	}
	defer func() { n.VerIn <- resp }()

	if _, err := conn.Write(msg.New(msg.Cverack, []byte{}).Encode()); err != nil {
		panic(err)
	}

	n.verOutVerackIn(conn, resp.Ver.FromAddr, resp.Ver.Protocol())
	n.sendInvAndAddr(conn, resp.Ver.Protocol())

	// wait for addr and inv messages
	m = msg.Must(msg.ReadKind(conn, msg.Caddr))
	resp.Peers, err = payload.AddrDecode(resp.Ver.Protocol(), m.Payload())
	if err != nil {
		panic(err)
	}

	m = msg.Must(msg.ReadKind(conn, msg.Cinv))
	resp.Inv, err = payload.InventoryDecode(resp.Ver.Protocol(), m.Payload())
	if err != nil {
		panic(err)
	}
	n.Log.Printf("[INFO] version sequence with %v successful", conn.RemoteAddr())
}