]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_sock.c
Create BIO_read_ex() which handles size_t arguments
[thirdparty/openssl.git] / crypto / bio / bss_sock.c
CommitLineData
b1322259
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
b1322259
RS
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
d02b48c6
RE
10#include <stdio.h>
11#include <errno.h>
12#define USE_SOCKETS
a146ae55 13#include "bio_lcl.h"
b39fc560 14#include "internal/cryptlib.h"
c836f8ef
DSH
15
16#ifndef OPENSSL_NO_SOCK
17
0f113f3e 18# include <openssl/bio.h>
d02b48c6 19
0f113f3e 20# ifdef WATT32
2c25ebd1
RL
21/* Watt-32 uses same names */
22# undef sock_write
23# undef sock_read
24# undef sock_puts
25# define sock_write SockWrite
0f113f3e
MC
26# define sock_read SockRead
27# define sock_puts SockPuts
28# endif
f642ebc1 29
0e1c0612
UM
30static int sock_write(BIO *h, const char *buf, int num);
31static int sock_read(BIO *h, char *buf, int size);
32static int sock_puts(BIO *h, const char *str);
33static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
d02b48c6
RE
34static int sock_new(BIO *h);
35static int sock_free(BIO *data);
36int BIO_sock_should_retry(int s);
d02b48c6 37
04f6b0fd 38static const BIO_METHOD methods_sockp = {
0f113f3e
MC
39 BIO_TYPE_SOCKET,
40 "socket",
41 sock_write,
d07aee2c
MC
42 /* TODO: Convert to new style read function */
43 bread_conv,
0f113f3e
MC
44 sock_read,
45 sock_puts,
46 NULL, /* sock_gets, */
47 sock_ctrl,
48 sock_new,
49 sock_free,
50 NULL,
51};
d02b48c6 52
04f6b0fd 53const BIO_METHOD *BIO_s_socket(void)
0f113f3e
MC
54{
55 return (&methods_sockp);
56}
d02b48c6 57
6b691a5c 58BIO *BIO_new_socket(int fd, int close_flag)
0f113f3e
MC
59{
60 BIO *ret;
d02b48c6 61
0f113f3e
MC
62 ret = BIO_new(BIO_s_socket());
63 if (ret == NULL)
64 return (NULL);
65 BIO_set_fd(ret, fd, close_flag);
66 return (ret);
67}
d02b48c6 68
6b691a5c 69static int sock_new(BIO *bi)
0f113f3e
MC
70{
71 bi->init = 0;
72 bi->num = 0;
73 bi->ptr = NULL;
74 bi->flags = 0;
75 return (1);
76}
d02b48c6 77
6b691a5c 78static int sock_free(BIO *a)
0f113f3e
MC
79{
80 if (a == NULL)
81 return (0);
82 if (a->shutdown) {
83 if (a->init) {
8731a4fc 84 BIO_closesocket(a->num);
0f113f3e
MC
85 }
86 a->init = 0;
87 a->flags = 0;
88 }
89 return (1);
90}
91
6b691a5c 92static int sock_read(BIO *b, char *out, int outl)
0f113f3e
MC
93{
94 int ret = 0;
95
96 if (out != NULL) {
97 clear_socket_error();
98 ret = readsocket(b->num, out, outl);
99 BIO_clear_retry_flags(b);
100 if (ret <= 0) {
101 if (BIO_sock_should_retry(ret))
102 BIO_set_retry_read(b);
103 }
104 }
105 return (ret);
106}
d02b48c6 107
0e1c0612 108static int sock_write(BIO *b, const char *in, int inl)
0f113f3e
MC
109{
110 int ret;
111
112 clear_socket_error();
113 ret = writesocket(b->num, in, inl);
114 BIO_clear_retry_flags(b);
115 if (ret <= 0) {
116 if (BIO_sock_should_retry(ret))
117 BIO_set_retry_write(b);
118 }
119 return (ret);
120}
d02b48c6 121
0e1c0612 122static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
123{
124 long ret = 1;
125 int *ip;
126
127 switch (cmd) {
128 case BIO_C_SET_FD:
129 sock_free(b);
130 b->num = *((int *)ptr);
131 b->shutdown = (int)num;
132 b->init = 1;
133 break;
134 case BIO_C_GET_FD:
135 if (b->init) {
136 ip = (int *)ptr;
137 if (ip != NULL)
138 *ip = b->num;
139 ret = b->num;
140 } else
141 ret = -1;
142 break;
143 case BIO_CTRL_GET_CLOSE:
144 ret = b->shutdown;
145 break;
146 case BIO_CTRL_SET_CLOSE:
147 b->shutdown = (int)num;
148 break;
149 case BIO_CTRL_DUP:
150 case BIO_CTRL_FLUSH:
151 ret = 1;
152 break;
153 default:
154 ret = 0;
155 break;
156 }
157 return (ret);
158}
d02b48c6 159
0e1c0612 160static int sock_puts(BIO *bp, const char *str)
0f113f3e
MC
161{
162 int n, ret;
d02b48c6 163
0f113f3e
MC
164 n = strlen(str);
165 ret = sock_write(bp, str, n);
166 return (ret);
167}
d02b48c6 168
6b691a5c 169int BIO_sock_should_retry(int i)
0f113f3e
MC
170{
171 int err;
58964a49 172
0f113f3e
MC
173 if ((i == 0) || (i == -1)) {
174 err = get_last_socket_error();
d02b48c6 175
0f113f3e
MC
176 return (BIO_sock_non_fatal_error(err));
177 }
178 return (0);
179}
d02b48c6 180
6b691a5c 181int BIO_sock_non_fatal_error(int err)
0f113f3e
MC
182{
183 switch (err) {
1fbab1dc 184# if defined(OPENSSL_SYS_WINDOWS)
0f113f3e
MC
185# if defined(WSAEWOULDBLOCK)
186 case WSAEWOULDBLOCK:
187# endif
d02b48c6
RE
188# endif
189
0f113f3e
MC
190# ifdef EWOULDBLOCK
191# ifdef WSAEWOULDBLOCK
192# if WSAEWOULDBLOCK != EWOULDBLOCK
193 case EWOULDBLOCK:
194# endif
195# else
196 case EWOULDBLOCK:
dfeab068 197# endif
d02b48c6 198# endif
d02b48c6 199
0f113f3e
MC
200# if defined(ENOTCONN)
201 case ENOTCONN:
202# endif
203
204# ifdef EINTR
205 case EINTR:
206# endif
207
208# ifdef EAGAIN
209# if EWOULDBLOCK != EAGAIN
210 case EAGAIN:
d02b48c6 211# endif
d02b48c6 212# endif
d02b48c6 213
0f113f3e
MC
214# ifdef EPROTO
215 case EPROTO:
216# endif
58964a49 217
0f113f3e
MC
218# ifdef EINPROGRESS
219 case EINPROGRESS:
220# endif
d02b48c6 221
0f113f3e
MC
222# ifdef EALREADY
223 case EALREADY:
d02b48c6 224# endif
0f113f3e
MC
225 return (1);
226 /* break; */
227 default:
228 break;
229 }
230 return (0);
231}
232
233#endif /* #ifndef OPENSSL_NO_SOCK */