Skip to content

[mdns]: Refactor stage #1 #776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

david-cermak
Copy link
Collaborator

@david-cermak david-cermak commented Mar 5, 2025

MDNS Component Refactor

Introduction

The MDNS component has been refactored from a single monolithic file mdns.c into a set of focused modules with clear responsibilities. This restructuring maintains the same functionality while improving code organization, maintainability, and testability.

The refactor has been performed in thee major stages, to ensure smooth transition to production while avoiding major changes in untested paths. These stages are:

  • Restructuring into several modules while keeping the actual code changes to minimum
  • Cover functionality of each module by specifically focused unit tests.
  • Optimizations on module levels (string and queue operations, esp_timer dependency, socket task improvements, error checking)

Module Structure

mdns_service.c

The central service module that orchestrates the MDNS component operation. It manages the service task, timer, action queue, and system event handling. This module provides the entry points for the public API and coordinates actions between different modules. It's responsible for the general lifecycle of the MDNS service.

mdns_responder.c

Implements the responder functionality that answers incoming MDNS queries. It manages hostname and service registration, and generates appropriate response packets based on the queried information. The responder tracks all registered services and their associated metadata, handling hostname conflicts and service announcement.

mdns_browser.c

Handles browse/query functionality, managing browse requests for MDNS services on the network. It provides the infrastructure for adding, tracking, and removing browse requests, and processes incoming service discovery responses. The module manages browsing state and notifies applications when services appear or disappear.

mdns_querier.c

Handles outgoing query functionality, maintaining state for ongoing queries and processing query responses. It supports one-shot and continuous queries, manages query timeouts, and organizes results. The module provides the infrastructure for applications to discover services and resolve hostnames.

mdns_send.c

Manages packet generation and transmission. It constructs properly formatted MDNS packets, with correct headers and resource records, and handles the transmission scheduling and queueing of outgoing messages. This module encapsulates knowledge about the MDNS protocol packet structure.

mdns_receive.c

Processes incoming MDNS packets, parsing and validating their structure. It extracts queries and responses from received packets and dispatches them to the appropriate handling modules. This module focuses on packet parsing and initial classification.

mdns_pcb.c

Manages protocol control blocks (PCBs) that handle the state machine for MDNS interface operation. It coordinates the probing, announcing, and running states for each network interface and protocol combination. This module is responsible for service conflict detection, duplicate interface handling, and ensuring proper service announcements.

mdns_networking_lwip.c and mdns_networking_socket.c

These modules provide networking abstraction for different underlying network stacks. They handle multicast group management, packet reception, and transmission over the network interfaces. This abstraction allows the MDNS implementation to work with different networking stacks.

mdns_netif.c

Manages network interface registration and monitoring. It tracks network interface state changes and notifies the MDNS service when interfaces become available or unavailable, enabling dynamic adaptation to network configuration changes.

mdns_utils.c

Contains common utility functions used across multiple modules, such as string handling, data structure operations, and debug helpers. This module centralizes shared functionality to avoid code duplication.

mdns_mem_caps.c

Provides memory allocation functions with capability-based allocation support. It encapsulates memory management operations, making it easier to track and debug memory usage across the MDNS component.

mdns_debug.c

Contains debugging and logging utilities specific to the MDNS component. It provides structured logging and debug information for troubleshooting complex MDNS operations.

Testability Improvements

The refactored module structure significantly enhances testability by clearly separating different functional areas. Each module can now be tested in isolation with proper mocking of its dependencies. The separation of networking, packet handling, and business logic makes it possible to create focused unit tests without the complexity of managing the entire MDNS stack. Module-specific state is now contained within individual modules rather than distributed throughout a monolithic codebase, making test case setup and verification more straightforward. The refactoring also improves the ability to simulate various network conditions and edge cases by intercepting inter-module communication at well-defined boundaries.

Conclusion

The MDNS component refactoring provides a more maintainable and testable architecture while preserving the existing public API. By breaking down the monolithic implementation into focused modules with clear responsibilities, the codebase becomes easier to understand, extend, and maintain. The refactored structure makes it simpler to identify and fix bugs, implement new features, and adapt to future requirements. This architectural improvement supports long-term evolution of the component while maintaining backward compatibility for existing applications.

Adding fuzzer tests

@david-cermak david-cermak self-assigned this Mar 5, 2025
@david-cermak david-cermak marked this pull request as draft March 5, 2025 16:33
@david-cermak david-cermak force-pushed the mdns/refactor branch 7 times, most recently from 2019c2f to 611c665 Compare March 9, 2025 17:25
@david-cermak david-cermak force-pushed the mdns/refactor branch 6 times, most recently from bf55daf to 89499cf Compare March 11, 2025 15:31
@david-cermak david-cermak force-pushed the mdns/refactor branch 7 times, most recently from e7072f5 to ae08137 Compare March 21, 2025 13:32
@david-cermak david-cermak force-pushed the mdns/refactor branch 3 times, most recently from 751a537 to 5d33c18 Compare April 1, 2025 13:25
@david-cermak david-cermak force-pushed the mdns/refactor branch 3 times, most recently from ff69c6f to b4f9290 Compare April 2, 2025 07:02
@david-cermak david-cermak marked this pull request as ready for review April 2, 2025 09:12
Copy link
Collaborator

@zwx1995esp zwx1995esp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the whole architecture, LGTM. I reviewed only for mdns_service.c and mdns_utils.c and left some nits and questions. For the other files, I will finish this weekend.

* @param index offset of uint16_t value
* @param value the value to set
*/
static inline void set_u16(uint8_t *packet, uint16_t index, uint16_t value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: what is the difference between this function and mdns_utils_append_u16?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the append function is supposed to be used when composing a packet, so it keeps track of the current pointer and returns the position.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I just see the implementation of the two function are much the same, can we use the function mdns_utils_append_u16 for both set and append scenario?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, but i'd again leave it for phase III, where we can address optimizations. I'd keep it here as is, just to reduce the complexity of this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants