Send hostname with persistent DHCP requests

pull/8/head
Jack O'Sullivan 5 years ago
parent 010e9203a9
commit 7933149acf

@ -91,6 +91,12 @@ def await_endpoint_container_iface(n, e, timeout=5):
raise NetDhcpError('Timed out waiting for container to become availabile')
return iface
def endpoint_container_name(n, e):
for info in client.networks.get(n).attrs['Containers'].values():
if info['EndpointID'] == e:
return info['Name']
return None
@app.route('/NetworkDriver.GetCapabilities', methods=['POST'])
def net_get_capabilities():
return jsonify({
@ -340,13 +346,14 @@ class ContainerDHCPManager:
def run(self):
try:
iface = await_endpoint_container_iface(self.network, self.endpoint)
hostname = endpoint_container_name(self.network, self.endpoint)
self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event)
self.dhcp = udhcpc.DHCPClient(iface, event_listener=self._on_event, hostname=hostname)
logger.info('Starting DHCPv4 client on %s in container namespace %s', iface['ifname'], \
self.dhcp.netns)
if self.ipv6:
self.dhcp6 = udhcpc.DHCPClient(iface, v6=True, event_listener=self._on_event)
self.dhcp6 = udhcpc.DHCPClient(iface, v6=True, event_listener=self._on_event, hostname=hostname)
logger.info('Starting DHCPv6 client on %s in container namespace %s', iface['ifname'], \
self.dhcp6.netns)
except Exception as e:

@ -1,6 +1,8 @@
from enum import Enum
import ipaddress
import json
import struct
import binascii
import os
from os import path
from select import select
@ -30,7 +32,7 @@ class DHCPClientError(Exception):
def _nspopen_wrapper(netns):
return lambda *args, **kwargs: NSPopen(netns, *args, **kwargs)
class DHCPClient:
def __init__(self, iface, v6=False, once=False, event_listener=None):
def __init__(self, iface, v6=False, once=False, hostname=None, event_listener=None):
self.iface = iface
self.v6 = v6
self.once = once
@ -47,6 +49,18 @@ class DHCPClient:
bin_path = '/usr/bin/udhcpc6' if v6 else '/sbin/udhcpc'
cmdline = [bin_path, '-s', HANDLER_SCRIPT, '-i', iface['ifname'], '-f']
cmdline.append('-q' if once else '-R')
if hostname:
cmdline.append('-x')
if v6:
# TODO: We encode the fqdn for DHCPv6 because udhcpc6 seems to be broken
# flags: S bit set (see RFC4704)
enc_hostname = hostname.encode('utf-8')
enc_hostname = struct.pack('BB', 0b0001, len(enc_hostname)) + enc_hostname
enc_hostname = binascii.hexlify(enc_hostname).decode('ascii')
hostname_opt = f'0x27:{enc_hostname}'
else:
hostname_opt = f'hostname:{hostname}'
cmdline.append(hostname_opt)
if not v6:
cmdline += ['-V', VENDOR_ID]
@ -54,6 +68,8 @@ class DHCPClient:
self._event_queue = posix_ipc.MessageQueue(f'/udhcpc{self._suffix}_{iface["address"].replace(":", "_")}', \
flags=os.O_CREAT | os.O_EXCL)
self.proc = Popen(cmdline, env={'EVENT_QUEUE': self._event_queue.name})
if hostname:
logger.debug('[udhcpc%s#%d] using hostname "%s"', self._suffix, self.proc.pid, hostname)
self._has_lease = threading.Event()
self.ip = None
@ -110,7 +126,7 @@ class DHCPClient:
if self._shutdown_event.is_set():
return
if self.proc.returncode != None and (not self.once or self.proc.returncode != 0):
if self.proc.returncode is not None and (not self.once or self.proc.returncode != 0):
raise DHCPClientError(f'udhcpc{self._suffix} exited early with code {self.proc.returncode}')
if self.once:
self.await_ip()

Loading…
Cancel
Save