Combine readMessage with ReadMessage.

These functions used to be split into multiple files, but since the code
was reorganized there is no longer any reason to split them.
This commit is contained in:
Dave Collins 2013-05-09 20:15:27 -05:00
parent d829f688b9
commit 6286a39378
3 changed files with 101 additions and 115 deletions

View file

@ -87,12 +87,6 @@ func TstWriteBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
return writeBlockHeader(w, pver, bh)
}
// TstReadMessage makes the internal readMessage function available to
// the test package.
func TstReadMessage(r io.Reader, pver uint32, hdr *messageHeader) (Message, []byte, error) {
return readMessage(r, pver, hdr)
}
// TstReadMessageHeader makes the internal readMessageHeader function available
// to the test package.
func TstReadMessageHeader(r io.Reader) (*messageHeader, error) {

View file

@ -160,64 +160,6 @@ func discardInput(r io.Reader, n uint32) {
}
}
// readMessage reads the next bitcoin message from r for the provided protocol
// version and message header.
func readMessage(r io.Reader, pver uint32, hdr *messageHeader) (Message, []byte, error) {
if hdr == nil {
return nil, nil, fmt.Errorf("readMessage: nil header")
}
command := hdr.command
if !utf8.ValidString(command) {
discardInput(r, hdr.length)
str := "readMessage: invalid command %v"
return nil, nil, fmt.Errorf(str, []byte(command))
}
// Create struct of appropriate message type based on the command.
msg, err := makeEmptyMessage(command)
if err != nil {
discardInput(r, hdr.length)
return nil, nil, fmt.Errorf("readMessage: %v", err)
}
// Check for maximum length based on the message type as a malicious client
// could otherwise create a well-formed header and set the length to max
// numbers in order to exhaust the machine's memory.
mpl := msg.MaxPayloadLength(pver)
if hdr.length > mpl {
discardInput(r, hdr.length)
str := "ReadMessage: payload exceeds max length - Header " +
"indicates %v bytes, but max payload size for messages of type " +
"[%v] is %v."
return nil, nil, fmt.Errorf(str, hdr.length, command, mpl)
}
// Read payload.
payload := make([]byte, hdr.length)
_, err = io.ReadFull(r, payload)
if err != nil {
return nil, nil, err
}
// Test checksum.
checksum := DoubleSha256(payload)[0:4]
if !bytes.Equal(checksum[:], hdr.checksum[:]) {
str := "readMessage: payload checksum failed - Header " +
"indicates %v, but actual checksum is %v."
return nil, nil, fmt.Errorf(str, hdr.checksum, checksum)
}
// Unmarshal message.
pr := bytes.NewBuffer(payload)
err = msg.BtcDecode(pr, pver)
if err != nil {
return nil, nil, err
}
return msg, payload, nil
}
// WriteMessage writes a bitcoin Message to w including the necessary header
// information.
func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) error {
@ -271,7 +213,8 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) erro
return nil
}
// ReadMessage reads, validates, and parses the next bitcoin Message from r.
// ReadMessage reads, validates, and parses the next bitcoin Message from r for
// the provided protocol version and bitcoin network.
func ReadMessage(r io.Reader, pver uint32, btcnet BitcoinNet) (Message, []byte, error) {
hdr, err := readMessageHeader(r)
if err != nil {
@ -283,5 +226,53 @@ func ReadMessage(r io.Reader, pver uint32, btcnet BitcoinNet) (Message, []byte,
return nil, nil, fmt.Errorf(str, hdr.magic)
}
return readMessage(r, pver, hdr)
command := hdr.command
if !utf8.ValidString(command) {
discardInput(r, hdr.length)
str := "readMessage: invalid command %v"
return nil, nil, fmt.Errorf(str, []byte(command))
}
// Create struct of appropriate message type based on the command.
msg, err := makeEmptyMessage(command)
if err != nil {
discardInput(r, hdr.length)
return nil, nil, fmt.Errorf("readMessage: %v", err)
}
// Check for maximum length based on the message type as a malicious client
// could otherwise create a well-formed header and set the length to max
// numbers in order to exhaust the machine's memory.
mpl := msg.MaxPayloadLength(pver)
if hdr.length > mpl {
discardInput(r, hdr.length)
str := "ReadMessage: payload exceeds max length - Header " +
"indicates %v bytes, but max payload size for messages of type " +
"[%v] is %v."
return nil, nil, fmt.Errorf(str, hdr.length, command, mpl)
}
// Read payload.
payload := make([]byte, hdr.length)
_, err = io.ReadFull(r, payload)
if err != nil {
return nil, nil, err
}
// Test checksum.
checksum := DoubleSha256(payload)[0:4]
if !bytes.Equal(checksum[:], hdr.checksum[:]) {
str := "readMessage: payload checksum failed - Header " +
"indicates %v, but actual checksum is %v."
return nil, nil, fmt.Errorf(str, hdr.checksum, checksum)
}
// Unmarshal message.
pr := bytes.NewBuffer(payload)
err = msg.BtcDecode(pr, pver)
if err != nil {
return nil, nil, err
}
return msg, payload, nil
}

View file

@ -5,50 +5,47 @@ github.com/conformal/btcwire/common.go writeVarInt 100.00% (16/16)
github.com/conformal/btcwire/shahash.go NewShaHashFromStr 100.00% (15/15)
github.com/conformal/btcwire/protocol.go ServiceFlag.String 100.00% (12/12)
github.com/conformal/btcwire/common.go readVarString 100.00% (8/8)
github.com/conformal/btcwire/common.go randomUint64 100.00% (7/7)
github.com/conformal/btcwire/common.go DoubleSha256 100.00% (7/7)
github.com/conformal/btcwire/msgversion.go NewMsgVersionFromConn 100.00% (7/7)
github.com/conformal/btcwire/common.go writeVarString 100.00% (7/7)
github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5)
github.com/conformal/btcwire/common.go randomUint64 100.00% (7/7)
github.com/conformal/btcwire/common.go DoubleSha256 100.00% (7/7)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.AddBlockLocatorHash 100.00% (5/5)
github.com/conformal/btcwire/msginv.go MsgInv.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5)
github.com/conformal/btcwire/common.go writeElements 100.00% (5/5)
github.com/conformal/btcwire/shahash.go ShaHash.SetBytes 100.00% (5/5)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.AddBlockHeader 100.00% (5/5)
github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.AddBlockLocatorHash 100.00% (5/5)
github.com/conformal/btcwire/msggetdata.go MsgGetData.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddress 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddresses 100.00% (5/5)
github.com/conformal/btcwire/msggetdata.go MsgGetData.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/common.go writeElements 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.AddBlockLocatorHash 100.00% (5/5)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.AddBlockHeader 100.00% (5/5)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcDecode 100.00% (4/4)
github.com/conformal/btcwire/netaddress.go maxNetAddressPayload 100.00% (4/4)
github.com/conformal/btcwire/shahash.go ShaHash.String 100.00% (4/4)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcEncode 100.00% (4/4)
github.com/conformal/btcwire/msgpong.go MsgPong.MaxPayloadLength 100.00% (4/4)
github.com/conformal/btcwire/msgping.go MsgPing.MaxPayloadLength 100.00% (4/4)
github.com/conformal/btcwire/msgaddr.go MsgAddr.MaxPayloadLength 100.00% (3/3)
github.com/conformal/btcwire/invvect.go InvType.String 100.00% (3/3)
github.com/conformal/btcwire/netaddress.go NetAddress.HasService 100.00% (3/3)
github.com/conformal/btcwire/msgblock.go MsgBlock.AddTransaction 100.00% (3/3)
github.com/conformal/btcwire/netaddress.go maxNetAddressPayload 100.00% (4/4)
github.com/conformal/btcwire/shahash.go ShaHash.Bytes 100.00% (3/3)
github.com/conformal/btcwire/msgblock.go MsgBlock.AddTransaction 100.00% (3/3)
github.com/conformal/btcwire/msgaddr.go MsgAddr.MaxPayloadLength 100.00% (3/3)
github.com/conformal/btcwire/netaddress.go NetAddress.HasService 100.00% (3/3)
github.com/conformal/btcwire/msgversion.go MsgVersion.HasService 100.00% (3/3)
github.com/conformal/btcwire/invvect.go InvType.String 100.00% (3/3)
github.com/conformal/btcwire/netaddress.go NetAddress.SetAddress 100.00% (2/2)
github.com/conformal/btcwire/msgblock.go MsgBlock.ClearTransactions 100.00% (2/2)
github.com/conformal/btcwire/msgverack.go MsgVerAck.BtcEncode 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.BtcDecode 100.00% (1/1)
github.com/conformal/btcwire/msgalert.go MsgAlert.Command 100.00% (1/1)
github.com/conformal/btcwire/blockheader.go NewBlockHeader 100.00% (1/1)
github.com/conformal/btcwire/common.go readElement 100.00% (1/1)
github.com/conformal/btcwire/common.go writeElement 100.00% (1/1)
github.com/conformal/btcwire/common.go RandomUint64 100.00% (1/1)
github.com/conformal/btcwire/invvect.go NewInvVect 100.00% (1/1)
github.com/conformal/btcwire/msgalert.go MsgAlert.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/shahash.go ShaHash.IsEqual 100.00% (1/1)
github.com/conformal/btcwire/msgaddr.go MsgAddr.ClearAddresses 100.00% (1/1)
github.com/conformal/btcwire/msgaddr.go MsgAddr.Command 100.00% (1/1)
github.com/conformal/btcwire/msgaddr.go NewMsgAddr 100.00% (1/1)
github.com/conformal/btcwire/blockheader.go NewBlockHeader 100.00% (1/1)
github.com/conformal/btcwire/msgalert.go MsgAlert.Command 100.00% (1/1)
github.com/conformal/btcwire/msgalert.go MsgAlert.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgalert.go NewMsgAlert 100.00% (1/1)
github.com/conformal/btcwire/msgblock.go MsgBlock.Command 100.00% (1/1)
github.com/conformal/btcwire/msgblock.go MsgBlock.MaxPayloadLength 100.00% (1/1)
@ -59,19 +56,25 @@ github.com/conformal/btcwire/msggetaddr.go MsgGetAddr.BtcEncode 100.00% (1/1
github.com/conformal/btcwire/msggetaddr.go MsgGetAddr.Command 100.00% (1/1)
github.com/conformal/btcwire/msggetaddr.go MsgGetAddr.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msggetaddr.go NewMsgGetAddr 100.00% (1/1)
github.com/conformal/btcwire/netaddress.go NetAddress.AddService 100.00% (1/1)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.Command 100.00% (1/1)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msggetblocks.go NewMsgGetBlocks 100.00% (1/1)
github.com/conformal/btcwire/msggetdata.go MsgGetData.Command 100.00% (1/1)
github.com/conformal/btcwire/msggetdata.go MsgGetData.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msggetdata.go NewMsgGetData 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go NewMsgVersion 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.Command 100.00% (1/1)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msggetheaders.go NewMsgGetHeaders 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.Command 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.Command 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go NewMsgHeaders 100.00% (1/1)
github.com/conformal/btcwire/msginv.go MsgInv.Command 100.00% (1/1)
github.com/conformal/btcwire/msginv.go MsgInv.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msginv.go NewMsgInv 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.Command 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go NewMsgMemPool 100.00% (1/1)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.Command 100.00% (1/1)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgnotfound.go NewMsgNotFound 100.00% (1/1)
github.com/conformal/btcwire/msgping.go MsgPing.Command 100.00% (1/1)
@ -83,28 +86,25 @@ github.com/conformal/btcwire/msgtx.go NewTxIn 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go NewTxOut 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go MsgTx.AddTxIn 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go MsgTx.AddTxOut 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.Command 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go MsgTx.Command 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go MsgTx.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgtx.go NewMsgTx 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.Command 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgheaders.go NewMsgHeaders 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.AddService 100.00% (1/1)
github.com/conformal/btcwire/msginv.go MsgInv.Command 100.00% (1/1)
github.com/conformal/btcwire/msginv.go MsgInv.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msginv.go NewMsgInv 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.Command 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgmempool.go NewMsgMemPool 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go NewMsgVerAck 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.BtcDecode 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.BtcEncode 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.Command 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go MsgVerAck.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.Command 100.00% (1/1)
github.com/conformal/btcwire/msgverack.go NewMsgVerAck 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.AddService 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.Command 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go MsgVersion.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msgversion.go NewMsgVersion 100.00% (1/1)
github.com/conformal/btcwire/netaddress.go NetAddress.AddService 100.00% (1/1)
github.com/conformal/btcwire/shahash.go ShaHash.IsEqual 100.00% (1/1)
github.com/conformal/btcwire/message.go makeEmptyMessage 95.00% (19/20)
github.com/conformal/btcwire/msgtx.go MsgTx.TxSha 85.71% (6/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcDecode 85.71% (6/7)
github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 85.71% (6/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcEncode 85.71% (6/7)
github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 85.71% (6/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcDecode 85.71% (6/7)
github.com/conformal/btcwire/msgtx.go MsgTx.TxSha 85.71% (6/7)
github.com/conformal/btcwire/netaddress.go readNetAddress 85.00% (17/20)
github.com/conformal/btcwire/blockheader.go readBlockHeader 80.00% (8/10)
github.com/conformal/btcwire/msgblock.go MsgBlock.BtcDecode 80.00% (8/10)
@ -115,14 +115,14 @@ github.com/conformal/btcwire/msgblock.go MsgBlock.BtcEncode 77.78% (7/9)
github.com/conformal/btcwire/msgtx.go readTxIn 76.47% (13/17)
github.com/conformal/btcwire/msgtx.go MsgTx.BtcDecode 76.00% (19/25)
github.com/conformal/btcwire/msgtx.go readTxOut 75.00% (9/12)
github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 75.00% (6/8)
github.com/conformal/btcwire/blockheader.go writeBlockHeader 75.00% (6/8)
github.com/conformal/btcwire/msgalert.go MsgAlert.BtcDecode 75.00% (6/8)
github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 75.00% (6/8)
github.com/conformal/btcwire/msgalert.go MsgAlert.BtcEncode 75.00% (6/8)
github.com/conformal/btcwire/invvect.go readInvVect 75.00% (3/4)
github.com/conformal/btcwire/blockheader.go writeBlockHeader 75.00% (6/8)
github.com/conformal/btcwire/msgtx.go writeOutPoint 75.00% (3/4)
github.com/conformal/btcwire/msgtx.go readOutPoint 75.00% (3/4)
github.com/conformal/btcwire/invvect.go readInvVect 75.00% (3/4)
github.com/conformal/btcwire/invvect.go writeInvVect 75.00% (3/4)
github.com/conformal/btcwire/msgtx.go readOutPoint 75.00% (3/4)
github.com/conformal/btcwire/msgtx.go MsgTx.BtcEncode 73.91% (17/23)
github.com/conformal/btcwire/msgtx.go writeTxIn 73.33% (11/15)
github.com/conformal/btcwire/msgtx.go writeTxOut 72.73% (8/11)
@ -137,16 +137,17 @@ github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcDecode 68.42%
github.com/conformal/btcwire/msgversion.go MsgVersion.BtcDecode 68.00% (17/25)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.BtcEncode 66.67% (12/18)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcEncode 66.67% (12/18)
github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcEncode 66.67% (8/12)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcEncode 66.67% (8/12)
github.com/conformal/btcwire/msginv.go MsgInv.BtcEncode 66.67% (8/12)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcEncode 66.67% (8/12)
github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcEncode 66.67% (8/12)
github.com/conformal/btcwire/msgversion.go MsgVersion.BtcEncode 63.64% (14/22)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcDecode 62.50% (10/16)
github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcEncode 60.00% (9/15)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcEncode 60.00% (9/15)
github.com/conformal/btcwire/message.go ReadMessage 57.14% (4/7)
github.com/conformal/btcwire/message.go readMessage 53.12% (17/32)
github.com/conformal/btcwire/message.go ReadMessage 54.55% (18/33)
github.com/conformal/btcwire/msgblock.go MsgBlock.BtcDecodeTxLoc 0.00% (0/16)
github.com/conformal/btcwire/message.go discardInput 0.00% (0/10)
github.com/conformal/btcwire --------------------------------- 78.69% (735/934)
github.com/conformal/btcwire/error.go MessageError.Error 0.00% (0/1)
github.com/conformal/btcwire/error.go messageError 0.00% (0/1)
github.com/conformal/btcwire --------------------------------- 78.71% (732/930)