156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall/* 256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Copyright (C) 2011 The Android Open Source Project 356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* 456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Licensed under the Apache License, Version 2.0 (the "License"); 556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* you may not use this file except in compliance with the License. 656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* You may obtain a copy of the License at 756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* 856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* http://www.apache.org/licenses/LICENSE-2.0 956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* 1056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* Unless required by applicable law or agreed to in writing, software 1156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* distributed under the License is distributed on an "AS IS" BASIS, 1256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* See the License for the specific language governing permissions and 1456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall* limitations under the License. 1556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall*/ 1656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include "SocketStream.h" 1756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <cutils/sockets.h> 1856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <errno.h> 1956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <stdio.h> 2056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <stdlib.h> 2156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <unistd.h> 2256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <string.h> 2356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 2456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#ifndef _WIN32 2556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <netinet/in.h> 2656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <netinet/tcp.h> 2756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <sys/un.h> 2856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#else 2956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#include <ws2tcpip.h> 3056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#endif 3156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 3256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallSocketStream::SocketStream(size_t bufSize) : 3356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall IOStream(bufSize), 3456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_sock(-1), 3556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_bufsize(bufSize), 3656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf(NULL) 3756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 3856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 3956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 4056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallSocketStream::SocketStream(int sock, size_t bufSize) : 4156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall IOStream(bufSize), 4256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_sock(sock), 4356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_bufsize(bufSize), 4456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf(NULL) 4556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 4656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 4756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 4856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse HallSocketStream::~SocketStream() 4956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 5056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (m_sock >= 0) { 5156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#ifdef _WIN32 5256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall closesocket(m_sock); 5356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#else 5456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall ::close(m_sock); 5556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall#endif 5656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 5756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (m_buf != NULL) { 5856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall free(m_buf); 5956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf = NULL; 6056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 6156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 6256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 6356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 6456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallvoid *SocketStream::allocBuffer(size_t minSize) 6556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 6656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize); 6756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!m_buf) { 6856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf = (unsigned char *)malloc(allocSize); 6956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 7056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall else if (m_bufsize < allocSize) { 7156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall unsigned char *p = (unsigned char *)realloc(m_buf, allocSize); 7256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (p != NULL) { 7356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf = p; 7456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_bufsize = allocSize; 7556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } else { 7656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall ERR("%s: realloc (%zu) failed\n", __FUNCTION__, allocSize); 7756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall free(m_buf); 7856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_buf = NULL; 7956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall m_bufsize = 0; 8056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 8156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 8256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 8356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return m_buf; 8456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall}; 8556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 8656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint SocketStream::commitBuffer(size_t size) 8756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 8856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return writeFully(m_buf, size); 8956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 9056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 9156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint SocketStream::writeFully(const void* buffer, size_t size) 9256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 9356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!valid()) return -1; 9456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 9556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall size_t res = size; 9656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall int retval = 0; 9756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 9856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall while (res > 0) { 9956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0); 10056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (stat < 0) { 10156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (errno != EINTR) { 10256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall retval = stat; 10356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno)); 10456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall break; 10556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 10656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } else { 10756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall res -= stat; 10856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 10956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 11056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return retval; 11156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 11256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 11356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallconst unsigned char *SocketStream::readFully(void *buf, size_t len) 11456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 11556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall const unsigned char* ret = NULL; 11656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!valid()) return NULL; 11756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!buf) { 11856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return NULL; // do not allow NULL buf in that implementation 11956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 12056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall size_t res = len; 12156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall while (res > 0) { 12256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0); 12356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (stat > 0) { 12456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall res -= stat; 12556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall continue; 12656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 12756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (stat == 0 || errno != EINTR) { // client shutdown or error 12856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return NULL; 12956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 13056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 13156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return (const unsigned char *)buf; 13256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 13356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 13456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallconst unsigned char *SocketStream::read( void *buf, size_t *inout_len) 13556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 13656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!valid()) return NULL; 13756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!buf) { 13856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return NULL; // do not allow NULL buf in that implementation 13956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 14056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 14156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall int n; 14256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall do { 14356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall n = recv(buf, *inout_len); 14456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } while( n < 0 && errno == EINTR ); 14556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 14656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (n > 0) { 14756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall *inout_len = n; 14856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return (const unsigned char *)buf; 14956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 15056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 15156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return NULL; 15256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 15356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall 15456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hallint SocketStream::recv(void *buf, size_t len) 15556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall{ 15656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (!valid()) return int(ERR_INVALID_SOCKET); 15756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall int res = 0; 15856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall while(true) { 15956513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall res = ::recv(m_sock, (char *)buf, len, 0); 16056513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (res < 0) { 16156513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall if (errno == EINTR) { 16256513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall continue; 16356513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 16456513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 16556513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall break; 16656513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall } 16756513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall return res; 16856513f5ff4f3e851c5f0cb38dc8851d18616b3c0Jesse Hall} 169