svr4_socket.c revision 71449
143412Snewton/* 243412Snewton * Copyright (c) 1998 Mark Newton 343412Snewton * Copyright (c) 1996 Christos Zoulas. 443412Snewton * All rights reserved. 543412Snewton * 643412Snewton * Redistribution and use in source and binary forms, with or without 743412Snewton * modification, are permitted provided that the following conditions 843412Snewton * are met: 943412Snewton * 1. Redistributions of source code must retain the above copyright 1043412Snewton * notice, this list of conditions and the following disclaimer. 1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright 1243412Snewton * notice, this list of conditions and the following disclaimer in the 1343412Snewton * documentation and/or other materials provided with the distribution. 1443412Snewton * 3. All advertising materials mentioning features or use of this software 1543412Snewton * must display the following acknowledgement: 1643412Snewton * This product includes software developed by Christos Zoulas. 1743412Snewton * 4. The name of the author may not be used to endorse or promote products 1843412Snewton * derived from this software without specific prior written permission. 1943412Snewton * 2043412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2143412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2243412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2343412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2443412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2543412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2643412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2743412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2843412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2943412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3049267Snewton * 3150477Speter * $FreeBSD: head/sys/compat/svr4/svr4_socket.c 71449 2001-01-23 21:07:16Z jhb $ 3243412Snewton */ 3343412Snewton 3443412Snewton/* 3543412Snewton * In SVR4 unix domain sockets are referenced sometimes 3643412Snewton * (in putmsg(2) for example) as a [device, inode] pair instead of a pathname. 3743412Snewton * Since there is no iname() routine in the kernel, and we need access to 3843412Snewton * a mapping from inode to pathname, we keep our own table. This is a simple 3943412Snewton * linked list that contains the pathname, the [device, inode] pair, the 4043412Snewton * file corresponding to that socket and the process. When the 4143412Snewton * socket gets closed we remove the item from the list. The list gets loaded 4243412Snewton * every time a stat(2) call finds a socket. 4343412Snewton */ 4443412Snewton 4543412Snewton#include <sys/param.h> 4643412Snewton#include <sys/systm.h> 4743412Snewton#include <sys/queue.h> 4843412Snewton#include <sys/file.h> 4943412Snewton#include <sys/socket.h> 5043412Snewton#include <sys/socketvar.h> 5143412Snewton#include <sys/sysproto.h> 5243412Snewton#include <sys/un.h> 5343412Snewton#include <sys/stat.h> 5443412Snewton#include <sys/proc.h> 5543412Snewton#include <sys/malloc.h> 5643412Snewton 5765302Sobrien#include <compat/svr4/svr4.h> 5865302Sobrien#include <compat/svr4/svr4_types.h> 5965302Sobrien#include <compat/svr4/svr4_util.h> 6065302Sobrien#include <compat/svr4/svr4_socket.h> 6165302Sobrien#include <compat/svr4/svr4_signal.h> 6265302Sobrien#include <compat/svr4/svr4_sockmod.h> 6365302Sobrien#include <compat/svr4/svr4_proto.h> 6443412Snewton 6543412Snewtonstruct svr4_sockcache_entry { 6643412Snewton struct proc *p; /* Process for the socket */ 6743412Snewton void *cookie; /* Internal cookie used for matching */ 6843412Snewton struct sockaddr_un sock;/* Pathname for the socket */ 6949267Snewton udev_t dev; /* Device where the socket lives on */ 7043412Snewton ino_t ino; /* Inode where the socket lives on */ 7160938Sjake TAILQ_ENTRY(svr4_sockcache_entry) entries; 7243412Snewton}; 7343412Snewton 7460938Sjakeextern TAILQ_HEAD(svr4_sockcache_head, svr4_sockcache_entry) svr4_head; 7543412Snewtonextern int svr4_str_initialized; 7643412Snewton 7743412Snewtonstruct sockaddr_un * 7843412Snewtonsvr4_find_socket(p, fp, dev, ino) 7943412Snewton struct proc *p; 8043412Snewton struct file *fp; 8149267Snewton udev_t dev; 8243412Snewton ino_t ino; 8343412Snewton{ 8443412Snewton struct svr4_sockcache_entry *e; 8543412Snewton void *cookie = ((struct socket *) fp->f_data)->so_emuldata; 8643412Snewton 8771449Sjhb if (svr4_str_initialized != 2) { 8871449Sjhb if (atomic_cmpset_acq_int(&svr4_str_initialized, 0, 1)) { 8971449Sjhb DPRINTF(("svr4_find_socket: uninitialized [%p,%d,%d]\n", 9071449Sjhb p, dev, ino)); 9171449Sjhb TAILQ_INIT(&svr4_head); 9271449Sjhb atomic_store_rel(&svr4_str_initialized, 2); 9371449Sjhb } 9443412Snewton return NULL; 9543412Snewton } 9643412Snewton 9743412Snewton 9843412Snewton DPRINTF(("svr4_find_socket: [%p,%d,%d]: ", p, dev, ino)); 9971449Sjhb TAILQ_FOREACH(e, &svr4_head, entries) 10043412Snewton if (e->p == p && e->dev == dev && e->ino == ino) { 10143412Snewton#ifdef DIAGNOSTIC 10243412Snewton if (e->cookie != NULL && e->cookie != cookie) 10343412Snewton panic("svr4 socket cookie mismatch"); 10443412Snewton#endif 10543412Snewton e->cookie = cookie; 10643412Snewton DPRINTF(("%s\n", e->sock.sun_path)); 10743412Snewton return &e->sock; 10843412Snewton } 10943412Snewton 11043412Snewton DPRINTF(("not found\n")); 11143412Snewton return NULL; 11243412Snewton} 11343412Snewton 11443412Snewton 11554305Snewton/* 11654305Snewton * svr4_delete_socket() is in sys/dev/streams.c (because it's called by 11754305Snewton * the streams "soo_close()" routine). 11854305Snewton */ 11943412Snewtonint 12043412Snewtonsvr4_add_socket(p, path, st) 12143412Snewton struct proc *p; 12243412Snewton const char *path; 12343412Snewton struct stat *st; 12443412Snewton{ 12543412Snewton struct svr4_sockcache_entry *e; 12643412Snewton int len, error; 12743412Snewton 12871449Sjhb /* 12971449Sjhb * Wait for the TAILQ to be initialized. Only the very first CPU 13071449Sjhb * will succeed on the atomic_cmpset(). The other CPU's will spin 13171449Sjhb * until the first one finishes the initialization. Once the 13271449Sjhb * initialization is complete, the condition will always fail 13371449Sjhb * avoiding expensive atomic operations in the common case. 13471449Sjhb */ 13571449Sjhb while (svr4_str_initialized != 2) 13671449Sjhb if (atomic_cmpset_acq_int(&svr4_str_initialized, 0, 1)) { 13771449Sjhb TAILQ_INIT(&svr4_head); 13871449Sjhb atomic_store_rel_int(&svr4_str_initialized, 2); 13971449Sjhb } 14043412Snewton 14143412Snewton e = malloc(sizeof(*e), M_TEMP, M_WAITOK); 14243412Snewton e->cookie = NULL; 14343412Snewton e->dev = st->st_dev; 14443412Snewton e->ino = st->st_ino; 14543412Snewton e->p = p; 14643412Snewton 14743412Snewton if ((error = copyinstr(path, e->sock.sun_path, 14843412Snewton sizeof(e->sock.sun_path), &len)) != 0) { 14943412Snewton DPRINTF(("svr4_add_socket: copyinstr failed %d\n", error)); 15043412Snewton free(e, M_TEMP); 15143412Snewton return error; 15243412Snewton } 15343412Snewton 15443412Snewton e->sock.sun_family = AF_LOCAL; 15543412Snewton e->sock.sun_len = len; 15643412Snewton 15743412Snewton TAILQ_INSERT_HEAD(&svr4_head, e, entries); 15843412Snewton DPRINTF(("svr4_add_socket: %s [%p,%d,%d]\n", e->sock.sun_path, 15943412Snewton p, e->dev, e->ino)); 16043412Snewton return 0; 16143412Snewton} 16243412Snewton 16343412Snewton 16443412Snewtonint 16543412Snewtonsvr4_sys_socket(p, uap) 16643412Snewton struct proc *p; 16743412Snewton struct svr4_sys_socket_args *uap; 16843412Snewton{ 16943412Snewton switch (SCARG(uap, type)) { 17043412Snewton case SVR4_SOCK_DGRAM: 17143412Snewton SCARG(uap, type) = SOCK_DGRAM; 17243412Snewton break; 17343412Snewton 17443412Snewton case SVR4_SOCK_STREAM: 17543412Snewton SCARG(uap, type) = SOCK_STREAM; 17643412Snewton break; 17743412Snewton 17843412Snewton case SVR4_SOCK_RAW: 17943412Snewton SCARG(uap, type) = SOCK_RAW; 18043412Snewton break; 18143412Snewton 18243412Snewton case SVR4_SOCK_RDM: 18343412Snewton SCARG(uap, type) = SOCK_RDM; 18443412Snewton break; 18543412Snewton 18643412Snewton case SVR4_SOCK_SEQPACKET: 18743412Snewton SCARG(uap, type) = SOCK_SEQPACKET; 18843412Snewton break; 18943412Snewton default: 19043412Snewton return EINVAL; 19143412Snewton } 19243412Snewton return socket(p, (struct socket_args *)uap); 19343412Snewton} 194