fastboot: fix TCP protocol version check.

Currently the TCP handshake fails if the device TCP protocol version
doesn't match the host exactly, but the protocol is supposed to allow
for forwards compatibility by accepting any protocol version >= itself.
That way the other side can potentially lower its protocol to match and
keep going.

This CL fixes the protocol version check and adds corresponding unit
tests.

Bug: http://b/27220700
Change-Id: Ib17f0a55eb910105a27609bc94bf76a30442e92e
This commit is contained in:
David Pursell 2016-02-17 10:00:09 -08:00
parent 8c09555aac
commit aad72a533f
2 changed files with 18 additions and 5 deletions

View file

@ -28,6 +28,7 @@
#include "tcp.h"
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
namespace tcp {
@ -98,7 +99,8 @@ bool TcpTransport::InitializeProtocol(std::string* error) {
return false;
}
char buffer[kHandshakeLength];
char buffer[kHandshakeLength + 1];
buffer[kHandshakeLength] = '\0';
if (socket_->ReceiveAll(buffer, kHandshakeLength, kHandshakeTimeoutMs) != kHandshakeLength) {
*error = android::base::StringPrintf(
"No initialization message received (%s). Target may not support TCP fastboot",
@ -111,9 +113,10 @@ bool TcpTransport::InitializeProtocol(std::string* error) {
return false;
}
if (memcmp(buffer + 2, "01", 2) != 0) {
int version = 0;
if (!android::base::ParseInt(buffer + 2, &version) || version < kProtocolVersion) {
*error = android::base::StringPrintf("Unknown TCP protocol version %s (host version %02d)",
std::string(buffer + 2, 2).c_str(), kProtocolVersion);
buffer + 2, kProtocolVersion);
return false;
}

View file

@ -42,6 +42,16 @@ TEST(TcpConnectTest, TestSuccess) {
EXPECT_EQ("", error);
}
TEST(TcpConnectTest, TestNewerVersionSuccess) {
std::unique_ptr<SocketMock> mock(new SocketMock);
mock->ExpectSend("FB01");
mock->AddReceive("FB99");
std::string error;
EXPECT_NE(nullptr, tcp::internal::Connect(std::move(mock), &error));
EXPECT_EQ("", error);
}
TEST(TcpConnectTest, TestSendFailure) {
std::unique_ptr<SocketMock> mock(new SocketMock);
mock->ExpectSendFailure("FB01");
@ -74,11 +84,11 @@ TEST(TcpConnectTest, TestBadResponseFailure) {
TEST(TcpConnectTest, TestUnknownVersionFailure) {
std::unique_ptr<SocketMock> mock(new SocketMock);
mock->ExpectSend("FB01");
mock->AddReceive("FB02");
mock->AddReceive("FB00");
std::string error;
EXPECT_EQ(nullptr, tcp::internal::Connect(std::move(mock), &error));
EXPECT_EQ("Unknown TCP protocol version 02 (host version 01)", error);
EXPECT_EQ("Unknown TCP protocol version 00 (host version 01)", error);
}
// Fixture to configure a SocketMock for a successful TCP connection.