Exemplo n.º 1
0
static ssize_t
tls_readv(struct wrap_io *wio, iovec_t *iov, int iovcnt)
{
    struct gnutella_socket *s = wio->ctx;
    ssize_t ret, done;
    int i;

    g_assert(socket_uses_tls(s));
    g_assert(iovcnt > 0);

    done = 0;
    ret = 0;
    for (i = 0; i < iovcnt; i++) {
        const size_t size = iovec_len(&iov[i]);

        ret = tls_read(wio, iovec_base(&iov[i]), size);
        if ((ssize_t) -1 == ret)
            break;
        done += (size_t) ret;
        if (size != (size_t) ret)
            break;
    }

    return done > 0 ? done : ret;
}
Exemplo n.º 2
0
/**
 * Write I/O vector.
 *
 * @return amount of bytes written, or -1 on error.
 */
static ssize_t
tx_deflate_writev(txdrv_t *tx, iovec_t *iov, int iovcnt)
{
	struct attr *attr = tx->opaque;
	int sent = 0;

	if (tx_deflate_debugging(9)) {
		g_debug("TX %s: (%s) (buffer #%d, nagle %s, unflushed %zu) [%c%c]",
			G_STRFUNC, gnet_host_to_string(&tx->host), attr->fill_idx,
			(attr->flags & DF_NAGLE) ? "on" : "off", attr->unflushed,
			(attr->flags & DF_FLOWC) ? 'C' : '-',
			(attr->flags & DF_FLUSH) ? 'f' : '-');
	}

	while (iovcnt-- > 0) {
		int ret;

		/*
		 * If we're flow controlled or shut down, stop sending.
		 */

		if (attr->flags & (DF_FLOWC|DF_SHUTDOWN))
			break;

		ret = deflate_add(tx, iovec_base(iov), iovec_len(iov));

		if (-1 == ret)
			return -1;

		sent += ret;
		if (UNSIGNED(ret) < iovec_len(iov)) {
			/* Could not write all, flow-controlled */
			break;
		}
		iov++;
	}

	if (tx_deflate_debugging(9)) {
		g_debug("TX %s: (%s) sent %lu bytes (buffer #%d, nagle %s, "
			"unflushed %zu) [%c%c]", G_STRFUNC,
			gnet_host_to_string(&tx->host), (ulong) sent, attr->fill_idx,
			(attr->flags & DF_NAGLE) ? "on" : "off", attr->unflushed,
			(attr->flags & DF_FLOWC) ? 'C' : '-',
			(attr->flags & DF_FLUSH) ? 'f' : '-');
	}
	return sent;
}
Exemplo n.º 3
0
ssize_t do_writev(struct epoll_event *p_entry, int epoll_fd, const struct iovec vec[], size_t cnt, bool more)
{
	g2_connection_t *w_entry = (g2_connection_t *)p_entry->data.ptr;
	ssize_t result = 0;

	if(!cnt)
		return 0;

	do	{
		set_s_errno(0);
		result = writev(w_entry->com_socket, vec, cnt);
	} while(-1 == result && EINTR == s_errno);

	switch(result)
	{
	default:
		if(!more && iovec_len(vec, cnt) <= (size_t)result)
		{
			shortlock_lock(&w_entry->pts_lock);
			w_entry->poll_interrests &= ~((uint32_t)EPOLLOUT);
			if(!(w_entry->poll_interrests & EPOLLONESHOT))
			{
				struct epoll_event t_entry;
				t_entry.data.u64 = p_entry->data.u64;
				t_entry.events = w_entry->poll_interrests;
				shortlock_unlock(&w_entry->pts_lock);

				if(0 > my_epoll_ctl(epoll_fd, EPOLL_CTL_MOD, w_entry->com_socket, &t_entry)) {
					logg_serrno(LOGF_DEBUG, "changing sockets Epoll-interrests");
					w_entry->flags.dismissed = true;
					result = -1;
				}
			}
			else
			{
				shortlock_unlock(&w_entry->pts_lock);

				if(w_entry->flags.dismissed) {
					logg_posd(LOGF_DEVEL_OLD, "%s Ip: %p#I\tFDNum: %i\n",
					          "Dismissed!", &w_entry->remote_host, w_entry->com_socket);
					result = -1;
				}
			}
		}
		break;
	case  0:
		if(iovec_len(vec, cnt))
		{
			if(EAGAIN != s_errno) {
				logg_posd(LOGF_DEVEL_OLD, "%s Ip: %p#I\tFDNum: %i\n",
				          "Dismissed!", &w_entry->remote_host, w_entry->com_socket);
				w_entry->flags.dismissed = true;
				result = -1;
			} else
				logg_devel("not ready to write\n");
		}
		else if(!more)
		{
			shortlock_lock(&w_entry->pts_lock);
			w_entry->poll_interrests &= ~((uint32_t)EPOLLOUT);
			if(!(w_entry->poll_interrests & EPOLLONESHOT))
			{
				struct epoll_event t_entry;
				t_entry.data.u64 = p_entry->data.u64;
				t_entry.events = w_entry->poll_interrests;
				shortlock_unlock(&w_entry->pts_lock);

				if(0 > my_epoll_ctl(epoll_fd, EPOLL_CTL_MOD, w_entry->com_socket, &t_entry)) {
					logg_serrno(LOGF_DEBUG, "changing sockets Epoll-interrests");
					w_entry->flags.dismissed = true;
					result = -1;
				}
			}
			else
			{
				shortlock_unlock(&w_entry->pts_lock);

				if(w_entry->flags.dismissed) {
					logg_posd(LOGF_DEBUG, "%s ERRNO=%i Ip: %p#I\tFDNum: %i\n",
					          "EOF reached!", s_errno, &w_entry->remote_host, w_entry->com_socket);
					result = -1;
				}
			}
		}
		break;
	case -1:
		if(EAGAIN != s_errno)
			logg_serrno(LOGF_DEBUG, "write");
		break;
	}
	return result;
}