1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 // This file implements the fastboot UDP protocol; see fastboot_protocol.txt for documentation.
30 
31 #include "udp.h"
32 
33 #include <errno.h>
34 #include <stdio.h>
35 
36 #include <list>
37 #include <memory>
38 #include <vector>
39 
40 #include <android-base/macros.h>
41 #include <android-base/stringprintf.h>
42 
43 #include "socket.h"
44 
45 namespace udp {
46 
47 using namespace internal;
48 
49 constexpr size_t kMinPacketSize = 512;
50 constexpr size_t kHeaderSize = 4;
51 
52 enum Index {
53     kIndexId = 0,
54     kIndexFlags = 1,
55     kIndexSeqH = 2,
56     kIndexSeqL = 3,
57 };
58 
59 // Extracts a big-endian uint16_t from a byte array.
ExtractUint16(const uint8_t * bytes)60 static uint16_t ExtractUint16(const uint8_t* bytes) {
61     return (static_cast<uint16_t>(bytes[0]) << 8) | bytes[1];
62 }
63 
64 // Packet header handling.
65 class Header {
66   public:
67     Header();
68     ~Header() = default;
69 
id() const70     uint8_t id() const { return bytes_[kIndexId]; }
bytes() const71     const uint8_t* bytes() const { return bytes_; }
72 
73     void Set(uint8_t id, uint16_t sequence, Flag flag);
74 
75     // Checks whether |response| is a match for this header.
76     bool Matches(const uint8_t* response);
77 
78   private:
79     uint8_t bytes_[kHeaderSize];
80 };
81 
Header()82 Header::Header() {
83     Set(kIdError, 0, kFlagNone);
84 }
85 
Set(uint8_t id,uint16_t sequence,Flag flag)86 void Header::Set(uint8_t id, uint16_t sequence, Flag flag) {
87     bytes_[kIndexId] = id;
88     bytes_[kIndexFlags] = flag;
89     bytes_[kIndexSeqH] = sequence >> 8;
90     bytes_[kIndexSeqL] = sequence;
91 }
92 
Matches(const uint8_t * response)93 bool Header::Matches(const uint8_t* response) {
94     // Sequence numbers must be the same to match, but the response ID can either be the same
95     // or an error response which is always accepted.
96     return bytes_[kIndexSeqH] == response[kIndexSeqH] &&
97            bytes_[kIndexSeqL] == response[kIndexSeqL] &&
98            (bytes_[kIndexId] == response[kIndexId] || response[kIndexId] == kIdError);
99 }
100 
101 // Implements the Transport interface to work with the fastboot engine.
102 class UdpTransport : public Transport {
103   public:
104     // Factory function so we can return nullptr if initialization fails.
105     static std::unique_ptr<UdpTransport> NewTransport(std::unique_ptr<Socket> socket,
106                                                       std::string* error);
107     ~UdpTransport() override = default;
108 
109     ssize_t Read(void* data, size_t length) override;
110     ssize_t Write(const void* data, size_t length) override;
111     int Close() override;
112     int Reset() override;
113 
114   private:
UdpTransport(std::unique_ptr<Socket> socket)115     explicit UdpTransport(std::unique_ptr<Socket> socket) : socket_(std::move(socket)) {}
116 
117     // Performs the UDP initialization procedure. Returns true on success.
118     bool InitializeProtocol(std::string* error);
119 
120     // Sends |length| bytes from |data| and waits for the response packet up to |attempts| times.
121     // Continuation packets are handled automatically and any return data is written to |rx_data|.
122     // Excess bytes that cannot fit in |rx_data| are dropped.
123     // On success, returns the number of response data bytes received, which may be greater than
124     // |rx_length|. On failure, returns -1 and fills |error| on failure.
125     ssize_t SendData(Id id, const uint8_t* tx_data, size_t tx_length, uint8_t* rx_data,
126                      size_t rx_length, int attempts, std::string* error);
127 
128     // Helper for SendData(); sends a single packet and handles the response. |header| specifies
129     // the initial outgoing packet information but may be modified by this function.
130     ssize_t SendSinglePacketHelper(Header* header, const uint8_t* tx_data, size_t tx_length,
131                                    uint8_t* rx_data, size_t rx_length, int attempts,
132                                    std::string* error);
133 
134     std::unique_ptr<Socket> socket_;
135     int sequence_ = -1;
136     size_t max_data_length_ = kMinPacketSize - kHeaderSize;
137     std::vector<uint8_t> rx_packet_;
138 
139     DISALLOW_COPY_AND_ASSIGN(UdpTransport);
140 };
141 
NewTransport(std::unique_ptr<Socket> socket,std::string * error)142 std::unique_ptr<UdpTransport> UdpTransport::NewTransport(std::unique_ptr<Socket> socket,
143                                                          std::string* error) {
144     std::unique_ptr<UdpTransport> transport(new UdpTransport(std::move(socket)));
145 
146     if (!transport->InitializeProtocol(error)) {
147         return nullptr;
148     }
149 
150     return transport;
151 }
152 
InitializeProtocol(std::string * error)153 bool UdpTransport::InitializeProtocol(std::string* error) {
154     uint8_t rx_data[4];
155 
156     sequence_ = 0;
157     rx_packet_.resize(kMinPacketSize);
158 
159     // First send the query packet to sync with the target. Only attempt this a small number of
160     // times so we can fail out quickly if the target isn't available.
161     ssize_t rx_bytes = SendData(kIdDeviceQuery, nullptr, 0, rx_data, sizeof(rx_data),
162                                 kMaxConnectAttempts, error);
163     if (rx_bytes == -1) {
164         return false;
165     } else if (rx_bytes < 2) {
166         *error = "invalid query response from target";
167         return false;
168     }
169     // The first two bytes contain the next expected sequence number.
170     sequence_ = ExtractUint16(rx_data);
171 
172     // Now send the initialization packet with our version and maximum packet size.
173     uint8_t init_data[] = {kProtocolVersion >> 8, kProtocolVersion & 0xFF,
174                            kHostMaxPacketSize >> 8, kHostMaxPacketSize & 0xFF};
175     rx_bytes = SendData(kIdInitialization, init_data, sizeof(init_data), rx_data, sizeof(rx_data),
176                         kMaxTransmissionAttempts, error);
177     if (rx_bytes == -1) {
178         return false;
179     } else if (rx_bytes < 4) {
180         *error = "invalid initialization response from target";
181         return false;
182     }
183 
184     // The first two data bytes contain the version, the second two bytes contain the target max
185     // supported packet size, which must be at least 512 bytes.
186     uint16_t version = ExtractUint16(rx_data);
187     if (version < kProtocolVersion) {
188         *error = android::base::StringPrintf("target reported invalid protocol version %d",
189                                              version);
190         return false;
191     }
192     uint16_t packet_size = ExtractUint16(rx_data + 2);
193     if (packet_size < kMinPacketSize) {
194         *error = android::base::StringPrintf("target reported invalid packet size %d", packet_size);
195         return false;
196     }
197 
198     packet_size = std::min(kHostMaxPacketSize, packet_size);
199     max_data_length_ = packet_size - kHeaderSize;
200     rx_packet_.resize(packet_size);
201 
202     return true;
203 }
204 
205 // SendData() is just responsible for chunking |data| into packets until it's all been sent.
206 // Per-packet timeout/retransmission logic is done in SendSinglePacketHelper().
SendData(Id id,const uint8_t * tx_data,size_t tx_length,uint8_t * rx_data,size_t rx_length,int attempts,std::string * error)207 ssize_t UdpTransport::SendData(Id id, const uint8_t* tx_data, size_t tx_length, uint8_t* rx_data,
208                                size_t rx_length, int attempts, std::string* error) {
209     if (socket_ == nullptr) {
210         *error = "socket is closed";
211         return -1;
212     }
213 
214     Header header;
215     size_t packet_data_length;
216     ssize_t ret = 0;
217     // We often send header-only packets with no data as part of the protocol, so always send at
218     // least once even if |length| == 0, then repeat until we've sent all of |data|.
219     do {
220         // Set the continuation flag and truncate packet data if needed.
221         if (tx_length > max_data_length_) {
222             packet_data_length = max_data_length_;
223             header.Set(id, sequence_, kFlagContinuation);
224         } else {
225             packet_data_length = tx_length;
226             header.Set(id, sequence_, kFlagNone);
227         }
228 
229         ssize_t bytes = SendSinglePacketHelper(&header, tx_data, packet_data_length, rx_data,
230                                                rx_length, attempts, error);
231 
232         // Advance our read and write buffers for the next packet. Keep going even if we run out
233         // of receive buffer space so we can detect overflows.
234         if (bytes == -1) {
235             return -1;
236         } else if (static_cast<size_t>(bytes) < rx_length) {
237             rx_data += bytes;
238             rx_length -= bytes;
239         } else {
240             rx_data = nullptr;
241             rx_length = 0;
242         }
243 
244         tx_length -= packet_data_length;
245         tx_data += packet_data_length;
246 
247         ret += bytes;
248     } while (tx_length > 0);
249 
250     return ret;
251 }
252 
SendSinglePacketHelper(Header * header,const uint8_t * tx_data,size_t tx_length,uint8_t * rx_data,size_t rx_length,const int attempts,std::string * error)253 ssize_t UdpTransport::SendSinglePacketHelper(
254         Header* header, const uint8_t* tx_data, size_t tx_length, uint8_t* rx_data,
255         size_t rx_length, const int attempts, std::string* error) {
256     ssize_t total_data_bytes = 0;
257     error->clear();
258 
259     int attempts_left = attempts;
260     while (attempts_left > 0) {
261         if (!socket_->Send({{header->bytes(), kHeaderSize}, {tx_data, tx_length}})) {
262             *error = Socket::GetErrorMessage();
263             return -1;
264         }
265 
266         // Keep receiving until we get a matching response or we timeout.
267         ssize_t bytes = 0;
268         do {
269             bytes = socket_->Receive(rx_packet_.data(), rx_packet_.size(), kResponseTimeoutMs);
270             if (bytes == -1) {
271                 if (socket_->ReceiveTimedOut()) {
272                     break;
273                 }
274                 *error = Socket::GetErrorMessage();
275                 return -1;
276             } else if (bytes < static_cast<ssize_t>(kHeaderSize)) {
277                 *error = "protocol error: incomplete header";
278                 return -1;
279             }
280         } while (!header->Matches(rx_packet_.data()));
281 
282         if (socket_->ReceiveTimedOut()) {
283             --attempts_left;
284             continue;
285         }
286         ++sequence_;
287 
288         // Save to |error| or |rx_data| as appropriate.
289         if (rx_packet_[kIndexId] == kIdError) {
290             error->append(rx_packet_.data() + kHeaderSize, rx_packet_.data() + bytes);
291         } else {
292             total_data_bytes += bytes - kHeaderSize;
293             size_t rx_data_bytes = std::min<size_t>(bytes - kHeaderSize, rx_length);
294             if (rx_data_bytes > 0) {
295                 memcpy(rx_data, rx_packet_.data() + kHeaderSize, rx_data_bytes);
296                 rx_data += rx_data_bytes;
297                 rx_length -= rx_data_bytes;
298             }
299         }
300 
301         // If the response has a continuation flag we need to prompt for more data by sending
302         // an empty packet.
303         if (rx_packet_[kIndexFlags] & kFlagContinuation) {
304             // We got a valid response so reset our attempt counter.
305             attempts_left = attempts;
306             header->Set(rx_packet_[kIndexId], sequence_, kFlagNone);
307             tx_data = nullptr;
308             tx_length = 0;
309             continue;
310         }
311 
312         break;
313     }
314 
315     if (attempts_left <= 0) {
316         *error = "no response from target";
317         return -1;
318     }
319 
320     if (rx_packet_[kIndexId] == kIdError) {
321         *error = "target reported error: " + *error;
322         return -1;
323     }
324 
325     return total_data_bytes;
326 }
327 
Read(void * data,size_t length)328 ssize_t UdpTransport::Read(void* data, size_t length) {
329     // Read from the target by sending an empty packet.
330     std::string error;
331     ssize_t bytes = SendData(kIdFastboot, nullptr, 0, reinterpret_cast<uint8_t*>(data), length,
332                              kMaxTransmissionAttempts, &error);
333 
334     if (bytes == -1) {
335         fprintf(stderr, "UDP error: %s\n", error.c_str());
336         return -1;
337     } else if (static_cast<size_t>(bytes) > length) {
338         // Fastboot protocol error: the target sent more data than our fastboot engine was prepared
339         // to receive.
340         fprintf(stderr, "UDP error: receive overflow, target sent too much fastboot data\n");
341         return -1;
342     }
343 
344     return bytes;
345 }
346 
Write(const void * data,size_t length)347 ssize_t UdpTransport::Write(const void* data, size_t length) {
348     std::string error;
349     ssize_t bytes = SendData(kIdFastboot, reinterpret_cast<const uint8_t*>(data), length, nullptr,
350                              0, kMaxTransmissionAttempts, &error);
351 
352     if (bytes == -1) {
353         fprintf(stderr, "UDP error: %s\n", error.c_str());
354         return -1;
355     } else if (bytes > 0) {
356         // UDP protocol error: only empty ACK packets are allowed when writing to a device.
357         fprintf(stderr, "UDP error: target sent fastboot data out-of-turn\n");
358         return -1;
359     }
360 
361     return length;
362 }
363 
Close()364 int UdpTransport::Close() {
365     if (socket_ == nullptr) {
366         return 0;
367     }
368 
369     int result = socket_->Close();
370     socket_.reset();
371     return result;
372 }
373 
Reset()374 int UdpTransport::Reset() {
375     return 0;
376 }
377 
Connect(const std::string & hostname,int port,std::string * error)378 std::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) {
379     return internal::Connect(Socket::NewClient(Socket::Protocol::kUdp, hostname, port, error),
380                              error);
381 }
382 
383 namespace internal {
384 
Connect(std::unique_ptr<Socket> sock,std::string * error)385 std::unique_ptr<Transport> Connect(std::unique_ptr<Socket> sock, std::string* error) {
386     if (sock == nullptr) {
387         // If Socket creation failed |error| is already set.
388         return nullptr;
389     }
390 
391     return UdpTransport::NewTransport(std::move(sock), error);
392 }
393 
394 }  // namespace internal
395 
396 }  // namespace udp
397