bss_sock.c revision 109998
1261287Sdes/* crypto/bio/bss_sock.c */ 2261287Sdes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3261287Sdes * All rights reserved. 4261287Sdes * 5261287Sdes * This package is an SSL implementation written 6261287Sdes * by Eric Young (eay@cryptsoft.com). 7261287Sdes * The implementation was written so as to conform with Netscapes SSL. 8261287Sdes * 9261287Sdes * This library is free for commercial and non-commercial use as long as 10261287Sdes * the following conditions are aheared to. The following conditions 11261287Sdes * apply to all code found in this distribution, be it the RC4, RSA, 12261287Sdes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13261287Sdes * included with this distribution is covered by the same copyright terms 14261287Sdes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15261287Sdes * 16261287Sdes * Copyright remains Eric Young's, and as such any Copyright notices in 17261287Sdes * the code are not to be removed. 18261287Sdes * If this package is used in a product, Eric Young should be given attribution 19261287Sdes * as the author of the parts of the library used. 20261287Sdes * This can be in the form of a textual message at program startup or 21261287Sdes * in documentation (online or textual) provided with the package. 22261287Sdes * 23261287Sdes * Redistribution and use in source and binary forms, with or without 24261287Sdes * modification, are permitted provided that the following conditions 25261287Sdes * are met: 26261287Sdes * 1. Redistributions of source code must retain the copyright 27261287Sdes * notice, this list of conditions and the following disclaimer. 28261287Sdes * 2. Redistributions in binary form must reproduce the above copyright 29261287Sdes * notice, this list of conditions and the following disclaimer in the 30261287Sdes * documentation and/or other materials provided with the distribution. 31261287Sdes * 3. All advertising materials mentioning features or use of this software 32261287Sdes * must display the following acknowledgement: 33261287Sdes * "This product includes cryptographic software written by 34261287Sdes * Eric Young (eay@cryptsoft.com)" 35261287Sdes * The word 'cryptographic' can be left out if the rouines from the library 36261287Sdes * being used are not cryptographic related :-). 37261287Sdes * 4. If you include any Windows specific code (or a derivative thereof) from 38261287Sdes * the apps directory (application code) you must include an acknowledgement: 39261287Sdes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40261287Sdes * 41261287Sdes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42261287Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43261287Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44261287Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45261287Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46261287Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47261287Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48261287Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49261287Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50261287Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51261287Sdes * SUCH DAMAGE. 52261287Sdes * 53261287Sdes * The licence and distribution terms for any publically available version or 54261287Sdes * derivative of this code cannot be changed. i.e. this code cannot simply be 55261287Sdes * copied and put under another distribution licence 56261287Sdes * [including the GNU Public Licence.] 57261287Sdes */ 58261287Sdes 59261287Sdes#ifndef OPENSSL_NO_SOCK 60261287Sdes 61261287Sdes#include <stdio.h> 62261287Sdes#include <errno.h> 63261287Sdes#define USE_SOCKETS 64261287Sdes#include "cryptlib.h" 65261287Sdes#include <openssl/bio.h> 66261287Sdes 67261287Sdes#ifdef WATT32 68261287Sdes#define sock_write SockWrite /* Watt-32 uses same names */ 69261287Sdes#define sock_read SockRead 70261287Sdes#define sock_puts SockPuts 71261287Sdes#endif 72261287Sdes 73261287Sdesstatic int sock_write(BIO *h, const char *buf, int num); 74261287Sdesstatic int sock_read(BIO *h, char *buf, int size); 75261287Sdesstatic int sock_puts(BIO *h, const char *str); 76261287Sdesstatic long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); 77261287Sdesstatic int sock_new(BIO *h); 78261287Sdesstatic int sock_free(BIO *data); 79261287Sdesint BIO_sock_should_retry(int s); 80261287Sdes 81261287Sdesstatic BIO_METHOD methods_sockp= 82261287Sdes { 83261287Sdes BIO_TYPE_SOCKET, 84261287Sdes "socket", 85261287Sdes sock_write, 86261287Sdes sock_read, 87261287Sdes sock_puts, 88261287Sdes NULL, /* sock_gets, */ 89261287Sdes sock_ctrl, 90261287Sdes sock_new, 91261287Sdes sock_free, 92261287Sdes NULL, 93261287Sdes }; 94261287Sdes 95261287SdesBIO_METHOD *BIO_s_socket(void) 96261287Sdes { 97261287Sdes return(&methods_sockp); 98261287Sdes } 99261287Sdes 100261287SdesBIO *BIO_new_socket(int fd, int close_flag) 101261287Sdes { 102261287Sdes BIO *ret; 103261287Sdes 104261287Sdes ret=BIO_new(BIO_s_socket()); 105261287Sdes if (ret == NULL) return(NULL); 106261287Sdes BIO_set_fd(ret,fd,close_flag); 107261287Sdes return(ret); 108261287Sdes } 109261287Sdes 110261287Sdesstatic int sock_new(BIO *bi) 111261287Sdes { 112261287Sdes bi->init=0; 113261287Sdes bi->num=0; 114261287Sdes bi->ptr=NULL; 115261287Sdes bi->flags=0; 116261287Sdes return(1); 117261287Sdes } 118261287Sdes 119261287Sdesstatic int sock_free(BIO *a) 120261287Sdes { 121261287Sdes if (a == NULL) return(0); 122261287Sdes if (a->shutdown) 123261287Sdes { 124261287Sdes if (a->init) 125261287Sdes { 126261287Sdes SHUTDOWN2(a->num); 127261287Sdes } 128261287Sdes a->init=0; 129261287Sdes a->flags=0; 130261287Sdes } 131261287Sdes return(1); 132261287Sdes } 133261287Sdes 134261287Sdesstatic int sock_read(BIO *b, char *out, int outl) 135261287Sdes { 136261287Sdes int ret=0; 137261287Sdes 138261287Sdes if (out != NULL) 139261287Sdes { 140261287Sdes clear_socket_error(); 141261287Sdes ret=readsocket(b->num,out,outl); 142261287Sdes BIO_clear_retry_flags(b); 143261287Sdes if (ret <= 0) 144261287Sdes { 145261287Sdes if (BIO_sock_should_retry(ret)) 146261287Sdes BIO_set_retry_read(b); 147261287Sdes } 148261287Sdes } 149261287Sdes return(ret); 150261287Sdes } 151261287Sdes 152261287Sdesstatic int sock_write(BIO *b, const char *in, int inl) 153261287Sdes { 154261287Sdes int ret; 155261287Sdes 156261287Sdes clear_socket_error(); 157261287Sdes ret=writesocket(b->num,in,inl); 158261287Sdes BIO_clear_retry_flags(b); 159261287Sdes if (ret <= 0) 160261287Sdes { 161261287Sdes if (BIO_sock_should_retry(ret)) 162261287Sdes BIO_set_retry_write(b); 163261287Sdes } 164261287Sdes return(ret); 165261287Sdes } 166261287Sdes 167261287Sdesstatic long sock_ctrl(BIO *b, int cmd, long num, void *ptr) 168261287Sdes { 169261287Sdes long ret=1; 170261287Sdes int *ip; 171261287Sdes 172261287Sdes switch (cmd) 173261287Sdes { 174261287Sdes case BIO_CTRL_RESET: 175261287Sdes num=0; 176261287Sdes case BIO_C_FILE_SEEK: 177261287Sdes ret=0; 178261287Sdes break; 179261287Sdes case BIO_C_FILE_TELL: 180261287Sdes case BIO_CTRL_INFO: 181261287Sdes ret=0; 182261287Sdes break; 183261287Sdes case BIO_C_SET_FD: 184261287Sdes sock_free(b); 185261287Sdes b->num= *((int *)ptr); 186261287Sdes b->shutdown=(int)num; 187261287Sdes b->init=1; 188261287Sdes break; 189261287Sdes case BIO_C_GET_FD: 190261287Sdes if (b->init) 191261287Sdes { 192261287Sdes ip=(int *)ptr; 193261287Sdes if (ip != NULL) *ip=b->num; 194261287Sdes ret=b->num; 195261287Sdes } 196261287Sdes else 197261287Sdes ret= -1; 198261287Sdes break; 199261287Sdes case BIO_CTRL_GET_CLOSE: 200261287Sdes ret=b->shutdown; 201261287Sdes break; 202261287Sdes case BIO_CTRL_SET_CLOSE: 203261287Sdes b->shutdown=(int)num; 204261287Sdes break; 205261287Sdes case BIO_CTRL_PENDING: 206261287Sdes case BIO_CTRL_WPENDING: 207261287Sdes ret=0; 208261287Sdes break; 209261287Sdes case BIO_CTRL_DUP: 210261287Sdes case BIO_CTRL_FLUSH: 211261287Sdes ret=1; 212261287Sdes break; 213261287Sdes default: 214261287Sdes ret=0; 215261287Sdes break; 216261287Sdes } 217261287Sdes return(ret); 218261287Sdes } 219261287Sdes 220261287Sdesstatic int sock_puts(BIO *bp, const char *str) 221261287Sdes { 222261287Sdes int n,ret; 223261287Sdes 224261287Sdes n=strlen(str); 225261287Sdes ret=sock_write(bp,str,n); 226261287Sdes return(ret); 227261287Sdes } 228261287Sdes 229261287Sdesint BIO_sock_should_retry(int i) 230261287Sdes { 231261287Sdes int err; 232261287Sdes 233261287Sdes if ((i == 0) || (i == -1)) 234261287Sdes { 235261287Sdes err=get_last_socket_error(); 236261287Sdes 237261287Sdes#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ 238261287Sdes if ((i == -1) && (err == 0)) 239261287Sdes return(1); 240261287Sdes#endif 241261287Sdes 242261287Sdes return(BIO_sock_non_fatal_error(err)); 243261287Sdes } 244261287Sdes return(0); 245261287Sdes } 246261287Sdes 247261287Sdesint BIO_sock_non_fatal_error(int err) 248261287Sdes { 249261287Sdes switch (err) 250261287Sdes { 251261287Sdes#if defined(OPENSSL_SYS_WINDOWS) 252261287Sdes# if defined(WSAEWOULDBLOCK) 253261287Sdes case WSAEWOULDBLOCK: 254261287Sdes# endif 255261287Sdes 256261287Sdes# if 0 /* This appears to always be an error */ 257261287Sdes# if defined(WSAENOTCONN) 258261287Sdes case WSAENOTCONN: 259261287Sdes# endif 260261287Sdes# endif 261261287Sdes#endif 262261287Sdes 263261287Sdes#ifdef EWOULDBLOCK 264261287Sdes# ifdef WSAEWOULDBLOCK 265261287Sdes# if WSAEWOULDBLOCK != EWOULDBLOCK 266261287Sdes case EWOULDBLOCK: 267261287Sdes# endif 268261287Sdes# else 269261287Sdes case EWOULDBLOCK: 270261287Sdes# endif 271261287Sdes#endif 272261287Sdes 273261287Sdes#if defined(ENOTCONN) 274261287Sdes case ENOTCONN: 275261287Sdes#endif 276261287Sdes 277261287Sdes#ifdef EINTR 278261287Sdes case EINTR: 279261287Sdes#endif 280261287Sdes 281261287Sdes#ifdef EAGAIN 282261287Sdes#if EWOULDBLOCK != EAGAIN 283261287Sdes case EAGAIN: 284261287Sdes# endif 285261287Sdes#endif 286261287Sdes 287261287Sdes#ifdef EPROTO 288261287Sdes case EPROTO: 289261287Sdes#endif 290261287Sdes 291261287Sdes#ifdef EINPROGRESS 292261287Sdes case EINPROGRESS: 293261287Sdes#endif 294261287Sdes 295261287Sdes#ifdef EALREADY 296261287Sdes case EALREADY: 297261287Sdes#endif 298261287Sdes return(1); 299261287Sdes /* break; */ 300261287Sdes default: 301261287Sdes break; 302261287Sdes } 303261287Sdes return(0); 304261287Sdes } 305261287Sdes#endif 306261287Sdes