60 time_t earliest_release = 0;
61 int previous_usage = -1;
64 for (i = 0; i < pool->
size; ++i)
92 if (previous_usage < 0 && common_name && ipe->
common_name
100 if (previous_usage >= 0)
102 return previous_usage;
124 msg(msglevel,
"--ifconfig-pool start IP [%s] is greater than end IP [%s]",
131 "--ifconfig-pool address range is too large [%s -> %s]. Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.",
141 const bool duplicate_cn,
const bool ipv6_pool,
const struct in6_addr ipv6_base,
142 const int ipv6_netbits)
146 int pool_ipv4_size = -1, pool_ipv6_size = -1;
162 pool_ipv4_size = (((end | 3) + 1) - pool->
ipv4.
base) >> 2;
167 pool_ipv4_size = end - start + 1;
174 if (pool_ipv4_size < 2)
176 msg(
M_FATAL,
"IPv4 pool size is too small (%d), must be at least 2", pool_ipv4_size);
182 pool->
size = pool_ipv4_size;
194 uint32_t
base = (ipv6_base.s6_addr[12] << 24) | (ipv6_base.s6_addr[13] << 16)
195 | (ipv6_base.s6_addr[14] << 8) | ipv6_base.s6_addr[15];
199 if ((128 - ipv6_netbits) < 32)
208 uint32_t mask = (1 << (128 - ipv6_netbits)) - 1;
226 "to avoid ::0 assignment");
234 if (pool_ipv6_size < 2)
236 msg(
M_FATAL,
"IPv6 pool size is too small (%d), must be at least 2", pool_ipv6_size);
245 if (pool->
size <= 0 || pool_ipv6_size < pool->
size)
247 pool->
size = pool_ipv6_size;
253 if (pool_ipv4_size < pool_ipv6_size)
256 "NOTE: IPv4 pool size is %d, IPv6 pool size is %d. "
257 "IPv4 pool size limits the number of clients that can be "
258 "served from the pool",
259 pool_ipv4_size, pool_ipv6_size);
261 else if (pool_ipv4_size > pool_ipv6_size)
264 "WARNING: IPv4 pool size is %d, IPv6 pool size is %d. "
265 "IPv6 pool size limits the number of clients that can be "
266 "served from the pool. This is likely a MISTAKE - please check "
267 "your configuration",
268 pool_ipv4_size, pool_ipv6_size);
287 for (i = 0; i < pool->
size; ++i)
298 struct in6_addr *remote_ipv6,
const char *common_name)
353 if (pool && hand >= 0 && hand < pool->size)
375 ret = (addr - pool->
ipv4.
base) >> 2;
389 if (ret < 0 || ret >= pool->
size)
409 for (
int i = 0; i < (12); i++)
411 if (pool->
ipv6.
base.s6_addr[i] != in_addr->s6_addr[i])
417 base = (pool->
ipv6.
base.s6_addr[12] << 24) | (pool->
ipv6.
base.s6_addr[13] << 16)
420 addr = (in_addr->s6_addr[12] << 24) | (in_addr->s6_addr[13] << 16) | (in_addr->s6_addr[14] << 8)
421 | in_addr->s6_addr[15];
424 if (ret < 0 || ret >= pool->
size)
437 if (pool->
ipv4.
enabled && hand >= 0 && hand < pool->size)
443 ret = pool->
ipv4.
base + (hand << 2);
461static struct in6_addr
464 struct in6_addr ret = IN6ADDR_ANY_INIT;
467 if (pool->ipv6.enabled && hand >= 0 && hand < pool->size)
494 for (i = 0; i < pool->
size; ++i)
499 const char *ip6_str =
"";
500 const char *ip_str =
"";
545 if (refresh_freq > 0)
588 const int buf_size = 128;
592 if (persist && persist->
file && pool)
596 char *cn_buf, *ip_buf, *ip6_buf;
615 if (c ==
'#' || c ==
';')
639 if (strlen(ip_buf) > 0)
646 msg(
M_WARN,
"pool: invalid IPv4 (%s) for CN=%s", ip_buf, cn_buf);
653 msg(
M_WARN,
"pool: IPv4 (%s) out of pool range for CN=%s", ip_buf, cn_buf);
658 if (
buf_parse(&in,
',', ip6_buf, buf_size) && strlen(ip6_buf) > 0)
660 struct in6_addr addr6;
664 msg(
M_WARN,
"pool: invalid IPv6 (%s) for CN=%s", ip6_buf, cn_buf);
671 msg(
M_WARN,
"pool: IPv6 (%s) out of pool range for CN=%s", ip6_buf, cn_buf);
689 if ((h6 >= 0) && (h != h6))
691 msg(
M_WARN,
"pool: IPv4 (%s) and IPv6 (%s) have different offsets! Relying on IPv4",
700 msg(
M_INFO,
"succeeded -> ifconfig_pool_set(hand=%d)", h);
726#ifdef IFCONFIG_POOL_TEST
742 for (i = 0; i < (int)
SIZE(array); ++i)
748 snprintf(buf,
sizeof(buf),
"common-name-%d", i);
765 for (i = (
int)
SIZE(array) / 16; i < (int)
SIZE(array) / 8; ++i)
778 for (i = 0; i < (int)
SIZE(array); ++i)
784 snprintf(buf,
sizeof(buf),
"common-name-%d", i + 24);
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Extract the next token from a buffer, delimited by a given character.
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
Buffer management functions and garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
Allocate and zero-initialise an array of n elements of the given type.
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Allocate and zero-initialise a garbage-collected array of n elements.
#define BLEN(buf)
Return the length of the buffer content in bytes.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
#define ALLOC_OBJ_CLEAR(dptr, type)
Allocate and zero-initialise memory for a single object of the given type.
#define buf_init(buf, offset)
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
static void update_time(void)
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)
static void ifconfig_pool_list(const struct ifconfig_pool *pool, struct status_output *out)
static void ifconfig_pool_entry_free(struct ifconfig_pool_entry *ipe, bool hard)
static in_addr_t ifconfig_pool_handle_to_ip_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
static ifconfig_pool_handle ifconfig_pool_ip_base_to_handle(const struct ifconfig_pool *pool, const in_addr_t addr)
static ifconfig_pool_handle ifconfig_pool_ipv6_base_to_handle(const struct ifconfig_pool *pool, const struct in6_addr *in_addr)
bool ifconfig_pool_release(struct ifconfig_pool *pool, ifconfig_pool_handle hand, const bool hard)
struct ifconfig_pool_persist * ifconfig_pool_persist_init(const char *filename, int refresh_freq)
void ifconfig_pool_write(struct ifconfig_pool_persist *persist, const struct ifconfig_pool *pool)
static void ifconfig_pool_set(struct ifconfig_pool *pool, const char *cn, ifconfig_pool_handle h, const bool fixed)
void ifconfig_pool_persist_close(struct ifconfig_pool_persist *persist)
bool ifconfig_pool_write_trigger(struct ifconfig_pool_persist *persist)
bool ifconfig_pool_verify_range(const msglvl_t msglevel, const in_addr_t start, const in_addr_t end)
static int ifconfig_pool_find(struct ifconfig_pool *pool, const char *common_name)
void ifconfig_pool_free(struct ifconfig_pool *pool)
static void ifconfig_pool_msg(const struct ifconfig_pool *pool, int msglevel)
void ifconfig_pool_read(struct ifconfig_pool_persist *persist, struct ifconfig_pool *pool)
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)
static struct in6_addr ifconfig_pool_handle_to_ipv6_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
#define IFCONFIG_POOL_MAX
bool get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits, msglvl_t msglevel)
Translate an IPv6 addr or hostname from string form to in6_addr.
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
struct in6_addr add_in6_addr(struct in6_addr base, uint32_t add)
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
#define GETADDR_HOST_ORDER
bool status_trigger(struct status_output *so)
void status_printf(struct status_output *so, const char *format,...)
bool status_read(struct status_output *so, struct buffer *buf)
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
void status_flush(struct status_output *so)
void status_reset(struct status_output *so)
bool status_close(struct status_output *so)
static unsigned int status_rw_flags(const struct status_output *so)
#define STATUS_OUTPUT_WRITE
#define STATUS_OUTPUT_READ
Wrapper structure for dynamically allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
struct status_output * file
struct ifconfig_pool_entry * list
struct ifconfig_pool::@102204320242243241112225236071133341336301303254 ipv6
struct ifconfig_pool::@054126071253267302350043225374133241003025132045 ipv4