Esempio n. 1
0
void
SOCK_put_next_byte(SocketClass *self, UCHAR next_byte)
{
	int	bytes_sent, pos = 0, retry_count = 0, gerrno;

	if (!self)
		return;
	if (0 != self->errornumber)
		return;
	self->buffer_out[self->buffer_filled_out++] = next_byte;

	if (self->buffer_filled_out == self->buffer_size)
	{
		/* buffer is full, so write it out */
		do
		{
#ifdef USE_SSL
			if (self->ssl)
				bytes_sent = SOCK_SSL_send(self, (char *) self->buffer_out + pos, self->buffer_filled_out);
			else
#endif /* USE_SSL */
			{
				bytes_sent = SOCK_SSPI_send(self, (char *) self->buffer_out + pos, self->buffer_filled_out);
			}
			gerrno = SOCK_ERRNO;
			if (bytes_sent < 0)
			{
				switch (gerrno)
				{
					case	EINTR:
						continue;
#ifdef EAGAIN
					case	EAGAIN:
#endif /* EAGAIN */
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
					case	EWOULDBLOCK:
#endif /* EWOULDBLOCK */
						retry_count++;
						if (SOCK_wait_for_ready(self, TRUE, retry_count) >= 0)
							continue;
				}
				if (0 == self->errornumber)
					SOCK_set_error(self, SOCKET_WRITE_ERROR, "Error while writing to the socket.");
				break;
			}
			pos += bytes_sent;
			self->buffer_filled_out -= bytes_sent;
			retry_count = 0;
		} while (self->buffer_filled_out > 0);
	}
}
Esempio n. 2
0
Int4
SOCK_flush_output(SocketClass *self)
{
	int	written, pos = 0, retry_count = 0, ttlsnd = 0, gerrno;

	if (!self)
		return -1;
	if (0 != self->errornumber)
		return -1;
	while (self->buffer_filled_out > 0)
	{
#ifdef USE_SSL 
		if (self->ssl)
			written = SOCK_SSL_send(self, (char *) self->buffer_out + pos, self->buffer_filled_out);
		else
#endif /* USE_SSL */
		{
			written = SOCK_SSPI_send(self, (char *) self->buffer_out + pos, self->buffer_filled_out);
		}
		gerrno = SOCK_ERRNO;
		if (written < 0)
		{
			switch (gerrno)
			{
				case EINTR:
					continue;
					break;
#ifdef EAGAIN
				case EAGAIN:
#endif /* EAGAIN */
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
				case EWOULDBLOCK:
#endif /* EWOULDBLOCK */
					retry_count++;
					if (SOCK_wait_for_ready(self, TRUE, retry_count) >= 0)
						continue;
					break;
			}
			SOCK_set_error(self, SOCKET_WRITE_ERROR, "Could not flush socket buffer.");
			return -1;
		}
		pos += written;
		self->buffer_filled_out -= written;
		ttlsnd += written;
		retry_count = 0;
	}
	
	return ttlsnd;
}
Esempio n. 3
0
/*
 *	recv more than 1 bytes using SSL.
 */
static int SOCK_SSL_recv(SocketClass *sock, void *buffer, int len)
{
	CSTR	func = "SOCK_SSL_recv";
	int n, err, gerrno, retry_count = 0;

retry:
	n = SSL_read(sock->ssl, buffer, len);
	err = SSL_get_error(sock->ssl, len);
	gerrno = SOCK_ERRNO;
inolog("%s: %d get_error=%d Lasterror=%d\n", func, n, err, gerrno);
	switch (err)
	{
		case	SSL_ERROR_NONE:
			break;
		case	SSL_ERROR_WANT_READ:
			retry_count++;
			if (SOCK_wait_for_ready(sock, FALSE, retry_count) >= 0)
				goto retry;
			n = -1;
			break;
		case	SSL_ERROR_WANT_WRITE:
			goto retry;
			break;
		case	SSL_ERROR_SYSCALL:
			if (-1 != n)
			{
				n = -1;
				SOCK_ERRNO_SET(ECONNRESET);
			}
			break;
		case	SSL_ERROR_SSL:
		case	SSL_ERROR_ZERO_RETURN:
			n = -1;
			SOCK_ERRNO_SET(ECONNRESET);
			break;
		default:
			n = -1;
	}

	return n;
}
Esempio n. 4
0
static int
SOCK_get_next_n_bytes(SocketClass *self, int n, char *buf)
{
	int	retry_count = 0, gerrno, rest, rlen;
	BOOL	maybeEOF = FALSE;

	if (!self || !n)
		return 0;
	for (rest = n; 0 < rest;)
	{
	if (self->buffer_read_in >= self->buffer_filled_in)
	{
		/*
		 * there are no more bytes left in the buffer so reload the buffer
		 */
		self->buffer_read_in = 0;
retry:
#ifdef USE_SSL 
		if (self->ssl)
			self->buffer_filled_in = SOCK_SSL_recv(self, (char *) self->buffer_in, self->buffer_size);
		else
#endif /* USE_SSL */
			self->buffer_filled_in = SOCK_SSPI_recv(self, (char *) self->buffer_in, self->buffer_size);
		gerrno = SOCK_ERRNO;

		mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size);

		if (self->buffer_filled_in < 0)
		{
mylog("Lasterror=%d\n", gerrno);
			switch (gerrno)
			{
				case	EINTR:
					goto retry;
					break;
#ifdef EAGAIN
				case	EAGAIN:
#endif /* EAGAIN */
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
				case	EWOULDBLOCK:
#endif /* EWOULDBLOCK */
					retry_count++;
					if (SOCK_wait_for_ready(self, FALSE, retry_count) >= 0)
						goto retry;
					break;
				case	ECONNRESET:
inolog("ECONNRESET\n");
					maybeEOF = TRUE;
					SOCK_set_error(self, SOCKET_CLOSED, "Connection reset by peer.");
					break;
			}
			if (0 == self->errornumber)
				SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket.");
			self->buffer_filled_in = 0;
			return -1;
		}
		if (self->buffer_filled_in == 0)
		{
			if (!maybeEOF)
			{
				int	nready = SOCK_wait_for_ready(self, FALSE, 0);
				if (nready > 0)
				{
					maybeEOF = TRUE;
					goto retry;
				}
				else if (0 == nready)
					maybeEOF = TRUE;
			}
			if (maybeEOF)
			{
				SOCK_set_error(self, SOCKET_CLOSED, "Socket has been closed.");
				break;
			}
			else
			{
				SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket.");
				return -1;
			}
		}
	}
	rlen = self->buffer_filled_in - self->buffer_read_in;
	if (rlen > rest)
		rlen = rest;
	if (buf)
		memcpy(buf + n - rest, self->buffer_in + self->buffer_read_in, rlen);
	rest -= rlen;
	if (PG_PROTOCOL_74 == self->pversion)
		self->reslen -= rlen;
	self->buffer_read_in += rlen;
	}

	return n - rest;
}
Esempio n. 5
0
UCHAR
SOCK_get_next_byte(SocketClass *self, BOOL peek)
{
	int	retry_count = 0, gerrno;
	BOOL	maybeEOF = FALSE;

	if (!self)
		return 0;
	if (self->buffer_read_in >= self->buffer_filled_in)
	{
		/*
		 * there are no more bytes left in the buffer so reload the buffer
		 */
		self->buffer_read_in = 0;
retry:
#ifdef USE_SSL 
		if (self->ssl)
			self->buffer_filled_in = SOCK_SSL_recv(self, (char *) self->buffer_in, self->buffer_size);
		else
#endif /* USE_SSL */
			self->buffer_filled_in = SOCK_SSPI_recv(self, (char *) self->buffer_in, self->buffer_size);
		gerrno = SOCK_ERRNO;

		mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size);

		if (self->buffer_filled_in < 0)
		{
mylog("Lasterror=%d\n", gerrno);
			switch (gerrno)
			{
				case	EINTR:
					goto retry;
					break;
#ifdef EAGAIN
				case	EAGAIN:
#endif /* EAGAIN */
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
				case	EWOULDBLOCK:
#endif /* EWOULDBLOCK */
					retry_count++;
					if (SOCK_wait_for_ready(self, FALSE, retry_count) >= 0)
						goto retry;
					break;
				case	ECONNRESET:
inolog("ECONNRESET\n");
					maybeEOF = TRUE;
					SOCK_set_error(self, SOCKET_CLOSED, "Connection reset by peer.");
					break;
			}
			if (0 == self->errornumber)
				SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket.");
			self->buffer_filled_in = 0;
			return 0;
		}
		if (self->buffer_filled_in == 0)
		{
			if (!maybeEOF)
			{
				int	nbytes = SOCK_wait_for_ready(self, FALSE, 0);
				if (nbytes > 0)
				{
					maybeEOF = TRUE;
					goto retry;
				}
				else if (0 == nbytes)
					maybeEOF = TRUE;
			}
			if (maybeEOF)
				SOCK_set_error(self, SOCKET_CLOSED, "Socket has been closed.");
			else
				SOCK_set_error(self, SOCKET_READ_ERROR, "Error while reading from the socket.");
			return 0;
		}
	}
	if (peek)
		return self->buffer_in[self->buffer_read_in];
	if (PG_PROTOCOL_74 == self->pversion)
		self->reslen--;
	return self->buffer_in[self->buffer_read_in++];
}