ssl/libcrypto/src/crypto/bio/bss_rtcp.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* crypto/bio/bss_rtcp.c */
       
     2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       
     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.
       
     8  * 
       
     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).
       
    15  * 
       
    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.
       
    22  * 
       
    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 :-).
       
    37  * 4. If you include any Windows specific code (or a derivative thereof) from 
       
    38  *    the apps directory (application code) you must include an acknowledgement:
       
    39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
       
    40  * 
       
    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.
       
    52  * 
       
    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 
       
    59 /* Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu>
       
    60  * Date:   22-JUL-1996
       
    61  * Revised: 25-SEP-1997		Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD
       
    62  */
       
    63 /* VMS */
       
    64 #include <stdio.h>
       
    65 #include <stdlib.h>
       
    66 #include <string.h>
       
    67 #include <errno.h>
       
    68 #include "cryptlib.h"
       
    69 #include <openssl/bio.h>
       
    70 
       
    71 #include <iodef.h>		/* VMS IO$_ definitions */
       
    72 #include <starlet.h>
       
    73 
       
    74 typedef unsigned short io_channel;
       
    75 /*************************************************************************/
       
    76 struct io_status { short status, count; long flags; };
       
    77 
       
    78 struct rpc_msg {		/* Should have member alignment inhibited */
       
    79    char channel;		/* 'A'-app data. 'R'-remote client 'G'-global */
       
    80    char function;		/* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */
       
    81    unsigned short int length;	/* Amount of data returned or max to return */
       
    82    char data[4092];		/* variable data */
       
    83 };
       
    84 #define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092)
       
    85 
       
    86 struct rpc_ctx {
       
    87     int filled, pos;
       
    88     struct rpc_msg msg;
       
    89 };
       
    90 
       
    91 static int rtcp_write(BIO *h,const char *buf,int num);
       
    92 static int rtcp_read(BIO *h,char *buf,int size);
       
    93 static int rtcp_puts(BIO *h,const char *str);
       
    94 static int rtcp_gets(BIO *h,char *str,int size);
       
    95 static long rtcp_ctrl(BIO *h,int cmd,long arg1,void *arg2);
       
    96 static int rtcp_new(BIO *h);
       
    97 static int rtcp_free(BIO *data);
       
    98 
       
    99 static BIO_METHOD rtcp_method=
       
   100 	{
       
   101 	BIO_TYPE_FD,
       
   102 	"RTCP",
       
   103 	rtcp_write,
       
   104 	rtcp_read,
       
   105 	rtcp_puts,
       
   106 	rtcp_gets,
       
   107 	rtcp_ctrl,
       
   108 	rtcp_new,
       
   109 	rtcp_free,
       
   110 	NULL,
       
   111 	};
       
   112 
       
   113 BIO_METHOD *BIO_s_rtcp(void)
       
   114 	{
       
   115 	return(&rtcp_method);
       
   116 	}
       
   117 /*****************************************************************************/
       
   118 /* Decnet I/O routines.
       
   119  */
       
   120 
       
   121 #ifdef __DECC
       
   122 #pragma message save
       
   123 #pragma message disable DOLLARID
       
   124 #endif
       
   125 
       
   126 static int get ( io_channel chan, char *buffer, int maxlen, int *length )
       
   127 {
       
   128     int status;
       
   129     struct io_status iosb;
       
   130     status = sys$qiow ( 0, chan, IO$_READVBLK, &iosb, 0, 0,
       
   131 	buffer, maxlen, 0, 0, 0, 0 );
       
   132     if ( (status&1) == 1 ) status = iosb.status;
       
   133     if ( (status&1) == 1 ) *length = iosb.count;
       
   134     return status;
       
   135 }
       
   136 
       
   137 static int put ( io_channel chan, char *buffer, int length )
       
   138 {
       
   139     int status;
       
   140     struct io_status iosb;
       
   141     status = sys$qiow ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
       
   142 	buffer, length, 0, 0, 0, 0 );
       
   143     if ( (status&1) == 1 ) status = iosb.status;
       
   144     return status;
       
   145 }
       
   146 
       
   147 #ifdef __DECC
       
   148 #pragma message restore
       
   149 #endif
       
   150 
       
   151 /***************************************************************************/
       
   152 
       
   153 static int rtcp_new(BIO *bi)
       
   154 {
       
   155     struct rpc_ctx *ctx;
       
   156 	bi->init=1;
       
   157 	bi->num=0;
       
   158 	bi->flags = 0;
       
   159 	bi->ptr=OPENSSL_malloc(sizeof(struct rpc_ctx));
       
   160 	ctx = (struct rpc_ctx *) bi->ptr;
       
   161 	ctx->filled = 0;
       
   162 	ctx->pos = 0;
       
   163 	return(1);
       
   164 }
       
   165 
       
   166 static int rtcp_free(BIO *a)
       
   167 {
       
   168 	if (a == NULL) return(0);
       
   169 	if ( a->ptr ) OPENSSL_free ( a->ptr );
       
   170 	a->ptr = NULL;
       
   171 	return(1);
       
   172 }
       
   173 	
       
   174 static int rtcp_read(BIO *b, char *out, int outl)
       
   175 {
       
   176     int status, length;
       
   177     struct rpc_ctx *ctx;
       
   178     /*
       
   179      * read data, return existing.
       
   180      */
       
   181     ctx = (struct rpc_ctx *) b->ptr;
       
   182     if ( ctx->pos < ctx->filled ) {
       
   183 	length = ctx->filled - ctx->pos;
       
   184 	if ( length > outl ) length = outl;
       
   185 	memmove ( out, &ctx->msg.data[ctx->pos], length );
       
   186 	ctx->pos += length;
       
   187 	return length;
       
   188     }
       
   189     /*
       
   190      * Requst more data from R channel.
       
   191      */
       
   192     ctx->msg.channel = 'R';
       
   193     ctx->msg.function = 'G';
       
   194     ctx->msg.length = sizeof(ctx->msg.data);
       
   195     status = put ( b->num, (char *) &ctx->msg, RPC_HDR_SIZE );
       
   196     if ( (status&1) == 0 ) {
       
   197 	return -1;
       
   198     }
       
   199     /*
       
   200      * Read.
       
   201      */
       
   202     ctx->pos = ctx->filled = 0;
       
   203     status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
       
   204     if ( (status&1) == 0 ) length = -1;
       
   205     if ( ctx->msg.channel != 'R' || ctx->msg.function != 'C' ) {
       
   206 	length = -1;
       
   207     }
       
   208     ctx->filled = length - RPC_HDR_SIZE;
       
   209     
       
   210     if ( ctx->pos < ctx->filled ) {
       
   211 	length = ctx->filled - ctx->pos;
       
   212 	if ( length > outl ) length = outl;
       
   213 	memmove ( out, ctx->msg.data, length );
       
   214 	ctx->pos += length;
       
   215 	return length;
       
   216     }
       
   217 
       
   218     return length;
       
   219 }
       
   220 
       
   221 static int rtcp_write(BIO *b, const char *in, int inl)
       
   222 {
       
   223     int status, i, segment, length;
       
   224     struct rpc_ctx *ctx;
       
   225     /*
       
   226      * Output data, send in chunks no larger that sizeof(ctx->msg.data).
       
   227      */
       
   228     ctx = (struct rpc_ctx *) b->ptr;
       
   229     for ( i = 0; i < inl; i += segment ) {
       
   230 	segment = inl - i;
       
   231 	if ( segment > sizeof(ctx->msg.data) ) segment = sizeof(ctx->msg.data);
       
   232 	ctx->msg.channel = 'R';
       
   233 	ctx->msg.function = 'P';
       
   234 	ctx->msg.length = segment;
       
   235 	memmove ( ctx->msg.data, &in[i], segment );
       
   236 	status = put ( b->num, (char *) &ctx->msg, segment + RPC_HDR_SIZE );
       
   237 	if ((status&1) == 0 ) { i = -1; break; }
       
   238 
       
   239 	status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length );
       
   240 	if ( ((status&1) == 0) || (length < RPC_HDR_SIZE) ) { i = -1; break; }
       
   241 	if ( (ctx->msg.channel != 'R') || (ctx->msg.function != 'C') ) {
       
   242 	   printf("unexpected response when confirming put %c %c\n",
       
   243 		ctx->msg.channel, ctx->msg.function );
       
   244 
       
   245 	}
       
   246     }
       
   247     return(i);
       
   248 }
       
   249 
       
   250 static long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr)
       
   251 	{
       
   252 	long ret=1;
       
   253 
       
   254 	switch (cmd)
       
   255 		{
       
   256 	case BIO_CTRL_RESET:
       
   257 	case BIO_CTRL_EOF:
       
   258 		ret = 1;
       
   259 		break;
       
   260 	case BIO_C_SET_FD:
       
   261 		b->num = num;
       
   262 		ret = 1;
       
   263 	 	break;
       
   264 	case BIO_CTRL_SET_CLOSE:
       
   265 	case BIO_CTRL_FLUSH:
       
   266 	case BIO_CTRL_DUP:
       
   267 		ret=1;
       
   268 		break;
       
   269 	case BIO_CTRL_GET_CLOSE:
       
   270 	case BIO_CTRL_INFO:
       
   271 	case BIO_CTRL_GET:
       
   272 	case BIO_CTRL_PENDING:
       
   273 	case BIO_CTRL_WPENDING:
       
   274 	default:
       
   275 		ret=0;
       
   276 		break;
       
   277 		}
       
   278 	return(ret);
       
   279 	}
       
   280 
       
   281 static int rtcp_gets(BIO *bp, char *buf, int size)
       
   282 	{
       
   283 	return(0);
       
   284 	}
       
   285 
       
   286 static int rtcp_puts(BIO *bp, const char *str)
       
   287 {
       
   288     int length;
       
   289     if (str == NULL) return(0);
       
   290     length = strlen ( str );
       
   291     if ( length == 0 ) return (0);
       
   292     return rtcp_write ( bp,str, length );
       
   293 }
       
   294