1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2006 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 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stddef.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_WINSOCK 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_local_client(const char *name, int namespaceId, int type) 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ENOSYS; 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !HAVE_WINSOCK */ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/un.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/select.h> 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "socket_local.h" 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LISTEN_BACKLOG 4 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Documented in header file. */ 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_make_sockaddr_un(const char *name, int namespaceId, 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr_un *p_addr, socklen_t *alen) 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset (p_addr, 0, sizeof (*p_addr)); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t namelen; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (namespaceId) { 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ANDROID_SOCKET_NAMESPACE_ABSTRACT: 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = strlen(name); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Test with length +1 for the *initial* '\0'. 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((namelen + 1) > sizeof(p_addr->sun_path)) { 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Note: The path in this case is *not* supposed to be 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * '\0'-terminated. ("man 7 unix" for the gory details.) 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p_addr->sun_path[0] = 0; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(p_addr->sun_path + 1, name, namelen); 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this OS doesn't have the Linux abstract namespace */ 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* unix_path_max appears to be missing on linux */ 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (namelen > sizeof(*p_addr) 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project - offsetof(struct sockaddr_un, sun_path) - 1) { 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(p_addr->sun_path, name); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ANDROID_SOCKET_NAMESPACE_RESERVED: 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* unix_path_max appears to be missing on linux */ 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (namelen > sizeof(*p_addr) 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project - offsetof(struct sockaddr_un, sun_path) - 1) { 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(p_addr->sun_path, name); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ANDROID_SOCKET_NAMESPACE_FILESYSTEM: 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = strlen(name); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* unix_path_max appears to be missing on linux */ 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (namelen > sizeof(*p_addr) 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project - offsetof(struct sockaddr_un, sun_path) - 1) { 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(p_addr->sun_path, name); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // invalid namespace id 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p_addr->sun_family = AF_LOCAL; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecterror: 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * connect to peer named "name" on fd 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * returns same fd or -1 on error. 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * fd is not closed on error. that's your job. 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Used by AndroidSocketImpl 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_local_client_connect(int fd, const char *name, int namespaceId, 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int type) 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sockaddr_un addr; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project socklen_t alen; 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t namelen; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(connect(fd, (struct sockaddr *) &addr, alen) < 0) { 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fd; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecterror: 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * connect to peer named "name" 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * returns fd or -1 on error 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_local_client(const char *name, int namespaceId, int type) 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s = socket(AF_LOCAL, type, 0); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s < 0) return -1; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) { 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(s); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !HAVE_WINSOCK */ 168