Coverage Report

Created: 2025-06-13 06:58

/src/openssl32/crypto/async/async_wait.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016-2020 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
/* This must be the first #include file */
11
#include "async_local.h"
12
13
#include <openssl/err.h>
14
15
ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void)
16
0
{
17
0
    return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX));
18
0
}
19
20
void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
21
79.2k
{
22
79.2k
    struct fd_lookup_st *curr;
23
79.2k
    struct fd_lookup_st *next;
24
25
79.2k
    if (ctx == NULL)
26
79.2k
        return;
27
28
0
    curr = ctx->fds;
29
0
    while (curr != NULL) {
30
0
        if (!curr->del) {
31
            /* Only try and cleanup if it hasn't been marked deleted */
32
0
            if (curr->cleanup != NULL)
33
0
                curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data);
34
0
        }
35
        /* Always free the fd_lookup_st */
36
0
        next = curr->next;
37
0
        OPENSSL_free(curr);
38
0
        curr = next;
39
0
    }
40
41
0
    OPENSSL_free(ctx);
42
0
}
43
int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
44
                               OSSL_ASYNC_FD fd, void *custom_data,
45
                               void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
46
                                               OSSL_ASYNC_FD, void *))
47
0
{
48
0
    struct fd_lookup_st *fdlookup;
49
50
0
    if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL)
51
0
        return 0;
52
53
0
    fdlookup->key = key;
54
0
    fdlookup->fd = fd;
55
0
    fdlookup->custom_data = custom_data;
56
0
    fdlookup->cleanup = cleanup;
57
0
    fdlookup->add = 1;
58
0
    fdlookup->next = ctx->fds;
59
0
    ctx->fds = fdlookup;
60
0
    ctx->numadd++;
61
0
    return 1;
62
0
}
63
64
int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
65
                          OSSL_ASYNC_FD *fd, void **custom_data)
66
0
{
67
0
    struct fd_lookup_st *curr;
68
69
0
    curr = ctx->fds;
70
0
    while (curr != NULL) {
71
0
        if (curr->del) {
72
            /* This one has been marked deleted so do nothing */
73
0
            curr = curr->next;
74
0
            continue;
75
0
        }
76
0
        if (curr->key == key) {
77
0
            *fd = curr->fd;
78
0
            *custom_data = curr->custom_data;
79
0
            return 1;
80
0
        }
81
0
        curr = curr->next;
82
0
    }
83
0
    return 0;
84
0
}
85
86
int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
87
                               size_t *numfds)
88
0
{
89
0
    struct fd_lookup_st *curr;
90
91
0
    curr = ctx->fds;
92
0
    *numfds = 0;
93
0
    while (curr != NULL) {
94
0
        if (curr->del) {
95
            /* This one has been marked deleted so do nothing */
96
0
            curr = curr->next;
97
0
            continue;
98
0
        }
99
0
        if (fd != NULL) {
100
0
            *fd = curr->fd;
101
0
            fd++;
102
0
        }
103
0
        (*numfds)++;
104
0
        curr = curr->next;
105
0
    }
106
0
    return 1;
107
0
}
108
109
int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
110
                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
111
                                   size_t *numdelfds)
112
0
{
113
0
    struct fd_lookup_st *curr;
114
115
0
    *numaddfds = ctx->numadd;
116
0
    *numdelfds = ctx->numdel;
117
0
    if (addfd == NULL && delfd == NULL)
118
0
        return 1;
119
120
0
    curr = ctx->fds;
121
122
0
    while (curr != NULL) {
123
        /* We ignore fds that have been marked as both added and deleted */
124
0
        if (curr->del && !curr->add && (delfd != NULL)) {
125
0
            *delfd = curr->fd;
126
0
            delfd++;
127
0
        }
128
0
        if (curr->add && !curr->del && (addfd != NULL)) {
129
0
            *addfd = curr->fd;
130
0
            addfd++;
131
0
        }
132
0
        curr = curr->next;
133
0
    }
134
135
0
    return 1;
136
0
}
137
138
int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
139
0
{
140
0
    struct fd_lookup_st *curr, *prev;
141
142
0
    curr = ctx->fds;
143
0
    prev = NULL;
144
0
    while (curr != NULL) {
145
0
        if (curr->del == 1) {
146
            /* This one has been marked deleted already so do nothing */
147
0
            prev = curr;
148
0
            curr = curr->next;
149
0
            continue;
150
0
        }
151
0
        if (curr->key == key) {
152
            /* If fd has just been added, remove it from the list */
153
0
            if (curr->add == 1) {
154
0
                if (ctx->fds == curr) {
155
0
                    ctx->fds = curr->next;
156
0
                } else {
157
0
                    prev->next = curr->next;
158
0
                }
159
160
                /* It is responsibility of the caller to cleanup before calling
161
                 * ASYNC_WAIT_CTX_clear_fd
162
                 */
163
0
                OPENSSL_free(curr);
164
0
                ctx->numadd--;
165
0
                return 1;
166
0
            }
167
168
            /*
169
             * Mark it as deleted. We don't call cleanup if explicitly asked
170
             * to clear an fd. We assume the caller is going to do that (if
171
             * appropriate).
172
             */
173
0
            curr->del = 1;
174
0
            ctx->numdel++;
175
0
            return 1;
176
0
        }
177
0
        prev = curr;
178
0
        curr = curr->next;
179
0
    }
180
0
    return 0;
181
0
}
182
183
int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx,
184
                                ASYNC_callback_fn callback,
185
                                void *callback_arg)
186
0
{
187
0
      if (ctx == NULL)
188
0
          return 0;
189
190
0
      ctx->callback = callback;
191
0
      ctx->callback_arg = callback_arg;
192
0
      return 1;
193
0
}
194
195
int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx,
196
                                ASYNC_callback_fn *callback,
197
                                void **callback_arg)
198
0
{
199
0
      if (ctx->callback == NULL)
200
0
          return 0;
201
202
0
      *callback = ctx->callback;
203
0
      *callback_arg = ctx->callback_arg;
204
0
      return 1;
205
0
}
206
207
int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status)
208
0
{
209
0
      ctx->status = status;
210
0
      return 1;
211
0
}
212
213
int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx)
214
0
{
215
0
      return ctx->status;
216
0
}
217
218
void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
219
0
{
220
0
    struct fd_lookup_st *curr, *prev = NULL;
221
222
0
    ctx->numadd = 0;
223
0
    ctx->numdel = 0;
224
225
0
    curr = ctx->fds;
226
227
0
    while (curr != NULL) {
228
0
        if (curr->del) {
229
0
            if (prev == NULL)
230
0
                ctx->fds = curr->next;
231
0
            else
232
0
                prev->next = curr->next;
233
0
            OPENSSL_free(curr);
234
0
            if (prev == NULL)
235
0
                curr = ctx->fds;
236
0
            else
237
0
                curr = prev->next;
238
0
            continue;
239
0
        }
240
0
        if (curr->add) {
241
0
            curr->add = 0;
242
0
        }
243
0
        prev = curr;
244
0
        curr = curr->next;
245
0
    }
246
0
}