General

149 posts tagged with "General" (See all Category)

Atom Feed

Experiments with Matrix for the Purism Librem5, starring Ubports and Nheko

28.09.2017 00:00 — General Matthew Hodgson

TL;DR: If you love FOSS-friendly hardware and if you love Matrix, please preorder a Purism Librem5 Matrix-native smartphone, so we can fully bring native Matrix communication to both phones and desktop!

It's been just over a month since Purism announced the campaign to fund the Matrix-native Librem5 FOSS smartphone - and the campaign is doing pretty well, with 54% of its target reached as of the time of writing!  So in a shameless attempt to whet everyone's appetite and encourage everyone to fund the remaining 50%, we thought we'd share some of the experiments we've been doing with running native Matrix clients on a pure Linux phone.

Unfortunately the Librem5 doesn't exist yet, but we do happen to have an BQ Aquaris E5 Ubuntu Phone hanging around - so we wondered: Is it possible to run a native desktop Matrix client like mujx's Nheko on a Linux phone, given all the latest Qt voodoo? And just how hard is it anyway to update the Qt platform abstractions (or GTK for that matter) for a given platform?  In retrospect, we probably should have just run uMatriks on it - a proper dedicated Ubuntu Touch Matrix Client, but then we wouldn't have had a useful tour of maintaining the guts of a Qt distribution on mobile :)

So the core problem of running a client like Nheko on Ubuntu Touch is that it uses lots of fun glossy stuff from Qt 5.9, whereas Ubuntu Touch is still on Qt 5.4, which is over 2 years old now.  Also, it's been written as a desktop client so needs a bit of tuning to support a 'fat-finger' mobile form factor, although this is just a simple matter of programming and is a very similar problem to ensuring the desktop app has a nice responsive design on small screen window sizes (similar to how the telegram desktop client handles it).  In the end, we focused on solving the Qt problem: building a custom Qt 5.9 for Ubports (the community project who do a fantastic job of continuing Ubuntu Touch development since Canonical pulled out), while for simplicity building it on top of the current ubports distribution (which is effectively still Ubuntu 15.04).  The reason for all this Ubuntu stuff rather than using PureOS is simply that it's not far enough along, and we don't physically have a Librem5 dev kit yet to play with!

In practice, this has been a fascinating process: setting up a crosscompiler to build all of Qt5.9, and then porting the ubuntumirclient Qt Platform Abstraction to work with Qt5.9, as well as (finally) working out how to build a Qt5.9-compatible custom Maliit input context platform plugin to get the onscreen keyboard (OSK) up and running.  But we got there in the end, and it was rather fun to finally see the Nheko splash screen popping up on the Aquaris E5! :D

There was then a bit of a nightmare to get the OSK to work, thanks to https://bugreports.qt.io/browse/QTBUG-46009 causing the plugin to be silently not updated - but could then log in and the app worked great (albeit a bit slow thanks to being a debug build on the energy-efficient but slow Mediatek MT6582 SoC):

   
Now the next step here would obviously be to tweak the app properly to layout on a phone (bigger fonts; bigger buttons; resize the window to make room for the OSK; separate the Left Panel from the timeline view; etc) - but the point here was more to show a fully fledged native Matrix client running on a current Linux Phone environment and see how it feels.  And we're happy to say that it leaves us dying to get our hands on a proper Librem5 so we can work with Nheko, uMatriks, libqmatrixclient and all the other native Matrix client projects to see how we can get the best possible native client experience running in PureOS for the phone!!

Finally, there doesn't seem to be much documentation out there on how to do a heavy customisation of Ubports like this, so for the sake of posterity, here's the guide if anyone else is crazy enough to try this (or for when Ubports gets around to doing an official update to Qt 5.9 for their OS!).  A versioned copy of this lives over at this gist.

Thanks for reading, and don't forget to preorder!

Matthew

🔗Recipe: Librem5 experiments with an Ubuntu Phone and Nheko

Starting point: one old BQ Aquaris E5 ubuntu phone, running some old version of Ubuntu Touch which had got completely stuck (UI only unfreezing for 2-3 seconds every 2-3 minutes).

Step one: flash to latest UBPorts image:

sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
sudo apt-get update
sudo apt-get install ubuntu-device-flash
sudo apt-get install phablet-tools
  • Grab an adb-compatible recovery image (yes, seems like the right place is someone's personal webspace...)
wget http://people.canonical.com/~jhm/barajas/recovery-vegetahd.img
  • If your Ubuntu desktop is running in a VM, make sure you have USB 2.0 or 3.0 support enabled (in Virtualbox this needs the extension pack installed). USB 1 is too slow and the flash will timeout, semi-bricking the phone.
  • Press volume-up and power on the phone during boot to get at the bootloader. Make sure it's not plugged into USB
  • Select fastboot
  • Plug into USB
  • Flash the recovery image and latest UBPorts OS:
sudo ubuntu-device-flash --server=http://system-image.ubports.com touch --device=vegetahd \\
                         --channel=15.04/stable --bootstrap --recovery-image=recovery-vegetahd.img \\
                         --developer-mode --password=secret
  • Ensure the system OS is writable. (Ubuntu Touch runs the OS partition read-only by default to protect users. In this case, you can always re-flash it if all goes wrong.)
sudo phablet-config writable-image
  • Get an SSH server running on the phone before you go insane
adb shell
sudo /etc/init.d/ssh start # password is as set when flashing.
Step two: cross-compile latest Qt 5.9 for the phone.

Ubuntu 15.04 shipped with 5.4, which is pretty old now, and too old for nheko. Based on https://rm5248.com/cross-compile-qt-for-arm/

# grab the source for Qt5
git clone git://code.qt.io/qt/qt5.git
cd qt5
./init-repository

# grab the right dev headers (as qtubuntu needs dbus & atspi support)
ssh phablet@phone "sudo apt-get install libdbus-1-dev libatspi2.0-dev libssl-dev"

# grab a copy of the root filesystem on the phone for the cross-compile to run against.
# you could also sshfs mount or something if you could be bothered.
mkdir ~/phone
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
export ROOTFS=~/phone

# install the crosscompiler.
# We probably have to use GCC 4.9 so that it can link ok against the older system libraries
# (libstdc++ etc) on Ubuntu Touch 15.04
sudo apt-get install arm-linux-gnueabihf-g++-4.9

# fix up the absolute symlinks (important!)
cd ~
git clone https://github.com/rm5248/cross-compile-tools.git
./cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# define a mkspec target for armhf
cd ~/qt5
cp -a qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/linux-arm-gnueabihf-g++
cat > qtbase/mkspecs/linux-arm-gnueabihf-g++/qmake.conf <<EOT
#
# qmake configuration for building with arm-linux-gnueabihf-g++
#

MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib

include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)

# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabihf-gcc-4.9
QMAKE_CXX               = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK              = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK_SHLIB        = arm-linux-gnueabihf-g++-4.9

# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabihf-objcopy
QMAKE_NM                = arm-linux-gnueabihf-nm -P
QMAKE_STRIP             = arm-linux-gnueabihf-strip

!host_build {'{'}
        QMAKE_INCDIR_OPENGL     = $ROOTFS/usr/include/GL
        QMAKE_LIBDIR_OPENGL     = $ROOTFS/usr/lib/arm-linux-gnueabihf
        # GCC 4.9 apparently doesn't know where its own libstdc++ headers are when cross-compiling...
        QMAKE_INCDIR            = /usr/arm-linux-gnueabihf/include/c++/4.9.3 \\
                                  /usr/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf
{'}'}

load(qt_config)
EOT

# build it!
./configure \\
    -v \\
    -confirm-license \\
    -prefix /opt/qt5-arm \\
    -sysroot $ROOTFS \\
    -opensource \\
    -nomake examples \\
    -nomake tests \\
    -opengl es2 \\
    -qpa ubuntumirclient \\
    -xplatform linux-arm-gnueabihf-g++ \\
    -platform linux-g++ \\
    -feature-accessibility \\
    -feature-accessibility-atspi-bridge \\
    -feature-webrtc \\
    -feature-proprietary-codecs \\
    -reduce-exports

make -j8

# go to lunch

make install

If anything goes wrong, a good bet (having backed up your new mkspec target) is to git clean everything:

git submodule foreach --recursive "git clean -dfx"
git clean -dfx

Step 3: compile qtubuntu for Ubuntu-specific Qt stuff like the integration with the Mir display server (hey, at this point it feels like we're building our very own zombie Ubuntu Touch 17.04... :/)

# grab dev package deps
ssh phablet@phone "sudo apt-get install libubuntu-application-api-dev libudev-dev"
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# grab the qtubuntu source
bzr branch lp:qtubuntu

# find an version old enough that it builds against the old mir in 15.04
bzr revert -r 345

# cherrypick patches so it builds against qt 5.9...
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/354
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/372
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/394
# ...we probably need others too.

/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++

# we probably should have told Qt about more pkgconfig libraries when we built it, so as to not have to do it manually here...
export PKG_CONFIG_LIBDIR=$ROOTFS/usr/lib/pkgconfig:$ROOTFS/usr/share/pkgconfig:\\
$ROOTFS/usr/lib/arm-linux-gnueabihf/pkgconfig/:$ROOTFS/opt/qt5-arm/lib/pkgconfig/
export PKG_CONFIG_SYSROOT_DIR=$ROOTFS

# might need to manually explicitify the --sysroot definitions in qt's qconfig.pri
# as otherwise QT_SYSROOT seems not to be getting picked up for reasons unknown

make -j4
cp src/ubuntumirclient/libqpa-ubuntumirclient.so $ROOTFS/opt/qt5-arm/plugins/platforms/

# Need to build our own libmaliitphabletplatforminputcontextplugin.so for onscreen keyboard, as
# you can't mix Qt platform plugins between versions - see https://bugreports.qt.io/browse/QTBUG-46009
cd
bzr branch lp:ubuntu/vivid/maliit-framework
cd maliit-framework
# add QMAKE_LFLAGS+='-lQt5Network -lGLESv2' to config.pri

# technically don't need to build all of maliit - only the platform inputcontext plugin is required
export QMAKEMODULES=/mnt/build/qt5/qtdeclarative/mkspecs/modules 
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++
make -j4

# build the input-context plugin
cd input-context
# change the version of the plugin in main.cpp so that it's picked up by Qt 5.9 (the API hasn't changed;
# it's just the difference between an explicit and implicit version):
# Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" FILE "maliit.json")
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++

make -j4
make install

# rsync our beautiful new Qt5.9 over to the phone, including the qtubuntu plugin
rsync -avz $ROOTFS/opt/qt5-arm root@phone:/opt/

Step 4: cross-compile nheko as an experiment

# check it out
git clone --recursive git+ssh://[email protected]/mujx/nheko
cd nheko

# define a cross-compile toolchain (https://cmake.org/Wiki/CMake_Cross_Compiling)
cat > Toolchain-arm-linux-gnueabihf.cmake <<EOT
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
# this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# needed to get the right flavour of ARM
SET(CMAKE_SYSTEM_PROCESSOR armv7)

# specify the cross compiler
SET(CMAKE_C_COMPILER   /usr/bin/arm-linux-gnueabihf-gcc-4.9)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++-4.9)

# where is the target environment
SET(CMAKE_SYSROOT  $ROOTFS)
SET(CMAKE_FIND_ROOT_PATH  $ROOTFS)

# sort out our includes...
SET(CMAKE_CXX_FLAGS "${'{'}CMAKE_CXX_FLAGS{'}'} \\
    -I$ROOTFS/usr/include/c++/4.9 \\
    -I$ROOTFS/usr/include/arm-linux-gnueabihf \\
    -I$ROOTFS/usr/include/arm-linux-gnueabihf/c++/4.9")

SET(CMAKE_EXE_LINKER_FLAGS "${'{'}CMAKE_EXE_LINKER_FLAGS{'}'} \\
  $ROOTFS/lib/arm-linux-gnueabihf/libc.so.6 \\
  $ROOTFS/usr/lib/arm-linux-gnueabihf/libm.so \\
  $ROOTFS/usr/lib/arm-linux-gnueabihf/libhybris-egl/libGLESv2.so.2")

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

SET(CMAKE_PREFIX_PATH $ROOTFS/opt/qt5-arm)
EOT

# grab its dependencies on the phone and sync them over to your local phone FS copy
ssh phablet@phone 'sudo apt-get install liblmdb-dev'
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# gen the makefile
sudo apt-get install cmake
cmake -DLMDB_LIBRARY=$ROOTFS/usr/lib/arm-linux-gnueabihf/liblmdb.so \\
      -DCMAKE_TOOLCHAIN_FILE=`pwd`/Toolchain-arm-linux-gnueabihf.cmake \\
      -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
# remove -march=native from CMakeLists.txt

# build it
VERBOSE=1 make -C build -j4

# XXX: you might need to touch the Toolchain file and then run again to pick up
# the CXX_FLAGS correctly for some reason.

# run it!
rsync -avz $ROOTFS/home/phablet/nheko phablet@phone:/home/phablet
ssh phablet@phone "export MIR_SOCKET=/run/user/32011/mir_socket;
                   ./build/nheko --desktop_file_hint=unity8"

# N.B. if debugging under gdb, use `handle SIGILL nostop`

Step 5: Package nheko

# make sure you have a manifest.json, nheko.png, nheko.apparmor and nheko.desktop.
# If you don't have an icon, the app won't show up.
# you can grab it from the matthew/mobile branch of github.com/matrix-org/nheko
click build ./
scp im.vector.nheko_0.1_all.click phablet@phone:

# install it
ssh phablet@phone pkcon install-local --allow-untrusted im.vector.nheko_0.1_all.click

# ...and then swipe down on the app listing to hopefully see the app there.
# if that doesn't work, you can manually launch it with:
ssh phablet@phone ubuntu-app-launch im.vector.nheko_nheko_0.1

PR

30.08.2017 00:00 — General Thomas Lant

🔗Press/Media Contact

You can reach us by email at [email protected], or reach Matthew or Amandine on Matrix via Riot.im (or your favourite Matrix client).

🔗Who is Matrix.org?

Matrix.org is the world leader in decentralised encrypted communication, with project lead Matthew Hodgson a regular speaker at conferences such as FOSDEM and decentralisation/privacy summits. In Sept 2016 Matrix released the world's first ever publicly audited end-to-end encryption “Olm”, based on the Double Ratchet Algorithm.

Matrix core team is based in London (UK) and Rennes (France).

🔗Branding Identity

Matrix logo, black on transparent background, PNG format (also available in SVG)

Matrix logo, white on transparent background, PNG format

The Librem 5 from Purism: A Matrix Native Smartphone.

24.08.2017 00:00 — General Matthew Hodgson

Hi folks,

This is a big news week in Matrixland: hot on the heels of releasing Matrix Widgets and Riot 0.12, we have another massive announcement to make!

We've been approached by Purism to partner up to provide the communications subsystem for their upcoming Librem 5 smartphone - for which they are launching a crowdfunding campaign starting today! The whole idea of the phone is to provide unprecedented privacy, security and autonomy by running an entirely FOSS Debian-based GNU/Linux stack (even including CPU & GPU drivers!), and we are incredibly proud and overexcited that the folks at Purism have asked the Matrix core team to provide the native dialler and messaging app for the phone.  Yes, this means that the phone will literally boot by default into Matrix for all its primary communications (although, being FOSS, you could of course use a different dialler if you wanted).  The intention is to be a very usable and flexible phone for folks who value freedom, privacy and simplicity over the (relative) quagmire of iOS or Android - and of course jumping way ahead of where Apple or Google are in terms of integrating next-generation communications into the very heart of the device.

This is unbelievably exciting, as Matrix's vision from the outset has been to provide an open, decentralised and encrypted alternative to the Public Telephone Network - and the idea of devices emerging which are native to Matrix is a dream come true. It also gives us the excuse that we've been looking for to produce a truly excellent lightweight native Matrix client, built to run on both handset and desktop devices, complete with end-to-end encryption.  We're not sure whether this is going to end up being Qt or GTK based yet, but expect to see the Matrix team getting a lot more involved in the current native Matrix client projects (nheko, Quaternion, ruma-gtk, matrix-glib-sdk, qmatrixclient etc) in future!

Depending on the success of the crowdfunding campaign, it may also give us scope to finally build out proper carrier-grade Matrix<->PSTN bridges: letting Matrix clients terminate and originate VoIP calls on the public phone network.  It's long been an embarrassment that Matrix hasn't had this given that pre-Matrix we spent our lives building commercial SIP gateways and softphones for telcos, and the ability to use Matrix as a proper VoIP softphone on dedicated hardware is incredibly appealing.  Obviously the phone will also support GSM calling, but the intention is to default to WebRTC calling using Matrix whenever the phone has good IP connectivity - making it truly an IP-first smartphone.

Now, this is obviously a very ambitious project, but we believe that Purism is able to deliver based on the work they've done already with crowdfunding and shipping Librem 15 and 13 laptops, shipping with as open a FOSS stack as is possible on contemporary hardware, complete with unique privacy features such as hardware kill-switches for Camera, Wifi, Bluetooth etc.  We met with them at GUADEC 2017 and subsequently heard trusted reports from DebConf 2017 of the quality of the hardware.  It seems that as the company has gathered experience their ambitious goals have become more and more attainable - and it's also interesting that their dev team is significantly made up of core Debian developers (including Chris Lamb, the Debian Project Leader for 2017).  We're particularly excited from a philosophical perspective that the Librem 5 is targeting the NXP (Freescale) i.MX6 or i.MX8 ARM-based processor and Vivante GPU - both of which can be run without any proprietary microcode or proprietary drivers.  From everything we've heard, this is going to be a spectacularly FOSS-friendly device.

So, if you're interested in being first to own the world's first ever Matrix-native phone, or if you want to support the creation of a kick-ass native Matrix desktop/handset client, or perhaps if you want carrier-grade VoIP in Matrix... then please head over to Puri.sm and join the campaign!  Needless to say, if the campaign is successful it will also significantly help Matrix's current funding situation.

Finally, for more context, here's a special mid-week episode of Matrix "Live", featuring Matthew and Todd Weaver, the CEO of Purism, discussing the Librem 5 and what it means for both Purism and Matrix!

As always, feedback on this project is very welcome - come tell us in #matrix:matrix.org what you think!  And thank you, if you choose to support this campaign :)

Matthew, Amandine & the team.

Introducing Matrix Widgets - including Jitsi video conferencing!

23.08.2017 00:00 — General Matthew Hodgson

Hi all,

We've been working hard over the last few months on the brand new concept of Matrix "widgets” (sometimes called “apps”, but we'll call them “widgets” here to be marginally less ambiguous) - and we're super excited to see an initial implementation of them land today in Riot/Web 0.12 (alongside always-on Rich Text Editor - the culmination of huge amounts of work by Aviral Dasgupta in his GSoC 2016 project and Luke from the core Matrix team).  For user-focused details about Riot 0.12 you should probably head over to the Riot blog; meanwhile we'll focus here on widgets from the developer perspective.

Widgets are a deceptively simple idea: the ability to pin small form-factor webapps (called widgets) into a given Matrix room, letting admins build up a dashboard of functionality which is then in common and automatically available to everyone who views that room.  You can think of it as being similar to installing an app onto a smartphone, but instead pulling it into a Matrix conversation.  This could be a Jitsi video conference, or a collaborative document editor, or a Grafana dashboard, or anything you can imagine really (assuming its security headers support embedding).  Here's an example of a room with an ongoing Jitsi conference coupled with a Grafana graph, as you might use for a devops war room:

The URLs of the widgets are stored in the state of the room with some high-level layout hints, and the idea is that any Matrix client will be able to expose the widgets for the current room to a user.  For a simple command-line client this could just be listing the URLs of the widgets so the user can open them in a browser; for a web client like Riot/Web they're embedded via iframes; for a native client like Riot/iOS they could be shown via a WebView - or there's always the chance of the native client recognising the URL being requested and swapping it out for an optimised local native implementation instead.  For now, widgets don't really have a way of communicating with the host Matrix client (other than by speaking Matrix to the homeserver!), although we're looking at adding a PostMessage API to improve this.

Now, in an ideal world we would have enough bandwidth to have formally added widgets to the Matrix spec, but unfortunately we are way behind on spec work currently, thanks in part to our current funding problems. (Remember, if you like Matrix, please donate or get your company to donate otherwise we are at real risk of hitting a very big funding wall).  Rather than formal spec, we've focused on rushing an initial implementation out the door in matrix-react-sdk (and thus riot-web) to see how they work first in reality.  Riot/iOS and Riot/Android are coming soon - although we've special-cased the Jitsi video conferencing widget in iOS to be implemented natively, which is actually available already on develop(!)

Right now the widgets supported by Riot are prefixed behind the im.vector.modular.widgets state event, whose format is something like:

{
    type: "im.vector.modular.widgets",
    state_key: "widget1",
    content: {
        type: "grafana",
        url: "https://matrix.org/grafana/whatever",
        name: "matrix.org bridges dashboard"
    }
    room_id: "!foo:bar.com",
    sender: "@kegan:matrix.org"
}

Currently the only layout hint is that the order of the event determines the order in which the widget should be displayed on the page.  Riot/Web's initial implementation is very naive and shows only up to two widgets per page, although we're hoping to make this much more generic and flexible in future.  To add widgets in Riot/Web you can now hit the new widget manager button in the top right - and to show/hide existing ones in the room you can hit the show/hide app drawer button in the bottom right.

The UI for adding widgets to a room in Riot is currently via Modular - the new name for Riot's SaaS integration hosting platform, formally codenamed Scalar.  This is a separate webapp loaded in an iframe which guides you through choosing widgets to embed which are hosted by Modular, although in the near future we'll also add UI to let you specify widget URLs directly.  If you need this today, you'll need to manually inject a state event like the one above into the room to provision the widget.

This is very much the minimum viable implementation of widgets: the stuff left to do includes:

  • Adding them to the spec, and getting clients other than Riot using them!
  • Supporting better layouts (especially to allow for more screen real-estate) and more than 2 widgets
  • Ability to add widgets directly, for situations where Modular isn't available
  • Speccing APIs for widgets to interact directly with the host client - with the appropriate permissions model
  • Adding lots more prepackaged widgets to the Modular store!
Modular comes with 6 widgets ready to go: Grafana, Jitsi, Etherpad, YouTube, Google Docs and Custom Widget (which lets you add any arbitrary URL into the room). The most exciting of these is probably Jitsi, which provides Hangouts-style video conferencing into any room.  This provides a welcome alternative to our 'native' conferencing functionality which sadly got stuck in a permanent early beta - and includes full screensharing as well!  The only catch is that it hasn't been released on iOS yet, and Android is still be to be implemented - but the experience is a still massive improvement over what we've had historically.  Here's a screenshot of some of the core team doing a 6-way conference with the native Jitsi functionality now included in Riot/iOS!

Finally, if you want to write your own widget, just create a webapp and play with it via the Custom Widget interface.  If it's something useful for other people then please ping us on #matrix-dev:matrix.org and we'll see about getting it added as a preset application in Modular.

We think widgets are an awesome example of how Matrix can be used to coordinate collaboration between users in a room - for now it's just simply ensuring that users are looking at the same set of webapps when in a room, but in future you can see how it could extend to co-browsing, co-editing, payment functionality, or generally using Matrix to coordinate things other than textual/voip chat.  The sky's the limit, and we're hoping the Modular store (and other app stores) will start overflowing with apps in the near future!

As always, feedback is very welcome on new experimental stuff like this - so please come tell us what you think in #matrix:matrix.org!  And finally: huge kudos to Rick, Kegan, Rob, and everyone else who have been working away bringing Widgets to life.  It's the beginning of a new era :D

Matthew

Matrix.org status update - July 2017

19.07.2017 00:00 — General Matthew Hodgson

Hi folks,

Thought it was worth giving a quick status update on what's going on since our last blog post, which explained the funding situation Matrix has found itself in.  The TL;DR is that we're still here; things are moving faster than ever (not least as we refocus on getting everything needed to get Matrix funded and sustainable in the longer term), but we still need concrete support from the community (both company sponsorship and personal donations) to ensure things keep going at the current rate.

🔗Funding Status

So, the good news is that we had a great initial response to last week's call to help - right now we have 199 people signed up on Patreon (go on, be the 200th! you know you want to :D), ~30 on Liberapay, and 14 bitcoin donations.  This sums up to just over $2000/month - which is getting close to our initial Patreon goal of $2500/month to helping support half the cost of the less senior devs working on Matrix. Endless thanks to everyone who has donated - especially the 19 folks (18 on Patreon, one on Liberapay) who have so generously pledged $50 or more a month!! Meanwhile, if you're reading this and you haven't pledged support yet - please consider heading over to Patreon or Liberapay or Bitcoin 1LxowEgsquZ3UPZ68wHf8v2MDZw82dVmAE and helping keep the project running.  Literally every dollar counts.

Meanwhile, while Patreon & friends are headed in the right direction to support one developer, we still have another 10 people working on all the various core components of Matrix itself who need to be supported in the near future.  (We look to be safe for the next month or two, but beyond that we're counting on having solved this problem ;).  Right now we are hoping that companies who believe in Matrix and/or are building services on top will step up to sponsor development - as it's pretty obvious that accelerating Dendrite, final E2E, Groups etc will improve professional Matrix-based services immeasurably.  If this sounds like you, please get in touch asap.

We're also able to provide paid consulting and development (and prioritised development) services on Matrix (through Vector, the for-profit company responsible for Riot) for large pieces of work - for instance, if you're anxious to see enterprise-focused Matrix features land sooner than later, please reach out.

Exciting news is that we already have one concrete offer of paid consulting work from a very major company who happens to love Matrix, building out Integrations capabilities which should directly benefit the wider Matrix ecosystem - and we also are very proud to announce our very first official corporate sponsor (see the next section for details)!  However, we still have a long way to go, so don't be shy about getting in touch: we need your support!

Heads up that we've also started our various reward schemes for supporters - folks donating more than $5 on Patreon will have already heard most of this update in the first episode of the video blog that Amandine & I posted last Friday; and folks donating more than $10 will have heard some of the other details first hand through the broadcast of the global team weekly sync on Monday!  We're still figuring out how to get these rewards over to liberapay & bitcoin supporters (not helped by both services being anonymous...).  We haven't yet opened up the #matrix-supporters:matrix.org room as maintaining the accesslist is effectively blocked on Groups landing.  We also want to use Groups to manage the various lists of supporters around the place, so apologies that we haven't got the lists published yet!

Finally on the funding side of things: we're setting up the Matrix.org Foundation non-profit legal entity this week, letting us accept donations and sponsorship in a way which can directly fund the core developers (more details as we have them).  As soon as it's incorporated, we'll be able to sign up fully on Liberapay to accept donations there.

🔗Announcing UpCloud: our very first official Matrix.org Corporate Sponsor!

As hinted above, we're incredibly excited and happy that UpCloud have signed up as our first official corporate sponsor.  UpCloud has already been hosting all of Matrix.org's infrastructure for the last 6 months (no mean feat, given the scale of the Matrix.org synapse & postgres!) - and last week they committed to extend their sponsorship further to help the project out in our time of need.

We've been very impressed with UpCloud's service since migrating over back in February - particularly their spectacularly fast block IO (~350MB/s write, 92,000 IOPS, and over 5GB/s read!!) which is incredibly useful for running a huge synapse deployment like Matrix.org's - and they have a great footprint of datacentres around the world.

They also like Matrix so much that they've written this great tutorial for getting Synapse up and running on their hosts - and best of all, they have a special $25 discount for anyone in the Matrix community who wishes to use them: check out https://www.upcloud.com/matrix/ for the details!

We'd like to thank them profusely for being first in line to support us - and we look forward to seeing how far we can push their hardware over the coming months! :D

🔗Development Status

Finally, loads and loads of stuff is happening on Matrix itself.  The main headlines are:

  • Groups.  Work in Synapse and matrix-react-sdk is happening at breakneck speed to get Groups out the door as soon as possible, so we can use them both to support the funding drive and in general to implement one of the most asked-for features of Matrix: the ability to group rooms together into a well-defined community (similar to Slack Teams or Discord Servers etc).  The way Groups work is to let users define groupings of both users and rooms; you can also define a metadata for the group to let you build homepages similar to the one which Riot/Web sprouted a few months ago.  You can then refer to the group of users when inviting/banning/kicking etc - or when managing your own roomlist.  We think it's going to completely change how people use Matrix, and can't wait to see it land on riot.im/develop, although it's still a few weeks away.
  • E2E Crypto.  We have three main things remaining here, after which E2E should be much much more usable for day-to-day purposes:
    1. Fixing the matrix-js-sdk to store crypto state in indexeddb rather than localstorage, to prevent multiple browser tabs racing and corrupting localstorage (which provides no locking mechanism).  This turns out to be much more of an epic than we thought, as indexeddb's APIs are all strictly async, resulting in a whole bunch of previously synchronous APIs in matrix-js-sdk needing to become async too, as well as requiring us to switch promises library at least from Q to Bluebird.  However, most of this is now done so hopefully the new storage layer will land shortly.  https://github.com/vector-im/riot-web/issues/2325 is the bug tracking this one...
    2. Fixing the overall UX of managing devices in a room (including key shares).  https://github.com/vector-im/riot-web/issues/4522 is the bug for this one :)  Relatedly we also need to ensure invitees can decrypt messages in e2e rooms before they join (if history visibility allows it) - this is https://github.com/vector-im/riot-web/issues/3821
    3. Fixing the UX of verifying devices (including cross-signing devices), to minimise the pain in verifying device ownership. https://github.com/vector-im/riot-web/issues/2142 is the master bug for this.
  • Integrations.  A large slice of the team is working on our next-generation integration hosting platform, which is starting to look unspeakably awesome.  We'll be yelling loudly about this once there's something to see and play with...
  • Rich Text Editor.  This was originally a GSoC project from last year, but is finally on by default now in matrix-react-sdk - letting users author their messages with full WYSIWYG behaviour and critically have a radically improved autocompletion UI/UX, including emoji, user names, room names, etc.  You can check it out at riot.im/develop already :)
  • Mentions.  We're finally semantically tagging references to users in messages so that they can be displayed nicely in the UI, and help with highlighting notifications!  This is due as soon as the Rich Text Editor work has finished.
  • Mobile SDKs.  The iOS & Android teams are currently on a mission to get parity between the iOS & Android SDKs and matrix-react-sdk.  This is stuff like implementing the new User Search API; Membership Event List Summaries; Dark theme(!); Translations; etc.  Progress is looking good!
  • Synapse performance.  Many many optimisations when calculating push rules when sending messages, which was taking up a substantial amount of the send path time.  Synapse develop looks to have reduced this significantly now - and as of Monday we're running the new optimisations on Matrix.org.
  • Dendrite.  Lots of work going into implementing Invitations currently, including improvements to the overall append-only log architecture to support them nicely.
  • Riot-Static.  This is one of our GSoC projects this year, written by Michael Telatynski (t3chguy) - providing a full static (no-JS) read-only view of Matrix, suitable for dumb web browsers and search engines.  It's looking really exciting (although needs CSS) - there's a copy currently deployed over at https://stormy-bastion-98790.herokuapp.com/.
Meanwhile, there's a tonne of stuff happening in the community - an excellent summary may be found at this Community Round Up blog post by uhoreg!

So: this is where things stand right now - the team is sprinting away getting all the stuff above landed, and meanwhile I'm spending most of my life worrying about funding.  We'll try to keep blogging more regularly to give better visibility on progress on both the funding & development situation, as well as to ensure there's a written public record as well as the regular supporter-only updates.  However, for the latest realtime updates and sneak previews and tidbits you'll probably want to sign up on Patreon or Liberapay :D

--Matthew

[EDIT: I got the UpCloud stats completely wrong - they are even faster (by 10x!) than I quoted; the figures are now updated :)]

A Call to Arms: Supporting Matrix!

07.07.2017 00:00 — General Matthew Hodgson

Hi folks,

TL;DR: if you like Matrix (and especially if you're building stuff on it), please support us via Patreon or Liberapay to keep the core team able to work on it full-time, otherwise the project is going to be seriously impacted.  And if you're a company who is invested in Matrix (e.g. itching for Dendrite), please get in touch ASAP if you'd like to sponsor core development work from the team.  And if you're a philanthropic billionaire who believes in our ideals of decentralisation, encryption, and open communication as a basic human right - we'd love to hear from you too O:-)

I was expecting this blog post to be the Matrix Summer Special, focusing entirely on the incredible progress and updates we've made in the last few months in Matrix.  However, instead I'm going to talk about something different and literally critical to Matrix's success.

As many people know, Matrix.org development has historically been exclusively and very generously sponsored by a large multinational telecoms infrastructure company for whom most of the core team once built telco messaging apps.  However, despite the project progressing better than ever (more on that later), we have just had our funding dramatically cut by >60%. [Update: as of Aug 2017 it is effectively cut entirely, with enough $ left over to cover until end of October.]

We seem to be suffering from a darkly amusing paradox, as the rationale from our corporate overlords is essentially: “Wow! Matrix is doing great and growing well - and you seem to have all sorts of exciting people and companies using and building on it.  But we've been footing the whole development bill since the outset in May 2014, and this simply doesn't feel fair.  We're happy to keep funding though - but only if others do too!”.  In other words, in some ways we are a victim of our own success...

So we now find ourselves in the situation that despite the project looking better than ever and having a tonne of amazing stuff in the pipeline, we are suddenly missing the funding to keep the core team working on it.  And the team is quite sizeable - reflecting the ambition and size of Matrix: right now we have effectively 11 people working specifically on Matrix itself: 1 on Synapse, 1 on Dendrite, 1 on e2e crypto, 2 on matrix-react-sdk (which powers Riot/Web), 2 on matrix-ios-kit / matrix-ios-sdk, 2 on matrix-android-sdk, 1 on bridges, and me (Matthew) managing the overall project.  (This ignores folks who overlap the team who are working specifically on Riot stuff).

Over the last few years we've had countless people ask if they can financially support Matrix. We haven't been able to accept it for various reasons, but now is the time for us to step towards a more independent setup, and avoid a repeat of the situation we're currently facing by opening up to external support.

So we need help from the community to keep going!  Please head over to Patreon or Liberapay and put some money in the meter (or send some bitcoin to 1LxowEgsquZ3UPZ68wHf8v2MDZw82dVmAE or ether to 0xA5f9a4f9E024F6D727f7afdA9257e22329A97485). In return, you'll get to keep Matrix evolving at a decent rate, be a member of the upcoming +supporters:matrix.org group (complete with flair badges!), and other benefits like access to #matrix-supporters:matrix.org - a new dedicated room for prioritised support, discounted goodies from Riot once paid services arrive, access to a weekly supporters-only status podcast(!), and of course receive our eternal thanks. :)

Meanwhile, if you're a company who depends on Matrix: please get in touch. We have the option for you to sponsor core Matrix development (e.g. Dendrite) or for us to provide you with more targeted support or feature development.  We're already talking to several organisations who want to accelerate Dendrite specifically - and the more support we have there the faster we can go.

We'd also like to thank UpCloud for sponsoring hosting for the Matrix.org synapse instances - UpCloud has been coping impressively with the massive I/O and CPU/RAM requirements we have, and we recommend them unreservedly for folks looking to run their own homeservers.

Finally, one of the longer term plans to help fund Matrix is to get sponsorship from Riot, once Riot starts offering paid services. So, if you're an investor who's interested in the for-profit sides of Riot (paid integrations and paid Matrix hosting) then please get in touch with the Riot team ASAP!

Moving forward we are confident that we can secure funding, through sponsorship and Riot paid services, but in truth this decision caught us by surprise and so we need help both long term but also right now!

And whatever the funding situation, we're of course always looking for contributions for code, bug reports, or just spreading the word about the project too! :)

🔗Status Update

(or scroll to next section to see why this is bigger than "just" decentralised encrypted communication)

Despite the funding issue, the project really is going very well. Our vital stats (as seen through the lens of the matrix.org synapse) are looking like this:

And meanwhile, looking back at the last big update (Holiday Special 2016), we can compare our progress with our goals for 2017 thus far:

  • Getting E2E Encryption out of beta ASAP.
This has progressed massively - we haven't really yelled about it yet, but latest https://riot.im/develop/ now finally implements the ability to share message keys between clients to let them decrypt older history and fix “unable to decrypt” errors (Mobile coming soon).  Meanwhile various root causes of “unable to decrypt” errors have been gradually eliminated; I can't actually remember the last time I saw one! Once key-sharing and improved device verification UX is fully tested and tuned we should be able to declare E2E out of beta.

Work on fixing the final causes of "unable to decrypt" (UISI) errors in E2E is progressing well: here's a sneak preview of things to come!! pic.twitter.com/0oGJjm8ZHT

— Matrix (@matrixdotorg) May 25, 2017

  • Ensuring we can scale beyond Synapse – i.e. implement Dendrite
Likewise, Dendrite is on track: we've implemented all the Hard Stuff which forms the skeleton of Dendrite (core federation, message signing, /sync, message sending, media repository etc) - which takes us to over 50% of Phase 1. After phase 1, we will have an initial usable release for all the core functionality.  Synapse's performance has also improved enormously this year.

New milestone for Dendrite: sending messages over federation BOTH WAYS between dendrite & synapse! A bit more polish & we can cut an alpha!! pic.twitter.com/DWs6rFqZcQ

— Matrix (@matrixdotorg) June 23, 2017

  • Getting as many bots and bridges into Matrix as possible, and doing everything we can to support them, host them and help them be as high quality as possible – making the public federated Matrix network as useful and diverse as possible.
Bridges and bots continue - from the core team we have a ‘puppeting' Telegram bridge (matrix-appservice-tg), and from the wider community we have Discord, Skype, Signal, new Rocket.Chat and more.  Getting them polished and live is certainly an area where we need more manpower though.
  • Supporting Riot's leap to the mainstream, ensuring Matrix has at least one killer app.
Riot has been sprouting new releases every few weeks, with a huge emphasis on proving UX:
  • an entirely new streamlined sign-up process
  • the new concept of home pages
  • a user directory search that actually works
  • internationalised to 27 languages
  • compact layout
  • loads of desktop improvements
  • piwik analytics support; etc.

There is still a lot of UX work to be done, but it's converging fast on being a great entry point into the Matrix ecosystem, driving its growth across different groups and communities..

Meanwhile, a massive update to the iOS & Android apps just landed yesterday, switching to an entirely new UI layout to separate People from Rooms, synchronized Read Markers, and more!

  • Adding the final major missing features:
    • Customisable User Profiles (this is almost done, actually)
This is still hovering at ‘almost done', and will be needed for some of the implementation of Groups (see below)..
  • Groups (i.e. ability to define groups of users, and perform invites, powerlevels, etc. per-group as well as per-user)
Groups are also in testing in Synapse too!  These will probably be the single biggest change to Matrix that we've seen since E2E encryption landed: it changes the dynamic of the whole network, given users can explicitly declare allegiance to different groups, which in turn have their own home pages and directories etc.  It lets users form communities, and declare their participation in those communities (if desired), and also lets rooms be grouped together.  One of our single biggest requests has been “subrooms” and we're incredibly excited to see how well Groups solve this.
  • Threading
Sadly no progress on Threading so far this year.
  • Editable events (and Reactions)
We're hoping to get looking at this (at last!) once Groups are done.
  • Maturing and polishing the spec (we are way overdue a new release)
You'll have noticed that in the “how many people work on Matrix?” stats above, we didn't mention anyone working on the Spec.  Because right now there isn't anyone explicitly maintaining it, unfortunately; updates are done best-effort when everyone's primary responsibilities allow it.  That said, there's quite a lot of good stuff currently unreleased on HEAD. This is something which is obviously critical to fix once we have sustainable funding sorted again.  We can only apologise to folks like the Ruma developers who have suffered from the spec lag. :(
  • Improving VoIP – especially conferencing.
VoIP is improving lots on iOS, thanks to Denis Morozov's GSoC project, and meanwhile we have all new conferencing powered by Jitsi on the horizon in the next few weeks too.
  • Reputation/Moderation management (i.e. spam/abuse filtering).
Lots of thinking about this (see below), but no development yet.
  • Much-needed SDK performance work on matrix-{'{'}react,ios,android{'}'}-sdk.
About 40% of the desired performance work has happened here (although not all has gone live yet).
  • …and a few other things which would be premature to mention right now. :D
All will be revealed in the next week or two - but suffice it to say that Integrations are going to be getting a Lot More Useful™. :)

🔗Reflections

There are very very few people actually working professionally on trying to build general-purpose open communication networks and protocols.  There's us, some XMPP, IRCv3 and GNU Social/Mastodon folks, GNU Ring, Tox, Briar, Secure Scuttlebutt, IPFS, Status.im, Ricochet… and that's literally all the major projects I can think of (sorry if I missed you!).  There's probably only 50 developers in total working in this domain as their day job.

Meanwhile, there are literally hundreds of thousands of folks trudging away building more and more near-indistinguishable proprietary closed communication systems - trapping users inside ever more silos and fragmenting the basic ability to communicate on the ‘net.  It's like a world where the open web was pushed into a tiny underground resistance, and everyone else was trapped in the walled gardens of AOL and Compuserve (or more contemporarily: Facebook, Twitter, WhatsApp etc).

In other words: the whole world of decentralised communication desperately needs your support.  This is a clear case of user choice and freedom: to give users the ability to pick who they trust with their data and metadata, without being forced into unilaterally trusting the Silicon Valley megacorps.  And this, dear Reader, is your chance to fix the world for the greater good. Seriously, the Matrix team is one of a handful in the world in a position to continue to push things in the right direction and avoid us falling into a permanent dystopia where communication is even more closed and proprietary than the Public Telephone Network!

Finally, there's an even bigger issue at stake here than open communication.  As an open network, people can literally publish whatever content they like into Matrix - same as the web or the internet itself.  As a result, there's scope for spam; abusive/malicious content; propaganda; and generally the whole spectrum of the best and worst of humanity.  Now, if we were a centralised system like Facebook, we might hire thousands of content moderators to frantically impose a rulebook on ‘acceptable' content.  Or we might build invisible filter-bubbles for our users based on their social graph, cocooning them from scary unfamiliar content outside their social circles and reinforcing their preconceptions (whilst the resulting self-affirmation keeps them coming back, viewing more and more ads).

But we're decentralised, and we have no absolute moral arbiter, and nor should we - on an open network it should be up to users and users alone to define and manage their own worldview and alignment.  Plus we are not fiscally obligated to keep users coming back to view more ads no matter what.  Instead, we are forced to confront the fundamental problem: building tools which empower users to curate and visualise their own content filters; letting them filter out the stuff they're not interested in or find repellant… while still helping them be aware of their own viewpoint and the shape of the world beyond it.  We haven't really started building this yet, but in the long term our feeling is that these tools will literally be vital for the survival of the human race (e.g. exposing anti-climate-change propaganda for what it is or helping users opt out of World War 3) - let alone the success of decentralisation.  A world where users blindly consume propaganda is doomed, and it's a fascinating situation that the same tools which will allow Matrix users to tune out the rooms, users and conversations they're not interested in could be directly applied to the bigger global problem.

So: Matrix needs you. Please become a supporter on Patreon or Liberapay, and help us save the world :)

  • Matthew, Amandine & the whole Matrix.org team.

Synapse 0.19.3 released

21.03.2017 00:00 — General Matthew Hodgson

Hi all,

We've released Synapse 0.19.3-rc2 as 0.19.3 with no changes. This is a slightly unusual release, as 0.19.3-rc2 dates from March 13th and a lot of stuff has landed on the develop branch since then - however, we'll be releasing that as 0.20.0 once it's ready. Instead, 0.19.3 has a set of intermediary performance and bug fixes; the only new feature is a set of admin APIs kindly contributed by @morteza-araby.

The changelog follows - please upgrade from https://github.com/matrix-org/synapse or your OS packages as normal :)

🔗Changes in synapse v0.19.3 (2017-03-20)

No changes since v0.19.3-rc2

🔗Changes in synapse v0.19.3-rc2 (2017-03-13)

Bug fixes:

  • Fix bug in handling of incoming device list updates over federation.

🔗Changes in synapse v0.19.3-rc1 (2017-03-08)

Features:

Changes: Bug fixes:
  • Fix synapse_port_db failure. Thanks to @Pneumaticat! (PR #1904)
  • Fix caching to not cache error responses (PR #1913)
  • Fix APIs to make kick & ban reasons work (PR #1917)
  • Fix bugs in the /keys/changes api (PR #1921)
  • Fix bug where users couldn't forget rooms they were banned from (PR #1922)
  • Fix issue with long language values in pushers API (PR #1925)
  • Fix a race in transaction queue (PR #1930)
  • Fix dynamic thumbnailing to preserve aspect ratio. Thanks to @jkolo! (PR #1945)
  • Fix device list update to not constantly resync (PR #1964)
  • Fix potential for huge memory usage when getting device that have changed (PR #1969)

An Adventure in IRC-Land

14.03.2017 00:00 — General Kegan Dougal

Hi everyone. I'm Kegan, one of the core developers at matrix.org. This is the first in a series on the matrix.org IRC bridge. The aim of this series is to try to give a behind the scenes look at how the IRC bridge works, what kinds of problems we encountered, and how we plan to scale in the future. This post looks at how the IRC bridge actually works.

Firstly, what is "bridging"? The simple answer is that it is a program which maps between different messaging protocols so that users on different protocols can communicate with each other. Some protocols may have features which are not supported in the other (typing notifications in Matrix, DCC - direct file transfers - in IRC). This means that bridging will always be "inferior" to just using the respective protocol. That being said, where there is common ground a bridge can work well; all messaging protocols support sending and receiving text messages for example. As we'll see however, the devil is in the detail...

A lot of existing IRC bridges for different protocols share one thing in common: they use a single global bot to bridge traffic. This bot listens to all messages from IRC, and sends them to the other network. The bot also listens for messages from users on the other network, and sends messages on their behalf to IRC. This is a lot easier than having to maintain dedicated TCP connections for each user. However, it isn't a great experience for IRC users as they:

  • Don't know who is reading messages on a channel as there is just 1 bot in the membership list.
  • Cannot PM users on the other network.
  • Cannot kick/ban users on the other network without affecting everyone else.
  • Cannot bing/mention users on the other network easily (tab completion).
We made the decision very early on that we would keep dedicated TCP connections for each Matrix user. This means every Matrix user has their own tiny IRC client. This has its own problems:
  • It involves multiple connections to the IRCd so you need special permission to set up an i:line.
  • You need to be able to support identification of individual users (via ident or unique IPv6 addresses).
  • With all these connections to the same IRC channels, you need to have some way to identify which incoming messages have already been handled and which have not.

🔗Mapping Rooms

So now that we have a way to send and receive messages, how do we map the rooms/channels between protocols? This isn't as easy as you may think. We can have a single static one-to-one mapping:

  • All messages to #channel go to !abcdef:matrix.org.
  • All messages from !abcdef:matrix.org go to #channel.
  • All PMs between @alice:matrix.org and Bob go to !wxyz:matrix.org and the respective PM on IRC.
In order to make PMs secure, we need to limit who can access the room. This is done by making the Matrix PM room "invite-only". This can cause problems though if the Matrix user ever leaves that room: they won't be able to ever re-join! The IRC bridges get around this by allowing Matrix users to replace their dedicated PM room with a new room, and by checking to make sure that the Matrix user is inside the room before sending messages.

Then you have problem of "ownership" of rooms. Who should be able to kick users in a bridged room? There are two main scenarios to consider:

  • The IRC channel has existed for a while and there are existing IRC channel operators.
  • The IRC channel does not exist, but there are existing Matrix moderators.
In the first case, we want to defer ownership to the channel operators. This is what happens by default for all bridged IRC channels on matrix.org. The Matrix users have no power in the room, and are at the mercy of the IRC channel operators. The channel operators are represented by virtual Matrix users in the room. However, they do not have any power level: they are at the same level as real Matrix users. Why? The bridge does this because, unlike IRC, it's not possible in Matrix to bring a user to the same level as yourself (e.g +o), and then downgrade them back to a regular user (e.g. -o). Instead, the bridge bot itself acts as a custodian for the room, and performs privileged IRC operations (topic changing, kickbans, etc) on the IRC channel operator's behalf.

In the second case, we want to defer ownership to the Matrix moderators. This is what happens when you "provision a room" in Matrix. The bridge will PM a currently online channel operator and ask for their permission to bridge to Matrix. If they accept, the bridge is made and the power levels in the pre-existing Matrix room are left untouched, giving moderators in Matrix control over the room. However, this power doesn't extend completely to IRC. If a Matrix moderator grants moderator powers to another Matrix user, this will not be mapped to IRC. Why? It's not possible for the bridge to give chanops to any random user on any random IRC channel, so it cannot always honour the request. This relies on the humans on either side of the bridge to communicate and map power accordingly. This is done on purpose as there is no 100% perfect mapping between IRC powers and Matrix powers: it's always going to need to compromise which only a human can make.

Finally, there is the problem of one-to-many mappings. It is possible to have two Matrix rooms bridged to the same IRC channel. The problem occurs when a Matrix user in one room speaks. The bridge can easily map that to IRC, but unless it also maps it back to Matrix, the message will never make it to the 2nd Matrix room. The bridge cannot control/puppet the Matrix user who spoke, so instead it creates a virtual Matrix user to represent that real Matrix user and then sends the message into the 2nd Matrix room. Needless to say, this can be quite confusing and we strongly discourage one-to-many mappings for this reason.

🔗Mapping Messages

Mapping Matrix messages to IRC is rather easy for the most part. Messages are passed from the Homeserver to the bridge via the AS API, and the bridge sends a textual representation of the message to IRC using the IRC connection for that Matrix user. The exact form of the text for images, videos and long text can be quite subjective, and there is inevitably some data loss along the way. For example, you can send big text headings, tables and lists in Matrix, but there is no equivalent on IRC. Thankfully, most Matrix users are sending the corresponding markdown and so the formatting can be reasonably preserved by just sending the plaintext (markdown) body.

Mapping IRC messages to Matrix is more difficult: not because it's hard to represent the message in Matrix, but because of the architecture of the bridge. The bridge maintains separate connections for each Matrix user. This means the bridge might have, for example, 5 users (and hence connections) on the same channel. When an IRC user sends a message, the bridge gets 5 copies of the message. How does the bridge know:

  • If the message has already been sent?
  • If the message is an intentional duplicate?
The IRC protocol does not have message IDs, so the bridge cannot de-duplicate messages as they arrive. Instead, it "nominates" a single user's connection to be responsible for delivering messages from that channel. This introduces another problem though. Long-lived TCP connections are fickle things, and can fail without any kind of visible warning until you try to send bytes down it. If a user's connection drops, another user needs to take over responsibility for delivering messages. This is what the "IRC Event Broker" class does. It allows users to "steal" messages if the bridge has any indication that the connection in charge has dropped. This technique has worked well for us, and gives us the ability to have more robust connections to the channel than with one TCP connection alone.

🔗Admin Rooms

Admin rooms are private Matrix rooms between a real Matrix user and the bridge bot. It allows the Matrix user to control their connection to IRC. It allows:

  • The IRC nick to be changed.
  • The ability to issue /whois commands.
  • The ability to bypass the bridge and send raw IRC commands directly down the TCP connection (e.g. MODE commands).
  • The ability to save a NickServ password for use when the bridge reconnects you.
  • The ability to disconnect from the network entirely.
To perform these actions, Matrix users send a text message which starts with a command name, e.g !whois $ARG. Like all commands, you expect to get a reply once you've issued it. However, IRC makes this extremely difficult to do. There is no request/response pair like there is with HTTP requests. Instead, the IRC server may:
  • Ignore the request entirely.
  • Send an error you're aware of (in the RFC/most servers)
  • Send some information which can be assumed to indicate success.
  • Send an error you're unaware of.
  • Send some information which sometimes indicates success.
This makes it very difficult to know if a request succeeded or failed, and I'll go into more detail in the next post which focuses on problems we've encountered when developing the IRC bridge. This room is also used to inform the Matrix user about general information about their IRC connection, such as when their connection has been lost, or if there are any errors (e.g. "requires chanops to do this action"). The bridge makes no effort to parse these errors, because it doesn't always know what caused the error to happen.

🔗Wrapup

Developing a comprehensive IRC bridge is a very difficult task. This post has outlined a few of the ways in which we've designed our bridge, and some of the general problems in this field. The bridge is constantly improving as we discover new edge cases with the plethora of IRCd implementations out there. The next post will look at some of these edge cases and look back at some previous outages and examine why they occurred.

New bridged IRC network: GIMPNet

06.03.2017 00:00 — General Kegan Dougal

Hey everyone! As of last week, we are now bridging irc.gimp.org (GIMPNet) for all your GTK+/GNOME needs! It's running a bleeding-edge version of the IRC bridge which supports basic chanops syncing from IRC to Matrix. This means that if an IRC user gives chanops to a Matrix connection, the bridge will give that Matrix user moderator privileges in the room, allowing them to set the room topic/avatar/alias/etc! We hope this will make customising Matrix-bridged rooms a lot easier.

For a more complete list of current and future bridged IRC networks, see the official wishlist.