os/ossrv/ssl/libcrypto/src/crypto/bio/bss_rtcp.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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