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