1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #ifndef ADDRVEC_H_ 20 #define ADDRVEC_H_ 21 22 #ifndef WIN32 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <netinet/in.h> 26 #include <netdb.h> 27 #else 28 #include <WinSock2.h> 29 #include <stdint.h> 30 #endif 31 32 /** 33 * This structure represents a list of addresses. It stores the count of the 34 * number of elements that have been inserted via calls to addrvec_append and 35 * addrvec_append_addrinfo. It also has a capacity field for the number of 36 * addresses it has the ability to hold without needing to be enlarged. 37 */ 38 typedef struct _addrvec { 39 unsigned int next; // next index to use 40 unsigned int count; // number of addresses in this list 41 unsigned int capacity; // number of address this list can hold 42 struct sockaddr_storage *data; // list of addresses 43 } addrvec_t; 44 45 /** 46 * Initialize an addrvec by clearing out all its state. 47 */ 48 void addrvec_init(addrvec_t *avec); 49 50 /** 51 * Free any memory used internally by an addrvec 52 */ 53 void addrvec_free(addrvec_t *avec); 54 55 /** 56 * Allocate an addrvec with a default capacity (16) 57 */ 58 int addrvec_alloc(addrvec_t *avec); 59 60 /** 61 * Allocates an addrvec with a specified capacity 62 */ 63 int addrvec_alloc_capacity(addrvec_t *avec, uint32_t capacity); 64 65 /** 66 * Grow an addrvec by the specified amount. This will increase the capacity 67 * of the vector and not the contents. 68 */ 69 int addrvec_grow(addrvec_t *avec, uint32_t grow_amount); 70 71 /** 72 * Similar to addrvec_grow but uses a default growth amount of 16. 73 */ 74 int addrvec_grow_default(addrvec_t *avec); 75 76 /** 77 * Check if an addrvec contains the specificed sockaddr_storage value. 78 * \returns 1 if it contains the value and 0 otherwise. 79 */ 80 int addrvec_contains(const addrvec_t *avec, const struct sockaddr_storage *addr); 81 82 /** 83 * Append the given sockaddr_storage pointer into the addrvec. The contents of 84 * the given 'addr' are copied into the addrvec via memcpy. 85 */ 86 int addrvec_append(addrvec_t *avec, const struct sockaddr_storage *addr); 87 88 /** 89 * Append the given addrinfo pointer into the addrvec. The contents of the given 90 * 'addrinfo' are copied into the addrvec via memcpy. 91 */ 92 int addrvec_append_addrinfo(addrvec_t *avec, const struct addrinfo *addrinfo); 93 94 /** 95 * Shuffle the addrvec so that it's internal list of addresses are randomized. 96 * Uses random() and assumes it has been properly seeded. 97 */ 98 void addrvec_shuffle(addrvec_t *avec); 99 100 /** 101 * Determine if the addrvec has a next element (e.g. it's safe to call addrvec_next) 102 * 103 * \returns 1 if it has a next element and 0 otherwise 104 */ 105 int addrvec_hasnext(const addrvec_t *avec); 106 107 /** 108 * Determine if the addrvec is at the end or not. Specifically, this means a 109 * subsequent call to addrvec_next will loop around to the start again. 110 */ 111 int addrvec_atend(const addrvec_t *avec); 112 113 /** 114 * Get the next entry from the addrvec and update the associated index. 115 * 116 * If next is NULL, the index will still be updated. 117 * 118 * If the current index points at (or after) the last element in the vector then 119 * it will loop back around and start at the beginning of the list. 120 */ 121 void addrvec_next(addrvec_t *avec, struct sockaddr_storage *next); 122 123 /** 124 * Retrieves the next entry from the addrvec but doesn't update the index. 125 */ 126 void addrvec_peek(addrvec_t *avec, struct sockaddr_storage *next); 127 128 /** 129 * Compare two addrvecs for equality. 130 * 131 * \returns 1 if the contents of the two lists are identical and and 0 otherwise. 132 */ 133 int addrvec_eq(const addrvec_t *a1, const addrvec_t *a2); 134 135 #endif // ADDRVEC_H 136 137 138 139