1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-27 10:25:37 +03:00

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
This commit is contained in:
Lennart Poettering 2015-08-27 01:05:13 +02:00
parent b3ec603ce8
commit 0339cd7707
4 changed files with 426 additions and 322 deletions

View File

@ -49,56 +49,60 @@ struct sd_dhcp_raw_option {
struct sd_dhcp_lease { struct sd_dhcp_lease {
int n_ref; int n_ref;
int32_t time_offset; /* each 0 if unset */
uint32_t t1; uint32_t t1;
uint32_t t2; uint32_t t2;
uint32_t lifetime; uint32_t lifetime;
uint32_t mtu_aging_timeout;
/* each 0 if unset */
be32_t address; be32_t address;
be32_t server_address; be32_t server_address;
be32_t subnet_mask;
be32_t router; be32_t router;
be32_t next_server; be32_t next_server;
bool have_subnet_mask;
be32_t subnet_mask;
bool have_broadcast;
be32_t broadcast; be32_t broadcast;
struct in_addr *dns; struct in_addr *dns;
size_t dns_size; size_t dns_size;
struct in_addr *ntp; struct in_addr *ntp;
size_t ntp_size; size_t ntp_size;
struct in_addr *policy_filter;
size_t policy_filter_size;
struct sd_dhcp_route *static_route; struct sd_dhcp_route *static_route;
size_t static_route_size; size_t static_route_size, static_route_allocated;
size_t static_route_allocated;
uint16_t boot_file_size; uint16_t mtu; /* 0 if unset */
uint16_t mdr;
uint16_t mtu;
uint8_t ttl;
bool ip_forward;
bool ip_forward_non_local;
char *domainname; char *domainname;
char *hostname; char *hostname;
char *root_path; char *root_path;
void *client_id; void *client_id;
size_t client_id_len; size_t client_id_len;
void *vendor_specific; void *vendor_specific;
size_t vendor_specific_len; size_t vendor_specific_len;
char *timezone; char *timezone;
LIST_HEAD(struct sd_dhcp_raw_option, private_options); LIST_HEAD(struct sd_dhcp_raw_option, private_options);
}; };
int dhcp_lease_new(sd_dhcp_lease **ret); 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_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, int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *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_default_subnet_mask(sd_dhcp_lease *lease);
int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len);
size_t client_id_len);
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_save(sd_dhcp_lease *lease, const char *lease_file);
int dhcp_lease_load(sd_dhcp_lease **ret, 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)

View File

@ -376,8 +376,7 @@ static int client_initialize(sd_dhcp_client *client) {
client->state = DHCP_STATE_INIT; client->state = DHCP_STATE_INIT;
client->xid = 0; client->xid = 0;
if (client->lease) client->lease = sd_dhcp_lease_unref(client->lease);
client->lease = sd_dhcp_lease_unref(client->lease);
return 0; return 0;
} }
@ -1054,18 +1053,16 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
} }
lease->next_server = offer->siaddr; lease->next_server = offer->siaddr;
lease->address = offer->yiaddr; lease->address = offer->yiaddr;
if (lease->address == INADDR_ANY || if (lease->address == 0 ||
lease->server_address == INADDR_ANY || lease->server_address == 0 ||
lease->lifetime == 0) { lease->lifetime == 0) {
log_dhcp_client(client, "received lease lacks address, server " log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
"address or lease lifetime, ignoring");
return -ENOMSG; return -ENOMSG;
} }
if (lease->subnet_mask == INADDR_ANY) { if (!lease->have_subnet_mask) {
r = dhcp_lease_set_default_subnet_mask(lease); r = dhcp_lease_set_default_subnet_mask(lease);
if (r < 0) { if (r < 0) {
log_dhcp_client(client, "received lease lacks subnet " log_dhcp_client(client, "received lease lacks subnet "

File diff suppressed because it is too large Load Diff

View File

@ -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_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_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_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_router(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_next_server(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_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_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_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
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_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); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
#endif #endif