1*e71b7053SJung-uk Kim /* 2*e71b7053SJung-uk Kim * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. 3*e71b7053SJung-uk Kim * 4*e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5*e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6*e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7*e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 8*e71b7053SJung-uk Kim */ 9*e71b7053SJung-uk Kim 10*e71b7053SJung-uk Kim /* This must be the first #include file */ 11*e71b7053SJung-uk Kim #include "async_locl.h" 12*e71b7053SJung-uk Kim 13*e71b7053SJung-uk Kim #include <openssl/err.h> 14*e71b7053SJung-uk Kim 15*e71b7053SJung-uk Kim ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void) 16*e71b7053SJung-uk Kim { 17*e71b7053SJung-uk Kim return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX)); 18*e71b7053SJung-uk Kim } 19*e71b7053SJung-uk Kim 20*e71b7053SJung-uk Kim void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx) 21*e71b7053SJung-uk Kim { 22*e71b7053SJung-uk Kim struct fd_lookup_st *curr; 23*e71b7053SJung-uk Kim struct fd_lookup_st *next; 24*e71b7053SJung-uk Kim 25*e71b7053SJung-uk Kim if (ctx == NULL) 26*e71b7053SJung-uk Kim return; 27*e71b7053SJung-uk Kim 28*e71b7053SJung-uk Kim curr = ctx->fds; 29*e71b7053SJung-uk Kim while (curr != NULL) { 30*e71b7053SJung-uk Kim if (!curr->del) { 31*e71b7053SJung-uk Kim /* Only try and cleanup if it hasn't been marked deleted */ 32*e71b7053SJung-uk Kim if (curr->cleanup != NULL) 33*e71b7053SJung-uk Kim curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data); 34*e71b7053SJung-uk Kim } 35*e71b7053SJung-uk Kim /* Always free the fd_lookup_st */ 36*e71b7053SJung-uk Kim next = curr->next; 37*e71b7053SJung-uk Kim OPENSSL_free(curr); 38*e71b7053SJung-uk Kim curr = next; 39*e71b7053SJung-uk Kim } 40*e71b7053SJung-uk Kim 41*e71b7053SJung-uk Kim OPENSSL_free(ctx); 42*e71b7053SJung-uk Kim } 43*e71b7053SJung-uk Kim int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, 44*e71b7053SJung-uk Kim OSSL_ASYNC_FD fd, void *custom_data, 45*e71b7053SJung-uk Kim void (*cleanup)(ASYNC_WAIT_CTX *, const void *, 46*e71b7053SJung-uk Kim OSSL_ASYNC_FD, void *)) 47*e71b7053SJung-uk Kim { 48*e71b7053SJung-uk Kim struct fd_lookup_st *fdlookup; 49*e71b7053SJung-uk Kim 50*e71b7053SJung-uk Kim if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) { 51*e71b7053SJung-uk Kim ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, ERR_R_MALLOC_FAILURE); 52*e71b7053SJung-uk Kim return 0; 53*e71b7053SJung-uk Kim } 54*e71b7053SJung-uk Kim 55*e71b7053SJung-uk Kim fdlookup->key = key; 56*e71b7053SJung-uk Kim fdlookup->fd = fd; 57*e71b7053SJung-uk Kim fdlookup->custom_data = custom_data; 58*e71b7053SJung-uk Kim fdlookup->cleanup = cleanup; 59*e71b7053SJung-uk Kim fdlookup->add = 1; 60*e71b7053SJung-uk Kim fdlookup->next = ctx->fds; 61*e71b7053SJung-uk Kim ctx->fds = fdlookup; 62*e71b7053SJung-uk Kim ctx->numadd++; 63*e71b7053SJung-uk Kim return 1; 64*e71b7053SJung-uk Kim } 65*e71b7053SJung-uk Kim 66*e71b7053SJung-uk Kim int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, 67*e71b7053SJung-uk Kim OSSL_ASYNC_FD *fd, void **custom_data) 68*e71b7053SJung-uk Kim { 69*e71b7053SJung-uk Kim struct fd_lookup_st *curr; 70*e71b7053SJung-uk Kim 71*e71b7053SJung-uk Kim curr = ctx->fds; 72*e71b7053SJung-uk Kim while (curr != NULL) { 73*e71b7053SJung-uk Kim if (curr->del) { 74*e71b7053SJung-uk Kim /* This one has been marked deleted so do nothing */ 75*e71b7053SJung-uk Kim curr = curr->next; 76*e71b7053SJung-uk Kim continue; 77*e71b7053SJung-uk Kim } 78*e71b7053SJung-uk Kim if (curr->key == key) { 79*e71b7053SJung-uk Kim *fd = curr->fd; 80*e71b7053SJung-uk Kim *custom_data = curr->custom_data; 81*e71b7053SJung-uk Kim return 1; 82*e71b7053SJung-uk Kim } 83*e71b7053SJung-uk Kim curr = curr->next; 84*e71b7053SJung-uk Kim } 85*e71b7053SJung-uk Kim return 0; 86*e71b7053SJung-uk Kim } 87*e71b7053SJung-uk Kim 88*e71b7053SJung-uk Kim int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, 89*e71b7053SJung-uk Kim size_t *numfds) 90*e71b7053SJung-uk Kim { 91*e71b7053SJung-uk Kim struct fd_lookup_st *curr; 92*e71b7053SJung-uk Kim 93*e71b7053SJung-uk Kim curr = ctx->fds; 94*e71b7053SJung-uk Kim *numfds = 0; 95*e71b7053SJung-uk Kim while (curr != NULL) { 96*e71b7053SJung-uk Kim if (curr->del) { 97*e71b7053SJung-uk Kim /* This one has been marked deleted so do nothing */ 98*e71b7053SJung-uk Kim curr = curr->next; 99*e71b7053SJung-uk Kim continue; 100*e71b7053SJung-uk Kim } 101*e71b7053SJung-uk Kim if (fd != NULL) { 102*e71b7053SJung-uk Kim *fd = curr->fd; 103*e71b7053SJung-uk Kim fd++; 104*e71b7053SJung-uk Kim } 105*e71b7053SJung-uk Kim (*numfds)++; 106*e71b7053SJung-uk Kim curr = curr->next; 107*e71b7053SJung-uk Kim } 108*e71b7053SJung-uk Kim return 1; 109*e71b7053SJung-uk Kim } 110*e71b7053SJung-uk Kim 111*e71b7053SJung-uk Kim int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, 112*e71b7053SJung-uk Kim size_t *numaddfds, OSSL_ASYNC_FD *delfd, 113*e71b7053SJung-uk Kim size_t *numdelfds) 114*e71b7053SJung-uk Kim { 115*e71b7053SJung-uk Kim struct fd_lookup_st *curr; 116*e71b7053SJung-uk Kim 117*e71b7053SJung-uk Kim *numaddfds = ctx->numadd; 118*e71b7053SJung-uk Kim *numdelfds = ctx->numdel; 119*e71b7053SJung-uk Kim if (addfd == NULL && delfd == NULL) 120*e71b7053SJung-uk Kim return 1; 121*e71b7053SJung-uk Kim 122*e71b7053SJung-uk Kim curr = ctx->fds; 123*e71b7053SJung-uk Kim 124*e71b7053SJung-uk Kim while (curr != NULL) { 125*e71b7053SJung-uk Kim /* We ignore fds that have been marked as both added and deleted */ 126*e71b7053SJung-uk Kim if (curr->del && !curr->add && (delfd != NULL)) { 127*e71b7053SJung-uk Kim *delfd = curr->fd; 128*e71b7053SJung-uk Kim delfd++; 129*e71b7053SJung-uk Kim } 130*e71b7053SJung-uk Kim if (curr->add && !curr->del && (addfd != NULL)) { 131*e71b7053SJung-uk Kim *addfd = curr->fd; 132*e71b7053SJung-uk Kim addfd++; 133*e71b7053SJung-uk Kim } 134*e71b7053SJung-uk Kim curr = curr->next; 135*e71b7053SJung-uk Kim } 136*e71b7053SJung-uk Kim 137*e71b7053SJung-uk Kim return 1; 138*e71b7053SJung-uk Kim } 139*e71b7053SJung-uk Kim 140*e71b7053SJung-uk Kim int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key) 141*e71b7053SJung-uk Kim { 142*e71b7053SJung-uk Kim struct fd_lookup_st *curr, *prev; 143*e71b7053SJung-uk Kim 144*e71b7053SJung-uk Kim curr = ctx->fds; 145*e71b7053SJung-uk Kim prev = NULL; 146*e71b7053SJung-uk Kim while (curr != NULL) { 147*e71b7053SJung-uk Kim if (curr->del == 1) { 148*e71b7053SJung-uk Kim /* This one has been marked deleted already so do nothing */ 149*e71b7053SJung-uk Kim prev = curr; 150*e71b7053SJung-uk Kim curr = curr->next; 151*e71b7053SJung-uk Kim continue; 152*e71b7053SJung-uk Kim } 153*e71b7053SJung-uk Kim if (curr->key == key) { 154*e71b7053SJung-uk Kim /* If fd has just been added, remove it from the list */ 155*e71b7053SJung-uk Kim if (curr->add == 1) { 156*e71b7053SJung-uk Kim if (ctx->fds == curr) { 157*e71b7053SJung-uk Kim ctx->fds = curr->next; 158*e71b7053SJung-uk Kim } else { 159*e71b7053SJung-uk Kim prev->next = curr->next; 160*e71b7053SJung-uk Kim } 161*e71b7053SJung-uk Kim 162*e71b7053SJung-uk Kim /* It is responsibility of the caller to cleanup before calling 163*e71b7053SJung-uk Kim * ASYNC_WAIT_CTX_clear_fd 164*e71b7053SJung-uk Kim */ 165*e71b7053SJung-uk Kim OPENSSL_free(curr); 166*e71b7053SJung-uk Kim ctx->numadd--; 167*e71b7053SJung-uk Kim return 1; 168*e71b7053SJung-uk Kim } 169*e71b7053SJung-uk Kim 170*e71b7053SJung-uk Kim /* 171*e71b7053SJung-uk Kim * Mark it as deleted. We don't call cleanup if explicitly asked 172*e71b7053SJung-uk Kim * to clear an fd. We assume the caller is going to do that (if 173*e71b7053SJung-uk Kim * appropriate). 174*e71b7053SJung-uk Kim */ 175*e71b7053SJung-uk Kim curr->del = 1; 176*e71b7053SJung-uk Kim ctx->numdel++; 177*e71b7053SJung-uk Kim return 1; 178*e71b7053SJung-uk Kim } 179*e71b7053SJung-uk Kim prev = curr; 180*e71b7053SJung-uk Kim curr = curr->next; 181*e71b7053SJung-uk Kim } 182*e71b7053SJung-uk Kim return 0; 183*e71b7053SJung-uk Kim } 184*e71b7053SJung-uk Kim 185*e71b7053SJung-uk Kim void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx) 186*e71b7053SJung-uk Kim { 187*e71b7053SJung-uk Kim struct fd_lookup_st *curr, *prev = NULL; 188*e71b7053SJung-uk Kim 189*e71b7053SJung-uk Kim ctx->numadd = 0; 190*e71b7053SJung-uk Kim ctx->numdel = 0; 191*e71b7053SJung-uk Kim 192*e71b7053SJung-uk Kim curr = ctx->fds; 193*e71b7053SJung-uk Kim 194*e71b7053SJung-uk Kim while (curr != NULL) { 195*e71b7053SJung-uk Kim if (curr->del) { 196*e71b7053SJung-uk Kim if (prev == NULL) 197*e71b7053SJung-uk Kim ctx->fds = curr->next; 198*e71b7053SJung-uk Kim else 199*e71b7053SJung-uk Kim prev->next = curr->next; 200*e71b7053SJung-uk Kim OPENSSL_free(curr); 201*e71b7053SJung-uk Kim if (prev == NULL) 202*e71b7053SJung-uk Kim curr = ctx->fds; 203*e71b7053SJung-uk Kim else 204*e71b7053SJung-uk Kim curr = prev->next; 205*e71b7053SJung-uk Kim continue; 206*e71b7053SJung-uk Kim } 207*e71b7053SJung-uk Kim if (curr->add) { 208*e71b7053SJung-uk Kim curr->add = 0; 209*e71b7053SJung-uk Kim } 210*e71b7053SJung-uk Kim prev = curr; 211*e71b7053SJung-uk Kim curr = curr->next; 212*e71b7053SJung-uk Kim } 213*e71b7053SJung-uk Kim } 214