io.c 45 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
/* io.c
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * $Id$ */

/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Mller
 *
 * 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
J.H.M. Dassen's avatar
J.H.M. Dassen committed
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Niels Möller's avatar
Niels Möller committed
22
23
 */

24
#include "io.h"
25
26

#include "format.h"
27
28
29
#include "werror.h"
#include "xalloc.h"

Niels Möller's avatar
Niels Möller committed
30
31
32
#include <assert.h>
#include <string.h>

33
#if HAVE_UNISTD_H
Niels Möller's avatar
Niels Möller committed
34
#include <unistd.h>
35
#endif
36
37

#ifdef HAVE_POLL
38
39
40
41
42
# if HAVE_POLL_H
#  include <poll.h>
# elif HAVE_SYS_POLL_H
#  include <sys/poll.h>
# endif
43
#else
44
# include "jpoll.h"
45
46
#endif

47
48
49
50
51
52
53
/* Workaround for some version of FreeBSD. */
#ifdef POLLRDNORM
# define MY_POLLIN (POLLIN | POLLRDNORM)
#else /* !POLLRDNORM */
# define MY_POLLIN POLLIN
#endif /* !POLLRDNORM */

Niels Möller's avatar
Niels Möller committed
54
55
56
57
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
58
#include <sys/un.h>
Niels Möller's avatar
Niels Möller committed
59
#include <arpa/inet.h>
60
#include <signal.h>
61
62
#include <sys/stat.h>

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

64
#define GABA_DEFINE
65
#include "io.h.x"
66
#undef GABA_DEFINE
67
68
69

#include "io.c.x"

70
71
72
73
74
75
76
/* Calls trigged by a signal handler. */
/* GABA:
   (class
     (name lsh_signal_handler)
     (super resource)
     (vars
       (next object lsh_signal_handler)
Niels Möller's avatar
Added    
Niels Möller committed
77
       (flag . "volatile sig_atomic_t *")
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
       (action object lsh_callback)))
*/

/* Scheduled calls. FIXME: For now, no scheduling in time. */
/* GABA:
   (class
     (name lsh_callout)
     (super resource)
     (vars
       (next object lsh_callout)
       (action object lsh_callback)))
       ;; (when . time_t)
*/

/* GABA:
   (class
     (name io_backend)
     (vars
       ; Linked list of fds. 
       (files object lsh_fd)

       ; Stack of closed files
       ;; (closed object lsh_fd)

       ; Flags
       (signals object lsh_signal_handler)
       
       ; Callouts
       (callouts object lsh_callout)))
*/

Niels Möller's avatar
Niels Möller committed
109
110
111

/* Backend loop */

Niels Möller's avatar
Niels Möller committed
112
113
114
115
116
/* If there's nothing to do for this amount of time (ms), do
 * spontaneous gc. */

#define IDLE_TIME 100

Niels Möller's avatar
Niels Möller committed
117
118
119
120
int io_iter(struct io_backend *b)
{
  unsigned long nfds; /* FIXME: Should be nfds_t if that type is defined */
  struct pollfd *fds;
121
122
  struct lsh_fd **active_fds;
  
123
  /* FIXME: Real scheduling of callouts not implemented */
Niels Möller's avatar
Niels Möller committed
124
  /* int timeout; */
Niels Möller's avatar
Niels Möller committed
125
126
  int res;

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  /* Check all flags */
  if (b->signals)
    {
      struct lsh_signal_handler *f;
      struct lsh_signal_handler **f_p;
      for (f_p = &b->signals; (f = *f_p); )
	{
	  if (!f->super.alive)
	    *f_p = f->next;
	  else
	    {
	      if (*f->flag)
		{
		  *f->flag = 0;
		  LSH_CALLBACK(f->action);
		}
	      f_p = &f->next;
	    }
	}
    }
  
148
149
150
151
152
  /* Invoke all callouts. Clear the list first; if any callout
   * installs another one, that will not be invoked until the next
   * iteration. */
  if (b->callouts)
    {
153
      struct lsh_callout *p;
154
      
155
156
157
158
159
160
161
      for (p = b->callouts, b->callouts = NULL;
	   p; p = p->next)
	if (p->super.alive)
	  {
	    LSH_CALLBACK(p->action);
	    p->super.alive = 0;
	  }
162
163
    }
      
Niels Möller's avatar
Niels Möller committed
164
  {
165
166
167
    struct lsh_fd *fd;
    int need_close;
    
168
    /* Prepare fd:s. This phase calls the prepare-methods, also closes
Niels Möller's avatar
Niels Möller committed
169
170
     * and unlinks any fd:s that should be closed, and also counts how
     * many fd:s there are. */
171
172

    for (fd = b->files; fd; fd = fd->next)
Niels Möller's avatar
Niels Möller committed
173
      {
174
	if (fd->super.alive && fd->prepare)
175
	  FD_PREPARE(fd);
176
177
178
179
180
181
182
      }
    
    /* Note that calling a close callback might cause other files to
     * be closed as well, so we need a double loop.
     *
     * FIXME: How can we improve this? We could keep a stack of closed
     * files, but that will require backpointers from the fd:s to the
183
     * backend (so that kill_fd can find the top of the stack). */
184
185
186
187
188
189

    do
      {
	struct lsh_fd **fd_p;
	need_close = 0;
	nfds = 0;
Niels Möller's avatar
Niels Möller committed
190
	
191
	for(fd_p = &b->files; (fd = *fd_p); )
Niels Möller's avatar
Niels Möller committed
192
	  {
193
	    if (!fd->super.alive)
Niels Möller's avatar
Niels Möller committed
194
	      {
195
196
197
198
199
200
201
202
203
204
		if (fd->fd < 0)
		  /* Unlink the file object, but don't close any
		   * underlying file. */
		  ;
		else
		  {
		    /* Used by write fd:s to make sure that writing to its
		     * buffer fails. */
		    if (fd->write_close)
		      FD_WRITE_CLOSE(fd);
Niels Möller's avatar
Niels Möller committed
205
		
206
207
		    if (fd->close_callback)
		      {
208
			LSH_CALLBACK(fd->close_callback);
209
210
211
			need_close = 1;
		      }
		    trace("io.c: Closing fd %i.\n", fd->fd);
Niels Möller's avatar
Niels Möller committed
212
		
213
214
		    if (close(fd->fd) < 0)
		      {
215
			werror("io.c: close failed, (errno = %i): %z\n",
216
217
218
219
220
			       errno, STRERROR(errno));
			EXCEPTION_RAISE(fd->e,
					make_io_exception(EXC_IO_CLOSE, fd,
							  errno, NULL));
		      }
221
222
223
224
		  }
		/* Unlink this fd */
		*fd_p = fd->next;
		continue;
Niels Möller's avatar
Niels Möller committed
225
	      }
226

227
228
	    if (fd->want_read || fd->want_write)
	      nfds++;
229

230
231
232
	    fd_p = &fd->next;
	  }
      } while (need_close);
Niels Möller's avatar
Niels Möller committed
233
234
235
236
237
238
239
240
  }

  if (!nfds)
    /* Nothing more to do.
     *
     * NOTE: There might be some callouts left, but we won't wait for them. */
    return 0;

241
242
243
  fds = alloca(sizeof(struct pollfd) * nfds);
  active_fds = alloca(sizeof(struct lsh_fd *) *nfds);
  
Niels Möller's avatar
Niels Möller committed
244
245
246
  /* Fill out fds-array */
  {
    struct lsh_fd *fd;
247
    unsigned long i;
Niels Möller's avatar
Niels Möller committed
248
249
    int all_events = 0;
    
250
    for (fd = b->files, i = 0; fd; fd = fd->next)
Niels Möller's avatar
Niels Möller committed
251
      {
252
253
	assert(fd->super.alive);
	
254
255
	if (fd->want_read || fd->want_write)
	  {
256
257
	    assert(i < nfds);

258
	    active_fds[i] = fd;
Niels Möller's avatar
Niels Möller committed
259

260
261
262
263
	    fds[i].fd = fd->fd;
	    fds[i].events = 0;
	    
	    if (fd->want_read)
264
	      fds[i].events |= MY_POLLIN;
Niels Möller's avatar
Niels Möller committed
265

266
267
	    if (fd->want_write)
	      fds[i].events |= POLLOUT;
Niels Möller's avatar
Niels Möller committed
268

269
270
271
	    all_events |= fds[i].events;
	    i++;
	  }
Niels Möller's avatar
Niels Möller committed
272
273
      }
    assert(i == nfds);
274
    assert(all_events);
Niels Möller's avatar
Niels Möller committed
275
276
  }

Niels Möller's avatar
Niels Möller committed
277
  res = poll(fds, nfds, IDLE_TIME);
Niels Möller's avatar
Niels Möller committed
278

Niels Möller's avatar
Niels Möller committed
279
280
281
282
283
  if (!res)
    {
      gc_maybe(&b->super, 0);
      res = poll(fds, nfds, -1);
    }
284
285
  else
    gc_maybe(&b->super, 1);
Niels Möller's avatar
Niels Möller committed
286
  
Niels Möller's avatar
Niels Möller committed
287
288
289
290
291
292
293
294
295
296
297
298
  if (!res)
    {
      /* Callouts are not implemented */
      fatal("Unexpected timeout\n");
    }
  if (res < 0)
    switch(errno)
      {
      case EAGAIN:
      case EINTR:
	return 1;
      default:
299
	fatal("io_iter: poll failed: %z", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
300
301
302
303
      }
  
  {
    /* Do io. Note that the callback functions may add new fds to the
304
305
     * head of the list, or clear the alive flag on any fd. But this
     * is less of a problem now, as we use the active_fd array.*/
Niels Möller's avatar
Niels Möller committed
306

307
    /* struct lsh_fd *fd; */
308
    unsigned long i;
Niels Möller's avatar
Niels Möller committed
309
    
310
    for(i=0; i<nfds; i++)
Niels Möller's avatar
Niels Möller committed
311
      {
312
	struct lsh_fd *fd = active_fds[i];
Niels Möller's avatar
Niels Möller committed
313
	assert(i<nfds);
314
315

	debug("io.c: poll for fd %i: events = 0x%xi, revents = 0x%xi.\n",
316
 	      fds[i].fd, fds[i].events, fds[i].revents);
Niels Möller's avatar
Niels Möller committed
317
	
318
	if (!fd->super.alive)
Niels Möller's avatar
Niels Möller committed
319
320
	  continue;

321
322
	/* On systems without poll, we use jpoll.c to emulate some
	 * of poll, but we lack POLLNVAL, POLLPRI and POLLHUP. */
323
#ifdef POLLNVAL
324
325
326
327
328
329
330
331
	if (fds[i].revents & POLLNVAL)
	  {
	    werror("io.c: poll request on fd %i, for events of type %xi\n"
		   "      return POLLNVAL, revents = %xi\n",
		   fds[i].fd, fds[i].events, fds[i].revents);
	    kill_fd(fd);
	    continue;
	  }
332
#endif /* POLLNVAL */
333

334
#ifdef POLLHUP
335
	/* NOTE: The behaviour of poll at EOF varies quite a lot
336
337
338
	 * between systems.
	 *
	 * According to Solaris' man page, POLLHUP is mutually
339
340
341
	 * exclusive with POLLOUT, but orthogonal to POLLIN.
	 *
	 * However, on my system (sparc-linux) POLLHUP is set when we
342
343
	 * get EOF on an fd we are reading.
	 *
344
345
	 * I.e. on some systems, EOF is indicated by poll setting
	 * POLLIN and read returning 0 (in particular, this happens
346
	 * if the poll-by-select-code in jpoll.c is used), while on
347
	 * other systems, poll sets POLLHUP and subsequent read
348
349
	 * calls will return -1, not 0.
	 *
350
351
352
353
	 * But to complicate things some more, we can (also on Linux)
	 * get both POLLHUP and POLLIN set. In that case, we do an
	 * ordinary read.
	 *
354
	 * We set the hanged_up flag before calling FD_READ, which
355
	 * tells the io_callback that it should avoid calling read. */
356

357
358
	if (fds[i].revents & POLLHUP)
	  {
359
360
	    if (fd->want_write)
	      /* Will raise an i/o error */
361
	      FD_WRITE(fd);
362
	    else if (fd->want_read)
363
	      {
364
365
366
367
368
369
370
		if (!fd->super.alive)
		  continue;

		/* If reading is not possible, treat this as EOF. */ 
		if (!(fds[i].revents & MY_POLLIN))
		  fd->hanged_up = 1;

371
372
		FD_READ(fd);
	      }
373
	    else
374
375
	      {
		werror("io.c: poll said POLLHUP on an inactive fd.\n");
376
		close_fd(fd);
377
	      }
378
379
	    continue;
	  }
380
#endif /* POLLHUP */
381

Niels Möller's avatar
Niels Möller committed
382
383
384
385
386
387
388
389
390
391
392
393
394
#ifdef POLLERR
	if (fds[i].revents & POLLERR)
	  {
	    werror("io.c: POLLERR. Hanging up.\n");

	    /* FIXME: Should we raise any exception here? */

	    close_fd(fd); 

	    continue;
	  }
#endif /* POLLERR */
	
395
#ifdef POLLPRI
396
397
398
	if (fds[i].revents & POLLPRI)
	  {
	    werror("io.c: Peer is trying to send Out of Band data. Hanging up.\n");
399
400

	    /* FIXME: Should we raise any exception here? */
401

402
	    close_fd(fd); 
403
404
405

	    continue;
	  }
406
#endif /* POLLPRI */
Niels Möller's avatar
Niels Möller committed
407
	if (fds[i].revents & POLLOUT)
408
	  FD_WRITE(fd);
Niels Möller's avatar
Niels Möller committed
409

410
	if (!fd->super.alive)
Niels Möller's avatar
Niels Möller committed
411
412
	  continue;

413
	if (fds[i].revents & MY_POLLIN)
414
	  FD_READ(fd);
Niels Möller's avatar
Niels Möller committed
415
416
417
418
419
420
      }
    assert(i == nfds);
  }

  return 1;
}
Niels Möller's avatar
Niels Möller committed
421

422
  
423
424
void
io_run(struct io_backend *b)
Niels Möller's avatar
Niels Möller committed
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
{
  struct sigaction pipe;
  memset(&pipe, 0, sizeof(pipe));

  pipe.sa_handler = SIG_IGN;
  sigemptyset(&pipe.sa_mask);
  pipe.sa_flags = 0;
  
  if (sigaction(SIGPIPE, &pipe, NULL) < 0)
    fatal("Failed to ignore SIGPIPE.\n");
  
  while(io_iter(b))
    ;
}

440
441
struct io_backend *
make_io_backend(void)
Niels Möller's avatar
Niels Möller committed
442
{
443
444
  NEW(io_backend, b);

Niels Möller's avatar
Niels Möller committed
445
  b->files = NULL;
446
  b->signals = NULL;
447
  b->callouts = NULL;
448
449

  return b;
Niels Möller's avatar
Niels Möller committed
450
451
}

452
453
struct resource *
io_signal_handler(struct io_backend *b,
Niels Möller's avatar
Added    
Niels Möller committed
454
		  volatile sig_atomic_t *flag,
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
		  struct lsh_callback *action)
{
  NEW(lsh_signal_handler, handler);
  resource_init(&handler->super, NULL);

  handler->next = b->signals;
  handler->flag = flag;
  handler->action = action;

  b->signals = handler;
  
  return &handler->super;
}

/* Delays not implemented. */
struct resource *
io_callout(struct io_backend *b,
	   UINT32 delay UNUSED,
	   struct lsh_callback *action)
{
  NEW(lsh_callout, callout);
  resource_init(&callout->super, NULL);

  callout->next = b->callouts;
  callout->action = action;
  b->callouts = callout;

  return &callout->super;
}
Niels Möller's avatar
Niels Möller committed
484
485
486

/* Read-related callbacks */

487
488
489
static void
do_buffered_read(struct io_callback *s,
		 struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
490
491
492
{
  CAST(io_buffered_read, self, s);
  UINT8 *buffer = alloca(self->buffer_size);
493
494
495
  int res;

  assert(fd->want_read);   
496

497
  /* If hanged_up is set, pretend that read returned 0 */
498
  res = fd->hanged_up ? 0 : read(fd->fd, buffer, self->buffer_size);
Niels Möller's avatar
Niels Möller committed
499
500
501
502
503
504
505
506
507
508

  if (res < 0)
    switch(errno)
      {
      case EINTR:
	break;
      case EWOULDBLOCK:
	werror("io.c: read_callback: Unexpected EWOULDBLOCK\n");
	break;
      case EPIPE:
509
	/* Getting EPIPE from read seems strange, but appearantly
510
511
	 * it happens sometimes. */
	werror("Unexpected EPIPE.\n");
Niels Möller's avatar
Niels Möller committed
512
      default:
Niels Möller's avatar
Niels Möller committed
513
514
515
	EXCEPTION_RAISE(fd->e, 
			make_io_exception(EXC_IO_READ, fd,
					  errno, NULL));
Niels Möller's avatar
Niels Möller committed
516
517
518
519
520
521
	break;
      }
  else if (res > 0)
    {
      UINT32 left = res;
    
522
      while (fd->super.alive && fd->read && left)
Niels Möller's avatar
Niels Möller committed
523
524
	{
	  UINT32 done;
Niels Möller's avatar
Niels Möller committed
525

526
	  /* FIXME: What to do if want_read is false? To improve the
527
	   * connection_lock mechanism, it must be possible to
528
529
	   * temporarily stop reading, which means that fd->want_read
	   * has to be cleared.
530
531
532
533
534
535
536
537
538
539
540
	   *
	   * But when doing this, we have to keep the data that we
	   * have read, some of which is buffered here, on the stack,
	   * and the rest inside the read-handler.
	   *
	   * There are two alternatives: Save our buffer here, or
	   * continue looping, letting the read-handler process it
	   * into packets. In the latter case, the ssh_connection
	   * could keep a queue of waiting packets, but it would still
	   * have to clear the want_read flag, to prevent that queue
	   * from growing arbitrarily large.
541
	   *
542
	   * We now go with the second alternative. */
543

544
	  assert(self->handler);
Niels Möller's avatar
Niels Möller committed
545
546

	  /* NOTE: This call may replace self->handler */
Niels Möller's avatar
Niels Möller committed
547
	  done = READ_HANDLER(self->handler, left, buffer);
548
	  
Niels Möller's avatar
Niels Möller committed
549
550
	  buffer += done;
	  left -= done;
551

552
553
554
	  if (!fd->want_read)
	    debug("do_buffered_read: want_read = 0; handler needs a pause.\n");
	  
555
556
557
558
559
560
561
	  if (fd->want_read && !self->handler)
	    {
	      werror("do_buffered_read: Handler disappeared! Ignoring %i bytes\n",
		     left);
	      fd->want_read = 0;
	      return;
	    }
Niels Möller's avatar
Niels Möller committed
562
563
564
	}

      if (left)
565
	verbose("read_buffered: fd died, %i buffered bytes discarded\n",
Niels Möller's avatar
Niels Möller committed
566
567
568
		left);
    }
  else
569
570
571
572
573
574
575
    {
      /* We have read EOF. Pass available == 0 to the handler */
      assert(fd->super.alive);
      assert(fd->read);
      assert(fd->want_read);
      assert(self->handler);

Niels Möller's avatar
Niels Möller committed
576
577
      /* Close the fd, unless it has a write callback. */
      close_fd_read(fd);
578
      
579
580
581
      READ_HANDLER(self->handler, 0, NULL);
    }
	
Niels Möller's avatar
Niels Möller committed
582
583
}

584
struct io_callback *
Niels Möller's avatar
Niels Möller committed
585
586
587
588
589
make_buffered_read(UINT32 buffer_size,
		   struct read_handler *handler)
{
  NEW(io_buffered_read, self);

590
  self->super.f = do_buffered_read;
Niels Möller's avatar
Niels Möller committed
591
592
593
594
595
596
  self->buffer_size = buffer_size;
  self->handler = handler;

  return &self->super;
}

597
598
599
static void
do_consuming_read(struct io_callback *c,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
600
{
601
  CAST_SUBTYPE(io_consuming_read, self, c);
Niels Möller's avatar
Niels Möller committed
602
603
  UINT32 wanted = READ_QUERY(self);

604
605
606
  assert(fd->want_read);

  if (fd->hanged_up)
607
    {
608
      /* If hanged_up is set, pretend that read returned 0 */
Niels Möller's avatar
Niels Möller committed
609
      goto eof;
610
611
612
613
614
    }
  
  if (!wanted)
    {
      fd->want_read = 0;
615
    }
Niels Möller's avatar
Niels Möller committed
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  else
    {
      struct lsh_string *s = lsh_string_alloc(wanted);
      int res = read(fd->fd, s->data, wanted);

      if (res < 0)
	switch(errno)
	  {
	  case EINTR:
	    break;
	  case EWOULDBLOCK:
	    werror("io.c: read_consume: Unexpected EWOULDBLOCK\n");
	    break;
	  case EPIPE:
630
631
632
633
	    /* FIXME: I don't understand why reading should return
	     * EPIPE, but it happens occasionally under linux. Perhaps
	     * we should treat it as EOF instead? */
	    werror("io.c: read_consume: Unexpected EPIPE.\n");
Niels Möller's avatar
Niels Möller committed
634
	  default:
Niels Möller's avatar
Niels Möller committed
635
636
637
	    EXCEPTION_RAISE(fd->e, 
			    make_io_exception(EXC_IO_READ,
					      fd, errno, NULL));
Niels Möller's avatar
Niels Möller committed
638
639
640
641
642
	    break;
	  }
      else if (res > 0)
	{
	  s->length = res;
643
	  A_WRITE(self->consumer, s);
Niels Möller's avatar
Niels Möller committed
644
645
	}
      else
646
	{
Niels Möller's avatar
Niels Möller committed
647
648
649
	eof:
	  /* Close the fd, unless it has a write callback. */
	  close_fd_read(fd);
650
651
	  A_WRITE(self->consumer, NULL);
	}
Niels Möller's avatar
Niels Möller committed
652
653
654
655
656
657
658
659
    }
}

/* NOTE: Doesn't initialize the query field. That should be done in
 * the subclass's constructor. */
void init_consuming_read(struct io_consuming_read *self,
			 struct abstract_write *consumer)
{
660
  self->super.f = do_consuming_read;
Niels Möller's avatar
Niels Möller committed
661
662
  self->consumer = consumer;
}
663

664

Niels Möller's avatar
Niels Möller committed
665
/* Write related callbacks */
666
667
668
static void
do_write_callback(struct io_callback *s UNUSED,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
669
{
670
  /* CAST(io_write_callback, self, s); */
Niels Möller's avatar
Niels Möller committed
671
672
673
  UINT32 size;
  int res;
  
674
675
  size = MIN(fd->write_buffer->end - fd->write_buffer->start,
	     fd->write_buffer->block_size);
Niels Möller's avatar
Niels Möller committed
676
677
678
  assert(size);
  
  res = write(fd->fd,
679
	      fd->write_buffer->buffer + fd->write_buffer->start,
Niels Möller's avatar
Niels Möller committed
680
681
682
683
684
685
686
687
688
689
	      size);
  if (!res)
    fatal("Closed?");
  if (res < 0)
    switch(errno)
      {
      case EINTR:
      case EAGAIN:
	break;
      case EPIPE:
690
	debug("io.c: Broken pipe.\n");
691
	close_fd(fd);
Niels Möller's avatar
Niels Möller committed
692
693
	break;
      default:
694
	werror("io.c: write failed, %z\n", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
695
696
	EXCEPTION_RAISE(fd->e,
			make_io_exception(EXC_IO_WRITE, fd, errno, NULL));
697
	close_fd(fd);
Niels Möller's avatar
Niels Möller committed
698
699
700
701
	
	break;
      }
  else
702
    write_buffer_consume(fd->write_buffer, res);
Niels Möller's avatar
Niels Möller committed
703
}  
704

705
706
707
708
709
710
711
712
713
714
static struct io_callback io_write_callback =
{ STATIC_HEADER, do_write_callback };

static void
do_write_prepare(struct lsh_fd *fd)
{
  assert(fd->write_buffer);

  if (! (fd->want_write = write_buffer_pre_write(fd->write_buffer))
      && fd->write_buffer->closed)
715
    close_fd(fd);
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
}

static void
do_write_close(struct lsh_fd *fd)
{
  /* CAST(io_write_callback, self, s); */

  assert(fd->write_buffer);

  write_buffer_close(fd->write_buffer);
}

struct listen_value *
make_listen_value(struct lsh_fd *fd,
		  struct address_info *peer)
{
  NEW(listen_value, self);

  self->fd = fd;
  self->peer = peer;

  return self;
}

Niels Möller's avatar
Niels Möller committed
740
741
742

/* Listen callback */

743
744
745
746
747
748
749
750
751
752
/* GABA:
   (class
     (name io_listen_callback)
     (super io_callback)
     (vars
       (backend object io_backend)
       (c object command_continuation)
       (e object exception_handler)))
*/

Niels Möller's avatar
Niels Möller committed
753
static void
754
do_listen_callback(struct io_callback *s,
Niels Möller's avatar
Niels Möller committed
755
		   struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
756
{
757
  CAST(io_listen_callback, self, s);
758
759
760
761
762
763

#if WITH_IPV6
  struct sockaddr_storage peer;
#else
  struct sockaddr peer;
#endif
764
765

  socklen_t addr_len = sizeof(peer);
Niels Möller's avatar
Niels Möller committed
766
  int conn;
767

Niels Möller's avatar
Niels Möller committed
768
769
770
  conn = accept(fd->fd,
		(struct sockaddr *) &peer, &addr_len);
  if (conn < 0)
771
    {
772
      werror("io.c: accept failed, %z", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
773
      return;
774
    }
775
  trace("io.c: accept on fd %i\n", conn);
776
777
778
779
780
  COMMAND_RETURN(self->c,
		 make_listen_value(make_lsh_fd(self->backend,
					       conn, self->e),
				   sockaddr2info(addr_len,
						 (struct sockaddr *) &peer)));
Niels Möller's avatar
Niels Möller committed
781
}
782

783
784
785
786
787
788
789
790
791
792
793
794
795
struct io_callback *
make_listen_callback(struct io_backend *backend,
		     struct command_continuation *c,
		     struct exception_handler *e)
{
  NEW(io_listen_callback, self);
  self->super.f = do_listen_callback;
  self->backend = backend;
  self->c = c;
  self->e = e;
  
  return &self->super;
}
Niels Möller's avatar
Niels Möller committed
796

797
798
799
800
801
802
803
804
805
806
807
808
809
810
#if 0

static void
do_listen_callback_no_peer(struct io_callback *s,
			   struct lsh_fd *fd)
{
  CAST(io_listen_callback, self, s);

  int conn;

  conn = accept(fd->fd,
		(struct sockaddr *) &peer, &addr_len);
  if (conn < 0)
    {
811
      werror("io.c: accept failed, %z", STRERROR(errno));
812
813
      return;
    }
814
  trace("io.c: accept on fd %i\n", conn);
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
  COMMAND_RETURN(self->c, make_lsh_fd(self->backend,
				      conn, self->e));
}

struct io_callback *
make_listen_callback_no_peer(struct io_backend *backend,
			     struct command_continuation *c)
{
  NEW(io_listen_callback, self);
  self->super.f = do_listen_callback_no_peer;
  self->backend = backend;
  self->c = c;
  
  return &self->super;
}
#endif
Niels Möller's avatar
Niels Möller committed
831
832
833

/* Connect callback */

834
835
836
837
838
839
840
841
842
843
844
/* GABA:
   (class
     (name io_connect_callback)
     (super io_callback)
     (vars
       (c object command_continuation)))
*/

static void
do_connect_callback(struct io_callback *s,
		    struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
845
{
846
  CAST(io_connect_callback, self, s);
847
  int socket_error;
848
  socklen_t len = sizeof(socket_error);
849
  
850
  /* Check if the connection was successful */
851
852
  if ((getsockopt(fd->fd, SOL_SOCKET, SO_ERROR,
		  (char *) &socket_error, &len) < 0)
853
      || socket_error)
854
    {
855
      debug("io.c: connect_callback: Connect failed.\n");
Niels Möller's avatar
Niels Möller committed
856
      EXCEPTION_RAISE(fd->e,
857
		      make_io_exception(EXC_IO_CONNECT, fd, 0, "connect failed."));
858
      kill_fd(fd);
859
860
    }
  else
Niels Möller's avatar
Niels Möller committed
861
    {
862
863
864
      fd->write = NULL;
      fd->want_write = 0;
      COMMAND_RETURN(self->c, fd);
865
    }
866
867
868
869
870
871
872
873
874
875
876
}

static struct io_callback *
make_connect_callback(struct command_continuation *c)
{
  NEW(io_connect_callback, self);

  self->super.f = do_connect_callback;
  self->c = c;

  return &self->super;
877
878
}

879

Niels Möller's avatar
Niels Möller committed
880
/* This function is called if a connection this file somehow depends
881
882
883
884
885
886
887
888
 * on disappears. For instance, the connection may have spawned a
 * child process, and this file may be the stdin of that process. */

/* To kill a file, mark it for closing and the backend will do the work. */
static void do_kill_fd(struct resource *r)
{
  CAST_SUBTYPE(lsh_fd, fd, r);

Niels Möller's avatar
Niels Möller committed
889
890
  /* We use close_fd_nicely, so that any data in the write buffer is
   * flushed before the fd is closed. */
891
  if (r->alive)
892
    close_fd_nicely(fd);
893
894
}

895
896
897
898
899
900
901
902
903
904
/* Closes the file on i/o errors, and passes the exception on */

static void
do_exc_io_handler(struct exception_handler *self,
		  const struct exception *x)
{
  if (x->type & EXC_IO)
    {
      CAST_SUBTYPE(io_exception, e, x);

905
      if (e->fd)
906
	close_fd(e->fd);
907
908
909
910
911
    }
  EXCEPTION_RAISE(self->parent, x);
  return;
}

Niels Möller's avatar
Niels Möller committed
912
/* Initializes a file structure, and adds it to the backend's list. */
913
914
915
static void
init_file(struct io_backend *b, struct lsh_fd *f, int fd,
	  struct exception_handler *e)
Niels Möller's avatar
Niels Möller committed
916
{
917
918
  resource_init(&f->super, do_kill_fd);

Niels Möller's avatar
Niels Möller committed
919
  f->fd = fd;
Niels Möller's avatar
Niels Möller committed
920

921
  f->e = make_exception_handler(do_exc_io_handler, e, HANDLER_CONTEXT);
922
  
Niels Möller's avatar
Niels Möller committed
923
924
925
  f->close_callback = NULL;

  f->prepare = NULL;
926

927
928
  f->hanged_up = 0;
  
Niels Möller's avatar
Niels Möller committed
929
930
931
932
933
  f->want_read = 0;
  f->read = NULL;

  f->want_write = 0;
  f->write = NULL;
934
  f->write_close = NULL;
Niels Möller's avatar
Niels Möller committed
935
936
937
938

  f->next = b->files;
  b->files = f;
}
939

940
/* These functions are used by werror and friends */
Niels Möller's avatar
Niels Möller committed
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

/* For fd:s in blocking mode. */
const struct exception *
write_raw(int fd, UINT32 length, const UINT8 *data)
{
  while(length)
    {
      int written = write(fd, data, length);

      if (written < 0)
	switch(errno)
	  {
	  case EINTR:
	  case EAGAIN:
	    continue;
	  default:
	    return make_io_exception(EXC_IO_BLOCKING_WRITE,
				     NULL, errno, NULL);
	  }
      
      length -= written;
      data += written;
    }
  return NULL;
}

const struct exception *
write_raw_with_poll(int fd, UINT32 length, const UINT8 *data)
{
  while(length)
    {
      struct pollfd pfd;
      int res;
      int written;
      
      pfd.fd = fd;
      pfd.events = POLLOUT;

      res = poll(&pfd, 1, -1);

      if (res < 0)
	switch(errno)
	  {
	  case EINTR:
	  case EAGAIN:
	    continue;
	  default:
	    return make_io_exception(EXC_IO_BLOCKING_WRITE,
				     NULL, errno, NULL);
	  }
      
      written = write(fd, data, length);

      if (written < 0)
	switch(errno)
	  {
	  case EINTR:
	  case EAGAIN:
	    continue;
	  default:
	    return make_io_exception(EXC_IO_BLOCKING_WRITE,
				     NULL, errno, NULL);
	  }
      
      length -= written;
      data += written;
    }
  return NULL;
}

1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
/* For fd:s in blocking mode. */
const struct exception *
read_raw(int fd, UINT32 length, UINT8 *data)
{
  while(length)
    {
      int done = read(fd, data, length);

      if (done < 0)
	switch(errno)
	  {
	  case EINTR:
	  case EAGAIN:
	    continue;
	  default:
	    return make_io_exception(EXC_IO_BLOCKING_READ,
				     NULL, errno, NULL);
	  }
      else if (done == 0)
	{
	  /* EOF. */
	  /* FIXME: Indicate the amount of data read, somehow. */
	  return make_io_exception(EXC_IO_BLOCKING_READ,
				   NULL, 0, NULL);
	}
	
      length -= done;
      data += done;
    }
  return NULL;
}
Niels Möller's avatar
Niels Möller committed
1042
1043
1044

/* Network utility functions */

1045
/* Converts a string port number or service name to a port number.
1046
1047
 * Returns the port number in _host_ byte order, or 0 if lookup
 * fails. */
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068

int get_portno(const char *service, const char *protocol)
{
  if (service == NULL)
    return 0;
  else
    {
      char *end;
      long portno;

      portno = strtol(service, &end, 10);
      if (portno > 0
	  &&  portno <= 65535
	  &&  end != service
	  &&  *end == '\0')
	  return portno;
      else
	{
	  struct servent * serv;

	  serv = getservbyname(service, protocol);
1069
1070
	  if (!serv)
	    return 0;
1071
1072
1073
1074
1075
1076
	  return ntohs(serv->s_port);
	}
    }
}


1077
1078
1079
1080
1081
/* If def != 0, use that value as a fallback if the lookup fails. */
struct address_info *
make_address_info_c(const char *host,
		    const char *port,
		    int def)
1082
1083
{
  int portno = get_portno(port, "tcp");
1084
1085
1086
1087
1088
1089
  if (!portno)
    portno = def;

  if (!portno)
    return NULL;

1090
1091
1092
1093
1094
  else
    {
      NEW(address_info, info);
      
      info->port = portno;
1095
      info->ip = host ? ssh_format("%lz", host) : NULL;
1096
1097
1098
1099
      
      return info;
    }
}
1100

1101
1102
struct address_info *
make_address_info(struct lsh_string *host, UINT32 port)
1103
1104
1105
1106
1107
1108
1109
1110
{
  NEW(address_info, info);

  info->port = port; /* htons(port); */
  info->ip = host;
  return info;
}

1111
1112
1113
struct address_info *
sockaddr2info(size_t addr_len UNUSED,
	      struct sockaddr *addr)
1114
{
1115
  NEW(address_info, info);
1116
1117
1118
1119
1120
1121
1122
  
  switch(addr->sa_family)
    {
    case AF_INET:
      {
	struct sockaddr_in *in = (struct sockaddr_in *) addr;
	UINT32 ip = ntohl(in->sin_addr.s_addr);
1123
	info->port = ntohs(in->sin_port);
1124
1125
1126
1127
1128
	info->ip = ssh_format("%di.%di.%di.%di",
			      (ip >> 24) & 0xff,
			      (ip >> 16) & 0xff,
			      (ip >> 8) & 0xff,
			      ip & 0xff);
1129
1130
	return info;
      }
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
#if WITH_IPV6
    case AF_INET6:
      {
	struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
	UINT8 *ip = in->sin6_addr.s6_addr;
	info->port = ntohs(in->sin6_port);
	info->ip = ssh_format("%xi:%xi:%xi:%xi:%xi:%xi:%xi:%xi",
			      (ip[0]  << 8) | ip[1],
			      (ip[2]  << 8) | ip[3],
			      (ip[4]  << 8) | ip[5],
			      (ip[6]  << 8) | ip[7],
			      (ip[8]  << 8) | ip[9],
			      (ip[10] << 8) | ip[11],
			      (ip[12] << 8) | ip[13],
			      (ip[14] << 8) | ip[15]);
	return info;
      }
1148
#endif
1149
1150
1151
1152
    case AF_UNIX:
      /* Silently return NULL. This happens when a gateway client
       * connects. */
      return NULL;
1153
    default:
1154
      werror("io.c: sockaddr2info: Unsupported address family.\n");
1155
      return NULL;
1156
1157
    }
}
1158

1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
#if HAVE_GETADDRINFO
static struct addrinfo *
choose_address(struct addrinfo *list,
	       const int *preference)
{
  int i;
  for (i = 0; preference[i]; i++)
    {
      struct addrinfo *p;
      for (p = list; p; p = p->ai_next)
	if (preference[i] == p->ai_family)
	  return p;
    }
  return NULL;
}
#endif /* HAVE_GETADDRINFO */

/* FIXME: Perhaps this function should be changed to return a list of
 * sockaddr:s? */
1178
1179
1180
struct sockaddr *
address_info2sockaddr(socklen_t *length,
		      struct address_info *a,
1181
1182
		      /* Preferred address families. Zero-terminated array. */
		      const int *preference,
1183
		      int lookup)
1184
{
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  char *host;

  if (a->ip)
    {
      host = alloca(a->ip->length + 1);
  
      memcpy(host, a->ip->data, a->ip->length);
      host[a->ip->length] = '\0';
    }
  else
    host = NULL;
1196

1197
/* Some systems have getaddrinfo, but still doesn't implement all of
1198
1199
1200
 * RFC 2553 */
#if defined(HAVE_GETADDRINFO) && \
    defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST)
1201
1202
1203
  {
    struct addrinfo hints;
    struct addrinfo *list;
1204
    struct addrinfo *chosen;
1205
    struct sockaddr *res;
1206
1207
1208
1209
1210
1211
1212
    const int default_preference
#if WITH_IPV6
      [3] = { AF_INET6, AF_INET }
#else
      [2] = { AF_INET, 0 }
#endif      
      ;
1213
1214
1215
    int err;
    /* FIXME: It seems ugly to have to convert the port number to a
     * string. */
1216
    struct lsh_string *service = ssh_cformat("%di", a->port);
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    if (!lookup)
      hints.ai_flags |= AI_NUMERICHOST;
    
    err = getaddrinfo(host, service->data, &hints, &list);
    lsh_string_free(service);

    if (err)
      {
1231
	debug("address_info2sockaddr: getaddrinfo failed (err = %d): %z\n",
1232
1233
1234
1235
	      err, gai_strerror(err));
	return NULL;
      }

1236
1237
1238
1239
1240
1241
1242
1243
1244
    chosen = choose_address(list,
			    preference ? preference : default_preference);
    if (!chosen)
      {
	freeaddrinfo(list);
	return NULL;
      }
    
    *length = chosen->ai_addrlen;
1245
1246
    
    res = lsh_space_alloc(*length);
1247
    memcpy(res, chosen->ai_addr, *length);
1248
1249
1250
1251
    freeaddrinfo(list);

    return res;
  }
1252
1253
1254
#else
/* !(defined(HAVE_GETADDRINFO) &&
     defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST) */ 
1255
1256

#if WITH_IPV6
1257
#error IPv6 enabled, but getaddrinfo and friends were not found. 
1258
#endif
1259

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
  if (a->ip && memchr(a->ip->data, ':', a->ip->length))
    {
      debug("address_info2sockaddr: Literal IPv6 used. Failing.\n");
      return NULL;
    }
  else
    {
      struct sockaddr_in *addr;
      NEW_SPACE(addr);

      *length = sizeof(*addr);
      addr->sin_port = htons(a->port);
1272
1273
1274

      /* Use IPv4 only */
      addr->sin_family = AF_INET;
1275
1276
    
      if (!host)
1277
1278
	/* Any interface */
	addr->sin_addr.s_addr = INADDR_ANY;
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309

      else
	{
	  /* First check for numerical ip-number */
#if HAVE_INET_ATON
	  if (!inet_aton(host, &addr->sin_addr))
#else /* !HAVE_INET_ATON */
	    /* NOTE: It is wrong to work with ((unsigned long int) -1)
	     * directly, as this breaks Linux/Alpha systems. But
	     * INADDR_NONE isn't portable. That's what inet_aton is for;
	     * see the GNU libc documentation. */
# ifndef INADDR_NONE
# define INADDR_NONE ((unsigned long int) -1)
# endif /* !INADDR_NONE */
	  addr->sin_addr.s_addr = inet_addr(host);
	  if (addr->sin_addr.s_addr == INADDR_NONE)
#endif  /* !HAVE_INET_ATON */
	    {
	      struct hostent *hp;

	      if (! (lookup 
		     && (hp = gethostbyname(host))
		     && (hp->h_addrtype == AF_INET)))
		{
		  lsh_space_free(addr);
		  return NULL;
		}

	      memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
	    }
	}
1310
      return (struct sockaddr *) addr;
1311
1312
1313
1314
    }
#endif /* !HAVE_GETADDRINFO */  
}

1315

Niels Möller's avatar
Niels Möller committed
1316
1317
void io_set_nonblocking(int fd)
{
1318
1319
1320
1321
1322
1323
1324
  int old = fcntl(fd, F_GETFL);

  if (old < 0)
    fatal("io_set_nonblocking: fcntl(F_GETFL) failed, %z", STRERROR(errno));
  
  if (fcntl(fd, F_SETFL, old | O_NONBLOCK) < 0)
    fatal("io_set_nonblocking: fcntl(F_SETFL) failed, %z", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
1325
1326
}

1327
1328
void io_set_close_on_exec(int fd)
{
1329
1330
1331
1332
1333
1334
1335
1336
1337
  /* NOTE: There's only one documented flag bit, so reading the old
   * value should be redundant. */
  
  int old = fcntl(fd, F_GETFD);

  if (old < 0)
    fatal("io_set_nonblocking: fcntl(F_GETFD) failed, %z", STRERROR(errno));
  
  if (fcntl(fd, F_SETFD, old | 1) < 0)