Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/async/async_wait.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016-2018 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
/* This must be the first #include file */
11
#include "async_locl.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
0
{
22
0
    struct fd_lookup_st *curr;
23
0
    struct fd_lookup_st *next;
24
0
25
0
    if (ctx == NULL)
26
0
        return;
27
0
28
0
    curr = ctx->fds;
29
0
    while (curr != NULL) {
30
0
        if (!curr->del) {
31
0
            /* 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
0
        /* Always free the fd_lookup_st */
36
0
        next = curr->next;
37
0
        OPENSSL_free(curr);
38
0
        curr = next;
39
0
    }
40
0
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
0
50
0
    if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) {
51
0
        ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, ERR_R_MALLOC_FAILURE);
52
0
        return 0;
53
0
    }
54
0
55
0
    fdlookup->key = key;
56
0
    fdlookup->fd = fd;
57
0
    fdlookup->custom_data = custom_data;
58
0
    fdlookup->cleanup = cleanup;
59
0
    fdlookup->add = 1;
60
0
    fdlookup->next = ctx->fds;
61
0
    ctx->fds = fdlookup;
62
0
    ctx->numadd++;
63
0
    return 1;
64
0
}
65
66
int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
67
                          OSSL_ASYNC_FD *fd, void **custom_data)
68
0
{
69
0
    struct fd_lookup_st *curr;
70
0
71
0
    curr = ctx->fds;
72
0
    while (curr != NULL) {
73
0
        if (curr->del) {
74
0
            /* This one has been marked deleted so do nothing */
75
0
            curr = curr->next;
76
0
            continue;
77
0
        }
78
0
        if (curr->key == key) {
79
0
            *fd = curr->fd;
80
0
            *custom_data = curr->custom_data;
81
0
            return 1;
82
0
        }
83
0
        curr = curr->next;
84
0
    }
85
0
    return 0;
86
0
}
87
88
int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
89
                               size_t *numfds)
90
0
{
91
0
    struct fd_lookup_st *curr;
92
0
93
0
    curr = ctx->fds;
94
0
    *numfds = 0;
95
0
    while (curr != NULL) {
96
0
        if (curr->del) {
97
0
            /* This one has been marked deleted so do nothing */
98
0
            curr = curr->next;
99
0
            continue;
100
0
        }
101
0
        if (fd != NULL) {
102
0
            *fd = curr->fd;
103
0
            fd++;
104
0
        }
105
0
        (*numfds)++;
106
0
        curr = curr->next;
107
0
    }
108
0
    return 1;
109
0
}
110
111
int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
112
                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
113
                                   size_t *numdelfds)
114
0
{
115
0
    struct fd_lookup_st *curr;
116
0
117
0
    *numaddfds = ctx->numadd;
118
0
    *numdelfds = ctx->numdel;
119
0
    if (addfd == NULL && delfd == NULL)
120
0
        return 1;
121
0
122
0
    curr = ctx->fds;
123
0
124
0
    while (curr != NULL) {
125
0
        /* We ignore fds that have been marked as both added and deleted */
126
0
        if (curr->del && !curr->add && (delfd != NULL)) {
127
0
            *delfd = curr->fd;
128
0
            delfd++;
129
0
        }
130
0
        if (curr->add && !curr->del && (addfd != NULL)) {
131
0
            *addfd = curr->fd;
132
0
            addfd++;
133
0
        }
134
0
        curr = curr->next;
135
0
    }
136
0
137
0
    return 1;
138
0
}
139
140
int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
141
0
{
142
0
    struct fd_lookup_st *curr, *prev;
143
0
144
0
    curr = ctx->fds;
145
0
    prev = NULL;
146
0
    while (curr != NULL) {
147
0
        if (curr->del == 1) {
148
0
            /* This one has been marked deleted already so do nothing */
149
0
            prev = curr;
150
0
            curr = curr->next;
151
0
            continue;
152
0
        }
153
0
        if (curr->key == key) {
154
0
            /* If fd has just been added, remove it from the list */
155
0
            if (curr->add == 1) {
156
0
                if (ctx->fds == curr) {
157
0
                    ctx->fds = curr->next;
158
0
                } else {
159
0
                    prev->next = curr->next;
160
0
                }
161
0
162
0
                /* It is responsibility of the caller to cleanup before calling
163
0
                 * ASYNC_WAIT_CTX_clear_fd
164
0
                 */
165
0
                OPENSSL_free(curr);
166
0
                ctx->numadd--;
167
0
                return 1;
168
0
            }
169
0
170
0
            /*
171
0
             * Mark it as deleted. We don't call cleanup if explicitly asked
172
0
             * to clear an fd. We assume the caller is going to do that (if
173
0
             * appropriate).
174
0
             */
175
0
            curr->del = 1;
176
0
            ctx->numdel++;
177
0
            return 1;
178
0
        }
179
0
        prev = curr;
180
0
        curr = curr->next;
181
0
    }
182
0
    return 0;
183
0
}
184
185
void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
186
0
{
187
0
    struct fd_lookup_st *curr, *prev = NULL;
188
0
189
0
    ctx->numadd = 0;
190
0
    ctx->numdel = 0;
191
0
192
0
    curr = ctx->fds;
193
0
194
0
    while (curr != NULL) {
195
0
        if (curr->del) {
196
0
            if (prev == NULL)
197
0
                ctx->fds = curr->next;
198
0
            else
199
0
                prev->next = curr->next;
200
0
            OPENSSL_free(curr);
201
0
            if (prev == NULL)
202
0
                curr = ctx->fds;
203
0
            else
204
0
                curr = prev->next;
205
0
            continue;
206
0
        }
207
0
        if (curr->add) {
208
0
            curr->add = 0;
209
0
        }
210
0
        prev = curr;
211
0
        curr = curr->next;
212
0
    }
213
0
}