Skip to content
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

GUACAMOLE-249: Migrate to FreeRDP 2.x #243

Merged
merged 109 commits into from
Jan 14, 2020

Conversation

mike-jumper
Copy link
Contributor

This change refactors the entirety of Guacamole's RDP support to use FreeRDP 2.x, removing any remaining compatibility with older FreeRDP releases. These changes also:

  • Reorganize the source tree in the hopes of making things more maintainable going forward
  • Add missing documentation
  • Add support for the new "extended NLA" mode added by FreeRDP 2.x (I'm not entirely sure what this is, however) and switch over to "any" as the default security method (rather than "rdp").
  • Remove most plugins, replacing guacsvc/guacsnd/guacdr with a single common SVC plugin. The RDP support leverages that common plugin to provide a single API which the arbitrary SVC, RDPSND, and RDPDR support then use without having to make plugins for each.

There are going to be conflicts with master for the following non-1.1.0 changes:

  • GUACAMOLE-296 - Migrating to FreeRDP 2.x removes the need for this, as libwinpr is now automatically linked using pkgconfig.
  • GUACAMOLE-381 - Support for clipboard copy/paste disable flags within CLIPRDR need to be manually re-added due to the number of changes made to CLIPRDR (see below). Much of this applies cleanly without conflict.
  • GUACAMOLE-764 - Most applied cleanly without conflict, however one int -> uint64_t change has to be reapplied manually (see below).
  • GUACAMOLE-847 - The RDPSND memory leak is now inherently resolved via the common SVC plugin and changes to channel memory handling in FreeRDP 2.x.

To hopefully ease this, I've performed a test merge and manually resolved the above conflicts. I recommend resolving conflicts such that things match: https://github.com/mike-jumper/guacamole-server/tree/freerdp-migrate-2.x-resolve-merge-master

... Good luck.

…. If accepting the certificate, request that FreeRDP not store it.
…mats.

The "CB_FORMAT_*" constants which used to be defined by FreeRDP no
longer exist.
Most plugins built into FreeRDP implement the PVIRTUALCHANNELENTRYEX
entry point, but the FreeRDP standard function for loading plugins only
supports PVIRTUALCHANNELENTRY. It appears that only the commandline
argument parser included with FreeRDP was updated to leverage the new
entry points.
The CLIPRDR specification requires that the msgFlags field for the
Format List PDU be set to 0x0000. The function within FreeRDP overrides
this value to 0x0000, but it is still incorrect to attempt to set it.
@mike-jumper
Copy link
Contributor Author

mike-jumper commented Jan 13, 2020

After fixing the RAIL issue, I encountered the following:

...
  CC       libguac_client_rdp_la-color.lo
color.c: In function 'guac_rdp_convert_color':
color.c:62:16: error: implicit declaration of function 'FreeRDPConvertColor'; did you mean 'ConvertColor'? [-Werror=implicit-function-declaration]
     intermed = FreeRDPConvertColor(intermed, src_format, dst_format,
                ^~~~~~~~~~~~~~~~~~~
                ConvertColor
cc1: all warnings being treated as errors

Apparently, the FreeRDPConverColor() function was formerly known as ConvertColor(). It was renamed along with similarly-named functions due to Mac applications using GetColor() failing to build because that function clashes with a system function of the same name (see FreeRDP/FreeRDP#3810).

Adding tests to determine the proper function doesn't appear to be an option at the moment, as:

  • The necessary include path for FreeRDP is only known via pkg-config and I'm unaware of any way to get autoconf tests to find headers that can only be found when using the CFLAGS returned by pkg-config.
  • We can't simply test version numbers because all of these FreeRDP variants have the same version.

I tried addressing this by switching to ConvertColor(), which should work due to compatibility macros present in the FreeRDP headers. But, I then encountered issues with the glyph callbacks:

  CC       libguac_client_rdp_la-rdp.lo
rdp.c: In function 'rdp_freerdp_pre_connect':
rdp.c:155:16: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     glyph.Draw = guac_rdp_glyph_draw;
                ^
rdp.c:156:21: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     glyph.BeginDraw = guac_rdp_glyph_begindraw;
                     ^
rdp.c:157:19: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     glyph.EndDraw = guac_rdp_glyph_enddraw;
                   ^
cc1: all warnings being treated as errors

In this case, the incompatibility is due to switching from UINT32 to INT32 for width and height. At this point, I'm thinking we simply shouldn't support the version of FreeRDP on Bionic. The version of the API in use appears to be unique to Bionic and from before any 2.0.0 release candidate was made.

I've also created some Jenkins jobs to verify the build, so we should be able to better ensure build compatibility going forward:

@mike-jumper
Copy link
Contributor Author

Rerunning builds for all FreeRDP tags, it looks like the current code will build only against 2.0.0-rc4. Earlier tags suffer from the issues noted above for Bionic.

Copy link
Contributor

@necouchman necouchman left a comment

Choose a reason for hiding this comment

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

Going to pull the latest version and test, again.

@necouchman
Copy link
Contributor

Rerunning builds for all FreeRDP tags, it looks like the current code will build only against 2.0.0-rc4. Earlier tags suffer from the issues noted above for Bionic.

Lovely...so we're tied to a current RC of FreeRDP 2. That feels safe.

@mike-jumper
Copy link
Contributor Author

Lovely...so we're tied to a current RC of FreeRDP 2. That feels safe.

Well, 2.0.0-rc4 and master, but yeah - I know what you mean.

I'm not necessarily against trying to be compatible with rc0 through rc3, but I'm not sure how we would distinguish them. It doesn't seem possible to write configure tests because of pkg-config, and the version numbers are identical, even within FreeRDP's version.h.

2.0.0-rc0

#define FREERDP_VERSION_MAJOR 2
#define FREERDP_VERSION_MINOR 0
#define FREERDP_VERSION_REVISION 0
#define FREERDP_VERSION_SUFFIX "dev5"
#define FREERDP_API_VERSION "2"
#define FREERDP_VERSION "2.0.0"
#define FREERDP_VERSION_FULL "2.0.0-dev5"
#define GIT_REVISION "326a44895"

2.0.0-rc4

#define FREERDP_VERSION_MAJOR 2
#define FREERDP_VERSION_MINOR 0
#define FREERDP_VERSION_REVISION 0
#define FREERDP_VERSION_SUFFIX "dev5"
#define FREERDP_API_VERSION "2"
#define FREERDP_VERSION "2.0.0"
#define FREERDP_VERSION_FULL "2.0.0-dev5"
#define GIT_REVISION "326a44895"

@mike-jumper
Copy link
Contributor Author

I'll try nested autoconf. Perhaps adding a configure script which is dedicated to RDP and which is invoked by the top-level configure script will allow us to perform tests which inherit flags from pkg-config.

@mike-jumper
Copy link
Contributor Author

aHA! Manually setting CPPFLAGS within seems to allow tests to work, as it adds the needed -I flags globally:

    PKG_CHECK_MODULES([RDP], [freerdp2 freerdp-client2 winpr2],
                      [CPPFLAGS="${RDP_CFLAGS} $CPPFLAGS"],
                      [AC_MSG_WARN([

The downside is that it adds the flags globally. It shouldn't hurt the build, as part of the reason this is so cumbersome is that FreeRDP 2.x is double-namespaced, with headers being within freerdp2/freerdp/.

…nvertColor(), but was only available as ConvertColor() in older FreeRDP 2.0.0 release candidates.
@mike-jumper
Copy link
Contributor Author

OK, I'm having success with configure tests and am rewriting the previous typecast solutions for CLIPRDR, RAIL, etc. to instead use tests. This should be more future-proof in the sense that we'll get obvious build failures if API compatibility breaks, and it should allow us to support FreeRDP: Bionic Edition as well as 2.0.0-rc0 onward.

@necouchman
Copy link
Contributor

Everything looks good with CentOS7 with 2.0.0-rc4

@mike-jumper
Copy link
Contributor Author

OK, I've added configure tests and things seem to build across the board now: git master, 2.0.0-rc0 through 2.0.0-rc4, as well as Bionic Edition.

The ASF Jenkins instance is too backed up at the moment to be used to verify the builds, but I'm doing so manually on my own dev machine via Docker.

@mike-jumper
Copy link
Contributor Author

I've manually confirmed on:

  • CentOS 7
  • Fedora 29, 30, and 31
  • Debian stable and testing
  • Ubuntu Bionic, Disco, and Eoan
  • Builds of FreeRDP from source using 2.0.0-rc0, 2.0.0-rc1, 2.0.0-rc2, 2.0.0-rc3, 2.0.0-rc4, and master

I think we're good to go.

@necouchman
Copy link
Contributor

Sounds good. Giving @jmuehlner one last chance to throw in any input - otherwise I'll plan to merge it later today.

You mentioned needing to deal with conflicts in the master - anything special that we need to worry about for that?

@mike-jumper
Copy link
Contributor Author

You mentioned needing to deal with conflicts in the master - anything special that we need to worry about for that?

Only that these conflicts are likely to be more difficult to resolve than the usual conflicts. I've tried to summarize the specific issues that conflicted and how to resolve in the issue description. AFAIK, there's no real way to provide a patch which addresses merge conflicts, but I went ahead and performed the merge myself as a test, manually resolving the conflicts, and have been cherry-picking any new commits to that branch since then:

https://github.com/mike-jumper/guacamole-server/tree/freerdp-migrate-2.x-resolve-merge-master

My hope is that the above branch might help in verifying the result of the merge and/or in guiding the resolution of the conflicts.

@necouchman
Copy link
Contributor

Sounds good...I think it's go time...

:shipit:

@necouchman necouchman merged commit 3e22526 into apache:staging/1.1.0 Jan 14, 2020
@mike-jumper mike-jumper deleted the freerdp-migrate-2.x branch January 14, 2020 19:21
@necouchman
Copy link
Contributor

Okay, merge to staging/1.1.0 is done. I have to step out for a little while, but will work through the merge to master here, shortly.

@necouchman
Copy link
Contributor

Merge to master completed. I had to work around a couple of settings that got added into master, but I think I've managed to do it without clobbering any of the updates that have happened to master in the meantime. There's certainly an off-chance we'll have to go back and fix something that I accidentally undid, but I tried to go back and verify a few times that nothing substantial was removed.

@mike-jumper
Copy link
Contributor Author

Looks real solid. I just manually tried merging the previous HEAD of master onto my test merge resolution branch, resolved the conflicts manually, and the diff against current master showed no differences at all ... except for a new CLIPRDR-related log message.

I think that log message should probably be removed, and I will open a PR to that effect in a moment.

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.

3 participants