コード例 #1
0
ファイル: uping.c プロジェクト: Compy/Undernet-IRCU
/** Callback for uping listener socket.
 * Reads a uping from the socket and respond, but not more than 10
 * times per second.
 * @param[in] ev I/O event for uping socket.
 */
static void uping_echo_callback(struct Event* ev)
{
  struct Socket      *sock;
  struct irc_sockaddr from;
  unsigned int       len = 0;
  static time_t      last = 0;
  static int         counter = 0;
  char               buf[BUFSIZE + 1];

  assert(ev_type(ev) == ET_READ || ev_type(ev) == ET_ERROR);
  sock = ev_socket(ev);
  assert(sock == &upingSock_v4 || sock == &upingSock_v6);

  Debug((DEBUG_DEBUG, "UPING: uping_echo"));

  if (IO_SUCCESS != os_recvfrom_nonb(s_fd(sock), buf, BUFSIZE, &len, &from))
    return;
  /*
   * count em even if we're getting flooded so we can tell we're getting
   * flooded.
   */
  ++ServerStats->uping_recv;
  if (len < 19)
    return;
  else if (CurrentTime != last) {
    counter = 0;
    last = CurrentTime;
  } else if (++counter > 10)
    return;
  os_sendto_nonb(s_fd(sock), buf, len, NULL, 0, &from);
}
コード例 #2
0
ファイル: uping.c プロジェクト: evilnet/nefarious
/** Reads a uping from the socket and respond, but not more than 10
 * times per second.
 */
void uping_echo()
{
  struct sockaddr_in from = { 0 };
  unsigned int       len = 0;
  static time_t      last = 0;
  static int         counter = 0;
  char               buf[BUFSIZE + 1];

  Debug((DEBUG_DEBUG, "UPING: uping_echo"));

  if (IO_SUCCESS != os_recvfrom_nonb(UPingFileDescriptor, buf, BUFSIZE, &len, &from))
    return;
  /*
   * count em even if we're getting flooded so we can tell we're getting
   * flooded.
   */
  ++ServerStats->uping_recv;
  if (CurrentTime == last) {
    if (++counter > 10)
      return;
  }
  else {
    counter = 0;
    last    = CurrentTime;
  }
  if (len < 19)
    return;
  sendto(UPingFileDescriptor, buf, len, 0, (struct sockaddr*) &from, sizeof(from));
}
コード例 #3
0
ファイル: uping.c プロジェクト: Compy/Undernet-IRCU
/** Read the response from an outbound uping.
 * @param[in] pptr UPing to check.
 */
void uping_read(struct UPing* pptr)
{
  struct irc_sockaddr sin;
  struct timeval     tv;
  unsigned int       len;
  unsigned int       pingtime;
  char*              s;
  char               buf[BUFSIZE + 1];
  IOResult           ior;

  assert(0 != pptr);

  gettimeofday(&tv, NULL);

  ior = os_recvfrom_nonb(pptr->fd, buf, BUFSIZE, &len, &sin);
  if (IO_BLOCKED == ior)
    return;
  else if (IO_FAILURE == ior) {
    const char* msg = strerror(errno);
    if (!msg)
      msg = "Unknown error";
    sendcmdto_one(&me, CMD_NOTICE, pptr->client, "%C :UPING: receive error: "
		  "%s", pptr->client, msg);
    uping_end(pptr);
    return;
  }

  if (len < 19)
    return;			/* Broken packet */

  ++pptr->received;

  buf[len] = 0;
  pingtime = (tv.tv_sec - atol(&buf[1])) * 1000
             + (tv.tv_usec - atol(buf + strlen(buf) + 1)) / 1000;

  pptr->ms_ave += pingtime;
  if (!pptr->ms_min || pptr->ms_min > pingtime)
    pptr->ms_min = pingtime;
  if (pingtime > pptr->ms_max)
    pptr->ms_max = pingtime;

  timer_chg(&pptr->killer, TT_RELATIVE, UPINGTIMEOUT);

  s = pptr->buf + strlen(pptr->buf);
  sprintf(s, " %u", pingtime);

  if (pptr->received == pptr->count)
    uping_end(pptr);
  return;
}
コード例 #4
0
ファイル: ircd_res.c プロジェクト: Niichan/snircd
/** Read a DNS reply from the nameserver and process it.
 * @param[in] ev I/O activity event for resolver socket.
 */
static void
res_readreply(struct Event *ev)
{
  struct irc_sockaddr lsin;
  struct Socket *sock;
  char buf[sizeof(HEADER) + MAXPACKET];
  HEADER *header;
  struct reslist *request = NULL;
  unsigned int rc;
  int answer_count;

  assert((ev_socket(ev) == &res_socket_v4) || (ev_socket(ev) == &res_socket_v6));
  sock = ev_socket(ev);

  if (IO_SUCCESS != os_recvfrom_nonb(s_fd(sock), buf, sizeof(buf), &rc, &lsin)
      || (rc <= sizeof(HEADER)))
    return;

  /*
   * check against possibly fake replies
   */
  if (!res_ourserver(&lsin))
    return;

  /*
   * convert DNS reply reader from Network byte order to CPU byte order.
   */
  header = (HEADER *)buf;
  header->ancount = ntohs(header->ancount);
  header->qdcount = ntohs(header->qdcount);
  header->nscount = ntohs(header->nscount);
  header->arcount = ntohs(header->arcount);

  /*
   * response for an id which we have already received an answer for
   * just ignore this response.
   */
  if (0 == (request = find_id(header->id)))
    return;

  if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
  {
    if (SERVFAIL == header->rcode || NXDOMAIN == header->rcode)
    {
        /*
         * If a bad error was returned, we stop here and don't send
         * send any more (no retries granted).
         */
        Debug((DEBUG_DNS, "Request %p has bad response (state %d type %d rcode %d)", request, request->state, request->type, header->rcode));
        (*request->callback)(request->callback_ctx, NULL, NULL);
	rem_request(request);
    }
    else
    {
      /*
       * If we haven't already tried this, and we're looking up AAAA, try A
       * now
       */

      if (request->state == REQ_AAAA && request->type == T_AAAA)
      {
        request->timeout += feature_int(FEAT_IRCD_RES_TIMEOUT);
        resend_query(request);
      }
      else if (request->type == T_PTR && request->state != REQ_INT &&
               !irc_in_addr_is_ipv4(&request->addr))
      {
        request->state = REQ_INT;
        request->timeout += feature_int(FEAT_IRCD_RES_TIMEOUT);
        resend_query(request);
      }
    }

    return;
  }
  /*
   * If this fails there was an error decoding the received packet,
   * try it again and hope it works the next time.
   */
  answer_count = proc_answer(request, header, buf, buf + rc);

  if (answer_count)
  {
    if (request->type == T_PTR)
    {
      if (request->name == NULL)
      {
        /*
         * got a PTR response with no name, something bogus is happening
         * don't bother trying again, the client address doesn't resolve
         */
        Debug((DEBUG_DNS, "Request %p PTR had empty name", request));
        (*request->callback)(request->callback_ctx, NULL, NULL);
        rem_request(request);
        return;
      }

      /*
       * Lookup the 'authoritative' name that we were given for the
       * ip#.
       */
#ifdef IPV6
      if (!irc_in_addr_is_ipv4(&request->addr))
        do_query_name(request->callback, request->callback_ctx, request->name, NULL, T_AAAA);
      else
#endif
      do_query_name(request->callback, request->callback_ctx, request->name, NULL, T_A);
      Debug((DEBUG_DNS, "Request %p switching to forward resolution", request));
      rem_request(request);
    }
    else
    {
      /*
       * got a name and address response, client resolved
       */
      (*request->callback)(request->callback_ctx, &request->addr, request->name);
      Debug((DEBUG_DNS, "Request %p got forward resolution", request));
      rem_request(request);
    }
  }
  else if (!request->sent)
  {
    /* XXX - we got a response for a query we didn't send with a valid id?
     * this should never happen, bail here and leave the client unresolved
     */
    assert(0);

    /* XXX don't leak it */
    Debug((DEBUG_DNS, "Request %p was unexpected(!)", request));
    rem_request(request);
  }
}