Skip to content

DNSServer refactoring, switch to AsyncUDP #7482

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

Merged
merged 11 commits into from
Dec 18, 2023

Conversation

vortigont
Copy link
Contributor

@vortigont vortigont commented Nov 16, 2022

Following bugfix #7475. Current implementation of DNSServer lib uses WiFiUDP which is not very efficient considering cpu/mem resources. It hooks to loop() for packet processing doing useless malloc's/free each run cycle.

https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiUdp.cpp#L205-L221

int WiFiUDP::parsePacket(){
// skipped
  char * buf = new char[1460];
  if ((len = recvfrom(udp_server, buf, 1460, MSG_DONTWAIT, (struct sockaddr *) &si_other, (socklen_t *)&slen)) == -1){
    delete[] buf;
    return 0;
  }

This PR offers refactored DNSServer code based on bundled AsyncUDP lib and some other optimizations.
- got rid of intermediate mem buffers and extra data copies in DNSServer code
- added sanity checks for mem bounds
- optimize label/packet length calculations
- removed some dynamically allocated members
- refactored "Captive Portal" example, now it invokes a pop-up suggesting to access a portal page on majority of modern systems/devices/browsers
- other code cleanup

This PR in a forked lib ESP32-DNSServerAsync that could be easily tested.

Other known issues:

  • non A req's ain't handled properly, i.e. always reply with A type records
  • pkts with edns opt ain't handled properly, packets ignored due to additional RR's>1

AsyncUDP offers event driven approch for handling udp dns req's
WiFiUDP hooks to loop() for packet processing and making useless malloc's each run
get rid of intermediate mem buffers and extra data copies,
most of the data could be referenced or copied from the source packet
 - removed _buffer member
 - replaced DNSQuestion.QName from uint8_t[] to char*

added sanity checks for mem bounds
optimize label/packet length calculations
other code cleanup
DNSHeader and DNSQuestion structs could be created on stack
no need to keep it as obj members
@mrengineer7777
Copy link
Collaborator

Exciting work. The challenge with a major change like this is it won't be merged until the next major release (3.0.0?), so #7475 is still useful.

@vortigont
Copy link
Contributor Author

@mrengineer7777 you maybe right. So I've forked bundled lib integrating this PR into separate repo ESP32-DNSServerAsync for anyone wish to try/test/use.
Feedbacks are welcome ;)

@VojtechBartoska VojtechBartoska added this to the 3.0.0 milestone Nov 21, 2022
 - default constructor and start() method simply runs a catch-all DNS setup
 - avoid string comparison for domain reqs in catch-all mode
 - use IPaddress class for _resolvedIP (looking for IPv6 support in future)
 - use webserver instead of simple tcp setver
 - use redirects to allows CaptivePortal detection pop-ups in modern systems
add isUp() method - returns 'true' if server is up and UDP socket is listening for UDP req's
add isCaptive() method - returns 'true' if server runs in catch-all (captive portal mode)
some doxygen comments added
start() method now keeps existing IP address if any
@CLAassistant
Copy link

CLAassistant commented Apr 28, 2023

CLA assistant check
All committers have signed the CLA.

@VojtechBartoska VojtechBartoska modified the milestones: 3.0.0, 3.0.0-RC1 Nov 28, 2023
@VojtechBartoska VojtechBartoska added Area: Libraries Issue is related to Library support. Status: Review needed Issue or PR is awaiting review labels Nov 28, 2023
@me-no-dev
Copy link
Member

@vortigont could you please sign the CLA?

@me-no-dev me-no-dev added the Resolution: Awaiting response Waiting for response of author label Dec 18, 2023
@vortigont
Copy link
Contributor Author

@me-no-dev done!

Copy link
Contributor

Warnings
⚠️

Some issues found for the commit messages in this PR:

  • the commit message "CaptivePortal example refactored":
    • summary looks empty
    • type/action looks empty
  • the commit message "DNSServer code refactoring":
    • summary looks empty
    • type/action looks empty
  • the commit message "DNSServer drop dynamically allocated member structs":
    • summary looks empty
    • type/action looks empty
  • the commit message "DNSServer status getters added":
    • summary looks empty
    • type/action looks empty
  • the commit message "DNSServer use default settings for catch-all setup":
    • summary looks empty
    • type/action looks empty
  • the commit message "DNSServer: labels min length checks, simplified labels parser":
    • type/action should start with a lowercase letter
    • type/action should be one of [change, ci, docs, feat, fix, refactor, remove, revert]
  • the commit message "DNSServer: switch to AsyncUDP instead of WiFiUDP":
    • type/action should start with a lowercase letter
    • type/action should be one of [change, ci, docs, feat, fix, refactor, remove, revert]

Please fix these commit messages - here are some basic tips:

  • follow Conventional Commits style
  • correct format of commit message should be: <type/action>(<scope/component>): <summary>, for example fix(esp32): Fixed startup timeout issue
  • allowed types are: change,ci,docs,feat,fix,refactor,remove,revert
  • sufficiently descriptive message summary should be between 20 to 72 characters and start with upper case letter
  • avoid Jira references in commit messages (unavailable/irrelevant for our customers)

TIP: Install pre-commit hooks and run this check when committing (uses the Conventional Precommit Linter).

⚠️ Please consider squashing your 11 commits (simplifying branch history).

👋 Hello vortigont, we appreciate your contribution to this project!


Click to see more instructions ...


This automated output is generated by the PR linter DangerJS, which checks if your Pull Request meets the project's requirements and helps you fix potential issues.

DangerJS is triggered with each push event to a Pull Request and modify the contents of this comment.

Please consider the following:
- Danger mainly focuses on the PR structure and formatting and can't understand the meaning behind your code or changes.
- Danger is not a substitute for human code reviews; it's still important to request a code review from your colleagues.
- Resolve all warnings (⚠️ ) before requesting a review from human reviewers - they will appreciate it.
- To manually retry these Danger checks, please navigate to the Actions tab and re-run last Danger workflow.

Review and merge process you can expect ...


We do welcome contributions in the form of bug reports, feature requests and pull requests.

1. An internal issue has been created for the PR, we assign it to the relevant engineer.
2. They review the PR and either approve it or ask you for changes or clarifications.
3. Once the GitHub PR is approved we do the final review, collect approvals from core owners and make sure all the automated tests are passing.
- At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
4. If the change is approved and passes the tests it is merged into the default branch.

Generated by 🚫 dangerJS against c5c8636

@me-no-dev
Copy link
Member

@vortigont thanks a lot!

Tested and confirmed all working as expected

@me-no-dev me-no-dev merged commit d912710 into espressif:master Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Libraries Issue is related to Library support. Resolution: Awaiting response Waiting for response of author Status: Review needed Issue or PR is awaiting review
Projects
Development

Successfully merging this pull request may close these issues.

6 participants