Blame lib/system/sockets.c

Packit Service 4684c1
/*
Packit Service 4684c1
 * Copyright (C) 2010-2016 Free Software Foundation, Inc.
Packit Service 4684c1
 * Copyright (C) 2015-2016 Red Hat, Inc.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Author: Nikos Mavrogiannopoulos
Packit Service 4684c1
 *
Packit Service 4684c1
 * This file is part of GnuTLS.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The GnuTLS is free software; you can redistribute it and/or
Packit Service 4684c1
 * modify it under the terms of the GNU Lesser General Public License
Packit Service 4684c1
 * as published by the Free Software Foundation; either version 2.1 of
Packit Service 4684c1
 * the License, or (at your option) any later version.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This library is distributed in the hope that it will be useful, but
Packit Service 4684c1
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 4684c1
 * Lesser General Public License for more details.
Packit Service 4684c1
 *
Packit Service 4684c1
 * You should have received a copy of the GNU Lesser General Public License
Packit Service 4684c1
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
Packit Service 4684c1
 *
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
#include <config.h>
Packit Service 4684c1
#include <system.h>
Packit Service 4684c1
#include "gnutls_int.h"
Packit Service 4684c1
#include "errors.h"
Packit Service 4684c1
Packit Service 4684c1
#include <sys/socket.h>
Packit Service 4684c1
#include <errno.h>
Packit Service 4684c1
#include <sys/stat.h>
Packit Service 4684c1
#include <sys/types.h>
Packit Service 4684c1
Packit Service 4684c1
#ifdef _WIN32
Packit Service 4684c1
# include <windows.h>
Packit Service 4684c1
#else /* !_WIN32 */
Packit Service 4684c1
# include <poll.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/* System specific socket function wrappers.
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
#ifdef _WIN32
Packit Service 4684c1
/* Do not use the gnulib functions for sending and receiving data.
Packit Service 4684c1
 * Using them makes gnutls only working with gnulib applications.
Packit Service 4684c1
 */
Packit Service 4684c1
#undef send
Packit Service 4684c1
#undef recv
Packit Service 4684c1
#undef select
Packit Service 4684c1
Packit Service 4684c1
int system_errno(gnutls_transport_ptr p)
Packit Service 4684c1
{
Packit Service 4684c1
	int tmperr = WSAGetLastError();
Packit Service 4684c1
	int ret = 0;
Packit Service 4684c1
	switch (tmperr) {
Packit Service 4684c1
	case WSAEWOULDBLOCK:
Packit Service 4684c1
		ret = EAGAIN;
Packit Service 4684c1
		break;
Packit Service 4684c1
	case NO_ERROR:
Packit Service 4684c1
		ret = 0;
Packit Service 4684c1
		break;
Packit Service 4684c1
	case WSAEINTR:
Packit Service 4684c1
		ret = EINTR;
Packit Service 4684c1
		break;
Packit Service 4684c1
	case WSAEMSGSIZE:
Packit Service 4684c1
		ret = EMSGSIZE;
Packit Service 4684c1
		break;
Packit Service 4684c1
	default:
Packit Service 4684c1
		ret = EIO;
Packit Service 4684c1
		break;
Packit Service 4684c1
	}
Packit Service 4684c1
	WSASetLastError(tmperr);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
ssize_t
Packit Service 4684c1
system_write(gnutls_transport_ptr ptr, const void *data, size_t data_size)
Packit Service 4684c1
{
Packit Service 4684c1
	return send(GNUTLS_POINTER_TO_INT(ptr), data, data_size, 0);
Packit Service 4684c1
}
Packit Service 4684c1
#else				/* POSIX */
Packit Service 4684c1
int system_errno(gnutls_transport_ptr_t ptr)
Packit Service 4684c1
{
Packit Service 4684c1
#if defined(_AIX) || defined(AIX)
Packit Service 4684c1
	if (errno == 0)
Packit Service 4684c1
		errno = EAGAIN;
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
	return errno;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static ssize_t
Packit Service 4684c1
_system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
Packit Service 4684c1
	      int iovec_cnt, int flags)
Packit Service 4684c1
{
Packit Service 4684c1
	struct msghdr hdr;
Packit Service 4684c1
Packit Service 4684c1
	memset(&hdr, 0, sizeof(hdr));
Packit Service 4684c1
	hdr.msg_iov = (struct iovec *)iovec;
Packit Service 4684c1
	hdr.msg_iovlen = iovec_cnt;
Packit Service 4684c1
Packit Service 4684c1
	return sendmsg(GNUTLS_POINTER_TO_INT(ptr), &hdr, flags);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#ifdef MSG_NOSIGNAL
Packit Service 4684c1
ssize_t
Packit Service 4684c1
system_writev_nosignal(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
Packit Service 4684c1
	      int iovec_cnt)
Packit Service 4684c1
{
Packit Service 4684c1
	return _system_writev(ptr, iovec, iovec_cnt, MSG_NOSIGNAL);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
ssize_t
Packit Service 4684c1
system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
Packit Service 4684c1
	      int iovec_cnt)
Packit Service 4684c1
{
Packit Service 4684c1
	return _system_writev(ptr, iovec, iovec_cnt, 0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
ssize_t
Packit Service 4684c1
system_read(gnutls_transport_ptr_t ptr, void *data, size_t data_size)
Packit Service 4684c1
{
Packit Service 4684c1
	return recv(GNUTLS_POINTER_TO_INT(ptr), data, data_size, 0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_system_recv_timeout:
Packit Service 4684c1
 * @ptr: A file descriptor (wrapped in a gnutls_transport_ptr_t pointer)
Packit Service 4684c1
 * @ms: The number of milliseconds to wait.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Wait for data to be received from the provided socket (@ptr) within a
Packit Service 4684c1
 * timeout period in milliseconds, using select() on the provided @ptr.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function is provided as a helper for constructing custom
Packit Service 4684c1
 * callbacks for gnutls_transport_set_pull_timeout_function(),
Packit Service 4684c1
 * which can be used if you rely on socket file descriptors.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns -1 on error, 0 on timeout, positive value if data are available for reading.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.0
Packit Service 4684c1
 **/
Packit Service 4684c1
int gnutls_system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	int fd = GNUTLS_POINTER_TO_INT(ptr);
Packit Service 4684c1
#ifndef _WIN32
Packit Service 4684c1
	int timeo;
Packit Service 4684c1
	struct pollfd pfd;
Packit Service 4684c1
Packit Service 4684c1
	pfd.fd = fd;
Packit Service 4684c1
	pfd.events = POLLIN;
Packit Service 4684c1
	pfd.revents = 0;
Packit Service 4684c1
Packit Service 4684c1
	if (ms == GNUTLS_INDEFINITE_TIMEOUT)
Packit Service 4684c1
		timeo = -1;
Packit Service 4684c1
	else
Packit Service 4684c1
		timeo = ms;
Packit Service 4684c1
	do {
Packit Service 4684c1
		ret = poll(&pfd, 1, timeo);
Packit Service 4684c1
	} while(ret == -1 && errno == EINTR);
Packit Service 4684c1
#else
Packit Service 4684c1
	fd_set rfds;
Packit Service 4684c1
	struct timeval _tv, *tv = NULL;
Packit Service 4684c1
Packit Service 4684c1
	FD_ZERO(&rfds);
Packit Service 4684c1
	FD_SET(fd, &rfds);
Packit Service 4684c1
Packit Service 4684c1
	if (ms != GNUTLS_INDEFINITE_TIMEOUT) {
Packit Service 4684c1
		_tv.tv_sec = ms/1000;
Packit Service 4684c1
		_tv.tv_usec = (ms % 1000) * 1000;
Packit Service 4684c1
		tv = &_tv;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = select(fd + 1, &rfds, NULL, NULL, tv);
Packit Service 4684c1
#endif
Packit Service 4684c1
	if (ret <= 0)
Packit Service 4684c1
		return ret;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1