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 | |
| 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')
| -rw-r--r-- | src/core/downloader.c | 48 | ||||
| -rw-r--r-- | src/core/filter.c | 74 | ||||
| -rw-r--r-- | src/core/hw.c | 29 | ||||
| -rw-r--r-- | src/core/open.c | 69 | ||||
| -rw-r--r-- | src/core/posix_io.c | 47 | ||||
| -rw-r--r-- | src/core/resolv.c | 43 | ||||
| -rw-r--r-- | src/core/xfer.c | 371 |
7 files changed, 224 insertions, 457 deletions
diff --git a/src/core/downloader.c b/src/core/downloader.c index de5ea458c..488c86d9c 100644 --- a/src/core/downloader.c +++ b/src/core/downloader.c @@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stdlib.h> #include <stdarg.h> #include <errno.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/job.h> @@ -43,7 +44,7 @@ struct downloader { /** Job control interface */ struct interface job; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Image to contain downloaded file */ struct image *image; @@ -79,8 +80,7 @@ static void downloader_finished ( struct downloader *downloader, int rc ) { rc = downloader->register_image ( downloader->image ); /* Shut down interfaces */ - xfer_nullify ( &downloader->xfer ); - xfer_close ( &downloader->xfer, rc ); + intf_shutdown ( &downloader->xfer, rc ); intf_shutdown ( &downloader->job, rc ); } @@ -145,18 +145,16 @@ static void downloader_progress ( struct downloader *downloader, */ /** - * Handle deliver_raw() event received via data transfer interface + * Handle received data * - * @v xfer Downloader data transfer interface + * @v downloader Downloader * @v iobuf Datagram I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int downloader_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct downloader *downloader = - container_of ( xfer, struct downloader, xfer ); +static int downloader_xfer_deliver ( struct downloader *downloader, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { size_t len; size_t max; int rc; @@ -184,30 +182,16 @@ static int downloader_xfer_deliver_iob ( struct xfer_interface *xfer, return rc; } -/** - * Handle close() event received via data transfer interface - * - * @v xfer Downloader data transfer interface - * @v rc Reason for close - */ -static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct downloader *downloader = - container_of ( xfer, struct downloader, xfer ); - - /* Terminate download */ - downloader_finished ( downloader, rc ); -} - /** Downloader data transfer interface operations */ -static struct xfer_interface_operations downloader_xfer_operations = { - .close = downloader_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = downloader_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation downloader_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct downloader *, downloader_xfer_deliver ), + INTF_OP ( intf_close, struct downloader *, downloader_finished ), }; +/** Downloader data transfer interface descriptor */ +static struct interface_descriptor downloader_xfer_desc = + INTF_DESC ( struct downloader, xfer, downloader_xfer_operations ); + /**************************************************************************** * * Job control interface @@ -258,7 +242,7 @@ int create_downloader ( struct interface *job, struct image *image, ref_init ( &downloader->refcnt, downloader_free ); intf_init ( &downloader->job, &downloader_job_desc, &downloader->refcnt ); - xfer_init ( &downloader->xfer, &downloader_xfer_operations, + intf_init ( &downloader->xfer, &downloader_xfer_desc, &downloader->refcnt ); downloader->image = image_get ( image ); downloader->register_image = register_image; diff --git a/src/core/filter.c b/src/core/filter.c deleted file mode 100644 index 94a521459..000000000 --- a/src/core/filter.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <ipxe/xfer.h> -#include <ipxe/filter.h> - -/** @file - * - * Data transfer filters - * - */ - -/* - * Pass-through methods to be used by filters which don't want to - * intercept all events. - * - */ - -void filter_close ( struct xfer_interface *xfer, int rc ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - xfer_close ( other, rc ); -} - -int filter_vredirect ( struct xfer_interface *xfer, int type, - va_list args ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_vredirect ( other, type, args ); -} - -size_t filter_window ( struct xfer_interface *xfer ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_window ( other ); -} - -struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer, - size_t len ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_alloc_iob ( other, len ); -} - -int filter_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_deliver_iob_meta ( other, iobuf, meta ); -} - -int filter_deliver_raw ( struct xfer_interface *xfer, const void *data, - size_t len ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_deliver_raw ( other, data, len ); -} diff --git a/src/core/hw.c b/src/core/hw.c index b4a190271..aca558099 100644 --- a/src/core/hw.c +++ b/src/core/hw.c @@ -15,33 +15,24 @@ struct hw { struct refcnt refcnt; - struct xfer_interface xfer; + struct interface xfer; struct process process; }; static const char hw_msg[] = "Hello world!\n"; static void hw_finished ( struct hw *hw, int rc ) { - xfer_nullify ( &hw->xfer ); - xfer_close ( &hw->xfer, rc ); + intf_shutdown ( &hw->xfer, rc ); process_del ( &hw->process ); } -static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct hw *hw = container_of ( xfer, struct hw, xfer ); - - hw_finished ( hw, rc ); -} - -static struct xfer_interface_operations hw_xfer_operations = { - .close = hw_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, +static struct interface_operation hw_xfer_operations[] = { + INTF_OP ( intf_close, struct hw *, hw_finished ), }; +static struct interface_descriptor hw_xfer_desc = + INTF_DESC ( struct hw, xfer, hw_xfer_operations ); + static void hw_step ( struct process *process ) { struct hw *hw = container_of ( process, struct hw, process ); int rc; @@ -52,7 +43,7 @@ static void hw_step ( struct process *process ) { } } -static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) { +static int hw_open ( struct interface *xfer, struct uri *uri __unused ) { struct hw *hw; /* Allocate and initialise structure */ @@ -60,11 +51,11 @@ static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) { if ( ! hw ) return -ENOMEM; ref_init ( &hw->refcnt, NULL ); - xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt ); + intf_init ( &hw->xfer, &hw_xfer_desc, &hw->refcnt ); process_init ( &hw->process, hw_step, &hw->refcnt ); /* Attach parent interface, mortalise self, and return */ - xfer_plug_plug ( &hw->xfer, xfer ); + intf_plug_plug ( &hw->xfer, xfer ); ref_put ( &hw->refcnt ); return 0; } diff --git a/src/core/open.c b/src/core/open.c index 58edef561..f8ee9f3a8 100644 --- a/src/core/open.c +++ b/src/core/open.c @@ -35,14 +35,14 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** * Open URI * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v uri URI * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ -int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { +int xfer_open_uri ( struct interface *intf, struct uri *uri ) { struct uri_opener *opener; struct uri *resolved_uri; int rc = -ENOTSUP; @@ -55,14 +55,16 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { /* Find opener which supports this URI scheme */ for_each_table_entry ( opener, URI_OPENERS ) { if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) { - DBGC ( xfer, "XFER %p opening %s URI\n", - xfer, opener->scheme ); - rc = opener->open ( xfer, resolved_uri ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT + " opening %s URI\n", INTF_DBG ( intf ), + resolved_uri->scheme ); + rc = opener->open ( intf, resolved_uri ); goto done; } } - DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme " - "\"%s\"\n", xfer, resolved_uri->scheme ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " + "unsupported URI scheme \"%s\"\n", + INTF_DBG ( intf ), resolved_uri->scheme ); done: uri_put ( resolved_uri ); @@ -72,25 +74,26 @@ int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) { /** * Open URI string * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v uri_string URI string (e.g. "http://ipxe.org/kernel") * @ret rc Return status code * * The URI will be regarded as being relative to the current working * URI (see churi()). */ -int xfer_open_uri_string ( struct xfer_interface *xfer, +int xfer_open_uri_string ( struct interface *intf, const char *uri_string ) { struct uri *uri; int rc; - DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n", + INTF_DBG ( intf ), uri_string ); uri = parse_uri ( uri_string ); if ( ! uri ) return -ENOMEM; - rc = xfer_open_uri ( xfer, uri ); + rc = xfer_open_uri ( intf, uri ); uri_put ( uri ); return rc; @@ -99,29 +102,30 @@ int xfer_open_uri_string ( struct xfer_interface *xfer, /** * Open socket * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v semantics Communication semantics (e.g. SOCK_STREAM) * @v peer Peer socket address * @v local Local socket address, or NULL * @ret rc Return status code */ -int xfer_open_socket ( struct xfer_interface *xfer, int semantics, +int xfer_open_socket ( struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local ) { struct socket_opener *opener; - DBGC ( xfer, "XFER %p opening (%s,%s) socket\n", xfer, - socket_semantics_name ( semantics ), + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n", + INTF_DBG ( intf ), socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); for_each_table_entry ( opener, SOCKET_OPENERS ) { if ( ( opener->semantics == semantics ) && ( opener->family == peer->sa_family ) ) { - return opener->open ( xfer, peer, local ); + return opener->open ( intf, peer, local ); } } - DBGC ( xfer, "XFER %p attempted to open unsupported socket type " - "(%s,%s)\n", xfer, socket_semantics_name ( semantics ), + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open " + "unsupported socket type (%s,%s)\n", + INTF_DBG ( intf ), socket_semantics_name ( semantics ), socket_family_name ( peer->sa_family ) ); return -ENOTSUP; } @@ -129,30 +133,31 @@ int xfer_open_socket ( struct xfer_interface *xfer, int semantics, /** * Open location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) { +int xfer_vopen ( struct interface *intf, int type, va_list args ) { switch ( type ) { case LOCATION_URI_STRING: { const char *uri_string = va_arg ( args, const char * ); - return xfer_open_uri_string ( xfer, uri_string ); } + return xfer_open_uri_string ( intf, uri_string ); } case LOCATION_URI: { struct uri *uri = va_arg ( args, struct uri * ); - return xfer_open_uri ( xfer, uri ); } + return xfer_open_uri ( intf, uri ); } case LOCATION_SOCKET: { int semantics = va_arg ( args, int ); struct sockaddr *peer = va_arg ( args, struct sockaddr * ); struct sockaddr *local = va_arg ( args, struct sockaddr * ); - return xfer_open_socket ( xfer, semantics, peer, local ); } + return xfer_open_socket ( intf, semantics, peer, local ); } default: - DBGC ( xfer, "XFER %p attempted to open unsupported location " - "type %d\n", xfer, type ); + DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to " + "open unsupported location type %d\n", + INTF_DBG ( intf ), type ); return -ENOTSUP; } } @@ -160,17 +165,17 @@ int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) { /** * Open location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v ... Remaining arguments depend upon location type * @ret rc Return status code */ -int xfer_open ( struct xfer_interface *xfer, int type, ... ) { +int xfer_open ( struct interface *intf, int type, ... ) { va_list args; int rc; va_start ( args, type ); - rc = xfer_vopen ( xfer, type, args ); + rc = xfer_vopen ( intf, type, args ); va_end ( args ); return rc; } @@ -178,7 +183,7 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { /** * Reopen location * - * @v xfer Data transfer interface + * @v intf Data transfer interface * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code @@ -187,11 +192,11 @@ int xfer_open ( struct xfer_interface *xfer, int type, ... ) { * using xfer_vopen(). It is intended to be used as a .vredirect * method handler. */ -int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) { +int xfer_vreopen ( struct interface *intf, int type, va_list args ) { /* Close existing connection */ - xfer_close ( xfer, 0 ); + intf_restart ( intf, 0 ); /* Open new location */ - return xfer_vopen ( xfer, type, args ); + return xfer_vopen ( intf, type, args ); } diff --git a/src/core/posix_io.c b/src/core/posix_io.c index 2ecb15410..f7ca3f0db 100644 --- a/src/core/posix_io.c +++ b/src/core/posix_io.c @@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <string.h> #include <errno.h> #include <ipxe/list.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/process.h> @@ -50,7 +51,7 @@ struct posix_file { */ int rc; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Current seek position */ size_t pos; /** File size */ @@ -87,38 +88,21 @@ static void posix_file_free ( struct refcnt *refcnt ) { * @v rc Reason for termination */ static void posix_file_finished ( struct posix_file *file, int rc ) { - xfer_nullify ( &file->xfer ); - xfer_close ( &file->xfer, rc ); + intf_shutdown ( &file->xfer, rc ); file->rc = rc; } /** - * Handle close() event - * - * @v xfer POSIX file data transfer interface - * @v rc Reason for close - */ -static void posix_file_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct posix_file *file = - container_of ( xfer, struct posix_file, xfer ); - - posix_file_finished ( file, rc ); -} - -/** * Handle deliver_iob() event * - * @v xfer POSIX file data transfer interface + * @v file POSIX file * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int -posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, - struct io_buffer *iobuf, - struct xfer_metadata *meta ) { - struct posix_file *file = - container_of ( xfer, struct posix_file, xfer ); +static int posix_file_xfer_deliver ( struct posix_file *file, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { /* Keep track of file position solely for the filesize */ if ( meta->whence != SEEK_CUR ) @@ -137,15 +121,15 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, } /** POSIX file data transfer interface operations */ -static struct xfer_interface_operations posix_file_xfer_operations = { - .close = posix_file_xfer_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = posix_file_xfer_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +static struct interface_operation posix_file_xfer_operations[] = { + INTF_OP ( xfer_deliver, struct posix_file *, posix_file_xfer_deliver ), + INTF_OP ( intf_close, struct posix_file *, posix_file_finished ), }; +/** POSIX file data transfer interface descriptor */ +static struct interface_descriptor posix_file_xfer_desc = + INTF_DESC ( struct posix_file, xfer, posix_file_xfer_operations ); + /** * Identify file by file descriptor * @@ -201,8 +185,7 @@ int open ( const char *uri_string ) { ref_init ( &file->refcnt, posix_file_free ); file->fd = fd; file->rc = -EINPROGRESS; - xfer_init ( &file->xfer, &posix_file_xfer_operations, - &file->refcnt ); + intf_init ( &file->xfer, &posix_file_xfer_desc, &file->refcnt ); INIT_LIST_HEAD ( &file->data ); /* Open URI on data transfer interface */ diff --git a/src/core/resolv.c b/src/core/resolv.c index 4256de471..91f0c15ce 100644 --- a/src/core/resolv.c +++ b/src/core/resolv.c @@ -299,7 +299,7 @@ struct named_socket { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** Name resolution interface */ struct interface resolv; /** Communication semantics (e.g. SOCK_STREAM) */ @@ -319,33 +319,30 @@ struct named_socket { static void named_close ( struct named_socket *named, int rc ) { /* Shut down interfaces */ intf_shutdown ( &named->resolv, rc ); - xfer_nullify ( &named->xfer ); - xfer_close ( &named->xfer, rc ); + intf_shutdown ( &named->xfer, rc ); } /** - * Handle close() event + * Check flow control window * - * @v xfer Data transfer interface - * @v rc Reason for close + * @v named Named socket + * @ret len Length of window */ -static void named_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct named_socket *named = - container_of ( xfer, struct named_socket, xfer ); - - named_close ( named, rc ); +static size_t named_window ( struct named_socket *named __unused ) { + /* Not ready for data until we have redirected away */ + return 0; } /** Named socket opener data transfer interface operations */ -static struct xfer_interface_operations named_xfer_ops = { - .close = named_xfer_close, - .vredirect = ignore_xfer_vredirect, - .window = no_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ignore_xfer_deliver_raw, +static struct interface_operation named_xfer_ops[] = { + INTF_OP ( xfer_window, struct named_socket *, named_window ), + INTF_OP ( intf_close, struct named_socket *, named_close ), }; +/** Named socket opener data transfer interface descriptor */ +static struct interface_descriptor named_xfer_desc = + INTF_DESC ( struct named_socket, xfer, named_xfer_ops ); + /** * Name resolved * @@ -357,7 +354,7 @@ static void named_resolv_done ( struct named_socket *named, int rc; /* Nullify data transfer interface */ - xfer_nullify ( &named->xfer ); + intf_nullify ( &named->xfer ); /* Redirect data-xfer interface */ if ( ( rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET, @@ -370,7 +367,7 @@ static void named_resolv_done ( struct named_socket *named, } else { /* Redirection succeeded - unplug data-xfer interface */ DBGC ( named, "NAMED %p redirected successfully\n", named ); - xfer_unplug ( &named->xfer ); + intf_unplug ( &named->xfer ); } /* Terminate named socket opener */ @@ -396,7 +393,7 @@ static struct interface_descriptor named_resolv_desc = * @v local Local socket address, or NULL * @ret rc Return status code */ -int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, +int xfer_open_named_socket ( struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local ) { struct named_socket *named; @@ -407,7 +404,7 @@ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, if ( ! named ) return -ENOMEM; ref_init ( &named->refcnt, NULL ); - xfer_init ( &named->xfer, &named_xfer_ops, &named->refcnt ); + intf_init ( &named->xfer, &named_xfer_desc, &named->refcnt ); intf_init ( &named->resolv, &named_resolv_desc, &named->refcnt ); named->semantics = semantics; if ( local ) { @@ -423,7 +420,7 @@ int xfer_open_named_socket ( struct xfer_interface *xfer, int semantics, goto err; /* Attach parent interface, mortalise self, and return */ - xfer_plug_plug ( &named->xfer, xfer ); + intf_plug_plug ( &named->xfer, xfer ); ref_put ( &named->refcnt ); return 0; diff --git a/src/core/xfer.c b/src/core/xfer.c index 8dbfef6c8..057ab8b3f 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 ); |
