diff --git a/src/libknot/rrtype/opt.c b/src/libknot/rrtype/opt.c index d52fabbeef18b5c2e32b976b5e605ad0a778d233..9f2a9b878dc59a05c9b67d6e54348c446e68fffb 100644 --- a/src/libknot/rrtype/opt.c +++ b/src/libknot/rrtype/opt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -736,3 +736,50 @@ int knot_edns_client_subnet_get_addr(struct sockaddr_storage *addr, return KNOT_EOK; } + +_public_ +size_t knot_edns_keepalive_size(uint16_t timeout) +{ + return (timeout == 0) ? sizeof(uint16_t) : 2 * sizeof(uint16_t); +} + +_public_ +int knot_edns_keepalive_write(uint8_t *option, size_t option_len, uint16_t timeout) +{ + if (option == NULL) { + return KNOT_EINVAL; + } + + wire_ctx_t wire = wire_ctx_init(option, option_len); + if (timeout == 0) { + wire_ctx_write_u16(&wire, 0); + } else { + wire_ctx_write_u16(&wire, 2); + wire_ctx_write_u16(&wire, timeout); + } + + return wire.error; +} + +_public_ +int knot_edns_keepalive_parse(uint16_t *timeout, const uint8_t *option, size_t option_len) +{ + if (timeout == NULL || option == NULL) { + return KNOT_EINVAL; + } + + wire_ctx_t wire = wire_ctx_init_const(option, option_len); + + uint16_t len = wire_ctx_read_u16(&wire); + if (len == 0) { + *timeout = 0; + } else { + *timeout = wire_ctx_read_u16(&wire); + } + + if (wire.error != KNOT_EOK || wire_ctx_available(&wire) != 0) { + return KNOT_EMALF; + } + + return KNOT_EOK; +} diff --git a/src/libknot/rrtype/opt.h b/src/libknot/rrtype/opt.h index e87e70c6d29aef08adf0c397f3ce2427f08e42b4..81d280c7aee9b03c873648e51d56da7d9c183937 100644 --- a/src/libknot/rrtype/opt.h +++ b/src/libknot/rrtype/opt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -451,4 +451,35 @@ int knot_edns_client_subnet_set_addr(knot_edns_client_subnet_t *ecs, int knot_edns_client_subnet_get_addr(struct sockaddr_storage *addr, const knot_edns_client_subnet_t *ecs); +/*! + * \brief Get size of the EDNS Keepalive option wire size. + * + * \param[in] timeout EDNS TCP Keepalive timeout. + * + * \return Size of the EDNS option data. + */ +size_t knot_edns_keepalive_size(uint16_t timeout); + +/*! + * \brief Writes EDNS TCP Keepalive wire data. + * + * \param[out] option EDNS option data buffer. + * \param[in] option_len EDNS option data buffer size. + * \param[in] timeout EDNS TCP Keepalive timeout. + * + * \return Error code, KNOT_EOK if successful. + */ +int knot_edns_keepalive_write(uint8_t *option, size_t option_len, uint16_t timeout); + +/*! + * \brief Parses EDNS TCP Keepalive wire data. + * + * \param[out] timeout EDNS TCP Keepalive timeout. + * \param[in] option EDNS option data. + * \param[in] option_len EDNS option size. + * + * \return Error code, KNOT_EOK if successful. + */ +int knot_edns_keepalive_parse(uint16_t *timeout, const uint8_t *option, size_t option_len); + /*! @} */