Merge "Increase size of the the adb packets sent over the wire"
This commit is contained in:
commit
571c8d713c
14 changed files with 93 additions and 60 deletions
|
|
@ -334,10 +334,10 @@ void send_connect(atransport *t)
|
||||||
D("Calling send_connect \n");
|
D("Calling send_connect \n");
|
||||||
apacket *cp = get_apacket();
|
apacket *cp = get_apacket();
|
||||||
cp->msg.command = A_CNXN;
|
cp->msg.command = A_CNXN;
|
||||||
cp->msg.arg0 = A_VERSION;
|
cp->msg.arg0 = t->get_protocol_version();
|
||||||
cp->msg.arg1 = MAX_PAYLOAD;
|
cp->msg.arg1 = t->get_max_payload();
|
||||||
cp->msg.data_length = fill_connect_data((char *)cp->data,
|
cp->msg.data_length = fill_connect_data((char *)cp->data,
|
||||||
sizeof(cp->data));
|
MAX_PAYLOAD_V1);
|
||||||
send_packet(cp, t);
|
send_packet(cp, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,12 +424,12 @@ void handle_packet(apacket *p, atransport *t)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
|
case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
|
||||||
/* XXX verify version, etc */
|
|
||||||
if(t->connection_state != kCsOffline) {
|
if(t->connection_state != kCsOffline) {
|
||||||
t->connection_state = kCsOffline;
|
t->connection_state = kCsOffline;
|
||||||
handle_offline(t);
|
handle_offline(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t->update_version(p->msg.arg0, p->msg.arg1);
|
||||||
parse_banner(reinterpret_cast<const char*>(p->data), t);
|
parse_banner(reinterpret_cast<const char*>(p->data), t);
|
||||||
|
|
||||||
if (HOST || !auth_required) {
|
if (HOST || !auth_required) {
|
||||||
|
|
|
||||||
15
adb/adb.h
15
adb/adb.h
|
|
@ -25,7 +25,9 @@
|
||||||
#include "adb_trace.h"
|
#include "adb_trace.h"
|
||||||
#include "fdevent.h"
|
#include "fdevent.h"
|
||||||
|
|
||||||
#define MAX_PAYLOAD 4096
|
constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024;
|
||||||
|
constexpr size_t MAX_PAYLOAD_V2 = 256 * 1024;
|
||||||
|
constexpr size_t MAX_PAYLOAD = MAX_PAYLOAD_V2;
|
||||||
|
|
||||||
#define A_SYNC 0x434e5953
|
#define A_SYNC 0x434e5953
|
||||||
#define A_CNXN 0x4e584e43
|
#define A_CNXN 0x4e584e43
|
||||||
|
|
@ -137,6 +139,8 @@ struct asocket {
|
||||||
|
|
||||||
/* A socket is bound to atransport */
|
/* A socket is bound to atransport */
|
||||||
atransport *transport;
|
atransport *transport;
|
||||||
|
|
||||||
|
size_t get_max_payload() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -193,6 +197,8 @@ public:
|
||||||
atransport() {
|
atransport() {
|
||||||
auth_fde = {};
|
auth_fde = {};
|
||||||
transport_fde = {};
|
transport_fde = {};
|
||||||
|
protocol_version = A_VERSION;
|
||||||
|
max_payload = MAX_PAYLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~atransport() {}
|
virtual ~atransport() {}
|
||||||
|
|
@ -234,7 +240,14 @@ public:
|
||||||
|
|
||||||
const char* connection_state_name() const;
|
const char* connection_state_name() const;
|
||||||
|
|
||||||
|
void update_version(int version, size_t payload);
|
||||||
|
int get_protocol_version() const;
|
||||||
|
size_t get_max_payload() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int protocol_version;
|
||||||
|
size_t max_payload;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(atransport);
|
DISALLOW_COPY_AND_ASSIGN(atransport);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ void send_auth_publickey(atransport *t)
|
||||||
apacket *p = get_apacket();
|
apacket *p = get_apacket();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = adb_auth_get_userkey(p->data, sizeof(p->data));
|
ret = adb_auth_get_userkey(p->data, MAX_PAYLOAD_V1);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
D("Failed to get user public key\n");
|
D("Failed to get user public key\n");
|
||||||
put_apacket(p);
|
put_apacket(p);
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ static bool needs_retry = false;
|
||||||
static void read_keys(const char *file, struct listnode *list)
|
static void read_keys(const char *file, struct listnode *list)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char buf[MAX_PAYLOAD];
|
char buf[MAX_PAYLOAD_V1];
|
||||||
char *sep;
|
char *sep;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -191,7 +191,7 @@ static void adb_auth_event(int fd, unsigned events, void *data)
|
||||||
|
|
||||||
void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t)
|
void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t)
|
||||||
{
|
{
|
||||||
char msg[MAX_PAYLOAD];
|
char msg[MAX_PAYLOAD_V1];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!usb_transport) {
|
if (!usb_transport) {
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ static int write_public_keyfile(RSA *private_key, const char *private_key_path)
|
||||||
{
|
{
|
||||||
RSAPublicKey pkey;
|
RSAPublicKey pkey;
|
||||||
FILE *outfile = NULL;
|
FILE *outfile = NULL;
|
||||||
char path[PATH_MAX], info[MAX_PAYLOAD];
|
char path[PATH_MAX], info[MAX_PAYLOAD_V1];
|
||||||
uint8_t* encoded = nullptr;
|
uint8_t* encoded = nullptr;
|
||||||
size_t encoded_length;
|
size_t encoded_length;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
|
||||||
|
|
@ -608,7 +608,7 @@ jdwp_socket_ready( asocket* s )
|
||||||
*/
|
*/
|
||||||
if (jdwp->pass == 0) {
|
if (jdwp->pass == 0) {
|
||||||
apacket* p = get_apacket();
|
apacket* p = get_apacket();
|
||||||
p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD);
|
p->len = jdwp_process_list((char*)p->data, s->get_max_payload());
|
||||||
peer->enqueue(peer, p);
|
peer->enqueue(peer, p);
|
||||||
jdwp->pass = 1;
|
jdwp->pass = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -695,7 +695,7 @@ jdwp_tracker_ready( asocket* s )
|
||||||
if (t->need_update) {
|
if (t->need_update) {
|
||||||
apacket* p = get_apacket();
|
apacket* p = get_apacket();
|
||||||
t->need_update = 0;
|
t->need_update = 0;
|
||||||
p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data));
|
p->len = jdwp_process_list_msg((char*)p->data, s->get_max_payload());
|
||||||
s->peer->enqueue(s->peer, p);
|
s->peer->enqueue(s->peer, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,14 @@ The version is used to ensure protocol compatibility and maxdata
|
||||||
declares the maximum message body size that the remote system
|
declares the maximum message body size that the remote system
|
||||||
is willing to accept.
|
is willing to accept.
|
||||||
|
|
||||||
Currently, version=0x01000000 and maxdata=4096
|
Currently, version=0x01000000 and maxdata=256*1024. Older versions of adb
|
||||||
|
hard-coded maxdata=4096, so CONNECT and AUTH packets sent to a device must not
|
||||||
|
be larger than that because they're sent before the CONNECT from the device
|
||||||
|
that tells the adb server what maxdata the device can support.
|
||||||
|
|
||||||
Both sides send a CONNECT message when the connection between them is
|
Both sides send a CONNECT message when the connection between them is
|
||||||
established. Until a CONNECT message is received no other messages may
|
established. Until a CONNECT message is received no other messages may
|
||||||
be sent. Any messages received before a CONNECT message MUST be ignored.
|
be sent. Any messages received before a CONNECT message MUST be ignored.
|
||||||
|
|
||||||
If a CONNECT message is received with an unknown version or insufficiently
|
If a CONNECT message is received with an unknown version or insufficiently
|
||||||
large maxdata value, the connection with the other side must be closed.
|
large maxdata value, the connection with the other side must be closed.
|
||||||
|
|
|
||||||
|
|
@ -330,8 +330,9 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s)
|
||||||
if (ev & FDE_READ) {
|
if (ev & FDE_READ) {
|
||||||
apacket *p = get_apacket();
|
apacket *p = get_apacket();
|
||||||
unsigned char *x = p->data;
|
unsigned char *x = p->data;
|
||||||
size_t avail = MAX_PAYLOAD;
|
const size_t max_payload = s->get_max_payload();
|
||||||
int r;
|
size_t avail = max_payload;
|
||||||
|
int r = 0;
|
||||||
int is_eof = 0;
|
int is_eof = 0;
|
||||||
|
|
||||||
while (avail > 0) {
|
while (avail > 0) {
|
||||||
|
|
@ -354,10 +355,10 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s)
|
||||||
}
|
}
|
||||||
D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
|
D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
|
||||||
s->id, s->fd, r, is_eof, s->fde.force_eof);
|
s->id, s->fd, r, is_eof, s->fde.force_eof);
|
||||||
if ((avail == MAX_PAYLOAD) || (s->peer == 0)) {
|
if ((avail == max_payload) || (s->peer == 0)) {
|
||||||
put_apacket(p);
|
put_apacket(p);
|
||||||
} else {
|
} else {
|
||||||
p->len = MAX_PAYLOAD - avail;
|
p->len = max_payload - avail;
|
||||||
|
|
||||||
r = s->peer->enqueue(s->peer, p);
|
r = s->peer->enqueue(s->peer, p);
|
||||||
D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd,
|
D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd,
|
||||||
|
|
@ -569,9 +570,9 @@ void connect_to_remote(asocket *s, const char *destination)
|
||||||
{
|
{
|
||||||
D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
|
D("Connect_to_remote call RS(%d) fd=%d\n", s->id, s->fd);
|
||||||
apacket *p = get_apacket();
|
apacket *p = get_apacket();
|
||||||
int len = strlen(destination) + 1;
|
size_t len = strlen(destination) + 1;
|
||||||
|
|
||||||
if(len > (MAX_PAYLOAD-1)) {
|
if(len > (s->get_max_payload()-1)) {
|
||||||
fatal("destination oversized");
|
fatal("destination oversized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -700,7 +701,7 @@ static int smart_socket_enqueue(asocket *s, apacket *p)
|
||||||
s->pkt_first = p;
|
s->pkt_first = p;
|
||||||
s->pkt_last = p;
|
s->pkt_last = p;
|
||||||
} else {
|
} else {
|
||||||
if((s->pkt_first->len + p->len) > MAX_PAYLOAD) {
|
if((s->pkt_first->len + p->len) > s->get_max_payload()) {
|
||||||
D("SS(%d): overflow\n", s->id);
|
D("SS(%d): overflow\n", s->id);
|
||||||
put_apacket(p);
|
put_apacket(p);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -901,3 +902,14 @@ void connect_to_smartsocket(asocket *s)
|
||||||
ss->peer = s;
|
ss->peer = s;
|
||||||
s->ready(s);
|
s->ready(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t asocket::get_max_payload() const {
|
||||||
|
size_t max_payload = MAX_PAYLOAD;
|
||||||
|
if (transport) {
|
||||||
|
max_payload = std::min(max_payload, transport->get_max_payload());
|
||||||
|
}
|
||||||
|
if (peer && peer->transport) {
|
||||||
|
max_payload = std::min(max_payload, peer->transport->get_max_payload());
|
||||||
|
}
|
||||||
|
return max_payload;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -835,6 +835,19 @@ const char* atransport::connection_state_name() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void atransport::update_version(int version, size_t payload) {
|
||||||
|
protocol_version = std::min(version, A_VERSION);
|
||||||
|
max_payload = std::min(payload, MAX_PAYLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
int atransport::get_protocol_version() const {
|
||||||
|
return protocol_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t atransport::get_max_payload() const {
|
||||||
|
return max_payload;
|
||||||
|
}
|
||||||
|
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
|
|
||||||
static void append_transport_info(std::string* result, const char* key,
|
static void append_transport_info(std::string* result, const char* key,
|
||||||
|
|
@ -1020,15 +1033,16 @@ void unregister_usb_transport(usb_handle *usb) {
|
||||||
#undef TRACE_TAG
|
#undef TRACE_TAG
|
||||||
#define TRACE_TAG TRACE_RWX
|
#define TRACE_TAG TRACE_RWX
|
||||||
|
|
||||||
int check_header(apacket *p)
|
int check_header(apacket *p, atransport *t)
|
||||||
{
|
{
|
||||||
if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
|
if(p->msg.magic != (p->msg.command ^ 0xffffffff)) {
|
||||||
D("check_header(): invalid magic\n");
|
D("check_header(): invalid magic\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->msg.data_length > MAX_PAYLOAD) {
|
if(p->msg.data_length > t->get_max_payload()) {
|
||||||
D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length);
|
D("check_header(): %u > atransport::max_payload = %zu\n",
|
||||||
|
p->msg.data_length, t->get_max_payload());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ void unregister_usb_transport(usb_handle* usb);
|
||||||
void unregister_transport(atransport* t);
|
void unregister_transport(atransport* t);
|
||||||
void unregister_all_tcp_transports();
|
void unregister_all_tcp_transports();
|
||||||
|
|
||||||
int check_header(apacket* p);
|
int check_header(apacket* p, atransport* t);
|
||||||
int check_data(apacket* p);
|
int check_data(apacket* p);
|
||||||
|
|
||||||
/* for MacOS X cleanup */
|
/* for MacOS X cleanup */
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ static int remote_read(apacket *p, atransport *t)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(check_header(p)) {
|
if(check_header(p, t)) {
|
||||||
D("bad header: terminated (data)\n");
|
D("bad header: terminated (data)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ static int remote_read(apacket *p, atransport *t)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(check_header(p)) {
|
if(check_header(p, t)) {
|
||||||
D("remote usb: check_header failed\n");
|
D("remote usb: check_header failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -439,36 +439,21 @@ fail:
|
||||||
|
|
||||||
int usb_write(usb_handle *h, const void *_data, int len)
|
int usb_write(usb_handle *h, const void *_data, int len)
|
||||||
{
|
{
|
||||||
unsigned char *data = (unsigned char*) _data;
|
|
||||||
int n;
|
|
||||||
int need_zero = 0;
|
|
||||||
|
|
||||||
D("++ usb_write ++\n");
|
D("++ usb_write ++\n");
|
||||||
if(h->zero_mask) {
|
|
||||||
|
unsigned char *data = (unsigned char*) _data;
|
||||||
|
int n = usb_bulk_write(h, data, len);
|
||||||
|
if(n != len) {
|
||||||
|
D("ERROR: n = %d, errno = %d (%s)\n",
|
||||||
|
n, errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(h->zero_mask && !(len & h->zero_mask)) {
|
||||||
/* if we need 0-markers and our transfer
|
/* if we need 0-markers and our transfer
|
||||||
** is an even multiple of the packet size,
|
** is an even multiple of the packet size,
|
||||||
** we make note of it
|
** then send the zero markers.
|
||||||
*/
|
*/
|
||||||
if(!(len & h->zero_mask)) {
|
|
||||||
need_zero = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(len > 0) {
|
|
||||||
int xfer = (len > 4096) ? 4096 : len;
|
|
||||||
|
|
||||||
n = usb_bulk_write(h, data, xfer);
|
|
||||||
if(n != xfer) {
|
|
||||||
D("ERROR: n = %d, errno = %d (%s)\n",
|
|
||||||
n, errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
len -= xfer;
|
|
||||||
data += xfer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(need_zero){
|
|
||||||
n = usb_bulk_write(h, _data, 0);
|
n = usb_bulk_write(h, _data, 0);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -484,7 +469,7 @@ int usb_read(usb_handle *h, void *_data, int len)
|
||||||
|
|
||||||
D("++ usb_read ++\n");
|
D("++ usb_read ++\n");
|
||||||
while(len > 0) {
|
while(len > 0) {
|
||||||
int xfer = (len > 4096) ? 4096 : len;
|
int xfer = len;
|
||||||
|
|
||||||
D("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
|
D("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
|
||||||
n = usb_bulk_read(h, data, xfer);
|
n = usb_bulk_read(h, data, xfer);
|
||||||
|
|
|
||||||
|
|
@ -213,14 +213,20 @@ static int usb_adb_write(usb_handle *h, const void *data, int len)
|
||||||
|
|
||||||
static int usb_adb_read(usb_handle *h, void *data, int len)
|
static int usb_adb_read(usb_handle *h, void *data, int len)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
|
|
||||||
D("about to read (fd=%d, len=%d)\n", h->fd, len);
|
D("about to read (fd=%d, len=%d)\n", h->fd, len);
|
||||||
n = unix_read(h->fd, data, len);
|
while (len > 0) {
|
||||||
if(n != len) {
|
// The kernel implementation of adb_read in f_adb.c doesn't support
|
||||||
D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
|
// reads larger then 4096 bytes. Read the data in 4096 byte chunks to
|
||||||
h->fd, n, errno, strerror(errno));
|
// avoid the issue. (The ffs implementation doesn't have this limit.)
|
||||||
return -1;
|
int bytes_to_read = len < 4096 ? len : 4096;
|
||||||
|
int n = unix_read(h->fd, data, bytes_to_read);
|
||||||
|
if (n != bytes_to_read) {
|
||||||
|
D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
|
||||||
|
h->fd, n, errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
len -= n;
|
||||||
|
data = ((char*)data) + n;
|
||||||
}
|
}
|
||||||
D("[ done fd=%d ]\n", h->fd);
|
D("[ done fd=%d ]\n", h->fd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue