Network Hosts — Infrastructure Services¶
Network hosts are infrastructure-level servers that the rest of the system depends on during startup. They are not user-hosted features; they are fixed, always-on services that provide two functions:
| Host | Plugin type | Purpose |
|---|---|---|
| NetworkHost | ePluginTypeHostNetwork |
Directory / registry — stores and serves the list of active user hosts |
| ConnectionTestHost | ePluginTypeHostConnectTest |
Connectivity test — reports the caller's external IP address and whether its TCP port is reachable |
Both hosts are implemented as plugins derived from PluginBaseNetworkService
(libs/libptopengine/Plugins/PluginNetworkHost.cpp,
libs/libptopengine/Plugins/PluginConnectionTestHost.cpp).
Startup and Resolution¶
Resolution is driven by NetServicesMgr (libs/libptopengine/NetServices/), which owns a worker
thread that executes a queue of NetActionBase actions sequentially.
Step 1 — Wait for internet (NetActionWaitForInternet)¶
The engine does nothing until a local IP address is detected.
Step 2 — Resolve ConnectionTest URL (NetActionResolveConnectTestUrl)¶
- Reads
connectTestUrlfromEngineSettings. - Calls
VxResolvePtopUrl()on the URL to get the host IP. If the resolved IP matches our own external or local address the engine notes that we are the ConnectionTest host and marksconnectionTestAvail = trueimmediately. - Otherwise, calls
ConnectionMgr::applyDefaultHostUrl(eHostTypeConnectTest, url)which initiates a TCP handshake to the URL. During handshake the remote peer'sPktAnnouncepacket supplies itsVxGUID(online ID), which is cached inHostUrlListMgr. - Polls
ConnectionMgr::getDefaultHostOnlineId(eHostTypeConnectTest)for up to 20 seconds. - As a side-effect, also fires off
applyDefaultHostUrl(eHostTypeNetwork, networkHostUrl)in parallel so both hosts can resolve concurrently.
Step 3 — Resolve NetworkHost URL (NetActionResolveNetworkHostUrl)¶
Same pattern as step 2 but for networkHostUrl. Polls for up to 22 seconds.
Step 4 — Resolve Default User-Host URLs (NetActionResolveDefaultUserHosts)¶
Applies the configured URL for eHostTypeRandomConnect, eHostTypeGroup, and
eHostTypeChatRoom to ConnectionMgr so client plugins can connect to them later.
Note:
EngineSettingshas three separate getters —getRandomConnectUrl,getGroupHostUrl,getChatRoomHostUrl— for the three user-service URL settings.
Re-queuing¶
addNetActionToQueue() deduplicates: if an action is already in the queue it is not added again.
A 15-minute periodic timer fires onThreadOncePer15Minutes on each plugin, which re-triggers
sendHostAnnounce() on user hosts.
NetworkHost — Directory Service¶
Class: PluginNetworkHost
Plugin type: ePluginTypeHostNetwork
Role¶
The NetworkHost is the central directory for all user hosts (GroupHost, ChatRoomHost, RandomConnectHost). User hosts connect to it and announce themselves. Clients query it to discover which user hosts are currently available.
Incoming packet handlers¶
| Packet | Handler | What it does |
|---|---|---|
PktHostInviteAnnounceReq |
onPktHostInviteAnnReq |
A user host announces itself. Payload contains host type, invite URL, title, description, thumbnail ID, and modification timestamp. Stored in HostServerSearchMgr under the appropriate announce list (m_ChatRoomHostAnnList, m_GroupHostAnnList, m_RandConnectHostAnnList). After processing, temporary connections are closed. |
PktHostInviteSearchReq |
onPktHostInviteSearchReq |
A client requests the list of hosts of a given type. Delegates to HostServerSearchMgr::onPktHostInviteSearchReq which serialises matching HostSearchEntry records into a PktHostInviteSearchReply blob and sends it back. |
PktHostInviteSearchReply |
onPktHostInviteSearchReply |
NetworkHost acting as a client of another NetworkHost (not current use). |
PktHostInviteMoreReq |
onPktHostInviteMoreReq |
Pagination — client requests the next page of results. |
PktHostInviteMoreReply |
onPktHostInviteMoreReply |
Pagination reply (client role). |
Announce list maintenance¶
HostServerSearchMgr keeps one std::map<PluginId, HostSearchEntry> per host type.
Each HostSearchEntry records the last-received announce timestamp.
A host is considered offline if no announce has been received within
MIN_HOST_RX_UPDATE_TIME_MS (30 minutes).
Self-announce shortcut¶
When the running node is also a NetworkHost, user host plugins detect this:
if( netHostUrl.getOnlineId() == m_Engine.getMyOnlineId() )
{
// directly call updateHostSearchList on our own NetworkHost plugin
netHostPlugin->updateHostSearchList( ... );
// skip network round-trip
}
ConnectionTestHost — Connectivity Test Service¶
Class: PluginConnectionTestHost
Plugin type: ePluginTypeHostConnectTest
Role¶
The ConnectionTestHost answers two questions for its callers:
- What is my external IP address? — The host sees the caller's source IP and echoes it back.
- Is my TCP listen port reachable from the internet? — The host attempts to dial back the caller on its claimed listen port; success means the port is open.
Transport¶
ConnectionTestHost uses the lightweight NetService HTTP-like command protocol rather than
the full P2P packet protocol. All commands arrive through handlePtopConnection() as
NetServiceHdr structs.
Command types handled¶
| Command constant | String on wire | Purpose |
|---|---|---|
eNetCmdClientPing |
CMD_CLIENT_PING |
Caller sends a ping; host echoes a pong containing the caller's seen IP address. |
eNetCmdClientPong |
CMD_CLIENT_PONG |
Reply to the host-initiated ping (see port-open test below). |
eNetCmdIsMyPortOpenReq |
CMD_PORT_TEST_REQ |
Caller asks: "is my port N open?" Host attempts an outbound TCP connect to the caller's IP:port, then replies with success/fail. |
eNetCmdIsMyPortOpenReply |
CMD_PORT_TEST_REPLY |
Reply carrying ENetCmdError and the caller's external IP string. |
Port-open test flow¶
Client ConnectionTestHost
| |
|--- CMD_PORT_TEST_REQ (myPort=N) ------>|
| |--- TCP connect attempt to Client:N
|<--- CMD_PORT_TEST_REPLY (ok/fail) -----|
NetServicesMgr::doIsMyPortOpen() drives this sequence and stores the result in
NetStatusAccum. The result is raised via netActionResultIsMyPortOpen() → callback →
toGuiNetworkState().
Loopback sanity check¶
Before contacting the ConnectionTest host, the engine first performs a loopback ping on the
local IP:port to verify the listen socket is working (testLoobackPing). If the loopback
fails the port-open test is not attempted.
Network Status Summary¶
After resolution completes, NetStatusAccum tracks:
| Flag | Meaning |
|---|---|
isNetHostAvailable() |
NetworkHost URL resolved to a valid online ID |
isConnectionTestAvailable() |
ConnectionTest URL resolved to a valid online ID |
isRxPortOpen() |
Port-open test confirmed external port is reachable |
isDirectConnectTested() |
At least one successful direct connect test done |
canAnnounceToNlcHost() |
NetworkHost available AND port is open — user hosts may announce |
User hosts check canAnnounceToNlcHost() before every sendHostAnnounce() call.