Re: [systemd-devel] [PATCH 11/11] sd_dhcp6_lease: Support DNS and NTP options

2015-01-13 Thread Zbigniew Jędrzejewski-Szmek
On Tue, Jan 13, 2015 at 02:02:21PM +0200, Patrik Flykt wrote:
 Store arrays of found DNS and NTP IPv6 addresses and strings of DNS
 search domains and NTP host names as specified in RFC 3646 and RFC
 5908.
 ---
  src/libsystemd-network/dhcp6-internal.h   |   3 +
  src/libsystemd-network/dhcp6-lease-internal.h |  18 
  src/libsystemd-network/dhcp6-option.c |  22 
  src/libsystemd-network/dhcp6-protocol.h   |   6 ++
  src/libsystemd-network/sd-dhcp6-client.c  |  22 
  src/libsystemd-network/sd-dhcp6-lease.c   | 140 
 ++
  src/systemd/sd-dhcp6-lease.h  |   6 ++
  7 files changed, 217 insertions(+)
 
 diff --git a/src/libsystemd-network/dhcp6-internal.h 
 b/src/libsystemd-network/dhcp6-internal.h
 index 4f54ad8..fd7deb9 100644
 --- a/src/libsystemd-network/dhcp6-internal.h
 +++ b/src/libsystemd-network/dhcp6-internal.h
 @@ -68,6 +68,9 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, 
 uint16_t *optcode,
 size_t *optlen, uint8_t **optvalue);
  int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
DHCP6IA *ia);
 +int dhcp6_option_get_ip6addrs(uint8_t *optval, uint16_t optlen,
 +struct in6_addr **addrs, size_t *size,
 +size_t *allocated);
  
  int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
  int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
 diff --git a/src/libsystemd-network/dhcp6-lease-internal.h 
 b/src/libsystemd-network/dhcp6-lease-internal.h
 index 109e0f4..dcc7913 100644
 --- a/src/libsystemd-network/dhcp6-lease-internal.h
 +++ b/src/libsystemd-network/dhcp6-lease-internal.h
 @@ -40,6 +40,19 @@ struct sd_dhcp6_lease {
  DHCP6IA ia;
  
  DHCP6Address *addr_iter;
 +
 +struct in6_addr *dns;
 +size_t dns_size;
 +size_t dns_allocated;
 +char *domain_list;
 +size_t domain_list_size;
 +size_t domain_list_allocated;
This would be confusing, since we often use size to mean allocated size.
And also it's not a list. Maybe domains, domains_count, domains_allocated?

 +struct in6_addr *ntp;
 +size_t ntp_size;
 +size_t ntp_allocated;
 +char *ntp_fqdn;
 +size_t ntp_fqdn_size;
 +size_t ntp_fqdn_allocated;
  };
  
  int dhcp6_lease_clear_timers(DHCP6IA *ia);
 @@ -56,6 +69,11 @@ int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, 
 bool *rapid_commit);
  
  int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
  
 +int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t 
 optlen);
 +int dhcp6_lease_set_domain_list(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_new(sd_dhcp6_lease **ret);
  
  DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref);
 diff --git a/src/libsystemd-network/dhcp6-option.c 
 b/src/libsystemd-network/dhcp6-option.c
 index ea863f4..7a7aad4 100644
 --- a/src/libsystemd-network/dhcp6-option.c
 +++ b/src/libsystemd-network/dhcp6-option.c
 @@ -317,3 +317,25 @@ error:
  
  return r;
  }
 +
 +int dhcp6_option_get_ip6addrs(uint8_t *optval, uint16_t optlen,
 +struct in6_addr **addrs, size_t *size,
 +size_t *allocated) {
 +size_t in6_size = sizeof(**addrs);
 +
 +assert_return(optval, -EINVAL);
 +assert_return(addrs, -EINVAL);
 +assert_return(size, -EINVAL);
 +
 +if (optlen % in6_size)
 +return -EINVAL;
 +
 +if (!GREEDY_REALLOC0(*addrs, *allocated, *size + optlen))
 +return -ENOMEM;
Well, in this case !GREEDY_REALLOC0 seems overkill, greedy_realloc0 will be 
cleaner.

 +memcpy(*addrs + *size / in6_size, optval, optlen);
 +
 +*size += optlen;
 +
 +return 0;
 +}
 diff --git a/src/libsystemd-network/dhcp6-protocol.h 
 b/src/libsystemd-network/dhcp6-protocol.h
 index 3e0f339..9330f23 100644
 --- a/src/libsystemd-network/dhcp6-protocol.h
 +++ b/src/libsystemd-network/dhcp6-protocol.h
 @@ -134,6 +134,12 @@ enum {
  };
  
  enum {
 +DHCP6_NTP_SUBOPTION_SRV_ADDR= 1,
 +DHCP6_NTP_SUBOPTION_MC_ADDR = 2,
 +DHCP6_NTP_SUBOPTION_SRV_FQDN= 3,
 +};
 +
 +enum {
  DHCP6_STATUS_SUCCESS= 0,
  DHCP6_STATUS_UNSPEC_FAIL= 1,
  DHCP6_STATUS_NO_ADDRS_AVAIL = 2,
 diff --git a/src/libsystemd-network/sd-dhcp6-client.c 
 b/src/libsystemd-network/sd-dhcp6-client.c
 index 940a606..ca6f316 100644
 --- a/src/libsystemd-network/sd-dhcp6-client.c
 +++ b/src/libsystemd-network/sd-dhcp6-client.c
 @@ -804,7 +804,29 @@ static int client_parse_message(sd_dhcp6_client *client,
  return r;
  
   

[systemd-devel] [PATCH 11/11] sd_dhcp6_lease: Support DNS and NTP options

2015-01-13 Thread Patrik Flykt
Store arrays of found DNS and NTP IPv6 addresses and strings of DNS
search domains and NTP host names as specified in RFC 3646 and RFC
5908.
---
 src/libsystemd-network/dhcp6-internal.h   |   3 +
 src/libsystemd-network/dhcp6-lease-internal.h |  18 
 src/libsystemd-network/dhcp6-option.c |  22 
 src/libsystemd-network/dhcp6-protocol.h   |   6 ++
 src/libsystemd-network/sd-dhcp6-client.c  |  22 
 src/libsystemd-network/sd-dhcp6-lease.c   | 140 ++
 src/systemd/sd-dhcp6-lease.h  |   6 ++
 7 files changed, 217 insertions(+)

diff --git a/src/libsystemd-network/dhcp6-internal.h 
b/src/libsystemd-network/dhcp6-internal.h
index 4f54ad8..fd7deb9 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -68,6 +68,9 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, 
uint16_t *optcode,
size_t *optlen, uint8_t **optvalue);
 int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
   DHCP6IA *ia);
+int dhcp6_option_get_ip6addrs(uint8_t *optval, uint16_t optlen,
+struct in6_addr **addrs, size_t *size,
+size_t *allocated);
 
 int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
 int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
diff --git a/src/libsystemd-network/dhcp6-lease-internal.h 
b/src/libsystemd-network/dhcp6-lease-internal.h
index 109e0f4..dcc7913 100644
--- a/src/libsystemd-network/dhcp6-lease-internal.h
+++ b/src/libsystemd-network/dhcp6-lease-internal.h
@@ -40,6 +40,19 @@ struct sd_dhcp6_lease {
 DHCP6IA ia;
 
 DHCP6Address *addr_iter;
+
+struct in6_addr *dns;
+size_t dns_size;
+size_t dns_allocated;
+char *domain_list;
+size_t domain_list_size;
+size_t domain_list_allocated;
+struct in6_addr *ntp;
+size_t ntp_size;
+size_t ntp_allocated;
+char *ntp_fqdn;
+size_t ntp_fqdn_size;
+size_t ntp_fqdn_allocated;
 };
 
 int dhcp6_lease_clear_timers(DHCP6IA *ia);
@@ -56,6 +69,11 @@ int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool 
*rapid_commit);
 
 int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
 
+int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
+int dhcp6_lease_set_domain_list(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_new(sd_dhcp6_lease **ret);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref);
diff --git a/src/libsystemd-network/dhcp6-option.c 
b/src/libsystemd-network/dhcp6-option.c
index ea863f4..7a7aad4 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -317,3 +317,25 @@ error:
 
 return r;
 }
+
+int dhcp6_option_get_ip6addrs(uint8_t *optval, uint16_t optlen,
+struct in6_addr **addrs, size_t *size,
+size_t *allocated) {
+size_t in6_size = sizeof(**addrs);
+
+assert_return(optval, -EINVAL);
+assert_return(addrs, -EINVAL);
+assert_return(size, -EINVAL);
+
+if (optlen % in6_size)
+return -EINVAL;
+
+if (!GREEDY_REALLOC0(*addrs, *allocated, *size + optlen))
+return -ENOMEM;
+
+memcpy(*addrs + *size / in6_size, optval, optlen);
+
+*size += optlen;
+
+return 0;
+}
diff --git a/src/libsystemd-network/dhcp6-protocol.h 
b/src/libsystemd-network/dhcp6-protocol.h
index 3e0f339..9330f23 100644
--- a/src/libsystemd-network/dhcp6-protocol.h
+++ b/src/libsystemd-network/dhcp6-protocol.h
@@ -134,6 +134,12 @@ enum {
 };
 
 enum {
+DHCP6_NTP_SUBOPTION_SRV_ADDR= 1,
+DHCP6_NTP_SUBOPTION_MC_ADDR = 2,
+DHCP6_NTP_SUBOPTION_SRV_FQDN= 3,
+};
+
+enum {
 DHCP6_STATUS_SUCCESS= 0,
 DHCP6_STATUS_UNSPEC_FAIL= 1,
 DHCP6_STATUS_NO_ADDRS_AVAIL = 2,
diff --git a/src/libsystemd-network/sd-dhcp6-client.c 
b/src/libsystemd-network/sd-dhcp6-client.c
index 940a606..ca6f316 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -804,7 +804,29 @@ static int client_parse_message(sd_dhcp6_client *client,
 return r;
 
 break;
+
+case DHCP6_OPTION_DNS_SERVERS:
+r = dhcp6_lease_set_dns(lease, optval, optlen);
+if (r  0)
+return r;
+
+break;
+
+case DHCP6_OPTION_DOMAIN_LIST:
+r = dhcp6_lease_set_domain_list(lease, optval, optlen);
+if (r