示例#1
0
/*
 * scamper_fd_private
 *
 * allocate a private fd for scamper to manage.  this fd is not shared amongst
 * scamper.
 */
scamper_fd_t *scamper_fd_private(int fd,
				 scamper_fd_cb_t read_cb, void *read_param,
				 scamper_fd_cb_t write_cb, void *write_param)
{
  scamper_fd_t *fdn = NULL;

  if((fdn = fd_alloc(SCAMPER_FD_TYPE_PRIVATE, fd)) == NULL)
    {
      goto err;
    }

  if((fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL)
    goto err;

  if(read_cb != NULL)
    {
      scamper_fd_read_set(fdn, read_cb, read_param);
      scamper_fd_read_unpause(fdn);
    }

  if(write_cb != NULL)
    {
      scamper_fd_write_set(fdn, write_cb, write_param);
      scamper_fd_write_unpause(fdn);
    }

  return fdn;

 err:
  if(fdn != NULL) fd_free(fdn);
  return NULL;
}
示例#2
0
scamper_fd_t *scamper_fd_dl(int ifindex)
{
  scamper_fd_t *fdn = NULL, findme;
  int fd = -1;

  findme.type = SCAMPER_FD_TYPE_DL;
  findme.fd_dl_ifindex = ifindex;

  if((fdn = fd_find(&findme)) != NULL)
    {
      scamper_fd_read_unpause(fdn);
      return fdn;
    }

  /*
   * open the file descriptor for the ifindex, and then allocate a scamper_fd
   * for the file descriptor
   */
  if((fd  = scamper_dl_open(ifindex)) == -1 ||
     (fdn = fd_alloc(SCAMPER_FD_TYPE_DL, fd)) == NULL)
    {
      goto err;
    }

  /*
   * record the ifindex for the file descriptor, and then allocate the state
   * that is maintained with it
   */
  fdn->fd_dl_ifindex = ifindex;

  /*
   * 1. add the file descriptor to the splay tree
   * 2. allocate state for the datalink file descriptor
   */
  if((fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL ||
     (fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL ||
     (fdn->fd_dl_dl = scamper_dl_state_alloc(fdn)) == NULL)
    {
      goto err;
    }

  /* set the file descriptor up for reading */
  fdn->read.cb     = scamper_dl_read_cb;
  fdn->read.param  = fdn->fd_dl_dl;
  fdn->write.cb    = NULL;
  fdn->write.param = NULL;
  scamper_fd_read_unpause(fdn);

  return fdn;

 err:
  if(fdn != NULL) free(fdn);
  if(fd != -1) scamper_dl_close(fd);
  return NULL;
}
示例#3
0
static scamper_fd_t *fd_tcp(int type, void *addr, uint16_t sport)
{
  scamper_fd_t *fdn, findme;
  size_t len = 0;
  int fd = -1;

  findme.type = type;
  findme.fd_tcp_addr = addr;
  findme.fd_tcp_sport = sport;

  if((fdn = fd_find(&findme)) != NULL)
    {
      return fdn;
    }

  if(type == SCAMPER_FD_TYPE_TCP4)
    {
      fd  = scamper_tcp4_open(addr, sport);
      len = sizeof(struct in_addr);
    }
  else if(type == SCAMPER_FD_TYPE_TCP6)
    {
      fd = scamper_tcp6_open(addr, sport);
      len = sizeof(struct in6_addr);
    }

  if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL ||
     (addr != NULL && (fdn->fd_tcp_addr = memdup(addr, len)) == NULL))
    {
      goto err;
    }
  fdn->fd_tcp_sport = sport;

  if((fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL ||
     (fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL)
    {
      goto err;
    }

  return fdn;

 err:
  if(fd != -1)
    {
      if(type == SCAMPER_FD_TYPE_TCP4)
	scamper_tcp4_close(fd);
      else if(type == SCAMPER_FD_TYPE_TCP6)
	scamper_tcp6_close(fd);
    }
  if(fdn != NULL) fd_free(fdn);
  return NULL;
}
scamper_task_anc_t *scamper_task_anc_add(scamper_task_t *task, void *data,
					 void (*freedata)(void *))
{
  scamper_task_anc_t *anc = NULL;
  if(task->ancillary == NULL && (task->ancillary = dlist_alloc()) == NULL)
    return NULL;
  if((anc = malloc_zero(sizeof(scamper_task_anc_t))) == NULL)
    return NULL;
  anc->data = data;
  anc->freedata = freedata;
  if((anc->node = dlist_tail_push(task->ancillary, anc)) == NULL)
    {
      free(anc);
      return NULL;
    }
  return anc;
}
int scamper_task_sig_install(scamper_task_t *task)
{
  scamper_task_sig_t *sig;
  scamper_task_t *tf;
  s2t_t *s2t;
  slist_node_t *n;

  if(slist_count(task->siglist) < 1)
    return -1;

  for(n=slist_head_node(task->siglist); n != NULL; n = slist_node_next(n))
    {
      s2t = slist_node_item(n); sig = s2t->sig;

      /* check if another task has this signature already */
      if((tf = scamper_task_find(sig)) != NULL)
	{
	  if(tf != task)
	    goto err;
	  continue;
	}

      if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_TX_IP)
	s2t->node = splaytree_insert(tx_ip, s2t);
      else if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_TX_ND)
	s2t->node = splaytree_insert(tx_nd, s2t);
      else if(sig->sig_type == SCAMPER_TASK_SIG_TYPE_SNIFF)
	s2t->node = dlist_tail_push(sniff, s2t);

      if(s2t->node == NULL)
	{
	  scamper_debug(__func__, "could not install sig");
	  goto err;
	}
    }

  return 0;

 err:
  scamper_task_sig_deinstall(task);
  return -1;
}
示例#6
0
/*
 * fd_refcnt_0
 *
 * this function is called whenever a fdn with a refcnt field of zero is
 * found.
 */
static void fd_refcnt_0(scamper_fd_t *fdn)
{
  /*
   * if the fd is in a list that is currently locked, then it can't be
   * removed just yet
   */
  if(dlist_islocked(fd_list) != 0 ||
     (fdn->read.list  != NULL && dlist_islocked(fdn->read.list)  != 0) ||
     (fdn->write.list != NULL && dlist_islocked(fdn->write.list) != 0))
    {
      return;
    }

  /*
   * if this is a private fd and the reference count has reached zero,
   * then the scamper_fd structure can be freed up completely now
   */
  if(fdn->type == SCAMPER_FD_TYPE_PRIVATE)
    {
      fd_free(fdn);
      return;
    }

  /* if it is not possible to put the node on a list, just free it */
  if((fdn->rc0 = dlist_tail_push(refcnt_0, fdn)) == NULL)
    {
      fd_close(fdn);
      fd_free(fdn);
      return;
    }

  /*
   * set this fd to be closed in ten seconds unless something else comes
   * along and wants to use it.
   */
  gettimeofday_wrap(&fdn->tv);
  fdn->tv.tv_sec += 10;

  return;
}
void *scamper_task_onhold(scamper_task_t *task, void *param,
			  void (*unhold)(void *param))
{
  task_onhold_t *toh = NULL;
  dlist_node_t *cookie;

  if(task->onhold == NULL && (task->onhold = dlist_alloc()) == NULL)
    goto err;
  if((toh = malloc_zero(sizeof(task_onhold_t))) == NULL)
    goto err;
  if((cookie = dlist_tail_push(task->onhold, toh)) == NULL)
    goto err;

  toh->param = param;
  toh->unhold = unhold;

  return cookie;

 err:
  if(toh != NULL) free(toh);
  return NULL;
}
示例#8
0
static scamper_fd_t *fd_null(int type)
{
  scamper_fd_t *fdn = NULL, findme;
  int fd = -1;

  /* first check if a sharable fd exists for this type */
  findme.type = type;
  if((fdn = fd_find(&findme)) != NULL)
    {
      return fdn;
    }

  if(type == SCAMPER_FD_TYPE_RTSOCK) fd = scamper_rtsock_open();
  else if(type == SCAMPER_FD_TYPE_IFSOCK) fd = socket(AF_INET, SOCK_DGRAM, 0);
  else if(type == SCAMPER_FD_TYPE_IP4) fd = scamper_ip4_openraw();

  if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL ||
     (fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL ||
     (fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL)
    {
      goto err;
    }

  return fdn;

 err:
  if(fd != -1)
    {
      if(type == SCAMPER_FD_TYPE_RTSOCK)
	scamper_rtsock_close(fd);
      else if(type == SCAMPER_FD_TYPE_IFSOCK)
	close(fd);
      else if(type == SCAMPER_FD_TYPE_IP4)
	scamper_ip4_close(fd);
    }
  if(fdn != NULL) fd_free(fdn);
  return NULL;
}
示例#9
0
static scamper_fd_t *fd_udp(int type, void *addr, uint16_t sport)
{
  scamper_fd_t *fdn, findme;
  size_t len = 0;
  int fd = -1;

  findme.type = type;
  findme.fd_udp_addr = addr;
  findme.fd_udp_sport = sport;

  if((fdn = fd_find(&findme)) != NULL)
    return fdn;

  if(type == SCAMPER_FD_TYPE_UDP4)
    {
      fd  = scamper_udp4_openraw(addr);
      len = sizeof(struct in_addr);
    }
  else if(type == SCAMPER_FD_TYPE_UDP6)
    {
      fd  = scamper_udp6_open(addr, sport);
      len = sizeof(struct in6_addr);
    }
  else if(type == SCAMPER_FD_TYPE_UDP4DG)
    {
      fd  = scamper_udp4_opendgram(addr, sport);
      len = sizeof(struct in_addr);
    }

  if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL ||
     (addr != NULL && (fdn->fd_udp_addr = memdup(addr, len)) == NULL))
    {
      printerror(errno, strerror, __func__, "could not open socket");
      goto err;
    }
  fdn->fd_udp_sport = sport;

  if((fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL)
    {
      printerror(errno, strerror, __func__, "could not add socket to tree");
      goto err;
    }
  if((fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL)
    {
      printerror(errno, strerror, __func__, "could not add socket to list");
      goto err;
    }

  return fdn;

 err:
  if(fd != -1)
    {
      if(type == SCAMPER_FD_TYPE_UDP4 || type == SCAMPER_FD_TYPE_UDP4DG)
	scamper_udp4_close(fd);
      else if(type == SCAMPER_FD_TYPE_UDP6)
	scamper_udp6_close(fd);
    }
  if(fdn != NULL) fd_free(fdn);
  return NULL;
}