bss_sock.c revision 194206
155714Skris/* crypto/bio/bss_sock.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <errno.h> 6155714Skris#define USE_SOCKETS 6255714Skris#include "cryptlib.h" 63194206Ssimon 64194206Ssimon#ifndef OPENSSL_NO_SOCK 65194206Ssimon 6655714Skris#include <openssl/bio.h> 6755714Skris 68109998Smarkm#ifdef WATT32 69109998Smarkm#define sock_write SockWrite /* Watt-32 uses same names */ 70109998Smarkm#define sock_read SockRead 71109998Smarkm#define sock_puts SockPuts 72109998Smarkm#endif 73109998Smarkm 7468651Skrisstatic int sock_write(BIO *h, const char *buf, int num); 7568651Skrisstatic int sock_read(BIO *h, char *buf, int size); 7668651Skrisstatic int sock_puts(BIO *h, const char *str); 7768651Skrisstatic long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); 7855714Skrisstatic int sock_new(BIO *h); 7955714Skrisstatic int sock_free(BIO *data); 8055714Skrisint BIO_sock_should_retry(int s); 8155714Skris 8255714Skrisstatic BIO_METHOD methods_sockp= 8355714Skris { 8455714Skris BIO_TYPE_SOCKET, 8555714Skris "socket", 8655714Skris sock_write, 8755714Skris sock_read, 8855714Skris sock_puts, 8955714Skris NULL, /* sock_gets, */ 9055714Skris sock_ctrl, 9155714Skris sock_new, 9255714Skris sock_free, 9359191Skris NULL, 9455714Skris }; 9555714Skris 9655714SkrisBIO_METHOD *BIO_s_socket(void) 9755714Skris { 9855714Skris return(&methods_sockp); 9955714Skris } 10055714Skris 10155714SkrisBIO *BIO_new_socket(int fd, int close_flag) 10255714Skris { 10355714Skris BIO *ret; 10455714Skris 10555714Skris ret=BIO_new(BIO_s_socket()); 10655714Skris if (ret == NULL) return(NULL); 10755714Skris BIO_set_fd(ret,fd,close_flag); 10855714Skris return(ret); 10955714Skris } 11055714Skris 11155714Skrisstatic int sock_new(BIO *bi) 11255714Skris { 11355714Skris bi->init=0; 11455714Skris bi->num=0; 11555714Skris bi->ptr=NULL; 11655714Skris bi->flags=0; 11755714Skris return(1); 11855714Skris } 11955714Skris 12055714Skrisstatic int sock_free(BIO *a) 12155714Skris { 12255714Skris if (a == NULL) return(0); 12355714Skris if (a->shutdown) 12455714Skris { 12555714Skris if (a->init) 12655714Skris { 12759191Skris SHUTDOWN2(a->num); 12855714Skris } 12955714Skris a->init=0; 13055714Skris a->flags=0; 13155714Skris } 13255714Skris return(1); 13355714Skris } 13455714Skris 13555714Skrisstatic int sock_read(BIO *b, char *out, int outl) 13655714Skris { 13755714Skris int ret=0; 13855714Skris 13955714Skris if (out != NULL) 14055714Skris { 14155714Skris clear_socket_error(); 14255714Skris ret=readsocket(b->num,out,outl); 14355714Skris BIO_clear_retry_flags(b); 14455714Skris if (ret <= 0) 14555714Skris { 14655714Skris if (BIO_sock_should_retry(ret)) 14755714Skris BIO_set_retry_read(b); 14855714Skris } 14955714Skris } 15055714Skris return(ret); 15155714Skris } 15255714Skris 15368651Skrisstatic int sock_write(BIO *b, const char *in, int inl) 15455714Skris { 15555714Skris int ret; 15655714Skris 15755714Skris clear_socket_error(); 15855714Skris ret=writesocket(b->num,in,inl); 15955714Skris BIO_clear_retry_flags(b); 16055714Skris if (ret <= 0) 16155714Skris { 16255714Skris if (BIO_sock_should_retry(ret)) 16355714Skris BIO_set_retry_write(b); 16455714Skris } 16555714Skris return(ret); 16655714Skris } 16755714Skris 16868651Skrisstatic long sock_ctrl(BIO *b, int cmd, long num, void *ptr) 16955714Skris { 17055714Skris long ret=1; 17155714Skris int *ip; 17255714Skris 17355714Skris switch (cmd) 17455714Skris { 17555714Skris case BIO_CTRL_RESET: 17655714Skris num=0; 17755714Skris case BIO_C_FILE_SEEK: 17855714Skris ret=0; 17955714Skris break; 18055714Skris case BIO_C_FILE_TELL: 18155714Skris case BIO_CTRL_INFO: 18255714Skris ret=0; 18355714Skris break; 18455714Skris case BIO_C_SET_FD: 18555714Skris sock_free(b); 18655714Skris b->num= *((int *)ptr); 18755714Skris b->shutdown=(int)num; 18855714Skris b->init=1; 18955714Skris break; 19055714Skris case BIO_C_GET_FD: 19155714Skris if (b->init) 19255714Skris { 19355714Skris ip=(int *)ptr; 19455714Skris if (ip != NULL) *ip=b->num; 19555714Skris ret=b->num; 19655714Skris } 19755714Skris else 19855714Skris ret= -1; 19955714Skris break; 20055714Skris case BIO_CTRL_GET_CLOSE: 20155714Skris ret=b->shutdown; 20255714Skris break; 20355714Skris case BIO_CTRL_SET_CLOSE: 20455714Skris b->shutdown=(int)num; 20555714Skris break; 20655714Skris case BIO_CTRL_PENDING: 20755714Skris case BIO_CTRL_WPENDING: 20855714Skris ret=0; 20955714Skris break; 21055714Skris case BIO_CTRL_DUP: 21155714Skris case BIO_CTRL_FLUSH: 21255714Skris ret=1; 21355714Skris break; 21455714Skris default: 21555714Skris ret=0; 21655714Skris break; 21755714Skris } 21855714Skris return(ret); 21955714Skris } 22055714Skris 22168651Skrisstatic int sock_puts(BIO *bp, const char *str) 22255714Skris { 22355714Skris int n,ret; 22455714Skris 22555714Skris n=strlen(str); 22655714Skris ret=sock_write(bp,str,n); 22755714Skris return(ret); 22855714Skris } 22955714Skris 23055714Skrisint BIO_sock_should_retry(int i) 23155714Skris { 23255714Skris int err; 23355714Skris 23455714Skris if ((i == 0) || (i == -1)) 23555714Skris { 23655714Skris err=get_last_socket_error(); 23755714Skris 238109998Smarkm#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ 23955714Skris if ((i == -1) && (err == 0)) 24055714Skris return(1); 24155714Skris#endif 24255714Skris 24355714Skris return(BIO_sock_non_fatal_error(err)); 24455714Skris } 24555714Skris return(0); 24655714Skris } 24755714Skris 24855714Skrisint BIO_sock_non_fatal_error(int err) 24955714Skris { 25055714Skris switch (err) 25155714Skris { 252160814Ssimon#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) 25355714Skris# if defined(WSAEWOULDBLOCK) 25455714Skris case WSAEWOULDBLOCK: 25555714Skris# endif 25655714Skris 25755714Skris# if 0 /* This appears to always be an error */ 25855714Skris# if defined(WSAENOTCONN) 25955714Skris case WSAENOTCONN: 26055714Skris# endif 26155714Skris# endif 26255714Skris#endif 26355714Skris 26455714Skris#ifdef EWOULDBLOCK 26555714Skris# ifdef WSAEWOULDBLOCK 26655714Skris# if WSAEWOULDBLOCK != EWOULDBLOCK 26755714Skris case EWOULDBLOCK: 26855714Skris# endif 26955714Skris# else 27055714Skris case EWOULDBLOCK: 27155714Skris# endif 27255714Skris#endif 27355714Skris 27455714Skris#if defined(ENOTCONN) 27555714Skris case ENOTCONN: 27655714Skris#endif 27755714Skris 27855714Skris#ifdef EINTR 27955714Skris case EINTR: 28055714Skris#endif 28155714Skris 28255714Skris#ifdef EAGAIN 283160814Ssimon# if EWOULDBLOCK != EAGAIN 28455714Skris case EAGAIN: 28555714Skris# endif 28655714Skris#endif 28755714Skris 28855714Skris#ifdef EPROTO 28955714Skris case EPROTO: 29055714Skris#endif 29155714Skris 29255714Skris#ifdef EINPROGRESS 29355714Skris case EINPROGRESS: 29455714Skris#endif 29555714Skris 29655714Skris#ifdef EALREADY 29755714Skris case EALREADY: 29855714Skris#endif 29955714Skris return(1); 30055714Skris /* break; */ 30155714Skris default: 30255714Skris break; 30355714Skris } 30455714Skris return(0); 30555714Skris } 306194206Ssimon 307194206Ssimon#endif /* #ifndef OPENSSL_NO_SOCK */ 308