1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
/* RCSID("$Id: nchan.h,v 1.2 1999/10/16 22:29:01 markus Exp $"); */
#ifndef NCHAN_H
#define NCHAN_H
/*
* SSH Protocol 1.5 aka New Channel Protocol
* Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
* Written by Markus Friedl in October 1999
*
* Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
* tear down of channels:
*
* 1.3: strict request-ack-protocol:
* CLOSE ->
* <- CLOSE_CONFIRM
*
* 1.5: uses variations of:
* IEOF ->
* <- OCLOSE
* <- IEOF
* OCLOSE ->
* i.e. both sides have to close the channel
*
* See the debugging output from 'ssh -v' and 'sshd -d' of
* ssh-1.2.27 as an example.
*
* Details: (for Channel data structure see channels.h)
*
* - the output_buffer gets data received from the remote peer and
* is written to the socket,
* - the input_buffer gets data from the socket and is sent to remote peer.
* - the socket represents the local object communicating with an object
* reachable via the peer
*
* PEER A PEER B
*
* read(sock, input_buffer) < 0;
* shutdown_read();
* flush(input_buffer) =: DATA
* send(DATA) -> rcvd(DATA)
* write(sock, output_buffer:=DATA);
* send(IEOF) -> rcvd(IEOF)
* shutdown_write() if:
* a) write fails
* b) rcvd_IEOF==true &&
* output_buffer==empty
* rcvd(OCLOSE) <- send(OCLOSE)
*
* The channel is now half closed. No data will flow from A to B.
*
* Note that each side can remove the channel only if 2 messages
* have been sent and received and the associated socket has been
* shutdown, see below:
*/
enum {
/* ssh-proto-1.5 overloads message-types */
CHAN_IEOF = SSH_MSG_CHANNEL_CLOSE,
/* there will be no more data from sender */
CHAN_OCLOSE = SSH_MSG_CHANNEL_CLOSE_CONFIRMATION,
/* all received data has been written to the socket */
/* channel close flags */
CHAN_IEOF_SENT = 0x01,
CHAN_IEOF_RCVD = 0x02,
CHAN_OCLOSE_SENT = 0x04,
CHAN_OCLOSE_RCVD = 0x08,
CHAN_SHUT_RD = 0x10,
CHAN_SHUT_WR = 0x20,
/* a channel can be removed if ALL the following flags are set: */
CHAN_CLOSED = CHAN_IEOF_SENT | CHAN_IEOF_RCVD |
CHAN_OCLOSE_SENT | CHAN_OCLOSE_RCVD |
CHAN_SHUT_RD | CHAN_SHUT_WR
};
void chan_del_if_dead(Channel *c);
void chan_rcvd_ieof(Channel *c);
void chan_rcvd_oclose(Channel *c);
void chan_send_ieof(Channel *c);
void chan_send_oclose(Channel *c);
void chan_shutdown_read(Channel *c);
void chan_shutdown_write(Channel *c);
#endif
|