⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buffer.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* buffer.c   Buffer access functions for the object management protocol... *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *   Internet Systems Consortium, Inc. *   950 Charter Street *   Redwood City, CA 94063 *   <info@isc.org> *   http://www.isc.org/ * * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. * To learn more about Internet Systems Consortium, see * ``http://www.isc.org/''.  To learn more about Vixie Enterprises, * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see * ``http://www.nominum.com''. */#include <omapip/omapip_p.h>#if defined (TRACING)static void trace_connection_input_input (trace_type_t *, unsigned, char *);static void trace_connection_input_stop (trace_type_t *);static void trace_connection_output_input (trace_type_t *, unsigned, char *);static void trace_connection_output_stop (trace_type_t *);static trace_type_t *trace_connection_input;static trace_type_t *trace_connection_output;static isc_result_t omapi_connection_reader_trace (omapi_object_t *,						   unsigned, char *,						   unsigned *);extern omapi_array_t *omapi_connections;void omapi_buffer_trace_setup (){	trace_connection_input =		trace_type_register ("connection-input",				     (void *)0,				     trace_connection_input_input,				     trace_connection_input_stop, MDL);	trace_connection_output =		trace_type_register ("connection-output",				     (void *)0,				     trace_connection_output_input,				     trace_connection_output_stop, MDL);}static void trace_connection_input_input (trace_type_t *ttype,					  unsigned length, char *buf){	unsigned left, taken, cc = 0;	char *s;	int32_t connect_index;	isc_result_t status;	omapi_connection_object_t *c = (omapi_connection_object_t *)0;	memcpy (&connect_index, buf, sizeof connect_index);	connect_index = ntohl (connect_index);	omapi_array_foreach_begin (omapi_connections,				   omapi_connection_object_t, lp) {		if (lp -> index == ntohl (connect_index)) {			omapi_connection_reference (&c, lp, MDL);			omapi_connection_dereference (&lp, MDL);			break;		}	} omapi_array_foreach_end (omapi_connections,				   omapi_connection_object_t, lp);	if (!c) {		log_error ("trace connection input: no connection index %ld",			   (long int)connect_index);		return;	}	s = buf + sizeof connect_index;	left = length - sizeof connect_index;	while (left) {		taken = 0;		status = omapi_connection_reader_trace ((omapi_object_t *)c,							left, s, &taken);		if (status != ISC_R_SUCCESS) {			log_error ("trace connection input: %s",				   isc_result_totext (status));			break;		}		if (!taken) {			if (cc > 0) {				log_error ("trace connection_input: %s",					   "input is not being consumed.");				break;			}			cc++;		} else {			cc = 0;			left -= taken;		}	}	omapi_connection_dereference (&c, MDL);}static void trace_connection_input_stop (trace_type_t *ttype) { }static void trace_connection_output_input (trace_type_t *ttype,					  unsigned length, char *buf){	/* We *could* check to see if the output is correct, but for now	   we aren't going to do that. */}static void trace_connection_output_stop (trace_type_t *ttype) { }#endif/* Make sure that at least len bytes are in the input buffer, and if not,   read enough bytes to make up the difference. */isc_result_t omapi_connection_reader (omapi_object_t *h){#if defined (TRACING)	return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)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;	/* Make sure c -> bytes_needed is valid. */	if (c -> bytes_needed < 0)		return ISC_R_INVALIDARG;		/* 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;}/* Put some bytes into the output buffer for a connection. */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;}/* Copy some bytes from the input buffer, and advance the input buffer   pointer beyond the bytes copied out. */isc_result_t omapi_connection_copyout (unsigned char *buf,				       omapi_object_t *h,				       unsigned size){	unsigned bytes_remaining;	unsigned bytes_this_copy;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -