Skip to content

Conversation

@wmergenthal
Copy link

@wmergenthal wmergenthal commented Dec 19, 2025

This pull request is meant to replace #7231, opened on 26 Jun 2025. Between that time and the actual review & approval process, other changes were made in the same two files. Significant merge conflicts surfaced after the review. The simplest way I saw to resolve them was to create a fresh branch from master and apply the same changes to that. That is what comprises this pull request, which has (nearly) the same title and the identical comment paragraphs below. I imagine that PR #7231 should be cancelled/deleted, but I am leaving it alone for now in case it is needed for reference.

When setting up to advertise a book over WiFi, BloomDesktop can sometimes use the wrong local IP address due to using the wrong network interface. I observed this in my home setup last November for the first time: C# sent UDP broadcast adverts out over a virtual interface associated with my VMware installation. Its local IP address lived on a different subnet, which a UDP broadcast cannot reach beyond, and the desired Desktop/Reader connection never occurred.

This changeset addresses the issue by determining the local IP like this:
A) Examine the machine's network interfaces. Note that there could be several interfaces - my Win10 laptop has 11. Focus on the active Wi-Fi and Ethernet network interfaces and record their "interface metric" values.
B) Determine which interface the network stack will use for network traffic. Literature says the stack wants to use the interface with the lowest metric value. We want to prefer Wi-Fi over Ethernet. I have not seen a case where these criteria conflict, so the "winning" interface is selected thus:

  • IF a Wi-Fi interface is active, choose that
  • ELSE IF an Ethernet interface is active, choose that
  • ELSE declare 'none' and no adverts will be sent
    An interface is considered active if its interface metric is less than the initialized value of (2^31 - 1). On my machine at least, inactive interfaces all do maintain this initial value.
    C) Note the winning interface's IP address - it will be the Local IP address.
    D) Also note the winning interface's subnet mask and, in conjunction with the Local IP address, calculate the "Directed" broadcast address. This will be the Remote IP address to which Desktop advertising is sent. This replaces 255.255.255.255, which is the "Limited" broadcast address.
    E) Use Local IP to instantiate an IPEndPoint, then use that to instantiate a UdpClient.
    F) Use Remote IP to instantiate another IPEndPoint, then make UdpClient use it for sending book adverts.

This changeset also addresses a second issue that I encountered: occasionally the book advert got to Reader okay, and Reader replied with a book request, but Desktop never got the request. The Reader side looked good, as far as I could tell. I concluded that Desktop was perhaps listening on the wrong interface. I learned that Desktop's listening UdpClient can be instantiated such that it will listen on all interfaces. This is what the changes in BloomReaderUDPListener are for. UdpClient was previously instantiated without specifying an IP address, but now we specify 0.0.0.0 ("IPAddress.Any"). I have not experienced similar failures since.


This change is Reviewable

…to one of two files

Merged in the changes for BloomReaderUDPListener.cs. Next will do the same for WiFiAdvertiser.cs. Temporarily added some debug output to both files to aid in test and verification before re-PR'ing this set of changes.
Fixes wrong IP address being advertised which was, on my PC, preventing Desktop/Reader connection. These are the changes from PR 7231 that have significant merge conflicts. They will be resubmitted, after more testing and cleanup, on this branch.
Removed all Debug.WriteLine() calls. Reformatted some calls that somehow got automatically formatted (did csharpier do this?) I'm trying to minimize the diffs to be viewed in what will be the second version of this PR.
There is one substantive change: added a dispose call on the UdpClient in Stop(). Visual Studio asked for this since WiFiAdvertiser now inherits from IDisposable (which was a main part of the merge conflict).
What is doing this? Csharpier? Whatever it is, it's insistent - I reverted its changes once but it is doing it again on this commit. My give up, my give up...
Missed this one dealing when resolving the merge conflicts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant