1*e71b7053SJung-uk Kim /* 2*e71b7053SJung-uk Kim * Copyright 2005-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 #include "ssl_locl.h" 11*e71b7053SJung-uk Kim #include <openssl/bn.h> 12*e71b7053SJung-uk Kim 13*e71b7053SJung-uk Kim struct pqueue_st { 14*e71b7053SJung-uk Kim pitem *items; 15*e71b7053SJung-uk Kim int count; 16*e71b7053SJung-uk Kim }; 17*e71b7053SJung-uk Kim 18*e71b7053SJung-uk Kim pitem *pitem_new(unsigned char *prio64be, void *data) 19*e71b7053SJung-uk Kim { 20*e71b7053SJung-uk Kim pitem *item = OPENSSL_malloc(sizeof(*item)); 21*e71b7053SJung-uk Kim 22*e71b7053SJung-uk Kim if (item == NULL) { 23*e71b7053SJung-uk Kim SSLerr(SSL_F_PITEM_NEW, ERR_R_MALLOC_FAILURE); 24*e71b7053SJung-uk Kim return NULL; 25*e71b7053SJung-uk Kim } 26*e71b7053SJung-uk Kim 27*e71b7053SJung-uk Kim memcpy(item->priority, prio64be, sizeof(item->priority)); 28*e71b7053SJung-uk Kim item->data = data; 29*e71b7053SJung-uk Kim item->next = NULL; 30*e71b7053SJung-uk Kim return item; 31*e71b7053SJung-uk Kim } 32*e71b7053SJung-uk Kim 33*e71b7053SJung-uk Kim void pitem_free(pitem *item) 34*e71b7053SJung-uk Kim { 35*e71b7053SJung-uk Kim OPENSSL_free(item); 36*e71b7053SJung-uk Kim } 37*e71b7053SJung-uk Kim 38*e71b7053SJung-uk Kim pqueue *pqueue_new(void) 39*e71b7053SJung-uk Kim { 40*e71b7053SJung-uk Kim pqueue *pq = OPENSSL_zalloc(sizeof(*pq)); 41*e71b7053SJung-uk Kim 42*e71b7053SJung-uk Kim if (pq == NULL) 43*e71b7053SJung-uk Kim SSLerr(SSL_F_PQUEUE_NEW, ERR_R_MALLOC_FAILURE); 44*e71b7053SJung-uk Kim 45*e71b7053SJung-uk Kim return pq; 46*e71b7053SJung-uk Kim } 47*e71b7053SJung-uk Kim 48*e71b7053SJung-uk Kim void pqueue_free(pqueue *pq) 49*e71b7053SJung-uk Kim { 50*e71b7053SJung-uk Kim OPENSSL_free(pq); 51*e71b7053SJung-uk Kim } 52*e71b7053SJung-uk Kim 53*e71b7053SJung-uk Kim pitem *pqueue_insert(pqueue *pq, pitem *item) 54*e71b7053SJung-uk Kim { 55*e71b7053SJung-uk Kim pitem *curr, *next; 56*e71b7053SJung-uk Kim 57*e71b7053SJung-uk Kim if (pq->items == NULL) { 58*e71b7053SJung-uk Kim pq->items = item; 59*e71b7053SJung-uk Kim return item; 60*e71b7053SJung-uk Kim } 61*e71b7053SJung-uk Kim 62*e71b7053SJung-uk Kim for (curr = NULL, next = pq->items; 63*e71b7053SJung-uk Kim next != NULL; curr = next, next = next->next) { 64*e71b7053SJung-uk Kim /* 65*e71b7053SJung-uk Kim * we can compare 64-bit value in big-endian encoding with memcmp:-) 66*e71b7053SJung-uk Kim */ 67*e71b7053SJung-uk Kim int cmp = memcmp(next->priority, item->priority, 8); 68*e71b7053SJung-uk Kim if (cmp > 0) { /* next > item */ 69*e71b7053SJung-uk Kim item->next = next; 70*e71b7053SJung-uk Kim 71*e71b7053SJung-uk Kim if (curr == NULL) 72*e71b7053SJung-uk Kim pq->items = item; 73*e71b7053SJung-uk Kim else 74*e71b7053SJung-uk Kim curr->next = item; 75*e71b7053SJung-uk Kim 76*e71b7053SJung-uk Kim return item; 77*e71b7053SJung-uk Kim } 78*e71b7053SJung-uk Kim 79*e71b7053SJung-uk Kim else if (cmp == 0) /* duplicates not allowed */ 80*e71b7053SJung-uk Kim return NULL; 81*e71b7053SJung-uk Kim } 82*e71b7053SJung-uk Kim 83*e71b7053SJung-uk Kim item->next = NULL; 84*e71b7053SJung-uk Kim curr->next = item; 85*e71b7053SJung-uk Kim 86*e71b7053SJung-uk Kim return item; 87*e71b7053SJung-uk Kim } 88*e71b7053SJung-uk Kim 89*e71b7053SJung-uk Kim pitem *pqueue_peek(pqueue *pq) 90*e71b7053SJung-uk Kim { 91*e71b7053SJung-uk Kim return pq->items; 92*e71b7053SJung-uk Kim } 93*e71b7053SJung-uk Kim 94*e71b7053SJung-uk Kim pitem *pqueue_pop(pqueue *pq) 95*e71b7053SJung-uk Kim { 96*e71b7053SJung-uk Kim pitem *item = pq->items; 97*e71b7053SJung-uk Kim 98*e71b7053SJung-uk Kim if (pq->items != NULL) 99*e71b7053SJung-uk Kim pq->items = pq->items->next; 100*e71b7053SJung-uk Kim 101*e71b7053SJung-uk Kim return item; 102*e71b7053SJung-uk Kim } 103*e71b7053SJung-uk Kim 104*e71b7053SJung-uk Kim pitem *pqueue_find(pqueue *pq, unsigned char *prio64be) 105*e71b7053SJung-uk Kim { 106*e71b7053SJung-uk Kim pitem *next; 107*e71b7053SJung-uk Kim pitem *found = NULL; 108*e71b7053SJung-uk Kim 109*e71b7053SJung-uk Kim if (pq->items == NULL) 110*e71b7053SJung-uk Kim return NULL; 111*e71b7053SJung-uk Kim 112*e71b7053SJung-uk Kim for (next = pq->items; next->next != NULL; next = next->next) { 113*e71b7053SJung-uk Kim if (memcmp(next->priority, prio64be, 8) == 0) { 114*e71b7053SJung-uk Kim found = next; 115*e71b7053SJung-uk Kim break; 116*e71b7053SJung-uk Kim } 117*e71b7053SJung-uk Kim } 118*e71b7053SJung-uk Kim 119*e71b7053SJung-uk Kim /* check the one last node */ 120*e71b7053SJung-uk Kim if (memcmp(next->priority, prio64be, 8) == 0) 121*e71b7053SJung-uk Kim found = next; 122*e71b7053SJung-uk Kim 123*e71b7053SJung-uk Kim if (!found) 124*e71b7053SJung-uk Kim return NULL; 125*e71b7053SJung-uk Kim 126*e71b7053SJung-uk Kim return found; 127*e71b7053SJung-uk Kim } 128*e71b7053SJung-uk Kim 129*e71b7053SJung-uk Kim pitem *pqueue_iterator(pqueue *pq) 130*e71b7053SJung-uk Kim { 131*e71b7053SJung-uk Kim return pqueue_peek(pq); 132*e71b7053SJung-uk Kim } 133*e71b7053SJung-uk Kim 134*e71b7053SJung-uk Kim pitem *pqueue_next(piterator *item) 135*e71b7053SJung-uk Kim { 136*e71b7053SJung-uk Kim pitem *ret; 137*e71b7053SJung-uk Kim 138*e71b7053SJung-uk Kim if (item == NULL || *item == NULL) 139*e71b7053SJung-uk Kim return NULL; 140*e71b7053SJung-uk Kim 141*e71b7053SJung-uk Kim /* *item != NULL */ 142*e71b7053SJung-uk Kim ret = *item; 143*e71b7053SJung-uk Kim *item = (*item)->next; 144*e71b7053SJung-uk Kim 145*e71b7053SJung-uk Kim return ret; 146*e71b7053SJung-uk Kim } 147*e71b7053SJung-uk Kim 148*e71b7053SJung-uk Kim size_t pqueue_size(pqueue *pq) 149*e71b7053SJung-uk Kim { 150*e71b7053SJung-uk Kim pitem *item = pq->items; 151*e71b7053SJung-uk Kim size_t count = 0; 152*e71b7053SJung-uk Kim 153*e71b7053SJung-uk Kim while (item != NULL) { 154*e71b7053SJung-uk Kim count++; 155*e71b7053SJung-uk Kim item = item->next; 156*e71b7053SJung-uk Kim } 157*e71b7053SJung-uk Kim return count; 158*e71b7053SJung-uk Kim } 159