示例#1
0
/* Returns whether something was read */
int pcap_read_on_nonselect(mspool *nsp) {
  gh_list_elem *current, *next;
  msevent *nse;
  int ret = 0;

  for (current = GH_LIST_FIRST_ELEM(&nsp->pcap_read_events); current != NULL; current = next) {
    nse = (msevent *)GH_LIST_ELEM_DATA(current);
    if (do_actual_pcap_read(nse) == 1) {
      /* something received */
      ret++;
      break;
    }
    next = GH_LIST_ELEM_NEXT(current);
  }

  return ret;
}
示例#2
0
/* Returns whether something was read */
int pcap_read_on_nonselect(struct npool *nsp) {
  gh_lnode_t *current, *next;
  struct nevent *nse;
  int ret = 0;

  for (current = gh_list_first_elem(&nsp->pcap_read_events);
       current != NULL;
       current = next) {
    nse = lnode_nevent2(current);
    if (do_actual_pcap_read(nse) == 1) {
      /* something received */
      ret++;
      break;
    }
    next = gh_lnode_next(current);
  }
  return ret;
}
示例#3
0
void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int ev) {
  int match_r = 0, match_w = 0;
#if HAVE_OPENSSL
  int desire_r = 0, desire_w = 0;
#endif

  nsock_log_debug_all("Processing event %lu (timeout in %ldms, done=%d)",
                      nse->id,
                      (long)TIMEVAL_MSEC_SUBTRACT(nse->timeout, nsock_tod),
                      nse->event_done);

  if (!nse->event_done) {
    switch (nse->type) {
      case NSE_TYPE_CONNECT:
      case NSE_TYPE_CONNECT_SSL:
        if (ev != EV_NONE)
          handle_connect_result(nsp, nse, NSE_STATUS_SUCCESS);
        if (event_timedout(nse))
          handle_connect_result(nsp, nse, NSE_STATUS_TIMEOUT);
        break;

      case NSE_TYPE_READ:
        match_r = ev & EV_READ;
        match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
        desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
        desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
        if (nse->iod->ssl && ((desire_r && match_r) || (desire_w && match_w)))
          handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);
        else
#endif
        if (!nse->iod->ssl && match_r)
          handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);

        if (event_timedout(nse))
          handle_read_result(nsp, nse, NSE_STATUS_TIMEOUT);
        break;

      case NSE_TYPE_WRITE:
        match_r = ev & EV_READ;
        match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
        desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
        desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
        if (nse->iod->ssl && ((desire_r && match_r) || (desire_w && match_w)))
          handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);
        else
#endif
          if (!nse->iod->ssl && match_w)
            handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);

          if (event_timedout(nse))
            handle_write_result(nsp, nse, NSE_STATUS_TIMEOUT);
          break;

      case NSE_TYPE_TIMER:
        if (event_timedout(nse))
          handle_timer_result(nsp, nse, NSE_STATUS_SUCCESS);
        break;

#if HAVE_PCAP
      case NSE_TYPE_PCAP_READ:{
        nsock_log_debug_all("PCAP iterating %lu", nse->id);

        if (ev & EV_READ) {
          /* buffer empty? check it! */
          if (fs_length(&(nse->iobuf)) == 0)
            do_actual_pcap_read(nse);
        }

        /* if already received something */
        if (fs_length(&(nse->iobuf)) > 0)
          handle_pcap_read_result(nsp, nse, NSE_STATUS_SUCCESS);

        if (event_timedout(nse))
          handle_pcap_read_result(nsp, nse, NSE_STATUS_TIMEOUT);

        #if PCAP_BSD_SELECT_HACK
        /* If event occurred, and we're in BSD_HACK mode, then this event was added
         * to two queues. read_event and pcap_read_event
         * Of course we should destroy it only once.
         * I assume we're now in read_event, so just unlink this event from
         * pcap_read_event */
        if (((mspcap *)nse->iod->pcap)->pcap_desc >= 0
            && nse->event_done
            && evlist == &nsp->read_events) {
          /* event is done, list is read_events and we're in BSD_HACK mode.
           * So unlink event from pcap_read_events */
          update_first_events(nse);
          gh_list_remove(&nsp->pcap_read_events, &nse->nodeq_pcap);

          nsock_log_debug_all("PCAP NSE #%lu: Removing event from PCAP_READ_EVENTS",
                              nse->id);
        }
        if (((mspcap *)nse->iod->pcap)->pcap_desc >= 0
            && nse->event_done
            && evlist == &nsp->pcap_read_events) {
          update_first_events(nse);
          gh_list_remove(&nsp->read_events, &nse->nodeq_io);
          nsock_log_debug_all("PCAP NSE #%lu: Removing event from READ_EVENTS",
                              nse->id);
        }
        #endif
        break;
      }
#endif
      default:
        fatal("Event has unknown type (%d)", nse->type);
    }
  }

  if (nse->event_done) {
    /* Security sanity check: don't return a functional SSL iod without
     * setting an SSL data structure. */
    if (nse->type == NSE_TYPE_CONNECT_SSL && nse->status == NSE_STATUS_SUCCESS)
      assert(nse->iod->ssl != NULL);

    nsock_log_debug_all("NSE #%lu: Sending event", nse->id);

    /* WooHoo!  The event is ready to be sent */
    event_dispatch_and_delete(nsp, nse, 1);
  }
}
示例#4
0
void process_event(mspool *nsp, gh_list *evlist, msevent *nse, int ev) {
  int match_r = 0, match_w = 0;
#if HAVE_OPENSSL
  int desire_r = 0, desire_w = 0;
#endif

  if (nsp->tracelevel > 7)
    nsock_trace(nsp, "Processing event %lu", nse->id);

  if (!nse->event_done) {
    switch(nse->type) {
      case NSE_TYPE_CONNECT:
      case NSE_TYPE_CONNECT_SSL:
        if (ev != EV_NONE)
          handle_connect_result(nsp, nse, NSE_STATUS_SUCCESS);
        if (!nse->event_done && nse->timeout.tv_sec && !TIMEVAL_AFTER(nse->timeout, nsock_tod))
          handle_connect_result(nsp, nse, NSE_STATUS_TIMEOUT);
        break;

      case NSE_TYPE_READ:
        match_r = ev & EV_READ;
        match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
        desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
        desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
        if (nse->iod->ssl && ((desire_r && match_r) || (desire_w && match_w)))
          handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);
        else
#endif
        if (!nse->iod->ssl && match_r)
          handle_read_result(nsp, nse, NSE_STATUS_SUCCESS);

        if (!nse->event_done && nse->timeout.tv_sec && !TIMEVAL_AFTER(nse->timeout, nsock_tod))
          handle_read_result(nsp, nse, NSE_STATUS_TIMEOUT);
        break;

      case NSE_TYPE_WRITE:
        match_r = ev & EV_READ;
        match_w = ev & EV_WRITE;
#if HAVE_OPENSSL
        desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ;
        desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE;
        if (nse->iod->ssl && ((desire_r && match_r) || (desire_w && match_w)))
          handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);
        else
#endif
          if (!nse->iod->ssl && match_w)
            handle_write_result(nsp, nse, NSE_STATUS_SUCCESS);

          if (!nse->event_done && nse->timeout.tv_sec && !TIMEVAL_AFTER(nse->timeout, nsock_tod))
            handle_write_result(nsp, nse, NSE_STATUS_TIMEOUT);
          break;

      case NSE_TYPE_TIMER:
        if (nse->timeout.tv_sec && !TIMEVAL_AFTER(nse->timeout, nsock_tod))
          handle_timer_result(nsp, nse, NSE_STATUS_SUCCESS);
        break;

#if HAVE_PCAP
      case NSE_TYPE_PCAP_READ:{
        if (nsp->tracelevel > 5)
          nsock_trace(nsp, "PCAP iterating %lu", nse->id);

        if (ev & EV_READ) {
          /* buffer empty? check it! */
          if (FILESPACE_LENGTH(&(nse->iobuf)) == 0)
            do_actual_pcap_read(nse);
        }

        /* if already received smth */
        if (FILESPACE_LENGTH(&(nse->iobuf)) > 0)
          handle_pcap_read_result(nsp, nse, NSE_STATUS_SUCCESS);

        if (!nse->event_done && nse->timeout.tv_sec && !TIMEVAL_AFTER(nse->timeout, nsock_tod))
          handle_pcap_read_result(nsp, nse, NSE_STATUS_TIMEOUT);

        #if PCAP_BSD_SELECT_HACK
        /* If event occurred, and we're in BSD_HACK mode, then this event was added
         * to two queues. read_event and pcap_read_event
         * Of course we should destroy it only once.
         * I assume we're now in read_event, so just unlink this event from
         * pcap_read_event */
        if (((mspcap *)nse->iod->pcap)->pcap_desc >= 0 && nse->event_done && evlist == &nsp->read_events) {
          /* event is done, list is read_events and we're in BSD_HACK mode.
           * So unlink event from pcap_read_events */
          update_first_events(nse);
          gh_list_remove(&nsp->pcap_read_events, nse);

          if (nsp->tracelevel > 8)
            nsock_trace(nsp, "PCAP NSE #%lu: Removing event from PCAP_READ_EVENTS", nse->id);
        }
        if (((mspcap *)nse->iod->pcap)->pcap_desc >= 0 && nse->event_done && evlist == &nsp->pcap_read_events) {
          update_first_events(nse);
          gh_list_remove(&nsp->read_events, nse);
          if (nsp->tracelevel > 8)
            nsock_trace(nsp, "PCAP NSE #%lu: Removing event from READ_EVENTS", nse->id);
        }
        #endif
        break;
      }
#endif
      default:
        fatal("Event has unknown type (%d)", nse->type);
        break; /* unreached */
      }
  }
  if (nse->event_done) {
    /* Security sanity check: don't return a functional SSL iod without setting an SSL data structure. */
    if (nse->type == NSE_TYPE_CONNECT_SSL && nse->status == NSE_STATUS_SUCCESS)
      assert(nse->iod->ssl != NULL);

    if (nsp->tracelevel > 8)
      nsock_trace(nsp, "NSE #%lu: Sending event", nse->id);

    /* WooHoo!  The event is ready to be sent */
    msevent_dispatch_and_delete(nsp, nse, 1);
  } else {
    /* Is this event the next-to-timeout? */
    if (nse->timeout.tv_sec != 0) {
      if (nsp->next_ev.tv_sec == 0)
        nsp->next_ev = nse->timeout;
      else if (TIMEVAL_AFTER(nsp->next_ev, nse->timeout))
        nsp->next_ev = nse->timeout;
    }
  }
}