io.c 56.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

/* 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
25
26
#if HAVE_CONFIG_H
#include "config.h"
#endif
27

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

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

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

46
47
48
49
50
51
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
52
53
/* For the popen code */
#include <sys/wait.h>
54
55
56

#include <arpa/inet.h>

57
58
#include <oop.h>

59
60
61
62
63
64
65
66
#include "io.h"

#include "command.h"
#include "format.h"
#include "string_buffer.h"
#include "werror.h"
#include "xalloc.h"

67
68
69
70
71
72
73
/* Workaround for some version of FreeBSD. */
#ifdef POLLRDNORM
# define MY_POLLIN (POLLIN | POLLRDNORM)
#else /* !POLLRDNORM */
# define MY_POLLIN POLLIN
#endif /* !POLLRDNORM */

74
75
/* Max number of simultaneous connection attempts */
#define CONNECT_ATTEMPTS_LIMIT 3
Niels Möller's avatar
Niels Möller committed
76

77
#define GABA_DEFINE
78
#include "io.h.x"
79
#undef GABA_DEFINE
80
81
82

#include "io.c.x"

83
84
/* Glue to liboop */

85
/* Because of signal handlers, there can be only one oop object. */
86
87
static oop_source_sys *global_oop_sys = NULL;
static oop_source *source = NULL;
Niels Möller's avatar
Niels Möller committed
88
static unsigned nfiles = 0;
89

90
/* OOP Callbacks */
91
static void *
92
lsh_oop_signal_callback(oop_source *s UNUSED, int sig, void *data)
93
94
95
{
  CAST(lsh_signal_handler, self, (struct lsh_object *) data);

96
  trace("lsh_oop_signal_callback: Signal %i, handler: %t\n",
97
	sig, self->action);
98
  
99
100
  assert(sig == self->signum);
  
101
  LSH_CALLBACK(self->action);
102

103
  return OOP_CONTINUE;
104
105
106
}

static void
107
lsh_oop_register_signal(struct lsh_signal_handler *handler)
108
{
109
110
111
  trace("lsh_oop_register_signal: signal: %i, handler: %t\n",
	handler->signum, handler);
  
112
  assert(source);
113
  if (handler->super.alive)
Niels Möller's avatar
Niels Möller committed
114
115
    source->on_signal(source, handler->signum,
		      lsh_oop_signal_callback, handler);
116
117
}

118
static void
119
lsh_oop_cancel_signal(struct lsh_signal_handler *handler)
120
{
121
122
  trace("lsh_oop_cancel_signal: signal: %i, handler: %t\n",
	handler->signum, handler);
123

124
  assert(source);
125
  if (handler->super.alive)
Niels Möller's avatar
Niels Möller committed
126
127
    source->cancel_signal(source, handler->signum,
			  lsh_oop_signal_callback, handler);
128
}
129
130

static void *
Niels Möller's avatar
Niels Möller committed
131
132
lsh_oop_fd_read_callback(oop_source *s UNUSED, int fileno,
			 oop_event event, void *data)
133
134
135
136
{
  CAST(lsh_fd, fd, (struct lsh_object *) data);

  assert(fileno == fd->fd);
137
138
  assert(event == OOP_READ);
  assert(fd->super.alive);
139

140
  trace("lsh_oop_fd_read_callback: fd %i: %z\n",
141
142
143
	fd->fd, fd->label);

  FD_READ(fd);
144

145
  return OOP_CONTINUE;
146
147
}

148
149
void
lsh_oop_register_read_fd(struct lsh_fd *fd)
150
{
151
152
153
  trace("lsh_oop_register_read_fd: fd: %i, %z\n",
	fd->fd, fd->label);
  
154
  assert(source);
155
  if (fd->super.alive && !fd->want_read)
156
157
158
159
160
161
    {
      assert(fd->read);
      
      source->on_fd(source, fd->fd, OOP_READ, lsh_oop_fd_read_callback, fd);
      fd->want_read = 1;
    }
162
163
}

164
165
166
void
lsh_oop_cancel_read_fd(struct lsh_fd *fd)
{
167
168
169
  trace("lsh_oop_cancel_read_fd: fd: %i, %z\n",
	fd->fd, fd->label);
  
170
  assert(source);
171
172
173
174
175
176
  if (fd->super.alive)
    {
      source->cancel_fd(source, fd->fd, OOP_READ);
      fd->want_read = 0;
    }
}
177
178

static void *
Niels Möller's avatar
Niels Möller committed
179
180
lsh_oop_fd_write_callback(oop_source *s UNUSED, int fileno,
			  oop_event event, void *data)
181
{
182
  CAST(lsh_fd, fd, (struct lsh_object *) data);
183

184
  assert(fileno == fd->fd);
185
  assert(event == OOP_WRITE);
186
187
  assert(fd->super.alive);
  
188
  trace("lsh_oop_fd_write_callback: fd %i: %z\n",
189
	fd->fd, fd->label);
190

191
  FD_WRITE(fd);
192

193
  return OOP_CONTINUE;
194
195
}

196
197
void
lsh_oop_register_write_fd(struct lsh_fd *fd)
198
{
199
200
201
  trace("lsh_oop_register_write_fd: fd: %i, %z\n",
	fd->fd, fd->label);
  
202
  assert(source);
203
  if (fd->super.alive && !fd->want_write)
204
205
206
207
208
209
210
    {
      assert(fd->write);
      
      source->on_fd(source, fd->fd, OOP_WRITE, lsh_oop_fd_write_callback, fd);
      fd->want_write = 1;
    }
}
211

212
213
void
lsh_oop_cancel_write_fd(struct lsh_fd *fd)
214
{
215
216
217
  trace("lsh_oop_cancel_write_fd: fd: %i, %z\n",
	fd->fd, fd->label);

218
  assert(source);
219
220
221
222
223
  if (fd->super.alive)
    {
      source->cancel_fd(source, fd->fd, OOP_WRITE);
      fd->want_write = 0;
    }
224
225
}

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
static void *
lsh_oop_time_callback(oop_source *source UNUSED,
                      struct timeval time UNUSED, void *data)
{
  CAST(lsh_callout, callout, (struct lsh_object *) data);

  assert(callout->super.alive);

  trace("lsh_oop_time_callback: action: %t\n",
        callout->action);
  
  callout->super.alive = 0;

  LSH_CALLBACK(callout->action);

  return OOP_CONTINUE;
}

static void
lsh_oop_register_callout(struct lsh_callout *callout)
{
247
  assert(source);
248
249
250
  trace("lsh_oop_register_callout: action: %t\n",
        callout->action);

251
  if (callout->super.alive)
252
    source->on_time(source, callout->when, lsh_oop_time_callback, callout);
253
254
255
256
257
}

static void
lsh_oop_cancel_callout(struct lsh_callout *callout)
{
258
  assert(source);
259
260
  trace("lsh_oop_cancel_callout: action: %t\n",
        callout->action);
261
  if (callout->super.alive)
262
    source->cancel_time(source, callout->when, lsh_oop_time_callback, callout);
263
264
}

Niels Möller's avatar
Niels Möller committed
265
266
267
268
269
270
271
272
static void *
lsh_oop_stop_callback(oop_source *source UNUSED,
                      struct timeval time UNUSED, void *data UNUSED)
{
  trace("lsh_oop_stop_callback\n");
  
  if (!nfiles)
    /* An arbitrary non-NULL value stops oop_sys_run. */
273
    return OOP_HALT;
Niels Möller's avatar
Niels Möller committed
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
  else
    return OOP_CONTINUE;
}

static void
lsh_oop_stop(void)
{
  assert(source);
  trace("lsh_oop_stop\n");
  source->on_time(source, OOP_TIME_NOW, lsh_oop_stop_callback, NULL);
}

static void
lsh_oop_cancel_stop(void)
{
  assert(source);
  trace("lsh_oop_cancel_stop\n");
  source->cancel_time(source, OOP_TIME_NOW, lsh_oop_stop_callback, NULL);
}

void
io_init(void)
{
  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");

  assert(!global_oop_sys);
  global_oop_sys = oop_sys_new();
  if (!global_oop_sys)
    fatal("Failed to initialize liboop.\n");

  source = oop_sys_source(global_oop_sys);
}

void
io_final(void)
{
  assert(source);
  gc_final();

  /* The final gc may have closed some files, and called lsh_oop_stop.
   * So we must unregister that before deleting the oop source. */
  lsh_oop_cancel_stop();
  
  /* There mustn't be any outstanding callbacks left. */
  oop_sys_delete(global_oop_sys);
  global_oop_sys = NULL;
  source = NULL;
329
330
331
332
333
334

  /* It's a good idea to reset std* to blocking mode. */

  io_set_blocking(STDIN_FILENO);
  io_set_blocking(STDOUT_FILENO);
  io_set_blocking(STDERR_FILENO);
Niels Möller's avatar
Niels Möller committed
335
336
337
338
339
340
341
342
343
344
}

void
io_run(void)
{
  void *res = oop_sys_run(global_oop_sys);

  /* We need liboop-0.8, OOP_ERROR is not defined in liboop-0.7. */

  if (res == OOP_ERROR)
345
    werror("oop_sys_run %e\n", errno);
Niels Möller's avatar
Niels Möller committed
346
347
348
349

  trace("io_run: Exiting\n");
}

350

351
352
353
354
355
356
/* Calls trigged by a signal handler. */
/* GABA:
   (class
     (name lsh_signal_handler)
     (super resource)
     (vars
357
       (signum . int)
358
359
360
361
362
363
364
365
       (action object lsh_callback)))
*/

/* GABA:
   (class
     (name lsh_callout)
     (super resource)
     (vars
366
       (when . "struct timeval")
367
368
369
       (action object lsh_callback)))
*/

370

371
372
373
374
375
376
377
static void
do_kill_signal_handler(struct resource *s)
{
  CAST(lsh_signal_handler, self, s);

  if (self->super.alive)
    {
378
      lsh_oop_cancel_signal(self);
379
380
381
382
      self->super.alive = 0;
    }
}

383
struct resource *
384
io_signal_handler(int signum,
385
386
387
		  struct lsh_callback *action)
{
  NEW(lsh_signal_handler, handler);
388
389

  init_resource(&handler->super, do_kill_signal_handler);
390

391
  handler->signum = signum;
392
393
  handler->action = action;

394
  lsh_oop_register_signal(handler);
395
  gc_global(&handler->super);
396
397
398
399
  
  return &handler->super;
}

400
401
402
403
404
405
406
407
408
409
410
411
static void
do_kill_callout(struct resource *s)
{
  CAST(lsh_callout, self, s);

  if (self->super.alive)
    {
      lsh_oop_cancel_callout(self);
      self->super.alive = 0;
    }
}

412
struct resource *
413
io_callout(struct lsh_callback *action, unsigned seconds)
414
{
415
  NEW(lsh_callout, self);
416
  init_resource(&self->super, do_kill_callout);
417

418
419
420
421
422
423
424
425
426
427
428
  if (seconds)
    {
      /* NOTE: Using absolute times, like oop does, is a little
       * dangerous if the system time is changed abruptly. */
      if (gettimeofday(&self->when, NULL) < 0)
	fatal("io_callout: gettimeofday failed!\n");
      self->when.tv_sec += seconds;
    }
  else
    self->when = OOP_TIME_NOW;
  
429
  self->action = action;
430
      
431
432
  lsh_oop_register_callout(self);
  
433
434
  gc_global(&self->super);
  return &self->super;
435
}
Niels Möller's avatar
Niels Möller committed
436
437
438

/* Read-related callbacks */

439
440
441
static void
do_buffered_read(struct io_callback *s,
		 struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
442
443
{
  CAST(io_buffered_read, self, s);
444
  uint8_t *buffer = alloca(self->buffer_size);
445
446
447
  int res;

  assert(fd->want_read);   
448

449
  res = read(fd->fd, buffer, self->buffer_size);
450
  
Niels Möller's avatar
Niels Möller committed
451
452
453
454
455
456
457
458
459
  if (res < 0)
    switch(errno)
      {
      case EINTR:
	break;
      case EWOULDBLOCK:
	werror("io.c: read_callback: Unexpected EWOULDBLOCK\n");
	break;
      case EPIPE:
460
	/* Getting EPIPE from read seems strange, but appearantly
461
	 * it happens sometimes. */
462
	werror("Unexpected EPIPE from read.\n");
Niels Möller's avatar
Niels Möller committed
463
      default:
Niels Möller's avatar
Niels Möller committed
464
465
466
	EXCEPTION_RAISE(fd->e, 
			make_io_exception(EXC_IO_READ, fd,
					  errno, NULL));
467
468
469
	/* Close the fd, unless it has a write callback. */
	close_fd_read(fd);
	
Niels Möller's avatar
Niels Möller committed
470
471
472
473
	break;
      }
  else if (res > 0)
    {
474
      uint32_t left = res;
Niels Möller's avatar
Niels Möller committed
475
    
476
      while (fd->super.alive && fd->read && left)
Niels Möller's avatar
Niels Möller committed
477
	{
478
	  uint32_t done;
Niels Möller's avatar
Niels Möller committed
479

480
	  /* NOTE: What to do if want_read is false? To improve the
481
	   * connection_lock mechanism, it must be possible to
482
483
	   * temporarily stop reading, which means that fd->want_read
	   * has to be cleared.
484
485
486
487
488
489
490
491
492
493
494
	   *
	   * 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.
495
	   *
496
	   * We now go with the second alternative. */
497

498
	  assert(self->handler);
Niels Möller's avatar
Niels Möller committed
499
500

	  /* NOTE: This call may replace self->handler */
Niels Möller's avatar
Niels Möller committed
501
	  done = READ_HANDLER(self->handler, left, buffer);
502
	  
Niels Möller's avatar
Niels Möller committed
503
504
	  buffer += done;
	  left -= done;
505

506
507
508
	  if (!fd->want_read)
	    debug("do_buffered_read: want_read = 0; handler needs a pause.\n");
	  
509
510
511
512
	  if (fd->want_read && !self->handler)
	    {
	      werror("do_buffered_read: Handler disappeared! Ignoring %i bytes\n",
		     left);
513
	      lsh_oop_cancel_read_fd(fd);
514
515
	      return;
	    }
Niels Möller's avatar
Niels Möller committed
516
517
518
	}

      if (left)
519
	verbose("read_buffered: fd died, %i buffered bytes discarded\n",
Niels Möller's avatar
Niels Möller committed
520
521
522
		left);
    }
  else
523
524
525
526
527
528
529
    {
      /* 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
530
531
      /* Close the fd, unless it has a write callback. */
      close_fd_read(fd);
532
      
533
534
535
      READ_HANDLER(self->handler, 0, NULL);
    }
	
Niels Möller's avatar
Niels Möller committed
536
537
}

538
struct io_callback *
539
make_buffered_read(uint32_t buffer_size,
Niels Möller's avatar
Niels Möller committed
540
541
542
543
		   struct read_handler *handler)
{
  NEW(io_buffered_read, self);

544
  self->super.f = do_buffered_read;
Niels Möller's avatar
Niels Möller committed
545
546
547
548
549
550
  self->buffer_size = buffer_size;
  self->handler = handler;

  return &self->super;
}

551
552
553
static void
do_consuming_read(struct io_callback *c,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
554
{
555
  CAST_SUBTYPE(io_consuming_read, self, c);
556
  uint32_t wanted = READ_QUERY(self);
Niels Möller's avatar
Niels Möller committed
557

558
559
560
561
  assert(fd->want_read);
  
  if (!wanted)
    {
562
      lsh_oop_cancel_read_fd(fd);
563
    }
Niels Möller's avatar
Niels Möller committed
564
565
566
567
568
569
  else
    {
      struct lsh_string *s = lsh_string_alloc(wanted);
      int res = read(fd->fd, s->data, wanted);

      if (res < 0)
570
571
572
573
574
575
576
577
578
579
580
581
582
	{
	  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");
583
	      /* Fall through */
584
585
586
587
588
589
590
591
	    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
592
593
      else if (res > 0)
	{
594
	  lsh_string_trunc(s, res);
595
	  A_WRITE(self->consumer, s);
Niels Möller's avatar
Niels Möller committed
596
597
	}
      else
598
	{
599
	  lsh_string_free(s);
600

Niels Möller's avatar
Niels Möller committed
601
	  /* Close the fd, unless it has a write callback. */
602
	  A_WRITE(self->consumer, NULL);
603
	  close_fd_read(fd);
604
	}
Niels Möller's avatar
Niels Möller committed
605
606
607
608
609
610
611
612
    }
}

/* 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)
{
613
  self->super.f = do_consuming_read;
Niels Möller's avatar
Niels Möller committed
614
615
  self->consumer = consumer;
}
616

617

Niels Möller's avatar
Niels Möller committed
618
/* Write related callbacks */
619
620
621
static void
do_write_callback(struct io_callback *s UNUSED,
		  struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
622
{
623
  /* CAST(io_write_callback, self, s); */
624
625
626
  assert(fd->super.alive);
  
  if (!write_buffer_pre_write(fd->write_buffer))
627
    {
628
629
      /* Buffer is empty */
      if (fd->write_buffer->closed)
630
        close_fd_write(fd);
631
632
      else
	lsh_oop_cancel_write_fd(fd);
633
    }
634
635
  else
    {
636
      uint32_t size;
637
638
639
640
641
      int res;

      size = MIN(fd->write_buffer->end - fd->write_buffer->start,
		 fd->write_buffer->block_size);
      assert(size);
Niels Möller's avatar
Niels Möller committed
642
  
643
644
645
646
647
648
649
650
651
652
653
654
655
      res = write(fd->fd,
		  fd->write_buffer->buffer + fd->write_buffer->start,
		  size);
      if (!res)
	fatal("Closed?");
      if (res < 0)
	switch(errno)
	  {
	  case EINTR:
	  case EAGAIN:
	    break;
	  case EPIPE:
	    debug("io.c: Broken pipe.\n");
656

657
658
	    /* Fall through */
	  default:
659
660
661
662
663
664
665
#if 0
	    /* Don't complain if it was writing the final ^D
	     * character that failed. */
	    if ( (fd->type == IO_PTY_CLOSED)
		 && (fd->write_buffer->length == 1) )
	      debug("io.c: ignoring write error, on the final ^D character\n");
#endif
666
	    werror("io.c: write failed %e\n", errno);
667
	    EXCEPTION_RAISE(fd->e,
668
669
			    make_io_exception(EXC_IO_WRITE,
					      fd, errno, NULL));
670
	    close_fd(fd);
671
	    
672
673
674
675
676
677
	    break;
	  }
      else
	write_buffer_consume(fd->write_buffer, res);
    }
}
678

679
680
681
682
683
684
static struct io_callback io_write_callback =
{ STATIC_HEADER, do_write_callback };


struct listen_value *
make_listen_value(struct lsh_fd *fd,
685
686
		  struct address_info *peer,
		  struct address_info *local)
687
688
689
690
691
{
  NEW(listen_value, self);

  self->fd = fd;
  self->peer = peer;
692
  self->local = local;
693
694
695
696

  return self;
}

697
698
699
700
701
702
703
struct sockaddr_list *
sockaddr_cons(socklen_t length, const struct sockaddr *addr,
	      struct sockaddr_list *tail)
{
  NEW(sockaddr_list, self);
  self->next = tail;
  self->length = length;
704
705
  self->address = lsh_space_alloc(length);
  memcpy(self->address, addr, length);
706
707
708

  return self;
}
Niels Möller's avatar
Niels Möller committed
709
710
711

/* Listen callback */

712
713
714
715
716
/* GABA:
   (class
     (name io_listen_callback)
     (super io_callback)
     (vars
717
       (c object command)
718
719
720
       (e object exception_handler)))
*/

Niels Möller's avatar
Niels Möller committed
721
static void
722
do_listen_callback(struct io_callback *s,
Niels Möller's avatar
Niels Möller committed
723
		   struct lsh_fd *fd)
Niels Möller's avatar
Niels Möller committed
724
{
725
  CAST(io_listen_callback, self, s);
726
727
728
729
730
731

#if WITH_IPV6
  struct sockaddr_storage peer;
#else
  struct sockaddr peer;
#endif
732
733

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

Niels Möller's avatar
Niels Möller committed
736
737
738
  conn = accept(fd->fd,
		(struct sockaddr *) &peer, &addr_len);
  if (conn < 0)
739
    {
740
      werror("io.c: accept failed %e", errno);
Niels Möller's avatar
Niels Möller committed
741
      return;
742
    }
743

744
  trace("io.c: accept on fd %i\n", conn);
745
746
747
748
749
750
  COMMAND_CALL(self->c,
	       make_listen_value(make_lsh_fd(conn, "accepted socket", self->e),
				 sockaddr2info(addr_len,
					       (struct sockaddr *) &peer), 
				 fd2info(fd,0)),
	       &discard_continuation, self->e);
Niels Möller's avatar
Niels Möller committed
751
}
752

753
struct io_callback *
754
make_listen_callback(struct command *c,
755
756
757
758
759
760
761
762
763
		     struct exception_handler *e)
{
  NEW(io_listen_callback, self);
  self->super.f = do_listen_callback;
  self->c = c;
  self->e = e;
  
  return &self->super;
}
Niels Möller's avatar
Niels Möller committed
764

765

Niels Möller's avatar
Niels Möller committed
766
767
/* Connect callback */

768
769
770
771
772
773
774
775
776
777
778
/* 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
779
{
780
  CAST(io_connect_callback, self, s);
781
  int socket_error;
782
  socklen_t len = sizeof(socket_error);
783
  
784
  /* Check if the connection was successful */
785
786
  if ((getsockopt(fd->fd, SOL_SOCKET, SO_ERROR,
		  (char *) &socket_error, &len) < 0)
787
      || socket_error)
788
    {
789
      trace("io.c: connect_callback: Connect on fd %i failed.\n", fd->fd);
Niels Möller's avatar
Niels Möller committed
790
      EXCEPTION_RAISE(fd->e,
791
		      make_io_exception(EXC_IO_CONNECT, fd, 0, "connect failed."));
792
      close_fd(fd);
793
794
    }
  else
Niels Möller's avatar
Niels Möller committed
795
    {
796
      trace("io.c: connect_callback: fd %i connected.\n", fd->fd);
797
      fd->write = NULL;
798
      lsh_oop_cancel_write_fd(fd);
799
      fd->label = "connected socket";
800
      COMMAND_RETURN(self->c, fd);
801
    }
802
803
}

804
struct io_callback *
805
806
807
808
809
810
811
812
make_connect_callback(struct command_continuation *c)
{
  NEW(io_connect_callback, self);

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

  return &self->super;
813
814
}

815

Niels Möller's avatar
Niels Möller committed
816
/* This function is called if a connection this file somehow depends
817
818
819
820
821
822
823
824
 * 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
825
826
  /* We use close_fd_nicely, so that any data in the write buffer is
   * flushed before the fd is closed. */
827
  if (r->alive)
828
    close_fd_nicely(fd);
829
830
}

831
832
833
834
835
836
837
838
839
840
/* 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);

841
      if (e->fd)
842
	close_fd(e->fd);
843
844
845
846
847
    }
  EXCEPTION_RAISE(self->parent, x);
  return;
}

848

849
/* These functions are used by werror and friends */
Niels Möller's avatar
Niels Möller committed
850
851
852

/* For fd:s in blocking mode. */
const struct exception *
853
write_raw(int fd, uint32_t length, const uint8_t *data)
Niels Möller's avatar
Niels Möller committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
{
  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 *
877
write_raw_with_poll(int fd, uint32_t length, const uint8_t *data)
Niels Möller's avatar
Niels Möller committed
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
{
  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;
}

920
921
/* For fd:s in blocking mode. */
const struct exception *
922
read_raw(int fd, uint32_t length, uint8_t *data)
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
{
  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
951

952
struct lsh_string *
953
io_read_file_raw(int fd, uint32_t guess)
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
{
  struct string_buffer buffer;
  string_buffer_init(&buffer, guess);

  for (;;)
    {
      int res;
      
      if (!buffer.left)
        /* Roughly double the size of the buffer */
        string_buffer_grow(&buffer,
                           buffer.partial->length + buffer.total + 100);
      
      res = read(fd, buffer.current, buffer.left);
      
      if (res < 0)
        {
          if (errno == EINTR)
            continue;
          
          string_buffer_clear(&buffer);
          return NULL;
        }
      else if (!res)
        {
          /* EOF */
          return string_buffer_final(&buffer, buffer.left);
        }
      assert( (unsigned) res <= buffer.left);
      
      buffer.current += res;
      buffer.left -= res;
    }
}

Niels Möller's avatar
Niels Möller committed
989
990
/* Network utility functions */

991
/* Converts a string port number or service name to a port number.
992
993
 * Returns the port number in _host_ byte order, or 0 if lookup
 * fails. */
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

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);
1015
1016
	  if (!serv)
	    return 0;
1017
1018
1019
1020
1021
1022
	  return ntohs(serv->s_port);
	}
    }
}


1023
1024
1025
1026
1027
/* 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)
1028
1029
{
  int portno = get_portno(port, "tcp");
1030
1031
1032
1033
1034
1035
  if (!portno)
    portno = def;

  if (!portno)
    return NULL;

1036
1037
1038
1039
1040
  else
    {
      NEW(address_info, info);
      
      info->port = portno;
1041
      info->ip = host ? ssh_format("%lz", host) : NULL;
1042
1043
1044
1045
      
      return info;
    }
}
1046

1047
struct address_info *
1048
make_address_info(struct lsh_string *host, uint32_t port)
1049
1050
1051
{
  NEW(address_info, info);

1052
  info->port = port;
1053
1054
1055
1056
  info->ip = host;
  return info;
}

1057
struct address_info *
1058
sockaddr2info(size_t addr_len,
1059
	      struct sockaddr *addr)
1060
{
1061
  NEW(address_info, info);
1062
1063
1064
1065
  
  switch(addr->sa_family)
    {
    case AF_INET:
1066
      assert(addr_len == sizeof(struct sockaddr_in));
1067
1068
      {
	struct sockaddr_in *in = (struct sockaddr_in *) addr;
1069
	uint32_t ip = ntohl(in->sin_addr.s_addr);
1070
	
1071
	info->port = ntohs(in->sin_port);
1072
1073
1074
1075
1076
	info->ip = ssh_format("%di.%di.%di.%di",
			      (ip >> 24) & 0xff,
			      (ip >> 16) & 0xff,
			      (ip >> 8) & 0xff,
			      ip & 0xff);
1077
      }
1078
1079
      return info;
      
1080
1081
#if WITH_IPV6
    case AF_INET6:
1082
      assert(addr_len == sizeof(struct sockaddr_in6));
1083
1084
      {
	struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
1085

1086
	info->port = ntohs(in->sin6_port);
1087
1088
1089
1090
1091
1092
	info->ip = lsh_string_alloc(INET6_ADDRSTRLEN + 1);

	/* Does inet_ntop always use lower case letters? If not, we
	 * should perhaps lowercase the result explicitly. */
	if (!inet_ntop(addr->sa_family, &in->sin6_addr,
		       info->ip->data, info->ip->length))
1093
	  fatal("inet_ntop failed for IPv6 address.\n");
1094
1095

	lsh_string_trunc(info->ip, strlen(info->ip->data));
1096
      }
1097
      return info;
1098
#endif /* WITH_IPV6 */
1099

1100
1101
1102
1103
    case AF_UNIX:
      /* Silently return NULL. This happens when a gateway client
       * connects. */
      return NULL;
1104
    default:
1105
      werror("io.c: sockaddr2info: Unsupported address family.\n");
1106
      return NULL;
1107
1108
    }
}
1109

1110
1111
1112
1113
struct address_info *
fd2info(struct lsh_fd *fd, int side)
{
#if WITH_IPV6
Niels Möller's avatar
Niels Möller committed
1114
  struct sockaddr_storage sock;
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
#else
  struct sockaddr sock;
#endif
  
  socklen_t s_len = sizeof(sock);

  int get;

  if( !side ) /* Local */
    get = getsockname( fd->fd, (struct sockaddr *)  &sock, &s_len );
  else
    get = getpeername( fd->fd, (struct sockaddr *)  &sock, &s_len );
1127
  
1128
1129
  if (get < 0)  
    {               
1130
      werror("io.c: getXXXXname failed %e", errno);
1131
1132
1133
1134
1135
1136
1137
      return NULL;
    }

  return sockaddr2info(s_len,
		       (struct sockaddr *) &sock);
}

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

1155
1156
1157
/* Uses NUL-terminated strings. HOST can be NULL, meaning any address.
 * If PORT is NULL or can't be looked up, and DEFAULT_PORT is non-zero,
 * the DEFAULT_PORT is used. */
1158
unsigned
1159
1160
io_resolv_address(const char *host, const char *service,
		  unsigned default_port,
1161
		  struct sockaddr_list **tail)
1162
{
1163
  unsigned naddresses = 0;
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
  
  /* 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)
  {
    struct addrinfo hints;
    struct addrinfo *list;
    struct addrinfo *p;
    int err;

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

1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
    if (!service || (err = getaddrinfo(host, service, &hints, &list)))
      {
	/* FIXME: It seems ugly to have to convert the port number to
	 * a string. Perhaps we can call getaddrinfo with a NULL or
	 * dummy service and patch in the right port number later? */
	
	struct lsh_string *port = ssh_format("%di", default_port);
	err = getaddrinfo(host, lsh_get_cstring(port), &hints, &list);
	lsh_string_free(port);
      }
    
1191
1192
1193
1194
    if (err)
      {
	debug("io_listen_address: getaddrinfo failed (err = %i): %z\n",
	      err, gai_strerror(err));
1195
	return 0;