/* * 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; }
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; }
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; }
/* * 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; }
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; }
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; }