The REMOTE service provides higher-level data services across the network: text messaging, file transfer and remote command execution. It builds on the TRANSPORT service (Chapter 23), and adds metadata such as MIME types, mailboxes, message classes and threaded responses. These remote messages and their attributes are explored in detail in Chapter 8. The default remote access agent is accessed as remote.
Note
File transfer and remote command execution access the node’s filesystem and shell, and are disabled by default. They are enabled by setting remote.enable = true on the node being accessed.
Warning
Be clear about what enable opens up: the default remote access agent implements no authentication. Once enabled, the node honors every file and command request that arrives over the network — any node that can reach it can read and write its files and run shell commands on it. (The RemoteExecReq message carries a credentials field, but the service does not specify how authentication should work; the default implementation ignores it.) Enable remote access only on networks where every node is trusted.
Tip
For a basic layer of protection against outsiders, some commercial modems support a physical layer scrambler: setting phy[].scrambler to a common secret 64-bit seed on all your nodes whitens every frame with it, so modems without the seed cannot decode your traffic (Chapter 17). Be aware of its limits — it is not cryptographically strong, and does not protect against playback attacks — but it keeps a casually configured third-party modem from joining your network.
24.2 Messages
Agents providing this service honor the following requests:
Each request is answered with an AGREE once accepted (a REFUSE if invalid, a FAILURE if something goes wrong); the operation itself then proceeds over the network, and its outcome is reported to the requester:
RemoteFileNtf – file (or data) received from a remote node
Field
Type
Default
Remarks
data
byte[]
filename
string
from
int
-1
transferDuration
float
NaN
On the receiving node, an incoming remote message is delivered as a RemoteMessageNtf (or, for chat messages, a RemoteTextNtf) published on the global Topics.DATAGRAM topic — unless the sender named a remoteRecipient, in which case it is delivered to that agent or topic directly. Replies (inReplyTo set) are delivered back to the agent that sent the original message. A remote node that receives a command or file request while its enable flag is off responds with a RemoteFailureNtf instead of executing it.
24.3 Parameters
The parameters of the REMOTE service are implementation-specific (see the implementation section below for those of the default agent). The key contract parameter is enable, which gates remote command execution and file access.
24.4 Commands
tell – send a text message to remote node
Example:
tell 2, 'hello' // send text message to node 2
tell 2, 'hello', true // send reliable text message to node 2
fget – get file from remote node
fget can only get files from nodes with remote.enable = true.
Example:
fget 3, 'abc.txt' // get file abc.txt from node 3
fget 3, 'abc', 'abc2' // get file abc from node 3 as abc2
fget 3, 'abc', '' // get file abc from node 3 as byte[]
fput – put file on remote node
fput can only put files to nodes with remote.enable = true.
Examples:
fput 2, 'a.txt' // send file a.txt to node 2
fput 2, 'abc', 'abc2' // send file abc to node 2 as abc2
rsh – run shell command on remote node
rsh can only execute commands on nodes with remote.enable = true. The output of the command is sent back to the local node. If this is not desired, end the command with a semicolon.
Example:
rsh 3, 'reboot;' // ask node 3 to reboot itself
rsh 3, 'reboot;', true // reliably ask node 3 to reboot itself
rsh 3, 'phy.MTU' // ask node 3 to send me the value of phy.MTU
rsh 3, 'ls' // ask node 3 to send me the list of files
progress – enable/disable progress reporting for remote file transfers
Examples:
progress on // enable progress reporting for fget
progress true // enable progress reporting for fget
progress off // disable progress reporting for fget
progress false // disable progress reporting for fget
progress // check current setting for progress reporting
24.5 Examples
Start the 2-node-network, and connect to node A’s shell. The remote node (node B, address 31) must have remote access enabled before it will honor shell or file operations:
> remote.enable =truetrue
Back on node A, send a text message to node B, where it pops up on the shell:
> tell host('B'),'surfacing now'OK
[232]: surfacing now
Run a command remotely: the rsh command asks node B to execute a command — here, lowering its transmit power:
> rsh 31,'plvl -20'OK
A few seconds later (after the command has crossed the network and the remote node’s execDelay has elapsed), reading the parameter on node B confirms it was executed:
File transfers work the same way — fput sends a local file to the remote node, and fget retrieves a remote file, with a RemoteSuccessNtf or RemoteFileNtf reporting completion. The transcript below is illustrative (it assumes data.csv exists on node A and results.log on node B):
The default implementation is loaded as part of the default stack (Chapter 13) under the agent name caddy, and is most often used through its transport (transport service) and remote (remote service) shell handles. In addition to the REMOTE service described above, the same agent provides the TRANSPORT (Chapter 23) and DATAGRAM (Chapter 16) services. The base agent is CaddyLite; a licensed Caddy agent extends it with additional features (see the callout below).
24.6.1.1 How it works
Where a link delivers data to an immediate neighbor, the transport service delivers it all the way to a destination that may be several hops away, using the ROUTING service to choose the path. Two problems that the link layer cannot solve on its own are handled here. First, large datagrams are fragmented for transmission and reassembled at the destination, so an application can send payloads far larger than a single link frame; each fragment carries a compact transaction-and-fragment header, and a receiver that sees fragments arrive out of order abandons the transaction. Second, reliability is end-to-end: the destination acknowledges what it receives and the source retransmits what is lost, which is necessary because a datagram delivered reliably across each individual hop can still be lost if an intermediate node fails. The source waits up to ackTimeout for an end-to-end acknowledgement before retransmitting, and gives up after retry attempts. Outgoing datagrams are serviced from a queue, and large ones may be compressed before transmission.
The remote-access features map onto this reliable transport. Remote shell commands, text messages and file get/put are carried as transport datagrams; file transfers use a short handshake to exchange file information before the data flows. A command received from a remote node is run after a short execDelay (a safety margin), groovy controls whether such commands are interpreted as Groovy, cwd sets the working directory for file transfers, and retryDelay governs how long the agent waits before retrying when a route is temporarily unavailable. Remote operations are only honored when enable is set, and the agents this one builds on are named by dsp (the datagram/transport provider) and shell (the shell used to execute remote commands).
groovy – enable Groovy extensions for shell commands (default: true)
When Groovy extensions are enabled, rsh commands can use a me variable to denote the requesting node address.
Example:
rsh 3, 'tell me,"hello!"' // ask node 3 to send a text message to me
execDelay – delay before executing a command (seconds)
retryDelay – delay before retrying an unavailable route (seconds)
compress – enable compression for large datagrams
cwd – working directory to load/save files
ackTimeout – timeout for end-to-end ACKs (seconds)
retry – maximum retry attempts for datagram fragments
24.6.1.3 Usage notes
NotePremium feature
The base CaddyLite agent provides reliable multi-hop transport, remote access and file transfer, and is part of the standard distribution. The licensed Caddy agent is a drop-in replacement that adds:
Quality of Service (QoS) — datagram priority, time-to-live (TTL) and fairness, together with user-defined routing rules for selecting routes per message; and
Resumable file transfers — an interrupted file get/put resumes from where it left off, rather than restarting.
These are premium features (see Section 13.3). When the licensed Caddy agent is present, setup.groovy loads it automatically in place of CaddyLite; otherwise the base agent is used.
ping and the remote shell/file/text commands all use this agent; it is reachable as transport (transport service) and remote (remote service).
Enable remote shell/file operations (enable) only on nodes where you trust remote access.
Raise ackTimeout on long multi-hop paths where end-to-end acknowledgements take longer to return.