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> 29268068f25673242d1d5130d96202d3288c91b700Josh Gao#include <mutex> 30802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell#include <string> 31802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell#include <vector> 32363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low 337664901a355b959f312e9acff5a0fd31b7139623Dan Albert#if !ADB_HOST 347664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "cutils/properties.h" 357664901a355b959f312e9acff5a0fd31b7139623Dan Albert#endif 363313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 373313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb.h" 383313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb_io.h" 39268068f25673242d1d5130d96202d3288c91b700Josh Gao#include "sysdeps/mutex.h" 407664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h" 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 42268068f25673242d1d5130d96202d3288c91b700Josh 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 = { 4663760409ad833cf803482e098367f49741b5f6d3Josh 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 = { 5463760409ad833cf803482e098367f49741b5f6d3Josh 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. 6063760409ad833cf803482e098367f49741b5f6d3Josh Gaoasocket* find_local_socket(unsigned local_id, unsigned peer_id) { 6163760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s; 6263760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* result = NULL; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64268068f25673242d1d5130d96202d3288c91b700Josh 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) { 6663760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->id != local_id) { 67818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner continue; 6863760409ad833cf803482e098367f49741b5f6d3Josh 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 7863760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void insert_local_socket(asocket* s, asocket* list) { 7963760409ad833cf803482e098367f49741b5f6d3Josh Gao s->next = list; 8063760409ad833cf803482e098367f49741b5f6d3Josh 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 8563760409ad833cf803482e098367f49741b5f6d3Josh Gaovoid install_local_socket(asocket* s) { 86268068f25673242d1d5130d96202d3288c91b700Josh 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. 9163760409ad833cf803482e098367f49741b5f6d3Josh Gao if (local_socket_next_id == 0) { 92268068f25673242d1d5130d96202d3288c91b700Josh Gao fatal("local socket id overflow"); 9363760409ad833cf803482e098367f49741b5f6d3Josh 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 9863760409ad833cf803482e098367f49741b5f6d3Josh Gaovoid remove_socket(asocket* s) { 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // socket_list_lock should already be held 10063760409ad833cf803482e098367f49741b5f6d3Josh 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 10963760409ad833cf803482e098367f49741b5f6d3Josh Gaovoid close_all_sockets(atransport* t) { 11063760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11263760409ad833cf803482e098367f49741b5f6d3Josh Gao /* this is a little gross, but since s->close() *will* modify 11363760409ad833cf803482e098367f49741b5f6d3Josh Gao ** the list out from under you, your options are limited. 11463760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 115268068f25673242d1d5130d96202d3288c91b700Josh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrestart: 11763760409ad833cf803482e098367f49741b5f6d3Josh Gao for (s = local_socket_list.next; s != &local_socket_list; s = s->next) { 11863760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->transport == t || (s->peer && s->peer->transport == t)) { 119014b01706cc64dc9c2ad94a96f62e07c058d0b5dJosh 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 12563760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic int local_socket_enqueue(asocket* s, apacket* p) { 1267a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): enqueue %d", s->id, p->len); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->ptr = p->data; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 13063760409ad833cf803482e098367f49741b5f6d3Josh Gao /* if there is already data queue'd, we will receive 13163760409ad833cf803482e098367f49741b5f6d3Josh Gao ** events when it's time to write. just add this to 13263760409ad833cf803482e098367f49741b5f6d3Josh Gao ** the tail 13363760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 13463760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->pkt_first) { 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto enqueue; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 13863760409ad833cf803482e098367f49741b5f6d3Josh Gao /* write as much as we can, until we 13963760409ad833cf803482e098367f49741b5f6d3Josh Gao ** would block or there is an error/eof 14063760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 14163760409ad833cf803482e098367f49741b5f6d3Josh Gao while (p->len > 0) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r = adb_write(s->fd, p->ptr, p->len); 14363760409ad833cf803482e098367f49741b5f6d3Josh 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 } 14863760409ad833cf803482e098367f49741b5f6d3Josh Gao if ((r == 0) || (errno != EAGAIN)) { 14963760409ad833cf803482e098367f49741b5f6d3Josh 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 15963760409ad833cf803482e098367f49741b5f6d3Josh 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; 16663760409ad833cf803482e098367f49741b5f6d3Josh 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 17363760409ad833cf803482e098367f49741b5f6d3Josh 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 17963760409ad833cf803482e098367f49741b5f6d3Josh 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 18663760409ad833cf803482e098367f49741b5f6d3Josh 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 19263760409ad833cf803482e098367f49741b5f6d3Josh Gao /* IMPORTANT: the remove closes the fd 19363760409ad833cf803482e098367f49741b5f6d3Josh Gao ** that belongs to this socket 19463760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fdevent_remove(&s->fde); 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19763760409ad833cf803482e098367f49741b5f6d3Josh Gao /* dispose of any unwritten data */ 19863760409ad833cf803482e098367f49741b5f6d3Josh Gao for (p = s->pkt_first; p; p = n) { 1997a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): discarding %d 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 212268068f25673242d1d5130d96202d3288c91b700Josh Gaostatic void local_socket_close(asocket* s) { 213268068f25673242d1d5130d96202d3288c91b700Josh Gao D("entered local_socket_close. LS(%d) fd=%d", s->id, s->fd); 214268068f25673242d1d5130d96202d3288c91b700Josh Gao std::lock_guard<std::recursive_mutex> lock(local_socket_list_lock); 21563760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->peer) { 21663760409ad833cf803482e098367f49741b5f6d3Josh 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. */ 22163760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->peer->shutdown) { 22263760409ad833cf803482e098367f49741b5f6d3Josh Gao s->peer->shutdown(s->peer); 22363760409ad833cf803482e098367f49741b5f6d3Josh Gao } 224268068f25673242d1d5130d96202d3288c91b700Josh Gao s->peer->peer = nullptr; 225268068f25673242d1d5130d96202d3288c91b700Josh Gao s->peer->close(s->peer); 226268068f25673242d1d5130d96202d3288c91b700Josh Gao s->peer = nullptr; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22963760409ad833cf803482e098367f49741b5f6d3Josh Gao /* If we are already closing, or if there are no 23063760409ad833cf803482e098367f49741b5f6d3Josh Gao ** pending packets, destroy immediately 23163760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 232c1b1f6ff5de82b457923eea3f0bbad1ac2e459d7Yabin Cui if (s->closing || s->has_write_error || s->pkt_first == NULL) { 23363760409ad833cf803482e098367f49741b5f6d3Josh 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 23963760409ad833cf803482e098367f49741b5f6d3Josh Gao /* otherwise, put on the closing list 24063760409ad833cf803482e098367f49741b5f6d3Josh 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 25063760409ad833cf803482e098367f49741b5f6d3Josh 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) { 30863760409ad833cf803482e098367f49741b5f6d3Josh Gao apacket* p = get_apacket(); 30963760409ad833cf803482e098367f49741b5f6d3Josh Gao unsigned 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); 31763760409ad833cf803482e098367f49741b5f6d3Josh Gao D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu", s->id, s->fd, r, 31863760409ad833cf803482e098367f49741b5f6d3Josh 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 } 33363760409ad833cf803482e098367f49741b5f6d3Josh Gao D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d", s->id, s->fd, r, is_eof, 33463760409ad833cf803482e098367f49741b5f6d3Josh 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) { 34863760409ad833cf803482e098367f49741b5f6d3Josh Gao /* error return means they closed us as a side-effect 34963760409ad833cf803482e098367f49741b5f6d3Josh Gao ** and we must return immediately. 35063760409ad833cf803482e098367f49741b5f6d3Josh Gao ** 35163760409ad833cf803482e098367f49741b5f6d3Josh Gao ** note that if we still have buffered packets, the 35263760409ad833cf803482e098367f49741b5f6d3Josh Gao ** socket will be placed on the closing socket list. 35363760409ad833cf803482e098367f49741b5f6d3Josh Gao ** this handler function will be called again 35463760409ad833cf803482e098367f49741b5f6d3Josh Gao ** to process FDE_WRITE events. 35563760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (r > 0) { 36063760409ad833cf803482e098367f49741b5f6d3Josh Gao /* if the remote cannot accept further events, 36163760409ad833cf803482e098367f49741b5f6d3Josh Gao ** we disable notification of READs. They'll 36263760409ad833cf803482e098367f49741b5f6d3Josh Gao ** be enabled again when we get a call to ready() 36363760409ad833cf803482e098367f49741b5f6d3Josh 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) { 36963760409ad833cf803482e098367f49741b5f6d3Josh 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 37563760409ad833cf803482e098367f49741b5f6d3Josh Gao if (ev & FDE_ERROR) { 37663760409ad833cf803482e098367f49741b5f6d3Josh Gao /* this should be caught be the next read or write 37763760409ad833cf803482e098367f49741b5f6d3Josh Gao ** catching it here means we may skip the last few 37863760409ad833cf803482e098367f49741b5f6d3Josh Gao ** bytes of readable data. 37963760409ad833cf803482e098367f49741b5f6d3Josh 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 38563760409ad833cf803482e098367f49741b5f6d3Josh Gaoasocket* create_local_socket(int fd) { 38663760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 38763760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s == NULL) { 38863760409ad833cf803482e098367f49741b5f6d3Josh Gao fatal("cannot allocate socket"); 38963760409ad833cf803482e098367f49741b5f6d3Josh 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 40263760409ad833cf803482e098367f49741b5f6d3Josh Gaoasocket* create_local_service_socket(const char* name, const atransport* transport) { 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 40463760409ad833cf803482e098367f49741b5f6d3Josh Gao if (!strcmp(name, "jdwp")) { 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_jdwp_service_socket(); 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 40763760409ad833cf803482e098367f49741b5f6d3Josh 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); 41263760409ad833cf803482e098367f49741b5f6d3Josh Gao if (fd < 0) { 41363760409ad833cf803482e098367f49741b5f6d3Josh Gao return 0; 41463760409ad833cf803482e098367f49741b5f6d3Josh 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 4209885881d0689e7999f2d7e7558e894dc73a0a0b0Dan Pasanen char debug[PROPERTY_VALUE_MAX]; 42163760409ad833cf803482e098367f49741b5f6d3Josh Gao if (!strncmp(name, "root:", 5)) { 4221297d22bc99c26b2ad414faedd5bea73a16ecb90jzhuan property_get("ro.debuggable", debug, ""); 42363760409ad833cf803482e098367f49741b5f6d3Josh Gao } 4241297d22bc99c26b2ad414faedd5bea73a16ecb90jzhuan 42563760409ad833cf803482e098367f49741b5f6d3Josh Gao if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0) || 42663760409ad833cf803482e098367f49741b5f6d3Josh Gao (!strncmp(name, "unroot:", 7) && getuid() == 0) || 42763760409ad833cf803482e098367f49741b5f6d3Josh Gao !strncmp(name, "usb:", 4) || 42863760409ad833cf803482e098367f49741b5f6d3Josh Gao !strncmp(name, "tcpip:", 6)) { 4297a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): enabling exit_on_close", s->id); 430f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby s->exit_on_close = 1; 431f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby } 432f91259a8f0d75d721761d588a4b811427565c984JP Abgrall#endif 433f366b3698b409405e1ee88476d1186f29fe14b06Benoit Goby 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 43863760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic asocket* create_host_service_socket(const char* name, const char* serial) { 43963760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s; 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = host_service_to_socket(name, serial); 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s != NULL) { 4447a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d) bound to '%s'", s->id, name); 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45263760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic int remote_socket_enqueue(asocket* s, apacket* p) { 45363760409ad833cf803482e098367f49741b5f6d3Josh Gao D("entered remote_socket_enqueue RS(%d) WRITE fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_WRTE; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = p->len; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46263760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void remote_socket_ready(asocket* s) { 46363760409ad833cf803482e098367f49741b5f6d3Josh Gao D("entered remote_socket_ready RS(%d) OKAY fd=%d peer.fd=%d", s->id, s->fd, s->peer->fd); 46463760409ad833cf803482e098367f49741b5f6d3Josh Gao apacket* p = get_apacket(); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OKAY; 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = s->id; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47163760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void remote_socket_shutdown(asocket* s) { 47263760409ad833cf803482e098367f49741b5f6d3Josh Gao D("entered remote_socket_shutdown RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd, 47363760409ad833cf803482e098367f49741b5f6d3Josh Gao s->peer ? s->peer->fd : -1); 47463760409ad833cf803482e098367f49741b5f6d3Josh Gao apacket* p = get_apacket(); 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_CLSE; 47663760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->peer) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->peer->id; 478818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } 479818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg1 = s->id; 480818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner send_packet(p, s->transport); 481818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner} 482818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner 48363760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void remote_socket_close(asocket* s) { 484818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (s->peer) { 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 48663760409ad833cf803482e098367f49741b5f6d3Josh Gao D("RS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd); 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 48963760409ad833cf803482e098367f49741b5f6d3Josh Gao D("entered remote_socket_close RS(%d) CLOSE fd=%d peer->fd=%d", s->id, s->fd, 49063760409ad833cf803482e098367f49741b5f6d3Josh Gao s->peer ? s->peer->fd : -1); 4917a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("RS(%d): closed", s->id); 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 495fd28f327ee0e110208ef42ded829286643860394Yabin Cui// Create a remote socket to exchange packets with a remote service through transport 496fd28f327ee0e110208ef42ded829286643860394Yabin Cui// |t|. Where |id| is the socket id of the corresponding service on the other 497fd28f327ee0e110208ef42ded829286643860394Yabin Cui// side of the transport (it is allocated by the remote side and _cannot_ be 0). 498fd28f327ee0e110208ef42ded829286643860394Yabin Cui// Returns a new non-NULL asocket handle. 49963760409ad833cf803482e098367f49741b5f6d3Josh Gaoasocket* create_remote_socket(unsigned id, atransport* t) { 50063760409ad833cf803482e098367f49741b5f6d3Josh Gao if (id == 0) { 50163760409ad833cf803482e098367f49741b5f6d3Josh Gao fatal("invalid remote socket id (0)"); 50263760409ad833cf803482e098367f49741b5f6d3Josh Gao } 503fd28f327ee0e110208ef42ded829286643860394Yabin Cui asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50563760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s == NULL) { 50663760409ad833cf803482e098367f49741b5f6d3Josh Gao fatal("cannot allocate socket"); 50763760409ad833cf803482e098367f49741b5f6d3Josh Gao } 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->id = id; 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = remote_socket_enqueue; 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = remote_socket_ready; 511818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = remote_socket_shutdown; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = remote_socket_close; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->transport = t; 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5157a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("RS(%d): created", s->id); 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51963760409ad833cf803482e098367f49741b5f6d3Josh Gaovoid connect_to_remote(asocket* s, const char* destination) { 5207a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Connect_to_remote call RS(%d) fd=%d", s->id, s->fd); 52163760409ad833cf803482e098367f49741b5f6d3Josh Gao apacket* p = get_apacket(); 5223d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer size_t len = strlen(destination) + 1; 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52463760409ad833cf803482e098367f49741b5f6d3Josh Gao if (len > (s->get_max_payload() - 1)) { 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal("destination oversized"); 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5287a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("LS(%d): connect('%s')", s->id, destination); 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OPEN; 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = s->id; 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.data_length = len; 53263760409ad833cf803482e098367f49741b5f6d3Josh Gao strcpy((char*)p->data, destination); 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, s->transport); 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the go-ahead message when they connect */ 53863760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void local_socket_ready_notify(asocket* s) { 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 540818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 542e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(s->fd); 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* this is used by magic sockets to rig local sockets to 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send the failure message if they are closed before 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project connected (to avoid closing them without a status message) */ 54963760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void local_socket_close_notify(asocket* s) { 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = local_socket_ready; 551818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = local_socket_close; 553e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->fd, "closed"); 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55763760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic unsigned unhex(unsigned char* s, int len) { 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned n = 0, c; 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56063760409ad833cf803482e098367f49741b5f6d3Josh Gao while (len-- > 0) { 56163760409ad833cf803482e098367f49741b5f6d3Josh Gao switch ((c = *s++)) { 56263760409ad833cf803482e098367f49741b5f6d3Josh Gao case '0': 56363760409ad833cf803482e098367f49741b5f6d3Josh Gao case '1': 56463760409ad833cf803482e098367f49741b5f6d3Josh Gao case '2': 56563760409ad833cf803482e098367f49741b5f6d3Josh Gao case '3': 56663760409ad833cf803482e098367f49741b5f6d3Josh Gao case '4': 56763760409ad833cf803482e098367f49741b5f6d3Josh Gao case '5': 56863760409ad833cf803482e098367f49741b5f6d3Josh Gao case '6': 56963760409ad833cf803482e098367f49741b5f6d3Josh Gao case '7': 57063760409ad833cf803482e098367f49741b5f6d3Josh Gao case '8': 57163760409ad833cf803482e098367f49741b5f6d3Josh Gao case '9': 57263760409ad833cf803482e098367f49741b5f6d3Josh Gao c -= '0'; 57363760409ad833cf803482e098367f49741b5f6d3Josh Gao break; 57463760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'a': 57563760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'b': 57663760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'c': 57763760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'd': 57863760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'e': 57963760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'f': 58063760409ad833cf803482e098367f49741b5f6d3Josh Gao c = c - 'a' + 10; 58163760409ad833cf803482e098367f49741b5f6d3Josh Gao break; 58263760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'A': 58363760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'B': 58463760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'C': 58563760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'D': 58663760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'E': 58763760409ad833cf803482e098367f49741b5f6d3Josh Gao case 'F': 58863760409ad833cf803482e098367f49741b5f6d3Josh Gao c = c - 'A' + 10; 58963760409ad833cf803482e098367f49741b5f6d3Josh Gao break; 59063760409ad833cf803482e098367f49741b5f6d3Josh Gao default: 59163760409ad833cf803482e098367f49741b5f6d3Josh Gao return 0xffffffff; 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = (n << 4) | c; 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return n; 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 600e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#if ADB_HOST 601e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 602802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursellnamespace internal { 603802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell 604802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// Returns the position in |service| following the target serial parameter. Serial format can be 605802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// any of: 606802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// * [tcp:|udp:]<serial>[:<port>]:<command> 607802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// * <prefix>:<serial>:<command> 608802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// Where <port> must be a base-10 number and <prefix> may be any of {usb,product,model,device}. 609802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// 610802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell// The returned pointer will point to the ':' just before <command>, or nullptr if not found. 611802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursellchar* skip_host_serial(const char* service) { 612802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell static const std::vector<std::string>& prefixes = 613802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell *(new std::vector<std::string>{"usb:", "product:", "model:", "device:"}); 614802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell 615802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell for (const std::string& prefix : prefixes) { 616802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell if (!strncmp(service, prefix.c_str(), prefix.length())) { 617802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell return strchr(service + prefix.length(), ':'); 618802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell } 619802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell } 620802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell 621802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell // For fastboot compatibility, ignore protocol prefixes. 622802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell if (!strncmp(service, "tcp:", 4) || !strncmp(service, "udp:", 4)) { 623802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell service += 4; 6243608d832425ca3a6d00c4040f3bb979c5aa49899Scott Anderson } 6253608d832425ca3a6d00c4040f3bb979c5aa49899Scott Anderson 626802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell char* first_colon = strchr(service, ':'); 62728e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if (!first_colon) { 628802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell // No colon in service string. 629802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell return nullptr; 63028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 631802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell 632802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell char* serial_end = first_colon; 63328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock if (isdigit(serial_end[1])) { 63428e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 635802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell while (*serial_end && isdigit(*serial_end)) { 63628e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end++; 63728e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 638802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell if (*serial_end != ':') { 63928e1390e688f721e13a9877d3c41884bf151db60Terence Haddock // Something other than numbers was found, reset the end. 64028e1390e688f721e13a9877d3c41884bf151db60Terence Haddock serial_end = first_colon; 64128e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 64228e1390e688f721e13a9877d3c41884bf151db60Terence Haddock } 64328e1390e688f721e13a9877d3c41884bf151db60Terence Haddock return serial_end; 64428e1390e688f721e13a9877d3c41884bf151db60Terence Haddock} 64528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock 646802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell} // namespace internal 647802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell 64863760409ad833cf803482e098367f49741b5f6d3Josh Gao#endif // ADB_HOST 649e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 65063760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic int smart_socket_enqueue(asocket* s, apacket* p) { 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned len; 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 65363760409ad833cf803482e098367f49741b5f6d3Josh Gao char* service = nullptr; 6548d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes char* serial = nullptr; 6553bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes TransportType type = kTransportAny; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6587a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): enqueue %d", s->id, p->len); 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66063760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->pkt_first == 0) { 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first = p; 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_last = p; 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 66463760409ad833cf803482e098367f49741b5f6d3Josh Gao if ((s->pkt_first->len + p->len) > s->get_max_payload()) { 6657a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): overflow", s->id); 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67063760409ad833cf803482e098367f49741b5f6d3Josh Gao memcpy(s->pkt_first->data + s->pkt_first->len, p->data, p->len); 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->pkt_first->len += p->len; 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = s->pkt_first; 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6777e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao /* don't bother if we can't decode the length */ 67863760409ad833cf803482e098367f49741b5f6d3Josh Gao if (p->len < 4) { 67963760409ad833cf803482e098367f49741b5f6d3Josh Gao return 0; 68063760409ad833cf803482e098367f49741b5f6d3Josh Gao } 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = unhex(p->data, 4); 6837e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao if ((len < 1) || (len > MAX_PAYLOAD_V1)) { 6847a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): bad size (%d)", s->id, len); 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68863760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): len is %d", s->id, len); 6897e6683ce40ba79c94ccc1e3b984cd39e63651dd5Josh Gao /* can't do anything until we have the full header */ 69063760409ad833cf803482e098367f49741b5f6d3Josh Gao if ((len + 4) > p->len) { 69163760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): waiting for %d more bytes", s->id, len + 4 - p->len); 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->data[len + 4] = 0; 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69763760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): '%s'", s->id, (char*)(p->data + 4)); 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 70063760409ad833cf803482e098367f49741b5f6d3Josh Gao service = (char*)p->data + 4; 70163760409ad833cf803482e098367f49741b5f6d3Josh Gao if (!strncmp(service, "host-serial:", strlen("host-serial:"))) { 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial_end; 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-serial:"); 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70528e1390e688f721e13a9877d3c41884bf151db60Terence Haddock // serial number should follow "host:" and could be a host:port string. 706802c54ebb79453256a8c7fd3c3cab88acc8a84e8David Pursell serial_end = internal::skip_host_serial(service); 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial_end) { 70863760409ad833cf803482e098367f49741b5f6d3Josh Gao *serial_end = 0; // terminate string 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial = service; 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service = serial_end + 1; 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { 7133bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportUsb; 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-usb:"); 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { 7163bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportLocal; 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host-local:"); 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "host:", strlen("host:"))) { 7193bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes type = kTransportAny; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("host:"); 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 7228d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes service = nullptr; 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (service) { 72663760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s2; 72763760409ad833cf803482e098367f49741b5f6d3Josh Gao 72863760409ad833cf803482e098367f49741b5f6d3Josh Gao /* some requests are handled immediately -- in that 72963760409ad833cf803482e098367f49741b5f6d3Josh Gao ** case the handle_host_request() routine has sent 73063760409ad833cf803482e098367f49741b5f6d3Josh Gao ** the OKAY or FAIL message and all we have to do 73163760409ad833cf803482e098367f49741b5f6d3Josh Gao ** is clean up. 73263760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 73363760409ad833cf803482e098367f49741b5f6d3Josh Gao if (handle_host_request(service, type, serial, s->peer->fd, s) == 0) { 73463760409ad833cf803482e098367f49741b5f6d3Josh Gao /* XXX fail message? */ 73563760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): handled host service '%s'", s->id, service); 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport", strlen("transport"))) { 73963760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): okay transport", s->id); 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = 0; 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74463760409ad833cf803482e098367f49741b5f6d3Josh Gao /* try to find a local service with this name. 74563760409ad833cf803482e098367f49741b5f6d3Josh Gao ** if no such service exists, we'll fail out 74663760409ad833cf803482e098367f49741b5f6d3Josh Gao ** and tear down here. 74763760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2 = create_host_service_socket(service, serial); 74963760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s2 == 0) { 75063760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): couldn't create host service '%s'", s->id, service); 751e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->peer->fd, "unknown host service"); 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75563760409ad833cf803482e098367f49741b5f6d3Josh Gao /* we've connected to a local host service, 75663760409ad833cf803482e098367f49741b5f6d3Josh Gao ** so we make our peer back into a regular 75763760409ad833cf803482e098367f49741b5f6d3Josh Gao ** local socket and bind it to the new local 75863760409ad833cf803482e098367f49741b5f6d3Josh Gao ** service socket, acknowledge the successful 75963760409ad833cf803482e098367f49741b5f6d3Josh Gao ** connection, and close this smart socket now 76063760409ad833cf803482e098367f49741b5f6d3Josh Gao ** that its work is done. 76163760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 762e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(s->peer->fd); 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready; 7658d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->peer->shutdown = nullptr; 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close; 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s2; 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->peer = s->peer; 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 77063760409ad833cf803482e098367f49741b5f6d3Josh Gao D("SS(%d): okay", s->id); 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77363760409ad833cf803482e098367f49741b5f6d3Josh Gao /* initial state is "ready" */ 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s2->ready(s2); 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */ 7788d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes if (s->transport == nullptr) { 7797be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes std::string error_msg = "unknown failure"; 7808d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg); 7818d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes if (s->transport == nullptr) { 782e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->peer->fd, error_msg); 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78863760409ad833cf803482e098367f49741b5f6d3Josh Gao if (!(s->transport) || (s->transport->connection_state == kCsOffline)) { 78963760409ad833cf803482e098367f49741b5f6d3Josh Gao /* if there's no remote we fail the connection 79063760409ad833cf803482e098367f49741b5f6d3Josh Gao ** right here and terminate it 79163760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 792e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(s->peer->fd, "device offline (x)"); 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79663760409ad833cf803482e098367f49741b5f6d3Josh Gao /* instrument our peer to pass the success or fail 79763760409ad833cf803482e098367f49741b5f6d3Josh Gao ** message back once it connects or closes, then 79863760409ad833cf803482e098367f49741b5f6d3Josh Gao ** detach from it, request the connection, and 79963760409ad833cf803482e098367f49741b5f6d3Josh Gao ** tear down 80063760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->ready = local_socket_ready_notify; 8028d28e191c5ba81b82e51e3fd120d03851e1d905fElliott Hughes s->peer->shutdown = nullptr; 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close = local_socket_close_notify; 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 80563760409ad833cf803482e098367f49741b5f6d3Josh Gao /* give him our transport and upref it */ 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->transport = s->transport; 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80863760409ad833cf803482e098367f49741b5f6d3Josh Gao connect_to_remote(s->peer, (char*)(p->data + 4)); 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = 0; 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 81463760409ad833cf803482e098367f49741b5f6d3Josh Gao /* we're going to close our peer as a side-effect, so 81563760409ad833cf803482e098367f49741b5f6d3Josh Gao ** return -1 to signal that state to the local socket 81663760409ad833cf803482e098367f49741b5f6d3Josh Gao ** who is enqueueing against us 81763760409ad833cf803482e098367f49741b5f6d3Josh Gao */ 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close(s); 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82263760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void smart_socket_ready(asocket* s) { 8237a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): ready", s->id); 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 82663760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic void smart_socket_close(asocket* s) { 8277a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d): closed", s->id); 82863760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->pkt_first) { 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(s->pkt_first); 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 83163760409ad833cf803482e098367f49741b5f6d3Josh Gao if (s->peer) { 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = 0; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->close(s->peer); 83449f1857dd8b64cdd57f28e965a1ff5fa0c2b0547Tom Marlin s->peer = 0; 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(s); 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83963760409ad833cf803482e098367f49741b5f6d3Josh Gaostatic asocket* create_smart_socket(void) { 8407a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Creating smart socket"); 84163760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); 842c419e2a210ad7e37a1f749f2ab4de7c7f95b90d7André Goddard Rosa if (s == NULL) fatal("cannot allocate socket"); 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->enqueue = smart_socket_enqueue; 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready = smart_socket_ready; 845818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->shutdown = NULL; 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->close = smart_socket_close; 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8487a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("SS(%d)", s->id); 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85263760409ad833cf803482e098367f49741b5f6d3Josh Gaovoid connect_to_smartsocket(asocket* s) { 8537a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Connecting to smart socket"); 85463760409ad833cf803482e098367f49741b5f6d3Josh Gao asocket* ss = create_smart_socket(); 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = ss; 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ss->peer = s; 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 8593d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer 8603d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammersize_t asocket::get_max_payload() const { 8613d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer size_t max_payload = MAX_PAYLOAD; 8623d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer if (transport) { 8633d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer max_payload = std::min(max_payload, transport->get_max_payload()); 8643d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer } 8653d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer if (peer && peer->transport) { 8663d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer max_payload = std::min(max_payload, peer->transport->get_max_payload()); 8673d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer } 8683d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer return max_payload; 8693d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer} 870