File Coverage

amqp_openssl_bio.c
Criterion Covered Total %
statement 0 55 0.0
branch 0 32 0.0
condition n/a
subroutine n/a
pod n/a
total 0 87 0.0


line stmt bran cond sub pod time code
1             // Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.
2             // SPDX-License-Identifier: mit
3              
4             #include "amqp_openssl_bio.h"
5             #include "amqp_socket.h"
6              
7             #include
8             #include
9             #if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__)))
10             #ifndef WIN32_LEAN_AND_MEAN
11             #define WIN32_LEAN_AND_MEAN
12             #endif
13             #include
14             #else
15             #include
16             #include
17             #endif
18              
19             #ifdef MSG_NOSIGNAL
20             #define AMQP_USE_AMQP_BIO
21             #endif
22              
23             static int amqp_ssl_bio_initialized = 0;
24              
25             #ifdef AMQP_USE_AMQP_BIO
26              
27             static BIO_METHOD *amqp_bio_method;
28              
29 0           static int amqp_openssl_bio_should_retry(int res) {
30 0 0         if (res == -1) {
31 0           int err = amqp_os_socket_error();
32 0 0         if (
33             #ifdef EWOULDBLOCK
34 0 0         err == EWOULDBLOCK ||
35             #endif
36             #ifdef WSAEWOULDBLOCK
37             err == WSAEWOULDBLOCK ||
38             #endif
39             #ifdef ENOTCONN
40 0 0         err == ENOTCONN ||
41             #endif
42             #ifdef EINTR
43 0 0         err == EINTR ||
44             #endif
45             #ifdef EAGAIN
46 0 0         err == EAGAIN ||
47             #endif
48             #ifdef EPROTO
49 0 0         err == EPROTO ||
50             #endif
51             #ifdef EINPROGRESS
52             err == EINPROGRESS ||
53             #endif
54             #ifdef EALREADY
55 0 0         err == EALREADY ||
56             #endif
57             0) {
58 0           return 1;
59             }
60             }
61 0           return 0;
62             }
63              
64 0           static int amqp_openssl_bio_write(BIO *b, const char *in, int inl) {
65 0           int flags = 0;
66             int fd;
67             int res;
68              
69             #ifdef MSG_NOSIGNAL
70 0           flags |= MSG_NOSIGNAL;
71             #endif
72              
73 0           BIO_get_fd(b, &fd);
74 0           res = send(fd, in, inl, flags);
75              
76 0           BIO_clear_retry_flags(b);
77 0 0         if (res <= 0 && amqp_openssl_bio_should_retry(res)) {
    0          
78 0           BIO_set_retry_write(b);
79             }
80              
81 0           return res;
82             }
83              
84 0           static int amqp_openssl_bio_read(BIO *b, char *out, int outl) {
85 0           int flags = 0;
86             int fd;
87             int res;
88              
89             #ifdef MSG_NOSIGNAL
90 0           flags |= MSG_NOSIGNAL;
91             #endif
92              
93 0           BIO_get_fd(b, &fd);
94 0           res = recv(fd, out, outl, flags);
95              
96 0           BIO_clear_retry_flags(b);
97 0 0         if (res <= 0 && amqp_openssl_bio_should_retry(res)) {
    0          
98 0           BIO_set_retry_read(b);
99             }
100              
101 0           return res;
102             }
103             #endif /* AMQP_USE_AMQP_BIO */
104              
105 0           int amqp_openssl_bio_init(void) {
106 0 0         assert(!amqp_ssl_bio_initialized);
107             #ifdef AMQP_USE_AMQP_BIO
108 0 0         if (!(amqp_bio_method = BIO_meth_new(BIO_TYPE_SOCKET, "amqp_bio_method"))) {
109 0           return AMQP_STATUS_NO_MEMORY;
110             }
111             #ifdef OPENSSL_IS_BORINGSSL
112             BIO_meth_set_create(amqp_bio_method, BIO_s_socket()->create);
113             BIO_meth_set_destroy(amqp_bio_method, BIO_s_socket()->destroy);
114             BIO_meth_set_ctrl(amqp_bio_method, BIO_s_socket()->ctrl);
115             BIO_meth_set_read(amqp_bio_method, BIO_s_socket()->bread);
116             BIO_meth_set_write(amqp_bio_method, BIO_s_socket()->bwrite);
117             BIO_meth_set_gets(amqp_bio_method, BIO_s_socket()->bgets);
118             BIO_meth_set_puts(amqp_bio_method, BIO_s_socket()->bputs);
119             #else
120 0           BIO_meth_set_create(amqp_bio_method, BIO_meth_get_create(BIO_s_socket()));
121 0           BIO_meth_set_destroy(amqp_bio_method, BIO_meth_get_destroy(BIO_s_socket()));
122 0           BIO_meth_set_ctrl(amqp_bio_method, BIO_meth_get_ctrl(BIO_s_socket()));
123 0           BIO_meth_set_callback_ctrl(amqp_bio_method,
124             BIO_meth_get_callback_ctrl(BIO_s_socket()));
125 0           BIO_meth_set_read(amqp_bio_method, BIO_meth_get_read(BIO_s_socket()));
126 0           BIO_meth_set_write(amqp_bio_method, BIO_meth_get_write(BIO_s_socket()));
127 0           BIO_meth_set_gets(amqp_bio_method, BIO_meth_get_gets(BIO_s_socket()));
128 0           BIO_meth_set_puts(amqp_bio_method, BIO_meth_get_puts(BIO_s_socket()));
129             #endif
130              
131 0           BIO_meth_set_write(amqp_bio_method, amqp_openssl_bio_write);
132 0           BIO_meth_set_read(amqp_bio_method, amqp_openssl_bio_read);
133             #endif
134              
135 0           amqp_ssl_bio_initialized = 1;
136 0           return AMQP_STATUS_OK;
137             }
138              
139 0           void amqp_openssl_bio_destroy(void) {
140 0 0         assert(amqp_ssl_bio_initialized);
141             #ifdef AMQP_USE_AMQP_BIO
142 0           BIO_meth_free(amqp_bio_method);
143 0           amqp_bio_method = NULL;
144             #endif
145 0           amqp_ssl_bio_initialized = 0;
146 0           }
147              
148 0           BIO_METHOD_PTR amqp_openssl_bio(void) {
149 0 0         assert(amqp_ssl_bio_initialized);
150             #ifdef AMQP_USE_AMQP_BIO
151 0           return amqp_bio_method;
152             #else
153             return BIO_s_socket();
154             #endif
155             }