Exemplo n.º 1
0
int
dns_resolve (const char *q, const char qtype[2])
{
    int r = 0;
    char servers[64];
    iopause_fd x[1];

    struct taia stamp;
    struct taia deadline;

    if (dns_resolvconfip (servers) == -1)
        return -1;

    memset (&dns_resolve_tx, 0, sizeof (dns_resolve_tx));
    r = dns_transmit_start (&dns_resolve_tx, servers, 1, q, qtype, "\0\0\0\0");
    if (r == -1)
        return -1;

    for (;;)
    {
        taia_now (&stamp);
        taia_uint (&deadline, 120);
        taia_add (&deadline, &deadline, &stamp);

        dns_transmit_io (&dns_resolve_tx, x, &deadline);
        iopause (x, 1, &deadline, &stamp);

        r = dns_transmit_get (&dns_resolve_tx, x, &stamp);
        if (r == -1)
            return -1;
        if (r == 1)
            return 0;
    }
}
Exemplo n.º 2
0
static void handle_accept( const int64 serversocket ) {
  struct http_data *h;
  unsigned char ip[4];
  uint16 port;
  tai6464 t;
  int64 i;

  while( ( i = socket_accept4( serversocket, (char*)ip, &port) ) != -1 ) {

    /* Put fd into a non-blocking mode */
    io_nonblock( i );

    if( !io_fd( i ) ||
        !( h = (struct http_data*)malloc( sizeof( struct http_data ) ) ) ) {
      io_close( i );
      continue;
    }
    io_setcookie( i, h );
    io_wantread( i );

    memset( h, 0, sizeof( struct http_data ) );
    memmove( h->ip, ip, sizeof( ip ) );

    stats_issue_event( EVENT_ACCEPT, 1, ntohl(*(uint32_t*)ip));

    /* That breaks taia encapsulation. But there is no way to take system
       time this often in FreeBSD and libowfat does not allow to set unix time */
    taia_uint( &t, 0 ); /* Clear t */
    tai_unix( &(t.sec), (g_now + OT_CLIENT_TIMEOUT) );
    io_timeout( i, t );
  }

  if( errno == EAGAIN )
    io_eagain( serversocket );
}
Exemplo n.º 3
0
int timeoutconn(int s,char ip[4],uint16 port,unsigned int timeout)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;

  if (socket_connect4(s,ip,port) == -1) {
    if ((errno != error_wouldblock) && (errno != error_inprogress)) 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 = error_timeout; /* note that connect attempt is continuing */
	    return -1;
      }
    }
    if (!socket_connected(s)) return -1;
  }

  if (ndelay_off(s) == -1) return -1;
  return 0;
}
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;
}
Exemplo n.º 5
0
void t_timeout(int j)
{
  struct taia now;
  if (!t[j].active) return;
  taia_now(&now);
  taia_uint(&t[j].timeout,10);
  taia_add(&t[j].timeout,&t[j].timeout,&now);
}
Exemplo n.º 6
0
static int
thistcp (struct dns_transmit *d)
{
    struct taia now;
    const char *ip = NULL;

    socketfree (d);
    packetfree (d);

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

            d->s1 = 1 + socket_tcp ();
            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_connect4 (d->s1 - 1, ip, 53) == 0)
            {
                d->pos = 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;
}
Exemplo n.º 7
0
int resolve(char *q,char qtype[2],char ip[16])
{
  struct taia start;
  struct taia stamp;
  struct taia deadline;
  char servers[256];
  iopause_fd x[1];
  int r;

  taia_now(&start);

  byte_zero(servers,256);
  byte_copy(servers,16,ip);

  if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1;

  for (;;) {
    taia_now(&stamp);
    taia_uint(&deadline,120);
    taia_add(&deadline,&deadline,&stamp);
    dns_transmit_io(&tx,x,&deadline);
    iopause(x,1,&deadline,&stamp);
    r = dns_transmit_get(&tx,x,&stamp);
    if (r == -1) return -1;
    if (r == 1) break;
  }

  taia_now(&stamp);
  taia_sub(&stamp,&stamp,&start);
  taia_uint(&deadline,1);
  if (taia_less(&deadline,&stamp)) {
    buffer_put(buffer_1,querystr.s,querystr.len);
    buffer_puts(buffer_1,"ALERT:took more than 1 second\n");
  }

  return 0;
}
Exemplo n.º 8
0
static ssize_t http_handle_fullscrape( const int64 sock, struct ot_workstruct *ws ) {
  struct http_data* cookie = io_getcookie( sock );
  int format = 0;
  tai6464 t;

#ifdef WANT_MODEST_FULLSCRAPES
  {
    ot_scrape_log this_peer, *new_peer;
    int exactmatch;
    memcpy( this_peer.ip, cookie->ip, sizeof(ot_ip6));
    this_peer.last_fullscrape = g_now_seconds;
    pthread_mutex_lock(&g_modest_fullscrape_mutex);
    new_peer = vector_find_or_insert( &g_modest_fullscrape_timeouts, &this_peer, sizeof(ot_scrape_log), sizeof(ot_ip6), &exactmatch );
    if( !new_peer ) {
      pthread_mutex_unlock(&g_modest_fullscrape_mutex);
      HTTPERROR_500;
    }
    if( exactmatch && ( this_peer.last_fullscrape - new_peer->last_fullscrape ) < OT_MODEST_PEER_TIMEOUT ) {
      pthread_mutex_unlock(&g_modest_fullscrape_mutex);
      HTTPERROR_402_NOTMODEST;
    }
    memcpy( new_peer, &this_peer, sizeof(ot_scrape_log));
    pthread_mutex_unlock(&g_modest_fullscrape_mutex);
  }
#endif

#ifdef WANT_COMPRESSION_GZIP
  ws->request[ws->request_size-1] = 0;
  if( strstr( ws->request, "gzip" ) ) {
    cookie->flag |= STRUCT_HTTP_FLAG_GZIP;
    format = TASK_FLAG_GZIP;
    stats_issue_event( EVENT_FULLSCRAPE_REQUEST_GZIP, 0, (uintptr_t)cookie->ip );
  } else
#endif
    stats_issue_event( EVENT_FULLSCRAPE_REQUEST, 0, (uintptr_t)cookie->ip );

#ifdef _DEBUG_HTTPERROR
  fprintf( stderr, "%s", ws->debugbuf );
#endif

  /* Pass this task to the worker thread */
  cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
  /* Clients waiting for us should not easily timeout */
  taia_uint( &t, 0 ); io_timeout( sock, t );
  fullscrape_deliver( sock, TASK_FULLSCRAPE | format );
  io_dontwantread( sock );
  return ws->reply_size = -2;
}
Exemplo n.º 9
0
int remoteinfo6(stralloc *out,char ipremote[16],uint16 portremote,char iplocal[16],uint16 portlocal,unsigned int timeout,uint32 netif)
{
  int s;
  int r;

  if (!stralloc_copys(out,"")) return -1;

  taia_now(&now);
  taia_uint(&deadline,timeout);
  taia_add(&deadline,&now,&deadline);

  s = socket_tcp6();
  if (s == -1) return -1;
  r = doit(out,s,ipremote,portremote,iplocal,portlocal,timeout,netif);
  close(s);
  return r;
}
Exemplo n.º 10
0
static void http_senddata( const int64 sock, struct ot_workstruct *ws ) {
  struct http_data *cookie = io_getcookie( sock );
  ssize_t written_size;

  if( !cookie ) { io_close(sock); return; }

  /* whoever sends data is not interested in its input-array */
  if( ws->keep_alive && ws->header_size != ws->request_size ) {
    size_t rest = ws->request_size - ws->header_size;
    if( array_start(&cookie->request) ) {
      memmove( array_start(&cookie->request), ws->request + ws->header_size, rest );
      array_truncate( &cookie->request, 1, rest );
    } else
      array_catb(&cookie->request, ws->request + ws->header_size, rest );    
  } else
    array_reset( &cookie->request );

  written_size = write( sock, ws->reply, ws->reply_size );
  if( ( written_size < 0 ) || ( ( written_size == ws->reply_size ) && !ws->keep_alive ) ) {
    array_reset( &cookie->request );
    free( cookie ); io_close( sock ); return;
  }

  if( written_size < ws->reply_size ) {
    char * outbuf;
    tai6464 t;

    if( !( outbuf = malloc( ws->reply_size - written_size ) ) ) {
      array_reset( &cookie->request );
      free(cookie); io_close( sock );
      return;
    }

    memcpy( outbuf, ws->reply + written_size, ws->reply_size - written_size );
    iob_addbuf_free( &cookie->batch, outbuf, ws->reply_size - written_size );

    /* writeable short data sockets just have a tcp timeout */
    if( !ws->keep_alive ) {
      taia_uint( &t, 0 ); io_timeout( sock, t );
      io_dontwantread( sock );
    }
    io_wantwrite( sock );
  }
}
Exemplo n.º 11
0
int ssl_timeoutaccept(SSL *ssl,unsigned int timeout)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;
  int r;
  int rfd;
  int wfd;

  taia_now(&now);
  taia_uint(&deadline,timeout);
  taia_add(&deadline,&now,&deadline);

  rfd = SSL_get_fd(ssl); /* XXX */
  wfd = SSL_get_fd(ssl); /* XXX */

  SSL_set_accept_state(ssl);

  for (;;) {
    r = SSL_accept(ssl);
    if (r == 1) return 0;
    ssl_errno = SSL_get_error(ssl,r);
    errno = error_proto;
    if ((ssl_errno != SSL_ERROR_WANT_READ) && (ssl_errno != SSL_ERROR_WANT_WRITE))
      return -1;
    if (ssl_errno == SSL_ERROR_WANT_READ) {
      x.events = IOPAUSE_READ;
      x.fd = rfd;
      if (x.fd == -1) return -1;
    }
    else {
      x.events = IOPAUSE_WRITE;
      x.fd = wfd;
      if (x.fd == -1) return -1;
    }
    for (;;) {
      taia_now(&now);
      iopause(&x,1,&deadline,&now);
      if (x.revents) break;
      if (taia_less(&deadline,&now))
	return -1;
    }
  }
}
Exemplo n.º 12
0
int dns_resolvconfip(char s[64])
{
  struct taia now;

  taia_now(&now);
  if (taia_less(&deadline,&now)) ok = 0;
  if (!uses) ok = 0;

  if (!ok) {
    if (init(ip) == -1) return -1;
    taia_uint(&deadline,600);
    taia_add(&deadline,&now,&deadline);
    uses = 10000;
    ok = 1;
  }

  --uses;
  byte_copy(s,64,ip);
  return 0;
}
Exemplo n.º 13
0
int dns_resolvconfrewrite(stralloc *out)
{
  struct taia now;

  taia_now(&now);
  if (taia_less(&deadline,&now)) ok = 0;
  if (!uses) ok = 0;

  if (!ok) {
    if (init(&rules) == -1) return -1;
    taia_uint(&deadline,600);
    taia_add(&deadline,&now,&deadline);
    uses = 10000;
    ok = 1;
  }

  --uses;
  if (!stralloc_copy(out,&rules)) return -1;
  return 0;
}
Exemplo n.º 14
0
int dns_resolve(const char *q,const char qtype[2])
{
  struct taia stamp;
  struct taia deadline;
  char servers[256];
  iopause_fd x[1];
  int r;

  if (dns_resolvconfip(servers) == -1) return -1;
  if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,V6any) == -1) return -1;

  for (;;) {
    taia_now(&stamp);
    taia_uint(&deadline,120);
    taia_add(&deadline,&deadline,&stamp);
    dns_transmit_io(&dns_resolve_tx,x,&deadline);
    iopause(x,1,&deadline,&stamp);
    r = dns_transmit_get(&dns_resolve_tx,x,&stamp);
    if (r == -1) return -1;
    if (r == 1) return 0;
  }
}
Exemplo n.º 15
0
int resolve(char *q,char qtype[2],char servers[256])
{
  struct taia stamp;
  struct taia deadline;
  iopause_fd x[1];
  int r;

  if (dns_transmit_start(&tx,servers,0,q,qtype,V6any) == -1) return -1;

  for (;;) {
    taia_now(&stamp);
    taia_uint(&deadline,120);
    taia_add(&deadline,&deadline,&stamp);
    dns_transmit_io(&tx,x,&deadline);
    iopause(x,1,&deadline,&stamp);
    r = dns_transmit_get(&tx,x,&stamp);
    if (r == -1) return -1;
    if (r == 1) break;
  }

  return 0;
}
Exemplo n.º 16
0
int timeoutwrite(int t,int fd,const char *buf,int len)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;

  taia_now(&now);
  taia_uint(&deadline,t);
  taia_add(&deadline,&now,&deadline);

  x.fd = fd;
  x.events = IOPAUSE_WRITE;
  for (;;) {
    taia_now(&now);
    iopause(&x,1,&deadline,&now);
    if (x.revents) break;
    if (taia_less(&deadline,&now)) {
      errno = error_timeout;
      return -1;
    }
  }
  return write(fd,buf,len);
}
Exemplo n.º 17
0
int timeoutread(int t,int fd,char *buf,int len)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;

  taia_now(&now);
  taia_uint(&deadline,t);
  taia_add(&deadline,&now,&deadline);

  x.fd = fd;
  x.events = IOPAUSE_READ;
  for (;;) {
    taia_now(&now);
    iopause(&x,1,&deadline,&now);
    if (x.revents) break;
    if (taia_less(&deadline,&now)) {
      errno = ETIMEDOUT;
      return -1;
    }
  }
  return read(fd,buf,len);
}
Exemplo n.º 18
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 + 4 * d->curserver;
      if (byte_diff(ip,4,"\0\0\0\0")) {
	d->query[2] = dns_random(256);
	d->query[3] = dns_random(256);
  
        d->s1 = 1 + socket_udp();
        if (!d->s1) { dns_transmit_free(d); return -1; }
	if (randombind(d) == -1) { dns_transmit_free(d); return -1; }

        if (socket_connect4(d->s1 - 1,ip,53) == 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;
}
int timeoutaccept6(int s,char ip[16],uint16 *port,unsigned int timeout,uint32 *scope_id)
{
  struct taia now;
  struct taia deadline;
  iopause_fd x;

  x.fd = s;
  x.events = IOPAUSE_READ;
  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 socket_accept6(s,ip,port,scope_id);
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
void doio(void) {
  iopause_fd x[2];
  struct taia deadline;
  struct taia now;
  struct taia timeout;

  if (! stralloc_ready(&encinbuf, bufsizein)) die_nomem();
  encin.buf =encin.start =encin.end =encinbuf.s; encin.size =bufsizein;
  if (! stralloc_ready(&decinbuf, bufsizein)) die_nomem();
  decin.buf =decin.start =decin.end =decinbuf.s; decin.size =bufsizein;
  if (! stralloc_ready(&encoubuf, bufsizeou)) die_nomem();
  encou.buf =encou.start =encou.end =encoubuf.s; encou.size =bufsizeou;
  if (! stralloc_ready(&decoubuf, bufsizeou)) die_nomem();
  decou.buf =decou.start =decou.end =decoubuf.s; decou.size =bufsizeou;

  if (client) {
    rc =matrixSslEncodeClientHello(ssl, &decou, 0);
    if (rc != 0) fatalx("unable to encode client hello");
    if (write(fdstdou, decou.start, decou.end -decou.start)
        != (decou.end -decou.start))
      fatal("unable to send client hello");
    if (verbose > 2) info("sending client hello");
    if (verbose > 2) infou("write bytes: ", decou.end -decou.start);
    bytesou +=decou.end -decou.start;
    decou.start =decou.end =decou.buf;
  }

  taia_now(&now);
  taia_uint(&timeout, handshake_timeout);
  taia_add(&timeout, &now, &timeout);

  for (;;) {
    iopause_fd *xx =x;
    int l =2;

    x[0].fd =encpipe[0];
    x[0].events =IOPAUSE_READ;
    x[0].revents =0;
    x[1].fd =fdstdin;
    x[1].events =IOPAUSE_READ;
    x[1].revents =0;

    if ((x[0].fd == -1) || handshake) { --l; ++xx; }
    if (x[1].fd == -1) --l;
    if (! l) return;

    taia_now(&now);
    if (handshake) {
      if (taia_less(&timeout, &now)) {
        if (verbose) info("ssl handshake timeout, exit.");
        return;
      }
      deadline.sec =timeout.sec;
      deadline.nano =timeout.nano;
      deadline.atto =timeout.atto;
    }
    else {
      taia_uint(&deadline, 30);
      taia_add(&deadline, &now, &deadline);
    }
    iopause(xx, l, &deadline, &now);
    
    if (x[0].revents) encode();
    if (x[1].revents) decode();
  }
}
Exemplo n.º 22
0
int main(int argc, char **argv)
{
    struct stat s;
    time_t mtime =0;
    int wstat;
    int curdir;
    int pid;
    struct taia deadline;
    struct taia now;
    struct taia stampcheck;
    char ch;
    int i;

    progname =*argv++;
    if (! argv || ! *argv) usage();
    if (**argv == '-')
    {
        switch (*(*argv +1))
        {
        case 'P':
            pgrp =1;
        case '-':
            ++argv;
        }
        if (! argv || ! *argv) usage();
    }

    sig_catch(sig_term, s_term);
    sig_catch(sig_hangup, s_hangup);
    svdir =*argv++;
    if (argv && *argv)
    {
        rplog =*argv;
        if (setup_log() != 1)
        {
            rplog =0;
            warn3x("log service disabled.", 0, 0);
        }
    }
    if ((curdir =open_read(".")) == -1)
        fatal("unable to open current directory", 0);
    coe(curdir);

    taia_now(&stampcheck);

    for (;;)
    {
        /* collect children */
        for (;;)
        {
            if ((pid =wait_nohang(&wstat)) <= 0) break;
            for (i =0; i < svnum; i++)
            {
                if (pid == sv[i].pid)
                {
                    /* runsv has gone */
                    sv[i].pid =0;
                    check =1;
                    break;
                }
            }
        }

        taia_now(&now);
        if (now.sec.x < (stampcheck.sec.x -3))
        {
            /* time warp */
            warn3x("time warp: resetting time stamp.", 0, 0);
            taia_now(&stampcheck);
            taia_now(&now);
            if (rplog) taia_now(&stamplog);
        }
        if (taia_less(&now, &stampcheck) == 0)
        {
            /* wait at least a second */
            taia_uint(&deadline, 1);
            taia_add(&stampcheck, &now, &deadline);

            if (stat(svdir, &s) != -1)
            {
                if (check || \
                        s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev)
                {
                    /* svdir modified */
                    if (chdir(svdir) != -1)
                    {
                        mtime =s.st_mtime;
                        dev =s.st_dev;
                        ino =s.st_ino;
                        check =0;
                        if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime))
                            sleep(1);
                        runsvdir();
                        while (fchdir(curdir) == -1)
                        {
                            warn("unable to change directory, pausing", 0);
                            sleep(5);
                        }
                    }
                    else
                        warn("unable to change directory to ", svdir);
                }
            }
            else
                warn("unable to stat ", svdir);
        }

        if (rplog)
            if (taia_less(&now, &stamplog) == 0)
            {
                write(logpipe[1], ".", 1);
                taia_uint(&deadline, 900);
                taia_add(&stamplog, &now, &deadline);
            }
        /* half a second */
        deadline.sec.x =0;
        deadline.nano =500000000UL;
        deadline.atto =0;
        taia_add(&deadline, &now, &deadline);

        sig_block(sig_child);
        if (rplog)
            iopause(io, 1, &deadline, &now);
        else
            iopause(0, 0, &deadline, &now);
        sig_unblock(sig_child);

        if (rplog && (io[0].revents | IOPAUSE_READ))
            while (read(logpipe[0], &ch, 1) > 0)
                if (ch)
                {
                    for (i =6; i < rploglen; i++)
                        rplog[i -1] =rplog[i];
                    rplog[rploglen -1] =ch;
                }

        switch(exitsoon)
        {
        case 1:
            _exit(0);
        case 2:
            for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
            _exit(111);
        }
    } /* for (;;) */
    /* not reached */
    _exit(0);
}
Exemplo n.º 23
0
int main(int argc,char **argv)
{
  struct taia stamp;
  struct taia deadline;
  int opt;
  unsigned long u;
  int i;
  int j;
  int r;

  while ((opt = getopt(argc,argv,"c:l:")) != opteof)
    switch(opt) {
      case 'c':
	scan_ulong(optarg,&u);
	if (u < 1) u = 1;
	if (u > 1000) u = 1000;
	maxactive = u;
	break;
      case 'l':
	scan_ulong(optarg,&u);
	if (u < 1) u = 1;
	if (u > 1000000) u = 1000000;
	xmax = u;
	break;
      default:
	strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]");
    }

  x = (struct line *) alloc(xmax * sizeof(struct line));
  if (!x) nomem();
  byte_zero(x,xmax * sizeof(struct line));

  io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd)); 
  if (!io) nomem();

  if (!stralloc_copys(&partial,"")) nomem();


  while (flag0 || inbuflen || partial.len || xnum) {
    taia_now(&stamp);
    taia_uint(&deadline,120);
    taia_add(&deadline,&deadline,&stamp);

    iolen = 0;

    if (flag0)
      if (inbuflen < sizeof inbuf) {
        inio = io + iolen++;
        inio->fd = 0;
        inio->events = IOPAUSE_READ;
      }

    for (i = 0;i < xnum;++i)
      if (x[i].flagactive) {
	x[i].io = io + iolen++;
	dns_transmit_io(&x[i].dt,x[i].io,&deadline);
      }

    iopause(io,iolen,&deadline,&stamp);

    if (flag0)
      if (inbuflen < sizeof inbuf)
        if (inio->revents) {
	  r = read(0,inbuf + inbuflen,(sizeof inbuf) - inbuflen);
	  if (r <= 0)
	    flag0 = 0;
	  else
	    inbuflen += r;
        }
    
    for (i = 0;i < xnum;++i)
      if (x[i].flagactive) {
	r = dns_transmit_get(&x[i].dt,x[i].io,&stamp);
	if (r == -1) {
	  errout(i);
	  x[i].flagactive = 0;
	  --numactive;
	}
	else if (r == 1) {
	  if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1)
	    errout(i);
	  if (x[i].middle.len)
	    if (!stralloc_cats(&x[i].left,"=")) nomem();
	  x[i].flagactive = 0;
	  --numactive;
	}
      }

    for (;;) {

      if (xnum && !x[0].flagactive) {
        buffer_put(buffer_1,x[0].left.s,x[0].left.len);
        buffer_put(buffer_1,x[0].middle.s,x[0].middle.len);
        buffer_put(buffer_1,x[0].right.s,x[0].right.len);
        buffer_flush(buffer_1);
        --xnum;
        tmp = x[0];
        for (i = 0;i < xnum;++i) x[i] = x[i + 1];
        x[xnum] = tmp;
	continue;
      }

      if ((xnum < xmax) && (numactive < maxactive)) {
        i = byte_chr(inbuf,inbuflen,'\n');
        if (inbuflen && (i == inbuflen)) {
	  if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem();
	  inbuflen = 0;
	  continue;
        }

	if ((i < inbuflen) || (!flag0 && partial.len)) {
	  if (i < inbuflen) ++i;
	  if (!stralloc_catb(&partial,inbuf,i)) nomem();
	  inbuflen -= i;
	  for (j = 0;j < inbuflen;++j) inbuf[j] = inbuf[j + i];
  
	  if (partial.len) {
	    i = byte_chr(partial.s,partial.len,'\n');
	    i = byte_chr(partial.s,i,'\t');
	    i = byte_chr(partial.s,i,' ');
    
	    if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem();
	    if (!stralloc_copys(&x[xnum].middle,"")) nomem();
	    if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem();
	    x[xnum].flagactive = 0;
  
	    partial.len = i;
	    if (!stralloc_0(&partial)) nomem();
	    if (ip4_scan(partial.s,ip)) {
	      dns_name4_domain(name,ip);
	      if (dns_resolvconfip(servers) == -1)
	        strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: ");
	      if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1)
	        errout(xnum);
	      else {
	        x[xnum].flagactive = 1;
	        ++numactive;
	      }
	    }
	    ++xnum;
	  }
  
	  partial.len = 0;
	  continue;
	}
      }

      break;
    }
  }

  _exit(0);
}
Exemplo n.º 24
0
int
main (int argc, char *argv[])
{
    time_t t = 0;
    char *x = NULL;
    struct sigaction sa;
    iopause_fd *iop = NULL;
    int i = 0, n = 0, *udp53 = NULL;

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]);

    sa.sa_handler = handle_term;
    sigaction (SIGINT, &sa, NULL);
    sigaction (SIGTERM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction (SIGPIPE, &sa, NULL);

    i = check_option (argc, argv);
    argc -= i;
    argv += i;

    if (mode & DAEMON)
    {
        i = fork ();
        if (i == -1)
            err (-1, "could not fork a daemon process");
        if (i > 0)
            return 0;
    }

    time (&t);
    memset (buf, 0, sizeof (buf));
    strftime (buf, sizeof (buf), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting: %s\n", VERSION, buf);

    set_timezone ();
    if (debug_level)
        warnx ("TIMEZONE: %s", env_get ("TZ"));

    initialize ();
    if (!debug_level)
        if ((x = env_get ("DEBUG_LEVEL")))
            debug_level = atol (x);
    warnx ("DEBUG_LEVEL set to `%d'", debug_level);

    if ((x = env_get ("DATALIMIT")))
    {
        struct rlimit r;
        unsigned long dlimit = atol (x);

        if (getrlimit (RLIMIT_DATA,  &r) != 0)
            err (-1, "could not get resource RLIMIT_DATA");

        r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max;

        if (setrlimit (RLIMIT_DATA, &r) != 0)
            err (-1, "could not set resource RLIMIT_DATA");

        if (debug_level)
            warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur);
    }

    if (!(x = env_get ("IP")))
        err (-1, "$IP not set");
    for (i = 0; (unsigned)i < strlen (x); i++)
        n = (x[i] == ',') ? n+1 : n;
    if (!(udp53 = calloc (n+1, sizeof (int))))
        err (-1, "could not allocate enough memory for udp53");
    if (!(iop = calloc (n+1, sizeof (iopause_fd))))
        err (-1, "could not allocate enough memory for iop");

    i = n = 0;
    while (x[i])
    {
        unsigned int l = 0;

        if (!(l = ip4_scan(x+i, ip)))
            errx (-1, "could not parse IP address `%s'", x + i);

        udp53[n] = socket_udp();
        if (udp53[n] == -1)
            errx (-1, "could not open UDP socket");
        if (socket_bind4_reuse (udp53[n], ip, server_port) == -1)
            errx (-1, "could not bind UDP socket");

        ndelay_off (udp53[n]);
        socket_tryreservein (udp53[n], 65536);

        iop[n].fd = udp53[n];
        iop[n].events = IOPAUSE_READ;

        n++;
        i += (x[i + l] == ',') ? l + 1 : l;
    }

    droproot ();
    while (1)
    {
        struct taia stamp;
        struct in_addr odst; /* original destination IP */
        struct taia deadline;

        taia_now (&stamp);
        taia_uint (&deadline, 300);
        taia_add (&deadline, &deadline, &stamp);
        iopause (iop, n, &deadline, &stamp);

        for (i = 0; i < n; i++)
        {
            if (!iop[i].revents)
                continue;

            len = socket_recv4 (udp53[i], buf, sizeof (buf), ip, &port, &odst);
            if (len < 0)
                continue;
            if (!doit ())
                continue;
            if (response_len > 512)
                response_tc ();

            /* may block for buffer space; if it fails, too bad */
            len = socket_send4 (udp53[i], response,
                                response_len, ip, port, &odst);
            if (len < 0)
                continue;
            if (debug_level > 1)
                log_querydone(qnum, response, response_len);
        }
    }

    return 0;
}
Exemplo n.º 25
0
static void
doit (void)
{
    struct taia stamp;
    struct taia deadline;
    int j = 0, r = 0, iolen = 0;

    for (;;)
    {
        taia_now (&stamp);
        taia_uint (&deadline, 120);
        taia_add (&deadline, &deadline, &stamp);

        iolen = 0;
        udp53io = io + iolen++;
        udp53io->fd = udp53;
        udp53io->events = IOPAUSE_READ;

        tcp53io = io + iolen++;
        tcp53io->fd = tcp53;
        tcp53io->events = IOPAUSE_READ;

        for (j = 0; j < MAXUDP; ++j)
        {
            if (u[j].active)
            {
                u[j].io = io + iolen++;
                query_io (&u[j].q, u[j].io, &deadline);
            }
        }

        for (j = 0; j < MAXTCP; ++j)
        {
            if (t[j].active)
            {
                t[j].io = io + iolen++;
                if (t[j].state == 0)
                    query_io (&t[j].q, t[j].io, &deadline);
                else
                {
                    if (taia_less (&t[j].timeout, &deadline))
                        deadline = t[j].timeout;
                    t[j].io->fd = t[j].tcp;
                    t[j].io->events = (t[j].state > 0) ?
                                            IOPAUSE_READ : IOPAUSE_WRITE;
                }
            }
        }
        iopause (io, iolen, &deadline, &stamp);

        for (j = 0; j < MAXUDP; ++j)
        {
            if (u[j].active)
            {
                r = query_get (&u[j].q, u[j].io, &stamp);
                if (r == -1)
                    u_drop (j);
                if (r == 1)
                    u_respond (j);
            }
        }
        for (j = 0; j < MAXTCP; ++j)
        {
            if (t[j].active)
            {
                if (t[j].io->revents)
                    t_timeout (j);
                if (t[j].state == 0)
                {
                    r = query_get (&t[j].q, t[j].io, &stamp);
                    if (r == -1)
                        t_drop (j);
                    if (r == 1)
                        t_respond (j);
                }
                else
                    if (t[j].io->revents || taia_less (&t[j].timeout, &stamp))
                        t_rw (j);
            }
        }

        if (udp53io && udp53io->revents)
                u_new();

        if (tcp53io && tcp53io->revents)
                t_new();
    }
}
Exemplo n.º 26
0
void doit(int fdleft,int fdright) /* copy 0 -> fdleft, copy fdright -> 1 */
{
  struct taia stamp;
  struct taia deadline;
  iopause_fd x[4];
  int xlen;
  iopause_fd *io0;
  iopause_fd *ioleft;
  iopause_fd *io1;
  iopause_fd *ioright;
  int r;

  for (;;) {
    xlen = 0;

    io0 = 0;
    if (leftstatus == 0) {
      io0 = &x[xlen++];
      io0->fd = 0;
      io0->events = IOPAUSE_READ;
    }
    ioleft = 0;
    if (leftstatus == 1) {
      ioleft = &x[xlen++];
      ioleft->fd = fdleft;
      ioleft->events = IOPAUSE_WRITE;
    }

    ioright = 0;
    if (rightstatus == 0) {
      ioright = &x[xlen++];
      ioright->fd = fdright;
      ioright->events = IOPAUSE_READ;
    }
    io1 = 0;
    if (rightstatus == 1) {
      io1 = &x[xlen++];
      io1->fd = 1;
      io1->events = IOPAUSE_WRITE;
    }

    taia_now(&stamp);
    taia_uint(&deadline,3600);
    taia_add(&deadline,&stamp,&deadline);
    iopause(x,xlen,&deadline,&stamp);

    if (io0 && io0->revents) {
      r = read(0,leftbuf,sizeof leftbuf);
      if (r <= 0) {
        leftstatus = -1;
        close(fdleft);
        buffer_puts(&ssrecord,pid);
        buffer_puts(&ssrecord," < [EOF]\n");
        buffer_flush(&ssrecord);
      }
      else {
        leftstatus = 1; leftpos = 0; leftlen = r;
        record(leftbuf,r," < ");
      }
    }

    if (ioleft && ioleft->revents) {
      r = write(fdleft,leftbuf + leftpos,leftlen - leftpos);
      if (r == -1) break;
      leftpos += r;
      if (leftpos == leftlen) leftstatus = 0;
    }

    if (ioright && ioright->revents) {
      r = read(fdright,rightbuf,sizeof rightbuf);
      if (r <= 0) {
        buffer_puts(&ssrecord,pid);
        buffer_puts(&ssrecord," > [EOF]\n");
        buffer_flush(&ssrecord);
        break;
      }
      rightstatus = 1; rightpos = 0; rightlen = r;
      record(rightbuf,r," > ");
    }

    if (io1 && io1->revents) {
      r = write(1,rightbuf + rightpos,rightlen - rightpos);
      if (r == -1) break;
      rightpos += r;
      if (rightpos == rightlen) rightstatus = 0;
    }
  }

  _exit(0);
}
Exemplo n.º 27
0
void doit(void)
{
  iopause_fd x[2];
  struct taia deadline;
  struct taia stamp;
  int wstat;
  int r;
  char ch;

  announce();

  for (;;) {
    if (flagexit && !pid) return;

    sig_unblock(sig_child);

    x[0].fd = selfpipe[0];
    x[0].events = IOPAUSE_READ;
    x[1].fd = fdcontrol;
    x[1].events = IOPAUSE_READ;
    taia_now(&stamp);
    taia_uint(&deadline,3600);
    taia_add(&deadline,&stamp,&deadline);
    iopause(x,2,&deadline,&stamp);

    sig_block(sig_child);

    while (read(selfpipe[0],&ch,1) == 1)
      ;

    for (;;) {
      r = wait_nohang(&wstat);
      if (!r) break;
      if ((r == -1) && (errno != error_intr)) break;
      if (r == pid) {
	pid = 0;
	pidchange();
	announce();
	if (flagexit) return;
	if (flagwant && flagwantup) trystart();
	break;
      }
    }

    if (read(fdcontrol,&ch,1) == 1)
      switch(ch) {
	case 'd':
	  flagwant = 1;
	  flagwantup = 0;
	  if (pid) { kill(pid,SIGTERM); kill(pid,SIGCONT); flagpaused = 0; }
	  announce();
	  break;
	case 'u':
	  flagwant = 1;
	  flagwantup = 1;
	  announce();
	  if (!pid) trystart();
	  break;
	case 'o':
	  flagwant = 0;
	  announce();
	  if (!pid) trystart();
	  break;
	case 'a':
	  if (pid) kill(pid,SIGALRM);
	  break;
	case 'h':
	  if (pid) kill(pid,SIGHUP);
	  break;
	case 'k':
	  if (pid) kill(pid,SIGKILL);
	  break;
	case 't':
	  if (pid) kill(pid,SIGTERM);
	  break;
	case 'i':
	  if (pid) kill(pid,SIGINT);
	  break;
	case 'p':
	  flagpaused = 1;
	  announce();
	  if (pid) kill(pid,SIGSTOP);
	  break;
	case 'c':
	  flagpaused = 0;
	  announce();
	  if (pid) kill(pid,SIGCONT);
	  break;
	case 'x':
	  flagexit = 1;
	  announce();
	  break;
      }
  }
}
Exemplo n.º 28
0
int dns_transmit_get(struct dns_transmit *d,const iopause_fd *x,const struct taia *when)
{
  char udpbuf[513];
  unsigned char ch;
  int r;
  int fd;

  errno = error_io;
  fd = d->s1 - 1;

  if (!x->revents) {
    if (taia_less(when,&d->deadline)) return 0;
    errno = error_timeout;
    if (d->tcpstate == 0) return nextudp(d);
    return nexttcp(d);
  }

  if (d->tcpstate == 0) {
/*
have attempted to send UDP query to each server udploop times
have sent query to curserver on UDP socket s
*/
    r = recv(fd,udpbuf,sizeof udpbuf,0);
    if (r <= 0) {
      if (errno == error_connrefused) if (d->udploop == 2) return 0;
      return nextudp(d);
    }
    if (r + 1 > sizeof udpbuf) return 0;

    if (irrelevant(d,udpbuf,r)) return 0;
    if (serverwantstcp(udpbuf,r)) return firsttcp(d);
    if (serverfailed(udpbuf,r)) {
      if (d->udploop == 2) return 0;
      return nextudp(d);
    }
    socketfree(d);

    d->packetlen = r;
    d->packet = alloc(d->packetlen);
    if (!d->packet) { dns_transmit_free(d); return -1; }
    byte_copy(d->packet,d->packetlen,udpbuf);
    queryfree(d);
    return 1;
  }

  if (d->tcpstate == 1) {
/*
have sent connection attempt to curserver on TCP socket s
pos not defined
*/
    if (!socket_connected(fd)) return nexttcp(d);
    d->pos = 0;
    d->tcpstate = 2;
    return 0;
  }

  if (d->tcpstate == 2) {
/*
have connection to curserver on TCP socket s
have sent pos bytes of query
*/
    r = write(fd,d->query + d->pos,d->querylen - d->pos);
    if (r <= 0) return nexttcp(d);
    d->pos += r;
    if (d->pos == d->querylen) {
      struct taia now;
      taia_now(&now);
      taia_uint(&d->deadline,10);
      taia_add(&d->deadline,&d->deadline,&now);
      d->tcpstate = 3;
    }
    return 0;
  }

  if (d->tcpstate == 3) {
/*
have sent entire query to curserver on TCP socket s
pos not defined
*/
    r = read(fd,&ch,1);
    if (r <= 0) return nexttcp(d);
    d->packetlen = ch;
    d->tcpstate = 4;
    return 0;
  }

  if (d->tcpstate == 4) {
/*
have sent entire query to curserver on TCP socket s
pos not defined
have received one byte of packet length into packetlen
*/
    r = read(fd,&ch,1);
    if (r <= 0) return nexttcp(d);
    d->packetlen <<= 8;
    d->packetlen += ch;
    d->tcpstate = 5;
    d->pos = 0;
    d->packet = alloc(d->packetlen);
    if (!d->packet) { dns_transmit_free(d); return -1; }
    return 0;
  }

  if (d->tcpstate == 5) {
/*
have sent entire query to curserver on TCP socket s
have received entire packet length into packetlen
packet is allocated
have received pos bytes of packet
*/
    r = read(fd,d->packet + d->pos,d->packetlen - d->pos);
    if (r <= 0) return nexttcp(d);
    d->pos += r;
    if (d->pos < d->packetlen) return 0;

    socketfree(d);
    if (irrelevant(d,d->packet,d->packetlen)) return nexttcp(d);
    if (serverwantstcp(d->packet,d->packetlen)) return nexttcp(d);
    if (serverfailed(d->packet,d->packetlen)) return nexttcp(d);

    queryfree(d);
    return 1;
  }

  return 0;
}
Exemplo n.º 29
0
void doit(int fdleft,int fdright)
{
  struct taia stamp;
  struct taia deadline;
  iopause_fd x[4];
  int xlen;
  iopause_fd *io0;
  iopause_fd *ioleft;
  iopause_fd *io1;
  iopause_fd *ioright;
  int r;
  int i;
  char ch;

  for (;;) {
    xlen = 0;

    io0 = 0;
    if (leftstatus == 0) {
      io0 = &x[xlen++];
      io0->fd = 0;
      io0->events = IOPAUSE_READ;
    }
    ioleft = 0;
    if (leftstatus == 1) {
      ioleft = &x[xlen++];
      ioleft->fd = fdleft;
      ioleft->events = IOPAUSE_WRITE;
    }

    ioright = 0;
    if (rightstatus == 0) {
      ioright = &x[xlen++];
      ioright->fd = fdright;
      ioright->events = IOPAUSE_READ;
    }
    io1 = 0;
    if (rightstatus == 1) {
      io1 = &x[xlen++];
      io1->fd = 1;
      io1->events = IOPAUSE_WRITE;
    }

    taia_now(&stamp);
    taia_uint(&deadline,3600);
    taia_add(&deadline,&stamp,&deadline);
    iopause(x,xlen,&deadline,&stamp);

    if (io0 && io0->revents) {
      r = read(0,prebuf,sizeof prebuf);
      if (r <= 0) {
        leftstatus = -1;
        close(fdleft);
      }
      else {
        leftstatus = 1;
    leftpos = 0;
    leftlen = 0;
    for (i = 0;i < r;++i) {
      ch = prebuf[i];
      if (ch == '\n')
        if (!leftflagcr)
          leftbuf[leftlen++] = '\r';
      leftbuf[leftlen++] = ch;
      leftflagcr = (ch == '\r');
    }
      }
    }

    if (ioleft && ioleft->revents) {
      r = write(fdleft,leftbuf + leftpos,leftlen - leftpos);
      if (r == -1) break;
      leftpos += r;
      if (leftpos == leftlen) leftstatus = 0;
    }

    if (ioright && ioright->revents) {
      r = read(fdright,prebuf,sizeof prebuf);
      if (r <= 0) break;
      rightstatus = 1;
      rightpos = 0;
      rightlen = 0;
      for (i = 0;i < r;++i) {
    ch = prebuf[i];
    if (ch == '\n')
      if (!rightflagcr)
        rightbuf[rightlen++] = '\r';
    rightbuf[rightlen++] = ch;
    rightflagcr = (ch == '\r');
      }
    }

    if (io1 && io1->revents) {
      r = write(1,rightbuf + rightpos,rightlen - rightpos);
      if (r == -1) break;
      rightpos += r;
      if (rightpos == rightlen) rightstatus = 0;
    }
  }

  _exit(0);
}
Exemplo n.º 30
0
static int
thisudp (struct dns_transmit *d)
{
    const char *ip = NULL;

    socketfree (d);
    mergefree (d);

    while (d->udploop < 4)
    {
        for (; d->curserver < 16; ++d->curserver)
        {
            ip = d->servers + 4 * d->curserver;
            if (byte_diff (ip, 4, "\0\0\0\0"))
            {
                if (merge_enable && try_merge (d))
                {
                    if (merge_logger)
                        merge_logger (ip, d->qtype, d->query + 14);
                    return 0;
                }

                d->query[2] = dns_random (256);
                d->query[3] = dns_random (256);

                d->s1 = 1 + socket_udp ();
                if (!d->s1)
                {
                    dns_transmit_free (d);
                    return -1;
                }
                if (randombind (d) == -1)
                {
                    dns_transmit_free (d);
                    return -1;
                }

                if (socket_connect4 (d->s1 - 1, ip, 53) == 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;
                        if (merge_enable)
                            register_inprogress (d);
                        return 0;
                    }
                }
                socketfree (d);
            }
        }

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

    dns_transmit_free (d);
    return -1;
}