Skip to content

GUACAMOLE-2284 : Add connection reachability status and WoL countdown notification#1208

Open
jairodmorales wants to merge 3 commits into
apache:mainfrom
jairodmorales:feature/wol-improvements
Open

GUACAMOLE-2284 : Add connection reachability status and WoL countdown notification#1208
jairodmorales wants to merge 3 commits into
apache:mainfrom
jairodmorales:feature/wol-improvements

Conversation

@jairodmorales

@jairodmorales jairodmorales commented May 17, 2026

Copy link
Copy Markdown

Summary

This PR adds two related features to improve the user experience when using Wake-on-LAN (WoL) connections in Apache Guacamole.


1. TCP reachability probe for connections

A new REST endpoint GET /api/session/data/{dataSource}/connections/reachable?ids=1,2,3 checks in parallel whether the host of each connection is reachable on its configured TCP port.

TCP is preferred over ICMP because Windows blocks ping by default while keeping the RDP/SSH port open when the machine is running.

A companion AngularJS service (connectionReachabilityService) polls this endpoint every 10 seconds and caches the results for use by templates.


2. Visual connection status indicator in the home screen

The connection icon in the home list gets a green tint (vm-running) when the host responds on its TCP port, or is dimmed (vm-stopped) when unreachable. The state unknown case (first poll pending) leaves the icon unchanged.


3. WoL countdown notification during WAITING state

When a connection enters the WAITING state and Wake-on-LAN is configured (wol-send-packet=true, wol-wait-time > 0), and the remote host was not reachable at connection time, a contextual message is displayed below the existing status notification:

  • A status line indicating the machine is off and WoL signal has been sent
  • A live countdown showing the estimated seconds remaining

The countdown is driven by $interval, is cancelled on state change or scope destroy, and uses reachable !== true (rather than === false) to also handle the case where the first poll has not yet completed.

UI strings are fully internationalised via en.json translation keys.


Files changed

Backend:

  • net/ReachabilityProbe.java (new) — parallel TCP probe with fixed thread pool (16 threads, 1 s timeout)
  • rest/connection/ConnectionDirectoryResource.java — new GET /reachable endpoint

Frontend:

  • rest/services/connectionReachabilityService.js (new) — polling service, exposes service.reachable{id: bool}
  • groupList/directives/guacGroupList.js — registers connection IDs per data source after building the list
  • home/templates/connection.html — applies vm-running/vm-stopped via ng-class
  • home/styles/home.css — green tint via CSS filter; opacity reduction for stopped state
  • client/directives/guacClientNotification.js — WoL countdown logic with reachability guard
  • client/templates/guacClientNotification.html — countdown UI using translate directive
  • client/styles/client.css — countdown styles
  • translations/en.json — adds CLIENT.INFO_WOL_MACHINE_OFF and CLIENT.INFO_WOL_CONNECTING

Testing

Tested against Guacamole 1.6.0 with RDP connections to Windows VMs and SSH connections to Linux VMs:

  • Connection list correctly reflects powered on/off state within 10 s of state change
  • WoL countdown appears only when the machine was confirmed off at connection time
  • Countdown reaches zero and disappears cleanly; connection completes normally
  • Timer is cancelled correctly on disconnect and on scope destroy (no interval leaks)
  • No change to existing behaviour when WoL is not configured

Homelab added 3 commits May 17, 2026 14:37
Adds a new REST endpoint GET /api/session/data/{ds}/connections/reachable
that accepts a list of connection IDs and returns a map of
{ connectionId: boolean } indicating whether each connection host is
currently reachable via TCP on its configured port.

The probe is performed in parallel using a fixed thread pool
(ReachabilityProbe). This is preferable to ICMP ping because Windows
blocks ICMP by default while keeping the RDP/SSH port open when running.

A companion AngularJS service (connectionReachabilityService) polls this
endpoint every 10 seconds and exposes the results for use by templates.
Uses the new connectionReachabilityService to apply a vm-running
or vm-stopped CSS class to each connection icon in the home screen,
giving visual feedback about whether the remote host is currently
reachable via TCP.

- guacGroupList.js: injects connectionReachabilityService, registers
  all connection IDs per data source after building the list, and
  exposes the service instance to child scopes via $scope.reachabilityService
- connection.html: applies vm-running / vm-stopped via ng-class
- home.css: vm-running applies a CSS filter to tint the icon green;
  vm-stopped reduces opacity to indicate an inactive host
When a connection enters the WAITING state and Wake-on-LAN is configured
(wol-send-packet=true, wol-wait-time>0), and the remote host was not
reachable at the time the connection was initiated, a contextual message
is displayed below the existing status notification:

  - A status line indicating the machine is powered off and WoL has been sent
  - A countdown showing the remaining estimated wait time in seconds

The countdown is driven by a $interval that decrements once per second
and is cancelled when the connection state changes or the scope is destroyed.

The condition 'reachable !== true' is used instead of '=== false' to
also handle the case where the first poll has not yet completed (undefined).

Translation keys added to en.json:
  CLIENT.INFO_WOL_MACHINE_OFF
  CLIENT.INFO_WOL_CONNECTING
@necouchman

necouchman commented May 17, 2026

Copy link
Copy Markdown
Contributor

@jairodmorales Thanks for contributing to the project and for opening this pull request. I appreciate your willingness to jump in and be involved in the community! Before I move forward with a detailed review, I have a couple of issues that I think are worth noting and discussing.

The easy one is that every change to the code needs a Jira ticket, and the pull request and commits need to be tagged with that Jira issue. You can see plenty examples of this in the existing pull requests, both opened and closed, and you can read more about our contribution guidelines, here: https://guacamole.apache.org/open-source/.

There are several other items that jump out at me as I do an initial review of the code that require a bit more thought and discussion to address. The short version is:

  • WoL currently happens in guacd code, and reachability checks probably should, too.
  • I'm not sure that having this functionality forcibly enabled or even enabled by default is a good idea.
  • The integration between guacd's WoL functionality and the timer/countdown implemented, here, on the client side, needs some work.

==TL;DR==

The most basic issue that I have with the proposed changes, and the more difficult one to address, is that the countdown timer and reach-ability checks all happens within the guacamole-client code. This is fine in many simpler installations of Guacamole, where the client (Tomcat) and the guacd processes run on the same system or network, and where that system can be expected to have access directly from Tomcat to the systems that you're trying to connect to, but it breaks down in more complex setups - and ones where Guacamole is specifically designed to operate - where guacd is sitting inside a remote network and the client components only have access to the guacd system and do not have direct access to the systems being managed. This is one of the reasons why the WoL packet is not sent directly from the Client (Java/Tomcat) components, and is, instead, implemented as part of the protocols within guacd.

I've given this some thought in the past as to how this could be accomplished, and the answer I've come up with is to implement some sort of TCP ping instruction as part of the Guacamole protocol, so that the Guacamole Client can reach out to guacd, give it a hostname or IP address and TCP port number, and ask it to verify whether the system is reachable or not. guacd can respond with a simple status (Up/Down, True/False, 0/1, etc.), and maybe with some other useful data (latency to the target, etc.). I haven't done much work on that, but I believe if the changes are going to be made as you've proposed, to the core of the existing Guacamole components, then that status communication must go through guacd and must operate under the assumption that the client-side components may not be able to directly access the remote system.

A couple of other assumptions that are made by the code that I'm not sure are good:

  • The code seems to be enabled, whether you like it or not. The assumption is that everyone will want their Guacamole instance doing reach-ability checks for any and all connections. The Guacamole instance that I use in my day job has over 500 connections in it, and the company already has a robust monitoring system in place - if I were to put this change in place I'd have my network, InfoSec, and monitoring teams all asking me what I'm doing and why.
  • Related to the comment above about the WoL functionality being implemented in guacd, there is no direct link between that functionality in guacd and the timer implemented here on the client-side. The assumption is that, if the client ends up in the WAITING state it must be waiting on Wake-on-LAN, that guacd has actually sent the WoL packet successfully and started its timer, and that the timer started on the client side (user's browser) must be close enough to the WoL timer on the guacd side that it's a good interval at which to retry the connection. That's a series of assumptions that aren't necessarily valid or accurate (at least not in many cases), and I'm not sure it's a great idea to implement this functionality without doing some more concrete linking between these client-side functions and guacd's WoL implementation.

The changes, here, could be implemented as a decorating extension, which would allow the functionality to be installed by admins in situations where they know it would work, and I'd probably be okay with that (with a few alterations). But I really do think the better way to go is to more concretely link the client-side visualization of reach-ability and WoL timer status into guacd.

Hopefully that makes sense - I'm happy to discuss further, so let me know what you think!

@jairodmorales

Copy link
Copy Markdown
Author

Hi @necouchman,

Thank you for the thorough review and for taking the time to explain the architectural concerns so clearly. I really appreciate it.

A bit about who I am

I'm a homelab enthusiast, not a professional developer. I run Apache Guacamole in my personal lab and have been using AI assistance (Claude) to help me implement features that I find useful but that are beyond my current coding skill level on my own. I want to be upfront about that so you have the right context when evaluating this contribution.

How this PR came about

My starting point was GUACAMOLE-2107 — a bug where guac_tcp_connect() returned inconsistent error codes, silently breaking Wake-on-LAN in Guacamole 1.6.0. The fix was merged into staging/1.6.1 via guacamole-server PR #609, but since it isn't in a stable release yet, I applied it locally. While testing WoL behavior I noticed two usability gaps:

There is no visual indication on the home screen of whether a machine is powered on or off.
When WoL is triggered and the connection enters the WAITING state, there is no feedback about how long to expect to wait — it just spins silently.
Those two observations led to this PR.

I understand the architectural concern now

After reading your review carefully I now understand why putting the TCP reachability check inside Tomcat is wrong: in real-world deployments guacd sits inside a private network and Tomcat may have no direct path to the managed systems at all — which is exactly the scenario Guacamole is designed for. The same reasoning is why WoL packet sending lives inside guacd and not in the Java client.

Revised plan based on your feedback

Based on your suggestion of implementing a TCP ping instruction as part of the Guacamole protocol, here is what I am proposing:

Define a TCP ping instruction in the Guacamole protocol — guacamole-client sends a batch request to guacd with a list of (hostname, port) pairs. guacd performs the TCP checks (since it has actual network access to the managed systems) and responds with a status per host (up/down) and optionally latency. (Affects: guacamole-server C codebase + protocol)
Implement the TCP ping handler in guacd — guacd attempts a TCP connection to each target and returns the result. (Affects: guacamole-server)
Implement the client-side handler in guacamole-client — Tomcat sends the batch ping request on page load and caches results briefly to avoid flooding guacd. (Affects: guacamole-client Java backend)
Make the feature opt-in — Add a guacamole.properties flag so the feature is disabled by default and does not impact large installations with existing monitoring systems. (Affects: guacamole-client)
Visual indicator on the home screen — Connection icons reflect the state returned by guacd. (Affects: guacamole-client frontend)
WoL countdown notification — When entering WAITING state with WoL configured, show a live countdown based on wol-wait-time, informed by the ping result rather than a client-side probe. (Affects: guacamole-client frontend)
One note on Jira

I have requested an Apache Jira account but I am still waiting for approval. I will create the corresponding ticket and tag this PR as soon as access is granted.

My question

Given my profile as a non-professional contributor working with AI assistance, do you think it is worthwhile for me to continue pursuing this? I want to make sure I am not wasting the project's review time if this type of contribution is not a good fit. I am happy to iterate and learn either way.

Thank you again for your patience and guidance.

@necouchman

necouchman commented May 22, 2026

Copy link
Copy Markdown
Contributor

Hi @necouchman,

Thank you for the thorough review and for taking the time to explain the architectural concerns so clearly. I really appreciate it.

Of course. Thank you for being open to the conversation.

A bit about who I am

I'm a homelab enthusiast, not a professional developer. I run Apache Guacamole in my personal lab and have been using AI assistance (Claude) to help me implement features that I find useful but that are beyond my current coding skill level on my own. I want to be upfront about that so you have the right context when evaluating this contribution.

I'm not a professional developer, either - I'm a manager/director of systems engineers/admins. So, no need to let that dissuade you. I contribute to Guacamole as a hobby and because I use it in my Day Job.

The AI piece is fine, too, according to Apache's guidelines, so long as you can be reasonably certain that the code it is giving you is not stolen from some other person or organization in violation of licensing/copyright/copyleft restrictions.

How this PR came about

My starting point was GUACAMOLE-2107 — a bug where guac_tcp_connect() returned inconsistent error codes, silently breaking Wake-on-LAN in Guacamole 1.6.0. The fix was merged into staging/1.6.1 via guacamole-server PR #609, but since it isn't in a stable release yet, I applied it locally. While testing WoL behavior I noticed two usability gaps:

There is no visual indication on the home screen of whether a machine is powered on or off. When WoL is triggered and the connection enters the WAITING state, there is no feedback about how long to expect to wait — it just spins silently. Those two observations led to this PR.

Yep, this is certainly an area where it could use some improvement, and you're not the first to notice or ask about it.

I understand the architectural concern now

After reading your review carefully I now understand why putting the TCP reachability check inside Tomcat is wrong: in real-world deployments guacd sits inside a private network and Tomcat may have no direct path to the managed systems at all — which is exactly the scenario Guacamole is designed for. The same reasoning is why WoL packet sending lives inside guacd and not in the Java client.

Revised plan based on your feedback

Based on your suggestion of implementing a TCP ping instruction as part of the Guacamole protocol, here is what I am proposing:

Define a TCP ping instruction in the Guacamole protocol — guacamole-client sends a batch request to guacd with a list of (hostname, port) pairs. guacd performs the TCP checks (since it has actual network access to the managed systems) and responds with a status per host (up/down) and optionally latency. (Affects: guacamole-server C codebase + protocol) Implement the TCP ping handler in guacd — guacd attempts a TCP connection to each target and returns the result. (Affects: guacamole-server) Implement the client-side handler in guacamole-client — Tomcat sends the batch ping request on page load and caches results briefly to avoid flooding guacd. (Affects: guacamole-client Java backend) Make the feature opt-in — Add a guacamole.properties flag so the feature is disabled by default and does not impact large installations with existing monitoring systems. (Affects: guacamole-client) Visual indicator on the home screen — Connection icons reflect the state returned by guacd. (Affects: guacamole-client frontend) WoL countdown notification — When entering WAITING state with WoL configured, show a live countdown based on wol-wait-time, informed by the ping result rather than a client-side probe. (Affects: guacamole-client frontend) One note on Jira

At a high-level I think this sounds reasonable - once we get into the details of implementing and reviewing the code there may be some suggestions and changes to it, but this sounds like a plausible solution. Also, I'm one voice in the existing community of Guacamole developers/committers/PMC members, so other folks may have feedback for you, as well.

I have requested an Apache Jira account but I am still waiting for approval. I will create the corresponding ticket and tag this PR as soon as access is granted.

I believe your account has now been approved.

My question

Given my profile as a non-professional contributor working with AI assistance, do you think it is worthwhile for me to continue pursuing this? I want to make sure I am not wasting the project's review time if this type of contribution is not a good fit. I am happy to iterate and learn either way.

Yes! We welcome contributions from anyone in the community, provided you're willing to take the time to work through our feedback and review process, incorporate our feedback into the code, and see it through to completion.

@jairodmorales jairodmorales changed the title Add connection reachability status and WoL countdown notification Guacamole-2284 : Add connection reachability status and WoL countdown notification May 29, 2026
@jairodmorales jairodmorales changed the title Guacamole-2284 : Add connection reachability status and WoL countdown notification GUACAMOLE-2284 : Add connection reachability status and WoL countdown notification May 29, 2026
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.

2 participants