io.c 44.3 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
77
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
/* Calls trigged by a signal handler. */
/* GABA:
   (class
     (name lsh_signal_handler)
     (super resource)
     (vars
       (next object lsh_signal_handler)
       (flag . "sig_atomic_t *")
       (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
183
184
185
186
187
188
189
      }
    
    /* 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
     * backend (so that kill_fd() can find the top of the stack). */

    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
323
	/* On systems without poll(), we use jpoll.c to emulate some
	 * of poll(), but we lack POLLNVAL, POLLPRI and POLLHUP. */
#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
336
337
338
	/* NOTE: The behaviour of poll() at EOF varies quite a lot
	 * 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
344
345
346
347
348
349
	 * get EOF on an fd we are reading.
	 *
	 * I.e. on some systems, EOF is indicated by poll() setting
	 * POLLIN and read() returning 0 (in particular, this happens
	 * if the poll-by-select-code in jpoll.c is used), while on
	 * other systems, poll() sets POLLHUP and subsequent read()
	 * 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
355
	 * We set the hanged_up flag before calling FD_READ, which
	 * 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

382
#ifdef POLLPRI
383
384
385
	if (fds[i].revents & POLLPRI)
	  {
	    werror("io.c: Peer is trying to send Out of Band data. Hanging up.\n");
386
387

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

389
	    close_fd(fd); 
390
391
392

	    continue;
	  }
393
#endif /* POLLPRI */
Niels Möller's avatar
Niels Möller committed
394
	if (fds[i].revents & POLLOUT)
395
	  FD_WRITE(fd);
Niels Möller's avatar
Niels Möller committed
396

397
	if (!fd->super.alive)
Niels Möller's avatar
Niels Möller committed
398
399
	  continue;

400
	if (fds[i].revents & MY_POLLIN)
401
	  FD_READ(fd);
Niels Möller's avatar
Niels Möller committed
402
403
404
405
406
407
      }
    assert(i == nfds);
  }

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

409
  
410
411
void
io_run(struct io_backend *b)
Niels Möller's avatar
Niels Möller committed
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
{
  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))
    ;
}

427
428
struct io_backend *
make_io_backend(void)
Niels Möller's avatar
Niels Möller committed
429
{
430
431
  NEW(io_backend, b);

Niels Möller's avatar
Niels Möller committed
432
  b->files = NULL;
433
  b->signals = NULL;
434
  b->callouts = NULL;
435
436

  return b;
Niels Möller's avatar
Niels Möller committed
437
438
}

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
struct resource *
io_signal_handler(struct io_backend *b,
		  sig_atomic_t *flag,
		  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
471
472
473

/* Read-related callbacks */

474
475
476
static void
do_buffered_read(struct io_callback *s,
		 struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
477
478
479
{
  CAST(io_buffered_read, self, s);
  UINT8 *buffer = alloca(self->buffer_size);
480
481
482
  int res;

  assert(fd->want_read);   
483
484
485

  /* If hanged_up is set, pretend that read() returned 0 */
  res = fd->hanged_up ? 0 : read(fd->fd, buffer, self->buffer_size);
Niels Möller's avatar
Niels Möller committed
486
487
488
489
490
491
492
493
494
495

  if (res < 0)
    switch(errno)
      {
      case EINTR:
	break;
      case EWOULDBLOCK:
	werror("io.c: read_callback: Unexpected EWOULDBLOCK\n");
	break;
      case EPIPE:
496
497
498
	/* Getting EPIPE from read() seems strange, but appearantly
	 * it happens sometimes. */
	werror("Unexpected EPIPE.\n");
Niels Möller's avatar
Niels Möller committed
499
      default:
Niels Möller's avatar
Niels Möller committed
500
501
502
	EXCEPTION_RAISE(fd->e, 
			make_io_exception(EXC_IO_READ, fd,
					  errno, NULL));
Niels Möller's avatar
Niels Möller committed
503
504
505
506
507
508
	break;
      }
  else if (res > 0)
    {
      UINT32 left = res;
    
509
      while (fd->super.alive && fd->read && left)
Niels Möller's avatar
Niels Möller committed
510
511
	{
	  UINT32 done;
Niels Möller's avatar
Niels Möller committed
512

513
514
515
516
	  /* FIXME: What to do if want_read is false? To improve the
	   * connection_lock() mechanism, it must be possible to
	   * temporarily stop reading, which means that fd->want_read
	   * has to be cleared.
517
518
519
520
521
522
523
524
525
526
527
	   *
	   * 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.
528
	   *
529
	   * We now go with the second alternative. */
530

531
	  assert(self->handler);
Niels Möller's avatar
Niels Möller committed
532
533

	  /* NOTE: This call may replace self->handler */
Niels Möller's avatar
Niels Möller committed
534
	  done = READ_HANDLER(self->handler, left, buffer);
535
	  
Niels Möller's avatar
Niels Möller committed
536
537
	  buffer += done;
	  left -= done;
538

539
540
541
	  if (!fd->want_read)
	    debug("do_buffered_read: want_read = 0; handler needs a pause.\n");
	  
542
543
544
545
546
547
548
	  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
549
550
551
552
553
554
555
	}

      if (left)
	verbose("read_buffered(): fd died, %i buffered bytes discarded\n",
		left);
    }
  else
556
557
558
559
560
561
562
    {
      /* We have read EOF. Pass available == 0 to the handler */
      assert(fd->super.alive);
      assert(fd->read);
      assert(fd->want_read);
      assert(self->handler);

563
      close_fd_nicely(fd);
564
565
566
      READ_HANDLER(self->handler, 0, NULL);
    }
	
Niels Möller's avatar
Niels Möller committed
567
568
}

569
struct io_callback *
Niels Möller's avatar
Niels Möller committed
570
571
572
573
574
make_buffered_read(UINT32 buffer_size,
		   struct read_handler *handler)
{
  NEW(io_buffered_read, self);

575
  self->super.f = do_buffered_read;
Niels Möller's avatar
Niels Möller committed
576
577
578
579
580
581
  self->buffer_size = buffer_size;
  self->handler = handler;

  return &self->super;
}

582
583
584
static void
do_consuming_read(struct io_callback *c,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
585
{
586
  CAST_SUBTYPE(io_consuming_read, self, c);
Niels Möller's avatar
Niels Möller committed
587
588
589
590
591
592
  UINT32 wanted = READ_QUERY(self);

  if (!wanted)
    {
      fd->want_read = 0;
    }
593
594
595
596
597
598
  else if (fd->hanged_up)
    {
      /* If hanged_up is set, pretend that read() returned 0 */
      close_fd_nicely(fd);
      A_WRITE(self->consumer, NULL);
    }
Niels Möller's avatar
Niels Möller committed
599
600
601
602
603
604
605
606
607
608
609
610
611
612
  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:
613
614
615
616
	    /* 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
617
	  default:
Niels Möller's avatar
Niels Möller committed
618
619
620
	    EXCEPTION_RAISE(fd->e, 
			    make_io_exception(EXC_IO_READ,
					      fd, errno, NULL));
Niels Möller's avatar
Niels Möller committed
621
622
623
624
625
	    break;
	  }
      else if (res > 0)
	{
	  s->length = res;
626
	  A_WRITE(self->consumer, s);
Niels Möller's avatar
Niels Möller committed
627
628
	}
      else
629
	{
630
	  close_fd_nicely(fd);
631
632
633
	  A_WRITE(self->consumer, NULL);
	}
      
Niels Möller's avatar
Niels Möller committed
634
635
636
637
638
639
640
641
    }
}

/* 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)
{
642
  self->super.f = do_consuming_read;
Niels Möller's avatar
Niels Möller committed
643
644
  self->consumer = consumer;
}
645

646

Niels Möller's avatar
Niels Möller committed
647
/* Write related callbacks */
648
649
650
static void
do_write_callback(struct io_callback *s UNUSED,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
651
{
652
  /* CAST(io_write_callback, self, s); */
Niels Möller's avatar
Niels Möller committed
653
654
655
  UINT32 size;
  int res;
  
656
657
  size = MIN(fd->write_buffer->end - fd->write_buffer->start,
	     fd->write_buffer->block_size);
Niels Möller's avatar
Niels Möller committed
658
659
660
  assert(size);
  
  res = write(fd->fd,
661
	      fd->write_buffer->buffer + fd->write_buffer->start,
Niels Möller's avatar
Niels Möller committed
662
663
664
665
666
667
668
669
670
671
	      size);
  if (!res)
    fatal("Closed?");
  if (res < 0)
    switch(errno)
      {
      case EINTR:
      case EAGAIN:
	break;
      case EPIPE:
672
	debug("io.c: Broken pipe.\n");
673
	close_fd(fd);
Niels Möller's avatar
Niels Möller committed
674
675
	break;
      default:
676
	werror("io.c: write failed, %z\n", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
677
678
	EXCEPTION_RAISE(fd->e,
			make_io_exception(EXC_IO_WRITE, fd, errno, NULL));
679
	close_fd(fd);
Niels Möller's avatar
Niels Möller committed
680
681
682
683
	
	break;
      }
  else
684
    write_buffer_consume(fd->write_buffer, res);
Niels Möller's avatar
Niels Möller committed
685
}  
686

687
688
689
690
691
692
693
694
695
696
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)
697
    close_fd(fd);
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
}

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
722
723
724

/* Listen callback */

725
726
727
728
729
730
731
732
733
734
/* 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
735
static void
736
do_listen_callback(struct io_callback *s,
Niels Möller's avatar
Niels Möller committed
737
		   struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
738
{
739
  CAST(io_listen_callback, self, s);
740
741
742
743
744
745

#if WITH_IPV6
  struct sockaddr_storage peer;
#else
  struct sockaddr peer;
#endif
746
747

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

Niels Möller's avatar
Niels Möller committed
750
751
752
  conn = accept(fd->fd,
		(struct sockaddr *) &peer, &addr_len);
  if (conn < 0)
753
    {
754
      werror("io.c: accept() failed, %z", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
755
      return;
756
    }
757
  trace("io.c: accept() on fd %i\n", conn);
758
759
760
761
762
  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
763
}
764

765
766
767
768
769
770
771
772
773
774
775
776
777
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
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
#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)
    {
      werror("io.c: accept() failed, %z", STRERROR(errno));
      return;
    }
  trace("io.c: accept() on fd %i\n", conn);
  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
813
814
815

/* Connect callback */

816
817
818
819
820
821
822
823
824
825
826
/* 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
827
{
828
  CAST(io_connect_callback, self, s);
829
  int socket_error;
830
  socklen_t len = sizeof(socket_error);
831
  
832
  /* Check if the connection was successful */
833
834
  if ((getsockopt(fd->fd, SOL_SOCKET, SO_ERROR,
		  (char *) &socket_error, &len) < 0)
835
      || socket_error)
836
    {
837
      debug("io.c: connect_callback: Connect failed.\n");
Niels Möller's avatar
Niels Möller committed
838
      EXCEPTION_RAISE(fd->e,
839
		      make_io_exception(EXC_IO_CONNECT, fd, 0, "connect() failed."));
840
      kill_fd(fd);
841
842
    }
  else
Niels Möller's avatar
Niels Möller committed
843
    {
844
845
846
      fd->write = NULL;
      fd->want_write = 0;
      COMMAND_RETURN(self->c, fd);
847
    }
848
849
850
851
852
853
854
855
856
857
858
}

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;
859
860
}

861

Niels Möller's avatar
Niels Möller committed
862
/* This function is called if a connection this file somehow depends
863
864
865
866
867
868
869
870
 * 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);

871
  /* FIXME: Should we use close_fd() or close_fd_nicely() ? */
872
  if (r->alive)
873
    close_fd_nicely(fd);
874
875
}

876
877
878
879
880
881
882
883
884
885
/* 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);

886
      if (e->fd)
887
	close_fd(e->fd);
888
889
890
891
892
    }
  EXCEPTION_RAISE(self->parent, x);
  return;
}

Niels Möller's avatar
Niels Möller committed
893
/* Initializes a file structure, and adds it to the backend's list. */
894
895
896
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
897
{
898
899
  resource_init(&f->super, do_kill_fd);

Niels Möller's avatar
Niels Möller committed
900
  f->fd = fd;
Niels Möller's avatar
Niels Möller committed
901

902
  f->e = make_exception_handler(do_exc_io_handler, e, HANDLER_CONTEXT);
903
  
Niels Möller's avatar
Niels Möller committed
904
905
906
  f->close_callback = NULL;

  f->prepare = NULL;
907

908
909
  f->hanged_up = 0;
  
Niels Möller's avatar
Niels Möller committed
910
911
912
913
914
  f->want_read = 0;
  f->read = NULL;

  f->want_write = 0;
  f->write = NULL;
915
  f->write_close = NULL;
Niels Möller's avatar
Niels Möller committed
916
917
918
919

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

Niels Möller's avatar
Niels Möller committed
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
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
/* These functions are used by werror() and friends */

/* 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;
}

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
/* 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
1023
1024
1025

/* Network utility functions */

1026
/* Converts a string port number or service name to a port number.
1027
1028
 * Returns the port number in _host_ byte order, or 0 if lookup
 * fails. */
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049

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);
1050
1051
	  if (!serv)
	    return 0;
1052
1053
1054
1055
1056
1057
	  return ntohs(serv->s_port);
	}
    }
}


1058
1059
1060
1061
1062
/* 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)
1063
1064
{
  int portno = get_portno(port, "tcp");
1065
1066
1067
1068
1069
1070
  if (!portno)
    portno = def;

  if (!portno)
    return NULL;

1071
1072
1073
1074
1075
  else
    {
      NEW(address_info, info);
      
      info->port = portno;
1076
      info->ip = host ? ssh_format("%lz", host) : NULL;
1077
1078
1079
1080
      
      return info;
    }
}
1081

1082
1083
struct address_info *
make_address_info(struct lsh_string *host, UINT32 port)
1084
1085
1086
1087
1088
1089
1090
1091
{
  NEW(address_info, info);

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

1092
1093
1094
struct address_info *
sockaddr2info(size_t addr_len UNUSED,
	      struct sockaddr *addr)
1095
{
1096
  NEW(address_info, info);
1097
1098
1099
1100
1101
1102
1103
  
  switch(addr->sa_family)
    {
    case AF_INET:
      {
	struct sockaddr_in *in = (struct sockaddr_in *) addr;
	UINT32 ip = ntohl(in->sin_addr.s_addr);
1104
	info->port = ntohs(in->sin_port);
1105
1106
1107
1108
1109
	info->ip = ssh_format("%di.%di.%di.%di",
			      (ip >> 24) & 0xff,
			      (ip >> 16) & 0xff,
			      (ip >> 8) & 0xff,
			      ip & 0xff);
1110
1111
	return info;
      }
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
#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;
      }
1129
1130
#endif
    default:
1131
1132
      werror("io.c: sockaddr2info(): Unsupported address family.\n");
      return NULL;
1133
1134
    }
}
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
#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? */
1155
1156
1157
struct sockaddr *
address_info2sockaddr(socklen_t *length,
		      struct address_info *a,
1158
1159
		      /* Preferred address families. Zero-terminated array. */
		      const int *preference,
1160
		      int lookup)
1161
{
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
  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;
1173
1174
1175
1176
1177

/* Some systems have getaddrinfo(), but still doesn't implement all of
 * RFC 2553 */
#if defined(HAVE_GETADDRINFO) && \
    defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST)
1178
1179
1180
  {
    struct addrinfo hints;
    struct addrinfo *list;
1181
    struct addrinfo *chosen;
1182
    struct sockaddr *res;
1183
1184
1185
1186
1187
1188
1189
    const int default_preference
#if WITH_IPV6
      [3] = { AF_INET6, AF_INET }
#else
      [2] = { AF_INET, 0 }
#endif      
      ;
1190
1191
1192
    int err;
    /* FIXME: It seems ugly to have to convert the port number to a
     * string. */
1193
    struct lsh_string *service = ssh_cformat("%di", a->port);
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207

    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)
      {
1208
	debug("address_info2sockaddr: getaddrinfo failed (err = %d): %z\n",
1209
1210
1211
1212
	      err, gai_strerror(err));
	return NULL;
      }

1213
1214
1215
1216
1217
1218
1219
1220
1221
    chosen = choose_address(list,
			    preference ? preference : default_preference);
    if (!chosen)
      {
	freeaddrinfo(list);
	return NULL;
      }
    
    *length = chosen->ai_addrlen;
1222
1223
    
    res = lsh_space_alloc(*length);
1224
    memcpy(res, chosen->ai_addr, *length);
1225
1226
1227
1228
    freeaddrinfo(list);

    return res;
  }
1229
1230
1231
#else
/* !(defined(HAVE_GETADDRINFO) &&
     defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST) */ 
1232
1233

#if WITH_IPV6
1234
#error IPv6 enabled, but getaddrinfo() and friends were not found. 
1235
#endif
1236

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
  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);
1249
1250
1251

      /* Use IPv4 only */
      addr->sin_family = AF_INET;
1252
1253
    
      if (!host)
1254
1255
	/* Any interface */
	addr->sin_addr.s_addr = INADDR_ANY;
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

      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);
	    }
	}
1287
      return (struct sockaddr *) addr;
1288
1289
1290
1291
    }
#endif /* !HAVE_GETADDRINFO */  
}

1292

Niels Möller's avatar
Niels Möller committed
1293
1294
void io_set_nonblocking(int fd)
{
1295
1296
1297
1298
1299
1300
1301
  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
1302
1303
}

1304
1305
void io_set_close_on_exec(int fd)
{
1306
1307
1308
1309
1310
1311
1312
1313
1314
  /* 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)
1315
    fatal("Can't set close-on-exec flag for fd %i: %z\n",
1316
	  fd, STRERROR(errno));
1317
1318
}

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

1320
1321
1322
1323
1324
1325
1326
1327
1328
/* ALL file descripters handled by the backend should use non-blocking mode,
 * and have the close-on-exec flag set. */

void io_init_fd(int fd)
{
  io_set_nonblocking(fd);
  io_set_close_on_exec(fd);
}

1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
struct lsh_fd *
make_lsh_fd(struct io_backend *b,
	    int fd,
	    struct exception_handler *e)
{
  NEW(lsh_fd, f);

  io_init_fd(fd);
  init_file(b, f, fd, e);

  return f;
}

Niels Möller's avatar
Niels Möller committed
1342
/* Some code is taken from Thomas Bellman's tcputils. */
1343
struct lsh_fd *
1344
io_connect(struct io_backend *b,
1345
1346
	   struct sockaddr *remote,
	   socklen_t remote_length,
1347
	   struct command_continuation *c,
1348
	   struct exception_handler *e)
Niels Möller's avatar
Niels Möller committed
1349
{
1350
  int s = socket(remote->sa_family, SOCK_STREAM, 0);
1351
  struct lsh_fd *fd;
Niels Möller's avatar
Niels Möller committed
1352