1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2008-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21%%----------------------------------------------------------------------
22%% Purpose: The ssh subsystem supervisor
23%%----------------------------------------------------------------------
24
25-module(ssh_subsystem_sup).
26
27-behaviour(supervisor).
28
29-include("ssh.hrl").
30
31-export([start_link/5,
32         start_channel/8,
33         tcpip_fwd_supervisor/1
34	]).
35
36%% Supervisor callback
37-export([init/1]).
38
39%%%=========================================================================
40%%%  API
41%%%=========================================================================
42start_link(Role, Address=#address{}, Id, Socket, Options) ->
43    case supervisor:start_link(?MODULE, [Role, Address, Id, Socket, Options]) of
44        {error, {shutdown, {failed_to_start_child, _, Error}}} ->
45            {error,Error};
46        Other ->
47            Other
48    end.
49
50start_channel(Role, SupPid, ConnRef, Callback, Id, Args, Exec, Opts) ->
51    ChannelSup = channel_supervisor(SupPid),
52    ssh_channel_sup:start_child(Role, ChannelSup, ConnRef, Callback, Id, Args, Exec, Opts).
53
54tcpip_fwd_supervisor(SubSysSup) ->
55    find_child(tcpip_forward_acceptor_sup, SubSysSup).
56
57
58%%%=========================================================================
59%%%  Supervisor callback
60%%%=========================================================================
61init([Role, Address, Id, Socket, Options]) ->
62    SubSysSup = self(),
63    SupFlags = #{strategy      => one_for_all,
64                 auto_shutdown => any_significant,
65                 intensity     =>    0,
66                 period        => 3600
67                },
68    ChildSpecs = [#{id          => connection,
69                    restart     => temporary,
70                    type        => worker,
71                    significant => true,
72                    start       => {ssh_connection_handler,
73                                    start_link,
74                                    [Role, Address, Id, Socket,
75                                     ?PUT_INTERNAL_OPT([
76                                                        {subsystem_sup, SubSysSup}
77                                                       ], Options)
78                                    ]
79                                   }
80                   },
81                  #{id      => channel_sup,
82                    restart => temporary,
83                    type    => supervisor,
84                    start   => {ssh_channel_sup, start_link, [Options]}
85                   },
86
87                 #{id      => tcpip_forward_acceptor_sup,
88                   restart => temporary,
89                   type    => supervisor,
90                   start   => {ssh_tcpip_forward_acceptor_sup, start_link, []}
91                  }
92                 ],
93    {ok, {SupFlags,ChildSpecs}}.
94
95%%%=========================================================================
96%%%  Internal functions
97%%%=========================================================================
98channel_supervisor(SubSysSup) -> find_child(channel_sup, SubSysSup).
99
100find_child(Id, Sup) when is_pid(Sup) ->
101    try
102       {Id, Pid, _, _} = lists:keyfind(Id, 1, supervisor:which_children(Sup)),
103       Pid
104    catch
105        exit:{no_proc,_} ->
106            {error, no_proc};
107        _:_ ->
108            {error, {id_not_found,?MODULE,Id}}
109    end.
110
111