OpenVPN
pool.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #include "pool.h"
33 #include "buffer.h"
34 #include "error.h"
35 #include "socket.h"
36 #include "otime.h"
37 
38 #include "memdbg.h"
39 
40 #if P2MP
41 
42 static void
44 {
45  ipe->in_use = false;
46  if (hard && ipe->common_name)
47  {
48  free(ipe->common_name);
49  ipe->common_name = NULL;
50  }
51  if (hard)
52  {
53  ipe->last_release = 0;
54  }
55  else
56  {
57  ipe->last_release = now;
58  }
59 }
60 
61 static int
62 ifconfig_pool_find(struct ifconfig_pool *pool, const char *common_name)
63 {
64  int i;
65  time_t earliest_release = 0;
66  int previous_usage = -1;
67  int new_usage = -1;
68 
69  for (i = 0; i < pool->size; ++i)
70  {
71  struct ifconfig_pool_entry *ipe = &pool->list[i];
72  if (!ipe->in_use)
73  {
74  /*
75  * If duplicate_cn mode, take first available IP address
76  */
77  if (pool->duplicate_cn)
78  {
79  new_usage = i;
80  break;
81  }
82 
83  /*
84  * Keep track of the unused IP address entry which
85  * was released earliest.
86  */
87  if ((new_usage == -1 || ipe->last_release < earliest_release) && !ipe->fixed)
88  {
89  earliest_release = ipe->last_release;
90  new_usage = i;
91  }
92 
93  /*
94  * Keep track of a possible allocation to us
95  * from an earlier session.
96  */
97  if (previous_usage < 0
98  && common_name
99  && ipe->common_name
100  && !strcmp(common_name, ipe->common_name))
101  {
102  previous_usage = i;
103  }
104 
105  }
106  }
107 
108  if (previous_usage >= 0)
109  {
110  return previous_usage;
111  }
112 
113  if (new_usage >= 0)
114  {
115  return new_usage;
116  }
117 
118  return -1;
119 }
120 
121 /*
122  * Verify start/end range
123  */
124 bool
125 ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
126 {
127  struct gc_arena gc = gc_new();
128  bool ret = true;
129 
130  if (start > end)
131  {
132  msg(msglevel, "--ifconfig-pool start IP [%s] is greater than end IP [%s]",
133  print_in_addr_t(start, 0, &gc),
134  print_in_addr_t(end, 0, &gc));
135  ret = false;
136  }
137  if (end - start >= IFCONFIG_POOL_MAX)
138  {
139  msg(msglevel, "--ifconfig-pool address range is too large [%s -> %s]. Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.",
140  print_in_addr_t(start, 0, &gc),
141  print_in_addr_t(end, 0, &gc),
143  ret = false;
144  }
145  gc_free(&gc);
146  return ret;
147 }
148 
149 struct ifconfig_pool *
150 ifconfig_pool_init(const bool ipv4_pool, enum pool_type type, in_addr_t start,
151  in_addr_t end, const bool duplicate_cn,
152  const bool ipv6_pool, const struct in6_addr ipv6_base,
153  const int ipv6_netbits )
154 {
155  struct gc_arena gc = gc_new();
156  struct ifconfig_pool *pool = NULL;
157  int pool_ipv4_size = -1, pool_ipv6_size = -1;
158 
159  ASSERT(start <= end && end - start < IFCONFIG_POOL_MAX);
160  ALLOC_OBJ_CLEAR(pool, struct ifconfig_pool);
161 
162  pool->duplicate_cn = duplicate_cn;
163 
164  pool->ipv4.enabled = ipv4_pool;
165 
166  if (pool->ipv4.enabled)
167  {
168  pool->ipv4.type = type;
169  switch (pool->ipv4.type)
170  {
171  case IFCONFIG_POOL_30NET:
172  pool->ipv4.base = start & ~3;
173  pool_ipv4_size = (((end | 3) + 1) - pool->ipv4.base) >> 2;
174  break;
175 
176  case IFCONFIG_POOL_INDIV:
177  pool->ipv4.base = start;
178  pool_ipv4_size = end - start + 1;
179  break;
180 
181  default:
182  ASSERT(0);
183  }
184 
185  if (pool_ipv4_size < 2)
186  {
187  msg(M_FATAL, "IPv4 pool size is too small (%d), must be at least 2",
188  pool_ipv4_size);
189  }
190 
191  msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv4: base=%s size=%d",
192  print_in_addr_t(pool->ipv4.base, 0, &gc), pool_ipv4_size);
193 
194  pool->size = pool_ipv4_size;
195  }
196 
197  /* IPv6 pools are always "INDIV" type */
198  pool->ipv6.enabled = ipv6_pool;
199 
200  if (pool->ipv6.enabled)
201  {
202  /* the host portion of the address will always be contained in the last
203  * 4 bytes, therefore we can just extract that and use it as base in
204  * integer form
205  */
206  uint32_t base = (ipv6_base.s6_addr[12] << 24)
207  | (ipv6_base.s6_addr[13] << 16)
208  | (ipv6_base.s6_addr[14] << 8)
209  | ipv6_base.s6_addr[15];
210  /* some bits of the last 4 bytes may still be part of the network
211  * portion of the address, therefore we need to set them to 0
212  */
213  if ((128 - ipv6_netbits) < 32)
214  {
215  /* extract only the bits that are really part of the host portion of
216  * the address.
217  *
218  * Example: if we have netbits=31, the first bit has to be zero'd,
219  * the following operation first computes mask=0x3fffff and then
220  * uses mask to extract the wanted bits from base
221  */
222  uint32_t mask = (1 << (128 - ipv6_netbits) ) - 1;
223  base &= mask;
224  }
225 
226  pool->ipv6.base = ipv6_base;
227 
228  /* if a pool starts at a base address that has all-zero in the
229  * host part, that first IPv6 address must not be assigned to
230  * clients because it is not usable (subnet anycast address).
231  * Start with 1, then.
232  *
233  * NOTE: this will also (mis-)fire for something like
234  * ifconfig-ipv6-pool 2001:db8:0:1:1234::0/64
235  * as we only check the rightmost 32 bits of the host part. So be it.
236  */
237  if (base == 0)
238  {
239  msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: incrementing pool start "
240  "to avoid ::0 assignment");
241  base++;
242  pool->ipv6.base.s6_addr[15]++;
243  }
244 
245  pool_ipv6_size = ipv6_netbits >= 112
246  ? (1 << (128 - ipv6_netbits)) - base
248 
249  if (pool_ipv6_size < 2)
250  {
251  msg(M_FATAL, "IPv6 pool size is too small (%d), must be at least 2",
252  pool_ipv6_size);
253  }
254 
255  msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: base=%s size=%d netbits=%d",
256  print_in6_addr(pool->ipv6.base, 0, &gc), pool_ipv6_size,
257  ipv6_netbits);
258 
259  /* if there is no v4 pool, or the v6 pool is smaller, use
260  * v6 pool size as "unified pool size"
261  */
262  if (pool->size <= 0 || pool_ipv6_size < pool->size)
263  {
264  pool->size = pool_ipv6_size;
265  }
266  }
267 
268  if (pool->ipv4.enabled && pool->ipv6.enabled)
269  {
270  if (pool_ipv4_size < pool_ipv6_size)
271  {
272  msg(M_INFO, "NOTE: IPv4 pool size is %d, IPv6 pool size is %d. "
273  "IPv4 pool size limits the number of clients that can be "
274  "served from the pool", pool_ipv4_size, pool_ipv6_size);
275  }
276  else if (pool_ipv4_size > pool_ipv6_size)
277  {
278  msg(M_WARN, "WARNING: IPv4 pool size is %d, IPv6 pool size is %d. "
279  "IPv6 pool size limits the number of clients that can be "
280  "served from the pool. This is likely a MISTAKE - please check "
281  "your configuration", pool_ipv4_size, pool_ipv6_size);
282  }
283  }
284 
285  ASSERT(pool->size > 0);
286 
287  ALLOC_ARRAY_CLEAR(pool->list, struct ifconfig_pool_entry, pool->size);
288 
289  gc_free(&gc);
290  return pool;
291 }
292 
293 void
295 {
296  if (pool)
297  {
298  int i;
299 
300  for (i = 0; i < pool->size; ++i)
301  {
302  ifconfig_pool_entry_free(&pool->list[i], true);
303  }
304  free(pool->list);
305  free(pool);
306  }
307 }
308 
310 ifconfig_pool_acquire(struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
311 {
312  int i;
313 
314  i = ifconfig_pool_find(pool, common_name);
315  if (i >= 0)
316  {
317  struct ifconfig_pool_entry *ipe = &pool->list[i];
318  ASSERT(!ipe->in_use);
319  ifconfig_pool_entry_free(ipe, true);
320  ipe->in_use = true;
321  if (common_name)
322  {
323  ipe->common_name = string_alloc(common_name, NULL);
324  }
325 
326  if (pool->ipv4.enabled && local && remote)
327  {
328  switch (pool->ipv4.type)
329  {
330  case IFCONFIG_POOL_30NET:
331  {
332  in_addr_t b = pool->ipv4.base + (i << 2);
333  *local = b + 1;
334  *remote = b + 2;
335  break;
336  }
337 
338  case IFCONFIG_POOL_INDIV:
339  {
340  in_addr_t b = pool->ipv4.base + i;
341  *local = 0;
342  *remote = b;
343  break;
344  }
345 
346  default:
347  ASSERT(0);
348  }
349  }
350 
351  /* IPv6 pools are always INDIV (--linear) */
352  if (pool->ipv6.enabled && remote_ipv6)
353  {
354  *remote_ipv6 = add_in6_addr(pool->ipv6.base, i);
355  }
356  }
357  return i;
358 }
359 
360 bool
361 ifconfig_pool_release(struct ifconfig_pool *pool, ifconfig_pool_handle hand, const bool hard)
362 {
363  bool ret = false;
364 
365  if (pool && hand >= 0 && hand < pool->size)
366  {
367  ifconfig_pool_entry_free(&pool->list[hand], hard);
368  ret = true;
369  }
370  return ret;
371 }
372 
373 /*
374  * private access functions
375  */
376 
377 /* currently handling IPv4 logic only */
380 {
381  ifconfig_pool_handle ret = -1;
382 
383  switch (pool->ipv4.type)
384  {
385  case IFCONFIG_POOL_30NET:
386  {
387  ret = (addr - pool->ipv4.base) >> 2;
388  break;
389  }
390 
391  case IFCONFIG_POOL_INDIV:
392  {
393  ret = (addr - pool->ipv4.base);
394  break;
395  }
396 
397  default:
398  ASSERT(0);
399  }
400 
401  if (ret < 0 || ret >= pool->size)
402  {
403  ret = -1;
404  }
405 
406  return ret;
407 }
408 
411  const struct in6_addr *in_addr)
412 {
414  uint32_t base, addr;
415 
416  /* IPv6 pool is always IFCONFIG_POOL_INDIV.
417  *
418  * We assume the offset can't be larger than 2^32-1, therefore we compute
419  * the difference only among the last 4 bytes like if they were two 32bit
420  * long integers. The rest of the address must match.
421  */
422  for (int i = 0; i < (12); i++)
423  {
424  if (pool->ipv6.base.s6_addr[i] != in_addr->s6_addr[i])
425  {
426  return -1;
427  }
428  }
429 
430  base = (pool->ipv6.base.s6_addr[12] << 24)
431  | (pool->ipv6.base.s6_addr[13] << 16)
432  | (pool->ipv6.base.s6_addr[14] << 8)
433  | pool->ipv6.base.s6_addr[15];
434 
435  addr = (in_addr->s6_addr[12] << 24)
436  | (in_addr->s6_addr[13] << 16)
437  | (in_addr->s6_addr[14] << 8)
438  | in_addr->s6_addr[15];
439 
440  ret = addr - base;
441  if (ret < 0 || ret >= pool->size)
442  {
443  ret = -1;
444  }
445 
446  return ret;
447 }
448 
449 static in_addr_t
451 {
452  in_addr_t ret = 0;
453 
454  if (pool->ipv4.enabled && hand >= 0 && hand < pool->size)
455  {
456  switch (pool->ipv4.type)
457  {
458  case IFCONFIG_POOL_30NET:
459  {
460  ret = pool->ipv4.base + (hand << 2);
461  break;
462  }
463 
464  case IFCONFIG_POOL_INDIV:
465  {
466  ret = pool->ipv4.base + hand;
467  break;
468  }
469 
470  default:
471  ASSERT(0);
472  }
473  }
474 
475  return ret;
476 }
477 
478 static struct in6_addr
480 {
481  struct in6_addr ret = IN6ADDR_ANY_INIT;
482 
483  /* IPv6 pools are always INDIV (--linear) */
484  if (pool->ipv6.enabled && hand >= 0 && hand < pool->size)
485  {
486  ret = add_in6_addr( pool->ipv6.base, hand );
487  }
488  return ret;
489 }
490 
491 static void
492 ifconfig_pool_set(struct ifconfig_pool *pool, const char *cn,
493  ifconfig_pool_handle h, const bool fixed)
494 {
495  struct ifconfig_pool_entry *e = &pool->list[h];
496  ifconfig_pool_entry_free(e, true);
497  e->in_use = false;
498  e->common_name = string_alloc(cn, NULL);
499  e->last_release = now;
500  e->fixed = fixed;
501 }
502 
503 static void
504 ifconfig_pool_list(const struct ifconfig_pool *pool, struct status_output *out)
505 {
506  if (pool && out)
507  {
508  struct gc_arena gc = gc_new();
509  int i;
510 
511  for (i = 0; i < pool->size; ++i)
512  {
513  const struct ifconfig_pool_entry *e = &pool->list[i];
514  struct in6_addr ip6;
515  in_addr_t ip;
516  const char *ip6_str = "";
517  const char *ip_str = "";
518 
519  if (e->common_name)
520  {
521  if (pool->ipv4.enabled)
522  {
523  ip = ifconfig_pool_handle_to_ip_base(pool, i);
524  ip_str = print_in_addr_t(ip, 0, &gc);
525  }
526 
527  if (pool->ipv6.enabled)
528  {
529  ip6 = ifconfig_pool_handle_to_ipv6_base(pool, i);
530  ip6_str = print_in6_addr(ip6, 0, &gc);
531  }
532 
533  status_printf(out, "%s,%s,%s", e->common_name, ip_str, ip6_str);
534  }
535  }
536  gc_free(&gc);
537  }
538 }
539 
540 static void
541 ifconfig_pool_msg(const struct ifconfig_pool *pool, int msglevel)
542 {
543  struct status_output *so = status_open(NULL, 0, msglevel, NULL, 0);
544  ASSERT(so);
545  status_printf(so, "IFCONFIG POOL LIST");
546  ifconfig_pool_list(pool, so);
547  status_close(so);
548 }
549 
550 /*
551  * Deal with reading/writing the ifconfig pool database to a file
552  */
553 
554 struct ifconfig_pool_persist *
555 ifconfig_pool_persist_init(const char *filename, int refresh_freq)
556 {
557  struct ifconfig_pool_persist *ret;
558 
559  ASSERT(filename);
560 
562  if (refresh_freq > 0)
563  {
564  ret->fixed = false;
565  ret->file = status_open(filename, refresh_freq, -1, NULL, STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE);
566  }
567  else
568  {
569  ret->fixed = true;
570  ret->file = status_open(filename, 0, -1, NULL, STATUS_OUTPUT_READ);
571  }
572  return ret;
573 }
574 
575 void
577 {
578  if (persist)
579  {
580  if (persist->file)
581  {
582  status_close(persist->file);
583  }
584  free(persist);
585  }
586 }
587 
588 bool
590 {
591  if (persist->file)
592  {
593  return status_trigger(persist->file);
594  }
595  else
596  {
597  return false;
598  }
599 }
600 
601 void
603 {
604  const int buf_size = 128;
605 
606  update_time();
607 
608  if (persist && persist->file && pool)
609  {
610  struct gc_arena gc = gc_new();
611  struct buffer in = alloc_buf_gc(256, &gc);
612  char *cn_buf, *ip_buf, *ip6_buf;
613  int line = 0;
614 
615  ALLOC_ARRAY_CLEAR_GC(cn_buf, char, buf_size, &gc);
616  ALLOC_ARRAY_CLEAR_GC(ip_buf, char, buf_size, &gc);
617  ALLOC_ARRAY_CLEAR_GC(ip6_buf, char, buf_size, &gc);
618 
619  while (true)
620  {
621  ASSERT(buf_init(&in, 0));
622  if (!status_read(persist->file, &in))
623  {
624  break;
625  }
626  ++line;
627  if (!BLEN(&in))
628  {
629  continue;
630  }
631 
632  int c = *BSTR(&in);
633  if (c == '#' || c == ';')
634  {
635  continue;
636  }
637 
638  msg(M_INFO, "ifconfig_pool_read(), in='%s'", BSTR(&in));
639 
640  /* The expected format of a line is: "CN,IP4,IP6".
641  *
642  * IP4 or IP6 may be empty when respectively no v4 or v6 pool
643  * was previously specified.
644  *
645  * This means that accepted strings can be:
646  * - CN,IP4,IP6
647  * - CN,IP4
648  * - CN,,IP6
649  */
650  if (!buf_parse(&in, ',', cn_buf, buf_size)
651  || !buf_parse(&in, ',', ip_buf, buf_size))
652  {
653  continue;
654  }
655 
656  ifconfig_pool_handle h = -1, h6 = -1;
657 
658  if (strlen(ip_buf) > 0)
659  {
660  bool v4_ok = true;
661  in_addr_t addr = getaddr(GETADDR_HOST_ORDER, ip_buf, 0, &v4_ok,
662  NULL);
663 
664  if (!v4_ok)
665  {
666  msg(M_WARN, "pool: invalid IPv4 (%s) for CN=%s", ip_buf,
667  cn_buf);
668  }
669  else
670  {
671  h = ifconfig_pool_ip_base_to_handle(pool, addr);
672  if (h < 0)
673  {
674  msg(M_WARN,
675  "pool: IPv4 (%s) out of pool range for CN=%s",
676  ip_buf, cn_buf);
677  }
678  }
679  }
680 
681  if (buf_parse(&in, ',', ip6_buf, buf_size) && strlen(ip6_buf) > 0)
682  {
683  struct in6_addr addr6;
684 
685  if (!get_ipv6_addr(ip6_buf, &addr6, NULL, M_WARN))
686  {
687  msg(M_WARN, "pool: invalid IPv6 (%s) for CN=%s", ip6_buf,
688  cn_buf);
689  }
690  else
691  {
692  h6 = ifconfig_pool_ipv6_base_to_handle(pool, &addr6);
693  if (h6 < 0)
694  {
695  msg(M_WARN,
696  "pool: IPv6 (%s) out of pool range for CN=%s",
697  ip6_buf, cn_buf);
698  }
699 
700  /* Rely on IPv6 if no IPv4 was provided or the one provided
701  * was not valid
702  */
703  if (h < 0)
704  {
705  h = h6;
706  }
707  }
708  }
709 
710  /* at the moment IPv4 and IPv6 share the same pool, therefore offsets
711  * have to match for the same client.
712  *
713  * If offsets differ we use the IPv4, therefore warn the user about this.
714  */
715  if ((h6 >= 0) && (h != h6))
716  {
717  msg(M_WARN,
718  "pool: IPv4 (%s) and IPv6 (%s) have different offsets! Relying on IPv4",
719  ip_buf, ip6_buf);
720  }
721 
722  /* if at least one among v4 and v6 was properly parsed, attempt
723  * setting an handle for this client
724  */
725  if (h >= 0)
726  {
727  msg(M_INFO, "succeeded -> ifconfig_pool_set(hand=%d)",h);
728  ifconfig_pool_set(pool, cn_buf, h, persist->fixed);
729  }
730  }
731 
733 
734  gc_free(&gc);
735  }
736 }
737 
738 void
739 ifconfig_pool_write(struct ifconfig_pool_persist *persist, const struct ifconfig_pool *pool)
740 {
741  if (persist && persist->file && (status_rw_flags(persist->file) & STATUS_OUTPUT_WRITE) && pool)
742  {
743  status_reset(persist->file);
744  ifconfig_pool_list(pool, persist->file);
745  status_flush(persist->file);
746  }
747 }
748 
749 /*
750  * TESTING ONLY
751  */
752 
753 #ifdef IFCONFIG_POOL_TEST
754 
755 #define DUP_CN
756 
757 void
758 ifconfig_pool_test(in_addr_t start, in_addr_t end)
759 {
760  struct gc_arena gc = gc_new();
761  struct ifconfig_pool *p = ifconfig_pool_init(IFCONFIG_POOL_30NET, start, end);
762  /*struct ifconfig_pool *p = ifconfig_pool_init (IFCONFIG_POOL_INDIV, start, end);*/
763  ifconfig_pool_handle array[256];
764  int i;
765 
766  CLEAR(array);
767 
768  msg(M_INFO | M_NOPREFIX, "************ 1");
769  for (i = 0; i < (int) SIZE(array); ++i)
770  {
771  char *cn;
773  in_addr_t local, remote;
774  char buf[256];
775  openvpn_snprintf(buf, sizeof(buf), "common-name-%d", i);
776 #ifdef DUP_CN
777  cn = NULL;
778 #else
779  cn = buf;
780 #endif
781  h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
782  if (h < 0)
783  {
784  break;
785  }
786  msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
787  print_in_addr_t(local, 0, &gc),
788  print_in_addr_t(remote, 0, &gc),
789  cn);
790  array[i] = h;
791 
792  }
793 
794  msg(M_INFO | M_NOPREFIX, "************* 2");
795  for (i = (int) SIZE(array) / 16; i < (int) SIZE(array) / 8; ++i)
796  {
797  msg(M_INFO, "Attempt to release %d cn=%s", array[i], p->list[i].common_name);
798  if (!ifconfig_pool_release(p, array[i]))
799  {
800  break;
801  }
802  msg(M_INFO, "Succeeded");
803  }
804 
805  CLEAR(array);
806 
807  msg(M_INFO | M_NOPREFIX, "**************** 3");
808  for (i = 0; i < (int) SIZE(array); ++i)
809  {
810  char *cn;
812  in_addr_t local, remote;
813  char buf[256];
814  snprintf(buf, sizeof(buf), "common-name-%d", i+24);
815 #ifdef DUP_CN
816  cn = NULL;
817 #else
818  cn = buf;
819 #endif
820  h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
821  if (h < 0)
822  {
823  break;
824  }
825  msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
826  print_in_addr_t(local, 0, &gc),
827  print_in_addr_t(remote, 0, &gc),
828  cn);
829  array[i] = h;
830 
831  }
832 
834  gc_free(&gc);
835 }
836 
837 #endif /* ifdef IFCONFIG_POOL_TEST */
838 
839 #endif /* if P2MP */
void ifconfig_pool_free(struct ifconfig_pool *pool)
Definition: pool.c:294
struct ifconfig_pool_persist * ifconfig_pool_persist_init(const char *filename, int refresh_freq)
Definition: pool.c:555
static void ifconfig_pool_entry_free(struct ifconfig_pool_entry *ipe, bool hard)
Definition: pool.c:43
bool ifconfig_pool_release(struct ifconfig_pool *pool, ifconfig_pool_handle hand, const bool hard)
Definition: pool.c:361
struct ifconfig_pool::@6 ipv4
#define M_NOPREFIX
Definition: error.h:102
static in_addr_t ifconfig_pool_handle_to_ip_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
Definition: pool.c:450
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:685
struct ifconfig_pool_entry * list
Definition: pool.h:64
#define STATUS_OUTPUT_WRITE
Definition: status.h:51
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, volatile int *signal_received)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition: socket.c:193
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:3021
#define M_INFO
Definition: errlevel.h:55
pool_type
Definition: pool.h:37
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1023
void ifconfig_pool_read(struct ifconfig_pool_persist *persist, struct ifconfig_pool *pool)
Definition: pool.c:602
bool fixed
Definition: pool.h:48
#define SIZE(x)
Definition: basic.h:30
#define in_addr_t
Definition: config-msvc.h:140
static unsigned int status_rw_flags(const struct status_output *so)
Definition: status.h:93
static ifconfig_pool_handle ifconfig_pool_ipv6_base_to_handle(const struct ifconfig_pool *pool, const struct in6_addr *in_addr)
Definition: pool.c:410
#define ASSERT(x)
Definition: error.h:221
static void ifconfig_pool_list(const struct ifconfig_pool *pool, struct status_output *out)
Definition: pool.c:504
#define snprintf
Definition: config-msvc.h:133
static void ifconfig_pool_msg(const struct ifconfig_pool *pool, int msglevel)
Definition: pool.c:541
void status_printf(struct status_output *so, const char *format,...)
Definition: status.c:224
bool ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
Definition: pool.c:125
void status_flush(struct status_output *so)
Definition: status.c:159
static ifconfig_pool_handle ifconfig_pool_ip_base_to_handle(const struct ifconfig_pool *pool, const in_addr_t addr)
Definition: pool.c:379
int ifconfig_pool_handle
Definition: pool.h:73
#define IFCONFIG_POOL_MAX
Definition: pool.h:34
void ifconfig_pool_persist_close(struct ifconfig_pool_persist *persist)
Definition: pool.c:576
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
Definition: status.c:63
in_addr_t base
Definition: pool.h:57
bool status_close(struct status_output *so)
Definition: status.c:190
#define CLEAR(x)
Definition: basic.h:33
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:296
void ifconfig_pool_write(struct ifconfig_pool_persist *persist, const struct ifconfig_pool *pool)
Definition: pool.c:739
static struct gc_arena gc_new(void)
Definition: buffer.h:1015
time_t now
Definition: otime.c:36
static void ifconfig_pool_set(struct ifconfig_pool *pool, const char *cn, ifconfig_pool_handle h, const bool fixed)
Definition: pool.c:492
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1050
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:3001
#define D_IFCONFIG_POOL
Definition: errlevel.h:84
bool duplicate_cn
Definition: pool.h:53
unsigned __int32 uint32_t
Definition: config-msvc.h:157
#define STATUS_OUTPUT_READ
Definition: status.h:50
bool status_trigger(struct status_output *so)
Definition: status.c:135
struct ifconfig_pool * ifconfig_pool_init(const bool ipv4_pool, enum pool_type type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits)
Definition: pool.c:150
#define msg
Definition: error.h:173
#define GETADDR_HOST_ORDER
Definition: socket.h:525
bool in_use
Definition: pool.h:45
char * common_name
Definition: pool.h:46
#define BLEN(buf)
Definition: buffer.h:127
static struct in6_addr ifconfig_pool_handle_to_ipv6_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
Definition: pool.c:479
struct status_output * file
Definition: pool.h:69
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
Definition: buffer.h:1066
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Definition: buffer.h:1072
ifconfig_pool_handle ifconfig_pool_acquire(struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
Definition: pool.c:310
struct ifconfig_pool::@7 ipv6
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition: buffer.c:862
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
#define M_FATAL
Definition: error.h:94
#define buf_init(buf, offset)
Definition: buffer.h:196
bool ifconfig_pool_write_trigger(struct ifconfig_pool_persist *persist)
Definition: pool.c:589
time_t last_release
Definition: pool.h:47
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:90
#define M_WARN
Definition: error.h:96
#define free
Definition: cmocka.c:1850
static int ifconfig_pool_find(struct ifconfig_pool *pool, const char *common_name)
Definition: pool.c:62
bool get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits, int msglevel)
Translate an IPv6 addr or hostname from string form to in6_addr.
Definition: socket.c:224
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
bool enabled
Definition: pool.h:55
#define BSTR(buf)
Definition: buffer.h:129
bool status_read(struct status_output *so, struct buffer *buf)
Definition: status.c:270
static void update_time(void)
Definition: otime.h:94
Definition: pool.h:43
int size
Definition: pool.h:63
void status_reset(struct status_output *so)
Definition: status.c:150
enum pool_type type
Definition: pool.h:56
struct in6_addr add_in6_addr(struct in6_addr base, uint32_t add)
Definition: socket.c:3043