apache / apache/nuttx

[HELP] `dhcpd_stop()` does not return if no packets were received (recv blocking behavior)

Open
#16,135 7 comments 0 reactions 0 assignees View on GitHub
Community: Question
Dominant language
C
Stars
4k
Forks
1.7k
Avg merge
1d 17h
Merged PRs (30d)
237

Description

### Description

This issue documents the observed behavior of the `dhcpd` daemon (`apps/netutils/dhcpd`) when `dhcpd_stop()` is called after starting the daemon without any DHCP packets being received.

### Observed Behavior

When starting the DHCP server using `dhcpd_start()` and stopping it with `dhcpd_stop()`, the `dhcpd_stop()` call blocks indefinitely **if no DHCP packets were received** during the server execution. This blocks further logic execution, including restarting the daemon.

#### Sequence:

1. Start DHCPD using `dhcpd_start("wlan0")` (or `"eth0"` on `sim`).
2. No devices send DHCP requests.
3. After 30 seconds, call `dhcpd_stop()`.
4. `dhcpd_stop()` sends the configured signal (default `NETUTILS_DHCPD_SIGWAKEUP`) using `kill()`.
5. The daemon remains stuck inside the `recv()` call.
6. The semaphore used to synchronize (`ds_sync`) is never released.
7. The task state remains as `Stopped`, but the stack is not reclaimed.

### Platforms Tested

- `esp32c6-devkitc:wifi` (interface: `wlan0`)
- `sim:tcpblaster` (interface: `eth0`)

### dhcpd daemon state

Example output from `ps` after calling `dhcpd_stop()`:

```
PID GROUP PRI POLICY TYPE NPX STATE EVENT SIGMASK STACK COMMAND
...
6 6 100 RR Task - Stopped 0000000000400000 0004040 DHCPD_daemon wlan0
...
```

Despite being marked as "Stopped", the task is never released due to blocking on `recv()`.

### Impact

This behavior prevents:

- Reusing the DHCP daemon in long-running applications.
- Performing controlled shutdowns or restarts.
- Completing the application logic after `dhcpd_stop()`.

### Questions
1. Is this behavior known to the NuttX community?

2. Is there any official recommendation on how to handle the graceful termination of dhcpd, considering that it blocks on recv()?

3. Is there a standard in NuttX for handling blocking recv() in daemons, allowing the task to be terminated safely via signal or other mechanism?

### Verification

- [x] I have verified before submitting the report.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.