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