return 1;
}
+int shorten_overlong(const char *s, char **ret) {
+ char *h, *p;
+
+ /* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
+ * whatever comes earlier. */
+
+ assert(s);
+
+ h = strdup(s);
+ if (!h)
+ return -ENOMEM;
+
+ if (hostname_is_valid(h, false)) {
+ *ret = h;
+ return 0;
+ }
+
+ p = strchr(h, '.');
+ if (p)
+ *p = 0;
+
+ strshorten(h, HOST_NAME_MAX);
+
+ if (!hostname_is_valid(h, false)) {
+ free(h);
+ return -EDOM;
+ }
+
+ *ret = h;
+ return 1;
+}
+
int read_etc_hostname_stream(FILE *f, char **ret) {
int r;
}
if (link->network->dhcp_use_hostname) {
- const char *hostname = NULL;
+ const char *dhcpname = NULL;
+ _cleanup_free_ char *hostname = NULL;
if (link->network->dhcp_hostname)
- hostname = link->network->dhcp_hostname;
+ dhcpname = link->network->dhcp_hostname;
else
- (void) sd_dhcp_lease_get_hostname(lease, &hostname);
+ (void) sd_dhcp_lease_get_hostname(lease, &dhcpname);
+
+ if (dhcpname) {
+ r = shorten_overlong(dhcpname, &hostname);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname);
+ if (r == 1)
+ log_link_notice(link, "Overlong DCHP hostname received, shortened from '%s' to '%s'", dhcpname, hostname);
+ }
if (hostname) {
r = manager_set_hostname(link->manager, hostname);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/param.h>
+
#include "alloc-util.h"
#include "dhcp-lease-internal.h"
+#include "hostname-util.h"
#include "network-internal.h"
#include "networkd-manager.h"
+#include "string-util.h"
#include "udev-util.h"
static void test_deserialize_in_addr(void) {
assert_se(!address_equal(a1, a2));
}
+static void test_dhcp_hostname_shorten_overlong(void) {
+ int r;
+
+ {
+ /* simple hostname, no actions, no errors */
+ _cleanup_free_ char *shortened = NULL;
+ r = shorten_overlong("name1", &shortened);
+ assert_se(r == 0);
+ assert_se(streq("name1", shortened));
+ }
+
+ {
+ /* simple fqdn, no actions, no errors */
+ _cleanup_free_ char *shortened = NULL;
+ r = shorten_overlong("name1.example.com", &shortened);
+ assert_se(r == 0);
+ assert_se(streq("name1.example.com", shortened));
+ }
+
+ {
+ /* overlong fqdn, cut to first dot, no errors */
+ _cleanup_free_ char *shortened = NULL;
+ r = shorten_overlong("name1.test-dhcp-this-one-here-is-a-very-very-long-domain.example.com", &shortened);
+ assert_se(r == 1);
+ assert_se(streq("name1", shortened));
+ }
+
+ {
+ /* overlong hostname, cut to HOST_MAX_LEN, no errors */
+ _cleanup_free_ char *shortened = NULL;
+ r = shorten_overlong("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-domainname", &shortened);
+ assert_se(r == 1);
+ assert_se(streq("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-dom", shortened));
+ }
+
+ {
+ /* overlong fqdn, cut to first dot, empty result error */
+ _cleanup_free_ char *shortened = NULL;
+ r = shorten_overlong(".test-dhcp-this-one-here-is-a-very-very-long-hostname.example.com", &shortened);
+ assert_se(r == -EDOM);
+ assert_se(shortened == NULL);
+ }
+
+}
+
int main(void) {
_cleanup_manager_free_ Manager *manager = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
test_deserialize_in_addr();
test_deserialize_dhcp_routes();
test_address_equality();
+ test_dhcp_hostname_shorten_overlong();
assert_se(sd_event_default(&event) >= 0);