blob: eb0ce85fb82cf0c5feb09ea9e0cb2240a8322268 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG SOCKETS
Dan Albert33134262015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Dan Albert76649012015-02-24 15:51:19 -080021#include <ctype.h>
22#include <errno.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023#include <stdio.h>
24#include <stdlib.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <string.h>
Dan Albert76649012015-02-24 15:51:19 -080026#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080027
Spencer Low363af562015-11-07 18:51:54 -080028#include <algorithm>
29
Dan Albert76649012015-02-24 15:51:19 -080030#if !ADB_HOST
31#include "cutils/properties.h"
32#endif
Dan Albert33134262015-03-19 15:21:08 -070033
34#include "adb.h"
35#include "adb_io.h"
Dan Albert76649012015-02-24 15:51:19 -080036#include "transport.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080037
38ADB_MUTEX_DEFINE( socket_list_lock );
39
40static void local_socket_close_locked(asocket *s);
41
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080042static unsigned local_socket_next_id = 1;
43
44static asocket local_socket_list = {
45 .next = &local_socket_list,
46 .prev = &local_socket_list,
47};
48
49/* the the list of currently closing local sockets.
50** these have no peer anymore, but still packets to
51** write to their fd.
52*/
53static asocket local_socket_closing_list = {
54 .next = &local_socket_closing_list,
55 .prev = &local_socket_closing_list,
56};
57
David 'Digit' Turner818d6412013-12-13 14:09:44 +010058// Parse the global list of sockets to find one with id |local_id|.
59// If |peer_id| is not 0, also check that it is connected to a peer
60// with id |peer_id|. Returns an asocket handle on success, NULL on failure.
61asocket *find_local_socket(unsigned local_id, unsigned peer_id)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080062{
63 asocket *s;
64 asocket *result = NULL;
65
66 adb_mutex_lock(&socket_list_lock);
André Goddard Rosa81828292010-06-12 11:40:20 -030067 for (s = local_socket_list.next; s != &local_socket_list; s = s->next) {
David 'Digit' Turner818d6412013-12-13 14:09:44 +010068 if (s->id != local_id)
69 continue;
70 if (peer_id == 0 || (s->peer && s->peer->id == peer_id)) {
André Goddard Rosa81828292010-06-12 11:40:20 -030071 result = s;
André Goddard Rosa81828292010-06-12 11:40:20 -030072 }
David 'Digit' Turner818d6412013-12-13 14:09:44 +010073 break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080074 }
75 adb_mutex_unlock(&socket_list_lock);
76
77 return result;
78}
79
80static void
81insert_local_socket(asocket* s, asocket* list)
82{
83 s->next = list;
84 s->prev = s->next->prev;
85 s->prev->next = s;
86 s->next->prev = s;
87}
88
89
90void install_local_socket(asocket *s)
91{
92 adb_mutex_lock(&socket_list_lock);
93
94 s->id = local_socket_next_id++;
David 'Digit' Turner818d6412013-12-13 14:09:44 +010095
96 // Socket ids should never be 0.
97 if (local_socket_next_id == 0)
98 local_socket_next_id = 1;
99
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800100 insert_local_socket(s, &local_socket_list);
101
102 adb_mutex_unlock(&socket_list_lock);
103}
104
105void remove_socket(asocket *s)
106{
107 // socket_list_lock should already be held
108 if (s->prev && s->next)
109 {
110 s->prev->next = s->next;
111 s->next->prev = s->prev;
112 s->next = 0;
113 s->prev = 0;
114 s->id = 0;
115 }
116}
117
118void close_all_sockets(atransport *t)
119{
120 asocket *s;
121
122 /* this is a little gross, but since s->close() *will* modify
123 ** the list out from under you, your options are limited.
124 */
125 adb_mutex_lock(&socket_list_lock);
126restart:
127 for(s = local_socket_list.next; s != &local_socket_list; s = s->next){
128 if(s->transport == t || (s->peer && s->peer->transport == t)) {
129 local_socket_close_locked(s);
130 goto restart;
131 }
132 }
133 adb_mutex_unlock(&socket_list_lock);
134}
135
136static int local_socket_enqueue(asocket *s, apacket *p)
137{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700138 D("LS(%d): enqueue %d", s->id, p->len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800139
140 p->ptr = p->data;
141
142 /* if there is already data queue'd, we will receive
143 ** events when it's time to write. just add this to
144 ** the tail
145 */
146 if(s->pkt_first) {
147 goto enqueue;
148 }
149
150 /* write as much as we can, until we
151 ** would block or there is an error/eof
152 */
153 while(p->len > 0) {
154 int r = adb_write(s->fd, p->ptr, p->len);
155 if(r > 0) {
156 p->len -= r;
157 p->ptr += r;
158 continue;
159 }
160 if((r == 0) || (errno != EAGAIN)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700161 D( "LS(%d): not ready, errno=%d: %s", s->id, errno, strerror(errno) );
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700162 put_apacket(p);
163 s->has_write_error = true;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800164 s->close(s);
165 return 1; /* not ready (error) */
166 } else {
167 break;
168 }
169 }
170
171 if(p->len == 0) {
172 put_apacket(p);
173 return 0; /* ready for more data */
174 }
175
176enqueue:
177 p->next = 0;
178 if(s->pkt_first) {
179 s->pkt_last->next = p;
180 } else {
181 s->pkt_first = p;
182 }
183 s->pkt_last = p;
184
185 /* make sure we are notified when we can drain the queue */
186 fdevent_add(&s->fde, FDE_WRITE);
187
188 return 1; /* not ready (backlog) */
189}
190
191static void local_socket_ready(asocket *s)
192{
Nanik Tolaramb627a0e2015-02-18 22:53:37 +1100193 /* far side is ready for data, pay attention to
194 readable events */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800195 fdevent_add(&s->fde, FDE_READ);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800196}
197
198static void local_socket_close(asocket *s)
199{
200 adb_mutex_lock(&socket_list_lock);
201 local_socket_close_locked(s);
202 adb_mutex_unlock(&socket_list_lock);
203}
204
205// be sure to hold the socket list lock when calling this
206static void local_socket_destroy(asocket *s)
207{
208 apacket *p, *n;
Benoit Gobyf366b362012-03-16 14:50:07 -0700209 int exit_on_close = s->exit_on_close;
210
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700211 D("LS(%d): destroying fde.fd=%d", s->id, s->fde.fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800212
213 /* IMPORTANT: the remove closes the fd
214 ** that belongs to this socket
215 */
216 fdevent_remove(&s->fde);
217
218 /* dispose of any unwritten data */
219 for(p = s->pkt_first; p; p = n) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700220 D("LS(%d): discarding %d bytes", s->id, p->len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800221 n = p->next;
222 put_apacket(p);
223 }
224 remove_socket(s);
225 free(s);
Benoit Gobyf366b362012-03-16 14:50:07 -0700226
227 if (exit_on_close) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700228 D("local_socket_destroy: exiting");
Benoit Gobyf366b362012-03-16 14:50:07 -0700229 exit(1);
230 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800231}
232
233
234static void local_socket_close_locked(asocket *s)
235{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700236 D("entered local_socket_close_locked. LS(%d) fd=%d", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800237 if(s->peer) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700238 D("LS(%d): closing peer. peer->id=%d peer->fd=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700239 s->id, s->peer->id, s->peer->fd);
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100240 /* Note: it's important to call shutdown before disconnecting from
241 * the peer, this ensures that remote sockets can still get the id
242 * of the local socket they're connected to, to send a CLOSE()
243 * protocol event. */
244 if (s->peer->shutdown)
245 s->peer->shutdown(s->peer);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800246 s->peer->peer = 0;
247 // tweak to avoid deadlock
Tom Marlin49f18572011-05-13 13:24:55 -0500248 if (s->peer->close == local_socket_close) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800249 local_socket_close_locked(s->peer);
Tom Marlin49f18572011-05-13 13:24:55 -0500250 } else {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800251 s->peer->close(s->peer);
Tom Marlin49f18572011-05-13 13:24:55 -0500252 }
253 s->peer = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800254 }
255
256 /* If we are already closing, or if there are no
257 ** pending packets, destroy immediately
258 */
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700259 if (s->closing || s->has_write_error || s->pkt_first == NULL) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260 int id = s->id;
261 local_socket_destroy(s);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700262 D("LS(%d): closed", id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800263 return;
264 }
265
266 /* otherwise, put on the closing list
267 */
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700268 D("LS(%d): closing", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800269 s->closing = 1;
270 fdevent_del(&s->fde, FDE_READ);
271 remove_socket(s);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700272 D("LS(%d): put on socket_closing_list fd=%d", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800273 insert_local_socket(s, &local_socket_closing_list);
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700274 CHECK_EQ(FDE_WRITE, s->fde.state & FDE_WRITE);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800275}
276
Dan Albertbac34742015-02-25 17:51:28 -0800277static void local_socket_event_func(int fd, unsigned ev, void* _s)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800278{
Dan Albertbac34742015-02-25 17:51:28 -0800279 asocket* s = reinterpret_cast<asocket*>(_s);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700280 D("LS(%d): event_func(fd=%d(==%d), ev=%04x)", s->id, s->fd, fd, ev);
JP Abgrall408fa572011-03-16 15:57:42 -0700281
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800282 /* put the FDE_WRITE processing before the FDE_READ
283 ** in order to simplify the code.
284 */
Dan Albertbac34742015-02-25 17:51:28 -0800285 if (ev & FDE_WRITE) {
286 apacket* p;
287 while ((p = s->pkt_first) != nullptr) {
288 while (p->len > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800289 int r = adb_write(fd, p->ptr, p->len);
Dan Albertbac34742015-02-25 17:51:28 -0800290 if (r == -1) {
291 /* returning here is ok because FDE_READ will
292 ** be processed in the next iteration loop
293 */
294 if (errno == EAGAIN) {
295 return;
296 }
297 } else if (r > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800298 p->ptr += r;
299 p->len -= r;
300 continue;
301 }
Dan Albertbac34742015-02-25 17:51:28 -0800302
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700303 D(" closing after write because r=%d and errno is %d", r, errno);
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700304 s->has_write_error = true;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800305 s->close(s);
306 return;
307 }
308
Dan Albertbac34742015-02-25 17:51:28 -0800309 if (p->len == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800310 s->pkt_first = p->next;
Dan Albertbac34742015-02-25 17:51:28 -0800311 if (s->pkt_first == 0) {
312 s->pkt_last = 0;
313 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800314 put_apacket(p);
315 }
316 }
317
Dan Albertbac34742015-02-25 17:51:28 -0800318 /* if we sent the last packet of a closing socket,
319 ** we can now destroy it.
320 */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800321 if (s->closing) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700322 D(" closing because 'closing' is set after write");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800323 s->close(s);
324 return;
325 }
326
Dan Albertbac34742015-02-25 17:51:28 -0800327 /* no more packets queued, so we can ignore
328 ** writable events again and tell our peer
329 ** to resume writing
330 */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800331 fdevent_del(&s->fde, FDE_WRITE);
332 s->peer->ready(s->peer);
333 }
334
335
Dan Albertbac34742015-02-25 17:51:28 -0800336 if (ev & FDE_READ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800337 apacket *p = get_apacket();
338 unsigned char *x = p->data;
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100339 const size_t max_payload = s->get_max_payload();
340 size_t avail = max_payload;
341 int r = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800342 int is_eof = 0;
343
Dan Albertbac34742015-02-25 17:51:28 -0800344 while (avail > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800345 r = adb_read(fd, x, avail);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700346 D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu",
Dan Albertbac34742015-02-25 17:51:28 -0800347 s->id, s->fd, r, r < 0 ? errno : 0, avail);
348 if (r == -1) {
349 if (errno == EAGAIN) {
350 break;
351 }
352 } else if (r > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800353 avail -= r;
354 x += r;
355 continue;
356 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800357
Dan Albertbac34742015-02-25 17:51:28 -0800358 /* r = 0 or unhandled error */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800359 is_eof = 1;
360 break;
361 }
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700362 D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700363 s->id, s->fd, r, is_eof, s->fde.force_eof);
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100364 if ((avail == max_payload) || (s->peer == 0)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800365 put_apacket(p);
366 } else {
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100367 p->len = max_payload - avail;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800368
Yabin Cui00674122015-08-26 12:27:40 -0700369 // s->peer->enqueue() may call s->close() and free s,
370 // so save variables for debug printing below.
371 unsigned saved_id = s->id;
372 int saved_fd = s->fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800373 r = s->peer->enqueue(s->peer, p);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700374 D("LS(%u): fd=%d post peer->enqueue(). r=%d", saved_id, saved_fd, r);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800375
Dan Albertbac34742015-02-25 17:51:28 -0800376 if (r < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800377 /* error return means they closed us as a side-effect
378 ** and we must return immediately.
379 **
380 ** note that if we still have buffered packets, the
381 ** socket will be placed on the closing socket list.
382 ** this handler function will be called again
383 ** to process FDE_WRITE events.
384 */
385 return;
386 }
387
Dan Albertbac34742015-02-25 17:51:28 -0800388 if (r > 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800389 /* if the remote cannot accept further events,
390 ** we disable notification of READs. They'll
391 ** be enabled again when we get a call to ready()
392 */
393 fdevent_del(&s->fde, FDE_READ);
394 }
395 }
JP Abgrall112445b2011-04-12 22:01:58 -0700396 /* Don't allow a forced eof if data is still there */
Dan Albertbac34742015-02-25 17:51:28 -0800397 if ((s->fde.force_eof && !r) || is_eof) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700398 D(" closing because is_eof=%d r=%d s->fde.force_eof=%d",
Dan Albertbac34742015-02-25 17:51:28 -0800399 is_eof, r, s->fde.force_eof);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800400 s->close(s);
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700401 return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800402 }
403 }
404
Dan Albertbac34742015-02-25 17:51:28 -0800405 if (ev & FDE_ERROR){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800406 /* this should be caught be the next read or write
407 ** catching it here means we may skip the last few
408 ** bytes of readable data.
409 */
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700410 D("LS(%d): FDE_ERROR (fd=%d)", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800411 return;
412 }
413}
414
415asocket *create_local_socket(int fd)
416{
Dan Albertbac34742015-02-25 17:51:28 -0800417 asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300418 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800419 s->fd = fd;
420 s->enqueue = local_socket_enqueue;
421 s->ready = local_socket_ready;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100422 s->shutdown = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800423 s->close = local_socket_close;
JP Abgrall408fa572011-03-16 15:57:42 -0700424 install_local_socket(s);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800425
426 fdevent_install(&s->fde, fd, local_socket_event_func, s);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700427 D("LS(%d): created (fd=%d)", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800428 return s;
429}
430
David Pursell0955c662015-08-31 10:42:13 -0700431asocket *create_local_service_socket(const char *name,
432 const atransport* transport)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800433{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800434#if !ADB_HOST
435 if (!strcmp(name,"jdwp")) {
436 return create_jdwp_service_socket();
437 }
438 if (!strcmp(name,"track-jdwp")) {
439 return create_jdwp_tracker_service_socket();
440 }
441#endif
David Pursell0955c662015-08-31 10:42:13 -0700442 int fd = service_to_fd(name, transport);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800443 if(fd < 0) return 0;
444
Dan Pasanen98858812014-10-06 12:57:20 -0500445 asocket* s = create_local_socket(fd);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700446 D("LS(%d): bound to '%s' via %d", s->id, name, fd);
Benoit Gobyf366b362012-03-16 14:50:07 -0700447
JP Abgrallf91259a2012-03-30 13:19:11 -0700448#if !ADB_HOST
Dan Pasanen98858812014-10-06 12:57:20 -0500449 char debug[PROPERTY_VALUE_MAX];
jzhuan51297d222013-05-24 17:40:15 -0400450 if (!strncmp(name, "root:", 5))
451 property_get("ro.debuggable", debug, "");
452
Dan Pasanen98858812014-10-06 12:57:20 -0500453 if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0)
454 || (!strncmp(name, "unroot:", 7) && getuid() == 0)
Benoit Gobyaeceb512012-06-12 12:12:18 -0700455 || !strncmp(name, "usb:", 4)
456 || !strncmp(name, "tcpip:", 6)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700457 D("LS(%d): enabling exit_on_close", s->id);
Benoit Gobyf366b362012-03-16 14:50:07 -0700458 s->exit_on_close = 1;
459 }
JP Abgrallf91259a2012-03-30 13:19:11 -0700460#endif
Benoit Gobyf366b362012-03-16 14:50:07 -0700461
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800462 return s;
463}
464
465#if ADB_HOST
466static asocket *create_host_service_socket(const char *name, const char* serial)
467{
468 asocket *s;
469
470 s = host_service_to_socket(name, serial);
471
472 if (s != NULL) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700473 D("LS(%d) bound to '%s'", s->id, name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800474 return s;
475 }
476
477 return s;
478}
479#endif /* ADB_HOST */
480
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800481static int remote_socket_enqueue(asocket *s, apacket *p)
482{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700483 D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700484 s->id, s->fd, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800485 p->msg.command = A_WRTE;
486 p->msg.arg0 = s->peer->id;
487 p->msg.arg1 = s->id;
488 p->msg.data_length = p->len;
489 send_packet(p, s->transport);
490 return 1;
491}
492
493static void remote_socket_ready(asocket *s)
494{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700495 D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700496 s->id, s->fd, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800497 apacket *p = get_apacket();
498 p->msg.command = A_OKAY;
499 p->msg.arg0 = s->peer->id;
500 p->msg.arg1 = s->id;
501 send_packet(p, s->transport);
502}
503
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100504static void remote_socket_shutdown(asocket *s)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800505{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700506 D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700507 s->id, s->fd, s->peer?s->peer->fd:-1);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800508 apacket *p = get_apacket();
509 p->msg.command = A_CLSE;
510 if(s->peer) {
511 p->msg.arg0 = s->peer->id;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100512 }
513 p->msg.arg1 = s->id;
514 send_packet(p, s->transport);
515}
516
517static void remote_socket_close(asocket *s)
518{
519 if (s->peer) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800520 s->peer->peer = 0;
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700521 D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d",
JP Abgrall408fa572011-03-16 15:57:42 -0700522 s->id, s->peer->id, s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800523 s->peer->close(s->peer);
524 }
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700525 D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d",
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100526 s->id, s->fd, s->peer?s->peer->fd:-1);
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700527 D("RS(%d): closed", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800528 free(s);
529}
530
Yabin Cuifd28f322015-08-27 18:50:04 -0700531// Create a remote socket to exchange packets with a remote service through transport
532// |t|. Where |id| is the socket id of the corresponding service on the other
533// side of the transport (it is allocated by the remote side and _cannot_ be 0).
534// Returns a new non-NULL asocket handle.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800535asocket *create_remote_socket(unsigned id, atransport *t)
536{
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100537 if (id == 0) fatal("invalid remote socket id (0)");
Yabin Cuifd28f322015-08-27 18:50:04 -0700538 asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800539
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300540 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800541 s->id = id;
542 s->enqueue = remote_socket_enqueue;
543 s->ready = remote_socket_ready;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100544 s->shutdown = remote_socket_shutdown;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800545 s->close = remote_socket_close;
546 s->transport = t;
547
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700548 D("RS(%d): created", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800549 return s;
550}
551
552void connect_to_remote(asocket *s, const char *destination)
553{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700554 D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800555 apacket *p = get_apacket();
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100556 size_t len = strlen(destination) + 1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800557
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100558 if(len > (s->get_max_payload()-1)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800559 fatal("destination oversized");
560 }
561
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700562 D("LS(%d): connect('%s')", s->id, destination);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800563 p->msg.command = A_OPEN;
564 p->msg.arg0 = s->id;
565 p->msg.data_length = len;
566 strcpy((char*) p->data, destination);
567 send_packet(p, s->transport);
568}
569
570
571/* this is used by magic sockets to rig local sockets to
572 send the go-ahead message when they connect */
573static void local_socket_ready_notify(asocket *s)
574{
575 s->ready = local_socket_ready;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100576 s->shutdown = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800577 s->close = local_socket_close;
Elliott Hughese67f1f82015-04-30 17:32:03 -0700578 SendOkay(s->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800579 s->ready(s);
580}
581
582/* this is used by magic sockets to rig local sockets to
583 send the failure message if they are closed before
584 connected (to avoid closing them without a status message) */
585static void local_socket_close_notify(asocket *s)
586{
587 s->ready = local_socket_ready;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100588 s->shutdown = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800589 s->close = local_socket_close;
Elliott Hughese67f1f82015-04-30 17:32:03 -0700590 SendFail(s->fd, "closed");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800591 s->close(s);
592}
593
Elliott Hughese67f1f82015-04-30 17:32:03 -0700594static unsigned unhex(unsigned char *s, int len)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800595{
596 unsigned n = 0, c;
597
598 while(len-- > 0) {
599 switch((c = *s++)) {
600 case '0': case '1': case '2':
601 case '3': case '4': case '5':
602 case '6': case '7': case '8':
603 case '9':
604 c -= '0';
605 break;
606 case 'a': case 'b': case 'c':
607 case 'd': case 'e': case 'f':
608 c = c - 'a' + 10;
609 break;
610 case 'A': case 'B': case 'C':
611 case 'D': case 'E': case 'F':
612 c = c - 'A' + 10;
613 break;
614 default:
615 return 0xffffffff;
616 }
617
618 n = (n << 4) | c;
619 }
620
621 return n;
622}
623
Elliott Hughese67f1f82015-04-30 17:32:03 -0700624#if ADB_HOST
625
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700626#define PREFIX(str) { str, sizeof(str) - 1 }
627static const struct prefix_struct {
628 const char *str;
629 const size_t len;
630} prefixes[] = {
631 PREFIX("usb:"),
632 PREFIX("product:"),
633 PREFIX("model:"),
634 PREFIX("device:"),
635};
636static const int num_prefixes = (sizeof(prefixes) / sizeof(prefixes[0]));
637
Terence Haddock28e13902011-03-16 09:43:56 +0100638/* skip_host_serial return the position in a string
639 skipping over the 'serial' parameter in the ADB protocol,
640 where parameter string may be a host:port string containing
641 the protocol delimiter (colon). */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700642static char *skip_host_serial(char *service) {
Terence Haddock28e13902011-03-16 09:43:56 +0100643 char *first_colon, *serial_end;
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700644 int i;
Terence Haddock28e13902011-03-16 09:43:56 +0100645
Scott Anderson2ca3e6b2012-05-30 18:11:27 -0700646 for (i = 0; i < num_prefixes; i++) {
647 if (!strncmp(service, prefixes[i].str, prefixes[i].len))
648 return strchr(service + prefixes[i].len, ':');
Scott Anderson3608d832012-05-31 12:04:23 -0700649 }
650
Terence Haddock28e13902011-03-16 09:43:56 +0100651 first_colon = strchr(service, ':');
652 if (!first_colon) {
653 /* No colon in service string. */
654 return NULL;
655 }
656 serial_end = first_colon;
657 if (isdigit(serial_end[1])) {
658 serial_end++;
659 while ((*serial_end) && isdigit(*serial_end)) {
660 serial_end++;
661 }
662 if ((*serial_end) != ':') {
663 // Something other than numbers was found, reset the end.
664 serial_end = first_colon;
665 }
666 }
667 return serial_end;
668}
669
Elliott Hughese67f1f82015-04-30 17:32:03 -0700670#endif // ADB_HOST
671
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800672static int smart_socket_enqueue(asocket *s, apacket *p)
673{
674 unsigned len;
675#if ADB_HOST
Elliott Hughes8d28e192015-10-07 14:55:10 -0700676 char *service = nullptr;
677 char* serial = nullptr;
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700678 TransportType type = kTransportAny;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800679#endif
680
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700681 D("SS(%d): enqueue %d", s->id, p->len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800682
683 if(s->pkt_first == 0) {
684 s->pkt_first = p;
685 s->pkt_last = p;
686 } else {
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100687 if((s->pkt_first->len + p->len) > s->get_max_payload()) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700688 D("SS(%d): overflow", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800689 put_apacket(p);
690 goto fail;
691 }
692
693 memcpy(s->pkt_first->data + s->pkt_first->len,
694 p->data, p->len);
695 s->pkt_first->len += p->len;
696 put_apacket(p);
697
698 p = s->pkt_first;
699 }
700
701 /* don't bother if we can't decode the length */
702 if(p->len < 4) return 0;
703
704 len = unhex(p->data, 4);
705 if((len < 1) || (len > 1024)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700706 D("SS(%d): bad size (%d)", s->id, len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800707 goto fail;
708 }
709
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700710 D("SS(%d): len is %d", s->id, len );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800711 /* can't do anything until we have the full header */
712 if((len + 4) > p->len) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700713 D("SS(%d): waiting for %d more bytes", s->id, len+4 - p->len);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800714 return 0;
715 }
716
717 p->data[len + 4] = 0;
718
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700719 D("SS(%d): '%s'", s->id, (char*) (p->data + 4));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800720
721#if ADB_HOST
722 service = (char *)p->data + 4;
723 if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
724 char* serial_end;
725 service += strlen("host-serial:");
726
Terence Haddock28e13902011-03-16 09:43:56 +0100727 // serial number should follow "host:" and could be a host:port string.
728 serial_end = skip_host_serial(service);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800729 if (serial_end) {
730 *serial_end = 0; // terminate string
731 serial = service;
732 service = serial_end + 1;
733 }
734 } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700735 type = kTransportUsb;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800736 service += strlen("host-usb:");
737 } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700738 type = kTransportLocal;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800739 service += strlen("host-local:");
740 } else if (!strncmp(service, "host:", strlen("host:"))) {
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700741 type = kTransportAny;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800742 service += strlen("host:");
743 } else {
Elliott Hughes8d28e192015-10-07 14:55:10 -0700744 service = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800745 }
746
747 if (service) {
748 asocket *s2;
749
750 /* some requests are handled immediately -- in that
751 ** case the handle_host_request() routine has sent
752 ** the OKAY or FAIL message and all we have to do
753 ** is clean up.
754 */
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700755 if(handle_host_request(service, type, serial, s->peer->fd, s) == 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800756 /* XXX fail message? */
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700757 D( "SS(%d): handled host service '%s'", s->id, service );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800758 goto fail;
759 }
760 if (!strncmp(service, "transport", strlen("transport"))) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700761 D( "SS(%d): okay transport", s->id );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800762 p->len = 0;
763 return 0;
764 }
765
766 /* try to find a local service with this name.
767 ** if no such service exists, we'll fail out
768 ** and tear down here.
769 */
770 s2 = create_host_service_socket(service, serial);
771 if(s2 == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700772 D( "SS(%d): couldn't create host service '%s'", s->id, service );
Elliott Hughese67f1f82015-04-30 17:32:03 -0700773 SendFail(s->peer->fd, "unknown host service");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800774 goto fail;
775 }
776
777 /* we've connected to a local host service,
778 ** so we make our peer back into a regular
779 ** local socket and bind it to the new local
780 ** service socket, acknowledge the successful
781 ** connection, and close this smart socket now
782 ** that its work is done.
783 */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700784 SendOkay(s->peer->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800785
786 s->peer->ready = local_socket_ready;
Elliott Hughes8d28e192015-10-07 14:55:10 -0700787 s->peer->shutdown = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800788 s->peer->close = local_socket_close;
789 s->peer->peer = s2;
790 s2->peer = s->peer;
791 s->peer = 0;
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700792 D( "SS(%d): okay", s->id );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800793 s->close(s);
794
795 /* initial state is "ready" */
796 s2->ready(s2);
797 return 0;
798 }
799#else /* !ADB_HOST */
Elliott Hughes8d28e192015-10-07 14:55:10 -0700800 if (s->transport == nullptr) {
Elliott Hughes7be29c82015-04-16 22:54:44 -0700801 std::string error_msg = "unknown failure";
Elliott Hughes8d28e192015-10-07 14:55:10 -0700802 s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg);
803 if (s->transport == nullptr) {
Elliott Hughese67f1f82015-04-30 17:32:03 -0700804 SendFail(s->peer->fd, error_msg);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800805 goto fail;
806 }
807 }
808#endif
809
Dan Albertdcd78a12015-05-18 16:43:57 -0700810 if(!(s->transport) || (s->transport->connection_state == kCsOffline)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800811 /* if there's no remote we fail the connection
812 ** right here and terminate it
813 */
Elliott Hughese67f1f82015-04-30 17:32:03 -0700814 SendFail(s->peer->fd, "device offline (x)");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800815 goto fail;
816 }
817
818
819 /* instrument our peer to pass the success or fail
820 ** message back once it connects or closes, then
821 ** detach from it, request the connection, and
822 ** tear down
823 */
824 s->peer->ready = local_socket_ready_notify;
Elliott Hughes8d28e192015-10-07 14:55:10 -0700825 s->peer->shutdown = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800826 s->peer->close = local_socket_close_notify;
827 s->peer->peer = 0;
828 /* give him our transport and upref it */
829 s->peer->transport = s->transport;
830
831 connect_to_remote(s->peer, (char*) (p->data + 4));
832 s->peer = 0;
833 s->close(s);
834 return 1;
835
836fail:
837 /* we're going to close our peer as a side-effect, so
838 ** return -1 to signal that state to the local socket
839 ** who is enqueueing against us
840 */
841 s->close(s);
842 return -1;
843}
844
845static void smart_socket_ready(asocket *s)
846{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700847 D("SS(%d): ready", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800848}
849
850static void smart_socket_close(asocket *s)
851{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700852 D("SS(%d): closed", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800853 if(s->pkt_first){
854 put_apacket(s->pkt_first);
855 }
856 if(s->peer) {
857 s->peer->peer = 0;
858 s->peer->close(s->peer);
Tom Marlin49f18572011-05-13 13:24:55 -0500859 s->peer = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800860 }
861 free(s);
862}
863
Benoit Goby9470c2f2013-02-20 15:04:53 -0800864static asocket *create_smart_socket(void)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800865{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700866 D("Creating smart socket");
Dan Albertbac34742015-02-25 17:51:28 -0800867 asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
André Goddard Rosac419e2a2010-06-10 20:48:19 -0300868 if (s == NULL) fatal("cannot allocate socket");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800869 s->enqueue = smart_socket_enqueue;
870 s->ready = smart_socket_ready;
David 'Digit' Turner818d6412013-12-13 14:09:44 +0100871 s->shutdown = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800872 s->close = smart_socket_close;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800873
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700874 D("SS(%d)", s->id);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800875 return s;
876}
877
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800878void connect_to_smartsocket(asocket *s)
879{
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700880 D("Connecting to smart socket");
Benoit Goby9470c2f2013-02-20 15:04:53 -0800881 asocket *ss = create_smart_socket();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800882 s->peer = ss;
883 ss->peer = s;
884 s->ready(s);
885}
Tamas Berghammer3d2904c2015-07-13 19:12:28 +0100886
887size_t asocket::get_max_payload() const {
888 size_t max_payload = MAX_PAYLOAD;
889 if (transport) {
890 max_payload = std::min(max_payload, transport->get_max_payload());
891 }
892 if (peer && peer->transport) {
893 max_payload = std::min(max_payload, peer->transport->get_max_payload());
894 }
895 return max_payload;
896}