io.c 44.4 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
       (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)
95
     (super resource)
96
97
98
99
100
101
102
103
104
105
106
107
108
109
     (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
110
111
112

/* Backend loop */

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

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  /* 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;
	    }
	}
    }
  
149
150
151
152
153
  /* 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)
    {
154
      struct lsh_callout *p;
155
      
156
157
158
159
160
161
162
      for (p = b->callouts, b->callouts = NULL;
	   p; p = p->next)
	if (p->super.alive)
	  {
	    LSH_CALLBACK(p->action);
	    p->super.alive = 0;
	  }
163
    }
164
165

  /* Prepare fds. */
Niels Möller's avatar
Niels Möller committed
166
  {
167
168
169
    struct lsh_fd *fd;

    for (fd = b->files; fd; fd = fd->next)
170
171
172
173
      /* NOTE: The prepare callback is allowed to close files. */
      if (fd->super.alive && fd->prepare)
	FD_PREPARE(fd);
  }
174

175
176
177
178
179
180
181
182
  /* This phase unlinks any closed fd:s, and also counts how many
   * fd:s there are. */
  {
    struct lsh_fd *fd;
    struct lsh_fd **fd_p;
    nfds = 0;
    
    for(fd_p = &b->files; (fd = *fd_p); )
183
      {
184
185
186
187
188
	if (!fd->super.alive)
	  /* Unlink this fd */
	  *fd_p = fd->next;
	    
	else
Niels Möller's avatar
Niels Möller committed
189
	  {
190
191
	    if (fd->want_read || fd->want_write)
	      nfds++;
192

193
194
	    fd_p = &fd->next;
	  }
195
      }
Niels Möller's avatar
Niels Möller committed
196
  }
197
    
Niels Möller's avatar
Niels Möller committed
198
199
200
201
202
203
  if (!nfds)
    /* Nothing more to do.
     *
     * NOTE: There might be some callouts left, but we won't wait for them. */
    return 0;

204
205
206
  fds = alloca(sizeof(struct pollfd) * nfds);
  active_fds = alloca(sizeof(struct lsh_fd *) *nfds);
  
Niels Möller's avatar
Niels Möller committed
207
208
209
  /* Fill out fds-array */
  {
    struct lsh_fd *fd;
210
    unsigned long i;
Niels Möller's avatar
Niels Möller committed
211
212
    int all_events = 0;
    
213
    for (fd = b->files, i = 0; fd; fd = fd->next)
Niels Möller's avatar
Niels Möller committed
214
      {
215
216
	assert(fd->super.alive);
	
217
218
	if (fd->want_read || fd->want_write)
	  {
219
220
	    assert(i < nfds);

221
	    active_fds[i] = fd;
Niels Möller's avatar
Niels Möller committed
222

223
224
225
226
	    fds[i].fd = fd->fd;
	    fds[i].events = 0;
	    
	    if (fd->want_read)
227
	      fds[i].events |= MY_POLLIN;
Niels Möller's avatar
Niels Möller committed
228

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

232
233
234
	    all_events |= fds[i].events;
	    i++;
	  }
Niels Möller's avatar
Niels Möller committed
235
236
      }
    assert(i == nfds);
237
    assert(all_events);
Niels Möller's avatar
Niels Möller committed
238
239
  }

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

Niels Möller's avatar
Niels Möller committed
242
243
  if (!res)
    {
244
      gc_maybe(&b->super.super, 0);
Niels Möller's avatar
Niels Möller committed
245
246
      res = poll(fds, nfds, -1);
    }
247
  else
248
    gc_maybe(&b->super.super, 1);
Niels Möller's avatar
Niels Möller committed
249
  
Niels Möller's avatar
Niels Möller committed
250
251
252
253
254
255
256
257
258
259
260
261
  if (!res)
    {
      /* Callouts are not implemented */
      fatal("Unexpected timeout\n");
    }
  if (res < 0)
    switch(errno)
      {
      case EAGAIN:
      case EINTR:
	return 1;
      default:
262
	fatal("io_iter: poll failed: %z", STRERROR(errno));
Niels Möller's avatar
Niels Möller committed
263
264
265
266
      }
  
  {
    /* Do io. Note that the callback functions may add new fds to the
267
268
     * 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
269

270
    /* struct lsh_fd *fd; */
271
    unsigned long i;
Niels Möller's avatar
Niels Möller committed
272
    
273
    for(i=0; i<nfds; i++)
Niels Möller's avatar
Niels Möller committed
274
      {
275
	struct lsh_fd *fd = active_fds[i];
Niels Möller's avatar
Niels Möller committed
276
	assert(i<nfds);
277
278

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

284
285
	/* On systems without poll, we use jpoll.c to emulate some
	 * of poll, but we lack POLLNVAL, POLLPRI and POLLHUP. */
286
#ifdef POLLNVAL
287
288
289
290
291
	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);
292
	    close_fd(fd);
293
294
	    continue;
	  }
295
#endif /* POLLNVAL */
296

297
#ifdef POLLHUP
298
	/* NOTE: The behaviour of poll at EOF varies quite a lot
299
300
301
	 * between systems.
	 *
	 * According to Solaris' man page, POLLHUP is mutually
302
303
304
	 * exclusive with POLLOUT, but orthogonal to POLLIN.
	 *
	 * However, on my system (sparc-linux) POLLHUP is set when we
305
306
	 * get EOF on an fd we are reading.
	 *
307
308
	 * I.e. on some systems, EOF is indicated by poll setting
	 * POLLIN and read returning 0 (in particular, this happens
309
	 * if the poll-by-select-code in jpoll.c is used), while on
310
	 * other systems, poll sets POLLHUP and subsequent read
311
312
	 * calls will return -1, not 0.
	 *
313
314
315
316
	 * 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.
	 *
317
	 * We set the hanged_up flag before calling FD_READ, which
318
	 * tells the io_callback that it should avoid calling read. */
319

320
321
	if (fds[i].revents & POLLHUP)
	  {
322
323
	    if (fd->want_write)
	      /* Will raise an i/o error */
324
	      FD_WRITE(fd);
325
	    else if (fd->want_read)
326
	      {
327
328
329
330
331
332
333
		if (!fd->super.alive)
		  continue;

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

334
335
		FD_READ(fd);
	      }
336
	    else
337
338
	      {
		werror("io.c: poll said POLLHUP on an inactive fd.\n");
339
		close_fd(fd);
340
	      }
341
342
	    continue;
	  }
343
#endif /* POLLHUP */
344

Niels Möller's avatar
Niels Möller committed
345
346
347
348
349
350
351
352
353
354
355
356
357
#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 */
	
358
#ifdef POLLPRI
359
360
361
	if (fds[i].revents & POLLPRI)
	  {
	    werror("io.c: Peer is trying to send Out of Band data. Hanging up.\n");
362
363

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

365
	    close_fd(fd); 
366
367
368

	    continue;
	  }
369
#endif /* POLLPRI */
Niels Möller's avatar
Niels Möller committed
370
	if (fds[i].revents & POLLOUT)
371
	  FD_WRITE(fd);
Niels Möller's avatar
Niels Möller committed
372

373
	if (!fd->super.alive)
Niels Möller's avatar
Niels Möller committed
374
375
	  continue;

376
	if (fds[i].revents & MY_POLLIN)
377
	  FD_READ(fd);
Niels Möller's avatar
Niels Möller committed
378
379
380
381
382
383
      }
    assert(i == nfds);
  }

  return 1;
}
384
  
385
386
void
io_run(struct io_backend *b)
Niels Möller's avatar
Niels Möller committed
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
{
  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))
    ;
}

402
403
404
405
406
407
408
409
410
411
412
413
static void
do_kill_io_backend(struct resource *s)
{
  CAST(io_backend, backend, s);

  if (backend->super.alive)
    {
      struct lsh_fd *fd;
      struct lsh_signal_handler *signal;
  
      for (fd = backend->files, backend->files = NULL;
	   fd; fd = fd->next)
414
415
	close_fd(fd);

416
417
418
419
420
421
422
423
424
425
426
      /* Check that no callback has opened new files. */
      assert(!backend->files);

      for (signal = backend->signals, backend->signals = NULL;
	   signal; signal = signal->next)
	signal->super.alive = 0;

      backend->super.alive = 0;
    }
}

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);

432
  init_resource(&b->super, do_kill_io_backend);
433
  
Niels Möller's avatar
Niels Möller committed
434
  b->files = NULL;
435
  b->signals = NULL;
436
  b->callouts = NULL;
437
438

  return b;
Niels Möller's avatar
Niels Möller committed
439
440
}

441
442
443
444
445
446
void
io_final(struct io_backend *b)
{
  KILL_RESOURCE(&b->super);
}

447
448
struct resource *
io_signal_handler(struct io_backend *b,
Niels Möller's avatar
Added    
Niels Möller committed
449
		  volatile sig_atomic_t *flag,
450
451
452
		  struct lsh_callback *action)
{
  NEW(lsh_signal_handler, handler);
453
  init_resource(&handler->super, NULL);
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

  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);
471
  init_resource(&callout->super, NULL);
472
473
474
475
476
477
478

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

  return &callout->super;
}
Niels Möller's avatar
Niels Möller committed
479
480
481

/* Read-related callbacks */

482
483
484
static void
do_buffered_read(struct io_callback *s,
		 struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
485
486
487
{
  CAST(io_buffered_read, self, s);
  UINT8 *buffer = alloca(self->buffer_size);
488
489
490
  int res;

  assert(fd->want_read);   
491

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

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

524
	  /* NOTE: What to do if want_read is false? To improve the
525
	   * connection_lock mechanism, it must be possible to
526
527
	   * temporarily stop reading, which means that fd->want_read
	   * has to be cleared.
528
529
530
531
532
533
534
535
536
537
538
	   *
	   * 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.
539
	   *
540
	   * We now go with the second alternative. */
541

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

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

550
551
552
	  if (!fd->want_read)
	    debug("do_buffered_read: want_read = 0; handler needs a pause.\n");
	  
553
554
555
556
557
558
559
	  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
560
561
562
	}

      if (left)
563
	verbose("read_buffered: fd died, %i buffered bytes discarded\n",
Niels Möller's avatar
Niels Möller committed
564
565
566
		left);
    }
  else
567
568
569
570
571
572
573
    {
      /* 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
574
575
      /* Close the fd, unless it has a write callback. */
      close_fd_read(fd);
576
      
577
578
579
      READ_HANDLER(self->handler, 0, NULL);
    }
	
Niels Möller's avatar
Niels Möller committed
580
581
}

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

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

  return &self->super;
}

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

602
603
604
  assert(fd->want_read);

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

      if (res < 0)
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
	{
	  switch(errno)
	    {
	    case EINTR:
	      break;
	    case EWOULDBLOCK:
	      werror("io.c: read_consume: Unexpected EWOULDBLOCK\n");
	      break;
	    case EPIPE:
	      /* 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");
	    default:
	      EXCEPTION_RAISE(fd->e, 
			      make_io_exception(EXC_IO_READ,
						fd, errno, NULL));
	      break;
	    }
	  lsh_string_free(s);
	}
Niels Möller's avatar
Niels Möller committed
641
642
643
      else if (res > 0)
	{
	  s->length = res;
644
	  A_WRITE(self->consumer, s);
Niels Möller's avatar
Niels Möller committed
645
646
	}
      else
647
	{
648
	  lsh_string_free(s);
Niels Möller's avatar
Niels Möller committed
649
650
	eof:
	  /* Close the fd, unless it has a write callback. */
651
	  A_WRITE(self->consumer, NULL);
652
	  close_fd_read(fd);
653
	}
Niels Möller's avatar
Niels Möller committed
654
655
656
657
658
659
660
661
    }
}

/* 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)
{
662
  self->super.f = do_consuming_read;
Niels Möller's avatar
Niels Möller committed
663
664
  self->consumer = consumer;
}
665

666

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

707
708
709
710
711
712
713
714
715
716
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)
717
    close_fd(fd);
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
}

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
742
743
744

/* Listen callback */

745
746
747
748
749
750
751
752
753
754
/* 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
755
static void
756
do_listen_callback(struct io_callback *s,
Niels Möller's avatar
Niels Möller committed
757
		   struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
758
{
759
  CAST(io_listen_callback, self, s);
760
761
762
763
764
765

#if WITH_IPV6
  struct sockaddr_storage peer;
#else
  struct sockaddr peer;
#endif
766
767

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

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

785
786
787
788
789
790
791
792
793
794
795
796
797
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
798

Niels Möller's avatar
Niels Möller committed
799
800
/* Connect callback */

801
802
803
804
805
806
807
808
809
810
811
/* 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
812
{
813
  CAST(io_connect_callback, self, s);
814
  int socket_error;
815
  socklen_t len = sizeof(socket_error);
816
  
817
  /* Check if the connection was successful */
818
819
  if ((getsockopt(fd->fd, SOL_SOCKET, SO_ERROR,
		  (char *) &socket_error, &len) < 0)
820
      || socket_error)
821
    {
822
      debug("io.c: connect_callback: Connect failed.\n");
Niels Möller's avatar
Niels Möller committed
823
      EXCEPTION_RAISE(fd->e,
824
		      make_io_exception(EXC_IO_CONNECT, fd, 0, "connect failed."));
825
      close_fd(fd);
826
827
    }
  else
Niels Möller's avatar
Niels Möller committed
828
    {
829
830
      fd->write = NULL;
      fd->want_write = 0;
831
      fd->label = "connected socket";
832
      COMMAND_RETURN(self->c, fd);
833
    }
834
835
836
837
838
839
840
841
842
843
844
}

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;
845
846
}

847

Niels Möller's avatar
Niels Möller committed
848
/* This function is called if a connection this file somehow depends
849
850
851
852
853
854
855
856
 * 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
857
858
  /* We use close_fd_nicely, so that any data in the write buffer is
   * flushed before the fd is closed. */
859
  if (r->alive)
860
    close_fd_nicely(fd);
861
862
}

863
864
865
866
867
868
869
870
871
872
/* 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);

873
      if (e->fd)
874
	close_fd(e->fd);
875
876
877
878
879
    }
  EXCEPTION_RAISE(self->parent, x);
  return;
}

Niels Möller's avatar
Niels Möller committed
880
/* Initializes a file structure, and adds it to the backend's list. */
881
882
static void
init_file(struct io_backend *b, struct lsh_fd *f, int fd,
883
	  const char *label,
884
	  struct exception_handler *e)
Niels Möller's avatar
Niels Möller committed
885
{
886
  init_resource(&f->super, do_kill_fd);
887

Niels Möller's avatar
Niels Möller committed
888
  f->fd = fd;
889
890
  f->label = label;
  
891
  f->e = make_exception_handler(do_exc_io_handler, e, HANDLER_CONTEXT);
892
  
Niels Möller's avatar
Niels Möller committed
893
894
895
  f->close_callback = NULL;

  f->prepare = NULL;
896

897
898
  f->hanged_up = 0;
  
Niels Möller's avatar
Niels Möller committed
899
900
901
902
903
  f->want_read = 0;
  f->read = NULL;

  f->want_write = 0;
  f->write = NULL;
904
  f->write_close = NULL;
Niels Möller's avatar
Niels Möller committed
905
906
907
908

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

910
/* These functions are used by werror and friends */
Niels Möller's avatar
Niels Möller committed
911
912
913
914
915
916
917
918
919
920
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

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

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
1011
/* 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
1012
1013
1014

/* Network utility functions */

1015
/* Converts a string port number or service name to a port number.
1016
1017
 * Returns the port number in _host_ byte order, or 0 if lookup
 * fails. */
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038

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);
1039
1040
	  if (!serv)
	    return 0;
1041
1042
1043
1044
1045
1046
	  return ntohs(serv->s_port);
	}
    }
}


1047
1048
1049
1050
1051
/* 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)
1052
1053
{
  int portno = get_portno(port, "tcp");
1054
1055
1056
1057
1058
1059
  if (!portno)
    portno = def;

  if (!portno)
    return NULL;

1060
1061
1062
1063
1064
  else
    {
      NEW(address_info, info);
      
      info->port = portno;
1065
      info->ip = host ? ssh_format("%lz", host) : NULL;
1066
1067
1068
1069
      
      return info;
    }
}
1070

1071
1072
struct address_info *
make_address_info(struct lsh_string *host, UINT32 port)
1073
1074
1075
1076
1077
1078
1079
1080
{
  NEW(address_info, info);

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

1081
1082
1083
struct address_info *
sockaddr2info(size_t addr_len UNUSED,
	      struct sockaddr *addr)
1084
{
1085
  NEW(address_info, info);
1086
1087
1088
1089
1090
1091
1092
  
  switch(addr->sa_family)
    {
    case AF_INET:
      {
	struct sockaddr_in *in = (struct sockaddr_in *) addr;
	UINT32 ip = ntohl(in->sin_addr.s_addr);
1093
	info->port = ntohs(in->sin_port);
1094
1095
1096
1097
1098
	info->ip = ssh_format("%di.%di.%di.%di",
			      (ip >> 24) & 0xff,
			      (ip >> 16) & 0xff,
			      (ip >> 8) & 0xff,
			      ip & 0xff);
1099
1100
	return info;
      }
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
#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;
      }
1118
#endif
1119
1120
1121
1122
    case AF_UNIX:
      /* Silently return NULL. This happens when a gateway client
       * connects. */
      return NULL;
1123
    default:
1124
      werror("io.c: sockaddr2info: Unsupported address family.\n");
1125
      return NULL;
1126
1127
    }
}
1128

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
#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? */
1148
1149
1150
struct sockaddr *
address_info2sockaddr(socklen_t *length,
		      struct address_info *a,
1151
1152
		      /* Preferred address families. Zero-terminated array. */
		      const int *preference,
1153
		      int lookup)
1154
{
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  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;
1166

Niels Möller's avatar
Niels Möller committed
1167
1168
  /* Some systems have getaddrinfo, but still doesn't implement all of
   * RFC 2553 */
1169
1170
#if defined(HAVE_GETADDRINFO) && \
    defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST)
1171
1172
1173
  {
    struct addrinfo hints;
    struct addrinfo *list;
1174
    struct addrinfo *chosen;
1175
    struct sockaddr *res;
1176
1177
1178
1179
1180
1181
1182
    const int default_preference
#if WITH_IPV6
      [3] = { AF_INET6, AF_INET }
#else
      [2] = { AF_INET, 0 }
#endif      
      ;
1183
1184
1185
    int err;
    /* FIXME: It seems ugly to have to convert the port number to a
     * string. */
1186
    struct lsh_string *service = ssh_format("%di", a->port);
1187
1188
1189
1190
1191
1192
1193
1194
1195

    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;
    
1196
    err = getaddrinfo(host, lsh_get_cstring(service), &hints, &list);
1197
1198
1199
1200
    lsh_string_free(service);

    if (err)
      {
1201
	debug("address_info2sockaddr: getaddrinfo failed (err = %d): %z\n",
1202
1203
1204
1205
	      err, gai_strerror(err));
	return NULL;
      }

1206
1207
1208
1209
1210
1211
1212
1213
1214
    chosen = choose_address(list,
			    preference ? preference : default_preference);
    if (!chosen)
      {
	freeaddrinfo(list);
	return NULL;
      }
    
    *length = chosen->ai_addrlen;
1215
1216
    
    res = lsh_space_alloc(*length);
1217
    memcpy(res, chosen->ai_addr, *length);
1218
1219
1220
1221
    freeaddrinfo(list);

    return res;
  }
1222
1223
1224
#else
/* !(defined(HAVE_GETADDRINFO) &&
     defined(HAVE_GAI_STRERROR) && defined(HAVE_AI_NUMERICHOST) */ 
1225
1226

#if WITH_IPV6
1227
#error IPv6 enabled, but getaddrinfo and friends were not found. 
1228
#endif
1229

1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
  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);
1242
1243
1244

      /* Use IPv4 only */
      addr->sin_family = AF_INET;
1245
1246
    
      if (!host)
1247
1248
	/* Any interface */
	addr->sin_addr.s_addr = INADDR_ANY;
1249
1250
1251
1252
1253
1254
1255
1256