/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
  Copyright © 2014-2015 Intel Corporation. All rights reserved.
***/

#include <errno.h>

#include "alloc-util.h"
#include "dhcp6-internal.h"
#include "dhcp6-lease-internal.h"
#include "strv.h"

#define IRT_DEFAULT (1 * USEC_PER_DAY)
#define IRT_MINIMUM (600 * USEC_PER_SEC)

static void dhcp6_lease_set_timestamp(sd_dhcp6_lease *lease, const triple_timestamp *timestamp) {
        assert(lease);

        if (timestamp && triple_timestamp_is_set(timestamp))
                lease->timestamp = *timestamp;
        else
                triple_timestamp_get(&lease->timestamp);
}

int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret) {
        assert_return(lease, -EINVAL);
        assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP);
        assert_return(clock_supported(clock), -EOPNOTSUPP);
        assert_return(ret, -EINVAL);

        if (!triple_timestamp_is_set(&lease->timestamp))
                return -ENODATA;

        *ret = triple_timestamp_by_clock(&lease->timestamp, clock);
        return 0;
}

static usec_t sec2usec(uint32_t sec) {
        return sec == UINT32_MAX ? USEC_INFINITY : sec * USEC_PER_SEC;
}

static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) {
        uint32_t t1 = UINT32_MAX, t2 = UINT32_MAX, min_valid_lt = UINT32_MAX;

        assert(lease);
        assert(lease->ia_na || lease->ia_pd);

        if (lease->ia_na) {
                t1 = MIN(t1, be32toh(lease->ia_na->header.lifetime_t1));
                t2 = MIN(t2, be32toh(lease->ia_na->header.lifetime_t2));

                LIST_FOREACH(addresses, a, lease->ia_na->addresses)
                        min_valid_lt = MIN(min_valid_lt, be32toh(a->iaaddr.lifetime_valid));
        }

        if (lease->ia_pd) {
                t1 = MIN(t1, be32toh(lease->ia_pd->header.lifetime_t1));
                t2 = MIN(t2, be32toh(lease->ia_pd->header.lifetime_t2));

                LIST_FOREACH(addresses, a, lease->ia_pd->addresses)
                        min_valid_lt = MIN(min_valid_lt, be32toh(a->iapdprefix.lifetime_valid));
        }

        if (t2 == 0 || t2 > min_valid_lt) {
                /* If T2 is zero or longer than the minimum valid lifetime of the addresses or prefixes,
                 * then adjust lifetime with it. */
                t1 = min_valid_lt / 2;
                t2 = min_valid_lt / 10 * 8;
        }

        lease->lifetime_valid = sec2usec(min_valid_lt);
        lease->lifetime_t1 = sec2usec(t1);
        lease->lifetime_t2 = sec2usec(t2);
}

int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid) {
        assert(lease);

        if (!lease->ia_na && !lease->ia_pd)
                return -ENODATA;

        if (ret_t1)
                *ret_t1 = lease->lifetime_t1;
        if (ret_t2)
                *ret_t2 = lease->lifetime_t2;
        if (ret_valid)
                *ret_valid = lease->lifetime_valid;
        return 0;
}

static void dhcp6_lease_set_server_address(sd_dhcp6_lease *lease, const struct in6_addr *server_address) {
        assert(lease);

        if (server_address)
                lease->server_address = *server_address;
        else
                lease->server_address = (struct in6_addr) {};
}

int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *ret) {
        assert_return(lease, -EINVAL);
        assert_return(ret, -EINVAL);

        *ret = lease->server_address;
        return 0;
}

void dhcp6_ia_clear_addresses(DHCP6IA *ia) {
        assert(ia);

        LIST_FOREACH(addresses, a, ia->addresses)
                free(a);

        ia->addresses = NULL;
}

DHCP6IA *dhcp6_ia_free(DHCP6IA *ia) {
        if (!ia)
                return NULL;

        dhcp6_ia_clear_addresses(ia);

        return mfree(ia);
}

int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) {
        uint8_t *clientid = NULL;

        assert(lease);
        assert(id || len == 0);

        if (len > 0) {
                clientid = memdup(id, len);
                if (!clientid)
                        return -ENOMEM;
        }

        free_and_replace(lease->clientid, clientid);
        lease->clientid_len = len;

        return 0;
}

int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) {
        assert(lease);

        if (!lease->clientid)
                return -ENODATA;

        if (ret_id)
                *ret_id = lease->clientid;
        if (ret_len)
                *ret_len = lease->clientid_len;

        return 0;
}

int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) {
        uint8_t *serverid = NULL;

        assert(lease);
        assert(id || len == 0);

        if (len > 0) {
                serverid = memdup(id, len);
                if (!serverid)
                        return -ENOMEM;
        }

        free_and_replace(lease->serverid, serverid);
        lease->serverid_len = len;

        return 0;
}

int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) {
        assert(lease);

        if (!lease->serverid)
                return -ENODATA;

        if (ret_id)
                *ret_id = lease->serverid;
        if (ret_len)
                *ret_len = lease->serverid_len;
        return 0;
}

int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
        assert(lease);

        lease->preference = preference;
        return 0;
}

int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *ret) {
        assert(lease);
        assert(ret);

        *ret = lease->preference;
        return 0;
}

int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
        assert(lease);

        lease->rapid_commit = true;
        return 0;
}

int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *ret) {
        assert(lease);
        assert(ret);

        *ret = lease->rapid_commit;
        return 0;
}

int sd_dhcp6_lease_get_address(
                sd_dhcp6_lease *lease,
                struct in6_addr *ret_addr,
                uint32_t *ret_lifetime_preferred,
                uint32_t *ret_lifetime_valid) {

        assert_return(lease, -EINVAL);

        if (!lease->addr_iter)
                return -ENODATA;

        if (ret_addr)
                *ret_addr = lease->addr_iter->iaaddr.address;
        if (ret_lifetime_preferred)
                *ret_lifetime_preferred = be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
        if (ret_lifetime_valid)
                *ret_lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);

        lease->addr_iter = lease->addr_iter->addresses_next;
        return 0;
}

void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
        if (lease)
                lease->addr_iter = lease->ia_na ? lease->ia_na->addresses : NULL;
}

int sd_dhcp6_lease_get_pd(
                sd_dhcp6_lease *lease,
                struct in6_addr *ret_prefix,
                uint8_t *ret_prefix_len,
                uint32_t *ret_lifetime_preferred,
                uint32_t *ret_lifetime_valid) {

        assert_return(lease, -EINVAL);

        if (!lease->prefix_iter)
                return -ENODATA;

        if (ret_prefix)
                *ret_prefix = lease->prefix_iter->iapdprefix.address;
        if (ret_prefix_len)
                *ret_prefix_len = lease->prefix_iter->iapdprefix.prefixlen;
        if (ret_lifetime_preferred)
                *ret_lifetime_preferred = be32toh(lease->prefix_iter->iapdprefix.lifetime_preferred);
        if (ret_lifetime_valid)
                *ret_lifetime_valid = be32toh(lease->prefix_iter->iapdprefix.lifetime_valid);

        lease->prefix_iter = lease->prefix_iter->addresses_next;
        return 0;
}

void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) {
        if (lease)
                lease->prefix_iter = lease->ia_pd ? lease->ia_pd->addresses : NULL;
}

int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
        assert(lease);
        assert(optval || optlen == 0);

        if (optlen == 0)
                return 0;

        return dhcp6_option_parse_addresses(optval, optlen, &lease->dns, &lease->dns_count);
}

int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
        assert_return(lease, -EINVAL);

        if (!lease->dns)
                return -ENODATA;

        if (ret)
                *ret = lease->dns;

        return lease->dns_count;
}

int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
        _cleanup_strv_free_ char **domains = NULL;
        int r;

        assert(lease);
        assert(optval || optlen == 0);

        if (optlen == 0)
                return 0;

        r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
        if (r < 0)
                return r;

        return strv_extend_strv(&lease->domains, domains, true);
}

int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret) {
        assert_return(lease, -EINVAL);
        assert_return(ret, -EINVAL);

        if (!lease->domains)
                return -ENODATA;

        *ret = lease->domains;
        return strv_length(lease->domains);
}

int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
        int r;

        assert(lease);
        assert(optval || optlen == 0);

        for (size_t offset = 0; offset < optlen;) {
                const uint8_t *subval;
                size_t sublen;
                uint16_t subopt;

                r = dhcp6_option_parse(optval, optlen, &offset, &subopt, &sublen, &subval);
                if (r < 0)
                        return r;

                switch (subopt) {
                case DHCP6_NTP_SUBOPTION_SRV_ADDR:
                case DHCP6_NTP_SUBOPTION_MC_ADDR:
                        if (sublen != 16)
                                return -EINVAL;

                        r = dhcp6_option_parse_addresses(subval, sublen, &lease->ntp, &lease->ntp_count);
                        if (r < 0)
                                return r;

                        break;

                case DHCP6_NTP_SUBOPTION_SRV_FQDN: {
                        _cleanup_free_ char *server = NULL;

                        r = dhcp6_option_parse_domainname(subval, sublen, &server);
                        if (r < 0)
                                return r;

                        if (strv_contains(lease->ntp_fqdn, server))
                                continue;

                        r = strv_consume(&lease->ntp_fqdn, TAKE_PTR(server));
                        if (r < 0)
                                return r;

                        break;
                }}
        }

        return 0;
}

int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
        assert(lease);
        assert(optval || optlen == 0);

        if (optlen == 0)
                return 0;

        /* SNTP option is defined in RFC4075, and deprecated by RFC5908. */
        return dhcp6_option_parse_addresses(optval, optlen, &lease->sntp, &lease->sntp_count);
}

int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
        assert_return(lease, -EINVAL);

        if (lease->ntp) {
                if (ret)
                        *ret = lease->ntp;
                return lease->ntp_count;
        }

        if (lease->sntp && !lease->ntp_fqdn) {
                /* Fallback to the deprecated SNTP option. */
                if (ret)
                        *ret = lease->sntp;
                return lease->sntp_count;
        }

        return -ENODATA;
}

int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
        assert_return(lease, -EINVAL);

        if (!lease->ntp_fqdn)
                return -ENODATA;

        if (ret)
                *ret = lease->ntp_fqdn;
        return strv_length(lease->ntp_fqdn);
}

int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
        char *fqdn;
        int r;

        assert(lease);
        assert(optval || optlen == 0);

        if (optlen == 0)
                return 0;

        if (optlen < 2)
                return -ENODATA;

        /* Ignore the flags field, it doesn't carry any useful
           information for clients. */
        r = dhcp6_option_parse_domainname(optval + 1, optlen - 1, &fqdn);
        if (r < 0)
                return r;

        return free_and_replace(lease->fqdn, fqdn);
}

int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **ret) {
        assert_return(lease, -EINVAL);
        assert_return(ret, -EINVAL);

        if (!lease->fqdn)
                return -ENODATA;

        *ret = lease->fqdn;
        return 0;
}

static int dhcp6_lease_parse_message(
                sd_dhcp6_client *client,
                sd_dhcp6_lease *lease,
                const DHCP6Message *message,
                size_t len) {

        usec_t irt = IRT_DEFAULT;
        int r;

        assert(client);
        assert(lease);
        assert(message);
        assert(len >= sizeof(DHCP6Message));

        len -= sizeof(DHCP6Message);
        for (size_t offset = 0; offset < len;) {
                uint16_t optcode;
                size_t optlen;
                const uint8_t *optval;

                r = dhcp6_option_parse(message->options, len, &offset, &optcode, &optlen, &optval);
                if (r < 0)
                        return log_dhcp6_client_errno(client, r,
                                                      "Failed to parse option header at offset %zu of total length %zu: %m",
                                                      offset, len);

                switch (optcode) {
                case SD_DHCP6_OPTION_CLIENTID:
                        if (dhcp6_lease_get_clientid(lease, NULL, NULL) >= 0)
                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple client IDs",
                                                              dhcp6_message_type_to_string(message->type));

                        r = dhcp6_lease_set_clientid(lease, optval, optlen);
                        if (r < 0)
                                return log_dhcp6_client_errno(client, r, "Failed to set client ID: %m");

                        break;

                case SD_DHCP6_OPTION_SERVERID:
                        if (dhcp6_lease_get_serverid(lease, NULL, NULL) >= 0)
                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple server IDs",
                                                              dhcp6_message_type_to_string(message->type));

                        r = dhcp6_lease_set_serverid(lease, optval, optlen);
                        if (r < 0)
                                return log_dhcp6_client_errno(client, r, "Failed to set server ID: %m");

                        break;

                case SD_DHCP6_OPTION_PREFERENCE:
                        if (optlen != 1)
                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Received invalid length for preference.");

                        r = dhcp6_lease_set_preference(lease, optval[0]);
                        if (r < 0)
                                return log_dhcp6_client_errno(client, r, "Failed to set preference: %m");

                        break;

                case SD_DHCP6_OPTION_STATUS_CODE: {
                        _cleanup_free_ char *msg = NULL;

                        r = dhcp6_option_parse_status(optval, optlen, &msg);
                        if (r < 0)
                                return log_dhcp6_client_errno(client, r, "Failed to parse status code: %m");
                        if (r > 0)
                                return log_dhcp6_client_errno(client, dhcp6_message_status_to_errno(r),
                                                              "Received %s message with non-zero status%s%s",
                                                              dhcp6_message_type_to_string(message->type),
                                                              isempty(msg) ? "." : ": ", strempty(msg));
                        break;
                }
                case SD_DHCP6_OPTION_IA_NA: {
                        _cleanup_(dhcp6_ia_freep) DHCP6IA *ia = NULL;

                        if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
                                log_dhcp6_client(client, "Ignoring IA NA option in information requesting mode.");
                                break;
                        }

                        r = dhcp6_option_parse_ia(client, client->ia_na.header.id, optcode, optlen, optval, &ia);
                        if (r == -ENOMEM)
                                return log_oom_debug();
                        if (r < 0) {
                                log_dhcp6_client_errno(client, r, "Failed to parse IA_NA option, ignoring: %m");
                                continue;
                        }

                        if (lease->ia_na) {
                                log_dhcp6_client(client, "Received duplicate matching IA_NA option, ignoring.");
                                continue;
                        }

                        dhcp6_ia_free(lease->ia_na);
                        lease->ia_na = TAKE_PTR(ia);
                        break;
                }
                case SD_DHCP6_OPTION_IA_PD: {
                        _cleanup_(dhcp6_ia_freep) DHCP6IA *ia = NULL;

                        if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
                                log_dhcp6_client(client, "Ignoring IA PD option in information requesting mode.");
                                break;
                        }

                        r = dhcp6_option_parse_ia(client, client->ia_pd.header.id, optcode, optlen, optval, &ia);
                        if (r == -ENOMEM)
                                return log_oom_debug();
                        if (r < 0) {
                                log_dhcp6_client_errno(client, r, "Failed to parse IA_PD option, ignoring: %m");
                                continue;
                        }

                        if (lease->ia_pd) {
                                log_dhcp6_client(client, "Received duplicate matching IA_PD option, ignoring.");
                                continue;
                        }

                        dhcp6_ia_free(lease->ia_pd);
                        lease->ia_pd = TAKE_PTR(ia);
                        break;
                }
                case SD_DHCP6_OPTION_RAPID_COMMIT:
                        if (optlen != 0)
                                log_dhcp6_client(client, "Received rapid commit option with an invalid length (%zu), ignoring.", optlen);

                        r = dhcp6_lease_set_rapid_commit(lease);
                        if (r < 0)
                                return log_dhcp6_client_errno(client, r, "Failed to set rapid commit flag: %m");

                        break;

                case SD_DHCP6_OPTION_DNS_SERVER:
                        r = dhcp6_lease_add_dns(lease, optval, optlen);
                        if (r < 0)
                                log_dhcp6_client_errno(client, r, "Failed to parse DNS server option, ignoring: %m");

                        break;

                case SD_DHCP6_OPTION_DOMAIN:
                        r = dhcp6_lease_add_domains(lease, optval, optlen);
                        if (r < 0)
                                log_dhcp6_client_errno(client, r, "Failed to parse domain list option, ignoring: %m");

                        break;

                case SD_DHCP6_OPTION_NTP_SERVER:
                        r = dhcp6_lease_add_ntp(lease, optval, optlen);
                        if (r < 0)
                                log_dhcp6_client_errno(client, r, "Failed to parse NTP server option, ignoring: %m");

                        break;

                case SD_DHCP6_OPTION_SNTP_SERVER:
                        r = dhcp6_lease_add_sntp(lease, optval, optlen);
                        if (r < 0)
                                log_dhcp6_client_errno(client, r, "Failed to parse SNTP server option, ignoring: %m");

                        break;

                case SD_DHCP6_OPTION_CLIENT_FQDN:
                        r = dhcp6_lease_set_fqdn(lease, optval, optlen);
                        if (r < 0)
                                log_dhcp6_client_errno(client, r, "Failed to parse FQDN option, ignoring: %m");

                        break;

                case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
                        if (optlen != 4)
                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
                                                              "Received information refresh time option with an invalid length (%zu).", optlen);

                        irt = unaligned_read_be32(optval) * USEC_PER_SEC;
                        break;
                }
        }

        uint8_t *clientid;
        size_t clientid_len;
        if (dhcp6_lease_get_clientid(lease, &clientid, &clientid_len) < 0)
                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
                                              "%s message does not contain client ID. Ignoring.",
                                              dhcp6_message_type_to_string(message->type));

        if (memcmp_nn(clientid, clientid_len, &client->duid, client->duid_len) != 0)
                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
                                              "The client ID in %s message does not match. Ignoring.",
                                              dhcp6_message_type_to_string(message->type));

        if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
                client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM);
                log_dhcp6_client(client, "New information request will be refused in %s.",
                                 FORMAT_TIMESPAN(client->information_refresh_time_usec, USEC_PER_SEC));

        } else {
                r = dhcp6_lease_get_serverid(lease, NULL, NULL);
                if (r < 0)
                        return log_dhcp6_client_errno(client, r, "%s has no server id",
                                                      dhcp6_message_type_to_string(message->type));

                if (!lease->ia_na && !lease->ia_pd)
                        return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
                                                      "No IA_PD prefix or IA_NA address received. Ignoring.");

                dhcp6_lease_set_lifetime(lease);
        }

        return 0;
}

static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
        if (!lease)
                return NULL;

        free(lease->clientid);
        free(lease->serverid);
        dhcp6_ia_free(lease->ia_na);
        dhcp6_ia_free(lease->ia_pd);
        free(lease->dns);
        free(lease->fqdn);
        strv_free(lease->domains);
        free(lease->ntp);
        strv_free(lease->ntp_fqdn);
        free(lease->sntp);

        return mfree(lease);
}

DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_lease, sd_dhcp6_lease, dhcp6_lease_free);

int dhcp6_lease_new(sd_dhcp6_lease **ret) {
        sd_dhcp6_lease *lease;

        assert(ret);

        lease = new(sd_dhcp6_lease, 1);
        if (!lease)
                return -ENOMEM;

        *lease = (sd_dhcp6_lease) {
                .n_ref = 1,
        };

        *ret = lease;
        return 0;
}

int dhcp6_lease_new_from_message(
                sd_dhcp6_client *client,
                const DHCP6Message *message,
                size_t len,
                const triple_timestamp *timestamp,
                const struct in6_addr *server_address,
                sd_dhcp6_lease **ret) {

        _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
        int r;

        assert(client);
        assert(message);
        assert(len >= sizeof(DHCP6Message));
        assert(ret);

        r = dhcp6_lease_new(&lease);
        if (r < 0)
                return r;

        dhcp6_lease_set_timestamp(lease, timestamp);
        dhcp6_lease_set_server_address(lease, server_address);

        r = dhcp6_lease_parse_message(client, lease, message, len);
        if (r < 0)
                return r;

        *ret = TAKE_PTR(lease);
        return 0;
}
