]>
Commit | Line | Data |
---|---|---|
d02b48c6 | 1 | /* crypto/bio/bss_rtcp.c */ |
58964a49 | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
d02b48c6 RE |
3 | * All rights reserved. |
4 | * | |
5 | * This package is an SSL implementation written | |
6 | * by Eric Young (eay@cryptsoft.com). | |
7 | * The implementation was written so as to conform with Netscapes SSL. | |
40720ce3 | 8 | * |
d02b48c6 RE |
9 | * This library is free for commercial and non-commercial use as long as |
10 | * the following conditions are aheared to. The following conditions | |
11 | * apply to all code found in this distribution, be it the RC4, RSA, | |
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
13 | * included with this distribution is covered by the same copyright terms | |
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
40720ce3 | 15 | * |
d02b48c6 RE |
16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
17 | * the code are not to be removed. | |
18 | * If this package is used in a product, Eric Young should be given attribution | |
19 | * as the author of the parts of the library used. | |
20 | * This can be in the form of a textual message at program startup or | |
21 | * in documentation (online or textual) provided with the package. | |
40720ce3 | 22 | * |
d02b48c6 RE |
23 | * Redistribution and use in source and binary forms, with or without |
24 | * modification, are permitted provided that the following conditions | |
25 | * are met: | |
26 | * 1. Redistributions of source code must retain the copyright | |
27 | * notice, this list of conditions and the following disclaimer. | |
28 | * 2. Redistributions in binary form must reproduce the above copyright | |
29 | * notice, this list of conditions and the following disclaimer in the | |
30 | * documentation and/or other materials provided with the distribution. | |
31 | * 3. All advertising materials mentioning features or use of this software | |
32 | * must display the following acknowledgement: | |
33 | * "This product includes cryptographic software written by | |
34 | * Eric Young (eay@cryptsoft.com)" | |
35 | * The word 'cryptographic' can be left out if the rouines from the library | |
36 | * being used are not cryptographic related :-). | |
40720ce3 | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
d02b48c6 RE |
38 | * the apps directory (application code) you must include an acknowledgement: |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
40720ce3 | 40 | * |
d02b48c6 RE |
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
51 | * SUCH DAMAGE. | |
40720ce3 | 52 | * |
d02b48c6 RE |
53 | * The licence and distribution terms for any publically available version or |
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |
55 | * copied and put under another distribution licence | |
56 | * [including the GNU Public Licence.] | |
57 | */ | |
58 | ||
564ccc55 MC |
59 | /*- |
60 | * Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu> | |
d02b48c6 | 61 | * Date: 22-JUL-1996 |
40720ce3 | 62 | * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD |
d02b48c6 RE |
63 | */ |
64 | /* VMS */ | |
65 | #include <stdio.h> | |
66 | #include <stdlib.h> | |
67 | #include <string.h> | |
68 | #include <errno.h> | |
69 | #include "cryptlib.h" | |
ec577822 | 70 | #include <openssl/bio.h> |
d02b48c6 | 71 | |
40720ce3 | 72 | #include <iodef.h> /* VMS IO$_ definitions */ |
7d7d2cbc UM |
73 | #include <starlet.h> |
74 | ||
d02b48c6 RE |
75 | typedef unsigned short io_channel; |
76 | /*************************************************************************/ | |
40720ce3 MC |
77 | struct io_status { |
78 | short status, count; | |
79 | long flags; | |
80 | }; | |
d02b48c6 | 81 | |
13270477 MC |
82 | /* Should have member alignment inhibited */ |
83 | struct rpc_msg { | |
40720ce3 MC |
84 | /* 'A'-app data. 'R'-remote client 'G'-global */ |
85 | char channel; | |
86 | /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ | |
87 | char function; | |
88 | /* Amount of data returned or max to return */ | |
89 | unsigned short int length; | |
90 | /* variable data */ | |
91 | char data[4092]; | |
d02b48c6 RE |
92 | }; |
93 | #define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) | |
94 | ||
95 | struct rpc_ctx { | |
96 | int filled, pos; | |
97 | struct rpc_msg msg; | |
98 | }; | |
99 | ||
40720ce3 MC |
100 | static int rtcp_write(BIO *h, const char *buf, int num); |
101 | static int rtcp_read(BIO *h, char *buf, int size); | |
102 | static int rtcp_puts(BIO *h, const char *str); | |
103 | static int rtcp_gets(BIO *h, char *str, int size); | |
104 | static long rtcp_ctrl(BIO *h, int cmd, long arg1, void *arg2); | |
d02b48c6 RE |
105 | static int rtcp_new(BIO *h); |
106 | static int rtcp_free(BIO *data); | |
107 | ||
40720ce3 MC |
108 | static BIO_METHOD rtcp_method = { |
109 | BIO_TYPE_FD, | |
110 | "RTCP", | |
111 | rtcp_write, | |
112 | rtcp_read, | |
113 | rtcp_puts, | |
114 | rtcp_gets, | |
115 | rtcp_ctrl, | |
116 | rtcp_new, | |
117 | rtcp_free, | |
118 | NULL, | |
119 | }; | |
d02b48c6 | 120 | |
6b691a5c | 121 | BIO_METHOD *BIO_s_rtcp(void) |
40720ce3 MC |
122 | { |
123 | return (&rtcp_method); | |
124 | } | |
125 | ||
d02b48c6 | 126 | /*****************************************************************************/ |
40720ce3 MC |
127 | /* |
128 | * Decnet I/O routines. | |
d02b48c6 | 129 | */ |
7d7d2cbc UM |
130 | |
131 | #ifdef __DECC | |
40720ce3 MC |
132 | # pragma message save |
133 | # pragma message disable DOLLARID | |
7d7d2cbc UM |
134 | #endif |
135 | ||
40720ce3 | 136 | static int get(io_channel chan, char *buffer, int maxlen, int *length) |
d02b48c6 RE |
137 | { |
138 | int status; | |
139 | struct io_status iosb; | |
40720ce3 MC |
140 | status = sys$qiow(0, chan, IO$_READVBLK, &iosb, 0, 0, |
141 | buffer, maxlen, 0, 0, 0, 0); | |
142 | if ((status & 1) == 1) | |
143 | status = iosb.status; | |
144 | if ((status & 1) == 1) | |
145 | *length = iosb.count; | |
d02b48c6 RE |
146 | return status; |
147 | } | |
148 | ||
40720ce3 | 149 | static int put(io_channel chan, char *buffer, int length) |
d02b48c6 RE |
150 | { |
151 | int status; | |
152 | struct io_status iosb; | |
40720ce3 MC |
153 | status = sys$qiow(0, chan, IO$_WRITEVBLK, &iosb, 0, 0, |
154 | buffer, length, 0, 0, 0, 0); | |
155 | if ((status & 1) == 1) | |
156 | status = iosb.status; | |
d02b48c6 RE |
157 | return status; |
158 | } | |
7d7d2cbc UM |
159 | |
160 | #ifdef __DECC | |
40720ce3 | 161 | # pragma message restore |
7d7d2cbc UM |
162 | #endif |
163 | ||
d02b48c6 RE |
164 | /***************************************************************************/ |
165 | ||
6b691a5c | 166 | static int rtcp_new(BIO *bi) |
d02b48c6 RE |
167 | { |
168 | struct rpc_ctx *ctx; | |
40720ce3 MC |
169 | bi->init = 1; |
170 | bi->num = 0; | |
171 | bi->flags = 0; | |
172 | bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx)); | |
173 | ctx = (struct rpc_ctx *)bi->ptr; | |
174 | ctx->filled = 0; | |
175 | ctx->pos = 0; | |
176 | return (1); | |
d02b48c6 RE |
177 | } |
178 | ||
6b691a5c | 179 | static int rtcp_free(BIO *a) |
d02b48c6 | 180 | { |
40720ce3 MC |
181 | if (a == NULL) |
182 | return (0); | |
183 | if (a->ptr) | |
184 | OPENSSL_free(a->ptr); | |
185 | a->ptr = NULL; | |
186 | return (1); | |
d02b48c6 | 187 | } |
40720ce3 | 188 | |
6b691a5c | 189 | static int rtcp_read(BIO *b, char *out, int outl) |
d02b48c6 RE |
190 | { |
191 | int status, length; | |
192 | struct rpc_ctx *ctx; | |
193 | /* | |
194 | * read data, return existing. | |
195 | */ | |
40720ce3 MC |
196 | ctx = (struct rpc_ctx *)b->ptr; |
197 | if (ctx->pos < ctx->filled) { | |
198 | length = ctx->filled - ctx->pos; | |
199 | if (length > outl) | |
200 | length = outl; | |
201 | memmove(out, &ctx->msg.data[ctx->pos], length); | |
202 | ctx->pos += length; | |
203 | return length; | |
d02b48c6 RE |
204 | } |
205 | /* | |
206 | * Requst more data from R channel. | |
207 | */ | |
208 | ctx->msg.channel = 'R'; | |
209 | ctx->msg.function = 'G'; | |
210 | ctx->msg.length = sizeof(ctx->msg.data); | |
40720ce3 MC |
211 | status = put(b->num, (char *)&ctx->msg, RPC_HDR_SIZE); |
212 | if ((status & 1) == 0) { | |
213 | return -1; | |
d02b48c6 RE |
214 | } |
215 | /* | |
216 | * Read. | |
217 | */ | |
218 | ctx->pos = ctx->filled = 0; | |
40720ce3 MC |
219 | status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); |
220 | if ((status & 1) == 0) | |
221 | length = -1; | |
222 | if (ctx->msg.channel != 'R' || ctx->msg.function != 'C') { | |
223 | length = -1; | |
d02b48c6 RE |
224 | } |
225 | ctx->filled = length - RPC_HDR_SIZE; | |
40720ce3 MC |
226 | |
227 | if (ctx->pos < ctx->filled) { | |
228 | length = ctx->filled - ctx->pos; | |
229 | if (length > outl) | |
230 | length = outl; | |
231 | memmove(out, ctx->msg.data, length); | |
232 | ctx->pos += length; | |
233 | return length; | |
d02b48c6 RE |
234 | } |
235 | ||
236 | return length; | |
237 | } | |
238 | ||
0baed24c | 239 | static int rtcp_write(BIO *b, const char *in, int inl) |
d02b48c6 RE |
240 | { |
241 | int status, i, segment, length; | |
242 | struct rpc_ctx *ctx; | |
243 | /* | |
244 | * Output data, send in chunks no larger that sizeof(ctx->msg.data). | |
245 | */ | |
40720ce3 MC |
246 | ctx = (struct rpc_ctx *)b->ptr; |
247 | for (i = 0; i < inl; i += segment) { | |
248 | segment = inl - i; | |
249 | if (segment > sizeof(ctx->msg.data)) | |
250 | segment = sizeof(ctx->msg.data); | |
251 | ctx->msg.channel = 'R'; | |
252 | ctx->msg.function = 'P'; | |
253 | ctx->msg.length = segment; | |
254 | memmove(ctx->msg.data, &in[i], segment); | |
255 | status = put(b->num, (char *)&ctx->msg, segment + RPC_HDR_SIZE); | |
256 | if ((status & 1) == 0) { | |
257 | i = -1; | |
258 | break; | |
259 | } | |
d02b48c6 | 260 | |
40720ce3 MC |
261 | status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); |
262 | if (((status & 1) == 0) || (length < RPC_HDR_SIZE)) { | |
263 | i = -1; | |
264 | break; | |
265 | } | |
266 | if ((ctx->msg.channel != 'R') || (ctx->msg.function != 'C')) { | |
267 | printf("unexpected response when confirming put %c %c\n", | |
268 | ctx->msg.channel, ctx->msg.function); | |
d02b48c6 | 269 | |
40720ce3 | 270 | } |
d02b48c6 | 271 | } |
40720ce3 | 272 | return (i); |
d02b48c6 RE |
273 | } |
274 | ||
0baed24c | 275 | static long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr) |
40720ce3 MC |
276 | { |
277 | long ret = 1; | |
d02b48c6 | 278 | |
40720ce3 MC |
279 | switch (cmd) { |
280 | case BIO_CTRL_RESET: | |
281 | case BIO_CTRL_EOF: | |
282 | ret = 1; | |
283 | break; | |
284 | case BIO_C_SET_FD: | |
285 | b->num = num; | |
286 | ret = 1; | |
287 | break; | |
288 | case BIO_CTRL_SET_CLOSE: | |
289 | case BIO_CTRL_FLUSH: | |
290 | case BIO_CTRL_DUP: | |
291 | ret = 1; | |
292 | break; | |
293 | case BIO_CTRL_GET_CLOSE: | |
294 | case BIO_CTRL_INFO: | |
295 | case BIO_CTRL_GET: | |
296 | case BIO_CTRL_PENDING: | |
297 | case BIO_CTRL_WPENDING: | |
298 | default: | |
299 | ret = 0; | |
300 | break; | |
301 | } | |
302 | return (ret); | |
303 | } | |
d02b48c6 | 304 | |
6b691a5c | 305 | static int rtcp_gets(BIO *bp, char *buf, int size) |
40720ce3 MC |
306 | { |
307 | return (0); | |
308 | } | |
d02b48c6 | 309 | |
0baed24c | 310 | static int rtcp_puts(BIO *bp, const char *str) |
d02b48c6 RE |
311 | { |
312 | int length; | |
40720ce3 MC |
313 | if (str == NULL) |
314 | return (0); | |
315 | length = strlen(str); | |
316 | if (length == 0) | |
317 | return (0); | |
318 | return rtcp_write(bp, str, length); | |
d02b48c6 | 319 | } |