Fix up path generation to use OPENSSL_MODULES
[openssl.git] / crypto / bio / bss_sock.c
1 /*
2  * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 #include "bio_local.h"
13 #include "internal/bio_tfo.h"
14 #include "internal/cryptlib.h"
15 #include "internal/ktls.h"
16
17 #ifndef OPENSSL_NO_SOCK
18
19 # include <openssl/bio.h>
20
21 # ifdef WATT32
22 /* Watt-32 uses same names */
23 #  undef sock_write
24 #  undef sock_read
25 #  undef sock_puts
26 #  define sock_write SockWrite
27 #  define sock_read  SockRead
28 #  define sock_puts  SockPuts
29 # endif
30
31 struct 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
39 static int sock_write(BIO *h, const char *buf, int num);
40 static int sock_read(BIO *h, char *buf, int size);
41 static int sock_puts(BIO *h, const char *str);
42 static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
43 static int sock_new(BIO *h);
44 static int sock_free(BIO *data);
45 int BIO_sock_should_retry(int s);
46
47 static const BIO_METHOD methods_sockp = {
48     BIO_TYPE_SOCKET,
49     "socket",
50     bwrite_conv,
51     sock_write,
52     bread_conv,
53     sock_read,
54     sock_puts,
55     NULL,                       /* sock_gets,         */
56     sock_ctrl,
57     sock_new,
58     sock_free,
59     NULL,                       /* sock_callback_ctrl */
60 };
61
62 const BIO_METHOD *BIO_s_socket(void)
63 {
64     return &methods_sockp;
65 }
66
67 BIO *BIO_new_socket(int fd, int close_flag)
68 {
69     BIO *ret;
70
71     ret = BIO_new(BIO_s_socket());
72     if (ret == NULL)
73         return NULL;
74     BIO_set_fd(ret, fd, close_flag);
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
86     return ret;
87 }
88
89 static int sock_new(BIO *bi)
90 {
91     bi->init = 0;
92     bi->num = 0;
93     bi->flags = 0;
94     bi->ptr = OPENSSL_zalloc(sizeof(struct bss_sock_st));
95     if (bi->ptr == NULL)
96         return 0;
97     return 1;
98 }
99
100 static int sock_free(BIO *a)
101 {
102     if (a == NULL)
103         return 0;
104     if (a->shutdown) {
105         if (a->init) {
106             BIO_closesocket(a->num);
107         }
108         a->init = 0;
109         a->flags = 0;
110     }
111     OPENSSL_free(a->ptr);
112     a->ptr = NULL;
113     return 1;
114 }
115
116 static int sock_read(BIO *b, char *out, int outl)
117 {
118     int ret = 0;
119
120     if (out != NULL) {
121         clear_socket_error();
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);
128         BIO_clear_retry_flags(b);
129         if (ret <= 0) {
130             if (BIO_sock_should_retry(ret))
131                 BIO_set_retry_read(b);
132             else if (ret == 0)
133                 b->flags |= BIO_FLAGS_IN_EOF;
134         }
135     }
136     return ret;
137 }
138
139 static int sock_write(BIO *b, const char *in, int inl)
140 {
141     int ret = 0;
142 # if !defined(OPENSSL_NO_KTLS) || defined(OSSL_TFO_SENDTO)
143     struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
144 # endif
145
146     clear_socket_error();
147 # ifndef OPENSSL_NO_KTLS
148     if (BIO_should_ktls_ctrl_msg_flag(b)) {
149         unsigned char record_type = data->ktls_record_type;
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
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
166 # endif
167         ret = writesocket(b->num, in, inl);
168     BIO_clear_retry_flags(b);
169     if (ret <= 0) {
170         if (BIO_sock_should_retry(ret))
171             BIO_set_retry_write(b);
172     }
173     return ret;
174 }
175
176 static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
177 {
178     long ret = 1;
179     int *ip;
180     struct bss_sock_st *data = (struct bss_sock_st *)b->ptr;
181 # ifndef OPENSSL_NO_KTLS
182     ktls_crypto_info_t *crypto_info;
183 # endif
184
185     switch (cmd) {
186     case BIO_C_SET_FD:
187         /* minimal sock_free() */
188         if (b->shutdown) {
189             if (b->init)
190                 BIO_closesocket(b->num);
191             b->flags = 0;
192         }
193         b->num = *((int *)ptr);
194         b->shutdown = (int)num;
195         b->init = 1;
196         data->tfo_first = 0;
197         memset(&data->tfo_peer, 0, sizeof(data->tfo_peer));
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;
218     case BIO_CTRL_GET_RPOLL_DESCRIPTOR:
219     case BIO_CTRL_GET_WPOLL_DESCRIPTOR:
220         {
221             BIO_POLL_DESCRIPTOR *pd = ptr;
222
223             if (!b->init) {
224                 ret = 0;
225                 break;
226             }
227
228             pd->type        = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD;
229             pd->value.fd    = b->num;
230         }
231         break;
232 # ifndef OPENSSL_NO_KTLS
233     case BIO_CTRL_SET_KTLS:
234         crypto_info = (ktls_crypto_info_t *)ptr;
235         ret = ktls_start(b->num, crypto_info, num);
236         if (ret)
237             BIO_set_ktls_flag(b, num);
238         break;
239     case BIO_CTRL_GET_KTLS_SEND:
240         return BIO_should_ktls_flag(b, 1) != 0;
241     case BIO_CTRL_GET_KTLS_RECV:
242         return BIO_should_ktls_flag(b, 0) != 0;
243     case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
244         BIO_set_ktls_ctrl_msg_flag(b);
245         data->ktls_record_type = (unsigned char)num;
246         ret = 0;
247         break;
248     case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
249         BIO_clear_ktls_ctrl_msg_flag(b);
250         ret = 0;
251         break;
252     case BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE:
253         ret = ktls_enable_tx_zerocopy_sendfile(b->num);
254         if (ret)
255             BIO_set_ktls_zerocopy_sendfile_flag(b);
256         break;
257 # endif
258     case BIO_CTRL_EOF:
259         ret = (b->flags & BIO_FLAGS_IN_EOF) != 0;
260         break;
261     case BIO_C_GET_CONNECT:
262         if (ptr != NULL && num == 2) {
263             const char **pptr = (const char **)ptr;
264
265             *pptr = (const char *)&data->tfo_peer;
266         } else {
267             ret = 0;
268         }
269         break;
270     case BIO_C_SET_CONNECT:
271         if (ptr != NULL && num == 2) {
272             ret = BIO_ADDR_make(&data->tfo_peer,
273                                 BIO_ADDR_sockaddr((const BIO_ADDR *)ptr));
274             if (ret)
275                 data->tfo_first = 1;
276         } else {
277             ret = 0;
278         }
279         break;
280     default:
281         ret = 0;
282         break;
283     }
284     return ret;
285 }
286
287 static int sock_puts(BIO *bp, const char *str)
288 {
289     int n, ret;
290
291     n = strlen(str);
292     ret = sock_write(bp, str, n);
293     return ret;
294 }
295
296 int BIO_sock_should_retry(int i)
297 {
298     int err;
299
300     if ((i == 0) || (i == -1)) {
301         err = get_last_socket_error();
302
303         return BIO_sock_non_fatal_error(err);
304     }
305     return 0;
306 }
307
308 int BIO_sock_non_fatal_error(int err)
309 {
310     switch (err) {
311 # if defined(OPENSSL_SYS_WINDOWS)
312 #  if defined(WSAEWOULDBLOCK)
313     case WSAEWOULDBLOCK:
314 #  endif
315 # endif
316
317 # ifdef EWOULDBLOCK
318 #  ifdef WSAEWOULDBLOCK
319 #   if WSAEWOULDBLOCK != EWOULDBLOCK
320     case EWOULDBLOCK:
321 #   endif
322 #  else
323     case EWOULDBLOCK:
324 #  endif
325 # endif
326
327 # if defined(ENOTCONN)
328     case ENOTCONN:
329 # endif
330
331 # ifdef EINTR
332     case EINTR:
333 # endif
334
335 # ifdef EAGAIN
336 #  if EWOULDBLOCK != EAGAIN
337     case EAGAIN:
338 #  endif
339 # endif
340
341 # ifdef EPROTO
342     case EPROTO:
343 # endif
344
345 # ifdef EINPROGRESS
346     case EINPROGRESS:
347 # endif
348
349 # ifdef EALREADY
350     case EALREADY:
351 # endif
352         return 1;
353     default:
354         break;
355     }
356     return 0;
357 }
358
359 #endif                          /* #ifndef OPENSSL_NO_SOCK */