]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_sock.c
Update copyright year
[thirdparty/openssl.git] / crypto / bio / bss_sock.c
CommitLineData
b1322259 1/*
fecb3aae 2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
09abbca1 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
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>
706457b7 12#include "bio_local.h"
a3e53d56 13#include "internal/bio_tfo.h"
b39fc560 14#include "internal/cryptlib.h"
6ba76c4f 15#include "internal/ktls.h"
c836f8ef
DSH
16
17#ifndef OPENSSL_NO_SOCK
18
0f113f3e 19# include <openssl/bio.h>
d02b48c6 20
0f113f3e 21# ifdef WATT32
2c25ebd1
RL
22/* Watt-32 uses same names */
23# undef sock_write
24# undef sock_read
25# undef sock_puts
26# define sock_write SockWrite
0f113f3e
MC
27# define sock_read SockRead
28# define sock_puts SockPuts
29# endif
f642ebc1 30
a3e53d56
TS
31struct bss_sock_st {
32 BIO_ADDR tfo_peer;
33 int tfo_first;
34#ifndef OPENSSL_NO_KTLS
35 unsigned char ktls_record_type;
36#endif
37};
38
0e1c0612
UM
39static int sock_write(BIO *h, const char *buf, int num);
40static int sock_read(BIO *h, char *buf, int size);
41static int sock_puts(BIO *h, const char *str);
42static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
d02b48c6
RE
43static int sock_new(BIO *h);
44static int sock_free(BIO *data);
45int BIO_sock_should_retry(int s);
d02b48c6 46
04f6b0fd 47static const BIO_METHOD methods_sockp = {
0f113f3e
MC
48 BIO_TYPE_SOCKET,
49 "socket",
3befffa3 50 bwrite_conv,
0f113f3e 51 sock_write,
d07aee2c 52 bread_conv,
0f113f3e
MC
53 sock_read,
54 sock_puts,
b4ff6622 55 NULL, /* sock_gets, */
0f113f3e
MC
56 sock_ctrl,
57 sock_new,
58 sock_free,
b4ff6622 59 NULL, /* sock_callback_ctrl */
0f113f3e 60};
d02b48c6 61
04f6b0fd 62const BIO_METHOD *BIO_s_socket(void)
0f113f3e 63{
26a7d938 64 return &methods_sockp;
0f113f3e 65}
d02b48c6 66
6b691a5c 67BIO *BIO_new_socket(int fd, int close_flag)
0f113f3e
MC
68{
69 BIO *ret;
d02b48c6 70
0f113f3e
MC
71 ret = BIO_new(BIO_s_socket());
72 if (ret == NULL)
26a7d938 73 return NULL;
0f113f3e 74 BIO_set_fd(ret, fd, close_flag);
6ba76c4f
BP
75# ifndef OPENSSL_NO_KTLS
76 {
77 /*
78 * The new socket is created successfully regardless of ktls_enable.
79 * ktls_enable doesn't change any functionality of the socket, except
80 * changing the setsockopt to enable the processing of ktls_start.
81 * Thus, it is not a problem to call it for non-TLS sockets.
82 */
83 ktls_enable(fd);
84 }
85# endif
26a7d938 86 return ret;
0f113f3e 87}
d02b48c6 88
6b691a5c 89static int sock_new(BIO *bi)
0f113f3e
MC
90{
91 bi->init = 0;
92 bi->num = 0;
0f113f3e 93 bi->flags = 0;
a3e53d56
TS
94 bi->ptr = OPENSSL_zalloc(sizeof(struct bss_sock_st));
95 if (bi->ptr == NULL)
96 return 0;
208fb891 97 return 1;
0f113f3e 98}
d02b48c6 99
6b691a5c 100static int sock_free(BIO *a)
0f113f3e
MC
101{
102 if (a == NULL)
26a7d938 103 return 0;
0f113f3e
MC
104 if (a->shutdown) {
105 if (a->init) {
8731a4fc 106 BIO_closesocket(a->num);
0f113f3e
MC
107 }
108 a->init = 0;
109 a->flags = 0;
110 }
a3e53d56
TS
111 OPENSSL_free(a->ptr);
112 a->ptr = NULL;
208fb891 113 return 1;
0f113f3e
MC
114}
115
6b691a5c 116static int sock_read(BIO *b, char *out, int outl)
0f113f3e
MC
117{
118 int ret = 0;
119
120 if (out != NULL) {
121 clear_socket_error();
e401ef80
BP
122# ifndef OPENSSL_NO_KTLS
123 if (BIO_get_ktls_recv(b))
124 ret = ktls_read_record(b->num, out, outl);
125 else
126# endif
127 ret = readsocket(b->num, out, outl);
0f113f3e
MC
128 BIO_clear_retry_flags(b);
129 if (ret <= 0) {
130 if (BIO_sock_should_retry(ret))
131 BIO_set_retry_read(b);
d924dbf4
MC
132 else if (ret == 0)
133 b->flags |= BIO_FLAGS_IN_EOF;
0f113f3e
MC
134 }
135 }
26a7d938 136 return ret;
0f113f3e 137}
d02b48c6 138
0e1c0612 139static int sock_write(BIO *b, const char *in, int inl)
0f113f3e 140{
6ba76c4f 141 int ret = 0;
a3e53d56
TS
142# if !defined(OPENSSL_NO_KTLS) || defined(OSSL_TFO_SENDTO)
143 struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
144# endif
0f113f3e
MC
145
146 clear_socket_error();
6ba76c4f
BP
147# ifndef OPENSSL_NO_KTLS
148 if (BIO_should_ktls_ctrl_msg_flag(b)) {
a3e53d56 149 unsigned char record_type = data->ktls_record_type;
6ba76c4f
BP
150 ret = ktls_send_ctrl_message(b->num, record_type, in, inl);
151 if (ret >= 0) {
152 ret = inl;
153 BIO_clear_ktls_ctrl_msg_flag(b);
154 }
155 } else
a3e53d56
TS
156# endif
157# if defined(OSSL_TFO_SENDTO)
158 if (data->tfo_first) {
159 struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
160 socklen_t peerlen = BIO_ADDR_sockaddr_size(&data->tfo_peer);
161
162 ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO,
163 BIO_ADDR_sockaddr(&data->tfo_peer), peerlen);
164 data->tfo_first = 0;
165 } else
6ba76c4f
BP
166# endif
167 ret = writesocket(b->num, in, inl);
0f113f3e
MC
168 BIO_clear_retry_flags(b);
169 if (ret <= 0) {
170 if (BIO_sock_should_retry(ret))
171 BIO_set_retry_write(b);
172 }
26a7d938 173 return ret;
0f113f3e 174}
d02b48c6 175
0e1c0612 176static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
177{
178 long ret = 1;
179 int *ip;
a3e53d56 180 struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
6ba76c4f 181# ifndef OPENSSL_NO_KTLS
4b09e192 182 ktls_crypto_info_t *crypto_info;
6ba76c4f 183# endif
0f113f3e
MC
184
185 switch (cmd) {
186 case BIO_C_SET_FD:
a3e53d56
TS
187 /* minimal sock_free() */
188 if (b->shutdown) {
189 if (b->init)
190 BIO_closesocket(b->num);
191 b->flags = 0;
192 }
0f113f3e
MC
193 b->num = *((int *)ptr);
194 b->shutdown = (int)num;
195 b->init = 1;
a3e53d56
TS
196 data->tfo_first = 0;
197 memset(&data->tfo_peer, 0, sizeof(data->tfo_peer));
0f113f3e
MC
198 break;
199 case BIO_C_GET_FD:
200 if (b->init) {
201 ip = (int *)ptr;
202 if (ip != NULL)
203 *ip = b->num;
204 ret = b->num;
205 } else
206 ret = -1;
207 break;
208 case BIO_CTRL_GET_CLOSE:
209 ret = b->shutdown;
210 break;
211 case BIO_CTRL_SET_CLOSE:
212 b->shutdown = (int)num;
213 break;
214 case BIO_CTRL_DUP:
215 case BIO_CTRL_FLUSH:
216 ret = 1;
217 break;
6ba76c4f 218# ifndef OPENSSL_NO_KTLS
e401ef80 219 case BIO_CTRL_SET_KTLS:
4b09e192 220 crypto_info = (ktls_crypto_info_t *)ptr;
7f0f8824 221 ret = ktls_start(b->num, crypto_info, num);
6ba76c4f 222 if (ret)
e401ef80 223 BIO_set_ktls_flag(b, num);
6ba76c4f
BP
224 break;
225 case BIO_CTRL_GET_KTLS_SEND:
f16e52b6 226 return BIO_should_ktls_flag(b, 1) != 0;
e401ef80 227 case BIO_CTRL_GET_KTLS_RECV:
f16e52b6 228 return BIO_should_ktls_flag(b, 0) != 0;
e401ef80 229 case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
6ba76c4f 230 BIO_set_ktls_ctrl_msg_flag(b);
a3e53d56 231 data->ktls_record_type = (unsigned char)num;
6ba76c4f
BP
232 ret = 0;
233 break;
e401ef80 234 case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
6ba76c4f
BP
235 BIO_clear_ktls_ctrl_msg_flag(b);
236 ret = 0;
237 break;
238# endif
d924dbf4 239 case BIO_CTRL_EOF:
f16e52b6 240 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
d924dbf4 241 break;
a3e53d56
TS
242 case BIO_C_GET_CONNECT:
243 if (ptr != NULL && num == 2) {
244 const char **pptr = (const char **)ptr;
245
246 *pptr = (const char *)&data->tfo_peer;
247 } else {
248 ret = 0;
249 }
250 break;
251 case BIO_C_SET_CONNECT:
252 if (ptr != NULL && num == 2) {
253 ret = BIO_ADDR_make(&data->tfo_peer,
254 BIO_ADDR_sockaddr((const BIO_ADDR *)ptr));
255 if (ret)
256 data->tfo_first = 1;
257 } else {
258 ret = 0;
259 }
260 break;
0f113f3e
MC
261 default:
262 ret = 0;
263 break;
264 }
26a7d938 265 return ret;
0f113f3e 266}
d02b48c6 267
0e1c0612 268static int sock_puts(BIO *bp, const char *str)
0f113f3e
MC
269{
270 int n, ret;
d02b48c6 271
0f113f3e
MC
272 n = strlen(str);
273 ret = sock_write(bp, str, n);
26a7d938 274 return ret;
0f113f3e 275}
d02b48c6 276
6b691a5c 277int BIO_sock_should_retry(int i)
0f113f3e
MC
278{
279 int err;
58964a49 280
0f113f3e
MC
281 if ((i == 0) || (i == -1)) {
282 err = get_last_socket_error();
d02b48c6 283
26a7d938 284 return BIO_sock_non_fatal_error(err);
0f113f3e 285 }
26a7d938 286 return 0;
0f113f3e 287}
d02b48c6 288
6b691a5c 289int BIO_sock_non_fatal_error(int err)
0f113f3e
MC
290{
291 switch (err) {
1fbab1dc 292# if defined(OPENSSL_SYS_WINDOWS)
0f113f3e
MC
293# if defined(WSAEWOULDBLOCK)
294 case WSAEWOULDBLOCK:
295# endif
d02b48c6
RE
296# endif
297
0f113f3e
MC
298# ifdef EWOULDBLOCK
299# ifdef WSAEWOULDBLOCK
300# if WSAEWOULDBLOCK != EWOULDBLOCK
301 case EWOULDBLOCK:
302# endif
303# else
304 case EWOULDBLOCK:
dfeab068 305# endif
d02b48c6 306# endif
d02b48c6 307
0f113f3e
MC
308# if defined(ENOTCONN)
309 case ENOTCONN:
310# endif
311
312# ifdef EINTR
313 case EINTR:
314# endif
315
316# ifdef EAGAIN
317# if EWOULDBLOCK != EAGAIN
318 case EAGAIN:
d02b48c6 319# endif
d02b48c6 320# endif
d02b48c6 321
0f113f3e
MC
322# ifdef EPROTO
323 case EPROTO:
324# endif
58964a49 325
0f113f3e
MC
326# ifdef EINPROGRESS
327 case EINPROGRESS:
328# endif
d02b48c6 329
0f113f3e
MC
330# ifdef EALREADY
331 case EALREADY:
d02b48c6 332# endif
208fb891 333 return 1;
0f113f3e
MC
334 default:
335 break;
336 }
26a7d938 337 return 0;
0f113f3e
MC
338}
339
340#endif /* #ifndef OPENSSL_NO_SOCK */