From 43f447b121b38c01a7c5626a51cc571a822250b8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 19:18:11 +0200 Subject: dhcp: be more careful when parsing strings from DHCP packets Let's make sure there's no embedded 0 byte. Also, let's reset the string if the length is zero. --- src/libsystemd-network/sd-dhcp-lease.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index f5b9e22589..57369a353d 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -287,13 +287,17 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { if (len >= 1) { char *string; + if (memchr(option, 0, len)) + return -EINVAL; + string = strndup((const char *)option, len); if (!string) - return -errno; + return -ENOMEM; free(*ret); *ret = string; - } + } else + *ret = mfree(*ret); return 0; } -- cgit v1.2.3-54-g00ecf From 8eb9058dc1f99a5eb9b8726a978fcc0720837a10 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 19:19:32 +0200 Subject: dhcp,network: implement RFC 4833 (DHCP Timezone option) This one is simply to add: encode the tzdata timezone in the DHCP options and optionally make use of it. --- src/libsystemd-network/dhcp-lease-internal.h | 1 + src/libsystemd-network/dhcp-protocol.h | 2 ++ src/libsystemd-network/dhcp-server-internal.h | 2 ++ src/libsystemd-network/sd-dhcp-lease.c | 32 +++++++++++++++++++++ src/libsystemd-network/sd-dhcp-server.c | 27 ++++++++++++++++++ src/libsystemd/sd-network/sd-network.c | 22 +++++++++++++++ src/network/networkctl.c | 9 ++++-- src/network/networkd-dhcp4.c | 5 ++++ src/network/networkd-link.c | 29 +++++++++++++++++++ src/network/networkd-network-gperf.gperf | 3 ++ src/network/networkd-network.c | 40 ++++++++++++++++++++++++++- src/network/networkd.h | 5 ++++ src/systemd/sd-dhcp-lease.h | 1 + src/systemd/sd-dhcp-server.h | 2 ++ src/systemd/sd-network.h | 3 ++ 15 files changed, 180 insertions(+), 3 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index 5a3fcddb1b..6e247e9865 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -83,6 +83,7 @@ struct sd_dhcp_lease { size_t client_id_len; uint8_t *vendor_specific; size_t vendor_specific_len; + char *timezone; LIST_HEAD(struct sd_dhcp_raw_option, private_options); }; diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h index 4308723f91..88a81d2866 100644 --- a/src/libsystemd-network/dhcp-protocol.h +++ b/src/libsystemd-network/dhcp-protocol.h @@ -137,6 +137,8 @@ enum { DHCP_OPTION_REBINDING_T2_TIME = 59, DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, DHCP_OPTION_CLIENT_IDENTIFIER = 61, + DHCP_OPTION_NEW_POSIX_TIMEZONE = 100, + DHCP_OPTION_NEW_TZDB_TIMEZONE = 101, DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, DHCP_OPTION_PRIVATE_BASE = 224, DHCP_OPTION_PRIVATE_LAST = 254, diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 58750c4418..24f99f801d 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -62,6 +62,8 @@ struct sd_dhcp_server { size_t pool_size; size_t next_offer; + char *timezone; + Hashmap *leases_by_client_id; DHCPLease **bound_leases; }; diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 57369a353d..c312c7cad0 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -608,6 +608,22 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, break; + case DHCP_OPTION_NEW_TZDB_TIMEZONE: { + _cleanup_free_ char *tz = NULL; + + r = lease_parse_string(option, len, &tz); + if (r < 0) + return r; + + if (!timezone_is_valid(tz)) + return -EINVAL; + + free(lease->timezone); + lease->timezone = tz; + tz = NULL; + break; + } + case DHCP_OPTION_VENDOR_SPECIFIC: if (len >= 1) { free(lease->vendor_specific); @@ -757,6 +773,10 @@ int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { if (r >= 0) serialize_dhcp_routes(f, "ROUTES", routes, r); + r = sd_dhcp_lease_get_timezone(lease, &string); + if (r >= 0) + fprintf(f, "TIMEZONE=%s\n", string); + r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len); if (r >= 0) { _cleanup_free_ char *client_id_hex; @@ -840,6 +860,7 @@ int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "ROOT_PATH", &lease->root_path, "ROUTES", &routes, "CLIENTID", &client_id_hex, + "TIMEZONE", &lease->timezone, "VENDOR_SPECIFIC", &vendor_specific_hex, "OPTION_224", &options[0], "OPTION_225", &options[1], @@ -1026,3 +1047,14 @@ int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, return 0; } + +int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone) { + assert_return(lease, -EINVAL); + assert_return(timezone, -EINVAL); + + if (!lease->timezone) + return -ENXIO; + + *timezone = lease->timezone; + return 0; +} diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index faeab0fd30..730d95e2c0 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -136,6 +136,8 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) { sd_event_unref(server->event); + free(server->timezone); + while ((lease = hashmap_steal_first(server->leases_by_client_id))) dhcp_lease_free(lease); hashmap_free(server->leases_by_client_id); @@ -474,6 +476,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req, if (r < 0) return r; + if (server->timezone) { + r = dhcp_option_append( + &packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_NEW_TZDB_TIMEZONE, + strlen(server->timezone), server->timezone); + if (r < 0) + return r; + } + r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset); if (r < 0) return r; @@ -993,3 +1004,19 @@ int sd_dhcp_server_forcerenew(sd_dhcp_server *server) { return r; } + +int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone) { + int r; + + assert_return(server, -EINVAL); + assert_return(timezone_is_valid(timezone), -EINVAL); + + if (streq_ptr(timezone, server->timezone)) + return 0; + + r = free_and_strdup(&server->timezone, timezone); + if (r < 0) + return r; + + return 1; +} diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index b63fdf8fcb..87d87359b8 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -214,6 +214,28 @@ _public_ int sd_network_link_get_lldp(int ifindex, char **lldp) { return 0; } +int sd_network_link_get_timezone(int ifindex, char **ret) { + _cleanup_free_ char *s = NULL, *p = NULL; + int r; + + assert_return(ifindex > 0, -EINVAL); + assert_return(ret, -EINVAL); + + if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "TIMEZONE", &s, NULL); + if (r == -ENOENT) + return -ENODATA; + if (r < 0) + return r; + if (isempty(s)) + return -ENODATA; + + *ret = s; + s = NULL; + return 0; +} static int network_get_link_strv(const char *key, int ifindex, char ***ret) { _cleanup_free_ char *p = NULL, *s = NULL; diff --git a/src/network/networkctl.c b/src/network/networkctl.c index c9b53dc3f6..2281d4b718 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -497,7 +497,7 @@ static int link_status_one( sd_hwdb *hwdb, const char *name) { _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL; - _cleanup_free_ char *setup_state = NULL, *operational_state = NULL; + _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *timezone = NULL; _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL; _cleanup_device_unref_ sd_device *d = NULL; char devid[2 + DECIMAL_STR_MAX(int)]; @@ -570,7 +570,6 @@ static int link_status_one( setup_state_to_color(setup_state, &on_color_setup, &off_color_setup); sd_network_link_get_dns(ifindex, &dns); - sd_network_link_get_ntp(ifindex, &ntp); sd_network_link_get_domains(ifindex, &domains); r = sd_network_link_get_wildcard_domain(ifindex); if (r > 0) { @@ -652,6 +651,8 @@ static int link_status_one( dump_list(" DNS: ", dns); if (!strv_isempty(domains)) dump_list(" Domain: ", domains); + + (void) sd_network_link_get_ntp(ifindex, &ntp); if (!strv_isempty(ntp)) dump_list(" NTP: ", ntp); @@ -661,6 +662,10 @@ static int link_status_one( if (!strv_isempty(carrier_bound_by)) dump_list("Carrier Bound By: ", carrier_bound_by); + (void) sd_network_link_get_timezone(ifindex, &timezone); + if (timezone) + printf(" Time Zone: %s", timezone); + return 0; } diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 1b2ff7c769..7fce389fa2 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -624,6 +624,11 @@ int dhcp4_configure(Link *link) { return r; } + /* Always acquire the timezone */ + r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NEW_TZDB_TIMEZONE); + if (r < 0) + return r; + if (link->network->dhcp_sendhost) { _cleanup_free_ char *hostname = NULL; const char *hn = NULL; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index cc9dc393c6..c179aafebb 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -672,6 +672,27 @@ static int link_enter_set_addresses(Link *link) { return r; */ + if (link->network->dhcp_server_emit_timezone) { + _cleanup_free_ char *buffer = NULL; + const char *tz; + + if (link->network->dhcp_server_timezone) + tz = link->network->dhcp_server_timezone; + else { + r = get_timezone(&buffer); + if (r < 0) + log_warning_errno(r, "Failed to determine timezone: %m"); + else + tz = buffer; + } + + if (tz) { + r = sd_dhcp_server_set_timezone(link->dhcp_server, tz); + if (r < 0) + return r; + } + } + r = sd_dhcp_server_start(link->dhcp_server); if (r < 0) { log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m"); @@ -2413,6 +2434,14 @@ int link_save(Link *link) { fputs("\n", f); } + if (link->dhcp_lease) { + const char *tz = NULL; + + r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz); + if (r >= 0) + fprintf(f, "TIMEZONE=%s\n", tz); + } + if (link->dhcp_lease) { assert(link->network); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 7ac7ef1ea3..c8c612d4eb 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -73,6 +73,9 @@ DHCP.RequestBroadcast, config_parse_bool, 0 DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_timezone) +DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) +DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) Bridge.UseBPDU, config_parse_bool, 0, offsetof(Network, use_bpdu) Bridge.HairPin, config_parse_bool, 0, offsetof(Network, hairpin) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 8f773e738d..3619e3160c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -124,7 +124,8 @@ static int network_load_one(Manager *manager, const char *filename) { "Address\0" "Route\0" "DHCP\0" - "DHCPv4\0" + "DHCPv4\0" /* compat */ + "DHCPServer\0" "Bridge\0" "BridgeFDB\0", config_item_perf_lookup, network_network_gperf_lookup, @@ -258,6 +259,8 @@ void network_free(Network *network) { condition_free_list(network->match_kernel); condition_free_list(network->match_arch); + free(network->dhcp_server_timezone); + free(network); } @@ -849,3 +852,38 @@ int config_parse_hostname( *hostname = hostname_cleanup(hn); return 0; } + +int config_parse_timezone( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **timezone = data, *tz = NULL; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata); + if (r < 0) + return r; + + if (!timezone_is_valid(tz)) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Timezone is not valid, ignoring assignment: %s", rvalue); + free(tz); + return 0; + } + + free(*timezone); + *timezone = tz; + + return 0; +} diff --git a/src/network/networkd.h b/src/network/networkd.h index 5340922bf1..a337ea7bf0 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -143,12 +143,15 @@ struct Network { bool dhcp_broadcast; bool dhcp_critical; bool dhcp_routes; + bool dhcp_timezone; unsigned dhcp_route_metric; AddressFamilyBoolean link_local; bool ipv4ll_route; union in_addr_union ipv6_token; bool dhcp_server; + char *dhcp_server_timezone; + bool dhcp_server_emit_timezone; bool use_bpdu; bool hairpin; @@ -461,3 +464,5 @@ int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename, /* Hostname */ int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_timezone(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 5afa50a9d0..6e109e03fd 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -49,6 +49,7 @@ int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data size_t *data_len); int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, size_t *client_id_len); +int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index 9af3b6532d..a2e1995cf9 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -47,5 +47,7 @@ int sd_dhcp_server_stop(sd_dhcp_server *server); int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen); int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, size_t size); +int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone); + int sd_dhcp_server_forcerenew(sd_dhcp_server *server); #endif diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index 4d96c867d9..4179015fbf 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -122,6 +122,9 @@ int sd_network_link_get_carrier_bound_to(int ifindex, char ***carriers); /* Get the CARRIERS that are bound to current link. */ int sd_network_link_get_carrier_bound_by(int ifindex, char ***carriers); +/* Get the timezone that was learnt on a specific link. */ +int sd_network_link_get_timezone(int ifindex, char **timezone); + /* Returns whether or not domains that don't match any link should be resolved * on this link. 1 for yes, 0 for no and negative value for error */ int sd_network_link_get_wildcard_domain(int ifindex); -- cgit v1.2.3-54-g00ecf From 2d03c0b803aa822dfb5f0473a1e37c19f7774860 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 20:11:35 +0200 Subject: dhcp: various simplifications --- src/libsystemd-network/sd-dhcp-lease.c | 65 ++++++++-------------------------- 1 file changed, 15 insertions(+), 50 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index c312c7cad0..f2e6cb0ddc 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -423,9 +423,8 @@ static int lease_parse_classless_routes(const uint8_t *option, size_t len, struc return 0; } -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, - void *user_data) { - sd_dhcp_lease *lease = user_data; +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, void *userdata) { + sd_dhcp_lease *lease = userdata; int r; assert(lease); @@ -434,87 +433,60 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, case DHCP_OPTION_TIME_OFFSET: lease_parse_s32(option, len, &lease->time_offset); - break; case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT: lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0); - break; case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: lease_parse_u32(option, len, &lease->lifetime, 1); - break; case DHCP_OPTION_SERVER_IDENTIFIER: lease_parse_be32(option, len, &lease->server_address); - break; case DHCP_OPTION_SUBNET_MASK: lease_parse_be32(option, len, &lease->subnet_mask); - break; case DHCP_OPTION_BROADCAST: lease_parse_be32(option, len, &lease->broadcast); - break; case DHCP_OPTION_ROUTER: - if(len >= 4) + if (len >= 4) lease_parse_be32(option, 4, &lease->router); break; case DHCP_OPTION_DOMAIN_NAME_SERVER: - r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); - if (r < 0) - return r; - - break; + return lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); case DHCP_OPTION_NTP_SERVER: - r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); - if (r < 0) - return r; - - break; + return lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); case DHCP_OPTION_POLICY_FILTER: - r = lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size); - if (r < 0) - return r; - - break; + return lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size); case DHCP_OPTION_STATIC_ROUTE: - r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, - &lease->static_route_allocated); - if (r < 0) - return r; - - break; + return lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); case DHCP_OPTION_INTERFACE_MTU: lease_parse_u16(option, len, &lease->mtu, 68); - break; case DHCP_OPTION_INTERFACE_MDR: lease_parse_u16(option, len, &lease->mdr, 576); - break; case DHCP_OPTION_INTERFACE_TTL: lease_parse_u8(option, len, &lease->ttl, 1); - break; case DHCP_OPTION_BOOT_FILE_SIZE: lease_parse_u16(option, len, &lease->boot_file_size, 0); - break; case DHCP_OPTION_DOMAIN_NAME: @@ -573,40 +545,32 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, break; } - case DHCP_OPTION_ROOT_PATH: - r = lease_parse_string(option, len, &lease->root_path); - if (r < 0) - return r; - break; + case DHCP_OPTION_ROOT_PATH: + return lease_parse_string(option, len, &lease->root_path); case DHCP_OPTION_RENEWAL_T1_TIME: lease_parse_u32(option, len, &lease->t1, 1); - break; case DHCP_OPTION_REBINDING_T2_TIME: lease_parse_u32(option, len, &lease->t2, 1); - break; case DHCP_OPTION_ENABLE_IP_FORWARDING: lease_parse_bool(option, len, &lease->ip_forward); - break; case DHCP_OPTION_ENABLE_IP_FORWARDING_NL: lease_parse_bool(option, len, &lease->ip_forward_non_local); - break; case DHCP_OPTION_CLASSLESS_STATIC_ROUTE: - r = lease_parse_classless_routes(option, len, &lease->static_route, &lease->static_route_size, - &lease->static_route_allocated); - if (r < 0) - return r; - - break; + return lease_parse_classless_routes( + option, len, + &lease->static_route, + &lease->static_route_size, + &lease->static_route_allocated); case DHCP_OPTION_NEW_TZDB_TIMEZONE: { _cleanup_free_ char *tz = NULL; @@ -625,6 +589,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, } case DHCP_OPTION_VENDOR_SPECIFIC: + if (len >= 1) { free(lease->vendor_specific); lease->vendor_specific = memdup(option, len); -- cgit v1.2.3-54-g00ecf From 909816257937b24e9c3c7fa669ea79b6ffc33c0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 20:12:17 +0200 Subject: dhcp: normalize DHCP host and domain names from leases Previoulsy, we just checked whether the domain names specified in incoming DHCP leases are valid. Given that validation code actually internally normalizes anyway, it's a good idea to simply do the full normalization and store that in the lease structure. This allows us to remove the manual removal of a trailing dot, if there is one. --- src/libsystemd-network/sd-dhcp-lease.c | 59 +++++++++++++++------------------- 1 file changed, 26 insertions(+), 33 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index f2e6cb0ddc..37e187c738 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -489,59 +489,52 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, v lease_parse_u16(option, len, &lease->boot_file_size, 0); break; - case DHCP_OPTION_DOMAIN_NAME: - { - _cleanup_free_ char *domainname = NULL; - char *e; + case DHCP_OPTION_DOMAIN_NAME: { + _cleanup_free_ char *domainname = NULL, *normalized = NULL; r = lease_parse_string(option, len, &domainname); if (r < 0) return r; - /* Chop off trailing dot of domain name that some DHCP - * servers send us back. Internally we want to store - * host names without trailing dots and - * host_name_is_valid() doesn't accept them. */ - e = endswith(domainname, "."); - if (e) - *e = 0; - - if (is_localhost(domainname)) - break; + r = dns_name_normalize(domainname, &normalized); + if (r < 0) { + log_debug_errno(r, "Failed to normalize domain name '%s': %m", domainname); + return 0; + } - r = dns_name_is_valid(domainname); - if (r <= 0) { - if (r < 0) - log_error_errno(r, "Failed to validate domain name: %s: %m", domainname); - if (r == 0) - log_warning("Domain name is not valid, ignoring: %s", domainname); + if (is_localhost(normalized)) { + log_debug_errno(r, "Detected 'localhost' as suggested hostname, ignoring."); break; } free(lease->domainname); - lease->domainname = domainname; - domainname = NULL; + lease->domainname = normalized; + normalized = NULL; break; } - case DHCP_OPTION_HOST_NAME: - { - _cleanup_free_ char *hostname = NULL; - char *e; + + case DHCP_OPTION_HOST_NAME: { + _cleanup_free_ char *hostname = NULL, *normalized = NULL; r = lease_parse_string(option, len, &hostname); if (r < 0) return r; - e = endswith(hostname, "."); - if (e) - *e = 0; + r = dns_name_normalize(hostname, &normalized); + if (r < 0) { + log_debug_errno(r, "Failed to normalize host name '%s': %m", hostname); + return 0; + } - if (!hostname_is_valid(hostname, false) || is_localhost(hostname)) - break; + if (is_localhost(normalized)) { + log_debug_errno(r, "Detected 'localhost' as suggested hostname, ignoring."); + return 0; + } - free_and_replace(&lease->hostname, hostname); - hostname = NULL; + free(lease->hostname); + lease->hostname = normalized; + normalized = NULL; break; } -- cgit v1.2.3-54-g00ecf From bd91b83e578165b4c242c9f34ff1d3be8fb3ab22 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 20:48:21 +0200 Subject: dhcp: keep lease save/load functions private When we make sd-dhcp public one day we really should not make sd_dhcp_lease_save() and sd_dhcp_lease_load() public, since it's pretty much only useful as internal utility for networkd itself. --- src/libsystemd-network/dhcp-lease-internal.h | 3 +++ src/libsystemd-network/sd-dhcp-lease.c | 4 ++-- src/network/networkd-link.c | 3 ++- src/systemd/sd-dhcp-lease.h | 3 --- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index 6e247e9865..d6b8aaa2d1 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -100,3 +100,6 @@ int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref); #define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp) + +int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); +int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 37e187c738..482c36ec97 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -650,7 +650,7 @@ int dhcp_lease_new(sd_dhcp_lease **ret) { return 0; } -int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { +int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; struct sd_dhcp_raw_option *option; @@ -785,7 +785,7 @@ fail: return log_error_errno(r, "Failed to save lease data %s: %m", lease_file); } -int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { +int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL, *server_address = NULL, *next_server = NULL, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c179aafebb..09c27de22b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -29,6 +29,7 @@ #include "socket-util.h" #include "bus-util.h" #include "udev-util.h" +#include "dhcp-lease-internal.h" #include "network-internal.h" #include "networkd-link.h" #include "networkd-netdev.h" @@ -2445,7 +2446,7 @@ int link_save(Link *link) { if (link->dhcp_lease) { assert(link->network); - r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file); + r = dhcp_lease_save(link->dhcp_lease, link->lease_file); if (r < 0) goto fail; diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 6e109e03fd..e142ae03bb 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -51,7 +51,4 @@ int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, size_t *client_id_len); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); -int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); -int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); - #endif -- cgit v1.2.3-54-g00ecf From 3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 21:05:53 +0200 Subject: dhcp: stop using refcnt.h No need to invole atomic ops in single-threaded APIs, let's simplify this. --- src/libsystemd-network/dhcp-lease-internal.h | 3 +- src/libsystemd-network/dhcp-server-internal.h | 3 +- src/libsystemd-network/dhcp6-lease-internal.h | 4 +-- src/libsystemd-network/sd-dhcp-client.c | 44 ++++++++++++++---------- src/libsystemd-network/sd-dhcp-lease.c | 49 +++++++++++++++++---------- src/libsystemd-network/sd-dhcp-server.c | 15 +++++--- src/libsystemd-network/sd-dhcp6-client.c | 35 ++++++++++++------- src/libsystemd-network/sd-dhcp6-lease.c | 36 +++++++++++++------- 8 files changed, 118 insertions(+), 71 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index d6b8aaa2d1..e1d2555505 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -25,7 +25,6 @@ #include #include -#include "refcnt.h" #include "util.h" #include "list.h" @@ -48,7 +47,7 @@ struct sd_dhcp_raw_option { }; struct sd_dhcp_lease { - RefCount n_ref; + int n_ref; int32_t time_offset; uint32_t t1; diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 24f99f801d..a5d3554e12 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -26,7 +26,6 @@ #include "sd-dhcp-server.h" #include "hashmap.h" -#include "refcnt.h" #include "util.h" #include "log.h" @@ -47,7 +46,7 @@ typedef struct DHCPLease { } DHCPLease; struct sd_dhcp_server { - RefCount n_ref; + unsigned n_ref; sd_event *event; int event_priority; diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index 037f580eb6..4edecf7711 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -24,13 +24,11 @@ #include -#include "refcnt.h" - #include "sd-dhcp6-lease.h" #include "dhcp6-internal.h" struct sd_dhcp6_lease { - RefCount n_ref; + unsigned n_ref; uint8_t *serverid; size_t serverid_len; diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 46104afded..32af9aa3da 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -27,7 +27,6 @@ #include #include "util.h" -#include "refcnt.h" #include "random-util.h" #include "async.h" @@ -41,7 +40,7 @@ #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN) struct sd_dhcp_client { - RefCount n_ref; + unsigned n_ref; DHCPState state; sd_event *event; @@ -1676,30 +1675,41 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { } sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) { - if (client) - assert_se(REFCNT_INC(client->n_ref) >= 2); + + if (!client) + return NULL; + + assert(client->n_ref >= 1); + client->n_ref++; return client; } sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { - if (client && REFCNT_DEC(client->n_ref) == 0) { - log_dhcp_client(client, "FREE"); - client_initialize(client); + if (!client) + return NULL; - client->receive_message = - sd_event_source_unref(client->receive_message); + assert(client->n_ref >= 1); + client->n_ref--; - sd_dhcp_client_detach_event(client); + if (client->n_ref > 0) + return NULL; - sd_dhcp_lease_unref(client->lease); + log_dhcp_client(client, "FREE"); - free(client->req_opts); - free(client->hostname); - free(client->vendor_class_identifier); - free(client); - } + client_initialize(client); + + client->receive_message = sd_event_source_unref(client->receive_message); + + sd_dhcp_client_detach_event(client); + + sd_dhcp_lease_unref(client->lease); + + free(client->req_opts); + free(client->hostname); + free(client->vendor_class_identifier); + free(client); return NULL; } @@ -1713,7 +1723,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret) { if (!client) return -ENOMEM; - client->n_ref = REFCNT_INIT; + client->n_ref = 1; client->state = DHCP_STATE_INIT; client->index = -1; client->fd = -1; diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 482c36ec97..75989951cf 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -195,32 +195,45 @@ int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data } sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) { - if (lease) - assert_se(REFCNT_INC(lease->n_ref) >= 2); + + if (!lease) + return NULL; + + assert(lease->n_ref >= 1); + lease->n_ref++; return lease; } sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { - if (lease && REFCNT_DEC(lease->n_ref) == 0) { - while (lease->private_options) { - struct sd_dhcp_raw_option *option = lease->private_options; - LIST_REMOVE(options, lease->private_options, option); + if (!lease) + return NULL; - free(option->data); - free(option); - } - free(lease->hostname); - free(lease->domainname); - free(lease->dns); - free(lease->ntp); - free(lease->static_route); - free(lease->client_id); - free(lease->vendor_specific); - free(lease); + assert(lease->n_ref >= 1); + lease->n_ref--; + + if (lease->n_ref > 0) + return NULL; + + while (lease->private_options) { + struct sd_dhcp_raw_option *option = lease->private_options; + + LIST_REMOVE(options, lease->private_options, option); + + free(option->data); + free(option); } + free(lease->hostname); + free(lease->domainname); + free(lease->dns); + free(lease->ntp); + free(lease->static_route); + free(lease->client_id); + free(lease->vendor_specific); + free(lease); + return NULL; } @@ -643,7 +656,7 @@ int dhcp_lease_new(sd_dhcp_lease **ret) { return -ENOMEM; lease->router = INADDR_ANY; - lease->n_ref = REFCNT_INIT; + lease->n_ref = 1; LIST_HEAD_INIT(lease->private_options); *ret = lease; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 730d95e2c0..e2cd52ac0c 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -73,8 +73,12 @@ bool sd_dhcp_server_is_running(sd_dhcp_server *server) { } sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) { - if (server) - assert_se(REFCNT_INC(server->n_ref) >= 2); + + if (!server) + return NULL; + + assert(server->n_ref >= 1); + server->n_ref++; return server; } @@ -127,7 +131,10 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) { if (!server) return NULL; - if (REFCNT_DEC(server->n_ref) > 0) + assert(server->n_ref >= 1); + server->n_ref--; + + if (server->n_ref > 0) return NULL; log_dhcp_server(server, "UNREF"); @@ -158,7 +165,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) { if (!server) return -ENOMEM; - server->n_ref = REFCNT_INIT; + server->n_ref = 1; server->fd_raw = -1; server->fd = -1; server->address = htobe32(INADDR_ANY); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 10c3654020..7075a42f43 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -27,7 +27,6 @@ #include "udev.h" #include "udev-util.h" #include "util.h" -#include "refcnt.h" #include "random-util.h" #include "network-internal.h" @@ -40,7 +39,7 @@ #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN struct sd_dhcp6_client { - RefCount n_ref; + unsigned n_ref; enum DHCP6State state; sd_event *event; @@ -1222,26 +1221,36 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { } sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) { - if (client) - assert_se(REFCNT_INC(client->n_ref) >= 2); + + if (!client) + return NULL; + + assert(client->n_ref >= 1); + client->n_ref++; return client; } sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { - if (client && REFCNT_DEC(client->n_ref) == 0) { - client_reset(client); - sd_dhcp6_client_detach_event(client); - sd_dhcp6_lease_unref(client->lease); + if (!client) + return NULL; - free(client->req_opts); - free(client); + assert(client->n_ref >= 1); + client->n_ref--; + if (client->n_ref > 0) return NULL; - } - return client; + client_reset(client); + + sd_dhcp6_client_detach_event(client); + sd_dhcp6_lease_unref(client->lease); + + free(client->req_opts); + free(client); + + return NULL; } int sd_dhcp6_client_new(sd_dhcp6_client **ret) @@ -1255,7 +1264,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) if (!client) return -ENOMEM; - client->n_ref = REFCNT_INIT; + client->n_ref = 1; client->ia_na.type = DHCP6_OPTION_IA_NA; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index f0494b3c91..cf317408b7 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -361,26 +361,38 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) { } sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) { - if (lease) - assert_se(REFCNT_INC(lease->n_ref) >= 2); + + if (!lease) + return NULL; + + assert(lease->n_ref >= 1); + lease->n_ref++; return lease; } sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { - if (lease && REFCNT_DEC(lease->n_ref) == 0) { - free(lease->serverid); - dhcp6_lease_free_ia(&lease->ia); - free(lease->dns); + if (!lease) + return NULL; - lease->domains = strv_free(lease->domains); + assert(lease->n_ref >= 1); + lease->n_ref--; - free(lease->ntp); + if (lease->n_ref > 0) + return NULL; - lease->ntp_fqdn = strv_free(lease->ntp_fqdn); - free(lease); - } + free(lease->serverid); + dhcp6_lease_free_ia(&lease->ia); + + free(lease->dns); + + lease->domains = strv_free(lease->domains); + + free(lease->ntp); + + lease->ntp_fqdn = strv_free(lease->ntp_fqdn); + free(lease); return NULL; } @@ -392,7 +404,7 @@ int dhcp6_lease_new(sd_dhcp6_lease **ret) { if (!lease) return -ENOMEM; - lease->n_ref = REFCNT_INIT; + lease->n_ref = 1; LIST_HEAD_INIT(lease->ia.addresses); -- cgit v1.2.3-54-g00ecf From 0ae0e5cd96813bacad43a39920a043d8d20a67db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 21:09:00 +0200 Subject: dhcp: coding style fixes We place the opening bracket of a function on the same line as the function name. Let's do so in the DHCP sources too. --- src/libsystemd-network/sd-dhcp6-client.c | 61 +++++++++++++------------------- 1 file changed, 24 insertions(+), 37 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 7075a42f43..5489c77864 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -112,9 +112,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref); static int client_start(sd_dhcp6_client *client, enum DHCP6State state); -int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, - sd_dhcp6_client_cb_t cb, void *userdata) -{ +int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_cb_t cb, void *userdata) { assert_return(client, -EINVAL); client->cb = cb; @@ -123,8 +121,7 @@ int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, return 0; } -int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) -{ +int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) { assert_return(client, -EINVAL); assert_return(interface_index >= -1, -EINVAL); @@ -133,9 +130,11 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) return 0; } -int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr, - size_t addr_len, uint16_t arp_type) -{ +int sd_dhcp6_client_set_mac( + sd_dhcp6_client *client, + const uint8_t *addr, size_t addr_len, + uint16_t arp_type) { + assert_return(client, -EINVAL); assert_return(addr, -EINVAL); assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL); @@ -159,16 +158,17 @@ int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr, return 0; } -static int client_ensure_duid(sd_dhcp6_client *client) -{ +static int client_ensure_duid(sd_dhcp6_client *client) { if (client->duid_len != 0) return 0; + return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); } -int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid, - size_t duid_len) -{ +int sd_dhcp6_client_set_duid( + sd_dhcp6_client *client, + uint16_t type, + uint8_t *duid, size_t duid_len) { assert_return(client, -EINVAL); assert_return(duid, -EINVAL); assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL); @@ -202,8 +202,7 @@ int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *du return 0; } -int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, - bool enabled) { +int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, bool enabled) { assert_return(client, -EINVAL); client->information_request = enabled; @@ -211,8 +210,7 @@ int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, return 0; } -int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, - bool *enabled) { +int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, bool *enabled) { assert_return(client, -EINVAL); assert_return(enabled, -EINVAL); @@ -221,8 +219,7 @@ int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, return 0; } -int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, - uint16_t option) { +int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) { size_t t; assert_return(client, -EINVAL); @@ -804,9 +801,7 @@ static int client_parse_message(sd_dhcp6_client *client, return r; } -static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, - size_t len) -{ +static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, size_t len) { int r; _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; bool rapid_commit; @@ -842,8 +837,7 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, return DHCP6_STATE_BOUND; } -static int client_receive_advertise(sd_dhcp6_client *client, - DHCP6Message *advertise, size_t len) { +static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *advertise, size_t len) { int r; _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; uint8_t pref_advertise = 0, pref_lease = 0; @@ -878,8 +872,7 @@ static int client_receive_advertise(sd_dhcp6_client *client, return r; } -static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, - void *userdata) { +static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_dhcp6_client *client = userdata; DHCP6_CLIENT_DONT_DESTROY(client); _cleanup_free_ DHCP6Message *message; @@ -990,8 +983,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, return 0; } -static int client_start(sd_dhcp6_client *client, enum DHCP6State state) -{ +static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { int r; usec_t timeout, time_now; char time_string[FORMAT_TIMESPAN_MAX]; @@ -1120,15 +1112,13 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) return 0; } -int sd_dhcp6_client_stop(sd_dhcp6_client *client) -{ +int sd_dhcp6_client_stop(sd_dhcp6_client *client) { client_stop(client, DHCP6_EVENT_STOP); return 0; } -int sd_dhcp6_client_start(sd_dhcp6_client *client) -{ +int sd_dhcp6_client_start(sd_dhcp6_client *client) { int r = 0; enum DHCP6State state = DHCP6_STATE_SOLICITATION; @@ -1184,9 +1174,7 @@ error: return r; } -int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, - int priority) -{ +int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int priority) { int r; assert_return(client, -EINVAL); @@ -1253,8 +1241,7 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { return NULL; } -int sd_dhcp6_client_new(sd_dhcp6_client **ret) -{ +int sd_dhcp6_client_new(sd_dhcp6_client **ret) { _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL; size_t t; -- cgit v1.2.3-54-g00ecf From 89ca10c6a61309d84d54c5dc5a295387ce39e610 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 22:47:53 +0200 Subject: network: s/user_data/userdata/ Everywhere else we call the generic user data pointer just "userdata", rather than "user_data". Let's do this here, too. --- src/libsystemd-network/dhcp-internal.h | 4 ++-- src/libsystemd-network/dhcp-lease-internal.h | 2 +- src/libsystemd-network/dhcp-option.c | 12 ++++++------ src/libsystemd-network/sd-dhcp-server.c | 4 ++-- src/libsystemd-network/test-dhcp-client.c | 2 +- src/libsystemd-network/test-dhcp-option.c | 4 ++-- src/libsystemd-network/test-ipv4ll.c | 6 +++--- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index 7c60ef123c..0df14f8051 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -45,10 +45,10 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_ uint8_t code, size_t optlen, const void *optval); typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len, - const uint8_t *option, void *user_data); + const uint8_t *option, void *userdata); int dhcp_option_parse(DHCPMessage *message, size_t len, - dhcp_option_cb_t cb, void *user_data); + dhcp_option_cb_t cb, void *userdata); int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, uint8_t type, uint16_t arp_type, size_t optlen, diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index e1d2555505..1765fabd4b 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -88,7 +88,7 @@ struct sd_dhcp_lease { int dhcp_lease_new(sd_dhcp_lease **ret); int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, - void *user_data); + void *userdata); int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const uint8_t *data, uint8_t len); diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c index b6110c5f16..36be7d54ed 100644 --- a/src/libsystemd-network/dhcp-option.c +++ b/src/libsystemd-network/dhcp-option.c @@ -140,7 +140,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload, uint8_t *message_type, dhcp_option_cb_t cb, - void *user_data) { + void *userdata) { uint8_t code, len; size_t offset = 0; @@ -199,7 +199,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo return -EINVAL; if (cb) - cb(code, len, &options[offset], user_data); + cb(code, len, &options[offset], userdata); offset += len; @@ -214,7 +214,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo } int dhcp_option_parse(DHCPMessage *message, size_t len, - dhcp_option_cb_t cb, void *user_data) { + dhcp_option_cb_t cb, void *userdata) { uint8_t overload = 0; uint8_t message_type = 0; int r; @@ -228,20 +228,20 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, len -= sizeof(DHCPMessage); r = parse_options(message->options, len, &overload, &message_type, - cb, user_data); + cb, userdata); if (r < 0) return r; if (overload & DHCP_OVERLOAD_FILE) { r = parse_options(message->file, sizeof(message->file), - NULL, &message_type, cb, user_data); + NULL, &message_type, cb, userdata); if (r < 0) return r; } if (overload & DHCP_OVERLOAD_SNAME) { r = parse_options(message->sname, sizeof(message->sname), - NULL, &message_type, cb, user_data); + NULL, &message_type, cb, userdata); if (r < 0) return r; } diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index e2cd52ac0c..df74d9f3ae 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -551,8 +551,8 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address, } static int parse_request(uint8_t code, uint8_t len, const uint8_t *option, - void *user_data) { - DHCPRequest *req = user_data; + void *userdata) { + DHCPRequest *req = userdata; assert(req); diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index 200499d613..1e0df634a4 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -127,7 +127,7 @@ static void test_checksum(void) } static int check_options(uint8_t code, uint8_t len, const uint8_t *option, - void *user_data) + void *userdata) { switch(code) { case DHCP_OPTION_CLIENT_IDENTIFIER: diff --git a/src/libsystemd-network/test-dhcp-option.c b/src/libsystemd-network/test-dhcp-option.c index a63a4ea738..37f46c8c56 100644 --- a/src/libsystemd-network/test-dhcp-option.c +++ b/src/libsystemd-network/test-dhcp-option.c @@ -145,8 +145,8 @@ static void test_ignore_opts(uint8_t *descoption, int *descpos, int *desclen) { } } -static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, void *user_data) { - struct option_desc *desc = user_data; +static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, void *userdata) { + struct option_desc *desc = userdata; uint8_t *descoption = NULL; int *desclen = NULL, *descpos = NULL; uint8_t optcode = 0; diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c index 5677bfb2d2..d60ee98b25 100644 --- a/src/libsystemd-network/test-ipv4ll.c +++ b/src/libsystemd-network/test-ipv4ll.c @@ -39,9 +39,9 @@ static int test_fd[2]; static int basic_request_handler_bind = 0; static int basic_request_handler_stop = 0; -static void* basic_request_handler_user_data = (void*)0xCABCAB; +static void* basic_request_handler_userdata = (void*)0xCABCAB; static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) { - assert_se(userdata == basic_request_handler_user_data); + assert_se(userdata == basic_request_handler_userdata); switch(event) { case IPV4LL_EVENT_STOP: @@ -175,7 +175,7 @@ static void test_basic_request(sd_event *e) { assert_se(sd_ipv4ll_start(ll) == -EINVAL); assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler, - basic_request_handler_user_data) == 0); + basic_request_handler_userdata) == 0); assert_se(sd_ipv4ll_start(ll) == -EINVAL); assert_se(sd_ipv4ll_set_index(ll, 1) == 0); -- cgit v1.2.3-54-g00ecf From e473522841f630bfd25725b06605462e5e30587f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 23:05:34 +0200 Subject: dhcp: generic data should be void*, not uint8_t* If we handly arbitrary data we should use "void*" pointers, not "uint8_t*", how go intended C to be used. --- src/libsystemd-network/dhcp-internal.h | 2 +- src/libsystemd-network/dhcp-lease-internal.h | 10 +++++----- src/libsystemd-network/network-internal.c | 4 ++-- src/libsystemd-network/network-internal.h | 4 ++-- src/libsystemd-network/sd-dhcp-lease.c | 14 +++++++------- src/libsystemd-network/sd-dhcp-server.c | 2 +- src/libsystemd-network/test-dhcp-client.c | 8 ++++---- src/libsystemd-network/test-dhcp-option.c | 6 +++--- src/systemd/sd-dhcp-lease.h | 6 +++--- 9 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index 0df14f8051..df6f882af5 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -45,7 +45,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_ uint8_t code, size_t optlen, const void *optval); typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len, - const uint8_t *option, void *userdata); + const void *option, void *userdata); int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_cb_t cb, void *userdata); diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index 1765fabd4b..ebe6c2f7e7 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -78,23 +78,23 @@ struct sd_dhcp_lease { char *domainname; char *hostname; char *root_path; - uint8_t *client_id; + void *client_id; size_t client_id_len; - uint8_t *vendor_specific; + void *vendor_specific; size_t vendor_specific_len; char *timezone; LIST_HEAD(struct sd_dhcp_raw_option, private_options); }; int dhcp_lease_new(sd_dhcp_lease **ret); -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata); int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, - const uint8_t *data, uint8_t len); + const void *data, uint8_t len); int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease); -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref); diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index d8357c687e..26bd4088d9 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -525,7 +525,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t return 0; } -int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size) { +int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size) { _cleanup_free_ char *hex_buf = NULL; assert(f); @@ -541,7 +541,7 @@ int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t return 0; } -int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string) { +int deserialize_dhcp_option(void **data, size_t *data_len, const char *string) { assert(data); assert(data_len); assert(string); diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index dca82646ce..d5d4ef42f2 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -77,5 +77,5 @@ struct sd_dhcp_route; void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size); int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string); -int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size); -int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string); +int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size); +int deserialize_dhcp_option(void **data, size_t *data_len, const char *string); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 75989951cf..328ab152b8 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -179,7 +179,7 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes return 0; } -int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data, +int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) { assert_return(lease, -EINVAL); assert_return(data, -EINVAL); @@ -436,7 +436,7 @@ static int lease_parse_classless_routes(const uint8_t *option, size_t len, struc return 0; } -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, void *userdata) { +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata) { sd_dhcp_lease *lease = userdata; int r; @@ -619,7 +619,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, v } int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, - const uint8_t *data, uint8_t len) { + const void *data, uint8_t len) { struct sd_dhcp_raw_option *cur, *option; LIST_FOREACH(options, cur, lease->private_options) { @@ -669,7 +669,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { struct sd_dhcp_raw_option *option; struct in_addr address; const struct in_addr *addresses; - const uint8_t *client_id, *data; + const void *client_id, *data; size_t client_id_len, data_len; const char *string; uint16_t mtu; @@ -950,7 +950,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { } for (i = 0; i <= DHCP_OPTION_PRIVATE_LAST - DHCP_OPTION_PRIVATE_BASE; i++) { - _cleanup_free_ uint8_t *data = NULL; + _cleanup_free_ void *data = NULL; size_t len; if (!options[i]) @@ -990,7 +990,7 @@ int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { return 0; } -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) { assert_return(lease, -EINVAL); assert_return(client_id, -EINVAL); @@ -1001,7 +1001,7 @@ int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, return 0; } -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len) { assert_return(lease, -EINVAL); assert_return((!client_id && !client_id_len) || diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index df74d9f3ae..968df1f43d 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -550,7 +550,7 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address, return 0; } -static int parse_request(uint8_t code, uint8_t len, const uint8_t *option, +static int parse_request(uint8_t code, uint8_t len, const void *option, void *userdata) { DHCPRequest *req = userdata; diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index 1e0df634a4..b2a0d3bb8b 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -126,7 +126,7 @@ static void test_checksum(void) assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae)); } -static int check_options(uint8_t code, uint8_t len, const uint8_t *option, +static int check_options(uint8_t code, uint8_t len, const void *option, void *userdata) { switch(code) { @@ -141,10 +141,10 @@ static int check_options(uint8_t code, uint8_t len, const uint8_t *option, assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len); assert_se(len == 19); - assert_se(option[0] == 0xff); + assert_se(((uint8_t*) option)[0] == 0xff); - assert_se(memcmp(&option[1], &iaid, sizeof(iaid)) == 0); - assert_se(memcmp(&option[5], &duid, duid_len) == 0); + assert_se(memcmp((uint8_t*) option + 1, &iaid, sizeof(iaid)) == 0); + assert_se(memcmp((uint8_t*) option + 5, &duid, duid_len) == 0); break; } diff --git a/src/libsystemd-network/test-dhcp-option.c b/src/libsystemd-network/test-dhcp-option.c index 37f46c8c56..b1ef174849 100644 --- a/src/libsystemd-network/test-dhcp-option.c +++ b/src/libsystemd-network/test-dhcp-option.c @@ -145,7 +145,7 @@ static void test_ignore_opts(uint8_t *descoption, int *descpos, int *desclen) { } } -static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, void *userdata) { +static int test_options_cb(uint8_t code, uint8_t len, const void *option, void *userdata) { struct option_desc *desc = userdata; uint8_t *descoption = NULL; int *desclen = NULL, *descpos = NULL; @@ -207,10 +207,10 @@ static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, voi for (i = 0; i < len; i++) { if (verbose) - printf("0x%02x(0x%02x) ", option[i], + printf("0x%02x(0x%02x) ", ((uint8_t*) option)[i], descoption[*descpos + 2 + i]); - assert_se(option[i] == descoption[*descpos + 2 + i]); + assert_se(((uint8_t*) option)[i] == descoption[*descpos + 2 + i]); } if (verbose) diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index e142ae03bb..7fa126d198 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -44,10 +44,10 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname); int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path); -int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routesgn); -int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data, +int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes); +int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len); -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); -- cgit v1.2.3-54-g00ecf From 966d74c043098e12d4d5b101aa7650244c14b815 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 23:26:01 +0200 Subject: dhcp: properly handle error from ioctl() --- src/libsystemd-network/sd-dhcp-server.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 968df1f43d..8f6da4bc00 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -901,13 +901,12 @@ static int server_receive_message(sd_event_source *s, int fd, .msg_controllen = sizeof(cmsgbuf), }; struct cmsghdr *cmsg; - int buflen = 0, len, r; + int buflen = 0, len; assert(server); - r = ioctl(fd, FIONREAD, &buflen); - if (r < 0) - return r; + if (ioctl(fd, FIONREAD, &buflen) < 0) + return -errno; if (buflen < 0) return -EIO; -- cgit v1.2.3-54-g00ecf From 9a0f246fcdb1238e6b3397169a10095f4df89210 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 23:30:27 +0200 Subject: dhcp: store client id as void*, since we dont know what it is --- src/libsystemd-network/dhcp-server-internal.h | 2 +- src/libsystemd-network/sd-dhcp-server.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index a5d3554e12..52e2c9308b 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -33,7 +33,7 @@ typedef struct DHCPClientId { size_t length; - uint8_t *data; + void *data; } DHCPClientId; typedef struct DHCPLease { diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 8f6da4bc00..92276af233 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -617,22 +617,23 @@ static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) { /* set client id based on MAC address if client did not send an explicit one */ if (!req->client_id.data) { - uint8_t *data; + void *data; - data = new0(uint8_t, ETH_ALEN + 1); + data = malloc0(ETH_ALEN + 1); if (!data) return -ENOMEM; + ((uint8_t*) data)[0] = 0x01; + memcpy((uint8_t*) data + 1, &message->chaddr, ETH_ALEN); + req->client_id.length = ETH_ALEN + 1; req->client_id.data = data; - req->client_id.data[0] = 0x01; - memcpy(&req->client_id.data[1], &message->chaddr, ETH_ALEN); } if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE) req->max_optlen = DHCP_MIN_OPTIONS_SIZE; - if (!req->lifetime) + if (req->lifetime <= 0) req->lifetime = DHCP_DEFAULT_LEASE_TIME; return 0; @@ -683,8 +684,8 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, &req->client_id); switch(type) { - case DHCP_DISCOVER: - { + + case DHCP_DISCOVER: { be32_t address = INADDR_ANY; unsigned i; @@ -734,9 +735,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, return 1; - break; - case DHCP_REQUEST: - { + case DHCP_REQUEST: { be32_t address; bool init_reboot = false; int pool_offset; @@ -858,6 +857,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, break; } + case DHCP_RELEASE: { int pool_offset; -- cgit v1.2.3-54-g00ecf From b3ec603ce8053ba3f95da1d36f15ea762c83d1e1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Aug 2015 23:31:47 +0200 Subject: dhcp: rename index to ifindex This avoids confusion what this is, in particular as libc knows an index() function. --- src/libsystemd-network/dhcp-server-internal.h | 2 +- src/libsystemd-network/sd-dhcp-server.c | 26 ++++++++------------------ 2 files changed, 9 insertions(+), 19 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 52e2c9308b..74b09d6f37 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -54,7 +54,7 @@ struct sd_dhcp_server { int fd; int fd_raw; - int index; + int ifindex; be32_t address; be32_t netmask; be32_t pool_start; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 92276af233..bfb799a63d 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -170,7 +170,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) { server->fd = -1; server->address = htobe32(INADDR_ANY); server->netmask = htobe32(INADDR_ANY); - server->index = ifindex; + server->ifindex = ifindex; server->leases_by_client_id = hashmap_new(&client_id_hash_ops); *ret = server; @@ -232,13 +232,12 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server, union sockaddr_union link = { .ll.sll_family = AF_PACKET, .ll.sll_protocol = htons(ETH_P_IP), - .ll.sll_ifindex = server->index, + .ll.sll_ifindex = server->ifindex, .ll.sll_halen = ETH_ALEN, }; - int r; assert(server); - assert(server->index > 0); + assert(server->ifindex > 0); assert(server->address); assert(packet); assert(len > sizeof(DHCPPacket)); @@ -249,11 +248,7 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server, packet->dhcp.yiaddr, DHCP_PORT_CLIENT, len); - r = dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len); - if (r < 0) - return r; - - return 0; + return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len); } static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination, @@ -299,7 +294,7 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination, pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg); assert(pktinfo); - pktinfo->ipi_ifindex = server->index; + pktinfo->ipi_ifindex = server->ifindex; pktinfo->ipi_spec_dst.s_addr = server->address; r = sendmsg(server->fd, &msg, 0); @@ -508,11 +503,7 @@ static int server_send_nak(sd_dhcp_server *server, DHCPRequest *req) { if (r < 0) return r; - r = dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset); - if (r < 0) - return r; - - return 0; + return dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset); } static int server_send_forcerenew(sd_dhcp_server *server, be32_t address, @@ -550,8 +541,7 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address, return 0; } -static int parse_request(uint8_t code, uint8_t len, const void *option, - void *userdata) { +static int parse_request(uint8_t code, uint8_t len, const void *option, void *userdata) { DHCPRequest *req = userdata; assert(req); @@ -931,7 +921,7 @@ static int server_receive_message(sd_event_source *s, int fd, /* TODO figure out if this can be done as a filter on * the socket, like for IPv6 */ - if (server->index != info->ipi_ifindex) + if (server->ifindex != info->ipi_ifindex) return 0; break; -- cgit v1.2.3-54-g00ecf From 0339cd7707ac40c29d51ee6933d06bc87ed140a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 01:05:13 +0200 Subject: dhcp: clean up dhcp4 lease object a) drop handling of obsolete or unused DHCP options time_offset, mtu_aging_timeout, policy filter, mdr, ttl, ip forwarding settings. Should this become useful one day we can readd support for this. b) For subnet mask and broadcast it is not always clear whether 0 or 255.255.255.255 might be valid, hence maintain a boolean indicating validity next to it. c) serialize/deserialize broadcast address, lifetime, T1 and T2 together with the rest of the fields in dhcp_lease_save() and dhcp_lease_load(). d) consistently return ENODATA from getter functions for data that is missing in the lease. e) add missing getter calls for broadcast, lifetime, T1, T2. f) when decoding DHCP options, generate debug messages on parse failures, but try to proceed if possible. g) Similar, when deserializing a lease in dhcp_lease_load(), make sure we deal nicely with unparsable fields, to provide upgrade compat. h) fix some memory allocations --- src/libsystemd-network/dhcp-lease-internal.h | 48 +- src/libsystemd-network/sd-dhcp-client.c | 13 +- src/libsystemd-network/sd-dhcp-lease.c | 642 ++++++++++++++++----------- src/systemd/sd-dhcp-lease.h | 9 +- 4 files changed, 408 insertions(+), 304 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index ebe6c2f7e7..95c2375d48 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -49,56 +49,60 @@ struct sd_dhcp_raw_option { struct sd_dhcp_lease { int n_ref; - int32_t time_offset; + /* each 0 if unset */ uint32_t t1; uint32_t t2; uint32_t lifetime; - uint32_t mtu_aging_timeout; + + /* each 0 if unset */ be32_t address; be32_t server_address; - be32_t subnet_mask; be32_t router; be32_t next_server; + + bool have_subnet_mask; + be32_t subnet_mask; + + bool have_broadcast; be32_t broadcast; + struct in_addr *dns; size_t dns_size; + struct in_addr *ntp; size_t ntp_size; - struct in_addr *policy_filter; - size_t policy_filter_size; + struct sd_dhcp_route *static_route; - size_t static_route_size; - size_t static_route_allocated; - uint16_t boot_file_size; - uint16_t mdr; - uint16_t mtu; - uint8_t ttl; - bool ip_forward; - bool ip_forward_non_local; + size_t static_route_size, static_route_allocated; + + uint16_t mtu; /* 0 if unset */ + char *domainname; char *hostname; char *root_path; + void *client_id; size_t client_id_len; + void *vendor_specific; size_t vendor_specific_len; + char *timezone; + LIST_HEAD(struct sd_dhcp_raw_option, private_options); }; int dhcp_lease_new(sd_dhcp_lease **ret); -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, - void *userdata); -int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, - const void *data, uint8_t len); -int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease); +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata); +int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len); -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, - size_t client_id_len); +int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease); -DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref); -#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp) +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len); int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref); +#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 32af9aa3da..29c67f23be 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -376,8 +376,7 @@ static int client_initialize(sd_dhcp_client *client) { client->state = DHCP_STATE_INIT; client->xid = 0; - if (client->lease) - client->lease = sd_dhcp_lease_unref(client->lease); + client->lease = sd_dhcp_lease_unref(client->lease); return 0; } @@ -1054,18 +1053,16 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, } lease->next_server = offer->siaddr; - lease->address = offer->yiaddr; - if (lease->address == INADDR_ANY || - lease->server_address == INADDR_ANY || + if (lease->address == 0 || + lease->server_address == 0 || lease->lifetime == 0) { - log_dhcp_client(client, "received lease lacks address, server " - "address or lease lifetime, ignoring"); + log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring"); return -ENOMSG; } - if (lease->subnet_mask == INADDR_ANY) { + if (!lease->have_subnet_mask) { r = dhcp_lease_set_default_subnet_mask(lease); if (r < 0) { log_dhcp_client(client, "received lease lacks subnet " diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 328ab152b8..123ea68f19 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -28,18 +28,31 @@ #include "unaligned.h" #include "in-addr-util.h" #include "hostname-util.h" +#include "dns-domain.h" +#include "network-internal.h" #include "dhcp-protocol.h" #include "dhcp-lease-internal.h" #include "sd-dhcp-lease.h" -#include "network-internal.h" -#include "dns-domain.h" int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); + if (lease->address == 0) + return -ENODATA; + addr->s_addr = lease->address; + return 0; +} +int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (!lease->have_broadcast) + return -ENODATA; + + addr->s_addr = lease->broadcast; return 0; } @@ -47,8 +60,32 @@ int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) { assert_return(lease, -EINVAL); assert_return(lifetime, -EINVAL); + if (lease->lifetime <= 0) + return -ENODATA; + *lifetime = lease->lifetime; + return 0; +} +int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1) { + assert_return(lease, -EINVAL); + assert_return(t1, -EINVAL); + + if (lease->t1 <= 0) + return -ENODATA; + + *t1 = lease->t1; + return 0; +} + +int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2) { + assert_return(lease, -EINVAL); + assert_return(t2, -EINVAL); + + if (lease->t2 <= 0) + return -ENODATA; + + *t2 = lease->t2; return 0; } @@ -56,11 +93,10 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) { assert_return(lease, -EINVAL); assert_return(mtu, -EINVAL); - if (lease->mtu) - *mtu = lease->mtu; - else - return -ENOENT; + if (lease->mtu <= 0) + return -ENODATA; + *mtu = lease->mtu; return 0; } @@ -68,37 +104,32 @@ int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - if (lease->dns_size) { - *addr = lease->dns; - return lease->dns_size; - } else - return -ENOENT; + if (lease->dns_size <= 0) + return -ENODATA; - return 0; + *addr = lease->dns; + return (int) lease->dns_size; } int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - if (lease->ntp_size) { - *addr = lease->ntp; - return lease->ntp_size; - } else - return -ENOENT; + if (lease->ntp_size <= 0) + return -ENODATA; - return 0; + *addr = lease->ntp; + return (int) lease->ntp_size; } int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { assert_return(lease, -EINVAL); assert_return(domainname, -EINVAL); - if (lease->domainname) - *domainname = lease->domainname; - else - return -ENOENT; + if (!lease->domainname) + return -ENODATA; + *domainname = lease->domainname; return 0; } @@ -106,11 +137,10 @@ int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) { assert_return(lease, -EINVAL); assert_return(hostname, -EINVAL); - if (lease->hostname) - *hostname = lease->hostname; - else - return -ENOENT; + if (!lease->hostname) + return -ENODATA; + *hostname = lease->hostname; return 0; } @@ -118,11 +148,10 @@ int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) { assert_return(lease, -EINVAL); assert_return(root_path, -EINVAL); - if (lease->root_path) - *root_path = lease->root_path; - else - return -ENOENT; + if (!lease->root_path) + return -ENODATA; + *root_path = lease->root_path; return 0; } @@ -130,11 +159,10 @@ int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - if (lease->router != INADDR_ANY) - addr->s_addr = lease->router; - else - return -ENOENT; + if (lease->router == 0) + return -ENODATA; + addr->s_addr = lease->router; return 0; } @@ -142,8 +170,10 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - addr->s_addr = lease->subnet_mask; + if (!lease->have_subnet_mask) + return -ENODATA; + addr->s_addr = lease->subnet_mask; return 0; } @@ -151,8 +181,10 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - addr->s_addr = lease->server_address; + if (lease->server_address == 0) + return -ENODATA; + addr->s_addr = lease->server_address; return 0; } @@ -160,37 +192,34 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) { assert_return(lease, -EINVAL); assert_return(addr, -EINVAL); - addr->s_addr = lease->next_server; + if (lease->next_server == 0) + return -ENODATA; + addr->s_addr = lease->next_server; return 0; } int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) { - assert_return(lease, -EINVAL); assert_return(routes, -EINVAL); - if (lease->static_route_size) { - *routes = lease->static_route; - return lease->static_route_size; - } else - return -ENOENT; + if (lease->static_route_size <= 0) + return -ENODATA; - return 0; + *routes = lease->static_route; + return (int) lease->static_route_size; } -int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, - size_t *data_len) { +int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) { assert_return(lease, -EINVAL); assert_return(data, -EINVAL); assert_return(data_len, -EINVAL); - if (!lease->vendor_specific) - return -ENOENT; + if (lease->vendor_specific_len <= 0) + return -ENODATA; *data = lease->vendor_specific; *data_len = lease->vendor_specific_len; - return 0; } @@ -237,67 +266,52 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { return NULL; } -static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { +static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { assert(option); assert(ret); - if (len == 4) { - *ret = unaligned_read_be32((be32_t*) option); - - if (*ret < min) - *ret = min; - } -} - -static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) { - lease_parse_u32(option, len, (uint32_t *)ret, 0); -} - -static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) { - assert(option); - assert(ret); + if (len != 4) + return -EINVAL; - if (len == 2) { - *ret = unaligned_read_be16((be16_t*) option); + *ret = unaligned_read_be32((be32_t*) option); + if (*ret < min) + *ret = min; - if (*ret < min) - *ret = min; - } + return 0; } -static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) { +static int lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) { assert(option); assert(ret); - if (len == 4) - memcpy(ret, option, 4); -} + if (len != 2) + return -EINVAL; -static void lease_parse_bool(const uint8_t *option, size_t len, bool *ret) { - assert(option); - assert(ret); + *ret = unaligned_read_be16((be16_t*) option); + if (*ret < min) + *ret = min; - if (len == 1) - *ret = !!(*option); + return 0; } -static void lease_parse_u8(const uint8_t *option, size_t len, uint8_t *ret, uint8_t min) { +static int lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) { assert(option); assert(ret); - if (len == 1) { - *ret = *option; + if (len != 4) + return -EINVAL; - if (*ret < min) - *ret = min; - } + memcpy(ret, option, 4); + return 0; } static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { assert(option); assert(ret); - if (len >= 1) { + if (len <= 0) + *ret = mfree(*ret); + else { char *string; if (memchr(option, 0, len)) @@ -309,54 +323,52 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { free(*ret); *ret = string; - } else - *ret = mfree(*ret); + } return 0; } -static int lease_parse_in_addrs_aux(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size, size_t mult) { +static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) { assert(option); assert(ret); - assert(ret_size); + assert(n_ret); - if (len && !(len % (4 * mult))) { - size_t size; + if (len <= 0) { + *ret = mfree(*ret); + *n_ret = 0; + } else { + size_t n_addresses; struct in_addr *addresses; - size = len / 4; + if (len % 4 != 0) + return -EINVAL; - addresses = newdup(struct in_addr, option, size); + n_addresses = len / 4; + + addresses = newdup(struct in_addr, option, n_addresses); if (!addresses) return -ENOMEM; free(*ret); *ret = addresses; - *ret_size = size; + *n_ret = n_addresses; } return 0; } -static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) { - return lease_parse_in_addrs_aux(option, len, ret, ret_size, 1); -} - -static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) { - return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2); -} - -static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes, - size_t *routes_size, size_t *routes_allocated) { +static int lease_parse_routes( + const uint8_t *option, size_t len, + struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) { struct in_addr addr; - assert(option); + assert(option || len <= 0); assert(routes); assert(routes_size); assert(routes_allocated); - if (!len) + if (len <= 0) return 0; if (len % 8 != 0) @@ -371,15 +383,15 @@ static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_ r = in_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen); if (r < 0) { - log_error("Failed to determine destination prefix length from class based IP, ignoring"); + log_debug("Failed to determine destination prefix length from class based IP, ignoring"); continue; } - lease_parse_be32(option, 4, &addr.s_addr); + assert_se(lease_parse_be32(option, 4, &addr.s_addr) >= 0); route->dst_addr = inet_makeaddr(inet_netof(addr), 0); option += 4; - lease_parse_be32(option, 4, &route->gw_addr.s_addr); + assert_se(lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0); option += 4; len -= 8; @@ -390,14 +402,18 @@ static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_ } /* parses RFC3442 Classless Static Route Option */ -static int lease_parse_classless_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes, - size_t *routes_size, size_t *routes_allocated) { +static int lease_parse_classless_routes( + const uint8_t *option, size_t len, + struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) { - assert(option); + assert(option || len <= 0); assert(routes); assert(routes_size); assert(routes_allocated); + if (len <= 0) + return 0; + /* option format: (subnet-mask-width significant-subnet-octets gateway-ip)* */ while (len > 0) { @@ -405,7 +421,7 @@ static int lease_parse_classless_routes(const uint8_t *option, size_t len, struc struct sd_dhcp_route *route; if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1)) - return -ENOMEM; + return -ENOMEM; route = *routes + *routes_size; @@ -444,70 +460,76 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void switch(code) { - case DHCP_OPTION_TIME_OFFSET: - lease_parse_s32(option, len, &lease->time_offset); - break; - - case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT: - lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0); - break; - case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: - lease_parse_u32(option, len, &lease->lifetime, 1); + r = lease_parse_u32(option, len, &lease->lifetime, 1); + if (r < 0) + log_debug_errno(r, "Failed to parse lease time, ignoring: %m"); + break; case DHCP_OPTION_SERVER_IDENTIFIER: - lease_parse_be32(option, len, &lease->server_address); + r = lease_parse_be32(option, len, &lease->server_address); + if (r < 0) + log_debug_errno(r, "Failed to parse server identifier, ignoring: %m"); + break; case DHCP_OPTION_SUBNET_MASK: - lease_parse_be32(option, len, &lease->subnet_mask); + r = lease_parse_be32(option, len, &lease->subnet_mask); + if (r < 0) + log_debug_errno(r, "Failed to parse subnet mask, ignoring: %m"); + else + lease->have_subnet_mask = true; break; case DHCP_OPTION_BROADCAST: - lease_parse_be32(option, len, &lease->broadcast); + r = lease_parse_be32(option, len, &lease->broadcast); + if (r < 0) + log_debug_errno(r, "Failed to parse broadcast address, ignoring: %m"); + else + lease->have_broadcast = true; break; case DHCP_OPTION_ROUTER: - if (len >= 4) - lease_parse_be32(option, 4, &lease->router); - + if (len >= 4) { + r = lease_parse_be32(option, 4, &lease->router); + if (r < 0) + log_debug_errno(r, "Failed to parse router address, ignoring: %m"); + } break; case DHCP_OPTION_DOMAIN_NAME_SERVER: - return lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); - - case DHCP_OPTION_NTP_SERVER: - return lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); - - case DHCP_OPTION_POLICY_FILTER: - return lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size); - - case DHCP_OPTION_STATIC_ROUTE: - return lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); - - case DHCP_OPTION_INTERFACE_MTU: - lease_parse_u16(option, len, &lease->mtu, 68); + r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); + if (r < 0) + log_debug_errno(r, "Failed to parse DNS server, ignoring: %m"); break; - case DHCP_OPTION_INTERFACE_MDR: - lease_parse_u16(option, len, &lease->mdr, 576); + case DHCP_OPTION_NTP_SERVER: + r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); + if (r < 0) + log_debug_errno(r, "Failed to parse NTP server, ignoring: %m"); break; - case DHCP_OPTION_INTERFACE_TTL: - lease_parse_u8(option, len, &lease->ttl, 1); + case DHCP_OPTION_STATIC_ROUTE: + r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); + if (r < 0) + log_debug_errno(r, "Failed to parse static routes, ignoring: %m"); break; - case DHCP_OPTION_BOOT_FILE_SIZE: - lease_parse_u16(option, len, &lease->boot_file_size, 0); + case DHCP_OPTION_INTERFACE_MTU: + r = lease_parse_u16(option, len, &lease->mtu, 68); + if (r < 0) + log_debug_errno(r, "Failed to parse MTU, ignoring: %m"); break; case DHCP_OPTION_DOMAIN_NAME: { _cleanup_free_ char *domainname = NULL, *normalized = NULL; r = lease_parse_string(option, len, &domainname); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Failed to parse domain name, ignoring: %m"); + return 0; + } r = dns_name_normalize(domainname, &normalized); if (r < 0) { @@ -531,12 +553,14 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void _cleanup_free_ char *hostname = NULL, *normalized = NULL; r = lease_parse_string(option, len, &hostname); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Failed to parse host name, ignoring: %m"); + return 0; + } r = dns_name_normalize(hostname, &normalized); if (r < 0) { - log_debug_errno(r, "Failed to normalize host name '%s': %m", hostname); + log_debug_errno(r, "Failed to normalize host name '%s', ignoring: %m", hostname); return 0; } @@ -553,80 +577,97 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void } case DHCP_OPTION_ROOT_PATH: - return lease_parse_string(option, len, &lease->root_path); + r = lease_parse_string(option, len, &lease->root_path); + if (r < 0) + log_debug_errno(r, "Failed to parse root path, ignoring: %m"); + break; case DHCP_OPTION_RENEWAL_T1_TIME: - lease_parse_u32(option, len, &lease->t1, 1); + r = lease_parse_u32(option, len, &lease->t1, 1); + if (r < 0) + log_debug_errno(r, "Failed to parse T1 time, ignoring: %m"); break; case DHCP_OPTION_REBINDING_T2_TIME: - lease_parse_u32(option, len, &lease->t2, 1); - break; - - case DHCP_OPTION_ENABLE_IP_FORWARDING: - lease_parse_bool(option, len, &lease->ip_forward); - break; - - case DHCP_OPTION_ENABLE_IP_FORWARDING_NL: - lease_parse_bool(option, len, &lease->ip_forward_non_local); + r = lease_parse_u32(option, len, &lease->t2, 1); + if (r < 0) + log_debug_errno(r, "Failed to parse T2 time, ignoring: %m"); break; case DHCP_OPTION_CLASSLESS_STATIC_ROUTE: - return lease_parse_classless_routes( + r = lease_parse_classless_routes( option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); + if (r < 0) + log_debug_errno(r, "Failed to parse classless routes, ignoring: %m"); + break; case DHCP_OPTION_NEW_TZDB_TIMEZONE: { _cleanup_free_ char *tz = NULL; r = lease_parse_string(option, len, &tz); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Failed to parse timezone option, ignoring: %m"); + return 0; + } - if (!timezone_is_valid(tz)) - return -EINVAL; + if (!timezone_is_valid(tz)) { + log_debug_errno(r, "Timezone is not valid, ignoring: %m"); + return 0; + } free(lease->timezone); lease->timezone = tz; tz = NULL; + break; } case DHCP_OPTION_VENDOR_SPECIFIC: - if (len >= 1) { - free(lease->vendor_specific); - lease->vendor_specific = memdup(option, len); - if (!lease->vendor_specific) + if (len <= 0) + lease->vendor_specific = mfree(lease->vendor_specific); + else { + void *p; + + p = memdup(option, len); + if (!p) return -ENOMEM; - lease->vendor_specific_len = len; - } - break; + free(lease->vendor_specific); + lease->vendor_specific = p; + } - default: - if (code < DHCP_OPTION_PRIVATE_BASE || code > DHCP_OPTION_PRIVATE_LAST) - break; + lease->vendor_specific_len = len; + break; + case DHCP_OPTION_PRIVATE_BASE ... DHCP_OPTION_PRIVATE_LAST: r = dhcp_lease_insert_private_option(lease, code, option, len); if (r < 0) return r; + + break; + + default: + log_debug("Ignoring option DHCP option %i while parsing.", code); + break; } return 0; } -int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, - const void *data, uint8_t len) { +int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) { struct sd_dhcp_raw_option *cur, *option; + assert(lease); + LIST_FOREACH(options, cur, lease->private_options) { if (tag < cur->tag) break; - else if (tag == cur->tag) { - log_error("Ignoring duplicate option, tagged %d.", tag); + if (tag == cur->tag) { + log_debug("Ignoring duplicate option, tagged %i.", tag); return 0; } } @@ -644,7 +685,6 @@ int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, } LIST_INSERT_BEFORE(options, lease->private_options, cur, option); - return 0; } @@ -657,7 +697,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) { lease->router = INADDR_ANY; lease->n_ref = 1; - LIST_HEAD_INIT(lease->private_options); *ret = lease; return 0; @@ -674,6 +713,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { const char *string; uint16_t mtu; struct sd_dhcp_route *routes; + uint32_t t1, t2, lifetime; int r; assert(lease); @@ -685,19 +725,16 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { fchmod(fileno(f), 0644); - r = sd_dhcp_lease_get_address(lease, &address); - if (r < 0) - goto fail; - fprintf(f, - "# This is private data. Do not parse.\n" - "ADDRESS=%s\n", inet_ntoa(address)); + "# This is private data. Do not parse.\n"); - r = sd_dhcp_lease_get_netmask(lease, &address); - if (r < 0) - goto fail; + r = sd_dhcp_lease_get_address(lease, &address); + if (r >= 0) + fprintf(f, "ADDRESS=%s\n", inet_ntoa(address)); - fprintf(f, "NETMASK=%s\n", inet_ntoa(address)); + r = sd_dhcp_lease_get_netmask(lease, &address); + if (r >= 0) + fprintf(f, "NETMASK=%s\n", inet_ntoa(address)); r = sd_dhcp_lease_get_router(lease, &address); if (r >= 0) @@ -705,28 +742,45 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { r = sd_dhcp_lease_get_server_identifier(lease, &address); if (r >= 0) - fprintf(f, "SERVER_ADDRESS=%s\n", - inet_ntoa(address)); + fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntoa(address)); r = sd_dhcp_lease_get_next_server(lease, &address); if (r >= 0) fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address)); + r = sd_dhcp_lease_get_broadcast(lease, &address); + if (r >= 0) + fprintf(f, "BROADCAST=%s\n", inet_ntoa(address)); + r = sd_dhcp_lease_get_mtu(lease, &mtu); if (r >= 0) fprintf(f, "MTU=%" PRIu16 "\n", mtu); - fputs("DNS=", f); - r = sd_dhcp_lease_get_dns(lease, &addresses); + r = sd_dhcp_lease_get_t1(lease, &t1); + if (r >= 0) + fprintf(f, "T1=%" PRIu32 "\n", t1); + + r = sd_dhcp_lease_get_t2(lease, &t2); if (r >= 0) + fprintf(f, "T2=%" PRIu32 "\n", t2); + + r = sd_dhcp_lease_get_lifetime(lease, &lifetime); + if (r >= 0) + fprintf(f, "LIFETIME=%" PRIu32 "\n", lifetime); + + r = sd_dhcp_lease_get_dns(lease, &addresses); + if (r > 0) { + fputs("DNS=", f); serialize_in_addrs(f, addresses, r); - fputs("\n", f); + fputs("\n", f); + } - fputs("NTP=", f); r = sd_dhcp_lease_get_ntp(lease, &addresses); - if (r >= 0) + if (r > 0) { + fputs("NTP=", f); serialize_in_addrs(f, addresses, r); - fputs("\n", f); + fputs("\n", f); + } r = sd_dhcp_lease_get_domainname(lease, &string); if (r >= 0) @@ -741,7 +795,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { fprintf(f, "ROOT_PATH=%s\n", string); r = sd_dhcp_lease_get_routes(lease, &routes); - if (r >= 0) + if (r > 0) serialize_dhcp_routes(f, "ROUTES", routes, r); r = sd_dhcp_lease_get_timezone(lease, &string); @@ -774,6 +828,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { LIST_FOREACH(options, option, lease->private_options) { char key[strlen("OPTION_000")+1]; + snprintf(key, sizeof(key), "OPTION_%"PRIu8, option->tag); r = serialize_dhcp_option(f, key, option->data, option->length); if (r < 0) @@ -799,15 +854,26 @@ fail: } int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { + _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; - _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL, - *server_address = NULL, *next_server = NULL, - *dns = NULL, *ntp = NULL, *mtu = NULL, - *routes = NULL, *client_id_hex = NULL, - *vendor_specific_hex = NULL, - *options[DHCP_OPTION_PRIVATE_LAST - - DHCP_OPTION_PRIVATE_BASE + 1] = { NULL }; - struct in_addr addr; + _cleanup_free_ char + *address = NULL, + *router = NULL, + *netmask = NULL, + *server_address = NULL, + *next_server = NULL, + *broadcast = NULL, + *dns = NULL, + *ntp = NULL, + *mtu = NULL, + *routes = NULL, + *client_id_hex = NULL, + *vendor_specific_hex = NULL, + *lifetime = NULL, + *t1 = NULL, + *t2 = NULL, + *options[DHCP_OPTION_PRIVATE_LAST - DHCP_OPTION_PRIVATE_BASE + 1] = {}; + int r, i; assert(lease_file); @@ -823,6 +889,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "NETMASK", &netmask, "SERVER_IDENTIFIER", &server_address, "NEXT_SERVER", &next_server, + "BROADCAST", &broadcast, "DNS", &dns, "NTP", &ntp, "MTU", &mtu, @@ -833,6 +900,9 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "CLIENTID", &client_id_hex, "TIMEZONE", &lease->timezone, "VENDOR_SPECIFIC", &vendor_specific_hex, + "LIFETIME", &lifetime, + "T1", &t1, + "T2", &t2, "OPTION_224", &options[0], "OPTION_225", &options[1], "OPTION_226", &options[2], @@ -865,88 +935,109 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "OPTION_253", &options[29], "OPTION_254", &options[30], NULL); - if (r < 0) { - if (r == -ENOENT) - return 0; - - return log_error_errno(r, "Failed to read %s: %m", lease_file); - } - - r = inet_pton(AF_INET, address, &addr); if (r < 0) return r; - lease->address = addr.s_addr; + if (address) { + r = inet_pton(AF_INET, address, &lease->address); + if (r <= 0) + log_debug_errno(errno, "Failed to parse address %s, ignoring: %m", address); + } if (router) { - r = inet_pton(AF_INET, router, &addr); - if (r < 0) - return r; - - lease->router = addr.s_addr; + r = inet_pton(AF_INET, router, &lease->router); + if (r <= 0) + log_debug_errno(errno, "Failed to parse router %s, ignoring: %m", router); } - r = inet_pton(AF_INET, netmask, &addr); - if (r < 0) - return r; - - lease->subnet_mask = addr.s_addr; + if (netmask) { + r = inet_pton(AF_INET, netmask, &lease->subnet_mask); + if (r <= 0) + log_debug_errno(errno, "Failed to parse netmask %s, ignoring: %m", netmask); + else + lease->have_subnet_mask = true; + } if (server_address) { - r = inet_pton(AF_INET, server_address, &addr); - if (r < 0) - return r; - - lease->server_address = addr.s_addr; + r = inet_pton(AF_INET, server_address, &lease->server_address); + if (r <= 0) + log_debug_errno(errno, "Failed to parse netmask %s, ignoring: %m", server_address); } if (next_server) { - r = inet_pton(AF_INET, next_server, &addr); - if (r < 0) - return r; + r = inet_pton(AF_INET, next_server, &lease->next_server); + if (r <= 0) + log_debug_errno(errno, "Failed to parse next server %s, ignoring: %m", next_server); + } - lease->next_server = addr.s_addr; + if (broadcast) { + r = inet_pton(AF_INET, broadcast, &lease->broadcast); + if (r <= 0) + log_debug_errno(errno, "Failed to parse broadcast address %s, ignoring: %m", broadcast); + else + lease->have_broadcast = true; } if (dns) { r = deserialize_in_addrs(&lease->dns, dns); if (r < 0) - return r; - - lease->dns_size = r; + log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns); + else + lease->dns_size = r; } if (ntp) { r = deserialize_in_addrs(&lease->ntp, ntp); if (r < 0) - return r; - - lease->ntp_size = r; + log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp); + else + lease->ntp_size = r; } if (mtu) { - uint16_t u; - if (sscanf(mtu, "%" SCNu16, &u) > 0) - lease->mtu = u; + r = safe_atou16(mtu, &lease->mtu); + if (r < 0) + log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu); } if (routes) { - r = deserialize_dhcp_routes(&lease->static_route, &lease->static_route_size, - &lease->static_route_allocated, routes); + r = deserialize_dhcp_routes( + &lease->static_route, + &lease->static_route_size, + &lease->static_route_allocated, + routes); + if (r < 0) + log_debug_errno(r, "Failed to parse DHCP routes %s, ignoring: %m", routes); + } + + if (lifetime) { + r = safe_atou32(lifetime, &lease->lifetime); + if (r < 0) + log_debug_errno(r, "Failed to parse lifetime %s, ignoring: %m", lifetime); + } + + if (t1) { + r = safe_atou32(t1, &lease->t1); + if (r < 0) + log_debug_errno(r, "Failed to parse T1 %s, ignoring: %m", t1); + } + + if (t2) { + r = safe_atou32(t2, &lease->t2); if (r < 0) - return r; + log_debug_errno(r, "Failed to parse T2 %s, ignoring: %m", t2); } if (client_id_hex) { r = deserialize_dhcp_option(&lease->client_id, &lease->client_id_len, client_id_hex); if (r < 0) - return r; + log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex); } if (vendor_specific_hex) { r = deserialize_dhcp_option(&lease->vendor_specific, &lease->vendor_specific_len, vendor_specific_hex); if (r < 0) - return r; + log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex); } for (i = 0; i <= DHCP_OPTION_PRIVATE_LAST - DHCP_OPTION_PRIVATE_BASE; i++) { @@ -957,8 +1048,10 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { continue; r = deserialize_dhcp_option(&data, &len, options[i]); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i]); + continue; + } r = dhcp_lease_insert_private_option(lease, DHCP_OPTION_PRIVATE_BASE + i, data, len); if (r < 0) @@ -972,12 +1065,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { } int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { - struct in_addr address; - struct in_addr mask; + struct in_addr address, mask; int r; assert(lease); + if (lease->address == 0) + return -ENODATA; + address.s_addr = lease->address; /* fall back to the default subnet masks based on address class */ @@ -986,33 +1081,40 @@ int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { return r; lease->subnet_mask = mask.s_addr; + lease->have_subnet_mask = true; return 0; } -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, - size_t *client_id_len) { +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) { assert_return(lease, -EINVAL); assert_return(client_id, -EINVAL); assert_return(client_id_len, -EINVAL); + if (!lease->client_id) + return -ENODATA; + *client_id = lease->client_id; *client_id_len = lease->client_id_len; + return 0; } -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, - size_t client_id_len) { +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len) { assert_return(lease, -EINVAL); - assert_return((!client_id && !client_id_len) || - (client_id && client_id_len), -EINVAL); + assert_return(client_id || client_id_len <= 0, -EINVAL); + + if (client_id_len <= 0) + lease->client_id = mfree(lease->client_id); + else { + void *p; - free (lease->client_id); - lease->client_id = NULL; - lease->client_id_len = 0; + p = memdup(client_id, client_id_len); + if (!p) + return -ENOMEM; - if (client_id) { - lease->client_id = memdup (client_id, client_id_len); + free(lease->client_id); + lease->client_id = p; lease->client_id_len = client_id_len; } @@ -1024,7 +1126,7 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone) { assert_return(timezone, -EINVAL); if (!lease->timezone) - return -ENXIO; + return -ENODATA; *timezone = lease->timezone; return 0; diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 7fa126d198..ed5bceecdd 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -34,6 +34,9 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease); int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime); +int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1); +int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2); +int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr); @@ -45,10 +48,8 @@ int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname); int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path); int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes); -int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, - size_t *data_len); -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, - size_t *client_id_len); +int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len); +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); #endif -- cgit v1.2.3-54-g00ecf From 4b7b5abb785c03cb880e3a8a7a724d7de6e9cf3b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 01:14:20 +0200 Subject: dhcp: NTP servers should be requested by networkd but not implicitly by sd-dhcp The library so far always requested the NTP servers. This might be unnecessary in some uses, hence let's move the request into networkd instead. --- src/libsystemd-network/sd-dhcp-client.c | 1 - src/libsystemd-network/test-dhcp-client.c | 5 +---- src/network/networkd-dhcp4.c | 6 +++++- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 29c67f23be..008b21c3b8 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -105,7 +105,6 @@ static const uint8_t default_req_opts[] = { DHCP_OPTION_HOST_NAME, DHCP_OPTION_DOMAIN_NAME, DHCP_OPTION_DOMAIN_NAME_SERVER, - DHCP_OPTION_NTP_SERVER, }; static int client_receive_message_raw(sd_event_source *s, int fd, diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index b2a0d3bb8b..877adc7b0d 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -87,10 +87,7 @@ static void test_request_basic(sd_event *e) assert_se(sd_dhcp_client_set_request_option(client, DHCP_OPTION_DOMAIN_NAME) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, - DHCP_OPTION_DOMAIN_NAME_SERVER) - == -EEXIST); - assert_se(sd_dhcp_client_set_request_option(client, - DHCP_OPTION_NTP_SERVER) == -EEXIST); + DHCP_OPTION_DOMAIN_NAME_SERVER) == -EEXIST); assert_se(sd_dhcp_client_set_request_option(client, DHCP_OPTION_PAD) == -EINVAL); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 7fce389fa2..ea1b18a0e5 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -624,7 +624,11 @@ int dhcp4_configure(Link *link) { return r; } - /* Always acquire the timezone */ + /* Always acquire the timezone and NTP*/ + r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NTP_SERVER); + if (r < 0) + return r; + r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NEW_TZDB_TIMEZONE); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From 586ac6f711e2eccceb12421df22fca4f117226c4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 01:47:42 +0200 Subject: networkd: make DHCP lease timeouts configurable --- src/libsystemd-network/dhcp-server-internal.h | 4 +++- src/libsystemd-network/sd-dhcp-server.c | 34 +++++++++++++++++++++++---- src/network/networkd-link.c | 16 +++++++++++++ src/network/networkd-network-gperf.gperf | 2 ++ src/network/networkd.h | 1 + src/systemd/sd-dhcp-server.h | 3 +++ 6 files changed, 55 insertions(+), 5 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 74b09d6f37..4f562c73ef 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -65,6 +65,8 @@ struct sd_dhcp_server { Hashmap *leases_by_client_id; DHCPLease **bound_leases; + + uint32_t max_lease_time, default_lease_time; }; typedef struct DHCPRequest { @@ -76,7 +78,7 @@ typedef struct DHCPRequest { size_t max_optlen; be32_t server_id; be32_t requested_ip; - int lifetime; + uint32_t lifetime; } DHCPRequest; DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref); diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index bfb799a63d..35564d8317 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -28,7 +28,8 @@ #include "dhcp-server-internal.h" #include "dhcp-internal.h" -#define DHCP_DEFAULT_LEASE_TIME 3600 /* one hour */ +#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR +#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12) int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *address, @@ -172,6 +173,8 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) { server->netmask = htobe32(INADDR_ANY); server->ifindex = ifindex; server->leases_by_client_id = hashmap_new(&client_id_hash_ops); + server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC); + server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC); *ret = server; server = NULL; @@ -598,7 +601,7 @@ static void dhcp_request_free(DHCPRequest *req) { DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free); #define _cleanup_dhcp_request_free_ _cleanup_(dhcp_request_freep) -static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) { +static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) { assert(req); assert(message); @@ -624,7 +627,10 @@ static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) { req->max_optlen = DHCP_MIN_OPTIONS_SIZE; if (req->lifetime <= 0) - req->lifetime = DHCP_DEFAULT_LEASE_TIME; + req->lifetime = MAX(1ULL, server->default_lease_time); + + if (server->max_lease_time > 0 && req->lifetime > server->max_lease_time) + req->lifetime = server->max_lease_time; return 0; } @@ -665,7 +671,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, if (type < 0) return 0; - r = ensure_sane_request(req, message); + r = ensure_sane_request(server, req, message); if (r < 0) /* this only fails on critical errors */ return r; @@ -1016,3 +1022,23 @@ int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone) { return 1; } + +int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t) { + assert_return(server, -EINVAL); + + if (t == server->max_lease_time) + return 0; + + server->max_lease_time = t; + return 1; +} + +int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) { + assert_return(server, -EINVAL); + + if (t == server->default_lease_time) + return 0; + + server->default_lease_time = t; + return 1; +} diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 09c27de22b..5b7ebfb79d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -673,6 +673,22 @@ static int link_enter_set_addresses(Link *link) { return r; */ + if (link->network->dhcp_server_max_lease_time_usec > 0) { + r = sd_dhcp_server_set_max_lease_time( + link->dhcp_server, + DIV_ROUND_UP(link->network->dhcp_server_max_lease_time_usec, USEC_PER_SEC)); + if (r < 0) + return r; + } + + if (link->network->dhcp_server_default_lease_time_usec > 0) { + r = sd_dhcp_server_set_default_lease_time( + link->dhcp_server, + DIV_ROUND_UP(link->network->dhcp_server_default_lease_time_usec, USEC_PER_SEC)); + if (r < 0) + return r; + } + if (link->network->dhcp_server_emit_timezone) { _cleanup_free_ char *buffer = NULL; const char *tz; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c8c612d4eb..21e33efb42 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -74,6 +74,8 @@ DHCP.CriticalConnection, config_parse_bool, 0 DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_timezone) +DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec) +DHCPServer.DefaultLeaseTimeSec,config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec) DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) diff --git a/src/network/networkd.h b/src/network/networkd.h index a337ea7bf0..d5da764bab 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -152,6 +152,7 @@ struct Network { bool dhcp_server; char *dhcp_server_timezone; bool dhcp_server_emit_timezone; + usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec; bool use_bpdu; bool hairpin; diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index a2e1995cf9..e070174a88 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -49,5 +49,8 @@ int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone); +int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t); +int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t); + int sd_dhcp_server_forcerenew(sd_dhcp_server *server); #endif -- cgit v1.2.3-54-g00ecf From fbcd420aa407dc3c16efd9fb32cbae6d04d4f65d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 01:59:43 +0200 Subject: dhcp: don't underflow in lease time calculations Don't underflow when calculating lease time. --- src/libsystemd-network/sd-dhcp-client.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 008b21c3b8..c12768cf0e 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1163,13 +1163,17 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, return r; } -static uint64_t client_compute_timeout(sd_dhcp_client *client, - uint32_t lifetime, double factor) { +static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) { assert(client); assert(client->request_sent); - assert(lifetime); + assert(lifetime > 0); - return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) + + if (lifetime > 3) + lifetime -= 3; + else + lifetime = 0; + + return client->request_sent + (lifetime * USEC_PER_SEC * factor) + + (random_u32() & 0x1fffff); } @@ -1201,7 +1205,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { /* convert the various timeouts from relative (secs) to absolute (usecs) */ lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1); - if (client->lease->t1 && client->lease->t2) { + if (client->lease->t1 > 0 && client->lease->t2 > 0) { /* both T1 and T2 are given */ if (client->lease->t1 < client->lease->t2 && client->lease->t2 < client->lease->lifetime) { @@ -1215,7 +1219,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); client->lease->t1 = client->lease->lifetime / 2; } - } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) { + } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) { /* only T2 is given, and it is valid */ t2_timeout = client_compute_timeout(client, client->lease->t2, 1); t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); @@ -1225,7 +1229,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); client->lease->t2 = (client->lease->lifetime * 7) / 8; } - } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) { + } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) { /* only T1 is given, and it is valid */ t1_timeout = client_compute_timeout(client, client->lease->t1, 1); t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); -- cgit v1.2.3-54-g00ecf From 1a04db0fc9d08fffe80d6d7b5b60459295922b11 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 14:48:37 +0200 Subject: dhcp,network: support emitting DNS/NTP server information from DHCP server For now, this is very simple and IP addresses have to be configured manually. --- src/libsystemd-network/dhcp-server-internal.h | 3 + src/libsystemd-network/sd-dhcp-server.c | 72 ++++++++++++++++++++ src/network/networkd-link.c | 21 ++++++ src/network/networkd-network-gperf.gperf | 4 ++ src/network/networkd-network.c | 96 +++++++++++++++++++++++++++ src/network/networkd-network.h | 10 ++- src/systemd/sd-dhcp-server.h | 7 +- 7 files changed, 210 insertions(+), 3 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 4f562c73ef..6cc794c937 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -63,6 +63,9 @@ struct sd_dhcp_server { char *timezone; + struct in_addr *ntp, *dns; + unsigned n_ntp, n_dns; + Hashmap *leases_by_client_id; DHCPLease **bound_leases; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 35564d8317..a46858258b 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -145,6 +145,8 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) { sd_event_unref(server->event); free(server->timezone); + free(server->dns); + free(server->ntp); while ((lease = hashmap_steal_first(server->leases_by_client_id))) dhcp_lease_free(lease); @@ -481,6 +483,24 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req, if (r < 0) return r; + if (server->n_dns > 0) { + r = dhcp_option_append( + &packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_DOMAIN_NAME_SERVER, + sizeof(struct in_addr) * server->n_dns, server->dns); + if (r < 0) + return r; + } + + if (server->n_ntp > 0) { + r = dhcp_option_append( + &packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_NTP_SERVER, + sizeof(struct in_addr) * server->n_ntp, server->ntp); + if (r < 0) + return r; + } + if (server->timezone) { r = dhcp_option_append( &packet->dhcp, req->max_optlen, &offset, 0, @@ -1042,3 +1062,55 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) { server->default_lease_time = t; return 1; } + +int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) { + assert_return(server, -EINVAL); + assert_return(dns || n <= 0, -EINVAL); + + if (server->n_dns == n && + memcmp(server->dns, dns, sizeof(struct in_addr) * n) == 0) + return 0; + + if (n <= 0) { + server->dns = mfree(server->dns); + server->n_dns = 0; + } else { + struct in_addr *c; + + c = newdup(struct in_addr, dns, n); + if (!c) + return -ENOMEM; + + free(server->dns); + server->dns = c; + server->n_dns = n; + } + + return 1; +} + +int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) { + assert_return(server, -EINVAL); + assert_return(ntp || n <= 0, -EINVAL); + + if (server->n_ntp == n && + memcmp(server->ntp, ntp, sizeof(struct in_addr) * n) == 0) + return 0; + + if (n <= 0) { + server->ntp = mfree(server->ntp); + server->n_ntp = 0; + } else { + struct in_addr *c; + + c = newdup(struct in_addr, ntp, n); + if (!c) + return -ENOMEM; + + free(server->ntp); + server->ntp = c; + server->n_ntp = n; + } + + return 1; +} diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 0a72c14469..0d85005c8c 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -691,6 +691,27 @@ static int link_enter_set_addresses(Link *link) { return r; } + if (link->network->dhcp_server_emit_dns) { + + if (link->network->n_dhcp_server_dns > 0) { + r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns); + if (r < 0) + log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m"); + } else + log_link_warning_errno(link, r, "DNS server emitting enabled, but no DNS servers set, ignoring: %m"); + } + + + if (link->network->dhcp_server_emit_ntp) { + + if (link->network->n_dhcp_server_ntp > 0) { + r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp); + if (r < 0) + log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m"); + } else + log_link_warning_errno(link, r, "NTP server emitting enabled, but no NTP servers set, ignoring: %m"); + } + if (link->network->dhcp_server_emit_timezone) { _cleanup_free_ char *buffer = NULL; const char *tz; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 21e33efb42..108e892fb8 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -76,6 +76,10 @@ DHCP.RouteMetric, config_parse_unsigned, 0 DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_timezone) DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec) DHCPServer.DefaultLeaseTimeSec,config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec) +DHCPServer.EmitDNS, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_dns) +DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0 +DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp) +DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0 DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 11671b500d..848ec66151 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -260,6 +260,8 @@ void network_free(Network *network) { condition_free_list(network->match_arch); free(network->dhcp_server_timezone); + free(network->dhcp_server_dns); + free(network->dhcp_server_ntp); free(network); } @@ -802,3 +804,97 @@ int config_parse_timezone( return 0; } + +int config_parse_dhcp_server_dns( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = data; + const char *p = rvalue; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + for (;;) { + _cleanup_free_ char *w = NULL; + struct in_addr a, *m; + + r = extract_first_word(&p, &w, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue); + return 0; + } + + if (r == 0) + return 0; + + if (inet_pton(AF_INET, w, &a) <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server address, ignoring: %s", w); + continue; + } + + m = realloc(n->dhcp_server_dns, (n->n_dhcp_server_dns + 1) * sizeof(struct in_addr)); + if (!m) + return log_oom(); + + m[n->n_dhcp_server_dns++] = a; + n->dhcp_server_dns = m; + } +} + +int config_parse_dhcp_server_ntp( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = data; + const char *p = rvalue; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + for (;;) { + _cleanup_free_ char *w = NULL; + struct in_addr a, *m; + + r = extract_first_word(&p, &w, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, r, line, "Failed to extract word, ignoring: %s", rvalue); + return 0; + } + + if (r == 0) + return 0; + + if (inet_pton(AF_INET, w, &a) <= 0) { + log_syntax(unit, LOG_ERR, filename, r, line, "Failed to parse NTP server address, ignoring: %s", w); + continue; + } + + m = realloc(n->dhcp_server_ntp, (n->n_dhcp_server_ntp + 1) * sizeof(struct in_addr)); + if (!m) + return log_oom(); + + m[n->n_dhcp_server_ntp++] = a; + n->dhcp_server_ntp = m; + } +} diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 7d2add300f..d691cc3a45 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -93,8 +93,14 @@ struct Network { /* DHCP Server Support */ bool dhcp_server; - char *dhcp_server_timezone; + bool dhcp_server_emit_dns; + struct in_addr *dhcp_server_dns; + unsigned n_dhcp_server_dns; + bool dhcp_server_emit_ntp; + struct in_addr *dhcp_server_ntp; + unsigned n_dhcp_server_ntp; bool dhcp_server_emit_timezone; + char *dhcp_server_timezone; usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec; /* IPV4LL Support */ @@ -156,6 +162,8 @@ int config_parse_ipv6token(const char *unit, const char *filename, unsigned line int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_timezone(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_dhcp_server_dns(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_dhcp_server_ntp(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); /* Legacy IPv4LL support */ int config_parse_ipv4ll(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index e070174a88..7e4f2ffb30 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -30,11 +30,11 @@ typedef struct sd_dhcp_server sd_dhcp_server; +int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex); + sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server); sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server); -int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex); - int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int priority); int sd_dhcp_server_detach_event(sd_dhcp_server *client); sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client); @@ -48,9 +48,12 @@ int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, size_t size); int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone); +int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n); +int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n); int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t); int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t); int sd_dhcp_server_forcerenew(sd_dhcp_server *server); + #endif -- cgit v1.2.3-54-g00ecf From 52efd56a6369e19c2400a42981a197cd2eef924a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 17:48:24 +0200 Subject: tree-wide: we place the opening bracket on the same line as the function name Let's do this everywhere the same way. --- src/basic/ring.h | 3 +-- src/boot/efi/boot.c | 15 ++++------- src/libsystemd-network/dhcp6-network.c | 6 ++--- src/libsystemd-network/dhcp6-option.c | 4 +-- src/libsystemd-network/sd-dhcp6-lease.c | 3 +-- src/libsystemd-network/sd-icmp6-nd.c | 15 +++-------- src/libsystemd-network/test-dhcp-client.c | 42 ++++++++++++------------------ src/libsystemd-network/test-dhcp6-client.c | 3 +-- src/libsystemd/sd-hwdb/sd-hwdb.c | 13 +++++---- 9 files changed, 37 insertions(+), 67 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/basic/ring.h b/src/basic/ring.h index a7c44d1b56..dbd6296384 100644 --- a/src/basic/ring.h +++ b/src/basic/ring.h @@ -50,7 +50,6 @@ int ring_push(Ring *r, const void *u8, size_t size); void ring_pull(Ring *r, size_t size); /* return size of occupied buffer in bytes */ -static inline size_t ring_get_size(Ring *r) -{ +static inline size_t ring_get_size(Ring *r) { return r->used; } diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 4ac193e22a..38b79da886 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -70,16 +70,14 @@ typedef struct { BOOLEAN no_editor; } Config; -static VOID cursor_left(UINTN *cursor, UINTN *first) -{ +static VOID cursor_left(UINTN *cursor, UINTN *first) { if ((*cursor) > 0) (*cursor)--; else if ((*first) > 0) (*first)--; } -static VOID cursor_right(UINTN *cursor, UINTN *first, UINTN x_max, UINTN len) -{ +static VOID cursor_right(UINTN *cursor, UINTN *first, UINTN x_max, UINTN len) { if ((*cursor)+1 < x_max) (*cursor)++; else if ((*first) + (*cursor) < len) @@ -856,13 +854,11 @@ static VOID config_entry_free(ConfigEntry *entry) { FreePool(entry->options); } -static BOOLEAN is_digit(CHAR16 c) -{ +static BOOLEAN is_digit(CHAR16 c) { return (c >= '0') && (c <= '9'); } -static UINTN c_order(CHAR16 c) -{ +static UINTN c_order(CHAR16 c) { if (c == '\0') return 0; if (is_digit(c)) @@ -873,8 +869,7 @@ static UINTN c_order(CHAR16 c) return c + 0x10000; } -static INTN str_verscmp(CHAR16 *s1, CHAR16 *s2) -{ +static INTN str_verscmp(CHAR16 *s1, CHAR16 *s2) { CHAR16 *os1 = s1; CHAR16 *os2 = s2; diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c index fe56c10273..187975364b 100644 --- a/src/libsystemd-network/dhcp6-network.c +++ b/src/libsystemd-network/dhcp6-network.c @@ -41,8 +41,7 @@ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } -int dhcp_network_icmp6_bind_router_solicitation(int index) -{ +int dhcp_network_icmp6_bind_router_solicitation(int index) { struct icmp6_filter filter = { }; struct ipv6_mreq mreq = { .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, @@ -92,8 +91,7 @@ int dhcp_network_icmp6_bind_router_solicitation(int index) return r; } -int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) -{ +int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) { struct sockaddr_in6 dst = { .sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT, diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index 2fa4d5fac8..f41bebced0 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -338,9 +338,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, return count; } -int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, - char ***str_arr) -{ +int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) { size_t pos = 0, idx = 0; _cleanup_free_ char **names = NULL; int r; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index cf317408b7..f34af6eaba 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -247,8 +247,7 @@ int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains) { return -ENOENT; } -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 r; uint16_t subopt; size_t sublen; diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c index 2f867e8562..aac931f326 100644 --- a/src/libsystemd-network/sd-icmp6-nd.c +++ b/src/libsystemd-network/sd-icmp6-nd.c @@ -106,8 +106,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) { return 0; } -static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) -{ +static void icmp6_nd_notify(sd_icmp6_nd *nd, int event) { if (nd->callback) nd->callback(nd, event, nd->userdata); } @@ -376,9 +375,7 @@ int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr, return 0; } -int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, - uint8_t *prefixlen) -{ +int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr, uint8_t *prefixlen) { assert_return(nd, -EINVAL); assert_return(addr, -EINVAL); assert_return(prefixlen, -EINVAL); @@ -525,9 +522,7 @@ static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra, return 0; } -static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, - uint32_t revents, void *userdata) -{ +static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_icmp6_nd *nd = userdata; int r, buflen = 0; ssize_t len; @@ -586,9 +581,7 @@ static int icmp6_router_advertisment_recv(sd_event_source *s, int fd, return 0; } -static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, - void *userdata) -{ +static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec, void *userdata) { sd_icmp6_nd *nd = userdata; uint64_t time_now, next_timeout; struct ether_addr unset = { }; diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index 877adc7b0d..29c20b77e3 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -43,16 +43,13 @@ static test_callback_recv_t callback_recv; static be32_t xid; static sd_event_source *test_hangcheck; -static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, - void *userdata) -{ +static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) { assert_not_reached("Test case should have completed in 2 seconds"); return 0; } -static void test_request_basic(sd_event *e) -{ +static void test_request_basic(sd_event *e) { int r; sd_dhcp_client *client; @@ -109,8 +106,7 @@ static void test_request_basic(sd_event *e) sd_dhcp_client_unref(client); } -static void test_checksum(void) -{ +static void test_checksum(void) { uint8_t buf[20] = { 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -123,9 +119,7 @@ static void test_checksum(void) assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae)); } -static int check_options(uint8_t code, uint8_t len, const void *option, - void *userdata) -{ +static int check_options(uint8_t code, uint8_t len, const void *option, void *userdata) { switch(code) { case DHCP_OPTION_CLIENT_IDENTIFIER: { @@ -152,9 +146,7 @@ static int check_options(uint8_t code, uint8_t len, const void *option, return 0; } -int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, - const void *packet, size_t len) -{ +int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) { size_t size; _cleanup_free_ DHCPPacket *discover; uint16_t ip_check, udp_check; @@ -199,18 +191,20 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, return 575; } -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, - uint32_t id, const uint8_t *addr, - size_t addr_len, uint16_t arp_type) -{ +int dhcp_network_bind_raw_socket( + int index, + union sockaddr_union *link, + uint32_t id, + const uint8_t *addr, size_t addr_len, + uint16_t arp_type) { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0) return -errno; return test_fd[0]; } -int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) -{ +int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) { int fd; fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0); @@ -220,14 +214,11 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) return fd; } -int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, - const void *packet, size_t len) -{ +int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) { return 0; } -static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) -{ +static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) { int res; res = dhcp_option_parse(dhcp, size, check_options, NULL); @@ -239,8 +230,7 @@ static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) return 0; } -static void test_discover_message(sd_event *e) -{ +static void test_discover_message(sd_event *e) { sd_dhcp_client *client; int res, r; diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 6e62262443..12daac3211 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -501,8 +501,7 @@ static int test_client_verify_request(DHCP6Message *request, uint8_t *option, return 0; } -static int test_client_send_advertise(DHCP6Message *solicit) -{ +static int test_client_send_advertise(DHCP6Message *solicit) { DHCP6Message advertise; advertise.transaction_id = solicit->transaction_id; diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c index 40aa77ee5c..06c98314e8 100644 --- a/src/libsystemd/sd-hwdb/sd-hwdb.c +++ b/src/libsystemd/sd-hwdb/sd-hwdb.c @@ -79,8 +79,7 @@ static bool linebuf_add(struct linebuf *buf, const char *s, size_t len) { return true; } -static bool linebuf_add_char(struct linebuf *buf, char c) -{ +static bool linebuf_add_char(struct linebuf *buf, char c) { if (buf->len + 1 >= sizeof(buf->bytes)) return false; buf->bytes[buf->len++] = c; @@ -269,13 +268,13 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) { } static const char hwdb_bin_paths[] = - "/etc/systemd/hwdb/hwdb.bin\0" - "/etc/udev/hwdb.bin\0" - "/usr/lib/systemd/hwdb/hwdb.bin\0" + "/etc/systemd/hwdb/hwdb.bin\0" + "/etc/udev/hwdb.bin\0" + "/usr/lib/systemd/hwdb/hwdb.bin\0" #ifdef HAVE_SPLIT_USR - "/lib/systemd/hwdb/hwdb.bin\0" + "/lib/systemd/hwdb/hwdb.bin\0" #endif - UDEVLIBEXECDIR "/hwdb.bin\0"; + UDEVLIBEXECDIR "/hwdb.bin\0"; _public_ int sd_hwdb_new(sd_hwdb **ret) { _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL; -- cgit v1.2.3-54-g00ecf From 86514214e389f8b1ea3e5aecf9ae2e8d4d782798 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 19:55:29 +0200 Subject: dhcp: fix n_ref type Fixes fallout from 3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8. --- src/libsystemd-network/dhcp-lease-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index 95c2375d48..c6b97ca8f7 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -47,7 +47,7 @@ struct sd_dhcp_raw_option { }; struct sd_dhcp_lease { - int n_ref; + unsigned n_ref; /* each 0 if unset */ uint32_t t1; -- cgit v1.2.3-54-g00ecf From 9c8e3101ceef00342263d57dce3fa61956824985 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 19:56:52 +0200 Subject: network: get rid of more RefCnt usage A follow-up to 3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8 --- src/libsystemd-network/lldp-internal.c | 14 ++++----- src/libsystemd-network/lldp-internal.h | 3 +- src/libsystemd-network/sd-icmp6-nd.c | 56 +++++++++++++++++++++------------- src/libsystemd-network/sd-ipv4ll.c | 42 ++++++++++++++----------- src/libsystemd-network/sd-pppoe.c | 38 ++++++++++++++--------- 5 files changed, 92 insertions(+), 61 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/lldp-internal.c b/src/libsystemd-network/lldp-internal.c index 0f354461f7..3c04898e92 100644 --- a/src/libsystemd-network/lldp-internal.c +++ b/src/libsystemd-network/lldp-internal.c @@ -374,9 +374,8 @@ int lldp_mib_add_objects(Prioq *by_expiry, } /* Admission Control: Can this port attached to the existing chassis ? */ - if (REFCNT_GET(c->n_ref) >= LLDP_MIB_MAX_PORT_PER_CHASSIS) { - log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...", - REFCNT_GET(c->n_ref)); + if (c->n_ref >= LLDP_MIB_MAX_PORT_PER_CHASSIS) { + log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...", c->n_ref); c = NULL; goto drop; @@ -394,7 +393,7 @@ int lldp_mib_add_objects(Prioq *by_expiry, /* Attach new port to chassis */ LIST_PREPEND(port, c->ports, p); - REFCNT_INC(c->n_ref); + c->n_ref ++; p = NULL; c = NULL; @@ -424,7 +423,8 @@ void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p) { lldp_neighbour_port_free(p); /* Drop the Chassis if no port is attached */ - if (REFCNT_DEC(c->n_ref) <= 1) { + c->n_ref --; + if (c->n_ref <= 1) { hashmap_remove(c->neighbour_mib, &c->chassis_id); lldp_chassis_free(c); } @@ -486,7 +486,7 @@ void lldp_chassis_free(lldp_chassis *c) { if (!c) return; - if (REFCNT_GET(c->n_ref) > 1) + if (c->n_ref > 1) return; free(c->chassis_id.data); @@ -513,7 +513,7 @@ int lldp_chassis_new(tlv_packet *tlv, if (!c) return -ENOMEM; - c->n_ref = REFCNT_INIT; + c->n_ref = 1; c->chassis_id.type = type; c->chassis_id.length = length; diff --git a/src/libsystemd-network/lldp-internal.h b/src/libsystemd-network/lldp-internal.h index 8e09ee8f3a..f4eadbb87e 100644 --- a/src/libsystemd-network/lldp-internal.h +++ b/src/libsystemd-network/lldp-internal.h @@ -24,7 +24,6 @@ #include "log.h" #include "list.h" -#include "refcnt.h" #include "lldp-tlv.h" #include "prioq.h" @@ -63,7 +62,7 @@ struct lldp_chassis_id { }; struct lldp_chassis { - RefCount n_ref; + unsigned n_ref; lldp_chassis_id chassis_id; diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c index aac931f326..e80232a7e0 100644 --- a/src/libsystemd-network/sd-icmp6-nd.c +++ b/src/libsystemd-network/sd-icmp6-nd.c @@ -25,7 +25,6 @@ #include #include "socket-util.h" -#include "refcnt.h" #include "async.h" #include "dhcp6-internal.h" @@ -47,7 +46,7 @@ enum icmp6_nd_state { typedef struct ICMP6Prefix ICMP6Prefix; struct ICMP6Prefix { - RefCount n_ref; + unsigned n_ref; LIST_FIELDS(ICMP6Prefix, prefixes); @@ -57,7 +56,7 @@ struct ICMP6Prefix { }; struct sd_icmp6_nd { - RefCount n_ref; + unsigned n_ref; enum icmp6_nd_state state; sd_event *event; @@ -78,13 +77,18 @@ struct sd_icmp6_nd { #define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__) static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) { - if (prefix && REFCNT_DEC(prefix->n_ref) <= 0) { - prefix->timeout_valid = - sd_event_source_unref(prefix->timeout_valid); - free(prefix); - } + if (!prefix) + return NULL; + + assert(prefix->n_ref > 0); + prefix->n_ref--; + if (prefix->n_ref > 0) + return NULL; + + prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid); + free(prefix); return NULL; } @@ -97,7 +101,7 @@ static int icmp6_prefix_new(ICMP6Prefix **ret) { if (!prefix) return -ENOMEM; - prefix->n_ref = REFCNT_INIT; + prefix->n_ref = 1; LIST_INIT(prefixes, prefix); *ret = prefix; @@ -176,9 +180,12 @@ sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) { } sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) { - assert (nd); - assert_se(REFCNT_INC(nd->n_ref) >= 2); + if (!nd) + return NULL; + + assert(nd->n_ref > 0); + nd->n_ref++; return nd; } @@ -194,21 +201,28 @@ static int icmp6_nd_init(sd_icmp6_nd *nd) { } sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) { - if (nd && REFCNT_DEC(nd->n_ref) == 0) { - ICMP6Prefix *prefix, *p; + ICMP6Prefix *prefix, *p; - icmp6_nd_init(nd); - sd_icmp6_nd_detach_event(nd); + if (!nd) + return NULL; - LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { - LIST_REMOVE(prefixes, nd->prefixes, prefix); + assert(nd->n_ref > 0); + nd->n_ref--; - prefix = icmp6_prefix_unref(prefix); - } + if (nd->n_ref > 0) + return NULL; + + icmp6_nd_init(nd); + sd_icmp6_nd_detach_event(nd); - free(nd); + LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) { + LIST_REMOVE(prefixes, nd->prefixes, prefix); + + prefix = icmp6_prefix_unref(prefix); } + free(nd); + return NULL; } @@ -224,7 +238,7 @@ int sd_icmp6_nd_new(sd_icmp6_nd **ret) { if (!nd) return -ENOMEM; - nd->n_ref = REFCNT_INIT; + nd->n_ref = 1; nd->index = -1; nd->fd = -1; diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index f080c5c0a7..0fc05e1484 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -26,7 +26,6 @@ #include "util.h" #include "siphash24.h" #include "list.h" -#include "refcnt.h" #include "random-util.h" #include "ipv4ll-internal.h" @@ -68,7 +67,7 @@ typedef enum IPv4LLState { } IPv4LLState; struct sd_ipv4ll { - RefCount n_ref; + unsigned n_ref; IPv4LLState state; int index; @@ -598,30 +597,39 @@ int sd_ipv4ll_stop(sd_ipv4ll *ll) { } sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) { - if (ll) - assert_se(REFCNT_INC(ll->n_ref) >= 2); + + if (!ll) + return NULL; + + assert(ll->n_ref >= 1); + ll->n_ref++; return ll; } sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) { - if (ll && REFCNT_DEC(ll->n_ref) == 0) { - ll->receive_message = - sd_event_source_unref(ll->receive_message); - ll->fd = safe_close(ll->fd); - ll->timer = sd_event_source_unref(ll->timer); + if (!ll) + return NULL; - sd_ipv4ll_detach_event(ll); + assert(ll->n_ref >= 1); + ll->n_ref--; - free(ll->random_data); - free(ll->random_data_state); - free(ll); + if (ll->n_ref > 0) + return ll; - return NULL; - } + ll->receive_message = sd_event_source_unref(ll->receive_message); + ll->fd = safe_close(ll->fd); - return ll; + ll->timer = sd_event_source_unref(ll->timer); + + sd_ipv4ll_detach_event(ll); + + free(ll->random_data); + free(ll->random_data_state); + free(ll); + + return NULL; } DEFINE_TRIVIAL_CLEANUP_FUNC(sd_ipv4ll*, sd_ipv4ll_unref); @@ -636,7 +644,7 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) { if (!ll) return -ENOMEM; - ll->n_ref = REFCNT_INIT; + ll->n_ref = 1; ll->state = IPV4LL_STATE_INIT; ll->index = -1; ll->fd = -1; diff --git a/src/libsystemd-network/sd-pppoe.c b/src/libsystemd-network/sd-pppoe.c index ff064f563f..c6c9da812b 100644 --- a/src/libsystemd-network/sd-pppoe.c +++ b/src/libsystemd-network/sd-pppoe.c @@ -36,7 +36,6 @@ #include "random-util.h" #include "socket-util.h" #include "async.h" -#include "refcnt.h" #include "utf8.h" #define PPPOE_MAX_PACKET_SIZE 1484 @@ -68,7 +67,7 @@ typedef struct PPPoETags { } PPPoETags; struct sd_pppoe { - RefCount n_ref; + unsigned n_ref; PPPoEState state; uint64_t host_uniq; @@ -202,23 +201,34 @@ int sd_pppoe_detach_event(sd_pppoe *ppp) { } sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) { - if (ppp) - assert_se(REFCNT_INC(ppp->n_ref) >= 2); + + if (!ppp) + return NULL; + + assert(ppp->n_ref > 0); + ppp->n_ref++; return ppp; } sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) { - if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) { - pppoe_tags_clear(&ppp->tags); - free(ppp->ifname); - free(ppp->service_name); - sd_pppoe_stop(ppp); - sd_pppoe_detach_event(ppp); - - free(ppp); - } + if (!ppp) + return NULL; + + assert(ppp->n_ref > 0); + ppp->n_ref--; + + if (ppp->n_ref > 0) + return NULL; + + pppoe_tags_clear(&ppp->tags); + free(ppp->ifname); + free(ppp->service_name); + sd_pppoe_stop(ppp); + sd_pppoe_detach_event(ppp); + + free(ppp); return NULL; } @@ -231,7 +241,7 @@ int sd_pppoe_new (sd_pppoe **ret) { if (!ppp) return -ENOMEM; - ppp->n_ref = REFCNT_INIT; + ppp->n_ref = 1; ppp->state = _PPPOE_STATE_INVALID; ppp->ifindex = -1; ppp->fd = -1; -- cgit v1.2.3-54-g00ecf From e37d2c941f6493c2e3df1baead7f5565a256f4a2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2015 19:57:11 +0200 Subject: dhcp: say domain name, when we mean domain name --- src/libsystemd-network/sd-dhcp-lease.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libsystemd-network') diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 123ea68f19..6551e7c94c 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -538,7 +538,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void } if (is_localhost(normalized)) { - log_debug_errno(r, "Detected 'localhost' as suggested hostname, ignoring."); + log_debug_errno(r, "Detected 'localhost' as suggested domain name, ignoring."); break; } @@ -565,7 +565,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void } if (is_localhost(normalized)) { - log_debug_errno(r, "Detected 'localhost' as suggested hostname, ignoring."); + log_debug_errno(r, "Detected 'localhost' as suggested host name, ignoring."); return 0; } -- cgit v1.2.3-54-g00ecf