Compare commits
5 Commits
18dbc899ff
...
94efaa3181
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | 94efaa3181 | |
Zbigniew Jędrzejewski-Szmek | c9fecf18b9 | |
Chris Down | 45ba6a5853 | |
Beniamino Galvani | c43eea9f2e | |
Beniamino Galvani | af710b535b |
|
@ -128,7 +128,7 @@
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry valign="top" morerows="7">Container</entry>
|
<entry valign="top" morerows="8">Container</entry>
|
||||||
<entry><varname>openvz</varname></entry>
|
<entry><varname>openvz</varname></entry>
|
||||||
<entry>OpenVZ/Virtuozzo</entry>
|
<entry>OpenVZ/Virtuozzo</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
|
@ -966,6 +966,7 @@ int transaction_add_job_and_dependencies(
|
||||||
* Given building up the transaction is a synchronous operation, attempt
|
* Given building up the transaction is a synchronous operation, attempt
|
||||||
* to load the unit immediately. */
|
* to load the unit immediately. */
|
||||||
if (r < 0 && manager_unit_file_maybe_loadable_from_cache(unit)) {
|
if (r < 0 && manager_unit_file_maybe_loadable_from_cache(unit)) {
|
||||||
|
sd_bus_error_free(e);
|
||||||
unit->load_state = UNIT_STUB;
|
unit->load_state = UNIT_STUB;
|
||||||
r = unit_load(unit);
|
r = unit_load(unit);
|
||||||
if (r < 0 || unit->load_state == UNIT_STUB)
|
if (r < 0 || unit->load_state == UNIT_STUB)
|
||||||
|
|
|
@ -109,8 +109,9 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
||||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||||
struct in6_addr **addrs, size_t count,
|
struct in6_addr **addrs, size_t count,
|
||||||
size_t *allocated);
|
size_t *allocated);
|
||||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
|
||||||
char ***str_arr);
|
char ***str_arr);
|
||||||
|
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);
|
||||||
|
|
||||||
int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
|
int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
|
||||||
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct sd_dhcp6_lease {
|
||||||
size_t ntp_allocated;
|
size_t ntp_allocated;
|
||||||
char **ntp_fqdn;
|
char **ntp_fqdn;
|
||||||
size_t ntp_fqdn_count;
|
size_t ntp_fqdn_count;
|
||||||
|
char *fqdn;
|
||||||
};
|
};
|
||||||
|
|
||||||
int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
|
int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
|
||||||
|
@ -57,5 +58,6 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
|
||||||
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
|
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
|
||||||
int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval,
|
int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval,
|
||||||
size_t optlen) ;
|
size_t optlen) ;
|
||||||
|
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
|
|
||||||
int dhcp6_lease_new(sd_dhcp6_lease **ret);
|
int dhcp6_lease_new(sd_dhcp6_lease **ret);
|
||||||
|
|
|
@ -642,36 +642,40 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
|
static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain) {
|
||||||
size_t pos = 0, idx = 0;
|
|
||||||
_cleanup_strv_free_ char **names = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert_return(optlen > 1, -ENODATA);
|
|
||||||
assert_return(optval[optlen - 1] == '\0', -EINVAL);
|
|
||||||
|
|
||||||
while (pos < optlen) {
|
|
||||||
_cleanup_free_ char *ret = NULL;
|
_cleanup_free_ char *ret = NULL;
|
||||||
size_t n = 0, allocated = 0;
|
size_t n = 0, allocated = 0;
|
||||||
|
const uint8_t *optval = *data;
|
||||||
|
uint16_t optlen = *len;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (optlen <= 1)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const char *label;
|
const char *label;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
c = optval[pos++];
|
if (optlen == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
c = *optval;
|
||||||
|
optval++;
|
||||||
|
optlen--;
|
||||||
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
/* End of name */
|
/* End label */
|
||||||
break;
|
break;
|
||||||
if (c > 63)
|
if (c > 63)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
if (c > optlen)
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
/* Literal label */
|
/* Literal label */
|
||||||
label = (const char *)&optval[pos];
|
label = (const char *)optval;
|
||||||
pos += c;
|
optval += c;
|
||||||
if (pos >= optlen)
|
optlen -= c;
|
||||||
return -EMSGSIZE;
|
|
||||||
|
|
||||||
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -688,13 +692,53 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
|
||||||
n += r;
|
n += r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0)
|
if (n) {
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!GREEDY_REALLOC(ret, allocated, n + 1))
|
if (!GREEDY_REALLOC(ret, allocated, n + 1))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret[n] = 0;
|
ret[n] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_domain = TAKE_PTR(ret);
|
||||||
|
*data = optval;
|
||||||
|
*len = optlen;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str) {
|
||||||
|
_cleanup_free_ char *domain = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = parse_domain(&optval, &optlen, &domain);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
return -ENODATA;
|
||||||
|
if (optlen != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*str = TAKE_PTR(domain);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
|
||||||
|
size_t idx = 0;
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (optlen <= 1)
|
||||||
|
return -ENODATA;
|
||||||
|
if (optval[optlen - 1] != '\0')
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (optlen > 0) {
|
||||||
|
_cleanup_free_ char *ret = NULL;
|
||||||
|
|
||||||
|
r = parse_domain(&optval, &optlen, &ret);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
r = strv_extend(&names, ret);
|
r = strv_extend(&names, ret);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -1282,6 +1282,13 @@ static int client_parse_message(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP6_OPTION_FQDN:
|
||||||
|
r = dhcp6_lease_set_fqdn(lease, optval, optlen);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
|
case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
|
||||||
if (optlen != 4)
|
if (optlen != 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -236,7 +236,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
|
||||||
if (!optlen)
|
if (!optlen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = dhcp6_option_parse_domainname(optval, optlen, &domains);
|
r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCP6_NTP_SUBOPTION_SRV_FQDN:
|
case DHCP6_NTP_SUBOPTION_SRV_FQDN:
|
||||||
r = dhcp6_option_parse_domainname(subval, sublen,
|
r = dhcp6_option_parse_domainname_list(subval, sublen,
|
||||||
&servers);
|
&servers);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -365,6 +365,38 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval,
|
||||||
|
size_t optlen) {
|
||||||
|
int r;
|
||||||
|
char *fqdn;
|
||||||
|
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
assert_return(optval, -EINVAL);
|
||||||
|
|
||||||
|
if (optlen < 2)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
/* Ignore the flags field, it doesn't carry any useful
|
||||||
|
information for clients. */
|
||||||
|
r = dhcp6_option_parse_domainname(optval + 1, optlen - 1, &fqdn);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return free_and_replace(lease->fqdn, fqdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn) {
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
assert_return(fqdn, -EINVAL);
|
||||||
|
|
||||||
|
if (lease->fqdn) {
|
||||||
|
*fqdn = lease->fqdn;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
||||||
assert(lease);
|
assert(lease);
|
||||||
|
|
||||||
|
@ -373,6 +405,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
||||||
dhcp6_lease_free_ia(&lease->pd);
|
dhcp6_lease_free_ia(&lease->pd);
|
||||||
|
|
||||||
free(lease->dns);
|
free(lease->dns);
|
||||||
|
free(lease->fqdn);
|
||||||
|
|
||||||
lease->domains = strv_free(lease->domains);
|
lease->domains = strv_free(lease->domains);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
#include "virt.h"
|
#include "virt.h"
|
||||||
|
@ -106,6 +108,52 @@ static int test_client_basic(sd_event *e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_parse_domain(sd_event *e) {
|
||||||
|
uint8_t *data;
|
||||||
|
char *domain;
|
||||||
|
char **list;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
log_debug("/* %s */", __func__);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0 };
|
||||||
|
r = dhcp6_option_parse_domainname(data, 13, &domain);
|
||||||
|
assert_se(r == 0);
|
||||||
|
assert_se(domain);
|
||||||
|
assert_se(streq(domain, "example.com"));
|
||||||
|
free(domain);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 4, 't', 'e', 's', 't' };
|
||||||
|
r = dhcp6_option_parse_domainname(data, 5, &domain);
|
||||||
|
assert_se(r == 0);
|
||||||
|
assert_se(domain);
|
||||||
|
assert_se(streq(domain, "test"));
|
||||||
|
free(domain);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 0 };
|
||||||
|
r = dhcp6_option_parse_domainname(data, 1, &domain);
|
||||||
|
assert_se(r < 0);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'c', 'o', 'm', 0,
|
||||||
|
6, 'f', 'o', 'o', 'b', 'a', 'r', 0 };
|
||||||
|
r = dhcp6_option_parse_domainname_list(data, 21, &list);
|
||||||
|
assert_se(r == 2);
|
||||||
|
assert_se(list);
|
||||||
|
assert_se(streq(list[0], "example.com"));
|
||||||
|
assert_se(streq(list[1], "foobar"));
|
||||||
|
strv_free(list);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 1, 'a', 0, 20, 'b', 'c' };
|
||||||
|
r = dhcp6_option_parse_domainname_list(data, 6, &list);
|
||||||
|
assert_se(r < 0);
|
||||||
|
|
||||||
|
data = (uint8_t []) { 0 , 0 };
|
||||||
|
r = dhcp6_option_parse_domainname_list(data, 2, &list);
|
||||||
|
assert_se(r < 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int test_option(sd_event *e) {
|
static int test_option(sd_event *e) {
|
||||||
uint8_t packet[] = {
|
uint8_t packet[] = {
|
||||||
'F', 'O', 'O',
|
'F', 'O', 'O',
|
||||||
|
@ -330,7 +378,7 @@ static uint8_t msg_advertise[198] = {
|
||||||
0x53, 0x00, 0x07, 0x00, 0x01, 0x00
|
0x53, 0x00, 0x07, 0x00, 0x01, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t msg_reply[173] = {
|
static uint8_t msg_reply[191] = {
|
||||||
0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
|
0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
|
||||||
0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
|
0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
|
||||||
0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
|
0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
|
||||||
|
@ -352,7 +400,9 @@ static uint8_t msg_reply[173] = {
|
||||||
0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
|
0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
|
||||||
0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
|
0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
|
||||||
0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
|
0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x01
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00,
|
||||||
|
0x0e, 0x01, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
|
0x74, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t fqdn_wire[16] = {
|
static uint8_t fqdn_wire[16] = {
|
||||||
|
@ -747,6 +797,7 @@ static void test_client_information_cb(sd_dhcp6_client *client, int event,
|
||||||
const struct in6_addr *addrs;
|
const struct in6_addr *addrs;
|
||||||
struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
|
struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
|
||||||
char **domains;
|
char **domains;
|
||||||
|
const char *fqdn;
|
||||||
|
|
||||||
log_debug("/* %s */", __func__);
|
log_debug("/* %s */", __func__);
|
||||||
|
|
||||||
|
@ -759,6 +810,9 @@ static void test_client_information_cb(sd_dhcp6_client *client, int event,
|
||||||
assert_se(!strcmp("lab.intra", domains[0]));
|
assert_se(!strcmp("lab.intra", domains[0]));
|
||||||
assert_se(domains[1] == NULL);
|
assert_se(domains[1] == NULL);
|
||||||
|
|
||||||
|
assert_se(sd_dhcp6_lease_get_fqdn(lease, &fqdn) >= 0);
|
||||||
|
assert_se(streq(fqdn, "client.intra"));
|
||||||
|
|
||||||
assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
|
assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
|
||||||
assert_se(!memcmp(addrs, &msg_advertise[124], 16));
|
assert_se(!memcmp(addrs, &msg_advertise[124], 16));
|
||||||
|
|
||||||
|
@ -945,6 +999,7 @@ int main(int argc, char *argv[]) {
|
||||||
test_option_status(e);
|
test_option_status(e);
|
||||||
test_advertise_option(e);
|
test_advertise_option(e);
|
||||||
test_client_solicit(e);
|
test_client_solicit(e);
|
||||||
|
test_parse_domain(e);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **addrs)
|
||||||
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains);
|
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains);
|
||||||
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **addrs);
|
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **addrs);
|
||||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn);
|
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn);
|
||||||
|
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn);
|
||||||
|
|
||||||
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
|
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
|
||||||
sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
|
sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
|
||||||
|
|
Loading…
Reference in New Issue