summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/sockmods/socksctp.h
blob: 1aadcdf768fb7e16e565d44d9d05246bb64e4bdb (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
/*
 * 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) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_SOCKSCTP_H_
#define	_SOCKSCTP_H_

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * SCTP socket structure.
 *
 * The opaque pointer passed in upcalls is either a pointer to sctp_sonode,
 * or sctp_soassoc. The identification is done through the first element
 * in data structure (if it cannot be identified by upcall which gets called).
 */
struct sctp_sonode {
	int			ss_type;	/* sonode or soassoc */
	struct sonode		ss_so;
	sctp_assoc_t		ss_maxassoc;	/* assoc array size for 1-N */
	sctp_assoc_t		ss_assoccnt;	/* current # of assocs */
	struct sctp_sa_id	*ss_assocs;	/* assoc array for 1-N */
#define	ss_wroff	ss_so.so_proto_props.sopp_wroff
#define	ss_wrsize	ss_so.so_proto_props.sopp_maxblk
};

/*
 * Association for 1-N sockets.
 */
struct sctp_soassoc {
	int			ssa_type;
	sctp_assoc_t		ssa_id;		/* association ID */
	uint_t			ssa_refcnt;
	struct sctp_sonode	*ssa_sonode;
	struct sctp_s		*ssa_conn;	/* opaque ptr passed to SCTP */
	uint_t			ssa_state;	/* same as so_state */
	int			ssa_error;	/* same as so_error */
	boolean_t		ssa_snd_qfull;
	ushort_t		ssa_wroff;
	ssize_t			ssa_wrsize;
	int			ssa_rcv_queued;	/* queued rx bytes/# of conn */
	boolean_t		ssa_flowctrld;	/* receive flow controlled */
};

/* 1-N socket association cache defined in socksctp.c */

/*
 * Association array element.
 *
 * Association data structures for 1-N socket are stored in
 * an array in similar manner to file descriptor array.
 * Each association is identified by its association ID, which also
 * is used as an index to this array (again, like file descriptor number).
 */
struct sctp_sa_id {
	sctp_assoc_t		ssi_alloc;
	struct sctp_soassoc	*ssi_assoc;
};

extern sonodeops_t sosctp_sonodeops;
extern sonodeops_t sosctp_seq_sonodeops;
extern sock_upcalls_t sosctp_sock_upcalls;
extern sock_upcalls_t sosctp_assoc_upcalls;

extern struct sonode *socksctp_create(struct sockparams *, int, int,
    int, int, int, int *, cred_t *);
extern void sosctp_fini(struct sonode *, struct cred *);
extern int sosctp_aid_grow(struct sctp_sonode *ss, sctp_assoc_t maxid,
    int kmflags);
extern sctp_assoc_t sosctp_aid_get(struct sctp_sonode *ss);
extern void sosctp_aid_reserve(struct sctp_sonode *ss, sctp_assoc_t id,
    int incr);
extern struct cmsghdr *sosctp_find_cmsg(const uchar_t *control, socklen_t clen,
    int type);
extern void sosctp_pack_cmsg(const uchar_t *, struct nmsghdr *, int);

extern int sosctp_assoc(struct sctp_sonode *ss, sctp_assoc_t id,
    struct sctp_soassoc **ssa);
extern struct sctp_soassoc *sosctp_assoc_create(struct sctp_sonode *ss,
    int kmflags);
extern void sosctp_assoc_free(struct sctp_sonode *ss, struct sctp_soassoc *ssa);
extern int sosctp_assoc_createconn(struct sctp_sonode *ss,
    const struct sockaddr *name, socklen_t namelen,
    const uchar_t *control, socklen_t controllen, int fflag, struct cred *,
    struct sctp_soassoc **ssap);
extern void sosctp_assoc_move(struct sctp_sonode *ss, struct sctp_sonode *nss,
    struct sctp_soassoc *ssa);
extern void sosctp_so_inherit(struct sctp_sonode *lss, struct sctp_sonode *nss);

extern void sosctp_assoc_isconnecting(struct sctp_soassoc *ssa);
extern void sosctp_assoc_isconnected(struct sctp_soassoc *ssa);
extern void sosctp_assoc_isdisconnecting(struct sctp_soassoc *ssa);
extern void sosctp_assoc_isdisconnected(struct sctp_soassoc *ssa, int error);

extern int sosctp_waitconnected(struct sonode *so, int fmode);
extern int sosctp_uiomove(mblk_t *hdr_mp, ssize_t count, ssize_t blk_size,
    int wroff, struct uio *uiop, int flags);

/*
 * Data structure types.
 */
#define	SOSCTP_SOCKET	0x1
#define	SOSCTP_ASSOC	0x2

#define	SOTOSSO(so) ((struct sctp_sonode *)(((char *)so) -	\
			offsetof(struct sctp_sonode, ss_so)))

#define	SSA_REFHOLD(ssa)					\
{								\
	ASSERT(MUTEX_HELD(&(ssa)->ssa_sonode->ss_so.so_lock));	\
	ASSERT((ssa)->ssa_refcnt > 0);				\
	++(ssa)->ssa_refcnt;					\
	dprint(3, ("ssa_refhold on %p %d (%s,%d)\n", 		\
		(void *)(ssa), (ssa)->ssa_refcnt,		\
		__FILE__, __LINE__));				\
}


#define	SSA_REFRELE(ss, ssa)					\
{								\
	dprint(3, ("ssa_refrele on %p %d (%s, %d)\n",		\
		(void *)(ssa),					\
		(ssa)->ssa_refcnt-1, __FILE__, __LINE__));	\
	ASSERT((ssa)->ssa_refcnt > 0);				\
	if (--(ssa)->ssa_refcnt == 0) {				\
		sosctp_assoc_free(ss, ssa);			\
	}							\
}

#ifdef	__cplusplus
}
#endif

#endif /* _SOCKSCTP_H_ */