1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG SOCKETS 183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "sysdeps.h" 203313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 217664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <ctype.h> 227664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <errno.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 267664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <unistd.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low#include <algorithm> 299b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao#include <mutex> 303f902aad5b427a8162bf860a758878b55b13e775David Pursell#include <string> 313f902aad5b427a8162bf860a758878b55b13e775David Pursell#include <vector> 32363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low 337664901a355b959f312e9acff5a0fd31b7139623Dan Albert#if !ADB_HOST 34ffdec180176094dac0fb902263370dea1deb138fElliott Hughes#include <android-base/properties.h> 351f83aa424f537cf3f07e1d27dbbcc524818b5358Steven Moreland#include <log/log_properties.h> 367664901a355b959f312e9acff5a0fd31b7139623Dan Albert#endif 373313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 383313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb.h" 393313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb_io.h" 407664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h" 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 429b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gaostatic std::recursive_mutex& local_socket_list_lock = *new std::recursive_mutex(); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned local_socket_next_id = 1; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic asocket local_socket_list = { 4652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao .next = &local_socket_list, .prev = &local_socket_list, 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* the the list of currently closing local sockets. 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** these have no peer anymore, but still packets to 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** write to their fd. 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic asocket local_socket_closing_list = { 5452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao .next = &local_socket_closing_list, .prev = &local_socket_closing_list, 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner// Parse the global list of sockets to find one with id |local_id|. 58818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner// If |peer_id| is not 0, also check that it is connected to a peer 59818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner// with id |peer_id|. Returns an asocket handle on success, NULL on failure. 6052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaoasocket* find_local_socket(unsigned local_id, unsigned peer_id) { 6152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s; 6252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* result = NULL; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 649b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 658182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa for (s = local_socket_list.next; s != &local_socket_list; s = s->next) { 6652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->id != local_id) { 67818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner continue; 6852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 69818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (peer_id == 0 || (s->peer && s->peer->id == peer_id)) { 708182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa result = s; 718182829ccb46fc5b043ea258672602dc2928dee2André Goddard Rosa } 72818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner break; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void insert_local_socket(asocket* s, asocket* list) { 7952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->next = list; 8052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->prev = s->next->prev; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev->next = s; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next->prev = s; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaovoid install_local_socket(asocket* s) { 869b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = local_socket_next_id++; 89818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 90818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner // Socket ids should never be 0. 9152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (local_socket_next_id == 0) { 929b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao fatal("local socket id overflow"); 9352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 94818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project insert_local_socket(s, &local_socket_list); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaovoid remove_socket(asocket* s) { 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // socket_list_lock should already be held 10052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->prev && s->next) { 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev->next = s->next; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next->prev = s->prev; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->next = 0; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->prev = 0; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = 0; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaovoid close_all_sockets(atransport* t) { 11052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* this is a little gross, but since s->close() *will* modify 11352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** the list out from under you, your options are limited. 11452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 1159b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrestart: 11752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao for (s = local_socket_list.next; s != &local_socket_list; s = s->next) { 11852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->transport == t || (s->peer && s->peer->transport == t)) { 11953eb31d87cb84a4212f4850bf745646e1fb12814Josh Gao s->close(s); 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto restart; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 12552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic int local_socket_enqueue(asocket* s, apacket* p) { 12606d61d4d96d28777f76578fb5d3c823168853166Josh Gao D("LS(%d): enqueue %zu", s->id, p->len); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr = p->data; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 13052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* if there is already data queue'd, we will receive 13152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** events when it's time to write. just add this to 13252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** the tail 13352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 13452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->pkt_first) { 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto enqueue; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 13852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* write as much as we can, until we 13952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** would block or there is an error/eof 14052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 14152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao while (p->len > 0) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r = adb_write(s->fd, p->ptr, p->len); 14352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (r > 0) { 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len -= r; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr += r; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 14852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if ((r == 0) || (errno != EAGAIN)) { 14952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("LS(%d): not ready, errno=%d: %s", s->id, errno, strerror(errno)); 150c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui put_apacket(p); 151c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui s->has_write_error = true; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; /* not ready (error) */ 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 15952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (p->len == 0) { 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; /* ready for more data */ 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectenqueue: 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->next = 0; 16652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->pkt_first) { 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last->next = p; 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last = p; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* make sure we are notified when we can drain the queue */ 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_add(&s->fde, FDE_WRITE); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; /* not ready (backlog) */ 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void local_socket_ready(asocket* s) { 180b627a0e2ed63377c828b1f324dd0120fee4e4cd3Nanik Tolaram /* far side is ready for data, pay attention to 181b627a0e2ed63377c828b1f324dd0120fee4e4cd3Nanik Tolaram readable events */ 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_add(&s->fde, FDE_READ); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// be sure to hold the socket list lock when calling this 18652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void local_socket_destroy(asocket* s) { 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p, *n; 188f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby int exit_on_close = s->exit_on_close; 189f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby 1907a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): destroying fde.fd=%d", s->id, s->fde.fd); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* IMPORTANT: the remove closes the fd 19352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** that belongs to this socket 19452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&s->fde); 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* dispose of any unwritten data */ 19852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao for (p = s->pkt_first; p; p = n) { 19906d61d4d96d28777f76578fb5d3c823168853166Josh Gao D("LS(%d): discarding %zu bytes", s->id, p->len); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = p->next; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_socket(s); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 205f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby 206f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby if (exit_on_close) { 2077a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("local_socket_destroy: exiting"); 208f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby exit(1); 209f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby } 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2129b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gaostatic void local_socket_close(asocket* s) { 2139b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao D("entered local_socket_close. LS(%d) fd=%d", s->id, s->fd); 2149b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 21552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->peer) { 21652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("LS(%d): closing peer. peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd); 217818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* Note: it's important to call shutdown before disconnecting from 218818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * the peer, this ensures that remote sockets can still get the id 219818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * of the local socket they're connected to, to send a CLOSE() 220818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * protocol event. */ 22152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->peer->shutdown) { 22252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->peer->shutdown(s->peer); 22352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 2249b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao s->peer->peer = nullptr; 2259b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao s->peer->close(s->peer); 2269b587dec6d0a57c8fe1083c1c543fbeb163d65faJosh Gao s->peer = nullptr; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* If we are already closing, or if there are no 23052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** pending packets, destroy immediately 23152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 232c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui if (s->closing || s->has_write_error || s->pkt_first == NULL) { 23352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao int id = s->id; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_socket_destroy(s); 2357a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): closed", id); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* otherwise, put on the closing list 24052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 2417a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): closing", s->id); 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->closing = 1; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_READ); 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project remove_socket(s); 2457a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): put on socket_closing_list fd=%d", s->id, s->fd); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project insert_local_socket(s, &local_socket_closing_list); 247c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui CHECK_EQ(FDE_WRITE, s->fde.state & FDE_WRITE); 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void local_socket_event_func(int fd, unsigned ev, void* _s) { 251bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert asocket* s = reinterpret_cast<asocket*>(_s); 2527a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): event_func(fd=%d(==%d), ev=%04x)", s->id, s->fd, fd, ev); 253408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* put the FDE_WRITE processing before the FDE_READ 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** in order to simplify the code. 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 257bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (ev & FDE_WRITE) { 258bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert apacket* p; 259bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert while ((p = s->pkt_first) != nullptr) { 260bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert while (p->len > 0) { 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r = adb_write(fd, p->ptr, p->len); 262bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (r == -1) { 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* returning here is ok because FDE_READ will 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ** be processed in the next iteration loop 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 266bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (errno == EAGAIN) { 267bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert return; 268bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 269bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } else if (r > 0) { 270bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert p->ptr += r; 271bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert p->len -= r; 272bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert continue; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 274bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert 2757a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D(" closing after write because r=%d and errno is %d", r, errno); 276c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui s->has_write_error = true; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 281bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (p->len == 0) { 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p->next; 283bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (s->pkt_first == 0) { 284bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert s->pkt_last = 0; 285bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert /* if we sent the last packet of a closing socket, 291bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert ** we can now destroy it. 292bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert */ 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s->closing) { 2947a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D(" closing because 'closing' is set after write"); 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 299bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert /* no more packets queued, so we can ignore 300bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert ** writable events again and tell our peer 301bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert ** to resume writing 302bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert */ 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_WRITE); 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready(s->peer); 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (ev & FDE_READ) { 30852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao apacket* p = get_apacket(); 30906d61d4d96d28777f76578fb5d3c823168853166Josh Gao char* x = p->data; 3103d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer const size_t max_payload = s->get_max_payload(); 3113d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer size_t avail = max_payload; 3123d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer int r = 0; 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int is_eof = 0; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 315bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert while (avail > 0) { 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, x, avail); 31752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu", s->id, s->fd, r, 31852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao r < 0 ? errno : 0, avail); 319bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (r == -1) { 320bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (errno == EAGAIN) { 321bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert break; 322bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 323bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } else if (r > 0) { 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project avail -= r; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x += r; 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 329bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert /* r = 0 or unhandled error */ 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_eof = 1; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 33352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d", s->id, s->fd, r, is_eof, 33452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->fde.force_eof); 3353d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer if ((avail == max_payload) || (s->peer == 0)) { 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 3383d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer p->len = max_payload - avail; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 34000674124213d6a9f0564632a5ad172cbd78caf24Yabin Cui // s->peer->enqueue() may call s->close() and free s, 34100674124213d6a9f0564632a5ad172cbd78caf24Yabin Cui // so save variables for debug printing below. 34200674124213d6a9f0564632a5ad172cbd78caf24Yabin Cui unsigned saved_id = s->id; 34300674124213d6a9f0564632a5ad172cbd78caf24Yabin Cui int saved_fd = s->fd; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = s->peer->enqueue(s->peer, p); 3457a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%u): fd=%d post peer->enqueue(). r=%d", saved_id, saved_fd, r); 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 347bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (r < 0) { 34852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* error return means they closed us as a side-effect 34952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** and we must return immediately. 35052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** 35152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** note that if we still have buffered packets, the 35252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** socket will be placed on the closing socket list. 35352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** this handler function will be called again 35452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** to process FDE_WRITE events. 35552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (r > 0) { 36052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* if the remote cannot accept further events, 36152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** we disable notification of READs. They'll 36252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** be enabled again when we get a call to ready() 36352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_del(&s->fde, FDE_READ); 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 367112445b8a752ce174f36cf853d5f1c356c3f5286JP Abgrall /* Don't allow a forced eof if data is still there */ 368bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if ((s->fde.force_eof && !r) || is_eof) { 36952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D(" closing because is_eof=%d r=%d s->fde.force_eof=%d", is_eof, r, s->fde.force_eof); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 371c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui return; 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (ev & FDE_ERROR) { 37652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* this should be caught be the next read or write 37752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** catching it here means we may skip the last few 37852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** bytes of readable data. 37952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 3807a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): FDE_ERROR (fd=%d)", s->id, s->fd); 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaoasocket* create_local_socket(int fd) { 38652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 38752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s == NULL) { 38852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao fatal("cannot allocate socket"); 38952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->fd = fd; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = local_socket_enqueue; 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 393818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 395408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall install_local_socket(s); 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_install(&s->fde, fd, local_socket_event_func, s); 3987a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): created (fd=%d)", s->id, s->fd); 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaoasocket* create_local_service_socket(const char* name, const atransport* transport) { 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 40452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (!strcmp(name, "jdwp")) { 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_jdwp_service_socket(); 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 40752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (!strcmp(name, "track-jdwp")) { 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_jdwp_tracker_service_socket(); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 4110955c66b226db7a7f34613f834f7b0a145fd407dDavid Pursell int fd = service_to_fd(name, transport); 41252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (fd < 0) { 413ffc73a39fd813c8823ca0e4cdc52b79521ce84daElliott Hughes return nullptr; 41452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4169885881d0689e7999f2d7e7558e894dc73a0a0b0Dan Pasanen asocket* s = create_local_socket(fd); 4177a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): bound to '%s' via %d", s->id, name, fd); 418f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby 419f91259a8f0d75d721761d588a4b811427565c984JP Abgrall#if !ADB_HOST 42097787a00e6aeb9aba2d744566cfd9de3d2f8c4f6Mark Salyzyn if ((!strncmp(name, "root:", 5) && getuid() != 0 && __android_log_is_debuggable()) || 42152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao (!strncmp(name, "unroot:", 7) && getuid() == 0) || 42252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao !strncmp(name, "usb:", 4) || 42352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao !strncmp(name, "tcpip:", 6)) { 4247a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): enabling exit_on_close", s->id); 425f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby s->exit_on_close = 1; 426f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby } 427f91259a8f0d75d721761d588a4b811427565c984JP Abgrall#endif 428f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 43352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic asocket* create_host_service_socket(const char* name, const char* serial) { 43452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = host_service_to_socket(name, serial); 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s != NULL) { 4397a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d) bound to '%s'", s->id, name); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic int remote_socket_enqueue(asocket* s, apacket* p) { 44852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_WRTE; 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = p->len; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void remote_socket_ready(asocket* s) { 45852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd); 45952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao apacket* p = get_apacket(); 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OKAY; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void remote_socket_shutdown(asocket* s) { 46752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd, 46852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->peer ? s->peer->fd : -1); 46952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao apacket* p = get_apacket(); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_CLSE; 47152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->peer) { 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 473818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } 474818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg1 = s->id; 475818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner send_packet(p, s->transport); 476818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner} 477818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 47852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void remote_socket_close(asocket* s) { 479818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (s->peer) { 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 48152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd); 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 48452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd, 48552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao s->peer ? s->peer->fd : -1); 4867a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("RS(%d): closed", s->id); 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 490fd28f327ee0e110208ef42ded829286643860394Yabin Cui// Create a remote socket to exchange packets with a remote service through transport 491fd28f327ee0e110208ef42ded829286643860394Yabin Cui// |t|. Where |id| is the socket id of the corresponding service on the other 492fd28f327ee0e110208ef42ded829286643860394Yabin Cui// side of the transport (it is allocated by the remote side and _cannot_ be 0). 493fd28f327ee0e110208ef42ded829286643860394Yabin Cui// Returns a new non-NULL asocket handle. 49452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaoasocket* create_remote_socket(unsigned id, atransport* t) { 49552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (id == 0) { 49652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao fatal("invalid remote socket id (0)"); 49752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 498fd28f327ee0e110208ef42ded829286643860394Yabin Cui asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s == NULL) { 50152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao fatal("cannot allocate socket"); 50252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = id; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = remote_socket_enqueue; 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = remote_socket_ready; 506818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = remote_socket_shutdown; 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = remote_socket_close; 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = t; 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5107a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("RS(%d): created", s->id); 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaovoid connect_to_remote(asocket* s, const char* destination) { 5157a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd); 51652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao apacket* p = get_apacket(); 5173d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer size_t len = strlen(destination) + 1; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (len > (s->get_max_payload() - 1)) { 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal("destination oversized"); 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5237a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): connect('%s')", s->id, destination); 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OPEN; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->id; 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = len; 52752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao strcpy((char*)p->data, destination); 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the go-ahead message when they connect */ 53352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void local_socket_ready_notify(asocket* s) { 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 535818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 537e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(s->fd); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the failure message if they are closed before 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project connected (to avoid closing them without a status message) */ 54452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void local_socket_close_notify(asocket* s) { 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 546818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 548e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->fd, "closed"); 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55206d61d4d96d28777f76578fb5d3c823168853166Josh Gaostatic unsigned unhex(char* s, int len) { 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n = 0, c; 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao while (len-- > 0) { 55652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao switch ((c = *s++)) { 55752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '0': 55852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '1': 55952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '2': 56052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '3': 56152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '4': 56252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '5': 56352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '6': 56452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '7': 56552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '8': 56652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case '9': 56752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao c -= '0'; 56852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao break; 56952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'a': 57052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'b': 57152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'c': 57252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'd': 57352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'e': 57452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'f': 57552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao c = c - 'a' + 10; 57652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao break; 57752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'A': 57852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'B': 57952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'C': 58052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'D': 58152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'E': 58252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao case 'F': 58352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao c = c - 'A' + 10; 58452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao break; 58552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao default: 58652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao return 0xffffffff; 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = (n << 4) | c; 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return n; 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 595e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#if ADB_HOST 596e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 5973f902aad5b427a8162bf860a758878b55b13e775David Pursellnamespace internal { 5983f902aad5b427a8162bf860a758878b55b13e775David Pursell 5993f902aad5b427a8162bf860a758878b55b13e775David Pursell// Returns the position in |service| following the target serial parameter. Serial format can be 6003f902aad5b427a8162bf860a758878b55b13e775David Pursell// any of: 6013f902aad5b427a8162bf860a758878b55b13e775David Pursell// * [tcp:|udp:]<serial>[:<port>]:<command> 6023f902aad5b427a8162bf860a758878b55b13e775David Pursell// * <prefix>:<serial>:<command> 6033f902aad5b427a8162bf860a758878b55b13e775David Pursell// Where <port> must be a base-10 number and <prefix> may be any of {usb,product,model,device}. 6043f902aad5b427a8162bf860a758878b55b13e775David Pursell// 6053f902aad5b427a8162bf860a758878b55b13e775David Pursell// The returned pointer will point to the ':' just before <command>, or nullptr if not found. 606b4cff495a1f93b6c92f4327cbfb9e564b28913d8Dan Austinchar* skip_host_serial(char* service) { 6073f902aad5b427a8162bf860a758878b55b13e775David Pursell static const std::vector<std::string>& prefixes = 6083f902aad5b427a8162bf860a758878b55b13e775David Pursell *(new std::vector<std::string>{"usb:", "product:", "model:", "device:"}); 6093f902aad5b427a8162bf860a758878b55b13e775David Pursell 6103f902aad5b427a8162bf860a758878b55b13e775David Pursell for (const std::string& prefix : prefixes) { 6113f902aad5b427a8162bf860a758878b55b13e775David Pursell if (!strncmp(service, prefix.c_str(), prefix.length())) { 6123f902aad5b427a8162bf860a758878b55b13e775David Pursell return strchr(service + prefix.length(), ':'); 6133f902aad5b427a8162bf860a758878b55b13e775David Pursell } 6143f902aad5b427a8162bf860a758878b55b13e775David Pursell } 6153f902aad5b427a8162bf860a758878b55b13e775David Pursell 6163f902aad5b427a8162bf860a758878b55b13e775David Pursell // For fastboot compatibility, ignore protocol prefixes. 6173f902aad5b427a8162bf860a758878b55b13e775David Pursell if (!strncmp(service, "tcp:", 4) || !strncmp(service, "udp:", 4)) { 6183f902aad5b427a8162bf860a758878b55b13e775David Pursell service += 4; 6193608d832425ca3a6d00c4040f3bb979c5aa49899Scott Anderson } 6203608d832425ca3a6d00c4040f3bb979c5aa49899Scott Anderson 62173d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell // Check for an IPv6 address. `adb connect` creates the serial number from the canonical 62273d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell // network address so it will always have the [] delimiters. 62373d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell if (service[0] == '[') { 62473d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell char* ipv6_end = strchr(service, ']'); 62573d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell if (ipv6_end != nullptr) { 62673d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell service = ipv6_end; 62773d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell } 62873d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell } 62973d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell 63073d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell // The next colon we find must either begin the port field or the command field. 63173d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell char* colon_ptr = strchr(service, ':'); 63273d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell if (!colon_ptr) { 6333f902aad5b427a8162bf860a758878b55b13e775David Pursell // No colon in service string. 6343f902aad5b427a8162bf860a758878b55b13e775David Pursell return nullptr; 63528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 6363f902aad5b427a8162bf860a758878b55b13e775David Pursell 63773d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell // If the next field is only decimal digits and ends with another colon, it's a port. 63873d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell char* serial_end = colon_ptr; 63928e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if (isdigit(serial_end[1])) { 64028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 6413f902aad5b427a8162bf860a758878b55b13e775David Pursell while (*serial_end && isdigit(*serial_end)) { 64228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 64328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 6443f902aad5b427a8162bf860a758878b55b13e775David Pursell if (*serial_end != ':') { 64573d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell // Something other than "<port>:" was found, this must be the command field instead. 64673d55aaab23256f85941730444e82cbc41a63f8bDavid Pursell serial_end = colon_ptr; 64728e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 64828e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 64928e1390e688f721e13a9877d3c41884bf151db60Terence Haddock return serial_end; 65028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock} 65128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock 6523f902aad5b427a8162bf860a758878b55b13e775David Pursell} // namespace internal 6533f902aad5b427a8162bf860a758878b55b13e775David Pursell 65452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao#endif // ADB_HOST 655e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 65652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic int smart_socket_enqueue(asocket* s, apacket* p) { 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned len; 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 65952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao char* service = nullptr; 6608d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes char* serial = nullptr; 6613bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes TransportType type = kTransportAny; 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66406d61d4d96d28777f76578fb5d3c823168853166Josh Gao D("SS(%d): enqueue %zu", s->id, p->len); 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->pkt_first == 0) { 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p; 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last = p; 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 67052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if ((s->pkt_first->len + p->len) > s->get_max_payload()) { 6717a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): overflow", s->id); 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao memcpy(s->pkt_first->data + s->pkt_first->len, p->data, p->len); 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first->len += p->len; 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = s->pkt_first; 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6837e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao /* don't bother if we can't decode the length */ 68452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (p->len < 4) { 68552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao return 0; 68652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao } 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = unhex(p->data, 4); 6897e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao if ((len < 1) || (len > MAX_PAYLOAD_V1)) { 6907a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): bad size (%d)", s->id, len); 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): len is %d", s->id, len); 6957e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao /* can't do anything until we have the full header */ 69652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if ((len + 4) > p->len) { 69706d61d4d96d28777f76578fb5d3c823168853166Josh Gao D("SS(%d): waiting for %zu more bytes", s->id, len + 4 - p->len); 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->data[len + 4] = 0; 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): '%s'", s->id, (char*)(p->data + 4)); 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 70652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao service = (char*)p->data + 4; 70752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (!strncmp(service, "host-serial:", strlen("host-serial:"))) { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial_end; 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-serial:"); 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock // serial number should follow "host:" and could be a host:port string. 7123f902aad5b427a8162bf860a758878b55b13e775David Pursell serial_end = internal::skip_host_serial(service); 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial_end) { 71452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao *serial_end = 0; // terminate string 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial = service; 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service = serial_end + 1; 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { 7193bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportUsb; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-usb:"); 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { 7223bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportLocal; 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-local:"); 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host:", strlen("host:"))) { 7253bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportAny; 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host:"); 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 7288d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes service = nullptr; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (service) { 73252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s2; 73352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao 73452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* some requests are handled immediately -- in that 73552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** case the handle_host_request() routine has sent 73652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** the OKAY or FAIL message and all we have to do 73752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** is clean up. 73852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 73952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (handle_host_request(service, type, serial, s->peer->fd, s) == 0) { 74052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* XXX fail message? */ 74152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): handled host service '%s'", s->id, service); 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport", strlen("transport"))) { 74552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): okay transport", s->id); 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = 0; 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* try to find a local service with this name. 75152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** if no such service exists, we'll fail out 75252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** and tear down here. 75352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2 = create_host_service_socket(service, serial); 75552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s2 == 0) { 75652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): couldn't create host service '%s'", s->id, service); 757e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->peer->fd, "unknown host service"); 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* we've connected to a local host service, 76252bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** so we make our peer back into a regular 76352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** local socket and bind it to the new local 76452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** service socket, acknowledge the successful 76552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** connection, and close this smart socket now 76652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** that its work is done. 76752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 768e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(s->peer->fd); 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready; 7718d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->peer->shutdown = nullptr; 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close; 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s2; 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->peer = s->peer; 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 77652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao D("SS(%d): okay", s->id); 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* initial state is "ready" */ 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->ready(s2); 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */ 7848d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes if (s->transport == nullptr) { 7857be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes std::string error_msg = "unknown failure"; 7868d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg); 7878d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes if (s->transport == nullptr) { 788e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->peer->fd, error_msg); 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79422d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao if (!s->transport) { 79522d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao SendFail(s->peer->fd, "device offline (no transport)"); 79622d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao goto fail; 79722d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao } else if (s->transport->connection_state == kCsOffline) { 79852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* if there's no remote we fail the connection 79952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** right here and terminate it 80052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 80122d2b3e1c2e1152ca9cf86c3eb42cd42e7448a31Josh Gao SendFail(s->peer->fd, "device offline (transport offline)"); 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* instrument our peer to pass the success or fail 80652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** message back once it connects or closes, then 80752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** detach from it, request the connection, and 80852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** tear down 80952bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready_notify; 8118d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->peer->shutdown = nullptr; 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close_notify; 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 81452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* give him our transport and upref it */ 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->transport = s->transport; 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao connect_to_remote(s->peer, (char*)(p->data + 4)); 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 82352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao /* we're going to close our peer as a side-effect, so 82452bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** return -1 to signal that state to the local socket 82552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao ** who is enqueueing against us 82652bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao */ 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void smart_socket_ready(asocket* s) { 8327a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): ready", s->id); 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83552bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic void smart_socket_close(asocket* s) { 8367a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): closed", s->id); 83752bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->pkt_first) { 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(s->pkt_first); 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 84052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao if (s->peer) { 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 84349f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin s->peer = 0; 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84852bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaostatic asocket* create_smart_socket(void) { 8497a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Creating smart socket"); 85052bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 851c419e2a210ad7e37a1f749f2ab4de7c7f95b90d7André Goddard Rosa if (s == NULL) fatal("cannot allocate socket"); 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = smart_socket_enqueue; 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = smart_socket_ready; 854818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = smart_socket_close; 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8577a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d)", s->id); 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86152bd8526aaaf10511177fb42c55c26bc722b0833Josh Gaovoid connect_to_smartsocket(asocket* s) { 8627a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Connecting to smart socket"); 86352bd8526aaaf10511177fb42c55c26bc722b0833Josh Gao asocket* ss = create_smart_socket(); 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = ss; 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ss->peer = s; 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 8683d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer 8693d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammersize_t asocket::get_max_payload() const { 8703d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer size_t max_payload = MAX_PAYLOAD; 8713d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer if (transport) { 8723d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer max_payload = std::min(max_payload, transport->get_max_payload()); 8733d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer } 8743d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer if (peer && peer->transport) { 8753d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer max_payload = std::min(max_payload, peer->transport->get_max_payload()); 8763d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer } 8773d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer return max_payload; 8783d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer} 879