|
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 |
|