summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/sockfs/sockcommon.h
blob: 4e333be0aaf59f906117c7b3b862abbe842d8bcd (plain)
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_SOCKCOMMON_H_
#define	_SOCKCOMMON_H_

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/filio.h>
#include <sys/socket_proto.h>

struct sonode;

extern kmem_cache_t *socket_cache;

/*
 * Socket access functions
 *
 * The following functions should only be used by sockfs, and are common
 * functions that can be used both by kernel sockets (i.e., no file
 * descriptors should ever be expected, or created), and to implement
 * the socket system calls.
 */
extern struct sonode *socket_create(int, int, int, char *, char *, int, int,
    struct cred *, int *);
extern struct sonode *socket_newconn(struct sonode *, sock_lower_handle_t,
    sock_downcalls_t *, int, int *);
extern int socket_bind(struct sonode *, struct sockaddr *, socklen_t, int,
    struct cred *);
extern int socket_accept(struct sonode *, int, struct cred *, struct sonode **);
extern int socket_listen(struct sonode *, int, struct cred *);
extern int socket_connect(struct sonode *, struct sockaddr *,
    socklen_t, int, int, struct cred *);
extern int socket_getpeername(struct sonode *, struct sockaddr *, socklen_t *,
    boolean_t, struct cred *);
extern int socket_getsockname(struct sonode *, struct sockaddr *, socklen_t *,
    struct cred *);
extern int socket_shutdown(struct sonode *, int, struct cred *);
extern int socket_getsockopt(struct sonode *, int, int, void *, socklen_t *,
    int, struct cred *);
extern int socket_setsockopt(struct sonode *, int, int, const void *,
    socklen_t, struct cred *);
extern int socket_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
    struct cred *);
extern int socket_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
    struct cred *);
extern int socket_sendmblk(struct sonode *, struct nmsghdr *, int,
    struct cred *, mblk_t **);
extern int socket_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
    int32_t *);
extern int socket_poll(struct sonode *, short, int, short *,
    struct pollhead **);
extern int socket_close(struct sonode *, int, struct cred *);
extern void socket_destroy(struct sonode *);

/*
 * Cancel the socket push timer.
 */
#define	SOCKET_TIMER_CANCEL(so) {					\
	timeout_id_t tid;						\
									\
	ASSERT(MUTEX_HELD(&(so)->so_lock));				\
	if ((so)->so_rcv_timer_tid != 0) {				\
		tid = (so)->so_rcv_timer_tid;				\
		(so)->so_rcv_timer_tid = 0;				\
		mutex_exit(&(so)->so_lock);				\
									\
		(void) untimeout(tid);					\
									\
		mutex_enter(&(so)->so_lock);				\
	}								\
}

#define	SOCKET_TIMER_START(so) {					\
	ASSERT(MUTEX_HELD(&(so)->so_lock));				\
	if ((so)->so_rcv_timer_interval != SOCKET_NO_RCVTIMER) {	\
		(so)->so_rcv_timer_tid = timeout(so_timer_callback,	\
		    (so), MSEC_TO_TICK((so)->so_rcv_timer_interval));	\
	}								\
}

/* Common sonode ops not support */
extern int so_listen_notsupp(struct sonode *, int, struct cred *);
extern int so_accept_notsupp(struct sonode *, int, struct cred *,
    struct sonode **);
extern int so_getpeername_notsupp(struct sonode *, struct sockaddr *,
    socklen_t *, boolean_t, struct cred *);
extern int so_shutdown_notsupp(struct sonode *, int, struct cred *);
extern int so_sendmblk_notsupp(struct sonode *, struct nmsghdr *,
    int, struct cred *, mblk_t **);

/* Common sonode ops */
extern int so_init(struct sonode *, struct sonode *, struct cred *, int);
extern int so_accept(struct sonode *, int, struct cred *, struct sonode **);
extern int so_bind(struct sonode *, struct sockaddr *, socklen_t, int,
    struct cred *);
extern int so_listen(struct sonode *, int, struct cred *);
extern int so_connect(struct sonode *, struct sockaddr *,
    socklen_t, int, int, struct cred *);
extern int so_getsockopt(struct sonode *, int, int, void *,
    socklen_t *, int, struct cred *);
extern int so_setsockopt(struct sonode *, int, int, const void *,
    socklen_t, struct cred *);
extern int so_getpeername(struct sonode *, struct sockaddr *,
    socklen_t *, boolean_t, struct cred *);
extern int so_getsockname(struct sonode *, struct sockaddr *,
    socklen_t *, struct cred *);
extern int so_ioctl(struct sonode *, int, intptr_t, int, struct cred *,
    int32_t *);
extern int so_poll(struct sonode *, short, int, short *,
    struct pollhead **);
extern int so_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
    struct cred *);
extern int so_sendmblk_impl(struct sonode *, struct nmsghdr *, int,
    struct cred *, mblk_t **, struct sof_instance *, boolean_t);
extern int so_sendmblk(struct sonode *, struct nmsghdr *, int,
    struct cred *, mblk_t **);
extern int so_recvmsg(struct sonode *, struct nmsghdr *, struct uio *,
    struct cred *);
extern int so_shutdown(struct sonode *, int, struct cred *);
extern int so_close(struct sonode *, int, struct cred *);

extern int so_tpi_fallback(struct sonode *, struct cred *);

/* Common upcalls */
extern sock_upper_handle_t so_newconn(sock_upper_handle_t,
    sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
    sock_upcalls_t **);
extern void	so_set_prop(sock_upper_handle_t,
	struct sock_proto_props *);
extern ssize_t	so_queue_msg(sock_upper_handle_t, mblk_t *, size_t, int,
    int *, boolean_t *);
extern ssize_t	so_queue_msg_impl(struct sonode *, mblk_t *, size_t, int,
    int *, boolean_t *, struct sof_instance *);
extern void	so_signal_oob(sock_upper_handle_t, ssize_t);

extern void	so_connected(sock_upper_handle_t, sock_connid_t, struct cred *,
    pid_t);
extern int	so_disconnected(sock_upper_handle_t, sock_connid_t, int);
extern void	so_txq_full(sock_upper_handle_t, boolean_t);
extern void 	so_opctl(sock_upper_handle_t, sock_opctl_action_t, uintptr_t);
/* Common misc. functions */

	/* accept queue */
extern int 	so_acceptq_enqueue(struct sonode *, struct sonode *);
extern int 	so_acceptq_enqueue_locked(struct sonode *, struct sonode *);
extern int	so_acceptq_dequeue(struct sonode *, boolean_t,
    struct sonode **);
extern void	so_acceptq_flush(struct sonode *, boolean_t);

	/* connect */
extern int 	so_wait_connected(struct sonode *, boolean_t, sock_connid_t);

	/* send */
extern int 	so_snd_wait_qnotfull(struct sonode *, boolean_t);
extern void	so_snd_qfull(struct sonode *so);
extern void 	so_snd_qnotfull(struct sonode *so);

extern int	socket_chgpgrp(struct sonode *, pid_t);
extern void	socket_sendsig(struct sonode *, int);
extern int	so_dequeue_msg(struct sonode *, mblk_t **, struct uio *,
    rval_t *, int);
extern void	so_enqueue_msg(struct sonode *, mblk_t *, size_t);
extern void	so_process_new_message(struct sonode *, mblk_t *, mblk_t *);
extern boolean_t	so_check_flow_control(struct sonode *);

extern mblk_t	*socopyinuio(uio_t *, ssize_t, size_t, ssize_t, size_t, int *);
extern mblk_t 	*socopyoutuio(mblk_t *, struct uio *, ssize_t, int *);

extern boolean_t somsghasdata(mblk_t *);
extern void	so_rcv_flush(struct sonode *);
extern int	sorecvoob(struct sonode *, struct nmsghdr *, struct uio *,
		    int, boolean_t);

extern void	so_timer_callback(void *);

extern struct sonode *socket_sonode_create(struct sockparams *, int, int, int,
    int, int, int *, struct cred *);

extern void socket_sonode_destroy(struct sonode *);
extern int socket_init_common(struct sonode *, struct sonode *, int flags,
    struct cred *);
extern int socket_getopt_common(struct sonode *, int, int, void *, socklen_t *,
    int);
extern int socket_ioctl_common(struct sonode *, int, intptr_t, int,
    struct cred *, int32_t *);
extern int socket_strioc_common(struct sonode *, int, intptr_t, int,
    struct cred *, int32_t *);

extern int so_zcopy_wait(struct sonode *);
extern int so_get_mod_version(struct sockparams *);

/* Notification functions */
extern void	so_notify_connected(struct sonode *);
extern void	so_notify_disconnecting(struct sonode *);
extern void	so_notify_disconnected(struct sonode *, boolean_t, int);
extern void	so_notify_writable(struct sonode *);
extern void	so_notify_data(struct sonode *, size_t);
extern void	so_notify_oobsig(struct sonode *);
extern void	so_notify_oobdata(struct sonode *, boolean_t);
extern void	so_notify_eof(struct sonode *);
extern void	so_notify_newconn(struct sonode *);
extern void	so_notify_shutdown(struct sonode *);
extern void	so_notify_error(struct sonode *);

/* Common sonode functions */
extern int 	sonode_constructor(void *, void *, int);
extern void	sonode_destructor(void *, void *);
extern void 	sonode_init(struct sonode *, struct sockparams *,
    int, int, int, sonodeops_t *);
extern void	sonode_fini(struct sonode *);

/*
 * Event flags to socket_sendsig().
 */
#define	SOCKETSIG_WRITE	0x1
#define	SOCKETSIG_READ	0x2
#define	SOCKETSIG_URG	0x4

extern sonodeops_t so_sonodeops;
extern sock_upcalls_t so_upcalls;

#ifdef	__cplusplus
}
#endif
#endif /* _SOCKCOMMON_H_ */