qcp(1)

NAME
qcp - Secure remote file copy utility which uses the QUIC protocol over UDP

SYNOPSIS
qcp [-4 ] [-6 ] [--address-family] [--aes256] [--color] [--congestion] [--initial-congestion-window] [--initial-mtu] [-l|--remote-user] [--log-file] [--max-mtu] [--min-mtu] [-p|--preserve] [-P|--remote-port] [--packet-threshold] [--port] [--profile] [-q|--quiet] [-r|--recurse] [--remote-qcp-binary] [--rx] [-s|--statistics] [-S ] [--ssh] [--ssh-config] [--ssh-subsystem] [--time-format] [--time-threshold] [--timeout] [--tls-auth-type] [--tx] [--udp-buffer] [--rtt] [--debug] [--dry-run] [--io-buffer-size] [--remote-config] [--remote-debug] [--config-files] [--help-buffers] [--list-features] [--show-config] [-h|--help] [SOURCE|DESTINATION]

DESCRIPTION
The QUIC Copier (qcp) is an experimental high-performance remote file copy utility for long-distance internet connections. It is intended as a drop-in replacement for scp.

qcp offers similar security to scp using existing, well-known mechanisms, and better throughput on congested networks.

USAGE

qcp [OPTIONS] SOURCE... DESTINATION
    e.g. qcp some/file my-server:some-directory/
           qcp -r dir1 dir2 my-server:

Exactly one side (source(s) or destination) must be remote. When copying multiple sources, the destination is a directory, which will be created if necessary.

Long options may be abbreviated where unambiguous.

qcp will read your ssh config file to resolve any host name aliases you may have defined. The idea is, if you can ssh directly to a given host, you should be able to qcp to it by the same name. However, some particularly complicated ssh config files may be too much for qcp to understand. (In particular, Match directives are not currently supported.) In that case, you can use --ssh-config to provide an alternative configuration (or set it in your qcp configuration file).

  LIMITATIONS

You must be able to ssh directly to the remote machine, and exchange UDP packets with it on a given port. (If the local machine is behind connection-tracking NAT, things work just fine. This is the case for the vast majority of home and many business network connections.)

Be aware that network security systems can’t readily identify QUIC traffic as such. It’s opaque, and high bandwidth. Some security systems might flag it as a potential threat.

  CAVEATS

This is an experimental implementation of an experimental protocol. While it has security goals, these have not been verified.

OPTIONS

--color [<MODE>]
    Colour mode for console output (default: auto) Passing `--color` without a value is equivalent to `--color always`. Note that color configuration is not shared with the remote system, so the color output from the remote system (log messages, remote-config) will be coloured per the config file on the remote system. qcp also supports the `CLICOLOR`, `CLICOLOR_FORCE` and `NO_COLOR` environment variables. See https://bixense.com/clicolors/ for more details. CLI options take precedence over the configuration file, which takes precedence over environment variables.
    Possible values:

    •   always: Forces colours on, whatever is happening

    •   never: Never use colours

    •   auto: Use colours only when writing to a terminal. This is the default behaviour

--log-file <FILE>
    Log to a file By default the log receives everything printed to stderr. To override this behaviour, set the environment variable `RUST_LOG_FILE_DETAIL` (same semantics as `RUST_LOG`).

-p, --preserve
    Preserves file/directory permissions and file modification times as far as possible. Directory modification times are not preserved. This is because they are OS-specific and not well defined.

--profile
    Output timing profile data after completion

-q, --quiet
    Quiet mode Switches off progress display and statistics; reports only errors

-r, --recurse
    Copies entire directories recursively, following symbolic links. Behaviour is intended to match scp.

-s, --statistics
    Show additional transfer statistics

--time-format <FORMAT>
    The time format to use when printing messages to the console or to file [default: local]
    Possible values:

    •   local: Local time (as best as we can figure it out), as "year-month-day HH:MM:SS"

    •   utc: UTC time, as "year-month-day HH:MM:SS"

    •   utc-micro: UTC time with microsecond resolution, as "year-month-day HH:MM:SS.uuuuuu"

    •   rfc3339: UTC time, in the format described in [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339)

-h, --help
    Print help (see a summary with '-h')

[SOURCE|DESTINATION]
    One or more SOURCE paths followed by a DESTINATION path. The last path is always treated as the destination. All preceding paths are treated as sources. Exactly one side of the transfer (all sources, or the destination) must be remote. Remote paths take the form `server:path` or `user@server:path` (as in rcp or scp).

DEBUG

--debug
    Enable detailed debug output This has the same effect as setting `RUST_LOG=qcp=debug` in the environment. If present, `RUST_LOG` overrides this option.

--dry-run
    Connects to a remote server but does not actually transfer any files. This is useful to test that the control channel works and when debugging the negotiated bandwidth parameters (see also `--remote-config`).

--remote-config
    Outputs the server's configuration for this connection. Unlike `--show-config`, this option does not prevent a file transfer. However, you can do so by selecting `--dry-run` mode. The output shows both the server's _static_ configuration (by reading config files) and its _final_ configuration (taking account of the client's expressed preferences).

--remote-debug
    Enables detailed debug output from the remote endpoint (this may interfere with transfer speeds)

--config-files
    Outputs the paths to configuration file(s), then exits. This option cannot be used with any other option.

--list-features
    Outputs all known protocol features with their compatibility levels, then exits. This option cannot be used with any other option.

--show-config
    Outputs the local configuration, then exits. If a remote `SOURCE` or `DESTINATION` argument is given, outputs the configuration we would use for operations to that host. If not, outputs only global settings from configuration, which may be overridden by `Host` blocks in configuration files.

TUNING

--rx <bytes>
    The maximum network bandwidth we expect receiving data FROM the remote system. [default: 12.5M] This is the single most important configuration necessary for good performance! If you configure nothing else, at least set this to suit your network. This parameter is always interpreted as the _local_ bandwidth, whether operating in client or server mode. This may be specified directly as a number, or as an SI quantity like `10M` or `256k`. Note that this is described in BYTES, not bits; if (for example) you expect to fill a 1Gbit ethernet connection, 125M would be a suitable setting.

--tx <bytes>
    The maximum network bandwidth we expect sending data TO the remote system, if it is different from the bandwidth FROM the system. (For example, when you are connected via an asymmetric last-mile DSL or fibre profile.) Specify as a number, or as an SI quantity (e.g. `10M`). This parameter is always interpreted as the _local_ bandwidth, whether operating in client or server mode. If not specified or 0, uses the value of `rx`.

--rtt <ms>
    The expected network Round Trip time to the target system, in milliseconds. [default: 300]

--help-buffers
    Outputs additional information about kernel UDP buffer sizes and platform-specific tips. Note that the recommendations are based on the `udp_buffer` field in your configuration, which you can also set on the CLI.

CONNECTION

-4  Forces use of IPv4 This is a convenience alias for `--address-family inet`

-6  Forces use of IPv6 This is a convenience alias for `--address-family inet6`

--address-family <FAMILY>
    Forces use of a particular IP version when connecting to the remote. [default: any]
    Possible values:

    •   inet: IPv4

    •   inet6: IPv6

    •   any: Unspecified. qcp will use whatever seems suitable given the target address or the result of DNS lookup

--aes256
    Use only AES256 cipher suites as far as possible This option is included for those who have a preference to use only AES256-based algorithms (aka CNSA 2.0). Note this option does not fully disable AES128, which is required for the QUIC 1.0 Initial Packet.

-l, --remote-user <NAME>
    The user on the remote machine to connect as. This is functionally the same as specifying a remote filename `user@host:file`. If unspecified, we leave it up to ssh to determine.

-P, --remote-port <M-N>
    Uses the given UDP port or range on the **remote** endpoint. This can be useful when there is a firewall between the endpoints. For example: `12345`, `20000-20100` If unspecified, uses any available UDP port.

--port <M-N>
    Uses the given UDP port or range on the **local** endpoint. This can be useful when there is a firewall between the endpoints. For example: `12345`, `20000-20100` If unspecified, uses any available UDP port.

--remote-qcp-binary <PATH>
    Path to the qcp binary on the remote machine. [default: `qcp`] This is useful where the remote system has a locked-down `PATH` and the qcp binary is installed in a non-standard location. qcp will run `<path> --server` after logging in.

-S <SSH OPTION>
    Provides an additional option or argument to pass to the ssh client. [default: none] On the command line, you must repeat `-S` for each argument. For example, to pass `-i /dev/null` to ssh, specify: `-S -i -S /dev/null`

--ssh <PATH>
    The ssh client program to use [default: `ssh`]

--ssh-config <FILE>
    Alternative ssh config file(s) By default, qcp reads your user and system ssh config files to look for Hostname aliases. In some cases the logic in qcp may not read them successfully; this is an escape hatch, allowing you to specify one or more alternative files to read instead (which may be empty, nonexistent or /dev/null). This option is really intended to be used in a qcp configuration file. On the command line, you can repeat `--ssh-config file` as many times as needed.

--ssh-subsystem
    Ssh subsystem mode This mode causes qcp to run `ssh <host> -s qcp` instead of `ssh <host> qcp --server`. This is useful where the remote system has a locked-down `PATH` and the qcp binary is not resident on that `PATH`. The remote system sshd has to be configured with a line like this: `Subsystem qcp /usr/local/bin/qcp --server`

--timeout <seconds>
    Connection timeout for the QUIC endpoints [seconds; default 5] This needs to be long enough for your network connection, but short enough to provide a timely indication that UDP may be blocked.

--tls-auth-type <TYPE>
    Forces the use of a particular TLS authentication type (default: any)
    Possible values:

    •   any: No preference. Autodetects based on protocol compatibility

    •   x509: Self-signed X509 certificate

    •   rawpublickey: Raw (RFC7250) public key

ADVANCED NETWORK TUNING

--congestion <ALGORITHM>
    The congestion control algorithm to use. [default: cubic]
    Possible values:

    •   cubic: The congestion algorithm TCP uses. This is good for most cases

    •   bbr: (Use with caution!) An experimental algorithm created by Google, which increases goodput in some situations (particularly long and fat connections where the intervening buffers are shallow). However this comes at the cost of having more data in-flight, and much greater packet retransmission. See `https://blog.apnic.net/2020/01/10/when-to-use-and-not-use-bbr/` for more discussion

    •   newreno: The traditional "NewReno" congestion algorithm. This was the algorithm used in TCP before the introduction of Cubic

--initial-congestion-window <bytes>
    (Network wizards only!) The initial value for the sending congestion control window, in bytes. If unspecified, the active congestion control algorithm decides. Setting this value too high reduces performance! This may be specified directly as a number, or as an SI quantity like `10k`.

--initial-mtu <bytes>
    The maximum UDP payload size to use before initial MTU discovery has completed (default: 1200) QUIC runs dynamic Path MTU detection, so this option is not necessary. Setting it appropriately can speed up the initial transfer phase, particularly if jumbo frames are in use. Setting it higher than supported will cause very poor performance while QUIC deals with blackhole events and figures out what the network is actually capable of.

--max-mtu <bytes>
    The maximum value that Path MTU discovery will search for (default: 1452) The maximum MTU only really affects the sending direction of the connection. If jumbo frames are possible with your end-to-end network connection, set this appropriately. The default is reasonably conservative. Depending on your network connection and any tunnelling or VPN in use, hosts connected by ethernet may be able to support a slightly higher maximum MTU. Some connections do not support even this MTU, so for best efficiency - particularly with small file transfers - it may be worth setting this lower to avoid the penalty caused by MTU detection triggering black hole behaviour. It is safe to set a high limit, but that may reduce efficiency as MTU discovery will take longer to complete.

--min-mtu <bytes>
    The minimum MTU that the network is guaranteed to support. Unless you have very good control over all the network infrastructure in use, this setting is unlikely to help you. The default, 1200, is the protocol minimum. Setting this higher than the network actually supports will cause very poor performance and unpredictable effects; it may not be possible to complete a file transfer in a reasonable time.

--packet-threshold <N>
    Packet reordering loss detection threshold The default, 3, should be good for most cases. See RFC 9002 s6.1 for more details.

--time-threshold <M>
    Time reordering loss detection threshold, in multiples of RTT The default, 1.125, should be good for most cases. See RFC 9002 s6.1 for more details.

--udp-buffer <bytes>
    Size of the UDP kernel buffer in bytes. Specify as an integer or as an SI quantity, e.g. 4M. The default, 4M, should be good for most cases. However there may be high-bandwidth situations (10Gbps or more) where this becomes a bottleneck, or situations where you wish to restrict memory consumption.

--io-buffer-size <bytes>
    Local I/O buffer size (bytes). With very high speed connections it may be worth experimenting with larger values to improve throughput and reduce CPU overhead. **Both sides of the connection must configure this setting independently.** It is not negotiated between client and server. This setting may be specified directly as a number, or as an SI quantity like `10M` or `256k`. The default is 1MB. Note that this setting changes only the size of the I/O buffer used to spool data to and from disk. It does not directly affect what appears on the network.

EXIT STATUS

The qcp utility exits 0 on success, and >0 if an error occurs.

NETWORK PROTOCOL

qcp is a hybrid protocol. We use ssh to establish a control channel and exchange ephemeral TLS keys, then a QUIC connection to transport data.

Detailed protocol documentation can be found at
    https://docs.rs/qcp/latest/qcp/protocol/

  PERFORMANCE TUNING
See https://docs.rs/qcp/latest/qcp/doc/performance/

  TROUBLESHOOTING
See https://docs.rs/qcp/latest/qcp/doc/troubleshooting/

BUGS

Please report any you find via the issue tracker:
    https://github.com/crazyscot/qcp/issues

SEE ALSO

ssh(1), ssh_config(5), RFC 4254, RFC 9000, RFC 9001

AUTHORS
Ross Younger <qcp@crazyscot.com>