Ejemplo n.º 1
0
/*
 * fds_select_check
 *
 * given an fd_set that has been passed to select, as well as a list of
 * fds that are being monitored, figure out which ones have an event and
 * use the callback provided to deal with the event.
 */
static void fds_select_check(fd_set *fdset, dlist_t *fds, int *count)
{
  scamper_fd_poll_t *fdp;
  dlist_node_t *node;

  /* stop now if there is nothing to check */
  if(fdset == NULL || *count == 0)
    {
      return;
    }

  /* nodes in this list should not be removed while this function is called */
  dlist_lock(fds);

  /* loop through */
  node = dlist_head_node(fds);
  while(node != NULL && *count > 0)
    {
      fdp = (scamper_fd_poll_t *)dlist_node_item(node);
      node = dlist_node_next(node);      

      if(FD_ISSET(fdp->fdn->fd, fdset))
	{
	  fdp->cb(fdp->fdn->fd, fdp->param);
	  (*count)--;
	}
    }

  /* can modify the list now */
  dlist_unlock(fds);

  return;
}
Ejemplo n.º 2
0
/*
 * fds_select_assemble
 *
 * given a list of scamper_fd_poll_t structures held in a list, compose an
 * fd_set for them to pass to select.
 */
static fd_set *fds_select_assemble(dlist_t *fds, fd_set *fdset, int *nfds)
{
  scamper_fd_poll_t *fdp;
  dlist_node_t      *node;
  int                count = 0;

  FD_ZERO(fdset);

  node = dlist_head_node(fds);
  while(node != NULL)
    {
      /* file descriptor associated with the node */
      fdp = (scamper_fd_poll_t *)dlist_node_item(node);

      /* get the next node incase this node is subsequently removed */
      node = dlist_node_next(node);

      /* if there is nothing using this fdn any longer, then stop polling it */
      if(fdp->fdn->refcnt == 0 && fdp->fdn->rc0 == NULL)
	{
	  fd_refcnt_0(fdp->fdn);
	  continue;
	}

      /* if the inactive flag is set, then skip over this file descriptor */
      if((fdp->flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0)
	{
	  dlist_node_eject(fds, fdp->node);
	  fdp->list = NULL;
	  continue;
	}

      /* monitor this file descriptor */
      FD_SET(fdp->fdn->fd, fdset);
      count++;

      /* update the maxfd seen if appropriate */
      if(*nfds < fdp->fdn->fd)
	{
	  *nfds = fdp->fdn->fd;
	}
    }

  /*
   * if there are no fds in the set to monitor, then return a null pointer
   * to pass to select
   */
  if(count == 0)
    {
      return NULL;
    }

  return fdset;
}
Ejemplo n.º 3
0
static rtsock_pair_t *rtsock_pair_get(uint16_t seq)
{
  rtsock_pair_t *pair;
  dlist_node_t  *node;

  for(node=dlist_head_node(pairs); node != NULL; node=dlist_node_next(node))
    {
      pair = dlist_node_item(node);
      if(pair->seq != seq)
	continue;
      dlist_node_pop(pairs, node);
      pair->node = NULL;
      return pair;
    }

  return NULL;
}
Ejemplo n.º 4
0
static void sniff_check(scamper_dl_rec_t *dl)
{
  scamper_task_sig_t *sig;
  s2t_t *s2t;
  dlist_node_t *n;
  scamper_addr_t src;
  uint16_t id;

  if(dlist_count(sniff) <= 0)
    return;

  if(SCAMPER_DL_IS_ICMP_ECHO_REPLY(dl))
    id = dl->dl_icmp_id;
  else if(SCAMPER_DL_IS_ICMP_Q_ICMP_ECHO(dl))
    id = dl->dl_icmp_icmp_id;
  else
    return;

  if(SCAMPER_DL_IS_IPV4(dl))
    src.type = SCAMPER_ADDR_TYPE_IPV4;
  else if(SCAMPER_DL_IS_IPV6(dl))
    src.type = SCAMPER_ADDR_TYPE_IPV6;
  else
    return;
  src.addr = dl->dl_ip_dst;

  for(n = dlist_head_node(sniff); n != NULL; n = dlist_node_next(n))
    {
      s2t = dlist_node_item(n); sig = s2t->sig;
      if(sig->sig_sniff_icmp_id != id)
	continue;
      if(scamper_addr_cmp(sig->sig_sniff_src, &src) != 0)
	continue;

      if(s2t->task->funcs->handle_dl != NULL)
	s2t->task->funcs->handle_dl(s2t->task, dl);
    }

  return;
}
Ejemplo n.º 5
0
static int fds_poll(struct timeval *tv)
{
  scamper_fd_t *fd;
  dlist_node_t *n;
  int timeout;
  int rc, count = 0, in = 0, out = 0;
  size_t size;

  n = dlist_head_node(fd_list);
  while(n != NULL)
    {
      fd = dlist_node_item(n);
      n  = dlist_node_next(n);

      /* if there is nothing using this fdn any longer, then stop polling it */
      if(fd->refcnt == 0 && fd->rc0 == NULL)
	{
	  fd_refcnt_0(fd);
	  continue;
	}

      /* don't poll an inactive fd */
      if((fd->read.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0 &&
	 (fd->write.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) != 0)
	continue;

      if(count + 1 > poll_fdc)
	{
	  size = (count+1) * sizeof(struct pollfd);
	  if(realloc_wrap((void **)&poll_fds, size) != 0)
	    {
	      printerror(errno,strerror,__func__,"could not realloc poll_fds");
	      return -1;
	    }
	  poll_fdc = count + 1;
	}

      poll_fds[count].fd = fd->fd;
      poll_fds[count].events = 0;
      poll_fds[count].revents = 0;

      if((fd->read.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) == 0)
	{
	  poll_fds[count].events |= POLLIN;
	  in++;
	}
      if((fd->write.flags & SCAMPER_FD_POLL_FLAG_INACTIVE) == 0)
	{
	  poll_fds[count].events |= POLLOUT;
	  out++;
	}

      count++;
    }

  if(tv != NULL)
    {
      timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
      if(timeout == 0 && tv->tv_usec != 0)
	timeout++;
    }
  else
    {
      timeout = -1;
    }

  if((rc = poll(poll_fds, count, timeout)) < 0)
    {
      printerror(errno, strerror, __func__, "could not poll");
      return -1;
    }

  if(rc > 0)
    {
      if(in != 0)
	fds_poll_check(POLLIN, rc < in ? rc : in, count);
      if(out != 0)
	fds_poll_check(POLLOUT, rc < out ? rc : out, count);
    }

  return 0;
}