# NAME

lcagent - the Librecast multicast agent

# SYNOPSIS

**lcagent** \[**-dflv**\] \[**\--bpslimit** *limit*\] \[**\--expires**
*seconds*\] \[**\--overhead** *packets*\] \[*command* \[*argument*
*\...*\]\]

# DESCRIPTION

**lcagent** is the Librecast multicast agent.

In server mode **lcagent** can be configured to listen on Librecast
Channels (multicast groups) and execute programs in response to packet
data received on those Channels.

Packets must be accompanied by an authorized token and signed by the
matching key or they will be silently dropped.

Data is encoded with RaptorQ using Librecast\'s *liblcrq* library to
provide forward error correction in the event of packet loss.

Any data received in addition to the required token will be piped to
*stdin* of the configured commands after they are executed. Multiple
commands can be executed sequentially.

**lcagent** can be used to send and receive data over multicast and to
pipe data between programs on one computer and as many receivers as the
multicast network can support simultaneously.

# OPTIONS

**-d**, **\--debug**

:   Enable debug mode to print additional debugging information.

**\--bpslimit** ***rate\[KMGT\]***

:   When sending, this option limits the sending speed to *rate*. Rate
    is a number in bits per second (bps) and can be followed by a
    capital letter representing SI units. eg. 100M limits the sending
    rate to 100 megabits per second (Mbps).

**\--expires** ***seconds***

:   For the *sign* command, this sets the validity of the token in
    seconds.

**-f**, **\--follow**

:   In **recv** mode, do not stop after first data object received. Keep
    blocking and receiving data until interrupted. eg. \^C is pressed or
    SIGINT is received by the process.

**-l**, **\--loopback**

:   Enable multicast loopback when sending. This will allow packets to
    be received by the same host that sent them. By default multicast
    packets are not received on the sending host.

**\--overhead** ***packets***

:   When sending, this option sets the number of additional repair
    packets sent to aid with recovery of lost packets with RaptorQ
    encoding. Default: 5

**-v**, **\--verbose**

:   Print more verbose output.

# COMMANDS

## exec

**lcagent** exec \[*options*\] channel \[*data*\] \[*-*\]

The **exec** command executes the commands configured for *channel*
locally, without requiring data to be received over the network.

This is a good way to test the configured commands that will be executed
before making them accessible on the network.

The *nojoin* configuration directive can be used to ensure that a
channel is not network-executable, by preventing **lcagent** from
joining the associated Librecast channel. See **lcagentrc**(1).

## help

**lcagent** help

Print some (possibly) helpful instructions for **lcagent**.

## key

**lcagent** key \[*options*\] add\|del *key*

Add or delete a key from the authorized_keys file. Packets that do not
include a token signed by a key in the authorized_keys file are silently
dropped.

## recv

**lcagent** recv \[*options*\] channel

Block and wait for data to be received on *channel*, where *channel* is
a string that will be hashed to create a Librecast channel.

Data received will be written to *stdout*. If expecting binary data, be
sure to redirect *stdout* somewhere appropriate.

By default, once EOF is received from the sender, the program will exit.
This behaviour can be changed by specifying the *\--follow* option.

## reload

**lcagent** reload \[*options*\]

Reload the **lcagent** configuration. Sends a SIGHUP to the daemon
process. Has no effect unless **lcagent** has been started using the
*start* command. Service files should simply send SIGHUP to the process.

## send

**lcagent** send \[*options*\] *channel* \[*payload*\] \[-\]

Send data to *channel*, where *channel* is a string that will be hashed
to create a Librecast channel.

If *payload* is specified, this string will be sent as data to the
channel. If no payload is specified, an NULL (empty) payload of zero
bytes will be sent to the channel.

A hyphen (*-*) at the end of the command indicates that the payload
should instead be read from *stdin*.

## server

**lcagent** \[*server*\] \[*options*\]

Starting lcagent with no command starts it in server mode. The
*.lcagentrc* file will be parsed and **lcagent** will join the
configured channels and wait for data, executing the configured commands
when packets are received on one of the configured channels and writing
any payload data to *stdin* of the command when executing it.

See **lcagentrc**(1) for details of the runtime control (configuration)
file.

## sign

**lcagent** sign \[*options*\] \[**\--expires** *seconds*\] *bearer_key*
*channel*

Create and sign a token for the given *bearer_key* and *channel* and
write to disk. The resulting token will be written to a file in the
user\'s state directory, and the file pathname will be printed. If the
token is copied to the state directory of the bearer it will be used
when sending to *channel*.

A signed token means that packets sent by the bearer will be accepted by
any receivers on *channel* which have the signer\'s key added to their
*authorized_keys* file. Tokens enable delegation of authority, which is
important for scaling. Using pre-signed tokens allows, say, a host to
issue tokens for virtual machines it creates without the need to add
individual keys for every machine to all receivers on the network.

In the absence of a signed token, packets will be sent with a
self-signed token, requiring that all receivers have the sender\'s key
installed in their *authorized_keys* file.

If the *expires* option is supplied, this will be the validity in
seconds of the generated token. A value of zero (0) means that the token
will never expire. By default tokens do not expire.

## start

**lcagent** start \[*options*\]

Start **lcagent** in server mode and fork it as a daemon.

Not intended for use with daemon supervising programs. If you are
running **lcagent** as a service, just start **lcagent** with no command
and let the init system or daemon supervisor handle forking and
pidfiles. If you are NOT running **lcagent** as a service and want it to
daemonize, use this command.

## stop

**lcagent** stop \[*options*\]

Stop the **lcagent** daemon. Has no effect unless **lcagent** has been
started using the *start* command. Sends SIGINT to the running daemon
process.

## version

**lcagent** version

Print the version of **lcagent** and exit.

## whoami

**lcagent** whoami \[*options*\]

Print the active key to *stdout* and exit. This key can be added to the
*authorized_keys* file of another host with:

**lcagent** key add *key*

# EXIT STATUS

**lcagent** exits with status 0 (EXIT_SUCCESS) if the command was
successful, or 1 (EXIT_FAILURE) if an error occurred.

# ENVIRONMENT

HOME

:   Set to the path of the user's home directory.

# FILES

*\~/.lcagentrc*

:   This is the runtime control file for **lcagent.** This is where
    global settings, channels and commands are defined that affect the
    runtime operation of the program. See **lcagentrc**(5) for more
    information.

*\~/.local/state/lcagent/authorized_keys*

:   This file contains the keys which are authorized to issue tokens
    which will be accepted by the program when receiving data. One key
    is stored per line. It can be managed with the **lcagent** key
    command.

# SECURITY

Authenticity of data received is established by checking that each
packet received contains a token signed by an authority with their
public key installed in the *authorized_keys* file. If the token is
valid, the packet must be signed by the bearer key contained in the
token.

Cryptographic signatures use the Ed25519ph algorithm provided by the
libsodium library.

Data can be encrypted using the *seed* configuration directive in
*.lcagentrc*. See **lcagentrc(5).**

The symmetric encryption key is generated from *seed* using BLAKE2b.

Symmetric encryption uses the XSalsa20 stream cipher from libsodium
using a Poly1305 MAC for authentication and random nonce.

If an encryption seed is used, the permissions for the rcfile must not
be world readable or lcagent will refuse to run and print an error.

# AUTHOR

**lcagent** was written by Brett Sheffield \<bacs@librecast.net\> and
released under the terms of the GPL-2 or (at your option) GPL-3.

*https://librecast.net/lcagent.html*

# BUGS

If you find one, email *bugs@librecast.net* or raise an issue in our
online bug tracker at: *https://bugs.librecast.net/lcagent*

# SEE ALSO

**lcagentrc**(1), **lcsync**(1), **librecast**(7)
