diff options
author | Michael Brown | 2010-06-16 02:31:29 +0200 |
---|---|---|
committer | Michael Brown | 2010-06-22 16:50:31 +0200 |
commit | 4327d5d39f101f1df0ace6c03f3b3ada5f6a6213 (patch) | |
tree | ccf92bdfd23046b6c7f64f87b57350f02f63ad6f /src/core/xfer.c | |
parent | [interface] Convert all name-resolution interfaces to generic interfaces (diff) | |
download | ipxe-4327d5d39f101f1df0ace6c03f3b3ada5f6a6213.tar.gz ipxe-4327d5d39f101f1df0ace6c03f3b3ada5f6a6213.tar.xz ipxe-4327d5d39f101f1df0ace6c03f3b3ada5f6a6213.zip |
[interface] Convert all data-xfer interfaces to generic interfaces
Remove data-xfer as an interface type, and replace data-xfer
interfaces with generic interfaces supporting the data-xfer methods.
Filter interfaces (as used by the TLS layer) are handled using the
generic pass-through interface capability. A side-effect of this is
that deliver_raw() no longer exists as a data-xfer method. (In
practice this doesn't lose any efficiency, since there are no
instances within the current codebase where xfer_deliver_raw() is used
to pass data to an interface supporting the deliver_raw() method.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/xfer.c')
-rw-r--r-- | src/core/xfer.c | 371 |
1 files changed, 126 insertions, 245 deletions
diff --git a/src/core/xfer.c b/src/core/xfer.c index 8dbfef6c..057ab8b3 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -21,7 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <string.h> #include <stdio.h> #include <errno.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> +#include <ipxe/open.h> /** @file * @@ -37,178 +39,206 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ static struct xfer_metadata dummy_metadata; -/** - * Close data transfer interface +/***************************************************************************** + * + * Data transfer interface operations * - * @v xfer Data transfer interface - * @v rc Reason for close */ -void xfer_close ( struct xfer_interface *xfer, int rc ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); - struct xfer_interface_operations *op = xfer->op; - - DBGC ( xfer, "XFER %p->%p close\n", xfer, dest ); - - xfer_unplug ( xfer ); - xfer_nullify ( xfer ); - dest->op->close ( dest, rc ); - xfer->op = op; - xfer_put ( dest ); -} /** * Send redirection event * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type New location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +int xfer_vredirect ( struct interface *intf, int type, va_list args ) { + struct interface *dest; + xfer_vredirect_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_vredirect, &dest ); + void *object = intf_object ( dest ); int rc; - DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect\n", + INTF_INTF_DBG ( intf, dest ) ); - rc = dest->op->vredirect ( dest, type, args ); + if ( op ) { + rc = op ( object, type, args ); + } else { + /* Default is to reopen the interface as instructed */ + rc = xfer_vreopen ( dest, type, args ); + } if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest, + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect " + "failed: %s\n", INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); } - xfer_put ( dest ); - return rc; -} -/** - * Send redirection event - * - * @v xfer Data transfer interface - * @v type New location type - * @v ... Remaining arguments depend upon location type - * @ret rc Return status code - */ -int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) { - va_list args; - int rc; - - va_start ( args, type ); - rc = xfer_vredirect ( xfer, type, args ); - va_end ( args ); + intf_put ( dest ); return rc; } /** * Check flow control window * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @ret len Length of window */ -size_t xfer_window ( struct xfer_interface *xfer ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +size_t xfer_window ( struct interface *intf ) { + struct interface *dest; + xfer_window_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_window, &dest ); + void *object = intf_object ( dest ); size_t len; - len = dest->op->window ( dest ); + if ( op ) { + len = op ( object ); + } else { + /* Default is to provide an unlimited window */ + len = ~( ( size_t ) 0 ); + } - xfer_put ( dest ); + intf_put ( dest ); return len; } /** * Allocate I/O buffer * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v len I/O buffer payload length * @ret iobuf I/O buffer */ -struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +struct io_buffer * xfer_alloc_iob ( struct interface *intf, size_t len ) { + struct interface *dest; + xfer_alloc_iob_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_alloc_iob, &dest ); + void *object = intf_object ( dest ); struct io_buffer *iobuf; - DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob %zd\n", + INTF_INTF_DBG ( intf, dest ), len ); - iobuf = dest->op->alloc_iob ( dest, len ); + if ( op ) { + iobuf = op ( object, len ); + } else { + /* Default is to allocate an I/O buffer with no + * reserved space. + */ + iobuf = alloc_iob ( len ); + } if ( ! iobuf ) { - DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob " + "failed\n", INTF_INTF_DBG ( intf, dest ) ); } - xfer_put ( dest ); + + intf_put ( dest ); return iobuf; } /** - * Deliver datagram as I/O buffer with metadata + * Deliver datagram * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -int xfer_deliver_iob_meta ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); +int xfer_deliver ( struct interface *intf, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { + struct interface *dest; + xfer_deliver_TYPE ( void * ) *op = + intf_get_dest_op ( intf, xfer_deliver, &dest ); + void *object = intf_object ( dest ); int rc; - DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest, - iob_len ( iobuf ) ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " deliver %zd\n", + INTF_INTF_DBG ( intf, dest ), iob_len ( iobuf ) ); - rc = dest->op->deliver_iob ( dest, iobuf, meta ); + if ( op ) { + rc = op ( object, iobuf, meta ); + } else { + /* Default is to discard the I/O buffer */ + free_iob ( iobuf ); + rc = -EPIPE; + } if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest, - strerror ( rc ) ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT + " deliver failed: %s\n", + INTF_INTF_DBG ( intf, dest ), strerror ( rc ) ); } - xfer_put ( dest ); + + intf_put ( dest ); + return rc; +} + +/***************************************************************************** + * + * Data transfer interface helper functions + * + */ + +/** + * Send redirection event + * + * @v intf Data transfer interface + * @v type New location type + * @v ... Remaining arguments depend upon location type + * @ret rc Return status code + */ +int xfer_redirect ( struct interface *intf, int type, ... ) { + va_list args; + int rc; + + va_start ( args, type ); + rc = xfer_vredirect ( intf, type, args ); + va_end ( args ); return rc; } /** - * Deliver datagram as I/O buffer with metadata + * Deliver datagram as I/O buffer without metadata * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ -int xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf ) { - return xfer_deliver_iob_meta ( xfer, iobuf, &dummy_metadata ); +int xfer_deliver_iob ( struct interface *intf, struct io_buffer *iobuf ) { + return xfer_deliver ( intf, iobuf, &dummy_metadata ); } /** * Deliver datagram as raw data * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v iobuf Datagram I/O buffer * @ret rc Return status code */ -int xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); - int rc; - - DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest, - data, len ); +int xfer_deliver_raw ( struct interface *intf, const void *data, size_t len ) { + struct io_buffer *iobuf; - rc = dest->op->deliver_raw ( dest, data, len ); + iobuf = xfer_alloc_iob ( intf, len ); + if ( ! iobuf ) + return -ENOMEM; - if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest, - strerror ( rc ) ); - } - xfer_put ( dest ); - return rc; + memcpy ( iob_put ( iobuf, len ), data, len ); + return xfer_deliver_iob ( intf, iobuf ); } /** * Deliver formatted string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v format Format string * @v args Arguments corresponding to the format string * @ret rc Return status code */ -int xfer_vprintf ( struct xfer_interface *xfer, const char *format, +int xfer_vprintf ( struct interface *intf, const char *format, va_list args ) { size_t len; va_list args_tmp; @@ -219,24 +249,24 @@ int xfer_vprintf ( struct xfer_interface *xfer, const char *format, char buf[len + 1]; vsnprintf ( buf, sizeof ( buf ), format, args_tmp ); va_end ( args_tmp ); - return xfer_deliver_raw ( xfer, buf, len ); + return xfer_deliver_raw ( intf, buf, len ); } } /** * Deliver formatted string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v format Format string * @v ... Arguments corresponding to the format string * @ret rc Return status code */ -int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { +int xfer_printf ( struct interface *intf, const char *format, ... ) { va_list args; int rc; va_start ( args, format ); - rc = xfer_vprintf ( xfer, format, args ); + rc = xfer_vprintf ( intf, format, args ); va_end ( args ); return rc; } @@ -244,174 +274,25 @@ int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { /** * Seek to position * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v offset Offset to new position * @v whence Basis for new position * @ret rc Return status code */ -int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { +int xfer_seek ( struct interface *intf, off_t offset, int whence ) { struct io_buffer *iobuf; struct xfer_metadata meta = { .offset = offset, .whence = whence, }; - DBGC ( xfer, "XFER %p seek %s+%ld\n", xfer, - whence_text ( whence ), offset ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " seek %s+%ld\n", + INTF_DBG ( intf ), whence_text ( whence ), offset ); /* Allocate and send a zero-length data buffer */ - iobuf = xfer_alloc_iob ( xfer, 0 ); + iobuf = xfer_alloc_iob ( intf, 0 ); if ( ! iobuf ) return -ENOMEM; - return xfer_deliver_iob_meta ( xfer, iobuf, &meta ); -} - -/**************************************************************************** - * - * Helper methods - * - * These functions are designed to be used as methods in the - * xfer_interface_operations table. - * - */ -/** - * Ignore close() event - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -void ignore_xfer_close ( struct xfer_interface *xfer __unused, - int rc __unused ) { - /* Nothing to do */ + return xfer_deliver ( intf, iobuf, &meta ); } - -/** - * Ignore vredirect() event - * - * @v xfer Data transfer interface - * @v type New location type - * @v args Remaining arguments depend upon location type - * @ret rc Return status code - */ -int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused, - int type __unused, va_list args __unused ) { - return 0; -} - -/** - * Unlimited flow control window - * - * @v xfer Data transfer interface - * @ret len Length of window - * - * This handler indicates that the interface is always ready to accept - * data. - */ -size_t unlimited_xfer_window ( struct xfer_interface *xfer __unused ) { - return ~( ( size_t ) 0 ); -} - -/** - * No flow control window - * - * @v xfer Data transfer interface - * @ret len Length of window - * - * This handler indicates that the interface is never ready to accept - * data. - */ -size_t no_xfer_window ( struct xfer_interface *xfer __unused ) { - return 0; -} - -/** - * Allocate I/O buffer - * - * @v xfer Data transfer interface - * @v len I/O buffer payload length - * @ret iobuf I/O buffer - */ -struct io_buffer * -default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) { - return alloc_iob ( len ); -} - -/** - * Deliver datagram as raw data - * - * @v xfer Data transfer interface - * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - * - * This function is intended to be used as the deliver() method for - * data transfer interfaces that prefer to handle raw data. - */ -int xfer_deliver_as_raw ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - int rc; - - rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) ); - free_iob ( iobuf ); - return rc; -} - -/** - * Deliver datagram as I/O buffer - * - * @v xfer Data transfer interface - * @v data Data buffer - * @v len Length of data buffer - * @ret rc Return status code - * - * This function is intended to be used as the deliver_raw() method - * for data transfer interfaces that prefer to handle I/O buffers. - */ -int xfer_deliver_as_iob ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct io_buffer *iobuf; - - iobuf = xfer->op->alloc_iob ( xfer, len ); - if ( ! iobuf ) - return -ENOMEM; - - memcpy ( iob_put ( iobuf, len ), data, len ); - return xfer->op->deliver_iob ( xfer, iobuf, &dummy_metadata ); -} - -/** - * Ignore datagram as raw data event - * - * @v xfer Data transfer interface - * @v data Data buffer - * @v len Length of data buffer - * @ret rc Return status code - */ -int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data __unused, size_t len ) { - DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len, - ( ( xfer == &null_xfer ) ? - "before connection" : "after termination" ) ); - return 0; -} - -/** Null data transfer interface operations */ -struct xfer_interface_operations null_xfer_ops = { - .close = ignore_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, -}; - -/** - * Null data transfer interface - * - * This is the interface to which data transfer interfaces are - * connected when unplugged. It will never generate messages, and - * will silently absorb all received messages. - */ -struct xfer_interface null_xfer = XFER_INIT ( &null_xfer_ops ); |