bss_sock.c revision 194206
1330887Snp/* crypto/bio/bss_sock.c */ 2330887Snp/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3330887Snp * All rights reserved. 4330887Snp * 5330887Snp * This package is an SSL implementation written 6330887Snp * by Eric Young (eay@cryptsoft.com). 7330887Snp * The implementation was written so as to conform with Netscapes SSL. 8330887Snp * 9330887Snp * This library is free for commercial and non-commercial use as long as 10330887Snp * the following conditions are aheared to. The following conditions 11330887Snp * apply to all code found in this distribution, be it the RC4, RSA, 12330887Snp * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13330887Snp * included with this distribution is covered by the same copyright terms 14330887Snp * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15330887Snp * 16330887Snp * Copyright remains Eric Young's, and as such any Copyright notices in 17330887Snp * the code are not to be removed. 18330887Snp * If this package is used in a product, Eric Young should be given attribution 19330887Snp * as the author of the parts of the library used. 20330887Snp * This can be in the form of a textual message at program startup or 21330887Snp * in documentation (online or textual) provided with the package. 22330887Snp * 23330887Snp * Redistribution and use in source and binary forms, with or without 24330887Snp * modification, are permitted provided that the following conditions 25330887Snp * are met: 26330887Snp * 1. Redistributions of source code must retain the copyright 27330887Snp * notice, this list of conditions and the following disclaimer. 28330887Snp * 2. Redistributions in binary form must reproduce the above copyright 29330887Snp * notice, this list of conditions and the following disclaimer in the 30330887Snp * documentation and/or other materials provided with the distribution. 31330887Snp * 3. All advertising materials mentioning features or use of this software 32330887Snp * must display the following acknowledgement: 33330887Snp * "This product includes cryptographic software written by 34330887Snp * Eric Young (eay@cryptsoft.com)" 35330887Snp * The word 'cryptographic' can be left out if the rouines from the library 36330887Snp * being used are not cryptographic related :-). 37330887Snp * 4. If you include any Windows specific code (or a derivative thereof) from 38330887Snp * the apps directory (application code) you must include an acknowledgement: 39330887Snp * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40330887Snp * 41330887Snp * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42330887Snp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43330887Snp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44330887Snp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45330887Snp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46330887Snp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47330887Snp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48330887Snp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49330887Snp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50330887Snp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51330887Snp * SUCH DAMAGE. 52330887Snp * 53330887Snp * The licence and distribution terms for any publically available version or 54330887Snp * derivative of this code cannot be changed. i.e. this code cannot simply be 55330887Snp * copied and put under another distribution licence 56330887Snp * [including the GNU Public Licence.] 57330887Snp */ 58330887Snp 59330887Snp#include <stdio.h> 60330887Snp#include <errno.h> 61330887Snp#define USE_SOCKETS 62330887Snp#include "cryptlib.h" 63330887Snp 64330887Snp#ifndef OPENSSL_NO_SOCK 65330887Snp 66330887Snp#include <openssl/bio.h> 67330887Snp 68330887Snp#ifdef WATT32 69330887Snp#define sock_write SockWrite /* Watt-32 uses same names */ 70330887Snp#define sock_read SockRead 71330887Snp#define sock_puts SockPuts 72330887Snp#endif 73330887Snp 74330887Snpstatic int sock_write(BIO *h, const char *buf, int num); 75330887Snpstatic int sock_read(BIO *h, char *buf, int size); 76330887Snpstatic int sock_puts(BIO *h, const char *str); 77330887Snpstatic long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); 78330887Snpstatic int sock_new(BIO *h); 79330887Snpstatic int sock_free(BIO *data); 80330887Snpint BIO_sock_should_retry(int s); 81330887Snp 82330887Snpstatic BIO_METHOD methods_sockp= 83330887Snp { 84330887Snp BIO_TYPE_SOCKET, 85330887Snp "socket", 86330887Snp sock_write, 87330887Snp sock_read, 88330887Snp sock_puts, 89330887Snp NULL, /* sock_gets, */ 90330887Snp sock_ctrl, 91330887Snp sock_new, 92330887Snp sock_free, 93330887Snp NULL, 94330887Snp }; 95330887Snp 96330887SnpBIO_METHOD *BIO_s_socket(void) 97330887Snp { 98330887Snp return(&methods_sockp); 99330887Snp } 100330887Snp 101330887SnpBIO *BIO_new_socket(int fd, int close_flag) 102330887Snp { 103330887Snp BIO *ret; 104330887Snp 105330887Snp ret=BIO_new(BIO_s_socket()); 106330887Snp if (ret == NULL) return(NULL); 107330887Snp BIO_set_fd(ret,fd,close_flag); 108330887Snp return(ret); 109330887Snp } 110330887Snp 111330887Snpstatic int sock_new(BIO *bi) 112330887Snp { 113330887Snp bi->init=0; 114330887Snp bi->num=0; 115330887Snp bi->ptr=NULL; 116330887Snp bi->flags=0; 117330887Snp return(1); 118330887Snp } 119330887Snp 120330887Snpstatic int sock_free(BIO *a) 121330887Snp { 122330887Snp if (a == NULL) return(0); 123330887Snp if (a->shutdown) 124330887Snp { 125330887Snp if (a->init) 126330887Snp { 127330887Snp SHUTDOWN2(a->num); 128330887Snp } 129330887Snp a->init=0; 130330887Snp a->flags=0; 131330887Snp } 132330887Snp return(1); 133330887Snp } 134330887Snp 135330887Snpstatic int sock_read(BIO *b, char *out, int outl) 136330887Snp { 137330887Snp int ret=0; 138330887Snp 139330887Snp if (out != NULL) 140330887Snp { 141330887Snp clear_socket_error(); 142330887Snp ret=readsocket(b->num,out,outl); 143330887Snp BIO_clear_retry_flags(b); 144330887Snp if (ret <= 0) 145330887Snp { 146330887Snp if (BIO_sock_should_retry(ret)) 147330887Snp BIO_set_retry_read(b); 148330887Snp } 149330887Snp } 150330887Snp return(ret); 151330887Snp } 152330887Snp 153330887Snpstatic int sock_write(BIO *b, const char *in, int inl) 154330887Snp { 155330887Snp int ret; 156330887Snp 157330887Snp clear_socket_error(); 158330887Snp ret=writesocket(b->num,in,inl); 159330887Snp BIO_clear_retry_flags(b); 160330887Snp if (ret <= 0) 161330887Snp { 162330887Snp if (BIO_sock_should_retry(ret)) 163330887Snp BIO_set_retry_write(b); 164330887Snp } 165330887Snp return(ret); 166330887Snp } 167330887Snp 168330887Snpstatic long sock_ctrl(BIO *b, int cmd, long num, void *ptr) 169330887Snp { 170330887Snp long ret=1; 171330887Snp int *ip; 172330887Snp 173330887Snp switch (cmd) 174330887Snp { 175330887Snp case BIO_CTRL_RESET: 176330887Snp num=0; 177330887Snp case BIO_C_FILE_SEEK: 178330887Snp ret=0; 179330887Snp break; 180330887Snp case BIO_C_FILE_TELL: 181330887Snp case BIO_CTRL_INFO: 182330887Snp ret=0; 183330887Snp break; 184330887Snp case BIO_C_SET_FD: 185330887Snp sock_free(b); 186330887Snp b->num= *((int *)ptr); 187330887Snp b->shutdown=(int)num; 188330887Snp b->init=1; 189330887Snp break; 190330887Snp case BIO_C_GET_FD: 191330887Snp if (b->init) 192330887Snp { 193330887Snp ip=(int *)ptr; 194330887Snp if (ip != NULL) *ip=b->num; 195330887Snp ret=b->num; 196330887Snp } 197330887Snp else 198330887Snp ret= -1; 199330887Snp break; 200330887Snp case BIO_CTRL_GET_CLOSE: 201330887Snp ret=b->shutdown; 202330887Snp break; 203330887Snp case BIO_CTRL_SET_CLOSE: 204330887Snp b->shutdown=(int)num; 205330887Snp break; 206330887Snp case BIO_CTRL_PENDING: 207330887Snp case BIO_CTRL_WPENDING: 208330887Snp ret=0; 209330887Snp break; 210330887Snp case BIO_CTRL_DUP: 211330887Snp case BIO_CTRL_FLUSH: 212330887Snp ret=1; 213330887Snp break; 214330887Snp default: 215330887Snp ret=0; 216330887Snp break; 217330887Snp } 218330887Snp return(ret); 219330887Snp } 220330887Snp 221330887Snpstatic int sock_puts(BIO *bp, const char *str) 222330887Snp { 223330887Snp int n,ret; 224330887Snp 225330887Snp n=strlen(str); 226330887Snp ret=sock_write(bp,str,n); 227330887Snp return(ret); 228330887Snp } 229330887Snp 230330887Snpint BIO_sock_should_retry(int i) 231330887Snp { 232330887Snp int err; 233330887Snp 234330887Snp if ((i == 0) || (i == -1)) 235330887Snp { 236330887Snp err=get_last_socket_error(); 237330887Snp 238330887Snp#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ 239330887Snp if ((i == -1) && (err == 0)) 240330887Snp return(1); 241330887Snp#endif 242330887Snp 243330887Snp return(BIO_sock_non_fatal_error(err)); 244330887Snp } 245330887Snp return(0); 246330887Snp } 247330887Snp 248330887Snpint BIO_sock_non_fatal_error(int err) 249330887Snp { 250330887Snp switch (err) 251330887Snp { 252330887Snp#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) 253330887Snp# if defined(WSAEWOULDBLOCK) 254330887Snp case WSAEWOULDBLOCK: 255330887Snp# endif 256330887Snp 257330887Snp# if 0 /* This appears to always be an error */ 258330887Snp# if defined(WSAENOTCONN) 259330887Snp case WSAENOTCONN: 260330887Snp# endif 261330887Snp# endif 262330887Snp#endif 263330887Snp 264330887Snp#ifdef EWOULDBLOCK 265330887Snp# ifdef WSAEWOULDBLOCK 266330887Snp# if WSAEWOULDBLOCK != EWOULDBLOCK 267330887Snp case EWOULDBLOCK: 268330887Snp# endif 269330887Snp# else 270330887Snp case EWOULDBLOCK: 271330887Snp# endif 272330887Snp#endif 273330887Snp 274330887Snp#if defined(ENOTCONN) 275330887Snp case ENOTCONN: 276330887Snp#endif 277330887Snp 278330887Snp#ifdef EINTR 279330887Snp case EINTR: 280330887Snp#endif 281330887Snp 282330887Snp#ifdef EAGAIN 283330887Snp# if EWOULDBLOCK != EAGAIN 284330887Snp case EAGAIN: 285330887Snp# endif 286330887Snp#endif 287330887Snp 288330887Snp#ifdef EPROTO 289330887Snp case EPROTO: 290330887Snp#endif 291330887Snp 292330887Snp#ifdef EINPROGRESS 293330887Snp case EINPROGRESS: 294330887Snp#endif 295330887Snp 296330887Snp#ifdef EALREADY 297330887Snp case EALREADY: 298330887Snp#endif 299330887Snp return(1); 300330887Snp /* break; */ 301330887Snp default: 302330887Snp break; 303330887Snp } 304330887Snp return(0); 305330887Snp } 306330887Snp 307330887Snp#endif /* #ifndef OPENSSL_NO_SOCK */ 308330887Snp