Example #1
0
main()
{
  char *x;
  int udp53;

  x = env_get("IP");
  if (!x)
    strerr_die2x(111,fatal,"$IP not set");
  if (!ip4_scan(x,ip))
    strerr_die3x(111,fatal,"unable to parse IP address ",x);

  udp53 = socket_udp();
  if (udp53 == -1)
    strerr_die2sys(111,fatal,"unable to create UDP socket: ");
  if (socket_bind4_reuse(udp53,ip,53) == -1)
    strerr_die2sys(111,fatal,"unable to bind UDP socket: ");

  droproot(fatal);

  initialize();
  
  ndelay_off(udp53);
  socket_tryreservein(udp53,65536);

  for (;;) {
    len = socket_recv4(udp53,buf,sizeof buf,ip,&port);
    if (len < 0) continue;
    if (!doit()) continue;
    if (response_len > 512) response_tc();
    socket_send4(udp53,response,response_len,ip,port);
    /* may block for buffer space; if it fails, too bad */
  }
}
Example #2
0
void
u_new (void)
{
    int i = 0, j = 0, len = 0;
    struct udpclient *x = NULL;

    static char *q = 0;
    char qtype[2], qclass[2];

    for (j = 0; j < MAXUDP; j++)
        if (!u[j].active)
            break;

    if (j >= MAXUDP)
    {
        j = 0;
        for (i = 1; i < MAXUDP; i++)
            if (taia_less (&u[i].start, &u[j].start))
                j = i;
        errno = error_timeout;
        u_drop (j);
    }

    x = u + j;
    taia_now (&x->start);

    len = socket_recv4 (udp53, buf, sizeof (buf), x->ip, &x->port, &odst);
    if (len == -1)
        return;
    if ((unsigned)len >= sizeof buf)
        return;
    if (x->port < 1024 && x->port != 53)
        return;
    if (!okclient (x->ip))
        return;
    if (!packetquery (buf, len, &q, qtype, qclass, x->id))
        return;

    x->active = ++numqueries;
    ++uactive;

    if (debug_level)
        log_query (x->active, x->ip, x->port, x->id, q, qtype);

    switch (query_start (&x->q, q, qtype, qclass, myipoutgoing))
    {
    case -1:
        u_drop (j);
        return;

    case 1:
        u_respond (j);
    }
}
Example #3
0
static int receive_packet(uint32 type, int minlength, int maxlength)
{
  int i;
  uint32 t;
  if ((i = socket_recv4(sock, rpacket.s, rpacket.size, &ip,&port)) < 0)
    REJECT1("Socket receive failed");
  if (i < minlength)
    REJECT1("Received packet is too short");
  if (maxlength > 0
      && i > maxlength)
    REJECT1("Received packet is too long");
  rpacket.len = i;
  pkt_get_u4(&rpacket, 0, &t);
  if (t != SRL2)
    REJECT1("Received packet format was not SRL2");
  pkt_get_u4(&rpacket, 4, &t);
  if (t != type)
    REJECT1("Received incorrect packet type");
  return 1;
}
Example #4
0
static void * livesync_worker( void * args ) {
  struct ot_workstruct ws;
  ot_ip6 in_ip; uint16_t in_port;

  (void)args;
  
  /* Initialize our "thread local storage" */
  ws.inbuf   = ws.request = malloc( LIVESYNC_INCOMING_BUFFSIZE );
  ws.outbuf  = ws.reply   = 0;
  
  memcpy( in_ip, V4mappedprefix, sizeof( V4mappedprefix ) );

  while( 1 ) {
    ws.request_size = socket_recv4(g_socket_in, (char*)ws.inbuf, LIVESYNC_INCOMING_BUFFSIZE, 12+(char*)in_ip, &in_port);

    /* Expect at least tracker id and packet type */
    if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) )
      continue;
    if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC))
      continue;
    if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) {
      /* TODO: log packet coming from ourselves */
      continue;
    }

    switch( uint32_read_big( sizeof( g_tracker_id ) + (char *)ws.inbuf ) ) {
    case OT_SYNC_PEER:
      livesync_handle_peersync( &ws );
      break;
    default:
      break;
    }
  }

  /* Never returns. */
  return NULL;
}
Example #5
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;
}