channel.h 11.8 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
2
/* channel.h
 *
3
4
5
 * Information about ssh channels.
 *
 * $Id$
Niels Möller's avatar
Niels Möller committed
6
7
 */

Niels Möller's avatar
Niels Möller committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Möller
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

Niels Möller's avatar
Niels Möller committed
27
28
29
#ifndef LSH_CHANNEL_H_INCLUDED
#define LSH_CHANNEL_H_INCLUDED

Niels Möller's avatar
Niels Möller committed
30
#include "alist.h"
31
#include "command.h"
Niels Möller's avatar
Niels Möller committed
32
33
#include "connection.h"
#include "parse.h"
Niels Möller's avatar
Niels Möller committed
34
#include "server_pty.h"
35
#include "write_buffer.h"
Niels Möller's avatar
Niels Möller committed
36

37
#define GABA_DECLARE
38
#include "channel.h.x"
39
#undef GABA_DECLARE
40

Niels Möller's avatar
Niels Möller committed
41
42
43
44
45
46
47
48
/* Channels are indexed by local channel number in some array. This
 * index is not stored in the channel struct. When sending messages on
 * the channel, it is identified by the *remote* sides index number,
 * and this number must be stored. */

#define CHANNEL_DATA 0
#define CHANNEL_STDERR_DATA 1

49
#define CHANNEL_SENT_CLOSE 1
50
#define CHANNEL_RECEIVED_CLOSE 2
51
#define CHANNEL_SENT_EOF 4
52
#define CHANNEL_RECEIVED_EOF 8
53

54
/* Means that we should send close when we have both sent and received EOF. */
55
#define CHANNEL_CLOSE_AT_EOF 0x10
56

57

58
/* GABA:
59
60
   (class
     (name ssh_channel)
61
     (super flow_controlled)
62
63
     (vars
       ; Remote channel number 
Niels Möller's avatar
Niels Möller committed
64
       (channel_number . UINT32)
65

Niels Möller's avatar
Niels Möller committed
66
67
68
69
70
       ; Somewhat redundant. Makes it easier to locate
       ; the channel_table entry for the channel, which
       ; is needed for deallocating it.
       ;; (local_number . UINT32)
       
71
72
73
74
75
76
77
       ; Where to pass errors. This is used for two different
       ; purposes: If opening the channel fails, EXC_CHANNEL_OPEN is
       ; raised. Once the channel is open, this handler is used for
       ; EXC_FINISH_CHANNEL and EXC_FINISH_PENDING. If the channel was
       ; opened on the peer's request, the connection's exception
       ; handler is a parent of the channel's. But that is not true in
       ; general.
Niels Möller's avatar
Niels Möller committed
78
       (e object exception_handler)
79
80
81
82

       ; Resources associated with the channel. This object is also
       ; put onto the connections resource list.
       (resources object resource_list)
Niels Möller's avatar
Niels Möller committed
83
       
84
       ; We try to keep the rec_window_size between max_window / 2
85
86
       ; and max_window. 
       ;; (max_window simple UINT32) 
87

88
89
90
       ; FIXME: Does the maximum packet sizes apply to complete ssh
       ; packets, or the data payload?

91
92
93
94
95
96
97
98
       (rec_window_size simple UINT32)
       (rec_max_packet simple UINT32)

       (send_window_size simple UINT32)
       (send_max_packet simple UINT32)

       ; FIXME: Perhaps this should be moved to the channel_table, and
       ; a pointer to that table be stored here instead?
99
100
       ; Now that we pass the connection pointer to most functions,
       ; is this field needed at all?
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
       (write object abstract_write)
  
       (request_types object alist)

       (flags simple int)

       ; Number of files connected to this channel. For instance,
       ; stdout and stderr can be multiplexed on the same channel. We
       ; should not close the channel until we have got an EOF on both
       ; sources.
       (sources simple int)

       ; FIXME: What about return values from these functions? A
       ; channel may fail to process it's data. Is there some way to
       ; propagate a channel broken message to the other end? 

       ; Type is CHANNEL_DATA or CHANNEL_STDERR_DATA
Niels Möller's avatar
Niels Möller committed
118
       (receive method void "int type" "struct lsh_string *data")
119

120
121
122
       ; Called when we are allowed to send more data on the channel.
       ; Implies that the send_window_size is non-zero. 
       (send_adjust method void "UINT32 increment")
123

Niels Möller's avatar
Niels Möller committed
124
125
       ; Called when the channel is closed
       ; FIXME: Is this needed for anything?
Niels Möller's avatar
Niels Möller committed
126
       (close method void)
127

128
       ; Called when eof is received on the channel (or when it is
129
       ; closed, whatever happens first).
Niels Möller's avatar
Niels Möller committed
130
       (eof method void)
131
132
  
       ; Reply from SSH_MSG_CHANNEL_OPEN_REQUEST
133
134
135
       ;; (open_confirm method int)
       ;; (open_failure method int)
       (open_continuation object command_continuation)
136

137
       ; Queue of channel requests that we expect replies on
138
139
140
141
142
       (pending_requests struct object_queue)

       ; Channel requests that we have received, and should reply to
       ; in the right order
       (active_requests struct object_queue)))
143
       
144
       ; Reply from SSH_MSG_CHANNEL_REQUEST 
145
       ;; (channel_success method int)
146
       ;; (channel_failure method int))) */
147

148
149
#define CHANNEL_RECEIVE(s, t, d) \
((s)->receive((s), (t), (d)))
Niels Möller's avatar
Niels Möller committed
150

151
#define CHANNEL_SEND_ADJUST(s, i) ((s)->send_adjust((s), (i)))
152
153
154
     
#define CHANNEL_CLOSE(s) \
((s)->close((s)))
Niels Möller's avatar
Niels Möller committed
155

156
157
#define CHANNEL_EOF(s) \
((s)->eof((s)))
Niels Möller's avatar
Niels Möller committed
158

159
160
#define CHANNEL_OPEN_CONFIRM(s) \
((s)->open_confirm((s)))
161

162
163
#define CHANNEL_OPEN_FAILURE(s) \
((s)->open_failure((s)))
Niels Möller's avatar
Niels Möller committed
164

165
166
167
168
169
/* Values used in the in_use array. */
#define CHANNEL_FREE 0
#define CHANNEL_RESERVED 1
#define CHANNEL_IN_USE 2

170
/* GABA:
171
172
   (class
     (name channel_table)
Niels Möller's avatar
Niels Möller committed
173
     ;; (super exception_handler)
174
175
176
177
178
179
180
     (vars
       ; FIXME: This is relevant only for the server side. It's
       ; probably better to store this in the connection struct.

       ;; uid_t user;  ; Authenticated user 

       ; Channels are indexed by local number
Niels Möller's avatar
Niels Möller committed
181
182
       (channels space (object ssh_channel) used_channels)
       
183
184
185
186
187
       ; Global requests that we support
       (global_requests object alist)
       ; Channel types that we can open
       (channel_types object alist)
       
188
189
190
191
       ; Allocation of local channel numbers is managed using the same
       ; method as is traditionally used for allocation of unix file 
       ; descriptors.

Niels Möller's avatar
Niels Möller committed
192
193
194
195
196
       ; Channel numbers can be reserved before there is any actual channel
       ; assigned to them. So the channels table is not enough for keeping track of which
       ; numbers are in use.
       (in_use space UINT8)
       
197
198
199
200
201
202
       (allocated_channels simple UINT32)
       (next_channel simple UINT32)
     
       (used_channels simple UINT32)
       (max_channels simple UINT32) ; Max number of channels allowed 

203
204
205
206
       ; Forwarded TCP ports
       (local_ports struct object_queue)
       (remote_ports struct object_queue)
       
207
208
       ; Global requests that we have received, and should reply to
       ; in the right order
209
       (active_global_requests struct object_queue)
210
211

       ; Queue of global requests that we expect replies on.
212
       (pending_global_requests struct object_queue)
213
       
214
215
216
217
218
219
220
221
       ; If non-zero, close connection after all active channels have
       ; died.
       (pending_close simple int)

       ; FIXME: Perhaps we should use an flag to indicate whether or
       ; not new channels can be opened?
       ))
*/
Niels Möller's avatar
Niels Möller committed
222
223

/* SSH_MSG_GLOBAL_REQUEST */
224

225
/* GABA:
226
227
228
   (class
     (name global_request)
     (vars
Niels Möller's avatar
Niels Möller committed
229
       (handler method void "struct ssh_connection *connection"
230
231
232
                            "UINT32 type"
			    ;; FIXME: Is want-reply really needed?
                            "int want_reply"
Niels Möller's avatar
Niels Möller committed
233
                            "struct simple_buffer *args"
234
235
			    "struct command_continuation *c"
			    "struct exception_handler *e")))
236
237
*/

238
#define GLOBAL_REQUEST(r, c, t, w, a, n, e) ((r)->handler((r), (c), (t), (w), (a), (n), (e)))
Niels Möller's avatar
Niels Möller committed
239
240

/* SSH_MSG_CHANNEL_OPEN */
Niels Möller's avatar
Niels Möller committed
241

Niels Möller's avatar
Niels Möller committed
242
243
/* Raised if opening of a channel fails. Used both on the client and
 * the server side.*/
Niels Möller's avatar
Niels Möller committed
244
245
246
247
248
249
250
251
/* GABA:
   (class
     (name channel_open_exception)
     (super exception)
     (vars
       (error_code . UINT32)))
*/

252
253
struct exception *
make_channel_open_exception(UINT32 error_code, const char *msg);
Niels Möller's avatar
Niels Möller committed
254

255

256
/* GABA:
257
258
259
   (class
     (name channel_open)
     (vars
Niels Möller's avatar
Niels Möller committed
260
       (handler method void
261
                "struct ssh_connection *connection"
262
		"UINT32 type"
263
		"UINT32 send_window_size"
264
		"UINT32 send_max_packet"
265
                "struct simple_buffer *data"
Niels Möller's avatar
Niels Möller committed
266
267
                "struct command_continuation *c"
		"struct exception_handler *e")))
268
269
*/

270
271
#define CHANNEL_OPEN(o, c, t, w, m, d, r, e) \
((o)->handler((o), (c), (t), (w), (m), (d), (r), (e)))
Niels Möller's avatar
Niels Möller committed
272

Niels Möller's avatar
Niels Möller committed
273
/* SSH_MSG_CHANNEL_REQUEST */
274
/* GABA:
275
276
277
   (class
     (name channel_request)
     (vars
Niels Möller's avatar
Niels Möller committed
278
       (handler method void
279
		"struct ssh_channel *channel"
280
		"struct ssh_connection *connection"
281
		"UINT32 type"
282
		"int want_reply"
283
284
285
		"struct simple_buffer *args"
		"struct command_continuation *c"
		"struct exception_handler *e")))
286
287
*/

288
289
#define CHANNEL_REQUEST(s, c, conn, t, w, a, n, e) \
((s)->handler((s), (c), (conn), (t), (w), (a), (n), (e)))
290

291
/* #define CONNECTION_START(c, s) ((c)->start((c), (s))) */
292

293
294
void init_channel(struct ssh_channel *channel);

295
296
297
struct channel_table *make_channel_table(void);
int alloc_channel(struct channel_table *table);
void dealloc_channel(struct channel_table *table, int i);
Niels Möller's avatar
Niels Möller committed
298

299
300
301
302
void
use_channel(struct ssh_connection *connection,
	    UINT32 local_channel_number);

303
void register_channel(struct ssh_connection *connection,
Niels Möller's avatar
Niels Möller committed
304
		      UINT32 local_channel_number,
305
306
		      struct ssh_channel *channel,
		      int take_into_use);
Niels Möller's avatar
Niels Möller committed
307

308
309
310
311
struct ssh_channel *
lookup_channel(struct channel_table *table, UINT32 i);
struct ssh_channel *
lookup_channel_reserved(struct channel_table *table, UINT32 i);
Niels Möller's avatar
Niels Möller committed
312

313
314
315
316
struct abstract_write *make_channel_write(struct ssh_channel *channel);
struct abstract_write *make_channel_write_extended(struct ssh_channel *channel,
						   UINT32 type);

317
318
struct io_callback *make_channel_read_data(struct ssh_channel *channel);
struct io_callback *make_channel_read_stderr(struct ssh_channel *channel);
319

Niels Möller's avatar
Niels Möller committed
320
struct lsh_string *format_global_failure(void);
321
struct lsh_string *format_global_success(void);
322

Niels Möller's avatar
Niels Möller committed
323
struct lsh_string *format_open_failure(UINT32 channel, UINT32 reason,
324
				       const char *msg, const char *language);
325
326
struct lsh_string *format_open_confirmation(struct ssh_channel *channel,
					    UINT32 channel_number,
327
					    const char *format, ...);
328
329

struct lsh_string *format_channel_success(UINT32 channel);
Niels Möller's avatar
Niels Möller committed
330
331
struct lsh_string *format_channel_failure(UINT32 channel);

Niels Möller's avatar
Niels Möller committed
332
333
334
struct lsh_string *prepare_window_adjust(struct ssh_channel *channel,
					 UINT32 add);

335
336
337
void
channel_start_receive(struct ssh_channel *channel,
		      UINT32 initial_window_size);
338

339
#if 0
340
struct lsh_string *prepare_channel_open(struct ssh_connection *connection,
341
342
					int type,
					struct ssh_channel *channel,
343
					const char *format, ...);
344
345
346
347
348
#endif
struct lsh_string *
format_channel_open(int type, UINT32 local_channel_number,
		    struct ssh_channel *channel,
		    const char *format, ...);
349

350
351
352
353
struct lsh_string *format_channel_request(int type,
					  struct ssh_channel *channel,
					  int want_reply,
					  const char *format, ...);
354

355
356
357
358
struct lsh_string *
format_global_request(int type, int want_reply,
		      const char *format, ...);

359
360
struct lsh_string *format_channel_close(struct ssh_channel *channel);
struct lsh_string *format_channel_eof(struct ssh_channel *channel);
361

Niels Möller's avatar
Niels Möller committed
362
363
void channel_close(struct ssh_channel *channel);
void channel_eof(struct ssh_channel *channel);
364

Niels Möller's avatar
Niels Möller committed
365
struct close_callback *
366
367
368
369
370
make_channel_read_close_callback(struct ssh_channel *channel);

struct exception_handler *
make_channel_io_exception_handler(struct ssh_channel *channel,
				  const char *prefix,
371
372
				  struct exception_handler *parent,
				  const char *context);
373

374
375
struct lsh_string *channel_transmit_data(struct ssh_channel *channel,
					 struct lsh_string *data);
376

377
378
379
struct lsh_string *channel_transmit_extended(struct ssh_channel *channel,
					     UINT32 type,
					     struct lsh_string *data);
380

381
382
extern struct command_simple connection_service_command;
#define INIT_CONNECTION_SERVICE (&connection_service_command.super.super)
383

Niels Möller's avatar
Niels Möller committed
384

Niels Möller's avatar
Niels Möller committed
385
#endif /* LSH_CHANNEL_H_INCLUDED */