aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/unpcb.h
blob: 5944e83e96a0b54e7993bdd14db6907b7f6a0e15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*-
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 1982, 1986, 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)unpcb.h	8.1 (Berkeley) 6/2/93
 * $FreeBSD$
 */

#ifndef _SYS_UNPCB_H_
#define _SYS_UNPCB_H_

typedef uint64_t unp_gen_t;

#if defined(_KERNEL) || defined(_WANT_UNPCB)
#include <sys/queue.h>
#include <sys/ucred.h>

/*
 * Protocol control block for an active
 * instance of a UNIX internal protocol.
 *
 * A socket may be associated with a vnode in the
 * filesystem.  If so, the unp_vnode pointer holds
 * a reference count to this vnode, which should be irele'd
 * when the socket goes away.
 *
 * A socket may be connected to another socket, in which
 * case the control block of the socket to which it is connected
 * is given by unp_conn.
 *
 * A socket may be referenced by a number of sockets (e.g. several
 * sockets may be connected to a datagram socket.)  These sockets
 * are in a linked list starting with unp_refs, linked through
 * unp_nextref and null-terminated.  Note that a socket may be referenced
 * by a number of other sockets and may also reference a socket (not
 * necessarily one which is referencing it).  This generates
 * the need for unp_refs and unp_nextref to be separate fields.
 *
 * Stream sockets keep copies of receive sockbuf sb_cc and sb_mbcnt
 * so that changes in the sockbuf may be computed to modify
 * back pressure on the sender accordingly.
 *
 * Locking key:
 * (a) Atomic
 * (c) Constant
 * (g) Locked using linkage lock
 * (l) Locked using list lock
 * (p) Locked using pcb lock
 */
LIST_HEAD(unp_head, unpcb);

struct unpcb {
	/* Cache line 1 */
	struct	mtx unp_mtx;		/* PCB mutex */
	struct	unpcb *unp_conn;	/* (p) connected socket */
	volatile u_int unp_refcount;	/* (a, p) atomic refcount */
	short	unp_flags;		/* (p) PCB flags */
	short	unp_gcflag;		/* (g) Garbage collector flags */
	struct	sockaddr_un *unp_addr;	/* (p) bound address of socket */
	struct	socket *unp_socket;	/* (c) pointer back to socket */
	/* Cache line 2 */
	u_int	unp_pairbusy;		/* (p) threads acquiring peer locks */
	struct	vnode *unp_vnode;	/* (p) associated file if applicable */
	struct	xucred unp_peercred;	/* (p) peer credentials if applicable */
	LIST_ENTRY(unpcb) unp_reflink;	/* (l) link in unp_refs list */
	LIST_ENTRY(unpcb) unp_link; 	/* (g) glue on list of all PCBs */
	struct	unp_head unp_refs;	/* (l) referencing socket linked list */
	unp_gen_t unp_gencnt;		/* (g) generation count of this item */
	struct	file *unp_file;		/* (g) back-pointer to file for gc */
	u_int	unp_msgcount;		/* (g) references from message queue */
	u_int	unp_gcrefs;		/* (g) garbage collector refcount */
	ino_t	unp_ino;		/* (g) fake inode number */
	LIST_ENTRY(unpcb) unp_dead;	/* (g) link in dead list */
} __aligned(CACHE_LINE_SIZE);

/*
 * Flags in unp_flags.
 *
 * UNP_HAVEPC - indicates that the unp_peercred member is filled in
 * and is really the credentials of the connected peer.  This is used
 * to determine whether the contents should be sent to the user or
 * not.
 */
#define	UNP_HAVEPC			0x001
#define	UNP_WANTCRED_ALWAYS		0x002	/* credentials wanted always */
#define	UNP_WANTCRED_ONESHOT		0x004	/* credentials wanted once */
#define	UNP_CONNWAIT			0x008	/* connect blocks until accepted */

#define	UNP_WANTCRED_MASK	(UNP_WANTCRED_ONESHOT | UNP_WANTCRED_ALWAYS)

/*
 * These flags are used to handle non-atomicity in connect() and bind()
 * operations on a socket: in particular, to avoid races between multiple
 * threads or processes operating simultaneously on the same socket.
 */
#define	UNP_CONNECTING			0x010	/* Currently connecting. */
#define	UNP_BINDING			0x020	/* Currently binding. */
#define	UNP_WAITING			0x040	/* Peer state is changing. */

/*
 * Flags in unp_gcflag.
 */
#define	UNPGC_DEAD			0x1	/* unpcb might be dead. */
#define	UNPGC_IGNORE_RIGHTS		0x2	/* Attached rights are freed */

#define	sotounpcb(so)	((struct unpcb *)((so)->so_pcb))

#endif	/* _KERNEL || _WANT_UNPCB */

/*
 * UNPCB structure exported to user-land via sysctl(3).
 *
 * Fields prefixed with "xu_" are unique to the export structure, and fields
 * with "unp_" or other prefixes match corresponding fields of 'struct unpcb'.
 *
 * Legend:
 * (s) - used by userland utilities in src
 * (p) - used by utilities in ports
 * (3) - is known to be used by third party software not in ports
 * (n) - no known usage
 *
 * Evil hack: declare only if sys/socketvar.h have been included.
 */
#ifdef	_SYS_SOCKETVAR_H_
struct xunpcb {
	ksize_t		xu_len;			/* length of this structure */
	kvaddr_t	xu_unpp;		/* to help netstat, fstat */
	kvaddr_t	unp_vnode;		/* (s) */
	kvaddr_t	unp_conn;		/* (s) */
	kvaddr_t	xu_firstref;		/* (s) */
	kvaddr_t	xu_nextref;		/* (s) */
	unp_gen_t	unp_gencnt;		/* (s) */
	int64_t		xu_spare64[8];
	int32_t		xu_spare32[8];
	union {
		struct	sockaddr_un xu_addr;	/* our bound address */
		char	xu_dummy1[256];
	};
	union {
		struct	sockaddr_un xu_caddr;	/* their bound address */
		char	xu_dummy2[256];
	};
	struct xsocket	xu_socket;
} __aligned(MAX(8, sizeof(void *)));

struct xunpgen {
	ksize_t	xug_len;
	u_int	xug_count;
	unp_gen_t xug_gen;
	so_gen_t xug_sogen;
} __aligned(8);;
#endif /* _SYS_SOCKETVAR_H_ */

#if defined(_KERNEL)
struct thread;

/* In uipc_userreq.c */
void
unp_copy_peercred(struct thread *td, struct unpcb *client_unp,
    struct unpcb *server_unp, struct unpcb *listen_unp);
#endif

#endif /* _SYS_UNPCB_H_ */