addrvec.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. #include <stdlib.h>
  19. #include <string.h>
  20. #include <assert.h>
  21. #include <errno.h>
  22. #ifdef WIN32
  23. #define random rand /* replace POSIX random with Windows rand */
  24. #include <winsock2.h> /* must always be included before ws2tcpip.h */
  25. #include <ws2tcpip.h> /* for sockaddr_storage */
  26. #include "winport.h"
  27. #endif
  28. #include "addrvec.h"
  29. #define ADDRVEC_DEFAULT_GROW_AMOUNT 16
  30. void addrvec_init(addrvec_t *avec)
  31. {
  32. assert(avec);
  33. avec->next = 0;
  34. avec->count = 0;
  35. avec->capacity = 0;
  36. avec->data = NULL;
  37. }
  38. void addrvec_free(addrvec_t *avec)
  39. {
  40. if (avec == NULL)
  41. {
  42. return;
  43. }
  44. avec->next = 0;
  45. avec->count = 0;
  46. avec->capacity = 0;
  47. if (avec->data) {
  48. free(avec->data);
  49. avec->data = NULL;
  50. }
  51. }
  52. int addrvec_alloc(addrvec_t *avec)
  53. {
  54. addrvec_init(avec);
  55. return addrvec_grow_default(avec);
  56. }
  57. int addrvec_alloc_capacity(addrvec_t* avec, uint32_t capacity)
  58. {
  59. addrvec_init(avec);
  60. return addrvec_grow(avec, capacity);
  61. }
  62. int addrvec_grow(addrvec_t *avec, uint32_t grow_amount)
  63. {
  64. unsigned int old_capacity = 0;
  65. struct sockaddr_storage *old_data = NULL;
  66. assert(avec);
  67. if (grow_amount == 0)
  68. {
  69. return 0;
  70. }
  71. // Save off old data and capacity in case there is a realloc failure
  72. old_capacity = avec->capacity;
  73. old_data = avec->data;
  74. avec->capacity += grow_amount;
  75. avec->data = realloc(avec->data, sizeof(*avec->data) * avec->capacity);
  76. if (avec->data == NULL)
  77. {
  78. avec->capacity = old_capacity;
  79. avec->data = old_data;
  80. errno = ENOMEM;
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. int addrvec_grow_default(addrvec_t *avec)
  86. {
  87. return addrvec_grow(avec, ADDRVEC_DEFAULT_GROW_AMOUNT);
  88. }
  89. static int addrvec_grow_if_full(addrvec_t *avec)
  90. {
  91. assert(avec);
  92. if (avec->count == avec->capacity)
  93. {
  94. int rc = addrvec_grow_default(avec);
  95. if (rc != 0)
  96. {
  97. return rc;
  98. }
  99. }
  100. return 0;
  101. }
  102. int addrvec_contains(const addrvec_t *avec, const struct sockaddr_storage *addr)
  103. {
  104. uint32_t i = 0;
  105. if (!avec || !addr)
  106. {
  107. return 0;
  108. }
  109. for (i = 0; i < avec->count; i++)
  110. {
  111. if (avec->data[i].ss_family != addr->ss_family)
  112. continue;
  113. switch (addr->ss_family) {
  114. case AF_INET:
  115. if (memcmp(&((struct sockaddr_in*)&avec->data[i])->sin_addr,
  116. &((struct sockaddr_in*)addr)->sin_addr,
  117. sizeof(struct in_addr)) == 0)
  118. return 1;
  119. break;
  120. #ifdef AF_INET6
  121. case AF_INET6:
  122. if (memcmp(&((struct sockaddr_in6*)&avec->data[i])->sin6_addr,
  123. &((struct sockaddr_in6*)addr)->sin6_addr,
  124. sizeof(struct in6_addr)) == 0)
  125. return 1;
  126. break;
  127. #endif
  128. default:
  129. break;
  130. }
  131. }
  132. return 0;
  133. }
  134. int addrvec_append(addrvec_t *avec, const struct sockaddr_storage *addr)
  135. {
  136. int rc = 0;
  137. assert(avec);
  138. assert(addr);
  139. rc = addrvec_grow_if_full(avec);
  140. if (rc != 0)
  141. {
  142. return rc;
  143. }
  144. // Copy addrinfo into address list
  145. memcpy(avec->data + avec->count, addr, sizeof(*addr));
  146. ++avec->count;
  147. return 0;
  148. }
  149. int addrvec_append_addrinfo(addrvec_t *avec, const struct addrinfo *addrinfo)
  150. {
  151. int rc = 0;
  152. assert(avec);
  153. assert(addrinfo);
  154. rc = addrvec_grow_if_full(avec);
  155. if (rc != 0)
  156. {
  157. return rc;
  158. }
  159. // Copy addrinfo into address list
  160. memcpy(avec->data + avec->count, addrinfo->ai_addr, addrinfo->ai_addrlen);
  161. ++avec->count;
  162. return 0;
  163. }
  164. void addrvec_shuffle(addrvec_t *avec)
  165. {
  166. int i = 0;
  167. for (i = avec->count - 1; i > 0; --i) {
  168. long int j = random()%(i+1);
  169. if (i != j) {
  170. struct sockaddr_storage t = avec->data[i];
  171. avec->data[i] = avec->data[j];
  172. avec->data[j] = t;
  173. }
  174. }
  175. }
  176. int addrvec_hasnext(const addrvec_t *avec)
  177. {
  178. return avec->count > 0 && (avec->next < avec->count);
  179. }
  180. int addrvec_atend(const addrvec_t *avec)
  181. {
  182. return avec->count > 0 && avec->next >= avec->count;
  183. }
  184. void addrvec_next(addrvec_t *avec, struct sockaddr_storage *next)
  185. {
  186. int index;
  187. // If we're at the end of the list, then reset index to start
  188. if (addrvec_atend(avec)) {
  189. avec->next = 0;
  190. }
  191. if (!addrvec_hasnext(avec)) {
  192. if (next) {
  193. memset(next, 0, sizeof(*next));
  194. }
  195. return;
  196. }
  197. index = avec->next++;
  198. if (next) {
  199. *next = avec->data[index];
  200. }
  201. }
  202. void addrvec_peek(addrvec_t *avec, struct sockaddr_storage *next)
  203. {
  204. int index = avec->next;
  205. if (avec->count == 0) {
  206. memset(next, 0, sizeof(*next));
  207. return;
  208. }
  209. if (addrvec_atend(avec)) {
  210. index = 0;
  211. }
  212. *next = avec->data[index];
  213. }
  214. int addrvec_eq(const addrvec_t *a1, const addrvec_t *a2)
  215. {
  216. uint32_t i = 0;
  217. if (a1->count != a2->count)
  218. {
  219. return 0;
  220. }
  221. for (i = 0; i < a1->count; ++i)
  222. {
  223. if (!addrvec_contains(a2, &a1->data[i]))
  224. return 0;
  225. }
  226. return 1;
  227. }