int timeoutconn6(int s,const char ip[16],uint16 port,unsigned int scope_id,unsigned int timeout)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;

  if (socket_connect6(s,ip,port,scope_id) == -1) {
    if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) return -1;
    x.fd = s;
    x.events = IOPAUSE_WRITE;
    taia_now(&now);
    taia_uint(&deadline,timeout);
    taia_add(&deadline,&now,&deadline);
    for (;;) {
      taia_now(&now);
      iopause(&x,1,&deadline,&now);
      if (x.revents) break;
      if (taia_less(&deadline,&now)) {
	errno = ETIMEDOUT; /* note that connect attempt is continuing */
	return -1;
      }
    }
    if (!socket_connected(s)) return -1;
  }

  if (ndelay_off(s) == -1) return -1;
  return 0;
}
Пример #2
0
static int make_connection(char* ip,uint16 port,uint32 scope_id,int s) {
  int v6=byte_diff(ip,12,V4mappedprefix);
  if (v6) {
    if (s==-1) {
      s=socket_tcp6();
      if (s==-1) return -1;
    }
    if (socket_connect6(s,ip,port,scope_id)==-1) {
      if (errno==EAGAIN || errno==EINPROGRESS || errno==EISCONN)
	return s;
      ++kaputt;
      if (errno!=ECONNREFUSED && errno!=ECONNRESET)
	carpsys("socket_connect6");
      close(s);
      return -1;
    }
  } else {
    if (s==-1) {
      s=socket_tcp4();
      if (s==-1) return -1;
    }
    if (socket_connect4(s,ip+12,port)==-1) {
      if (errno==EAGAIN || errno==EINPROGRESS || errno==EISCONN)
	return s;
      ++kaputt;
      if (errno!=ECONNREFUSED && errno!=ECONNRESET)
	carpsys("socket_connect6");
      close(s);
      return -1;
    }
  }
  return s;
}
Пример #3
0
static void handle_reconnects( void ) {
  int i;
  for( i=0; i<g_connection_count; ++i )
    if( PROXYPEER_NEEDSCONNECT( g_connections[i].state ) ) {
      int64 newfd = socket_tcp6( );
      fprintf( stderr, "(Re)connecting to peer..." );
      if( newfd < 0 ) continue; /* No socket for you */
      io_fd(newfd);
      if( socket_bind6_reuse(newfd,g_serverip,g_serverport,0) ) {
        io_close( newfd );
        continue;
      }
      if( socket_connect6(newfd,g_connections[i].ip,g_connections[i].port,0) == -1 &&
          errno != EINPROGRESS && errno != EWOULDBLOCK ) {
        close(newfd);
        continue;
      }
      io_wantwrite(newfd); /* So we will be informed when it is connected */
      io_setcookie(newfd,g_connections+i);

      /* Prepare connection info block */
      reset_info_block( g_connections+i );
      g_connections[i].fd            = newfd;
      PROXYPEER_SETCONNECTING( g_connections[i].state );
    }
  g_connection_reconn = time(NULL) + 30;
}
Пример #4
0
static int make_connection(char* ip,uint16 port,uint32 scope_id) {
  int v6=byte_diff(ip,12,V4mappedprefix);
  int s;
  if (v6) {
    s=socket_tcp6();
    if (s==-1)
      panic("socket_tcp6()");
    ndelay_off(s);
    if (bindport) {
      for (;;) {
	int r=socket_bind6_reuse(s,V6any,bindport,0);
	if (++bindport<1024) bindport=1024;
	if (r==0) break;
	if (errno!=EADDRINUSE)
	  panic("socket_bind6");
      }
    }
    if (socket_connect6(s,ip,port,scope_id)==-1) {
      carp("socket_connect6");
      close(s);
      return -1;
    }
  } else {
    s=socket_tcp4();
    if (s==-1)
      panic("socket_tcp4()");
    ndelay_off(s);
    if (bindport) {
      for (;;) {
	int r=socket_bind4_reuse(s,V6any,bindport);
	if (++bindport<1024) bindport=1024;
	if (r==0) break;
	if (errno!=EADDRINUSE)
	  panic("socket_bind4");
      }
    }
    if (socket_connect4(s,ip+12,port)==-1) {
      carp("socket_connect4");
      close(s);
      return -1;
    }
  }
  return s;
}
Пример #5
0
static int thisudp(struct dns_transmit *d)
{
  const char *ip;

  socketfree(d);

  while (d->udploop < 4) {
    for (;d->curserver < 16;++d->curserver) {
      ip = d->servers + 16 * d->curserver;
      if (byte_diff(ip,16,V6any)) {
	d->query[2] = dns_random(256);
	d->query[3] = dns_random(256);
  
        d->s1 = 1 + socket_udp6();
        if (!d->s1) { dns_transmit_free(d); return -1; }
	if (randombind(d) == -1) { dns_transmit_free(d); return -1; }

        if (socket_connect6(d->s1 - 1,ip,53,d->scope_id) == 0)
          if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) {
            struct taia now;
            taia_now(&now);
            taia_uint(&d->deadline,timeouts[d->udploop]);
            taia_add(&d->deadline,&d->deadline,&now);
            d->tcpstate = 0;
            return 0;
          }
  
        socketfree(d);
      }
    }

    ++d->udploop;
    d->curserver = 0;
  }

  dns_transmit_free(d); return -1;
}
Пример #6
0
static int thistcp(struct dns_transmit *d)
{
  struct taia now;
  const char *ip;

  socketfree(d);
  packetfree(d);

  for (;d->curserver < 16;++d->curserver) {
    ip = d->servers + 16 * d->curserver;
    if (byte_diff(ip,16,V6any)) {
      d->query[2] = dns_random(256);
      d->query[3] = dns_random(256);

      d->s1 = 1 + socket_tcp6();
      if (!d->s1) { dns_transmit_free(d); return -1; }
      if (randombind(d) == -1) { dns_transmit_free(d); return -1; }
  
      taia_now(&now);
      taia_uint(&d->deadline,10);
      taia_add(&d->deadline,&d->deadline,&now);
      if (socket_connect6(d->s1 - 1,ip,53,d->scope_id) == 0) {
        d->tcpstate = 2;
        return 0;
      }
      if ((errno == error_inprogress) || (errno == error_wouldblock)) {
        d->tcpstate = 1;
        return 0;
      }
  
      socketfree(d);
    }
  }

  dns_transmit_free(d); return -1;
}
int socket_deadlineconnstamp6 (int s, char const *ip, uint16 port, struct taia const *deadline, struct taia *stamp)
{
  if (socket_connect6(s, ip, port) >= 0) return 1 ;
  if (!error_isagain(errno) && !error_isalready(errno)) return 0 ;
  return socket_waitconn(s, deadline, stamp) ;
}
Пример #8
0
int
main(int argc, char* argv[]) {
  int s;
  uint16 port = 2342;
  uint32 scope_id = 0;
  char ip[16];
  char buf[8192];
  int i;
  struct pollfd p[2];

  if(argc < 3) {
  usage:
    __write2("usage: client ip port\n\nexample: dump -0 -f - | client 10.0.0.149 8000\n");
    return 0;
  }
  if(argv[1][i = scan_ip6if(argv[1], ip, &scope_id)]) {
    __write2("client: error: invalid ip address!\n");
    goto usage;
  }
  if(argv[2][scan_ushort(argv[2], &port)]) {
    __write2("client: error: invalid port number!\n");
    goto usage;
  }
  if(byte_equal(ip, 12, V4mappedprefix)) {
    s = socket_tcp4b();
    if(s == -1)
      panic("client: error: socket() failed");
    if(socket_connect4(s, ip + 12, port) == -1)
      panic("client: error: connect() failed");
  } else {
    s = socket_tcp6b();
    if(s == -1)
      panic("client: error: socket() failed");
    if(socket_connect6(s, ip, port, scope_id) == -1)
      panic("client: error: connect() failed");
  }
  ndelay_off(s);
  p[0].fd = 0;
  p[0].events = POLLIN;
  p[1].fd = s;
  p[1].events = POLLIN;
  while(poll(p, 2, 5000)) {
    if(p[0].revents) {
      int j;
      if(p[0].revents & POLLERR)
        panic("client: error: poll() signals POLLERR\n");
      i = read(0, buf, sizeof(buf));
      if(i == 0) {
        shutdown(s, SHUT_WR);
        blockingcopy(s, 1);
      }
      for(j = 0; j < i;) {
        int k = write(s, buf + j, i - j);
        if(k == -1)
          panic("client: error: write() failed");
        if(k == 0)
          panic("client: error: short write!\n");
        j += k;
      }
    }
    if(p[1].revents) {
      int j;
      if(p[1].revents & POLLERR)
        panic("client: error: poll() signals POLLERR\n");
      i = read(s, buf, sizeof(buf));
      if(i == 0) {
        shutdown(1, SHUT_WR);
        blockingcopy(0, s);
      }
      for(j = 0; j < i;) {
        int k = write(1, buf + j, i - j);
        if(k == -1)
          panic("client: error: write() failed");
        if(k == 0)
          panic("client: error: short write!\n");
        j += k;
      }
    }
  }
  return 0;
}
Пример #9
0
int
main(int argc, char* argv[]) {
  int s = socket_tcp6();
  uint32 scope_id;
  char ip[16];
  uint16 port;
  char hisip[16];
  uint16 hisport;
  uint32 hisscope_id;
  static char seed[128];
  static stralloc fqdn;
  static stralloc out;

  if(argc != 4) {
  usage:
    buffer_putsflush(buffer_2,
                     "usage: proxy myip myport hisip hisport\n"
                     "\n"
                     "e.g.: proxy 0 119 news.fu-berlin.de 119\n");
    return 0;
  }

  if(argv[1][scan_ip6if(argv[1], ip, &scope_id)]) {
    if(str_equal(argv[1], "0")) {
      byte_zero(ip, 16);
      scope_id = 0;
    } else
      goto usage;
  }
  if(argv[2][scan_ushort(argv[2], &port)])
    goto usage;
  if(argv[3][scan_ip6if(argv[3], hisip, &hisscope_id)]) {
    dns_random_init(seed);
    if(!stralloc_copys(&fqdn, argv[3]))
      goto nomem;
    if(dns_ip4(&out, &fqdn) == -1) {
      buffer_puts(buffer_2, "unable to find IP address for ");
      buffer_puts(buffer_2, argv[3]);
      buffer_puts(buffer_2, ": ");
      buffer_puterror(buffer_2);
      buffer_putnlflush(buffer_2);
      return 111;
    }
  } else if(!stralloc_catb(&out, hisip, 16)) {
  nomem:
    buffer_putsflush(buffer_2, "out of memory\n");
    return 111;
  }
  if(argv[4][scan_ushort(argv[4], &hisport)])
    goto usage;

  if(socket_bind6_reuse(s, ip, port, scope_id) == -1) {
    buffer_puts(buffer_2, "socket_bind6_reuse: ");
    buffer_puterror(buffer_2);
    buffer_putnlflush(buffer_2);
    return 111;
  }
  if(socket_listen(s, 16) == -1) {
    buffer_puts(buffer_2, "socket_listen: ");
    buffer_puterror(buffer_2);
    buffer_putnlflush(buffer_2);
    return 111;
  }
  if(!io_fd(s)) {
    buffer_puts(buffer_2, "io_fd: ");
    buffer_puterror(buffer_2);
    buffer_putnlflush(buffer_2);
    return 111;
  }
  io_wantread(s);
  for(;;) {
    int64 i;
    io_wait();
    while((i = io_canread()) != -1) {
      if(i == s) {
        /* the read event is on the server socket */
        /* that means it's an incoming connection */
        int n;
        while((n = socket_accept6(s, ip, &port, &scope_id)) != -1) {
          int x = socket_tcp6();
          if(x == -1) {
            buffer_puts(buffer_2, "socket_tcp6 failed: ");
          fail:
            buffer_puterror(buffer_2);
            buffer_putnlflush(buffer_2);
            io_close(n);
          } else {
            struct state* s = malloc(sizeof(struct state));
            if(!s)
              goto closefail;
            s->a = n;
            s->b = x;
            s->connected = 0;
            s->done = s->todo = 0;
            s->dir = UNDECIDED;
            io_nonblock(x);
            socket_connect6(x, out.s, hisport, hisscope_id);
            if(!io_fd(x) || !io_fd(n)) {
              buffer_puts(buffer_2, "io_fd failed: ");
            closefail:
              free(s);
              io_close(x);
              goto fail;
            }
            io_setcookie(x, s);
            io_setcookie(n, s);
            io_wantwrite(x);
          }
        }
        if(errno != EAGAIN) {
          buffer_puts(buffer_2, "socket_accept6 failed: ");
          buffer_puterror(buffer_2);
          buffer_putnlflush(buffer_2);
        }
      } else {
        /* read event on an established connection */
        struct state* s = io_getcookie(i);
        int l = io_tryread(i, s->buf, sizeof(s->buf));
        if(l == -1) {
          buffer_puts(buffer_2, "io_tryread(");
          buffer_putulong(buffer_2, i);
          buffer_puts(buffer_2, "): ");
          buffer_puterror(buffer_2);
          buffer_putnlflush(buffer_2);
          io_close(s->a);
          io_close(s->b);
        } else if(l == 0) {
          buffer_puts(buffer_2, "eof on fd #");
          buffer_putulong(buffer_2, i);
          buffer_putnlflush(buffer_2);
          io_close(i);
        } else {
          int r;
          switch(r = io_trywrite(i, s->buf, l)) {
            case -1:
              buffer_puts(buffer_2, "io_tryread(");
              buffer_putulong(buffer_2, i);
              buffer_puts(buffer_2, "): ");
              buffer_puterror(buffer_2);
              buffer_putnlflush(buffer_2);
              io_close(i);
              break;
            case 0:
              buffer_puts(buffer_2, "write eof on fd #");
              buffer_putulong(buffer_2, i);
              buffer_putnlflush(buffer_2);
              io_close(i);
            default:
              if(r != l) {
                buffer_puts(buffer_2, "short write on fd #");
                buffer_putulong(buffer_2, i);
                buffer_puts(buffer_2, ": wrote ");
                buffer_putulong(buffer_2, r);
                buffer_puts(buffer_2, ", wanted to write ");
                buffer_putulong(buffer_2, l);
                buffer_putsflush(buffer_2, ").\n");
              }
          }
        }
      }
    }
  }
  return 0;
}