Revert "Lease a single IPv6."

This reverts commit a3889c9053.
This commit is contained in:
Nikos Mavrogiannopoulos
2014-01-30 03:37:23 +01:00
parent ddfdd019c8
commit 040d552f5e
+176 -211
View File
@@ -27,94 +27,95 @@
#include <icmp-ping.h> #include <icmp-ping.h>
#include <arpa/inet.h> #include <arpa/inet.h>
static void bignum_add(uint8_t * num, unsigned size, unsigned step) static void bignum_add (uint8_t * num, unsigned size, unsigned step)
{ {
register int i; register int i;
register unsigned tmp, y; register unsigned tmp, y;
for (i = size - 1; i >= 0; i--) { for (i = size-1; i >= 0; i--)
tmp = num[i]; {
tmp = num[i];
num[i] += step;
if (num[i] < tmp)
y = 1;
else
y = 0;
num[i] += step; if (y == 0)
if (num[i] < tmp) break;
y = 1; }
else
y = 0;
if (y == 0)
break;
}
} }
void ip_lease_deinit(struct ip_lease_db_st *db)
void ip_lease_deinit(struct ip_lease_db_st* db)
{ {
struct ip_lease_st *cache; struct ip_lease_st * cache;
struct htable_iter iter; struct htable_iter iter;
cache = htable_first(&db->ht, &iter); cache = htable_first(&db->ht, &iter);
while (cache != NULL) { while(cache != NULL) {
free(cache); free(cache);
cache = htable_next(&db->ht, &iter); cache = htable_next(&db->ht, &iter);
} }
htable_clear(&db->ht); htable_clear(&db->ht);
return; return;
} }
static size_t rehash(const void *_e, void *unused) static size_t rehash(const void* _e, void* unused)
{ {
const struct ip_lease_st *e = _e; const struct ip_lease_st * e = _e;
return hash_any(&e->rip, e->rip_len, 0); return hash_any(&e->rip, e->rip_len, 0);
} }
void ip_lease_init(struct ip_lease_db_st *db) void ip_lease_init(struct ip_lease_db_st* db)
{ {
htable_init(&db->ht, rehash, NULL); htable_init(&db->ht, rehash, NULL);
} }
static bool ip_lease_cmp(const void *_c1, void *_c2) static bool ip_lease_cmp(const void* _c1, void* _c2)
{ {
const struct ip_lease_st *c1 = _c1; const struct ip_lease_st* c1 = _c1;
struct ip_lease_st *c2 = _c2; struct ip_lease_st* c2 = _c2;
if (c1->rip_len == c2->rip_len && if (c1->rip_len == c2->rip_len &&
ip_cmp(&c1->rip, &c2->rip, c2->rip_len) == 0) ip_cmp(&c1->rip, &c2->rip, c2->rip_len) == 0)
return 1; return 1;
return 0; return 0;
} }
static int ip_lease_exists(main_server_st * s, struct sockaddr_storage *ip, static int ip_lease_exists(main_server_st* s, struct sockaddr_storage* ip, size_t sockaddrlen)
size_t sockaddrlen)
{ {
struct ip_lease_st t; struct ip_lease_st t;
t.rip_len = sockaddrlen; t.rip_len = sockaddrlen;
memcpy(&t.rip, ip, sizeof(*ip)); memcpy(&t.rip, ip, sizeof(*ip));
if (htable_get(&s->ip_leases.ht, rehash(&t, NULL), ip_lease_cmp, &t) != if (htable_get(&s->ip_leases.ht, rehash(&t, NULL), ip_lease_cmp, &t) != 0)
0)
return 1; return 1;
return 0; return 0;
} }
#define MAX_IP_TRIES 16 #define MAX_IP_TRIES 16
static static
int get_ipv4_lease(main_server_st * s, struct proc_st *proc) int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
{ {
struct sockaddr_storage tmp, mask, network, rnd; struct sockaddr_storage tmp, mask, network, rnd;
unsigned i; unsigned i;
unsigned max_loops = MAX_IP_TRIES; unsigned max_loops = MAX_IP_TRIES;
int ret; int ret;
const char *c_network, *c_netmask; const char* c_network, *c_netmask;
char buf[64]; char buf[64];
if (proc->config.ipv4_network && proc->config.ipv4_netmask) { if (proc->config.ipv4_network && proc->config.ipv4_netmask) {
c_network = proc->config.ipv4_network; c_network = proc->config.ipv4_network;
c_netmask = proc->config.ipv4_netmask; c_netmask = proc->config.ipv4_netmask;
@@ -124,19 +125,19 @@ int get_ipv4_lease(main_server_st * s, struct proc_st *proc)
} }
if (c_network && c_netmask) { if (c_network && c_netmask) {
ret = inet_pton(AF_INET, c_network, SA_IN_P(&network)); ret =
inet_pton(AF_INET, c_network, SA_IN_P(&network));
if (ret != 1) { if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading IP: %s", mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
c_network);
return -1; return -1;
} }
ret = inet_pton(AF_INET, c_netmask, SA_IN_P(&mask)); ret =
inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
if (ret != 1) { if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading mask: %s", mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
c_netmask);
return -1; return -1;
} }
@@ -145,121 +146,96 @@ int get_ipv4_lease(main_server_st * s, struct proc_st *proc)
return ERR_MEM; return ERR_MEM;
/* mask the network (just in case it is wrong) */ /* mask the network (just in case it is wrong) */
for (i = 0; i < sizeof(struct in_addr); i++) for (i=0;i<sizeof(struct in_addr);i++)
SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]); SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]);
((struct sockaddr_in *)&network)->sin_family = AF_INET; ((struct sockaddr_in*)&network)->sin_family = AF_INET;
((struct sockaddr_in *)&network)->sin_port = 0; ((struct sockaddr_in*)&network)->sin_port = 0;
memcpy(&tmp, &network, sizeof(tmp)); memcpy(&tmp, &network, sizeof(tmp));
((struct sockaddr_in *)&tmp)->sin_family = AF_INET; ((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
((struct sockaddr_in *)&tmp)->sin_port = 0; ((struct sockaddr_in*)&tmp)->sin_port = 0;
memset(&rnd, 0, sizeof(rnd)); memset(&rnd, 0, sizeof(rnd));
((struct sockaddr_in *)&rnd)->sin_family = AF_INET; ((struct sockaddr_in*)&rnd)->sin_family = AF_INET;
((struct sockaddr_in *)&rnd)->sin_port = 0; ((struct sockaddr_in*)&rnd)->sin_port = 0;
do { do {
if (max_loops == 0) { if (max_loops == 0) {
mslog(s, proc, LOG_ERR, mslog(s, proc, LOG_ERR, "could not figure out a valid IPv4 IP.");
"could not figure out a valid IPv4 IP.");
ret = ERR_NO_IP; ret = ERR_NO_IP;
goto fail; goto fail;
} }
if (max_loops == MAX_IP_TRIES) { if (max_loops == MAX_IP_TRIES) {
if (proc->seeds_are_set) { if (proc->seeds_are_set) {
memcpy(SA_IN_U8_P(&rnd), memcpy(SA_IN_U8_P(&rnd), proc->ipv4_seed, 4);
proc->ipv4_seed, 4);
} else { } else {
uint32_t t = uint32_t t = hash_any(proc->username, strlen(proc->username), 0);
hash_any(proc->username,
strlen(proc->username), 0);
memcpy(SA_IN_U8_P(&rnd), &t, 4); memcpy(SA_IN_U8_P(&rnd), &t, 4);
} }
} else } else
gnutls_rnd(GNUTLS_RND_NONCE, SA_IN_U8_P(&rnd), gnutls_rnd(GNUTLS_RND_NONCE, SA_IN_U8_P(&rnd), sizeof(struct in_addr));
sizeof(struct in_addr));
max_loops--; max_loops--;
if (SA_IN_U8_P(&rnd)[3] == 255) /* broadcast */ if (SA_IN_U8_P(&rnd)[3] == 255) /* broadcast */
bignum_add(SA_IN_U8_P(&rnd), bignum_add(SA_IN_U8_P(&rnd), sizeof(struct in_addr), 1);
sizeof(struct in_addr), 1);
/* Mask the random number with the netmask */ /* Mask the random number with the netmask */
for (i = 0; i < sizeof(struct in_addr); i++) { for (i=0;i<sizeof(struct in_addr);i++) {
SA_IN_U8_P(&rnd)[i] &= ~(SA_IN_U8_P(&mask)[i]); SA_IN_U8_P(&rnd)[i] &= ~(SA_IN_U8_P(&mask)[i]);
} }
SA_IN_U8_P(&rnd)[sizeof(struct in_addr) - 1] &= 0xFE; SA_IN_U8_P(&rnd)[sizeof(struct in_addr)-1] &= 0xFE;
/* Now add the IP to the masked random number */ /* Now add the IP to the masked random number */
for (i = 0; i < sizeof(struct in_addr); i++) for (i=0;i<sizeof(struct in_addr);i++)
SA_IN_U8_P(&rnd)[i] |= SA_IN_U8_P(&rnd)[i] |= (SA_IN_U8_P(&network)[i]);
(SA_IN_U8_P(&network)[i]);
/* check if it exists in the hash table */ /* check if it exists in the hash table */
if (ip_lease_exists(s, &rnd, sizeof(struct sockaddr_in)) if (ip_lease_exists(s, &rnd, sizeof(struct sockaddr_in)) != 0) {
!= 0) { mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s to '%s'; it is in use.",
mslog(s, proc, LOG_DEBUG, human_addr((void*)&rnd, sizeof(struct sockaddr_in), buf, sizeof(buf)),
"cannot assign remote IP %s to '%s'; it is in use.",
human_addr((void *)&rnd,
sizeof(struct sockaddr_in),
buf, sizeof(buf)),
proc->username); proc->username);
continue; continue;
} }
memcpy(&proc->ipv4->lip, &rnd, memcpy(&proc->ipv4->lip, &rnd, sizeof(struct sockaddr_in));
sizeof(struct sockaddr_in)); proc->ipv4->lip_len = sizeof(struct sockaddr_in);
proc->ipv4->lip_len = sizeof(struct sockaddr_in);
/* RIP = LIP + 1 */ /* RIP = LIP + 1 */
memcpy(&tmp, &proc->ipv4->lip, memcpy(&tmp, &proc->ipv4->lip, sizeof(struct sockaddr_in));
sizeof(struct sockaddr_in)); bignum_add(SA_IN_U8_P(&tmp), sizeof(struct in_addr), 1);
bignum_add(SA_IN_U8_P(&tmp), sizeof(struct in_addr), 1);
/* check if it exists in the hash table */ /* check if it exists in the hash table */
if (ip_lease_exists(s, &tmp, sizeof(struct sockaddr_in)) if (ip_lease_exists(s, &tmp, sizeof(struct sockaddr_in)) != 0) {
!= 0) { mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s to '%s'; it is in use.",
mslog(s, proc, LOG_DEBUG, human_addr((void*)&tmp, sizeof(struct sockaddr_in), buf, sizeof(buf)),
"cannot assign remote IP %s to '%s'; it is in use.",
human_addr((void *)&tmp,
sizeof(struct sockaddr_in),
buf, sizeof(buf)),
proc->username); proc->username);
continue; continue;
} }
memcpy(&proc->ipv4->rip, &tmp, memcpy(&proc->ipv4->rip, &tmp, sizeof(struct sockaddr_in));
sizeof(struct sockaddr_in)); proc->ipv4->rip_len = sizeof(struct sockaddr_in);
proc->ipv4->rip_len = sizeof(struct sockaddr_in);
/* mask the last IP with the netmask */ /* mask the last IP with the netmask */
for (i = 0; i < sizeof(struct in_addr); i++) for (i=0;i<sizeof(struct in_addr);i++)
SA_IN_U8_P(&tmp)[i] &= (SA_IN_U8_P(&mask)[i]); SA_IN_U8_P(&tmp)[i] &= (SA_IN_U8_P(&mask)[i]);
/* the result should match the network */ /* the result should match the network */
if (memcmp if (memcmp(SA_IN_U8_P(&network), SA_IN_U8_P(&tmp), sizeof(struct in_addr)) != 0) {
(SA_IN_U8_P(&network), SA_IN_U8_P(&tmp), continue;
sizeof(struct in_addr)) != 0) { }
continue;
}
mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", proc->username,
proc->username, human_addr((void*)&proc->ipv4->lip, proc->ipv4->lip_len, buf, sizeof(buf)));
human_addr((void *)&proc->ipv4->lip,
proc->ipv4->lip_len, buf, if (icmp_ping4(s, (void*)&proc->ipv4->lip, (void*)&proc->ipv4->rip) == 0)
sizeof(buf))); break;
} while(1);
if (icmp_ping4
(s, (void *)&proc->ipv4->lip,
(void *)&proc->ipv4->rip) == 0)
break;
} while (1);
} }
return 0; return 0;
fail: fail:
free(proc->ipv4); free(proc->ipv4);
proc->ipv4 = NULL; proc->ipv4 = NULL;
@@ -267,13 +243,13 @@ int get_ipv4_lease(main_server_st * s, struct proc_st *proc)
} }
static static
int get_ipv6_lease(main_server_st * s, struct proc_st *proc) int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
{ {
struct sockaddr_storage tmp, mask, network, rnd; struct sockaddr_storage tmp, mask, network, rnd;
unsigned i, max_loops = MAX_IP_TRIES; unsigned i, max_loops = MAX_IP_TRIES;
int ret; int ret;
const char *c_network, *c_netmask; const char* c_network, *c_netmask;
char buf[64]; char buf[64];
if (proc->config.ipv6_network && proc->config.ipv6_netmask) { if (proc->config.ipv6_network && proc->config.ipv6_netmask) {
@@ -285,112 +261,114 @@ int get_ipv6_lease(main_server_st * s, struct proc_st *proc)
} }
if (c_network && c_netmask) { if (c_network && c_netmask) {
ret = inet_pton(AF_INET6, c_network, SA_IN6_P(&network)); ret =
inet_pton(AF_INET6, c_network, SA_IN6_P(&network));
if (ret != 1) { if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading IP: %s", mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
c_network);
return -1; return -1;
} }
ret = inet_pton(AF_INET6, c_netmask, SA_IN6_P(&mask)); ret =
inet_pton(AF_INET6, c_netmask, SA_IN6_P(&mask));
if (ret != 1) { if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading mask: %s", mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
c_netmask);
return -1; return -1;
} }
proc->ipv6 = calloc(1, sizeof(*proc->ipv6)); proc->ipv6 = calloc(1, sizeof(*proc->ipv6));
if (proc->ipv6 == NULL) if (proc->ipv6 == NULL)
return ERR_MEM; return ERR_MEM;
/* mask the network */ /* mask the network */
for (i = 0; i < sizeof(struct in6_addr); i++) for (i=0;i<sizeof(struct in6_addr);i++)
SA_IN6_U8_P(&network)[i] &= (SA_IN6_U8_P(&mask)[i]); SA_IN6_U8_P(&network)[i] &= (SA_IN6_U8_P(&mask)[i]);
((struct sockaddr_in6 *)&network)->sin6_family = AF_INET6; ((struct sockaddr_in6*)&network)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&network)->sin6_port = 0; ((struct sockaddr_in6*)&network)->sin6_port = 0;
memcpy(&tmp, &network, sizeof(tmp)); memcpy(&tmp, &network, sizeof(tmp));
((struct sockaddr_in6 *)&tmp)->sin6_family = AF_INET6; ((struct sockaddr_in6*)&tmp)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&tmp)->sin6_port = 0; ((struct sockaddr_in6*)&tmp)->sin6_port = 0;
((struct sockaddr_in6 *)&rnd)->sin6_family = AF_INET6; ((struct sockaddr_in6*)&rnd)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&rnd)->sin6_port = 0; ((struct sockaddr_in6*)&rnd)->sin6_port = 0;
do { do {
if (max_loops == 0) { if (max_loops == 0) {
mslog(s, NULL, LOG_ERR, mslog(s, NULL, LOG_ERR, "could not figure out a valid IPv6 IP.");
"could not figure out a valid IPv6 IP.");
ret = ERR_NO_IP; ret = ERR_NO_IP;
goto fail; goto fail;
} }
if (max_loops == MAX_IP_TRIES) { if (max_loops == MAX_IP_TRIES) {
memset(SA_IN6_U8_P(&rnd), 0, memset(SA_IN6_U8_P(&rnd), 0, sizeof(struct in6_addr));
sizeof(struct in6_addr));
if (proc->seeds_are_set) { if (proc->seeds_are_set) {
memcpy(SA_IN6_U8_P(&rnd) + memcpy(SA_IN6_U8_P(&rnd)+sizeof(struct in6_addr)-5, proc->ipv4_seed, 4);
sizeof(struct in6_addr) - 5,
proc->ipv4_seed, 4);
} else { } else {
uint32_t t = uint32_t t = hash_any(proc->username, strlen(proc->username), 0);
hash_any(proc->username, memcpy(SA_IN6_U8_P(&rnd)+sizeof(struct in6_addr)-5, &t, 4);
strlen(proc->username), 0);
memcpy(SA_IN6_U8_P(&rnd) +
sizeof(struct in6_addr) - 5, &t,
4);
} }
} else } else
gnutls_rnd(GNUTLS_RND_NONCE, SA_IN6_U8_P(&rnd), gnutls_rnd(GNUTLS_RND_NONCE, SA_IN6_U8_P(&rnd), sizeof(struct in6_addr));
sizeof(struct in6_addr));
max_loops--; max_loops--;
/* Mask the random number with the netmask */ /* Mask the random number with the netmask */
for (i = 0; i < sizeof(struct in6_addr); i++) for (i=0;i<sizeof(struct in6_addr);i++)
SA_IN6_U8_P(&rnd)[i] &= SA_IN6_U8_P(&rnd)[i] &= ~(SA_IN6_U8_P(&mask)[i]);
~(SA_IN6_U8_P(&mask)[i]);
SA_IN6_U8_P(&rnd)[sizeof(struct in6_addr) - 1] &= 0xFE; SA_IN6_U8_P(&rnd)[sizeof(struct in6_addr)-1] &= 0xFE;
/* Now add the network to the masked random number */ /* Now add the network to the masked random number */
for (i = 0; i < sizeof(struct in6_addr); i++) for (i=0;i<sizeof(struct in6_addr);i++)
SA_IN6_U8_P(&rnd)[i] |= SA_IN6_U8_P(&rnd)[i] |= (SA_IN6_U8_P(&network)[i]);
(SA_IN6_U8_P(&network)[i]);
/* check if it exists in the hash table */
/* check if it exists in the hash table */ if (ip_lease_exists(s, &rnd, sizeof(struct sockaddr_in6)) != 0) {
if (ip_lease_exists mslog(s, proc, LOG_DEBUG, "cannot assign local IP %s to '%s'; it is in use.",
(s, &rnd, sizeof(struct sockaddr_in6)) != 0) { human_addr((void*)&rnd, sizeof(struct sockaddr_in6), buf, sizeof(buf)),
mslog(s, proc, LOG_DEBUG,
"cannot assign local IP %s to '%s'; it is in use.",
human_addr((void *)&rnd,
sizeof(struct sockaddr_in6),
buf, sizeof(buf)),
proc->username); proc->username);
continue; continue;
} }
proc->ipv6->lip_len = sizeof(struct sockaddr_in6); proc->ipv6->lip_len = sizeof(struct sockaddr_in6);
memcpy(&proc->ipv6->lip, &rnd, proc->ipv6->lip_len); memcpy(&proc->ipv6->lip, &rnd, proc->ipv6->lip_len);
/* RIP = LIP in IPv6 */ /* RIP = LIP + 1 */
memcpy(&proc->ipv6->rip, &proc->ipv6->lip, memcpy(&tmp, &proc->ipv6->lip, sizeof(tmp));
sizeof(proc->ipv6->lip)); proc->ipv6->rip_len = proc->ipv6->lip_len;
proc->ipv6->rip_len = proc->ipv6->lip_len;
mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", bignum_add(SA_IN6_U8_P(&tmp), sizeof(struct in6_addr), 1);
proc->username,
human_addr((void *)&proc->ipv6->lip,
proc->ipv6->lip_len, buf,
sizeof(buf)));
if (icmp_ping6(s, (void *)&proc->ipv6->lip) == 0) /* check if it exists in the hash table */
break; if (ip_lease_exists(s, &tmp, sizeof(struct sockaddr_in6)) != 0) {
} while (1); mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s to '%s'; it is in use.",
human_addr((void*)&tmp, sizeof(struct sockaddr_in6), buf, sizeof(buf)),
proc->username);
continue;
}
memcpy(&proc->ipv6->rip, &tmp, proc->ipv6->rip_len);
/* mask the last IP with the netmask */
for (i=0;i<sizeof(struct in6_addr);i++)
SA_IN6_U8_P(&tmp)[i] &= (SA_IN6_U8_P(&mask)[i]);
/* the result should match the network */
if (memcmp(SA_IN6_U8_P(&network), SA_IN6_U8_P(&tmp), sizeof(struct in6_addr)) != 0) {
continue;
}
mslog(s, proc, LOG_DEBUG, "selected IP for '%s': %s", proc->username,
human_addr((void*)&proc->ipv6->lip, proc->ipv6->lip_len, buf, sizeof(buf)));
if (icmp_ping6(s, (void*)&proc->ipv6->lip, (void*)&proc->ipv6->rip) == 0)
break;
} while(1);
} }
return 0; return 0;
fail: fail:
free(proc->ipv6); free(proc->ipv6);
proc->ipv6 = NULL; proc->ipv6 = NULL;
@@ -398,10 +376,10 @@ int get_ipv6_lease(main_server_st * s, struct proc_st *proc)
} }
int get_ip_leases(main_server_st * s, struct proc_st *proc) int get_ip_leases(main_server_st* s, struct proc_st* proc)
{ {
int ret; int ret;
char buf[128]; char buf[128];
if (proc->ipv4 == NULL) { if (proc->ipv4 == NULL) {
ret = get_ipv4_lease(s, proc); ret = get_ipv4_lease(s, proc);
@@ -409,11 +387,8 @@ int get_ip_leases(main_server_st * s, struct proc_st *proc)
return ret; return ret;
if (proc->ipv4) { if (proc->ipv4) {
if (htable_add if (htable_add(&s->ip_leases.ht, rehash(proc->ipv4, NULL), proc->ipv4) == 0) {
(&s->ip_leases.ht, rehash(proc->ipv4, NULL), mslog(s, proc, LOG_ERR, "could not add IPv4 lease to hash table.");
proc->ipv4) == 0) {
mslog(s, proc, LOG_ERR,
"could not add IPv4 lease to hash table.");
return -1; return -1;
} }
} }
@@ -425,48 +400,38 @@ int get_ip_leases(main_server_st * s, struct proc_st *proc)
return ret; return ret;
if (proc->ipv6) { if (proc->ipv6) {
if (htable_add if (htable_add(&s->ip_leases.ht, rehash(proc->ipv6, NULL), proc->ipv6) == 0) {
(&s->ip_leases.ht, rehash(proc->ipv6, NULL), mslog(s, proc, LOG_ERR, "could not add IPv6 lease to hash table.");
proc->ipv6) == 0) {
mslog(s, proc, LOG_ERR,
"could not add IPv6 lease to hash table.");
return -1; return -1;
} }
} }
} }
if (proc->ipv4 == 0 && proc->ipv6 == 0) { if (proc->ipv4 == 0 && proc->ipv6 == 0) {
mslog(s, proc, LOG_ERR, mslog(s, proc, LOG_ERR, "no IPv4 or IPv6 addresses are configured. Cannot obtain lease.");
"no IPv4 or IPv6 addresses are configured. Cannot obtain lease.");
return -1; return -1;
} }
if (proc->ipv4) if (proc->ipv4)
mslog(s, proc, LOG_INFO, "assigned IPv4 to '%s': %s", mslog(s, proc, LOG_INFO, "assigned IPv4 to '%s': %s", proc->username,
proc->username, human_addr((void *)&proc->ipv4->rip, human_addr((void*)&proc->ipv4->rip, proc->ipv4->rip_len, buf, sizeof(buf)));
proc->ipv4->rip_len, buf,
sizeof(buf)));
if (proc->ipv6) if (proc->ipv6)
mslog(s, proc, LOG_INFO, "assigned IPv6 to '%s': %s", mslog(s, proc, LOG_INFO, "assigned IPv6 to '%s': %s", proc->username,
proc->username, human_addr((void *)&proc->ipv6->rip, human_addr((void*)&proc->ipv6->rip, proc->ipv6->rip_len, buf, sizeof(buf)));
proc->ipv6->rip_len, buf,
sizeof(buf)));
return 0; return 0;
} }
void remove_ip_leases(main_server_st * s, struct proc_st *proc) void remove_ip_leases(main_server_st* s, struct proc_st* proc)
{ {
if (proc->ipv4) { if (proc->ipv4) {
htable_del(&s->ip_leases.ht, rehash(proc->ipv4, NULL), htable_del(&s->ip_leases.ht, rehash(proc->ipv4, NULL), proc->ipv4);
proc->ipv4);
free(proc->ipv4); free(proc->ipv4);
proc->ipv4 = NULL; proc->ipv4 = NULL;
} }
if (proc->ipv6) { if (proc->ipv6) {
htable_del(&s->ip_leases.ht, rehash(proc->ipv6, NULL), htable_del(&s->ip_leases.ht, rehash(proc->ipv6, NULL), proc->ipv6);
proc->ipv6);
free(proc->ipv6); free(proc->ipv6);
proc->ipv6 = NULL; proc->ipv6 = NULL;
} }