def open_channel(<EOL>self,<EOL>kind,<EOL>dest_addr=None,<EOL>src_addr=None,<EOL>window_size=None,<EOL>max_packet_size=None,<EOL>timeout=None,<EOL>):
if not self.active:<EOL><INDENT>raise SSHException("<STR_LIT>")<EOL><DEDENT>timeout = <NUM_LIT> if timeout is None else timeout<EOL>self.lock.acquire()<EOL>try:<EOL><INDENT>window_size = self._sanitize_window_size(window_size)<EOL>max_packet_size = self._sanitize_packet_size(max_packet_size)<EOL>chanid = self._next_channel()<EOL>m = Message()<EOL>m.add_byte(cMSG_CHANNEL_OPEN)<EOL>m.add_string(kind)<EOL>m.add_int(chanid)<EOL>m.add_int(window_size)<EOL>m.add_int(max_packet_size)<EOL>if (kind == "<STR_LIT>") or (kind == "<STR_LIT>"):<EOL><INDENT>m.add_string(dest_addr[<NUM_LIT:0>])<EOL>m.add_int(dest_addr[<NUM_LIT:1>])<EOL>m.add_string(src_addr[<NUM_LIT:0>])<EOL>m.add_int(src_addr[<NUM_LIT:1>])<EOL><DEDENT>elif kind == "<STR_LIT>":<EOL><INDENT>m.add_string(src_addr[<NUM_LIT:0>])<EOL>m.add_int(src_addr[<NUM_LIT:1>])<EOL><DEDENT>chan = Channel(chanid)<EOL>self._channels.put(chanid, chan)<EOL>self.channel_events[chanid] = event = threading.Event()<EOL>self.channels_seen[chanid] = True<EOL>chan._set_transport(self)<EOL>chan._set_window(window_size, max_packet_size)<EOL><DEDENT>finally:<EOL><INDENT>self.lock.release()<EOL><DEDENT>self._send_user_message(m)<EOL>start_ts = time.time()<EOL>while True:<EOL><INDENT>event.wait(<NUM_LIT:0.1>)<EOL>if not self.active:<EOL><INDENT>e = self.get_exception()<EOL>if e is None:<EOL><INDENT>e = SSHException("<STR_LIT>")<EOL><DEDENT>raise e<EOL><DEDENT>if event.is_set():<EOL><INDENT>break<EOL><DEDENT>elif start_ts + timeout < time.time():<EOL><INDENT>raise SSHException("<STR_LIT>")<EOL><DEDENT><DEDENT>chan = self._channels.get(chanid)<EOL>if chan is not None:<EOL><INDENT>return chan<EOL><DEDENT>e = self.get_exception()<EOL>if e is None:<EOL><INDENT>e = SSHException("<STR_LIT>")<EOL><DEDENT>raise e<EOL>
Request a new channel to the server. `Channels <.Channel>` are
socket-like objects used for the actual transfer of data across the
session. You may only request a channel after negotiating encryption
(using `connect` or `start_client`) and authenticating.

.. note:: Modifying the the window and packet sizes might have adverse
    effects on the channel created. The default values are the same
    as in the OpenSSH code base and have been battle tested.

:param str kind:
    the kind of channel requested (usually ``"session"``,
    ``"forwarded-tcpip"``, ``"direct-tcpip"``, or ``"x11"``)
:param tuple dest_addr:
    the destination address (address + port tuple) of this port
    forwarding, if ``kind`` is ``"forwarded-tcpip"`` or
    ``"direct-tcpip"`` (ignored for other channel types)
:param src_addr: the source address of this port forwarding, if
    ``kind`` is ``"forwarded-tcpip"``, ``"direct-tcpip"``, or ``"x11"``
:param int window_size:
    optional window size for this session.
:param int max_packet_size:
    optional max packet size for this session.
:param float timeout:
    optional timeout opening a channel, default 3600s (1h)

:return: a new `.Channel` on success

:raises:
    `.SSHException` -- if the request is rejected, the session ends
    prematurely or there is a timeout openning a channel

.. versionchanged:: 1.15
    Added the ``window_size`` and ``max_packet_size`` arguments.