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