10469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/* 20469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Copyright 2011, The Android Open Source Project 30469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * 40469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Licensed under the Apache License, Version 2.0 (the "License"); 50469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * you may not use this file except in compliance with the License. 60469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * You may obtain a copy of the License at 70469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * 80469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * http://www.apache.org/licenses/LICENSE-2.0 90469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * 100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Unless required by applicable law or agreed to in writing, software 110469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * distributed under the License is distributed on an "AS IS" BASIS, 120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * See the License for the specific language governing permissions and 140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * limitations under the License. 150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */ 160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 172fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy#include <errno.h> 180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <stdlib.h> 190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <unistd.h> 200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 210832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy#include <unistd.h> 220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <sys/socket.h> 230832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy#include <sys/un.h> 240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <netinet/in.h> 250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <cutils/log.h> 278e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy#include <private/android_filesystem_config.h> 280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_transport.h" 300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android { 320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace { 330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 340832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamyint acceptClientConnection(char *sockname) { 350832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy int serverSocket = socket(AF_LOCAL, SOCK_STREAM, 0); 3693a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (serverSocket < 0) { 37e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error (%d) while creating socket. Check if app has network permissions.", 3893a826f78f6313db791e6fc880439189897651b3Siva Velusamy serverSocket); 3993a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 420832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy struct sockaddr_un server, client; 430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 440832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy memset(&server, 0, sizeof server); 450832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy server.sun_family = AF_UNIX; 460832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy // the first byte of sun_path should be '\0' for abstract namespace 470832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy strcpy(server.sun_path + 1, sockname); 480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 490832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy // note that sockaddr_len should be set to the exact size of the buffer that is used. 500832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy socklen_t sockaddr_len = sizeof(server.sun_family) + strlen(sockname) + 1; 510832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy if (bind(serverSocket, (struct sockaddr *) &server, sockaddr_len) < 0) { 5293a826f78f6313db791e6fc880439189897651b3Siva Velusamy close(serverSocket); 53e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Failed to bind the server socket"); 5493a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 5793a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (listen(serverSocket, 1) < 0) { 5893a826f78f6313db791e6fc880439189897651b3Siva Velusamy close(serverSocket); 59e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Failed to listen on server socket"); 6093a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 630832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy ALOGD("gltrace::waitForClientConnection: server listening @ path %s", sockname); 640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 6593a826f78f6313db791e6fc880439189897651b3Siva Velusamy int clientSocket = accept(serverSocket, (struct sockaddr *)&client, &sockaddr_len); 6693a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (clientSocket < 0) { 6793a826f78f6313db791e6fc880439189897651b3Siva Velusamy close(serverSocket); 68e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Failed to accept client connection"); 6993a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 728e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy struct ucred cr; 738e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy socklen_t cr_len = sizeof(cr); 748e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy if (getsockopt(clientSocket, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0) { 758e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy ALOGE("Error obtaining credentials of peer"); 768e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy return -1; 778e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy } 788e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy 79c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy // Only accept connects from the shell (adb forward comes to us as shell user), 80c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy // or the root user. 81c7d767ad57a25eeefbbfe2610396d800f04178edSiva Velusamy if (cr.uid != AID_SHELL && cr.uid != AID_ROOT) { 828e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy ALOGE("Unknown peer type (%d), expected shell to be the peer", cr.uid); 838e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy return -1; 848e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy } 858e2f3858d5a06dae5a543d9428278f59120f7f8cSiva Velusamy 860832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy ALOGD("gltrace::waitForClientConnection: client connected."); 8793a826f78f6313db791e6fc880439189897651b3Siva Velusamy 8893a826f78f6313db791e6fc880439189897651b3Siva Velusamy // do not accept any more incoming connections 8993a826f78f6313db791e6fc880439189897651b3Siva Velusamy close(serverSocket); 9093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 9193a826f78f6313db791e6fc880439189897651b3Siva Velusamy return clientSocket; 9293a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 9393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 9493a826f78f6313db791e6fc880439189897651b3Siva VelusamyTCPStream::TCPStream(int socket) { 9593a826f78f6313db791e6fc880439189897651b3Siva Velusamy mSocket = socket; 9693a826f78f6313db791e6fc880439189897651b3Siva Velusamy pthread_mutex_init(&mSocketWriteMutex, NULL); 970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 980469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 9993a826f78f6313db791e6fc880439189897651b3Siva VelusamyTCPStream::~TCPStream() { 10093a826f78f6313db791e6fc880439189897651b3Siva Velusamy pthread_mutex_destroy(&mSocketWriteMutex); 10193a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 10293a826f78f6313db791e6fc880439189897651b3Siva Velusamy 10393a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid TCPStream::closeStream() { 10493a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (mSocket > 0) { 10593a826f78f6313db791e6fc880439189897651b3Siva Velusamy close(mSocket); 10693a826f78f6313db791e6fc880439189897651b3Siva Velusamy mSocket = 0; 1070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 1080469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1090469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 11093a826f78f6313db791e6fc880439189897651b3Siva Velusamyint TCPStream::send(void *buf, size_t len) { 11193a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (mSocket <= 0) { 11293a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 1130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 1140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 11593a826f78f6313db791e6fc880439189897651b3Siva Velusamy pthread_mutex_lock(&mSocketWriteMutex); 11693a826f78f6313db791e6fc880439189897651b3Siva Velusamy int n = write(mSocket, buf, len); 11793a826f78f6313db791e6fc880439189897651b3Siva Velusamy pthread_mutex_unlock(&mSocketWriteMutex); 11893a826f78f6313db791e6fc880439189897651b3Siva Velusamy 11993a826f78f6313db791e6fc880439189897651b3Siva Velusamy return n; 12093a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 1210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 12293a826f78f6313db791e6fc880439189897651b3Siva Velusamyint TCPStream::receive(void *data, size_t len) { 12393a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (mSocket <= 0) { 12493a826f78f6313db791e6fc880439189897651b3Siva Velusamy return -1; 1250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 1260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1272fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy size_t totalRead = 0; 1282fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy while (totalRead < len) { 1292fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy int n = read(mSocket, (uint8_t*)data + totalRead, len - totalRead); 1302fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (n < 0) { 1312fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy ALOGE("Error receiving data from stream: %d", errno); 1322fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy return -1; 1332fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 1342fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 1352fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy totalRead += n; 1362fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 1372fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 1382fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy return 0; 13993a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 14093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14193a826f78f6313db791e6fc880439189897651b3Siva VelusamyBufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) { 14293a826f78f6313db791e6fc880439189897651b3Siva Velusamy mStream = stream; 14393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14493a826f78f6313db791e6fc880439189897651b3Siva Velusamy mBufferSize = bufferSize; 14593a826f78f6313db791e6fc880439189897651b3Siva Velusamy mStringBuffer = ""; 14693a826f78f6313db791e6fc880439189897651b3Siva Velusamy mStringBuffer.reserve(bufferSize); 14793a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 14893a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14993a826f78f6313db791e6fc880439189897651b3Siva Velusamyint BufferedOutputStream::flush() { 15093a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (mStringBuffer.size() == 0) { 15193a826f78f6313db791e6fc880439189897651b3Siva Velusamy return 0; 15293a826f78f6313db791e6fc880439189897651b3Siva Velusamy } 15393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 15493a826f78f6313db791e6fc880439189897651b3Siva Velusamy int n = mStream->send((void *)mStringBuffer.data(), mStringBuffer.size()); 15593a826f78f6313db791e6fc880439189897651b3Siva Velusamy mStringBuffer.clear(); 15693a826f78f6313db791e6fc880439189897651b3Siva Velusamy return n; 15793a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 15893a826f78f6313db791e6fc880439189897651b3Siva Velusamy 15993a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid BufferedOutputStream::enqueueMessage(GLMessage *msg) { 16093a826f78f6313db791e6fc880439189897651b3Siva Velusamy const uint32_t len = msg->ByteSize(); 16193a826f78f6313db791e6fc880439189897651b3Siva Velusamy 16293a826f78f6313db791e6fc880439189897651b3Siva Velusamy mStringBuffer.append((const char *)&len, sizeof(len)); // append header 16393a826f78f6313db791e6fc880439189897651b3Siva Velusamy msg->AppendToString(&mStringBuffer); // append message 16493a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 16593a826f78f6313db791e6fc880439189897651b3Siva Velusamy 16693a826f78f6313db791e6fc880439189897651b3Siva Velusamyint BufferedOutputStream::send(GLMessage *msg) { 16793a826f78f6313db791e6fc880439189897651b3Siva Velusamy enqueueMessage(msg); 16893a826f78f6313db791e6fc880439189897651b3Siva Velusamy 16993a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (mStringBuffer.size() > mBufferSize) { 17093a826f78f6313db791e6fc880439189897651b3Siva Velusamy return flush(); 1710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy } 17293a826f78f6313db791e6fc880439189897651b3Siva Velusamy 17393a826f78f6313db791e6fc880439189897651b3Siva Velusamy return 0; 1740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace gltrace 1770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace android 178