sockets.c revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
1/* 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 17#include <stdio.h> 18#include <stdlib.h> 19#include <unistd.h> 20#include <errno.h> 21#include <string.h> 22#include <ctype.h> 23 24#include "sysdeps.h" 25 26#define TRACE_TAG TRACE_SOCKETS 27#include "adb.h" 28 29ADB_MUTEX_DEFINE( socket_list_lock ); 30 31static void local_socket_close_locked(asocket *s); 32 33int sendfailmsg(int fd, const char *reason) 34{ 35 char buf[9]; 36 int len; 37 len = strlen(reason); 38 if(len > 0xffff) len = 0xffff; 39 snprintf(buf, sizeof buf, "FAIL%04x", len); 40 if(writex(fd, buf, 8)) return -1; 41 return writex(fd, reason, len); 42} 43 44//extern int online; 45 46static unsigned local_socket_next_id = 1; 47 48static asocket local_socket_list = { 49 .next = &local_socket_list, 50 .prev = &local_socket_list, 51}; 52 53asocket *find_local_socket(unsigned id) 54{ 55 asocket *s; 56 asocket *result = NULL; 57 58 adb_mutex_lock(&socket_list_lock); 59 for(s = local_socket_list.next; s != &local_socket_list && !result; s = s->next) { 60 if(s->id == id) result = s; 61 } 62 adb_mutex_unlock(&socket_list_lock); 63 64 return result; 65} 66 67void install_local_socket(asocket *s) 68{ 69 adb_mutex_lock(&socket_list_lock); 70 71 s->id = local_socket_next_id++; 72 73 s->next = &local_socket_list; 74 s->prev = local_socket_list.prev; 75 s->prev->next = s; 76 s->next->prev = s; 77 78 adb_mutex_unlock(&socket_list_lock); 79} 80 81void remove_socket(asocket *s) 82{ 83 // socket_list_lock should already be held 84 if (s->prev && s->next) 85 { 86 s->prev->next = s->next; 87 s->next->prev = s->prev; 88 s->next = 0; 89 s->prev = 0; 90 s->id = 0; 91 } 92} 93 94void close_all_sockets(atransport *t) 95{ 96 asocket *s; 97 98 /* this is a little gross, but since s->close() *will* modify 99 ** the list out from under you, your options are limited. 100 */ 101 adb_mutex_lock(&socket_list_lock); 102restart: 103 for(s = local_socket_list.next; s != &local_socket_list; s = s->next){ 104 if(s->transport == t || (s->peer && s->peer->transport == t)) { 105 local_socket_close_locked(s); 106 goto restart; 107 } 108 } 109 adb_mutex_unlock(&socket_list_lock); 110} 111 112static int local_socket_enqueue(asocket *s, apacket *p) 113{ 114 D("LS(%d): enqueue %d\n", s->id, p->len); 115 116 p->ptr = p->data; 117 118 /* if there is already data queue'd, we will receive 119 ** events when it's time to write. just add this to 120 ** the tail 121 */ 122 if(s->pkt_first) { 123 goto enqueue; 124 } 125 126 /* write as much as we can, until we 127 ** would block or there is an error/eof 128 */ 129 while(p->len > 0) { 130 int r = adb_write(s->fd, p->ptr, p->len); 131 if(r > 0) { 132 p->len -= r; 133 p->ptr += r; 134 continue; 135 } 136 if((r == 0) || (errno != EAGAIN)) { 137 D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) ); 138 s->close(s); 139 return 1; /* not ready (error) */ 140 } else { 141 break; 142 } 143 } 144 145 if(p->len == 0) { 146 put_apacket(p); 147 return 0; /* ready for more data */ 148 } 149 150enqueue: 151 p->next = 0; 152 if(s->pkt_first) { 153 s->pkt_last->next = p; 154 } else { 155 s->pkt_first = p; 156 } 157 s->pkt_last = p; 158 159 /* make sure we are notified when we can drain the queue */ 160 fdevent_add(&s->fde, FDE_WRITE); 161 162 return 1; /* not ready (backlog) */ 163} 164 165static void local_socket_ready(asocket *s) 166{ 167 /* far side is ready for data, pay attention to 168 readable events */ 169 fdevent_add(&s->fde, FDE_READ); 170// D("LS(%d): ready()\n", s->id); 171} 172 173static void local_socket_close(asocket *s) 174{ 175 adb_mutex_lock(&socket_list_lock); 176 local_socket_close_locked(s); 177 adb_mutex_unlock(&socket_list_lock); 178} 179 180static void local_socket_close_locked(asocket *s) 181{ 182 apacket *p, *n; 183 184 if(s->peer) { 185 s->peer->peer = 0; 186 // tweak to avoid deadlock 187 if (s->peer->close == local_socket_close) 188 local_socket_close_locked(s->peer); 189 else 190 s->peer->close(s->peer); 191 } 192 193 /* IMPORTANT: the remove closes the fd 194 ** that belongs to this socket 195 */ 196 fdevent_remove(&s->fde); 197 198 /* dispose of any unwritten data */ 199 for(p = s->pkt_first; p; p = n) { 200 D("LS(%d): discarding %d bytes\n", s->id, p->len); 201 n = p->next; 202 put_apacket(p); 203 } 204 205 D("LS(%d): closed\n", s->id); 206 remove_socket(s); 207 free(s); 208} 209 210static void local_socket_event_func(int fd, unsigned ev, void *_s) 211{ 212 asocket *s = _s; 213 214 if(ev & FDE_READ){ 215 apacket *p = get_apacket(); 216 unsigned char *x = p->data; 217 size_t avail = MAX_PAYLOAD; 218 int r; 219 int is_eof = 0; 220 221 while(avail > 0) { 222 r = adb_read(fd, x, avail); 223 if(r > 0) { 224 avail -= r; 225 x += r; 226 continue; 227 } 228 if(r < 0) { 229 if(errno == EAGAIN) break; 230 if(errno == EINTR) continue; 231 } 232 233 /* r = 0 or unhandled error */ 234 is_eof = 1; 235 break; 236 } 237 238 if((avail == MAX_PAYLOAD) || (s->peer == 0)) { 239 put_apacket(p); 240 } else { 241 p->len = MAX_PAYLOAD - avail; 242 243 r = s->peer->enqueue(s->peer, p); 244 245 if(r < 0) { 246 /* error return means they closed us as a side-effect 247 ** and we must retutn immediately 248 */ 249 return; 250 } 251 252 if(r > 0) { 253 /* if the remote cannot accept further events, 254 ** we disable notification of READs. They'll 255 ** be enabled again when we get a call to ready() 256 */ 257 fdevent_del(&s->fde, FDE_READ); 258 } 259 } 260 261 if(is_eof) { 262 s->close(s); 263 } 264 return; 265 } 266 267 if(ev & FDE_WRITE){ 268 apacket *p; 269 270 while((p = s->pkt_first) != 0) { 271 while(p->len > 0) { 272 int r = adb_write(fd, p->ptr, p->len); 273 if(r > 0) { 274 p->ptr += r; 275 p->len -= r; 276 continue; 277 } 278 if(r < 0) { 279 if(errno == EAGAIN) return; 280 if(errno == EINTR) continue; 281 } 282 s->close(s); 283 return; 284 } 285 286 if(p->len == 0) { 287 s->pkt_first = p->next; 288 if(s->pkt_first == 0) s->pkt_last = 0; 289 put_apacket(p); 290 } 291 } 292 293 /* no more packets queued, so we can ignore 294 ** writable events again and tell our peer 295 ** to resume writing 296 */ 297 fdevent_del(&s->fde, FDE_WRITE); 298 s->peer->ready(s->peer); 299 return; 300 } 301 302 if(ev & FDE_ERROR){ 303 /* this should be caught be the next read or write 304 ** catching it here means we may skip the last few 305 ** bytes of readable data. 306 */ 307// s->close(s); 308 return; 309 } 310} 311 312asocket *create_local_socket(int fd) 313{ 314 asocket *s = calloc(1, sizeof(asocket)); 315 if(s == 0) fatal("cannot allocate socket"); 316 install_local_socket(s); 317 s->fd = fd; 318 s->enqueue = local_socket_enqueue; 319 s->ready = local_socket_ready; 320 s->close = local_socket_close; 321 322 fdevent_install(&s->fde, fd, local_socket_event_func, s); 323/* fdevent_add(&s->fde, FDE_ERROR); */ 324 //fprintf(stderr, "Created local socket in create_local_socket \n"); 325 D("LS(%d): created (fd=%d)\n", s->id, s->fd); 326 return s; 327} 328 329asocket *create_local_service_socket(const char *name) 330{ 331 asocket *s; 332 int fd; 333 334#if !ADB_HOST 335 if (!strcmp(name,"jdwp")) { 336 return create_jdwp_service_socket(); 337 } 338 if (!strcmp(name,"track-jdwp")) { 339 return create_jdwp_tracker_service_socket(); 340 } 341#endif 342 fd = service_to_fd(name); 343 if(fd < 0) return 0; 344 345 s = create_local_socket(fd); 346 D("LS(%d): bound to '%s'\n", s->id, name); 347 return s; 348} 349 350#if ADB_HOST 351static asocket *create_host_service_socket(const char *name, const char* serial) 352{ 353 asocket *s; 354 355 s = host_service_to_socket(name, serial); 356 357 if (s != NULL) { 358 D("LS(%d) bound to '%s'\n", s->id, name); 359 return s; 360 } 361 362 return s; 363} 364#endif /* ADB_HOST */ 365 366/* a Remote socket is used to send/receive data to/from a given transport object 367** it needs to be closed when the transport is forcibly destroyed by the user 368*/ 369typedef struct aremotesocket { 370 asocket socket; 371 adisconnect disconnect; 372} aremotesocket; 373 374static int remote_socket_enqueue(asocket *s, apacket *p) 375{ 376 D("Calling remote_socket_enqueue\n"); 377 p->msg.command = A_WRTE; 378 p->msg.arg0 = s->peer->id; 379 p->msg.arg1 = s->id; 380 p->msg.data_length = p->len; 381 send_packet(p, s->transport); 382 return 1; 383} 384 385static void remote_socket_ready(asocket *s) 386{ 387 D("Calling remote_socket_ready\n"); 388 apacket *p = get_apacket(); 389 p->msg.command = A_OKAY; 390 p->msg.arg0 = s->peer->id; 391 p->msg.arg1 = s->id; 392 send_packet(p, s->transport); 393} 394 395static void remote_socket_close(asocket *s) 396{ 397 D("Calling remote_socket_close\n"); 398 apacket *p = get_apacket(); 399 p->msg.command = A_CLSE; 400 if(s->peer) { 401 p->msg.arg0 = s->peer->id; 402 s->peer->peer = 0; 403 s->peer->close(s->peer); 404 } 405 p->msg.arg1 = s->id; 406 send_packet(p, s->transport); 407 D("RS(%d): closed\n", s->id); 408 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); 409 free(s); 410} 411 412static void remote_socket_disconnect(void* _s, atransport* t) 413{ 414 asocket* s = _s; 415 asocket* peer = s->peer; 416 417 D("remote_socket_disconnect RS(%d)\n", s->id); 418 if (peer) { 419 peer->peer = NULL; 420 peer->close(peer); 421 } 422 remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); 423 free(s); 424} 425 426asocket *create_remote_socket(unsigned id, atransport *t) 427{ 428 asocket *s = calloc(1, sizeof(aremotesocket)); 429 adisconnect* dis = &((aremotesocket*)s)->disconnect; 430 431 if(s == 0) fatal("cannot allocate socket"); 432 s->id = id; 433 s->enqueue = remote_socket_enqueue; 434 s->ready = remote_socket_ready; 435 s->close = remote_socket_close; 436 s->transport = t; 437 438 dis->func = remote_socket_disconnect; 439 dis->opaque = s; 440 add_transport_disconnect( t, dis ); 441 D("RS(%d): created\n", s->id); 442 return s; 443} 444 445void connect_to_remote(asocket *s, const char *destination) 446{ 447 D("Connect_to_remote call \n"); 448 apacket *p = get_apacket(); 449 int len = strlen(destination) + 1; 450 451 if(len > (MAX_PAYLOAD-1)) { 452 fatal("destination oversized"); 453 } 454 455 D("LS(%d): connect('%s')\n", s->id, destination); 456 p->msg.command = A_OPEN; 457 p->msg.arg0 = s->id; 458 p->msg.data_length = len; 459 strcpy((char*) p->data, destination); 460 send_packet(p, s->transport); 461} 462 463 464/* this is used by magic sockets to rig local sockets to 465 send the go-ahead message when they connect */ 466static void local_socket_ready_notify(asocket *s) 467{ 468 s->ready = local_socket_ready; 469 s->close = local_socket_close; 470 adb_write(s->fd, "OKAY", 4); 471 s->ready(s); 472} 473 474/* this is used by magic sockets to rig local sockets to 475 send the failure message if they are closed before 476 connected (to avoid closing them without a status message) */ 477static void local_socket_close_notify(asocket *s) 478{ 479 s->ready = local_socket_ready; 480 s->close = local_socket_close; 481 sendfailmsg(s->fd, "closed"); 482 s->close(s); 483} 484 485unsigned unhex(unsigned char *s, int len) 486{ 487 unsigned n = 0, c; 488 489 while(len-- > 0) { 490 switch((c = *s++)) { 491 case '0': case '1': case '2': 492 case '3': case '4': case '5': 493 case '6': case '7': case '8': 494 case '9': 495 c -= '0'; 496 break; 497 case 'a': case 'b': case 'c': 498 case 'd': case 'e': case 'f': 499 c = c - 'a' + 10; 500 break; 501 case 'A': case 'B': case 'C': 502 case 'D': case 'E': case 'F': 503 c = c - 'A' + 10; 504 break; 505 default: 506 return 0xffffffff; 507 } 508 509 n = (n << 4) | c; 510 } 511 512 return n; 513} 514 515static int smart_socket_enqueue(asocket *s, apacket *p) 516{ 517 unsigned len; 518#if ADB_HOST 519 char *service = NULL; 520 char* serial = NULL; 521 transport_type ttype = kTransportAny; 522#endif 523 524 D("SS(%d): enqueue %d\n", s->id, p->len); 525 526 if(s->pkt_first == 0) { 527 s->pkt_first = p; 528 s->pkt_last = p; 529 } else { 530 if((s->pkt_first->len + p->len) > MAX_PAYLOAD) { 531 D("SS(%d): overflow\n", s->id); 532 put_apacket(p); 533 goto fail; 534 } 535 536 memcpy(s->pkt_first->data + s->pkt_first->len, 537 p->data, p->len); 538 s->pkt_first->len += p->len; 539 put_apacket(p); 540 541 p = s->pkt_first; 542 } 543 544 /* don't bother if we can't decode the length */ 545 if(p->len < 4) return 0; 546 547 len = unhex(p->data, 4); 548 if((len < 1) || (len > 1024)) { 549 D("SS(%d): bad size (%d)\n", s->id, len); 550 goto fail; 551 } 552 553 D("SS(%d): len is %d\n", s->id, len ); 554 /* can't do anything until we have the full header */ 555 if((len + 4) > p->len) { 556 D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len); 557 return 0; 558 } 559 560 p->data[len + 4] = 0; 561 562 D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4)); 563 564#if ADB_HOST 565 service = (char *)p->data + 4; 566 if(!strncmp(service, "host-serial:", strlen("host-serial:"))) { 567 char* serial_end; 568 service += strlen("host-serial:"); 569 570 // serial number should follow "host:" 571 serial_end = strchr(service, ':'); 572 if (serial_end) { 573 *serial_end = 0; // terminate string 574 serial = service; 575 service = serial_end + 1; 576 } 577 } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { 578 ttype = kTransportUsb; 579 service += strlen("host-usb:"); 580 } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { 581 ttype = kTransportLocal; 582 service += strlen("host-local:"); 583 } else if (!strncmp(service, "host:", strlen("host:"))) { 584 ttype = kTransportAny; 585 service += strlen("host:"); 586 } else { 587 service = NULL; 588 } 589 590 if (service) { 591 asocket *s2; 592 593 /* some requests are handled immediately -- in that 594 ** case the handle_host_request() routine has sent 595 ** the OKAY or FAIL message and all we have to do 596 ** is clean up. 597 */ 598 if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) { 599 /* XXX fail message? */ 600 D( "SS(%d): handled host service '%s'\n", s->id, service ); 601 goto fail; 602 } 603 if (!strncmp(service, "transport", strlen("transport"))) { 604 D( "SS(%d): okay transport\n", s->id ); 605 p->len = 0; 606 return 0; 607 } 608 609 /* try to find a local service with this name. 610 ** if no such service exists, we'll fail out 611 ** and tear down here. 612 */ 613 s2 = create_host_service_socket(service, serial); 614 if(s2 == 0) { 615 D( "SS(%d): couldn't create host service '%s'\n", s->id, service ); 616 sendfailmsg(s->peer->fd, "unknown host service"); 617 goto fail; 618 } 619 620 /* we've connected to a local host service, 621 ** so we make our peer back into a regular 622 ** local socket and bind it to the new local 623 ** service socket, acknowledge the successful 624 ** connection, and close this smart socket now 625 ** that its work is done. 626 */ 627 adb_write(s->peer->fd, "OKAY", 4); 628 629 s->peer->ready = local_socket_ready; 630 s->peer->close = local_socket_close; 631 s->peer->peer = s2; 632 s2->peer = s->peer; 633 s->peer = 0; 634 D( "SS(%d): okay\n", s->id ); 635 s->close(s); 636 637 /* initial state is "ready" */ 638 s2->ready(s2); 639 return 0; 640 } 641#else /* !ADB_HOST */ 642 if (s->transport == NULL) { 643 char* error_string = "unknown failure"; 644 s->transport = acquire_one_transport (CS_ANY, 645 kTransportAny, NULL, &error_string); 646 647 if (s->transport == NULL) { 648 sendfailmsg(s->peer->fd, error_string); 649 goto fail; 650 } 651 } 652#endif 653 654 if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) { 655 /* if there's no remote we fail the connection 656 ** right here and terminate it 657 */ 658 sendfailmsg(s->peer->fd, "device offline (x)"); 659 goto fail; 660 } 661 662 663 /* instrument our peer to pass the success or fail 664 ** message back once it connects or closes, then 665 ** detach from it, request the connection, and 666 ** tear down 667 */ 668 s->peer->ready = local_socket_ready_notify; 669 s->peer->close = local_socket_close_notify; 670 s->peer->peer = 0; 671 /* give him our transport and upref it */ 672 s->peer->transport = s->transport; 673 674 connect_to_remote(s->peer, (char*) (p->data + 4)); 675 s->peer = 0; 676 s->close(s); 677 return 1; 678 679fail: 680 /* we're going to close our peer as a side-effect, so 681 ** return -1 to signal that state to the local socket 682 ** who is enqueueing against us 683 */ 684 s->close(s); 685 return -1; 686} 687 688static void smart_socket_ready(asocket *s) 689{ 690 D("SS(%d): ready\n", s->id); 691} 692 693static void smart_socket_close(asocket *s) 694{ 695 D("SS(%d): closed\n", s->id); 696 if(s->pkt_first){ 697 put_apacket(s->pkt_first); 698 } 699 if(s->peer) { 700 s->peer->peer = 0; 701 s->peer->close(s->peer); 702 } 703 free(s); 704} 705 706asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act)) 707{ 708 D("Creating smart socket \n"); 709 asocket *s = calloc(1, sizeof(asocket)); 710 if(s == 0) fatal("cannot allocate socket"); 711 s->id = 0; 712 s->enqueue = smart_socket_enqueue; 713 s->ready = smart_socket_ready; 714 s->close = smart_socket_close; 715 s->extra = action_cb; 716 717 D("SS(%d): created %p\n", s->id, action_cb); 718 return s; 719} 720 721void smart_socket_action(asocket *s, const char *act) 722{ 723 724} 725 726void connect_to_smartsocket(asocket *s) 727{ 728 D("Connecting to smart socket \n"); 729 asocket *ss = create_smart_socket(smart_socket_action); 730 s->peer = ss; 731 ss->peer = s; 732 s->ready(s); 733} 734