Пример #1
0
static void
mowgli_linebuf_write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
	mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *) userdata;
	mowgli_linebuf_buf_t *buffer = &(linebuf->writebuf);
	int ret;

	if ((ret = mowgli_vio_write(linebuf->vio, buffer->buffer, buffer->buflen)) <= 0)
		if (linebuf->vio->error.code != MOWGLI_VIO_ERR_NONE)
			/* If we have a genuine error, we shouldn't come back to this func
			 * Otherwise we'll try again. */
			if (ret != 0)
			{
				mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
				mowgli_log("mowgli_vio_write returned error [%ld]: %s", linebuf->vio->error.code, linebuf->vio->error.string);
				return;
			}

	buffer->buflen -= ret;

	/* Anything else to write? */
	if (buffer->buflen == 0)
	{
		if (!mowgli_vio_hasflag(linebuf->vio, MOWGLI_VIO_FLAGS_NEEDWRITE))
			mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);

		if ((linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN) != 0)
			mowgli_linebuf_do_shutdown(linebuf);
	}
	else
	{
		mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
	}
}
Пример #2
0
/* Detach the linebuf instance from the eventloop */
void
mowgli_linebuf_detach_from_eventloop(mowgli_linebuf_t *linebuf)
{
	return_if_fail(linebuf != NULL);
	return_if_fail(linebuf->eventloop != NULL);
	mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_READ, NULL);
	mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
	mowgli_vio_eventloop_detach(linebuf->vio);
	linebuf->eventloop = NULL;
}
Пример #3
0
void
mowgli_helper_set_read_cb(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_proc_t *helper, mowgli_eventloop_io_cb_t *read_fn)
{
	return_if_fail(eventloop != NULL);
	return_if_fail(helper != NULL);

	if (read_fn == NULL)
		mowgli_pollable_setselect(eventloop, helper->pfd, MOWGLI_EVENTLOOP_IO_READ, NULL);

	helper->read_function = read_fn;
	mowgli_pollable_setselect(eventloop, helper->pfd, MOWGLI_EVENTLOOP_IO_READ, mowgli_helper_io_trampoline);
}
Пример #4
0
void
mowgli_linebuf_write(mowgli_linebuf_t *linebuf, const char *data, int len)
{
	char *ptr = linebuf->writebuf.buffer + linebuf->writebuf.buflen;

	return_if_fail(len > 0);
	return_if_fail(data != NULL);

	if (linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN)
		return;

	if (linebuf->writebuf.buflen + len + linebuf->endl_len > linebuf->writebuf.maxbuflen)
	{
		linebuf->flags |= MOWGLI_LINEBUF_ERR_WRITEBUF_FULL;
		mowgli_linebuf_error(linebuf->vio);
		return;
	}

	memcpy((void *) ptr, data, len);
	memcpy((void *) (ptr + len), linebuf->endl, linebuf->endl_len);

	linebuf->writebuf.buflen += len + linebuf->endl_len;

	/* Schedule our write */
	mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
}
Пример #5
0
u_link_origin *u_link_origin_create_from_fd(mowgli_eventloop_t *ev, int fd)
{
	const char *operation;
	u_link_origin *origin = NULL;

	/* Set the fd to be close-on-exec. All listening sockets will be closed when
	 * we upgrade. This may cause some slight disturbance for users currently
	 * connecting, but this is acceptable.
	 */
	operation = "set close-on-exec";
	if (set_cloexec(fd) < 0)
		goto error;

	u_log(LG_DEBUG, "u_link_origin_create_from_fd: %d", fd);

	origin = malloc(sizeof(*origin));

	operation = "create pollable";
	if (!(origin->poll = mowgli_pollable_create(ev, fd, origin))) {
		errno = -EINVAL; /* XXX */
		goto error;
	}

	mowgli_node_add(origin, &origin->n, &all_origins);
	mowgli_pollable_setselect(ev, origin->poll, MOWGLI_EVENTLOOP_IO_READ,
	                          accept_ready);

	return origin;
error:
	u_perror(operation);
	free(origin);
	return NULL;
}
Пример #6
0
/* Attach the linebuf instance to the eventloop -- socket must be created first with VIO instance! */
void
mowgli_linebuf_attach_to_eventloop(mowgli_linebuf_t *linebuf, mowgli_eventloop_t *eventloop)
{
	return_if_fail(eventloop != NULL);
	return_if_fail(linebuf != NULL);
	return_if_fail(linebuf->vio != NULL);
	return_if_fail((linebuf->vio->flags & MOWGLI_VIO_FLAGS_ISCLOSED) == 0);

#ifdef NOTYET
	mowgli_vio_eventloop_attach(linebuf->vio, eventloop, &linebuf_evops);
#else
	mowgli_vio_eventloop_attach(linebuf->vio, eventloop, NULL);
#endif
	mowgli_pollable_setselect(eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_READ, mowgli_linebuf_read_data);
	mowgli_pollable_setselect(eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);

	linebuf->eventloop = eventloop;
}
Пример #7
0
static void
mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
	mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *) userdata;
	mowgli_linebuf_buf_t *buffer = &(linebuf->readbuf);
	void *bufpos;
	size_t offset;
	int ret;

	if (buffer->maxbuflen - buffer->buflen == 0)
	{
		linebuf->flags |= MOWGLI_LINEBUF_ERR_READBUF_FULL;
		mowgli_linebuf_error(linebuf->vio);
		return;
	}

	bufpos = buffer->buffer + buffer->buflen;
	offset = buffer->maxbuflen - buffer->buflen + 1;

	if ((ret = mowgli_vio_read(linebuf->vio, bufpos, offset)) <= 0)
	{
		if (linebuf->vio->error.type == MOWGLI_VIO_ERR_NONE)
			return;

		/* Let's never come back here */
		mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_READ, NULL);
		mowgli_linebuf_do_shutdown(linebuf);
		return;
	}

	/* Le sigh -- stupid edge-triggered interfaces */
	if (mowgli_vio_hasflag(linebuf->vio, MOWGLI_VIO_FLAGS_NEEDREAD))
		mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_READ, mowgli_linebuf_read_data);

	/* Do we want a write for SSL? */
	if (mowgli_vio_hasflag(linebuf->vio, MOWGLI_VIO_FLAGS_NEEDWRITE))
		mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);

	buffer->buflen += ret;
	mowgli_linebuf_process(linebuf);
}
Пример #8
0
int
main(void)
{
	mowgli_eventloop_t *evloop = mowgli_eventloop_create();
	mowgli_dns_t *dns = mowgli_dns_create(evloop, MOWGLI_DNS_TYPE_ASYNC);
	mowgli_eventloop_pollable_t *stdin_pollable = mowgli_pollable_create(evloop, STDIN_FILENO, dns);

	mowgli_pollable_set_nonblocking(stdin_pollable, true);

	mowgli_pollable_setselect(evloop, stdin_pollable, MOWGLI_EVENTLOOP_IO_READ, read_data);

	mowgli_eventloop_run(evloop);

	mowgli_eventloop_destroy(evloop);

	return 0;
}
Пример #9
0
mowgli_eventloop_pollable_t* irc_connect(const char * host, const char * port)
{
    mowgli_eventloop_pollable_t* out;
    mowgli_descriptor_t fd;
    struct addrinfo hints, *res;
    
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    
    getaddrinfo(host, port, &hints, &res);

    fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    connect(fd, res->ai_addr, res->ai_addrlen);
    
    out = mowgli_pollable_create(base_eventloop, fd, NULL);
    mowgli_pollable_set_nonblocking(out, true);
    mowgli_pollable_setselect(base_eventloop, out, MOWGLI_EVENTLOOP_POLL_READ, irc_read);
    
    return out;
}
Пример #10
0
static int
linux_prepare(mowgli_eventloop_t *eventloop, mowgli_config_file_entry_t *entry)
{
	mowgli_eventloop_pollable_t *pollable;
	mowgli_config_file_entry_t *ce;
	char *interface = NULL;
	int fd;
	int ifindex = 0;
	bool promisc;

	MOWGLI_ITER_FOREACH(ce, entry)
	{
		if (!strcasecmp(ce->varname, "interface"))
			interface = strdup(ce->vardata);
		if (!strcasecmp(ce->varname, "promisc"))
			promisc = true;
	}

	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
	if (fd < 0)
		return;

	if (interface)
	{
		struct sockaddr_ll sll;
		struct ifreq ethreq = {};

		mowgli_strlcpy(ethreq.ifr_name, interface, IFNAMSIZ);
		ioctl(fd, SIOCGIFINDEX, &ethreq);

		DPRINTF("ifindex for %s: %d\n", interface, ethreq.ifr_ifindex);

		ifindex = ethreq.ifr_ifindex;

		sll.sll_family = AF_PACKET;
		sll.sll_protocol = htons(ETH_P_IP);
		sll.sll_ifindex = ifindex;

		if (bind(fd, (struct sockaddr *) &sll, sizeof sll) < 0)
		{
			DPRINTF("unable to bind(2) to interface '%s' (index %d): %s\n", interface, ifindex, strerror(errno));
			goto out;
		}

		DPRINTF("bound to interface '%s'\n", interface);
	}

	if (promisc)
	{
		struct packet_mreq mr;

		mr.mr_ifindex = ifindex;
		mr.mr_type = PACKET_MR_PROMISC;

		if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof mr) < 0)
		{
			DPRINTF("unable to add packet membership for fd=%d\n", fd);
			goto out;
		}

		DPRINTF("enabled promisc mode for fd=%d\n", fd);
	}

out:
	DPRINTF("opened raw packet socket as fd=%d\n", fd);

	pollable = mowgli_pollable_create(eventloop, fd, NULL);
	mowgli_pollable_setselect(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, linux_handle);
}