Пример #1
0
static void
test_10()
{
	int i;
	slist sl;
	slist *l = &sl;

	slist_init(l);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);
	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);
	ASSERT((int)slist_itr_next(l) == 2);
	for (i = 4; i < 10000; i++) {
		ASSERT(slist_itr_has_next(l));
		ASSERT((int)slist_itr_next(l) == i - 1);
		if (i % 3 == 1)
			slist_add(l, (void *)i);
		if (i % 3 == 0)
			ASSERT((int)slist_itr_remove(l) == i - 1);
		if (i % 3 != 1)
			slist_add(l, (void *)i);
	}
	slist_itr_first(l);
	while (slist_itr_has_next(l)) {
		slist_itr_next(l);
		slist_itr_remove(l);
	}
	ASSERT((int)slist_length(l) == 0);

	slist_fini(l);
}
Пример #2
0
static void
test_itr_subr_01(slist *l)
{
	int i;

	for (i = 0; i < slist_length(l); i++)
		slist_set(l, i, (void *)(i + 1));

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);	/* normal iterate */
	ASSERT((int)slist_itr_next(l) == 2);	/* normal iterate */
	slist_remove(l, 2);		      /* remove next. "3" is removed */
	ASSERT((int)slist_itr_next(l) == 4);	/* removed item is skipped */
	slist_remove(l, 1);		 /* remove past item. "2" is removed */
	ASSERT((int)slist_itr_next(l) == 5);	/* no influence */
	ASSERT((int)slist_get(l, 0) == 1);	/* checking for removing */
	ASSERT((int)slist_get(l, 1) == 4);	/* checking for removing */
	ASSERT((int)slist_get(l, 2) == 5);	/* checking for removing */

	/*
	 * Total number was 255. We removed 2 items and iterated 4 times.
	 * 1 removing was past item, so the remaining is 250.
	 */

	for (i = 0; i < 249; i++)
		ASSERT(slist_itr_next(l) != NULL);
	ASSERT(slist_itr_next(l) != NULL);
	ASSERT(slist_itr_next(l) == NULL);

	/*
	 * Same as above except removing before getting the last item.
	 */

	/* Reset (253 items) */
	for (i = 0; i < slist_length(l); i++)
		slist_set(l, i, (void *)(i + 1));
	slist_itr_first(l);

	ASSERT(slist_length(l) == 253);

	for (i = 0; i < 252; i++)
		ASSERT(slist_itr_next(l) != NULL);

	slist_remove(l, 252);
	ASSERT(slist_itr_next(l) == NULL);	/* The last item is NULL */

	slist_itr_first(l);
	while (slist_length(l) > 0)
		slist_remove_first(l);
	ASSERT(slist_length(l) == 0);
	ASSERT(slist_itr_next(l) == NULL);
}
Пример #3
0
static void
test_08()
{
	slist sl;
	slist *l = &sl;

	slist_init(l);
	slist_set_size(l, 4);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	/* [1, 2, 3] */

	slist_itr_first(l);
	slist_itr_has_next(l);
	slist_itr_next(l);
	slist_itr_remove(l);
	/* [2, 3] */

	slist_add(l, (void *)4);
	/* [2, 3, 4] */
	ASSERT((int)slist_get(l, 0) == 2);
	ASSERT((int)slist_get(l, 1) == 3);
	ASSERT((int)slist_get(l, 2) == 4);
	slist_add(l, (void *)5);

	/* [2, 3, 4, 5] */
	ASSERT((int)slist_get(l, 0) == 2);
	ASSERT((int)slist_get(l, 1) == 3);
	ASSERT((int)slist_get(l, 2) == 4);
	ASSERT((int)slist_get(l, 3) == 5);
}
Пример #4
0
/* finalize L2TP daemon instance */
void
l2tpd_uninit(l2tpd *_this)
{
	l2tpd_listener *plsnr;

	L2TPD_ASSERT(_this != NULL);

	slist_fini(&_this->free_session_id_list);
	if (_this->ctrl_map != NULL) {
		hash_free(_this->ctrl_map);
		_this->ctrl_map = NULL;
	}

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plsnr = slist_itr_next(&_this->listener);
		L2TPD_ASSERT(plsnr != NULL);
		L2TPD_ASSERT(plsnr->sock == -1);
		free(plsnr);
	}
	slist_fini(&_this->listener);

	event_del(&_this->ev_timeout);	/* just in case */
	_this->state = L2TPD_STATE_STOPPED;
}
Пример #5
0
void
pptpd_uninit(pptpd *_this)
{
	pptpd_listener *plstn;

	slist_fini(&_this->ctrl_list);
	slist_fini(&_this->call_free_list);

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plstn = slist_itr_next(&_this->listener);
		PPTPD_ASSERT(plstn != NULL);
		PPTPD_ASSERT(plstn->sock == -1);
		PPTPD_ASSERT(plstn->sock_gre == -1);
		free(plstn);
	}
	slist_fini(&_this->listener);
	if (_this->call_id_map != NULL) {
		hash_free(_this->call_id_map);
	}
	if (_this->ip4_allow != NULL)
		in_addr_range_list_remove_all(&_this->ip4_allow);
	_this->call_id_map = NULL;
	_this->config = NULL;
}
Пример #6
0
int
pptpd_assign_call(pptpd *_this, pptp_call *call)
{
	int shuffle_cnt = 0, call_id;

	shuffle_cnt = 0;
	slist_itr_first(&_this->call_free_list);
	while (slist_length(&_this->call_free_list) > 1 &&
	    slist_itr_has_next(&_this->call_free_list)) {
		call_id = (int)slist_itr_next(&_this->call_free_list);
		if (call_id == 0)
			break;
		slist_itr_remove(&_this->call_free_list);
		if (call_id == PPTPD_SHUFFLE_MARK) {
			if (shuffle_cnt++ > 0)
				break;
			slist_shuffle(&_this->call_free_list);
			slist_add(&_this->call_free_list,
			    (void *)PPTPD_SHUFFLE_MARK);
			slist_itr_first(&_this->call_free_list);
			continue;
		}
		call->id = call_id;
		hash_insert(_this->call_id_map, CALL_MAP_KEY(call), call);

		return 0;
	}
	errno = EBUSY;
	pptpd_log(_this, LOG_ERR, "call request reached limit=%d",
	    PPTP_MAX_CALL);
	return -1;
}
Пример #7
0
/* start L2TP daemon */
int
l2tpd_start(l2tpd *_this)
{
	int rval;
	l2tpd_listener *plsnr;

	rval = 0;

	L2TPD_ASSERT(_this->state == L2TPD_STATE_INIT);
	if (_this->state != L2TPD_STATE_INIT) {
		l2tpd_log(_this, LOG_ERR, "Failed to start l2tpd: illegal "
		    "state.");
		return -1;
	}

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plsnr = slist_itr_next(&_this->listener);
		rval |= l2tpd_listener_start(plsnr);
	}

	if (rval == 0)
		_this->state = L2TPD_STATE_RUNNING;

	return rval;
}
Пример #8
0
/* stop PPPoE daemon */
void
pppoed_stop(pppoed *_this)
{
	pppoed_listener *plistener;
	hash_link *hl;
	pppoe_session *session;

	if (!pppoed_is_running(_this))
		return;

	_this->state = PPPOED_STATE_STOPPED;
	if (_this->session_hash != NULL) {
		for (hl = hash_first(_this->session_hash);
		    hl != NULL;
		    hl = hash_next(_this->session_hash)) {
			session = (pppoe_session *)hl->item;
			pppoe_session_disconnect(session);
			pppoe_session_stop(session);
		}
	}
	for (slist_itr_first(&_this->listener);
	    slist_itr_has_next(&_this->listener);) {
		plistener = slist_itr_next(&_this->listener);
		pppoed_listener_stop(plistener);
		free(plistener);
		slist_itr_remove(&_this->listener);
	}
	PPPOED_DBG((_this, LOG_DEBUG, "Stopped"));
}
Пример #9
0
/* start PPPoE daemon */
int
pppoed_start(pppoed *_this)
{
	int rval = 0;
	int nlistener_fail = 0;
	pppoed_listener *plistener;

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plistener = slist_itr_next(&_this->listener);
		PPPOED_ASSERT(plistener != NULL);
		if (plistener->bpf < 0) {
			if (pppoed_listener_start(plistener,
			    _this->listen_incomplete) != 0)
				nlistener_fail++;
		}
	}
	if (nlistener_fail > 0)
		_this->listen_incomplete = 1;
	else
		_this->listen_incomplete = 0;

	_this->state = PPPOED_STATE_RUNNING;

	return rval;
}
Пример #10
0
/*
 * Configuration
 */
int
l2tpd_reload(l2tpd *_this, struct l2tp_confs *l2tp_conf)
{
	int			 i;
	struct l2tp_conf	*conf;
	l2tpd_listener		*listener;
	struct l2tp_listen_addr	*addr;

	if (slist_length(&_this->listener) > 0) {
		/*
		 * TODO: add / remove / restart listener.
		 */
		slist_itr_first(&_this->listener);
		while (slist_itr_has_next(&_this->listener)) {
			listener = slist_itr_next(&_this->listener);
			TAILQ_FOREACH(conf, l2tp_conf, entry) {
				if (strcmp(listener->tun_name,
				    conf->name) == 0) {
					listener->conf = conf;
					break;
				}
			}
		}

		return 0;
	}
Пример #11
0
static void
pptpd_close_1723(pptpd *_this)
{
	pptpd_listener *plistener;

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plistener = slist_itr_next(&_this->listener);
		pptpd_listener_close_1723(plistener);
	}
}
Пример #12
0
/* stop immediattly without disconnect operation */
void
l2tpd_stop_immediatly(l2tpd *_this)
{
	l2tpd_listener *plsnr;

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plsnr = slist_itr_next(&_this->listener);
		l2tpd_listener_stop(plsnr);
	}
	event_del(&_this->ev_timeout);	/* XXX */
	_this->state = L2TPD_STATE_STOPPED;
}
Пример #13
0
/*
 * Add a {@link :l2tpd_listener} to the {@link ::l2tpd L2TP daemon}
 * @param	_this	{@link ::l2tpd L2TP daemon}
 * @param	idx	index of the lisnter
 * @param	tun_name	tunnel name (ex. "L2TP")
 * @param	bindaddr	bind address
 */
int
l2tpd_add_listener(l2tpd *_this, int idx, struct l2tp_conf *conf,
    struct sockaddr *addr)
{
	l2tpd_listener *plistener, *plsnr;

	plistener = NULL;
	if (idx == 0 && slist_length(&_this->listener) > 0) {
		slist_itr_first(&_this->listener);
		while (slist_itr_has_next(&_this->listener)) {
			slist_itr_next(&_this->listener);
			plsnr = slist_itr_remove(&_this->listener);
			L2TPD_ASSERT(plsnr != NULL);
			L2TPD_ASSERT(plsnr->sock == -1);
			free(plsnr);
		}
	}
	L2TPD_ASSERT(slist_length(&_this->listener) == idx);
	if (slist_length(&_this->listener) != idx) {
		l2tpd_log(_this, LOG_ERR,
		    "Invalid argument error on %s(): idx must be %d but %d",
		    __func__, slist_length(&_this->listener), idx);
		goto fail;
	}
	if ((plistener = calloc(1, sizeof(l2tpd_listener))) == NULL) {
		l2tpd_log(_this, LOG_ERR, "calloc() failed in %s: %m",
		    __func__);
		goto fail;
	}
	L2TPD_ASSERT(sizeof(plistener->bind) >= addr->sa_len);
	memcpy(&plistener->bind, addr, addr->sa_len);

	if (plistener->bind.sin6.sin6_port == 0)
		plistener->bind.sin6.sin6_port = htons(L2TPD_DEFAULT_UDP_PORT);

	plistener->sock = -1;
	plistener->self = _this;
	plistener->index = idx;
	plistener->conf = conf;
	strlcpy(plistener->tun_name, conf->name, sizeof(plistener->tun_name));

	if (slist_add(&_this->listener, plistener) == NULL) {
		l2tpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
		    __func__);
		goto fail;
	}
	return 0;
fail:
	free(plistener);
	return 1;
}
Пример #14
0
int
pptpd_start(pptpd *_this)
{
	int rval = 0;
	pptpd_listener *plistener;

	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plistener = slist_itr_next(&_this->listener);
		PPTPD_ASSERT(plistener != NULL);
		rval |= pptpd_listener_start(plistener);
	}
	if (rval == 0)
		_this->state = PPTPD_STATE_RUNNING;

	return rval;
}
Пример #15
0
/* process PADR from the peer */
int
pppoe_session_recv_PADR(pppoe_session *_this, slist *tag_list)
{
	pppoed *pppoed0 = _this->pppoed;
	struct pppoe_tlv *tlv, *hostuniq, *service_name, *ac_cookie;

	service_name = NULL;
	hostuniq = NULL;
	ac_cookie = NULL;
	for (slist_itr_first(tag_list); slist_itr_has_next(tag_list); ) {
		tlv = slist_itr_next(tag_list);
		if (tlv->type == PPPOE_TAG_HOST_UNIQ)
			hostuniq = tlv;
		if (tlv->type == PPPOE_TAG_SERVICE_NAME)
			service_name = tlv;
		if (tlv->type == PPPOE_TAG_AC_COOKIE)
			ac_cookie = tlv;
	}

	if (ac_cookie) {
		/* avoid a session which has already has cookie. */
		if (hash_lookup(pppoed0->acookie_hash,
		    (void *)ac_cookie->value) != NULL)
			goto fail;

		_this->acookie = *(uint32_t *)(ac_cookie->value);
		hash_insert(pppoed0->acookie_hash,
			(void *)(intptr_t)_this->acookie, _this);
	}

	if (pppoe_session_send_PADS(_this, hostuniq, service_name) != 0)
		goto fail;

	if (pppoe_session_bind_ppp(_this) != 0)
		goto fail;

	_this->state = PPPOE_SESSION_STATE_RUNNING;
	return 0;
fail:
	return -1;
}
Пример #16
0
static void
test_07()
{
	int i;
	slist sl;
	slist *l = &sl;

	slist_init(l);
	slist_add(l, (void *)1);
	slist_remove_first(l);
	l->first_idx = 120;
	l->last_idx = 120;
	for (i = 0; i < 255; i++)
		slist_add(l, (void *)i);


	for (i = 0, slist_itr_first(l); slist_itr_has_next(l); i++) {
		ASSERT((int)slist_itr_next(l) == i);
		if (i > 200)
		    ASSERT((int)slist_itr_remove(l) == i);
	}
}
Пример #17
0
static void
test_06()
{
	int i, j;
	slist sl;
	slist *l = &sl;

	slist_init(l);
	for (i = 0; i < 255; i++)
		slist_add(l, (void *)i);

	i = 255;

	for (slist_itr_first(l); slist_itr_has_next(l); ) {
		ASSERT(slist_length(l) == i);
		slist_itr_next(l);
		ASSERT((int)slist_itr_remove(l) == 255 - i);
		ASSERT(slist_length(l) == i - 1);
		for (j = i; j < slist_length(l); j++)
			ASSERT((int)slist_get(l, j) == i + j);
		i--;
	}
}
Пример #18
0
void
pptpd_stop(pptpd *_this)
{
	int nctrl;
	pptp_ctrl *ctrl;
	struct timeval tv;

	if (event_initialized(&_this->ev_timer))
		evtimer_del(&_this->ev_timer);
	pptpd_close_1723(_this);

	/* XXX: use common procedure with l2tpd_stop */

	if (pptpd_is_stopped(_this))
		return;
	if (pptpd_is_shutting_down(_this)) {
		pptpd_stop_immediatly(_this);
		return;
	}
	_this->state = PPTPD_STATE_SHUTTING_DOWN;
	nctrl = 0;
	for (slist_itr_first(&_this->ctrl_list);
	    (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) {
		pptp_ctrl_stop(ctrl, PPTP_CDN_RESULT_ADMIN_SHUTDOWN);
		nctrl++;
	}
	if (nctrl > 0) {
		tv.tv_sec = PPTPD_SHUTDOWN_TIMEOUT;
		tv.tv_usec = 0;

		evtimer_set(&_this->ev_timer, pptpd_stop_timeout, _this);
		evtimer_add(&_this->ev_timer, &tv);

		return;
	}
	pptpd_stop_immediatly(_this);
}
Пример #19
0
void
pptpd_stop_immediatly(pptpd *_this)
{
	pptp_ctrl *ctrl;

	if (event_initialized(&_this->ev_timer))
		evtimer_del(&_this->ev_timer);
	if (_this->state != PPTPD_STATE_STOPPED) {
		/* lock, to avoid multiple call from pptp_ctrl_stop() */
		_this->state = PPTPD_STATE_STOPPED;

		pptpd_close_1723(_this);
		for (slist_itr_first(&_this->ctrl_list);
		    (ctrl = slist_itr_next(&_this->ctrl_list)) != NULL;) {
			pptp_ctrl_stop(ctrl, 0);
		}
		pptpd_close_gre(_this);
		slist_fini(&_this->ctrl_list);
		slist_fini(&_this->call_free_list);
		pptpd_log(_this, LOG_NOTICE, "Stopped");
	} else {
		PPTPD_DBG((_this, LOG_DEBUG, "(Already) Stopped"));
	}
}
Пример #20
0
static void
test_09()
{
	slist sl;
	slist *l = &sl;

	/*
	 * #1
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_add(l, (void *)4);			/* add a new item */
	ASSERT(slist_itr_has_next(l));			/* iterates the new */
	ASSERT((int)slist_itr_next(l) == 4);
	slist_fini(l);


	/*
	 * #2
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_itr_remove(l);				/* and remove the last*/
	slist_add(l, (void *)4);			/* add 4 (new last)*/
	ASSERT(slist_itr_has_next(l));			/* */
	ASSERT((int)slist_itr_next(l) == 4);		/* 4 */
	slist_fini(l);

	/*
	 * #3
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_add(l, (void *)4);			/* add a new */
	slist_itr_remove(l);
	ASSERT(slist_itr_has_next(l));
	ASSERT((int)slist_itr_next(l) == 4);		/* 4 */
	slist_fini(l);

	/*
	 * #4 - remove iterator's next and it is the last
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	slist_remove(l, 2);				/* remove the next */
	slist_add(l, (void *)4);			/* add the new next */
	ASSERT(slist_itr_has_next(l));			/* iterates the new */
	ASSERT((int)slist_itr_next(l) == 4);
	slist_fini(l);
}
Пример #21
0
/** Reload the account list */
static int
npppd_auth_reload_acctlist(npppd_auth_base *base)
{
	CSVREADER_STATUS status;
	int linno, ncols, usersz, nuser, eof, off;
	const char **cols, *passwd, *callnum;
	char line[8192];
	csvreader *csv;
	npppd_auth_user *user;
	struct in_addr ip4, ip4mask;
	slist users;
	FILE *file;
	struct stat st;

	if (base->acctlist_ready != 0 && lstat(base->acctlist_path, &st) == 0) {
		if (st.st_mtime == base->last_load)
			return 0;
		base->last_load = st.st_mtime;
	}

	slist_init(&users);
	csv = NULL;
	if ((file = priv_fopen(base->acctlist_path)) == NULL) {
		/* hash is empty if file is not found. */
		if (errno == ENOENT)
			hash_delete_all(base->users_hash, 1);
		npppd_auth_base_log(base,
		    (errno == ENOENT)? LOG_DEBUG : LOG_ERR,
		    "Open %s failed: %m", base->acctlist_path);
		return 0;
	}
	if ((csv = csvreader_create()) == NULL) {
		npppd_auth_base_log(base, LOG_ERR,
		    "Loading a account list failed: csvreader_create(): %m");
		goto fail;
	}

	for (linno = 0, eof = 0; !eof;) {
		ip4.s_addr = 0;
		ip4mask.s_addr = 0xffffffffL;
		if (fgets(line, sizeof(line), file) != NULL) {
			int linelen;

			linelen = strlen(line);
			if (linelen <= 0) {
				npppd_auth_base_log(base, LOG_ERR,
				    "Loading a account list failed: lineno=%d "
				    "line too short", linno + 1);
				goto fail;
			}
			if (line[linelen - 1] != '\n' && !feof(file)) {
				npppd_auth_base_log(base, LOG_ERR,
				    "Loading a account list failed: lineno=%d "
				    "line too long", linno + 1);
				goto fail;
			}

			status = csvreader_parse(csv, line);
		} else {
			if (!feof(file)) {
				npppd_auth_base_log(base, LOG_ERR,
				    "Loading a account list failed: %m");
				goto fail;
			}
			status = csvreader_parse_flush(csv);
			eof = 1;
		}
		if (status != CSVREADER_NO_ERROR) {
			if (status == CSVREADER_OUT_OF_MEMORY)
				npppd_auth_base_log(base, LOG_ERR,
				    "Loading a account list failed: %m");
			else
				npppd_auth_base_log(base, LOG_ERR,
				    "Loading a account list "
				    "failed: lineno=%d parse error", linno);
			goto fail;
		}
		ncols = csvreader_get_number_of_column(csv);
		if ((cols = csvreader_get_column(csv)) == NULL)
			continue;
		linno++; /* count up here because line number is treated as CSV. */
		if (linno == 1) {
			/* skip a title line */
			continue;
		}
		if (ncols < 1) {
			npppd_auth_base_log(base, LOG_ERR,
			    "account list lineno=%d has only %d fields.",
			    linno, ncols);
			continue;
		}
		if (strlen(cols[0]) <= 0)
			continue;	/* skip if the user-name is empty */
		if (ncols >= 3) {
			if (*cols[2] != '\0' && inet_aton(cols[2], &ip4) != 1) {
				npppd_auth_base_log(base, LOG_ERR,
				    "account list lineno=%d parse error: "
				    "invalid 'Framed-IP-Address' field: %s",
				    linno, cols[2]);
				continue;
			}
		}
		if (ncols >= 4) {
			if ((*cols[3] != '\0' &&
			    inet_aton(cols[3], &ip4mask) != 1) ||
			    netmask2prefixlen(htonl(ip4mask.s_addr)) < 0) {
				npppd_auth_base_log(base, LOG_ERR,
				    "account list lineno=%d parse error: "
				    "invalid 'Framed-IP-Netmask' field: %s",
				    linno, cols[3]);
				continue;
			}
		}

		passwd = "";
		if (cols[1] != NULL)
			passwd = cols[1];
		callnum = "";
		if (ncols >= 6 && cols[5] != NULL)
			callnum = cols[5];

		usersz = sizeof(npppd_auth_user);
		usersz += strlen(cols[0]) + 1;
		usersz += strlen(passwd) + 1;
		usersz += strlen(callnum) + 1;
		if ((user = malloc(usersz)) == NULL) {
			npppd_auth_base_log(base, LOG_ERR,
			    "Loading a account list failed: %m");
			goto fail;
		}
		memset(user, 0, usersz);

		off = 0;

		user->username = user->space + off;
		off += strlcpy(user->username, cols[0], usersz - off);
		++off;

		user->password = user->space + off;
		off += strlcpy(user->password, passwd, usersz - off);
		++off;

		user->calling_number = user->space + off;
		strlcpy(user->calling_number, callnum, usersz - off);

		user->framed_ip_address = ip4;
		user->framed_ip_netmask = ip4mask;

		slist_add(&users, user);
	}
	hash_delete_all(base->users_hash, 1);

	nuser = 0;
	for (slist_itr_first(&users); slist_itr_has_next(&users);) {
		user = slist_itr_next(&users);
		if (hash_lookup(base->users_hash, user->username) != NULL) {
			npppd_auth_base_log(base, LOG_WARNING,
			    "Record for user='******' is redefined, the first "
			    "record will be used.",  user->username);
			free(user);
			goto next_user;
		}
		if (hash_insert(base->users_hash, user->username, user) != 0) {
			npppd_auth_base_log(base, LOG_ERR,
			    "Loading a account list failed: hash_insert(): %m");
			goto fail;
		}
		nuser++;
next_user:
		slist_itr_remove(&users);
	}
	slist_fini(&users);
	csvreader_destroy(csv);

	fclose(file);
	npppd_auth_base_log(base, LOG_INFO,
	    "Loaded users from='%s' successfully.  %d users",
	    base->acctlist_path, nuser);
	base->acctlist_ready = 1;

	return 0;
fail:
	fclose(file);
	if (csv != NULL)
		csvreader_destroy(csv);
	hash_delete_all(base->users_hash, 1);
	for (slist_itr_first(&users); slist_itr_has_next(&users);) {
		user = slist_itr_next(&users);
		free(user);
	}
	slist_fini(&users);

	return 1;
}
Пример #22
0
/* timeout processing */
static void
l2tp_ctrl_timeout(int fd, short evtype, void *ctx)
{
	int next_timeout, need_resend;
	time_t curr_time;
	l2tp_ctrl *_this;
	l2tp_call *call;

	/*
	 * the timer must be reset, when leave this function.
	 * MEMO: l2tp_ctrl_stop() will reset the timer in it.
	 * and please remember that the l2tp_ctrl_stop() may free _this.
	 */
	_this = ctx;
	L2TP_CTRL_ASSERT(_this != NULL);

	curr_time = get_monosec();

	next_timeout = 2;
	need_resend = 0;

	if (l2tp_ctrl_txwin_size(_this) > 0)  {
		if (_this->state == L2TP_CTRL_STATE_ESTABLISHED) {
			if (_this->hello_wait_ack != 0) {
				/* wait Hello reply */
				if (curr_time - _this->hello_io_time >=
				    _this->hello_timeout) {
					l2tp_ctrl_log(_this, LOG_NOTICE,
					    "timeout waiting ack for hello "
					    "packets.");
					l2tp_ctrl_stop(_this,
					    L2TP_STOP_CCN_RCODE_GENERAL);
					return;
				}
			}
		} else if (curr_time - _this->last_snd_ctrl >=
		    L2TP_CTRL_CTRL_PKT_TIMEOUT) {
			l2tp_ctrl_log(_this, LOG_NOTICE,
			    "timeout waiting ack for ctrl packets.");
			l2tp_ctrl_stop(_this,
			    L2TP_STOP_CCN_RCODE_GENERAL);
			return;
		}
		need_resend = 1;
	} else {
		for (slist_itr_first(&_this->call_list);
		    slist_itr_has_next(&_this->call_list);) {
			call = slist_itr_next(&_this->call_list);
			if (call->state == L2TP_CALL_STATE_CLEANUP_WAIT) {
				l2tp_call_destroy(call, 1);
				slist_itr_remove(&_this->call_list);
			}
		}
	}

	switch (_this->state) {
	case L2TP_CTRL_STATE_IDLE:
		/*
		 * idle:
		 * XXX: never happen in current implementation
		 */
		l2tp_ctrl_log(_this, LOG_ERR,
		    "Internal error, timeout on illegal state=idle");
		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
		break;
	case L2TP_CTRL_STATE_WAIT_CTL_CONN:
		/*
		 * wait-ctrl-conn:
		 * 	if there is no ack for SCCRP, the peer will
		 * 	resend SCCRQ. however this implementation can
		 *	not recognize that the SCCRQ was resent or not.
		 *	Therefore, never resent from this side.
		 */
		need_resend = 0;
		break;
	case L2TP_CTRL_STATE_ESTABLISHED:
		if (slist_length(&_this->call_list) == 0 &&
		    curr_time - _this->last_snd_ctrl >=
			    L2TP_CTRL_WAIT_CALL_TIMEOUT) {
			if (_this->ncalls == 0)
				/* fail to receive first call */
				l2tp_ctrl_log(_this, LOG_WARNING,
				    "timeout waiting call");
			l2tp_ctrl_stop(_this,
			    L2TP_STOP_CCN_RCODE_GENERAL);
			return;
		}
		if (_this->hello_wait_ack == 0 && _this->hello_interval > 0) {
			/* send Hello */
			if (curr_time - _this->hello_interval >=
			    _this->hello_io_time) {
				if (l2tp_ctrl_send_HELLO(_this) == 0)
					/* success */
					_this->hello_wait_ack = 1;
				_this->hello_io_time = curr_time;
				need_resend = 0;
			}
		}
		break;
	case L2TP_CTRL_STATE_CLEANUP_WAIT:
		if (curr_time - _this->last_snd_ctrl >=
		    L2TP_CTRL_CLEANUP_WAIT_TIME) {
			l2tp_ctrl_log(_this, LOG_NOTICE,
			    "Cleanup timeout state=%d", _this->state);
			l2tp_ctrl_stop(_this, 0);
			return;
		}
		if (_this->active_closing != 0)
			l2tp_ctrl_send_disconnect_notify(_this);
		break;
	default:
		l2tp_ctrl_log(_this, LOG_ERR,
		    "Internal error, timeout on illegal state=%d",
			_this->state);
		l2tp_ctrl_stop(_this, L2TP_STOP_CCN_RCODE_GENERAL);
		return;
	}
	/* resend if required */
	if (need_resend)
		l2tp_ctrl_resend_una_packets(_this);
	l2tp_ctrl_reset_timeout(_this);
}
Пример #23
0
/* add a listner to pptpd daemon context */
int
pptpd_add_listener(pptpd *_this, int idx, const char *label,
    struct sockaddr *bindaddr)
{
	int inaddr_any;
	pptpd_listener *plistener, *plstn;

	plistener = NULL;
	if (idx == 0 && slist_length(&_this->listener) > 0) {
		slist_itr_first(&_this->listener);
		while (slist_itr_has_next(&_this->listener)) {
			slist_itr_next(&_this->listener);
			plstn = slist_itr_remove(&_this->listener);
			PPTPD_ASSERT(plstn != NULL);
			PPTPD_ASSERT(plstn->sock == -1);
			PPTPD_ASSERT(plstn->sock_gre == -1);
			free(plstn);
		}
	}
	PPTPD_ASSERT(slist_length(&_this->listener) == idx);
	if (slist_length(&_this->listener) != idx) {
		pptpd_log(_this, LOG_ERR,
		    "Invalid argument error on %s(): idx must be %d but %d",
		    __func__, slist_length(&_this->listener), idx);
		goto fail;
	}
	if ((plistener = malloc(sizeof(pptpd_listener))) == NULL) {
		pptpd_log(_this, LOG_ERR, "malloc() failed in %s: %m",
		    __func__);
		goto fail;
	}
	memset(plistener, 0, sizeof(pptpd_listener));

	PPTPD_ASSERT(sizeof(plistener->bind_sin) >= bindaddr->sa_len);
	memcpy(&plistener->bind_sin, bindaddr, bindaddr->sa_len);
	memcpy(&plistener->bind_sin_gre, bindaddr, bindaddr->sa_len);

	if (plistener->bind_sin.sin_port == 0)
		plistener->bind_sin.sin_port = htons(PPTPD_DEFAULT_TCP_PORT);

	/* When a raw socket binds both of an INADDR_ANY and specific IP
	 * address sockets, packets will be received by those sockets
	 * simultaneously. To avoid this duplicate receives, not
	 * permit such kind of configuration */
	inaddr_any = 0;
	slist_itr_first(&_this->listener);
	while (slist_itr_has_next(&_this->listener)) {
		plstn = slist_itr_next(&_this->listener);
		if (plstn->bind_sin_gre.sin_addr.s_addr == INADDR_ANY)
			inaddr_any++;
	}
	if (plistener->bind_sin_gre.sin_addr.s_addr == INADDR_ANY)
		inaddr_any++;
	if (inaddr_any > 0 && idx > 0) {
		log_printf(LOG_ERR, "configuration error at pptpd.listener_in: "
		    "combination 0.0.0.0 and other address is not allowed.");
		goto fail;
	}

	plistener->bind_sin_gre.sin_port = 0;
	plistener->sock = -1;
	plistener->sock_gre = -1;
	plistener->self = _this;
	plistener->index = idx;
	strlcpy(plistener->phy_label, label, sizeof(plistener->phy_label));

	if (slist_add(&_this->listener, plistener) == NULL) {
		pptpd_log(_this, LOG_ERR, "slist_add() failed in %s: %m",
		    __func__);
		goto fail;
	}
	return 0;
fail:
	if (plistener != NULL)
		free(plistener);
	return 1;
}