Example #1
0
void local_actor::reply_message(any_tuple&& what) {
    auto& whom = last_sender();
    if (whom == nullptr) {
        return;
    }
    auto id = m_current_node->mid;
    if (id.valid() == false || id.is_response()) {
        send_message(whom.get(), std::move(what));
    }
    else if (chaining_enabled()) {
        if (whom->chained_sync_enqueue(this, id.response_id(), std::move(what))) {
            m_chained_actor = whom;
        }
    }
    else whom->sync_enqueue(this, id.response_id(), std::move(what));
}
Example #2
0
message_id local_actor::sync_send_tuple_impl(message_priority mp,
                                             const actor& dest,
                                             any_tuple&& what) {
    auto nri = new_request_id();
    if (mp == message_priority::high) nri = nri.with_high_priority();
    dest->enqueue({address(), dest, nri}, std::move(what));
    return nri.response_id();
}
Example #3
0
 message_id sync_send_impl(message_priority mp, const Handle& dh, Ts&&... xs) {
   if (! dh) {
     throw std::invalid_argument("cannot sync_send to invalid_actor");
   }
   auto req_id = new_request_id(mp);
   send_impl(req_id, actor_cast<abstract_channel*>(dh),
             std::forward<Ts>(xs)...);
   return req_id.response_id();
 }
Example #4
0
void u_respond(int j)
{
  if (!u[j].active) return;
  response_id(u[j].id);
  if (response_len > 512) response_tc();
  socket_send6(udp53,response,response_len,u[j].ip,u[j].port,u[j].scope_id);
  log_querydone(&u[j].active,response_len);
  u[j].active = 0; --uactive;
}
Example #5
0
message_id local_actor::sync_send_tuple_impl(message_priority mp,
                                             const actor& dest,
                                             any_tuple&& what) {
    if (!dest) {
        throw std::invalid_argument("cannot send synchronous message "
                                    "to invalid_actor");
    }
    auto nri = new_request_id();
    if (mp == message_priority::high) nri = nri.with_high_priority();
    dest->enqueue({address(), dest, nri}, std::move(what), m_host);
    return nri.response_id();
}
Example #6
0
static int doit(void)
{
  unsigned int pos;
  char header[12];
  char qtype[2];
  char qclass[2];

  if (len >= sizeof buf) goto NOQ;
  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto NOQ;
  if (header[2] & 128) goto NOQ;
  if (header[4]) goto NOQ;
  if (header[5] != 1) goto NOQ;

  pos = dns_packet_getname(buf,len,pos,&q); if (!pos) goto NOQ;
  pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) goto NOQ;
  pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) goto NOQ;

  if (!response_query(q,qtype,qclass)) goto NOQ;
  response_id(header);
  if (byte_equal(qclass,2,DNS_C_IN))
    response[2] |= 4;
  else
    if (byte_diff(qclass,2,DNS_C_ANY)) goto WEIRDCLASS;
  response[3] &= ~128;
  if (!(header[2] & 1)) response[2] &= ~1;

  if (header[2] & 126) goto NOTIMP;
  if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP;

  case_lowerb(q,dns_domain_length(q));
  if (!respond(q,qtype,ip)) {
    qlog(ip,port,header,q,qtype," - ");
    return 0;
  }
  qlog(ip,port,header,q,qtype," + ");
  return 1;

  NOTIMP:
  response[3] &= ~15;
  response[3] |= 4;
  qlog(ip,port,header,q,qtype," I ");
  return 1;

  WEIRDCLASS:
  response[3] &= ~15;
  response[3] |= 1;
  qlog(ip,port,header,q,qtype," C ");
  return 1;

  NOQ:
  qlog(ip,port,"\0\0","","\0\0"," / ");
  return 0;
}
Example #7
0
/**
 * @brief Sends @p what as a synchronous message to @p whom.
 * @param whom Receiver of the message.
 * @param what Message content as tuple.
 * @returns A handle identifying a future to the response of @p whom.
 * @warning The returned handle is actor specific and the response to the sent
 *          message cannot be received by another actor.
 * @throws std::invalid_argument if <tt>whom == nullptr</tt>
 */
inline message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
    if (!whom) throw std::invalid_argument("whom == nullptr");
    auto req = self->new_request_id();
    message_header hdr{self, std::move(whom), req};
    if (self->chaining_enabled()) {
        if (hdr.receiver->chained_enqueue(hdr, std::move(what))) {
            self->chained_actor(hdr.receiver.downcast<actor>());
        }
    }
    else hdr.deliver(std::move(what));
    return req.response_id();
}
Example #8
0
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
                                                   const actor& dest,
                                                   const util::duration& rtime,
                                                   any_tuple&& what) {
    auto nri = new_request_id();
    if (mp == message_priority::high) nri = nri.with_high_priority();
    dest->enqueue({address(), dest, nri}, std::move(what));
    auto rri = nri.response_id();
    get_scheduler()->delayed_send({address(), this, rri}, rtime,
                                  make_any_tuple(sync_timeout_msg{}));
    return rri;
}
Example #9
0
void t_respond(int j)
{
  if (!t[j].active) return;
  log_querydone(&t[j].active,response_len);
  response_id(t[j].id);
  t[j].len = response_len + 2;
  t_free(j);
  t[j].buf = alloc(response_len + 2);
  if (!t[j].buf) { t_close(j); return; }
  uint16_pack_big(t[j].buf,response_len);
  byte_copy(t[j].buf + 2,response_len,response);
  t[j].pos = 0;
  t[j].state = -1;
}
Example #10
0
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
                                                   const actor& dest,
                                                   const util::duration& rtime,
                                                   any_tuple&& what) {
    if (!dest) {
        throw std::invalid_argument("cannot send synchronous message "
                                    "to invalid_actor");
    }
    auto nri = new_request_id();
    if (mp == message_priority::high) nri = nri.with_high_priority();
    dest->enqueue({address(), dest, nri}, std::move(what), m_host);
    auto rri = nri.response_id();
    get_scheduling_coordinator()->delayed_send({address(), this, rri}, rtime,
                                  make_any_tuple(sync_timeout_msg{}));
    return rri;
}
Example #11
0
void
u_respond (int j)
{
    if (!u[j].active)
        return;

    response_id (u[j].id);
    if (response_len > 512)
        response_tc ();
    socket_send4 (udp53, response, response_len, u[j].ip, u[j].port, &odst);

    if (debug_level)
        log_querydone (u[j].active, response, response_len);

    u[j].active = 0;
    --uactive;
}
Example #12
0
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
                                                   const actor& dest,
                                                   const duration& rtime,
                                                   message&& what) {
  if (!dest) {
    throw std::invalid_argument(
      "cannot send synchronous message "
      "to invalid_actor");
  }
  auto nri = new_request_id();
  if (mp == message_priority::high) {
    nri = nri.with_high_priority();
  }
  dest->enqueue(address(), nri, std::move(what), host());
  auto rri = nri.response_id();
  auto sched_cd = detail::singletons::get_scheduling_coordinator();
  sched_cd->delayed_send(rtime, address(), this, rri,
                         make_message(sync_timeout_msg{}));
  return rri;
}
Example #13
0
 // returns 0 if last_dequeued() is an asynchronous or sync request message,
 // a response id generated from the request id otherwise
 inline message_id get_response_id() const {
   auto mid = current_element_->mid;
   return (mid.is_request()) ? mid.response_id() : message_id();
 }
Example #14
0
int main()
{
  unsigned int pos;
  char header[12];
  char qtype[2];
  char qclass[2];
  const char *x;

  droproot(FATAL);
  dns_random_init(seed);

  axfr = env_get("AXFR");
  
  x = env_get("TCPREMOTEIP");
  if (x && ip6_scan(x,ip))
    ;
  else
    byte_zero(ip,16);

  x = env_get("TCPREMOTEPORT");
  if (!x) x = "0";
  scan_ulong(x,&port);

  for (;;) {
    netread(tcpheader,2);
    uint16_unpack_big(tcpheader,&len);
    if (len > 512) strerr_die2x(111,FATAL,"excessively large request");
    netread(buf,len);

    pos = dns_packet_copy(buf,len,0,header,12); if (!pos) die_truncated();
    if (header[2] & 254) strerr_die2x(111,FATAL,"bogus query");
    if (header[4] || (header[5] != 1)) strerr_die2x(111,FATAL,"bogus query");

    pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated();
    zonelen = dns_domain_length(zone);
    pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated();
    pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated();

    if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY))
      strerr_die2x(111,FATAL,"bogus query: bad class");

    pos = check_edns0(header, buf, len, pos);
    if (!pos) die_truncated();

    qlog(ip,port,header,zone,qtype," ");

    if (byte_equal(qtype,2,DNS_T_AXFR)) {
      case_lowerb(zone,zonelen);
      fdcdb = open_read("data.cdb");
      if (fdcdb == -1) die_cdbread();
      doaxfr(header);
      close(fdcdb);
    }
    else {
      if (!response_query(zone,qtype,qclass)) nomem();
      response[2] |= 4;
      case_lowerb(zone,zonelen);
      response_id(header);
      response[3] &= ~128;
      if (!(header[2] & 1)) response[2] &= ~1;
      if (!respond(zone,qtype,ip)) die_outside();
      print(response,response_len);
    }
  }
}
Example #15
0
 inline message_id new_request_id() {
     auto result = ++m_last_request_id;
     m_pending_responses.push_back(result.response_id());
     return result;
 }
Example #16
0
inline message_id local_actor::get_response_id() {
    auto id = m_current_node->mid;
    return (id.is_request()) ? id.response_id() : message_id();
}
Example #17
0
int
main (int argc, char *argv[])
{
    int n = 0;
    time_t t = 0;
    struct sigaction sa;

    char qtype[2];
    char qclass[2];
    char header[12];
    const char *x = NULL;
    unsigned int pos = 0;
    unsigned long long qnum = 0;

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

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

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

    if (mode & DAEMON)
        /* redirect stderr to a log file */
        redirect_to_log (logfile, STDERR_FILENO);

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

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

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

    dns_random_init (seed);

    axfr = env_get ("AXFR");
    if (debug_level)
        warnx ("AXFR set to `%s'", axfr);
    x = env_get ("TCPREMOTEIP");
    if (debug_level)
        warnx ("TCPREMOTEIP set to `%s'", x);
    if (x)
        ip4_scan (x, ip);
    else
        byte_zero (ip, 4);

    x = env_get ("TCPREMOTEPORT");
    if (debug_level)
        warnx ("TCPREMOTEPORT set to `%s'", x);
    if (!x)
        x = "0";
    scan_ulong (x, &port);

    droproot ();
    for (;;)
    {
        netread (tcpheader, 2);
        uint16_unpack_big (tcpheader, &len);
        if (len > 512)
            errx (-1, "excessively large request");
        netread (buf, len);

        pos = dns_packet_copy (buf, len, 0, header, 12);
        if (!pos)
            errx (-1, "truncated request");
        if (header[2] & 254)
            errx (-1, "bogus query");
        if (header[4] || (header[5] != 1))
            errx (-1, "bogus query");

        pos = dns_packet_getname (buf, len, pos, &zone);
        if (!pos)
            errx (-1, "truncated request");
        zonelen = dns_domain_length (zone);
        pos = dns_packet_copy (buf, len, pos, qtype, 2);
        if (!pos)
            errx (-1, "truncated request");
        pos = dns_packet_copy (buf, len, pos, qclass, 2);
        if (!pos)
            errx (-1, "truncated request");

        if (byte_diff(qclass, 2, DNS_C_IN) && byte_diff(qclass, 2, DNS_C_ANY))
            errx (-1, "bogus query: bad class");

        log_query (++qnum, ip, port, header, zone, qtype);
        if (byte_equal(qtype,2,DNS_T_AXFR))
        {
            case_lowerb (zone, zonelen);
            fdcdb = open_read ("data.cdb");
            if (fdcdb == -1)
                errx (-1, "could not read from file `data.cdb'");
            doaxfr (header);
            close (fdcdb);
        }
        else
        {
            if (!response_query (zone, qtype, qclass))
                err (-1, "could not allocate enough memory");
            response[2] |= 4;
            case_lowerb (zone, zonelen);
            response_id (header);
            response[3] &= ~128;
            if (!(header[2] & 1))
                response[2] &= ~1;
            if (!respond (zone, qtype, ip))
                errx (-1, "could not find information in file `data.cdb'");
            print (response, response_len);
        }
    }
}