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