Skip to content

Commit 7933149

Browse files
committed
Send hostname with persistent DHCP requests
1 parent 010e920 commit 7933149

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

net-dhcp/network.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ def await_endpoint_container_iface(n, e, timeout=5):
9191
raise NetDhcpError('Timed out waiting for container to become availabile')
9292
return iface
9393

94+
def endpoint_container_name(n, e):
95+
for info in client.networks.get(n).attrs['Containers'].values():
96+
if info['EndpointID'] == e:
97+
return info['Name']
98+
return None
99+
94100
@app.route('/NetworkDriver.GetCapabilities', methods=['POST'])
95101
def net_get_capabilities():
96102
return jsonify({
@@ -340,13 +346,14 @@ def _on_event(self, dhcp, event_type, _event):
340346
def run(self):
341347
try:
342348
iface = await_endpoint_container_iface(self.network, self.endpoint)
349+
hostname = endpoint_container_name(self.network, self.endpoint)
343350

344-
self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event)
351+
self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event, hostname=hostname)
345352
logger.info('Starting DHCPv4 client on %s in container namespace %s', iface['ifname'], \
346353
self.dhcp.netns)
347354

348355
if self.ipv6:
349-
self.dhcp6 = udhcpc.DHCPClient(iface, v6=True, event_listener=self._on_event)
356+
self.dhcp6 = udhcpc.DHCPClient(iface, v6=True, event_listener=self._on_event, hostname=hostname)
350357
logger.info('Starting DHCPv6 client on %s in container namespace %s', iface['ifname'], \
351358
self.dhcp6.netns)
352359
except Exception as e:

net-dhcp/udhcpc.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from enum import Enum
22
import ipaddress
33
import json
4+
import struct
5+
import binascii
46
import os
57
from os import path
68
from select import select
@@ -30,7 +32,7 @@ class DHCPClientError(Exception):
3032
def _nspopen_wrapper(netns):
3133
return lambda *args, **kwargs: NSPopen(netns, *args, **kwargs)
3234
class DHCPClient:
33-
def __init__(self, iface, v6=False, once=False, event_listener=None):
35+
def __init__(self, iface, v6=False, once=False, hostname=None, event_listener=None):
3436
self.iface = iface
3537
self.v6 = v6
3638
self.once = once
@@ -47,13 +49,27 @@ def __init__(self, iface, v6=False, once=False, event_listener=None):
4749
bin_path = '/usr/bin/udhcpc6' if v6 else '/sbin/udhcpc'
4850
cmdline = [bin_path, '-s', HANDLER_SCRIPT, '-i', iface['ifname'], '-f']
4951
cmdline.append('-q' if once else '-R')
52+
if hostname:
53+
cmdline.append('-x')
54+
if v6:
55+
# TODO: We encode the fqdn for DHCPv6 because udhcpc6 seems to be broken
56+
# flags: S bit set (see RFC4704)
57+
enc_hostname = hostname.encode('utf-8')
58+
enc_hostname = struct.pack('BB', 0b0001, len(enc_hostname)) + enc_hostname
59+
enc_hostname = binascii.hexlify(enc_hostname).decode('ascii')
60+
hostname_opt = f'0x27:{enc_hostname}'
61+
else:
62+
hostname_opt = f'hostname:{hostname}'
63+
cmdline.append(hostname_opt)
5064
if not v6:
5165
cmdline += ['-V', VENDOR_ID]
5266

5367
self._suffix = '6' if v6 else ''
5468
self._event_queue = posix_ipc.MessageQueue(f'/udhcpc{self._suffix}_{iface["address"].replace(":", "_")}', \
5569
flags=os.O_CREAT | os.O_EXCL)
5670
self.proc = Popen(cmdline, env={'EVENT_QUEUE': self._event_queue.name})
71+
if hostname:
72+
logger.debug('[udhcpc%s#%d] using hostname "%s"', self._suffix, self.proc.pid, hostname)
5773

5874
self._has_lease = threading.Event()
5975
self.ip = None
@@ -110,7 +126,7 @@ def finish(self, timeout=5):
110126
if self._shutdown_event.is_set():
111127
return
112128

113-
if self.proc.returncode != None and (not self.once or self.proc.returncode != 0):
129+
if self.proc.returncode is not None and (not self.once or self.proc.returncode != 0):
114130
raise DHCPClientError(f'udhcpc{self._suffix} exited early with code {self.proc.returncode}')
115131
if self.once:
116132
self.await_ip()

0 commit comments

Comments
 (0)