]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/bio/bss_sock.c
Create BIO_read_ex() which handles size_t arguments
[thirdparty/openssl.git] / crypto / bio / bss_sock.c
1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10 #include <stdio.h>
11 #include <errno.h>
12 #define USE_SOCKETS
13 #include "bio_lcl.h"
14 #include "internal/cryptlib.h"
15
16 #ifndef OPENSSL_NO_SOCK
17
18 # include <openssl/bio.h>
19
20 # ifdef WATT32
21 /* Watt-32 uses same names */
22 # undef sock_write
23 # undef sock_read
24 # undef sock_puts
25 # define sock_write SockWrite
26 # define sock_read SockRead
27 # define sock_puts SockPuts
28 # endif
29
30 static int sock_write(BIO *h, const char *buf, int num);
31 static int sock_read(BIO *h, char *buf, int size);
32 static int sock_puts(BIO *h, const char *str);
33 static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
34 static int sock_new(BIO *h);
35 static int sock_free(BIO *data);
36 int BIO_sock_should_retry(int s);
37
38 static const BIO_METHOD methods_sockp = {
39 BIO_TYPE_SOCKET,
40 "socket",
41 sock_write,
42 /* TODO: Convert to new style read function */
43 bread_conv,
44 sock_read,
45 sock_puts,
46 NULL, /* sock_gets, */
47 sock_ctrl,
48 sock_new,
49 sock_free,
50 NULL,
51 };
52
53 const BIO_METHOD *BIO_s_socket(void)
54 {
55 return (&methods_sockp);
56 }
57
58 BIO *BIO_new_socket(int fd, int close_flag)
59 {
60 BIO *ret;
61
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 }
68
69 static int sock_new(BIO *bi)
70 {
71 bi->init = 0;
72 bi->num = 0;
73 bi->ptr = NULL;
74 bi->flags = 0;
75 return (1);
76 }
77
78 static int sock_free(BIO *a)
79 {
80 if (a == NULL)
81 return (0);
82 if (a->shutdown) {
83 if (a->init) {
84 BIO_closesocket(a->num);
85 }
86 a->init = 0;
87 a->flags = 0;
88 }
89 return (1);
90 }
91
92 static int sock_read(BIO *b, char *out, int outl)
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 }
107
108 static int sock_write(BIO *b, const char *in, int inl)
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 }
121
122 static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
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 }
159
160 static int sock_puts(BIO *bp, const char *str)
161 {
162 int n, ret;
163
164 n = strlen(str);
165 ret = sock_write(bp, str, n);
166 return (ret);
167 }
168
169 int BIO_sock_should_retry(int i)
170 {
171 int err;
172
173 if ((i == 0) || (i == -1)) {
174 err = get_last_socket_error();
175
176 return (BIO_sock_non_fatal_error(err));
177 }
178 return (0);
179 }
180
181 int BIO_sock_non_fatal_error(int err)
182 {
183 switch (err) {
184 # if defined(OPENSSL_SYS_WINDOWS)
185 # if defined(WSAEWOULDBLOCK)
186 case WSAEWOULDBLOCK:
187 # endif
188 # endif
189
190 # ifdef EWOULDBLOCK
191 # ifdef WSAEWOULDBLOCK
192 # if WSAEWOULDBLOCK != EWOULDBLOCK
193 case EWOULDBLOCK:
194 # endif
195 # else
196 case EWOULDBLOCK:
197 # endif
198 # endif
199
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:
211 # endif
212 # endif
213
214 # ifdef EPROTO
215 case EPROTO:
216 # endif
217
218 # ifdef EINPROGRESS
219 case EINPROGRESS:
220 # endif
221
222 # ifdef EALREADY
223 case EALREADY:
224 # endif
225 return (1);
226 /* break; */
227 default:
228 break;
229 }
230 return (0);
231 }
232
233 #endif /* #ifndef OPENSSL_NO_SOCK */