diff options
Diffstat (limited to 'lib/ssh/doc/src/ssh_channel.xml')
-rw-r--r-- | lib/ssh/doc/src/ssh_channel.xml | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_channel.xml new file mode 100644 index 0000000000..c2b7aa94a5 --- /dev/null +++ b/lib/ssh/doc/src/ssh_channel.xml @@ -0,0 +1,520 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2009</year> + <year>2009</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + + <title>ssh_channel</title> + <prepared>Ingela Anderton Andin</prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date></date> + <rev></rev> + </header> + <module>ssh_channel</module> + <modulesummary>Generic Ssh Channel Behavior + </modulesummary> + <description> + <p>Ssh services are implemented as channels that are multiplexed + over an ssh connection and communicates via the ssh connection + protocol. This module provides a callback API that takes care of + generic channel aspects such as flow control and close messages + and lets the callback functions take care of the service specific + parts. + </p> + </description> + + <section> + <title>COMMON DATA TYPES </title> + + <p>Type definitions that are used more than once in this module + and/or abstractions to indicate the intended use of the data + type:</p> + + <p><c>boolean() = true | false </c></p> + <p><c>string() = list of ASCII characters</c></p> + <p><c>timeout() = infinity | integer() - in milliseconds.</c></p> + <p><c>ssh_connection_ref() - opaque to the user returned by + ssh:connect/3 or sent to a ssh channel process</c></p> + <p><c>ssh_channel_id() = integer() </c></p> + <p><c>ssh_data_type_code() = 1 ("stderr") | 0 ("normal") are + currently valid values see RFC 4254 section 5.2.</c></p> + </section> + + <funcs> + <func> + <name>call(ChannelRef, Msg) -></name> + <name>call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason}</name> + <fsummary> Makes a synchronous call to a channel.</fsummary> + <type> + <v>ChannelRef = pid() </v> + <d>As returned by start_link/4 </d> + <v>Msg = term() </v> + <v>Timeout = timeout() </v> + <v>Reply = term() </v> + <v>Reason = closed | timeout </v> + </type> + <desc> + <p>Makes a synchronous call to the channel process by sending + a message and waiting until a reply arrives or a timeout + occurs. The channel will call + <c>CallbackModule:handle_call/3</c> to handle the message. + If the channel process does not exist <c>{error, closed}</c> is returned. + </p> + </desc> + </func> + + <func> + <name>cast(ChannelRef, Msg) -> ok </name> + <fsummary>Sends an asynchronous message to the channel + ChannelRef and returns ok.</fsummary> + <type> + <v>ChannelRef = pid() </v> + <d>As returned by start_link/4 </d> + <v>Msg = term() </v> + </type> + <desc> + <p>Sends an asynchronous message to the channel process and + returns ok immediately, ignoring if the destination node or + channel process does not exist. The channel will call + <c>CallbackModule:handle_cast/2</c> to handle the message. + </p> + </desc> + </func> + + <func> + <name>enter_loop(State) -> _ </name> + <fsummary> Makes an existing process into a ssh_channel process. </fsummary> + <type> + <v> State = term() - as returned by ssh_channel:init/1</v> + </type> + <desc> + <p> Makes an existing process into a <c>ssh_channel</c> + process. Does not return, instead the calling process will + enter the <c>ssh_channel</c> process receive loop and become a + <c>ssh_channel process.</c> The process must have been started using + one of the start functions in proc_lib, see <seealso + marker="stdlib:proc_lib">proc_lib(3)</seealso>. The + user is responsible for any initialization of the process + and needs to call ssh_channel:init/1. + </p> + </desc> + </func> + + <func> + <name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name> + <fsummary> Initiates a ssh_channel process.</fsummary> + <type> + <v> Options = [{Option, Value}]</v> + </type> + <desc> + <p> + The following options must be present: + </p> + <taglist> + <tag><c><![CDATA[{channel_cb, atom()}]]></c></tag> + <item>The module that implements the channel behavior.</item> + + <tag><c><![CDATA[{init_args(), list()}]]></c></tag> + <item> The list of arguments to the callback modules + init function.</item> + + <tag><c><![CDATA[{cm, connection_ref()}]]></c></tag> + <item> Reference to the ssh connection.</item> + + <tag><c><![CDATA[{channel_id, channel_id()}]]></c></tag> + <item> Id of the ssh channel.</item> + + </taglist> + + <note><p>This function is normally not called by the user, it is + only needed if for some reason the channel process needs + to be started with help of <c>proc_lib</c> instead calling + <c>ssh_channel:start/4</c> or <c>ssh_channel:start_link/4</c> </p> + </note> + </desc> + </func> + + <func> + <name>reply(Client, Reply) -> _</name> + <fsummary>Send a reply to a client.</fsummary> + <type> + <v>Client - opaque to the user, see explanation below</v> + <v>Reply = term()</v> + </type> + <desc> + <p>This function can be used by a channel to explicitly send a + reply to a client that called <c>call/[2,3]</c> when the reply + cannot be defined in the return value of + <c>CallbackModule:handle_call/3</c>.</p> + <p><c>Client</c> must be the <c>From</c> argument provided to + the callback function <c>handle_call/3</c>. + <c>Reply</c> is an arbitrary term, + which will be given back to the client as the return value of + <c>ssh_channel:call/[2,3].</c></p> + </desc> + </func> + + <func> + <name>start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name> + <name>start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> + {ok, ChannelRef} | {error, Reason}</name> + <fsummary> Starts a processes that handles a ssh channel. </fsummary> + <type> + <v>SshConnection = ssh_connection_ref()</v> + <v>ChannelId = ssh_channel_id() </v> + <d> As returned by ssh_connection:session_channel/[2,4]</d> + <v>ChannelCb = atom()</v> + <d> The name of the module implementing the service specific parts + of the channel.</d> + <v>CbInitArgs = [term()]</v> + <d>Argument list for the init function in the callback module. </d> + <v>ChannelRef = pid()</v> + </type> + <desc> + <p>Starts a processes that handles a ssh channel. Will be + called internally by the ssh daemon or explicitly by the ssh + client implementations. A channel process traps exit signals + by default. + </p> + </desc> + </func> + + </funcs> + + <section> + <title>CALLBACK FUNCTIONS</title> + + <p>The functions init/1, terminate/2, handle_ssh_msg/2 and + handle_msg/2 are the functions that are required to provide the + implementation for a server side channel, such as a ssh subsystem + channel that can be plugged into the erlang ssh daemon see + <seealso marker="ssh">ssh:daemon/[2, 3]</seealso>. The + handle_call/3, handle_cast/2 code_change/3 and enter_loop/1 + functions are only relevant when implementing a client side + channel.</p> + </section> + + <section> + <marker id="cb_timeouts"></marker> + <title> CALLBACK TIMEOUTS</title> + <p> If an integer timeout value is provided in a return value of + one of the callback functions, a timeout will occur unless a + message is received within <c>Timeout</c> milliseconds. A timeout + is represented by the atom <c>timeout</c> which should be handled + by the <seealso marker="#handle_msg">handle_msg/2</seealso> + callback function. The atom infinity can be used to wait + indefinitely, this is the default value. </p> + </section> + + <funcs> + <func> + <name>CallbackModule:code_change(OldVsn, State, Extra) -> {ok, + NewState}</name> + <fsummary> Converts process state when code is changed.</fsummary> + <type> + <v> Converts process state when code is changed.</v> + </type> + <desc> + <p>This function is called by a client side channel when it + should update its internal state during a release + upgrade/downgrade, i.e. when the instruction + <c>{update,Module,Change,...}</c> where + <c>Change={advanced,Extra}</c> is given in the <c>appup</c> + file. See <seealso + marker="doc/design_principles:release_handling#instr">OTP + Design Principles</seealso> for more information. Any new + connection will benefit from a server side upgrade but + already started connections on the server side will not be + affected. + </p> + + <note><p>If there are long lived ssh connections and more + than one upgrade in a short time this may cause the old + connections to fail as only two versions of the code may + be loaded simultaneously.</p></note> + + <p>In the case of an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and + in the case of a downgrade, <c>OldVsn</c> is + <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> + attribute(s) of the old version of the callback module + <c>Module</c>. If no such attribute is defined, the version + is the checksum of the BEAM file.</p> + <p><c>State</c> is the internal state of the channel.</p> + <p><c>Extra</c> is passed as-is from the <c>{advanced,Extra}</c> + part of the update instruction.</p> + <p>The function should return the updated internal state.</p> + </desc> + </func> + + <func> + <name>CallbackModule:init(Args) -> {ok, State} | {ok, State, Timeout} | + {stop, Reason}</name> + <fsummary> Makes necessary initializations and returns the + initial channel state if the initializations succeed.</fsummary> + <type> + <v> Args = term() </v> + <d> Last argument to ssh_channel:start_link/4.</d> + <v> State = term() </v> + <v>Timeout = timeout() </v> + <v> Reason = term() </v> + </type> + <desc> + <p> Makes necessary initializations and returns the initial channel + state if the initializations succeed. + </p> + <p>For more detailed information on timeouts see the section + <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p> + </desc> + </func> + + <func> + <name>CallbackModule:handle_call(Msg, From, State) -> Result</name> + <fsummary> Handles messages sent by calling + <c>ssh_channel:call/[2,3]</c></fsummary> + <type> + <v>Msg = term()</v> + <v>From = opaque to the user should be used as argument to + ssh_channel:reply/2</v> + <v>State = term()</v> + <v>Result = {reply, Reply, NewState} | {reply, Reply, NewState, Timeout} + | {noreply, NewState} | {noreply , NewState, Timeout} + | {stop, Reason, Reply, NewState} | {stop, Reason, NewState} </v> + <v>Reply = term() - will be the return value of ssh_channel:call/[2,3]</v> + <v>Timeout = timeout() </v> + <v>NewState = term() - a possible updated version of State</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Handles messages sent by calling + <c>ssh_channel:call/[2,3]</c> + </p> + <p>For more detailed information on timeouts see the section + <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p> + </desc> + </func> + + <func> + <name>CallbackModule:handle_cast(Msg, State) -> Result</name> + <fsummary> Handles messages sent by calling + <c>ssh_channel:cact/2</c></fsummary> + <type> + <v>Msg = term()</v> + <v>State = term()</v> + <v>Result = {noreply, NewState} | {noreply, NewState, Timeout} + | {stop, Reason, NewState}</v> + <v>NewState = term() - a possible updated version of State</v> + <v>Timeout = timeout() </v> + <v>Reason = term()</v> + </type> + <desc> + <p> Handles messages sent by calling + <c>ssh_channel:cast/2</c> + </p> + <p>For more detailed information on timeouts see the section + <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p> + <marker id="handle_msg"></marker> + </desc> + </func> + + <func> + <name>CallbackModule:handle_msg(Msg, State) -> {ok, State} | + {stop, ChannelId, State}</name> + + <fsummary> Handle other messages than ssh connection protocol, + call or cast messages sent to the channel.</fsummary> + <type> + <v>Msg = timeout | term()</v> + <v>State = term() </v> + </type> + <desc> + <p>Handle other messages than ssh connection protocol, call or + cast messages sent to the channel. + </p> + + <p> Possible erlang 'EXIT'-messages should be handled by this + function and all channels should handle the following message.</p> + + <taglist> + <tag><c><![CDATA[{ssh_channel_up, ssh_channel_id(), + ssh_connection_ref()}]]></c></tag> + <item>This is the first messages that will be received + by the channel, it is sent just before + the ssh_channel:init/1 function returns successfully. + This is especially useful if the server wants + to send a message to the client without first receiving + a message from the client. If the message is not useful + for your particular problem just ignore it by immediately + returning {ok, State}. + </item> + </taglist> + </desc> + </func> + + <func> + <name>CallbackModule:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, + ssh_channel_id(), State}</name> + <fsummary> Handles ssh connection protocol messages. </fsummary> + <type> + <v>Msg = {ssh_cm, ssh_connection_ref(), SshMsg}</v> + <v> SshMsg = tuple() - see message list below</v> + <v>State = term()</v> + </type> + <desc> + <p> Handles ssh connection protocol messages that may need + service specific attention. + </p> + + <p> All channels should handle the following messages. For + channels implementing subsystems the handle_ssh_msg-callback + will not be called for any other messages. </p> + + <taglist> + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {data, ssh_channel_id(), + ssh_data_type_code(), binary() = Data}}]]></c></tag> + <item> Data has arrived on the channel. When the callback + for this message returns the channel behavior will adjust + the ssh flow control window.</item> + + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {eof, + ssh_channel_id()}}]]></c></tag> + <item>Indicteas that the other side will not send any more + data.</item> + + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {signal, + ssh_channel_id(), ssh_signal()}} ]]></c></tag> + <item>A signal can be delivered to the remote + process/service using the following message. Some systems + may not implement signals, in which case they should ignore + this message.</item> + + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), + {exit_signal, ssh_channel_id(), string() = exit_signal, + string() = ErrorMsg, string() = + LanguageString}}]]></c></tag> + <item>A remote execution may terminate violently due to a + signal then this message may be received. For details on valid string + values see RFC 4254 section 6.10</item> + + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {exit_status, + ssh_channel_id(), integer() = ExitStatus}}]]></c></tag> + <item> When the command running at the other end terminates, + the following message can be sent to return the exit status + of the command. A zero 'exit_status' usually means that the + command terminated successfully.</item> + </taglist> + + <p> Channels implementing a shell and command execution on the server side + should also handle the following messages. </p> + + <taglist> + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {env, ssh_channel_id(), + boolean() = WantReply, string() = Var, string() = Value}}]]></c></tag> + <item> Environment variables may be passed to the + shell/command to be started later. Note that before the + callback returns it should call the function + ssh_connection:reply_request/4 with the boolean value of <c> + WantReply</c> as the second argument. + </item> + + <tag><c><![CDATA[{ssh_cm, ConnectionRef, {exec, ssh_channel_id(), + boolean() = WantReply, string() = Cmd}}]]></c></tag> + <item> This message will request that the server start the + execution of the given command. Note that before the + callback returns it should call the function + ssh_connection:reply_request/4 with the boolean value of <c> + WantReply</c> as the second argument.</item> + + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {pty, ssh_channel_id(), + boolean() = WantReply, {string() = Terminal, integer() = CharWidth, + integer() = RowHeight, integer() = PixelWidth, integer() = PixelHight, + [{atom() | integer() = Opcode, + integer() = Value}] = TerminalModes}}}]]></c></tag> + <item>A pseudo-terminal has been requested for the + session. Terminal is the value of the TERM environment + variable value (e.g., vt100). Zero dimension parameters must + be ignored. The character/row dimensions override the pixel + dimensions (when nonzero). Pixel dimensions refer to the + drawable area of the window. The <c>Opcode</c> in the + <c>TerminalModes</c> list is the mnemonic name, represented + as an lowercase erlang atom, defined in RFC 4254 section 8, + or the opcode if the mnemonic name is not listed in the + RFC. Example <c>OP code: 53, mnemonic name ECHO erlang atom: + echo</c>. Note that before the callback returns it should + call the function ssh_connection:reply_request/4 with the + boolean value of <c> WantReply</c> as the second + argument.</item> + + <tag><c><![CDATA[{ssh_cm, ConnectionRef, {shell, boolean() = + WantReply}}]]></c></tag> + <item> This message will request that the user's default + shell be started at the other end. Note that before the + callback returns it should call the function + ssh_connection:reply_request/4 with the value of <c> + WantReply</c> as the second argument. + </item> + + <tag><c><![CDATA[ {ssh_cm, ssh_connection_ref(), {window_change, + ssh_channel_id(), integer() = CharWidth, integer() = RowHeight, + integer() = PixWidth, integer() = PixHeight}}]]></c></tag> + <item> When the window (terminal) size changes on the client + side, it MAY send a message to the other side to inform it + of the new dimensions.</item> + </taglist> + + <p> The following message is completely taken care of by the + ssh channel behavior</p> + + <taglist> + <tag><c><![CDATA[{ssh_cm, ssh_connection_ref(), {closed, + ssh_channel_id()}}]]></c></tag> + <item> The channel behavior will send a close message to the + other side if such a message has not already been sent and + then terminate the channel with reason normal.</item> + </taglist> + </desc> + </func> + + <func> + <name>CallbackModule:terminate(Reason, State) -> _</name> + <fsummary> </fsummary> + <type> + <v>Reason = term()</v> + <v>State = term()</v> + </type> + <desc> + <p>This function is called by a channel process when it is + about to terminate. Before this function is called ssh_connection:close/2 + will be called if it has not been called earlier. + This function should be the opposite of <c>CallbackModule:init/1</c> + and do any necessary cleaning up. When it returns, the + channel process terminates with reason <c>Reason</c>. The return value is + ignored. + </p> + </desc> + </func> + + </funcs> + +</erlref> |