Пример #1
0
static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
						   unsigned stuff_len,
						   char *stuff_buf,
						   unsigned *stuff_taken)
{
#endif
	omapi_buffer_t *buffer;
	isc_result_t status;
	unsigned read_len;
	int read_status;
	omapi_connection_object_t *c;
	unsigned bytes_to_read;
	
	if (!h || h -> type != omapi_type_connection)
		return ISC_R_INVALIDARG;
	c = (omapi_connection_object_t *)h;

	/* See if there are enough bytes. */
	if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
	    c -> in_bytes > c -> bytes_needed)
		return ISC_R_SUCCESS;


	if (c -> inbufs) {
		for (buffer = c -> inbufs; buffer -> next;
		     buffer = buffer -> next)
			;
		if (!BUFFER_BYTES_FREE (buffer)) {
			status = omapi_buffer_new (&buffer -> next, MDL);
			if (status != ISC_R_SUCCESS)
				return status;
			buffer = buffer -> next;
		}
	} else {
		status = omapi_buffer_new (&c -> inbufs, MDL);
		if (status != ISC_R_SUCCESS)
			return status;
		buffer = c -> inbufs;
	}

	bytes_to_read = BUFFER_BYTES_FREE (buffer);

	while (bytes_to_read) {
		if (buffer -> tail > buffer -> head)
			read_len = sizeof (buffer -> buf) - buffer -> tail;
		else
			read_len = buffer -> head - buffer -> tail;

#if defined (TRACING)
		if (trace_playback()) {
			if (stuff_len) {
				if (read_len > stuff_len)
					read_len = stuff_len;
				if (stuff_taken)
					*stuff_taken += read_len;
				memcpy (&buffer -> buf [buffer -> tail],
					stuff_buf, read_len);
				stuff_len -= read_len;
				stuff_buf += read_len;
				read_status = read_len;
			} else {
				break;
			}
		} else
#endif
		{
			read_status = read (c -> socket,
					    &buffer -> buf [buffer -> tail],
					    read_len);
		}
		if (read_status < 0) {
			if (errno == EWOULDBLOCK)
				break;
			else if (errno == EIO)
				return ISC_R_IOERROR;
			else if (errno == EINVAL)
				return ISC_R_INVALIDARG;
			else if (errno == ECONNRESET) {
				omapi_disconnect (h, 1);
				return ISC_R_SHUTTINGDOWN;
			} else
				return ISC_R_UNEXPECTED;
		}

		/* If we got a zero-length read, as opposed to EWOULDBLOCK,
		   the remote end closed the connection. */
		if (read_status == 0) {
			omapi_disconnect (h, 0);
			return ISC_R_SHUTTINGDOWN;
		}
#if defined (TRACING)
		if (trace_record ()) {
			trace_iov_t iov [2];
			int32_t connect_index;

			connect_index = htonl (c -> index);

			iov [0].buf = (char *)&connect_index;
			iov [0].len = sizeof connect_index;
			iov [1].buf = &buffer -> buf [buffer -> tail];
			iov [1].len = read_status;

			status = (trace_write_packet_iov
				  (trace_connection_input, 2, iov, MDL));
			if (status != ISC_R_SUCCESS) {
				trace_stop ();
				log_error ("trace connection input: %s",
					   isc_result_totext (status));
			}
		}
#endif
		buffer -> tail += read_status;
		c -> in_bytes += read_status;
		if (buffer -> tail == sizeof buffer -> buf)
			buffer -> tail = 0;
		if (read_status < read_len)
			break;
		bytes_to_read -= read_status;
	}

	if (c -> bytes_needed <= c -> in_bytes) {
		omapi_signal (h, "ready", c);
	}
	return ISC_R_SUCCESS;
}
Пример #2
0
isc_result_t omapi_connection_copyin (omapi_object_t *h,
				      const unsigned char *bufp,
				      unsigned len)
{
	omapi_buffer_t *buffer;
	isc_result_t status;
	int bytes_copied = 0;
	unsigned copy_len;
	int sig_flags = SIG_MODE_UPDATE;
	omapi_connection_object_t *c;

	/* Make sure len is valid. */
	//if (len < 0)
		//return ISC_R_INVALIDARG;
	if (!h || h -> type != omapi_type_connection)
		return ISC_R_INVALIDARG;
	c = (omapi_connection_object_t *)h;

	/* If the connection is closed, return an error if the caller
	   tries to copy in. */
	if (c -> state == omapi_connection_disconnecting ||
	    c -> state == omapi_connection_closed)
		return ISC_R_NOTCONNECTED;

	if (c -> outbufs) {
		for (buffer = c -> outbufs;
		     buffer -> next; buffer = buffer -> next)
			;
	} else {
		status = omapi_buffer_new (&c -> outbufs, MDL);
		if (status != ISC_R_SUCCESS)
			return status;
		buffer = c -> outbufs;
	}

	while (bytes_copied < len) {
		/* If there is no space available in this buffer,
                   allocate a new one. */
		if (!BUFFER_BYTES_FREE (buffer)) {
			status = (omapi_buffer_new (&buffer -> next, MDL));
			if (status != ISC_R_SUCCESS)
				return status;
			buffer = buffer -> next;
		}

		if (buffer -> tail > buffer -> head)
			copy_len = sizeof (buffer -> buf) - buffer -> tail;
		else
			copy_len = buffer -> head - buffer -> tail;

		if (copy_len > (len - bytes_copied))
			copy_len = len - bytes_copied;

		if (c -> out_key) {
			if (!c -> out_context)
				sig_flags |= SIG_MODE_INIT;
			status = omapi_connection_sign_data
				(sig_flags, c -> out_key, &c -> out_context,
				 &bufp [bytes_copied], copy_len,
				 (omapi_typed_data_t **)0);
			if (status != ISC_R_SUCCESS)
				return status;
		}

		memcpy (&buffer -> buf [buffer -> tail],
			&bufp [bytes_copied], copy_len);
		buffer -> tail += copy_len;
		c -> out_bytes += copy_len;
		bytes_copied += copy_len;
		if (buffer -> tail == sizeof buffer -> buf)
			buffer -> tail = 0;
	}
	return ISC_R_SUCCESS;
}
Пример #3
0
isc_result_t omapi_connection_copyin (omapi_object_t *h,
				      const unsigned char *bufp,
				      unsigned len)
{
	omapi_buffer_t *buffer;
	isc_result_t status;
	int bytes_copied = 0;
	unsigned copy_len;
	int sig_flags = SIG_MODE_UPDATE;
	omapi_connection_object_t *c;

	/* no need to verify len as it's unsigned */
	if (!h || h -> type != omapi_type_connection)
		return DHCP_R_INVALIDARG;
	c = (omapi_connection_object_t *)h;

	/* If the connection is closed, return an error if the caller
	   tries to copy in. */
	if (c -> state == omapi_connection_disconnecting ||
	    c -> state == omapi_connection_closed)
		return ISC_R_NOTCONNECTED;

	if (c -> outbufs) {
		for (buffer = c -> outbufs;
		     buffer -> next; buffer = buffer -> next)
			;
	} else {
		status = omapi_buffer_new (&c -> outbufs, MDL);
		if (status != ISC_R_SUCCESS)
			goto leave;
		buffer = c -> outbufs;
	}

	while (bytes_copied < len) {
		/* If there is no space available in this buffer,
                   allocate a new one. */
		if (!BUFFER_BYTES_FREE (buffer)) {
			status = (omapi_buffer_new (&buffer -> next, MDL));
			if (status != ISC_R_SUCCESS)
				goto leave;
			buffer = buffer -> next;
		}

		if (buffer -> tail > buffer -> head)
			copy_len = sizeof (buffer -> buf) - buffer -> tail;
		else
			copy_len = buffer -> head - buffer -> tail;

		if (copy_len > (len - bytes_copied))
			copy_len = len - bytes_copied;

		if (c -> out_key) {
			if (!c -> out_context)
				sig_flags |= SIG_MODE_INIT;
			status = omapi_connection_sign_data
				(sig_flags, c -> out_key, &c -> out_context,
				 &bufp [bytes_copied], copy_len,
				 (omapi_typed_data_t **)0);
			if (status != ISC_R_SUCCESS)
				goto leave;
		}

		memcpy (&buffer -> buf [buffer -> tail],
			&bufp [bytes_copied], copy_len);
		buffer -> tail += copy_len;
		c -> out_bytes += copy_len;
		bytes_copied += copy_len;
		if (buffer -> tail == sizeof buffer -> buf)
			buffer -> tail = 0;
	}

	status = ISC_R_SUCCESS;

 leave:
	/*
	 * If we have any bytes to send and we have a proper io object
	 * inform the socket code that we would like to know when we
	 * can send more bytes.
	 */
	if (c->out_bytes != 0) {
		if ((c->outer != NULL) &&
		    (c->outer->type == omapi_type_io_object)) {
			omapi_io_object_t *io = (omapi_io_object_t *)c->outer;
			isc_socket_fdwatchpoke(io->fd,
					       ISC_SOCKFDWATCH_WRITE);
		}
	}

	return (status);
}