summaryrefslogtreecommitdiff
path: root/shared/n-dhcp4
Commit message (Collapse)AuthorAgeFilesLines
* n-dhcp4: fix uninitialized variablebg/gcc10Beniamino Galvani2020-02-031-0/+1
| | | | | | | | Properly initialize 'overload' when the space in the file section ends. shared/n-dhcp4/src/n-dhcp4-outgoing.c: In function ‘n_dhcp4_outgoing_append’: shared/n-dhcp4/src/n-dhcp4-outgoing.c:198:17: error: ‘overload’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
* n-dhcp4: move back to INIT after lease expiresBeniamino Galvani2020-01-301-4/+3
| | | | | | | | | Move back to INIT state after the lease expires, as per section 4.4.5 of RFC 2131. Previously the client just moved to EXPIRED, closed the connection and cleared the probe, leaving to the caller of the library the choice to create a new client instance and to start from scratch. However, it seems more useful that the client, once initialized, always tries to get a lease even after an expiration.
* n-dhcp4: accept options that are longer than requestedBeniamino Galvani2020-01-251-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the server sends a packet with multiple instances of the same option, they are concatenated during n_dhcp4_incoming_linearize() and evaluated as a single option as per section 7 of RFC 3396. However, there are broken server implementations that send self-contained options in multiple copies. They are reassembled to form a single instance by the nettools client, which then fails to parse them because they have a length greater than the expected one. This problem can be reproduced by starting a server with: dnsmasq --bind-interfaces --interface veth1 -d --dhcp-range=172.25.1.100,172.25.1.200,1m --dhcp-option=54,172.25.1.1 In this way dnsmasq sends a duplicate option 54 (server-id) when the client requests it in the 'parameter request list' option, as dhcp=systemd and dhcp=nettools currently do. While this is a violation of the RFC by the server, both isc-dhcp and systemd-networkd client implementations have mechanisms to deal with this situation. dhclient simply takes the first bytes of the aggregated option. systemd-networkd doesn't follow RFC 3396 and doesn't aggregate multiple options; it considers only the last occurrence of each option. Change the parsing code to accept options that are longer than necessary. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/324
* n-dhcp4: fix integer context in n_dhcp4_client_probe_transition_nak() on 32 bitThomas Haller2020-01-141-3/+3
| | | | | | Fixes: 218782a9a3c3 ('n-dhcp4: restart the transaction after a NAK') https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/339
* n-dhcp4: use C_CLAMP() macro instead of c_clamp()Beniamino Galvani2020-01-091-1/+1
| | | | | | | | | | | | | | | The latter requires __auto_type which is not available in GCC versions older than 4.9. Fix the following compile error on RHEL 7.8: CC src/src_libNetworkManagerBase_la-NetworkManagerUtils.lo shared/n-dhcp4/src/n-dhcp4-c-probe.c: In function 'n_dhcp4_client_probe_transition_nak': shared/n-dhcp4/src/n-dhcp4-c-probe.c:1008:17: error: unknown type name '__auto_type' probe->ns_nak_restart_delay = c_clamp(probe->ns_nak_restart_delay * 2, ^ shared/n-dhcp4/src/n-dhcp4-c-probe.c:1008:17: error: unknown type name '__auto_type' shared/n-dhcp4/src/n-dhcp4-c-probe.c:1008:17: error: unknown type name '__auto_type' Fixes: 218782a9a3c3 ('n-dhcp4: restart the transaction after a NAK')
* n-dhcp4: restart the transaction after a NAKBeniamino Galvani2020-01-092-4/+7
| | | | | | | | | | | | | | It is not enough to set the INIT state after a NAK; a timeout (ns_deferred) must be set so that it is added to the event fd. The client retries immediately the first time, so that in the successful case it gets an address quickly. To avoid flooding the network in case of servers always replying with NAKs, next attempts are done with intervals from 2 seconds to 5 minutes using exponential backoff. See also systemd commit [1]. [1] https://github.com/systemd/systemd/commit/1d1a3e0afb85478cda43670b8ed92a6db6c83f3e https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/325
* n-dhcp4: allow calling listen() on already listening connectionBeniamino Galvani2020-01-091-0/+3
| | | | | | | When the client enters the INIT state, it calls listen() on the connection connection to create the packet socket. However, if the client is coming from the REBOOTING state after a NAK, the connection is already in the listening state; do nothing in such case.
* n-dhcp4: handle invalid return codes gracefullyBeniamino Galvani2019-12-231-1/+6
| | | | | | | | Instead of terminating the program when the dispatch function returns an invalid return code, log an error message and convert the error code to a valid, generic one. https://bugs.archlinux.org/task/64880
* n-dhcp4: use packet socket in rebinding stateBeniamino Galvani2019-12-232-3/+30
| | | | | | | After t1, the client tries to renew the lease by contacting via the udp socket the server specified in the server-id option. If this fails, after t2 it tries to contact any server using broadcast. For this to work, the packet socket must be used.
* n-dhcp4: support init-reboot stateBeniamino Galvani2019-12-233-7/+80
| | | | | | | | | | | | | | | | Currently the client always starts from the INIT state (i.e. sending a discover message). If a requested-ip was specified by the caller, it is added as an option in the discover. It was reported that some DHCP servers don't respond to discover messages with the requested-ip option set [1][2]. The RFC allows to skip the discover by entering the INIT-REBOOT state and starting directly with a broadcast request message containing the requested IP address. Implement that. [1] https://bugzilla.redhat.com/show_bug.cgi?id=1781856 [2] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/310
* n-dhcp4: fix logging broadcast messagesBeniamino Galvani2019-12-231-0/+7
| | | | | Log the broadcast address instead of the server IP as destination when needed.
* client: fallback to CLOCK_MONOTONIC for timerfdThomas Haller2019-12-152-4/+27
| | | | | | | | | | | | | | | | | | | RHEL7 supports clock_gettime(CLOCK_BOOTIME), but it does not support timerfd_create(CLOCK_BOOTIME). Creating a timerfd will fail with EINVAL. Fallback to CLOCK_MONOTONIC. Compare this to n-acd which also has compatibility code to fallback to CLOCK_MONOTONIC. However when n-acd falls back to CLOCK_MONOTONIC, it uses monotonic clock also for clock_gettime(). For n-dhcp4, the timestamps are also exposed in the public API (n_dhcp4_client_lease_get_lifetime()). Hence, for timestamps n-dhcp4 still uses and requires clock_gettime(CLOCK_BOOTIME). Only the internal timeout handling with the timerfd falls back to CLOCK_MONOTONIC. https://github.com/nettools/n-dhcp4/pull/13 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/362 (cherry picked from commit a1771c738dd2e1437bd9f7c73805fd8a1b1b3d1d)
* n-dhcp4/socket: use SO_REUSEADDR on UDP socketThomas Haller2019-12-111-0/+4
| | | | | | | | | | | | | | | Otherwise, other applications cannot bind to port 0.0.0.0:68 at the same time. This is for example what dhclient wants to do. So even when running dhclient on another, unrelated interface, it would fail to bind the UDP socket and quit. Note that also systemd-networkd's DHCPv4 client sets this socket option. Presumably for the same reasons. Signed-off-by: Thomas Haller <thaller@redhat.com> https://github.com/nettools/n-dhcp4/pull/12 (cherry picked from commit 53b74bc6148b8001b4dcec700d2fc65de41679aa)
* n-dhcp4: log outgoing packetsBeniamino Galvani2019-11-222-0/+26
| | | | | | Add log messages for outgoing packets. https://github.com/nettools/n-dhcp4/pull/8
* n-dhcp4: log incoming packetsBeniamino Galvani2019-11-222-0/+44
| | | | | | Add log messages for incoming packets. https://github.com/nettools/n-dhcp4/pull/8
* n-dhcp4: add logging APIBeniamino Galvani2019-11-223-0/+37
| | | | | | | | In some cases it is useful to have the library log what it is doing for debugging purposes; add a simple API that allows setting a syslog-style logging level and specifying a logging function. https://github.com/nettools/n-dhcp4/pull/8
* n-dhcp4: fix state transitions on timer dispatchBeniamino Galvani2019-11-201-3/+4
| | | | | | | | | | | | | | | | | Currently in any of the BOUND, RENEWING and REBINDING states the probe checks the expiration of T1, T2 and lifetime. This is not correct because, for example, if the timer fires in the RENEWING state, the probe must not transition to RENEWING again (i.e. check again that now >= T1). Note that there is no guarantee that the timer triggers exactly once for T1, T2 and lifetime expirations because the timer is also used for the retransmission logic in NDhcp4CConnection. Therefore, add some checks to ensure that only correct transitions are allowed. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/341 https://bugzilla.redhat.com/show_bug.cgi?id=1773456
* lease: add n_dhcp4_client_lease_get_basetime()Thomas Haller2019-11-202-0/+13
| | | | | | | | | | | The API already had n_dhcp4_client_lease_get_lifetime(), which is the CLOCK_BOOTTIME when the lease expires (or ((uint64_t)-1)). But it might be interesting to know the actual lease duration and when the lease was received (and the time started to count). Expose an API for that. With this, one can also calculate the original, exact lease lifetime, by subtracting n_dhcp4_client_lease_get_basetime() from n_dhcp4_client_lease_get_lifetime(), while taking care of ((uint64_t)-1).
* incoming: don't handle 0xFFFFFFFF timestamps special in ↵Thomas Haller2019-11-201-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | n_dhcp4_incoming_query_u32() First of all, from the naming of n_dhcp4_incoming_query_u32() it is confusing to coerce 0xFFFFFFFF to zero. It should just return the plain value. Also note that n_dhcp4_incoming_query_u32() only has three callers: n_dhcp4_incoming_query_lifetime(), n_dhcp4_incoming_query_t1() and n_dhcp4_incoming_query_t2(). Looking further, those three functions only have one caller: n_dhcp4_incoming_get_timeouts(). Note how the code there already tries to handle UINT32_MAX and interprets it as infinity (UINT64_MAX). But as it was, UINT32_MAX never actually was returned. It seems that RFC [1] does not specially define the meanings of 0xFFFFFFFF and 0. It sounds reasonable to assume that 0 just means 0 lifetime, and 0xFFFFFFFF means infinity. On the other hand, compare this to systemd's code [2], which coerces 0 to 1. This does not seem right to me though. Note how systemd returns 0xFFFFFFFF as-is. Drop the special handling of 0xFFFFFFFF from n_dhcp4_incoming_query_u32(). It now just returns the plain value and it's up to n_dhcp4_incoming_get_timeouts() to make sense of that. This will fix behavior, so that 0xFFFFFFFF will be reported as infinity, and not as zero. [1] https://tools.ietf.org/html/rfc2132#section-9.2 [2] https://github.com/systemd/systemd/blob/68c2b5ddb1881c40201c1d86a7852dd5c5c06a76/src/libsystemd-network/sd-dhcp-lease.c#L553
* probe: unconditionally pass ownership of message in ↵Thomas Haller2019-11-201-13/+11
| | | | | | | | | n_dhcp4_client_probe_dispatch_io() It is error prone when a function consumes an input only in certain cases (and telling the caller via the return code). At least in these cases, the message is never used afterwards, and we can always pass it on.
* probe: fix leaking message during client probeThomas Haller2019-11-201-3/+5
|
* n-dhcp4: ci: drop broken armv7hlDavid Rheinsberg2019-11-201-2/+0
| | | | | | Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com> https://github.com/nettools/n-dhcp4/commit/e4a01f5870a69fe53e1887369e51f6e74ca65f78
* n-dhcp4: util/link: suppress gcc warningDavid Rheinsberg2019-11-201-1/+1
| | | | | | | | | Avoid strncpy() and suppress a gcc warning about a truncated 0-terminator. Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com> https://github.com/nettools/n-dhcp4/commit/2546aa2c809ddbf7a8853657e10102d5fff941a3
* n-dhcp4/lease: expose the server IP addressLubomir Rintel2019-11-184-0/+17
| | | | | | This is useful for network booting. https://github.com/nettools/n-dhcp4/pull/7
* n-dhcp4: arm timers in bound stateBeniamino Galvani2019-09-181-1/+1
| | | | | | | Arm timers when the bound state is reached, otherwise the lease is never renewed. https://github.com/nettools/n-dhcp4/pull/4
* n-dhcp4: allocate memory of right size in n_dhcp4_client_probe_option_new()Thomas Haller2019-08-081-1/+1
| | | | | | Non-critical, as the allocated memory was larger than needed. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/224
* n-dhcp4: remove dead codeBeniamino Galvani2019-08-021-4/+1
| | | | | | Reported by coverity. (cherry picked from commit a32976568c13e22dd560610374782250f4d4ba9e)
* n-dhcp4: avoid "-Werror=declaration-after-statement" warning with static_assertThomas Haller2019-08-021-2/+2
| | | | | | | | | | | | | | | | | When we build n-dhcp4 for NetworkManager we get a compiler warning. This can also be reproduced by building n-dhcp4 alone: $ CFLAGS='-Werror=declaration-after-statement' meson build && ninja -C build ... [36/47] Compiling C object 'src/25a6634@@ndhcp4-private@sta/n-dhcp4-outgoing.c.o'. FAILED: src/25a6634@@ndhcp4-private@sta/n-dhcp4-outgoing.c.o ccache cc -Isrc/25a6634@@ndhcp4-private@sta -Isrc -I../src -Isubprojects/c-list/src -I../subprojects/c-list/src -Isubprojects/c-siphash/src -I../subprojects/c-siphash/src -Isubprojects/c-stdaux/src -I../subprojects/c-stdaux/src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c11 -g -D_GNU_SOURCE -Werror=declaration-after-statement -fPIC -fvisibility=hidden -fno-common -MD -MQ 'src/25a6634@@ndhcp4-private@sta/n-dhcp4-outgoing.c.o' -MF 'src/25a6634@@ndhcp4-private@sta/n-dhcp4-outgoing.c.o.d' -o 'src/25a6634@@ndhcp4-private@sta/n-dhcp4-outgoing.c.o' -c ../src/n-dhcp4-outgoing.c ../src/n-dhcp4-outgoing.c: In function ‘n_dhcp4_outgoing_new’: ../src/n-dhcp4-outgoing.c:63:9: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] 63 | static_assert(N_DHCP4_NETWORK_IP_MINIMUM_MAX_SIZE >= N_DHCP4_OUTGOING_MAX_PHDR + | ^~~~~~~~~~~~~ (cherry picked from commit 9e7ca3e0913e2ba6a38dd5b0cbd3a7b3e34cd286)
* n-dhcp4: client/probe: fix memory leakBeniamino Galvani2019-07-051-0/+1
| | | | | | | | | The probe takes a reference to the current lease and so it must release it upon destruction. Signed-off-by: Beniamino Galvani <bgalvani@redhat.com> https://github.com/nettools/n-dhcp4/pull/1
* n-dhcp4: client/connection: fix memory leakBeniamino Galvani2019-07-051-0/+1
| | | | | | | | Free the request when the connection gets destroyed. Signed-off-by: Beniamino Galvani <bgalvani@redhat.com> https://github.com/nettools/n-dhcp4/pull/1
* n-dhcp4: avoid {net,linux}/if.h clashes on old distrosTom Gundersen2019-07-054-7/+8
| | | | | | | In particular, avoid including linux/netdevice.h from headers. This is not a problem on newer distros, but required for CentOS 7.6. Signed-off-by: Tom Gundersen <teg@jklm.no>
* shared/n-dhcp4: avoid c_min() macro to work with old GCCTom Gundersen2019-07-052-4/+13
| | | | | This is required for the CI to pass, as CentOS has a too old version of GCC. Ideally this patch should be dropped.
* Merge commit 'e23b3c9c3ac86b065eef002fa5c4321cc4a87df2' as 'shared/n-dhcp4'Tom Gundersen2019-05-2540-0/+10480
Imported n-dhcp4 code with command: git subtree add --prefix shared/n-dhcp4/ git@github.com:nettools/n-dhcp4.git master --squash To update the library use: git subtree pull --prefix shared/n-dhcp4/ git@github.com:nettools/n-dhcp4.git master --squash