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/net/tcp | |
| 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/net/tcp')
| -rw-r--r-- | src/net/tcp/ftp.c | 144 | ||||
| -rw-r--r-- | src/net/tcp/http.c | 95 | ||||
| -rw-r--r-- | src/net/tcp/https.c | 2 | ||||
| -rw-r--r-- | src/net/tcp/iscsi.c | 75 |
4 files changed, 121 insertions, 195 deletions
diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index 58794c8b2..957f05cc8 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -8,6 +8,7 @@ #include <ipxe/socket.h> #include <ipxe/tcpip.h> #include <ipxe/in.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/uri.h> @@ -48,14 +49,14 @@ struct ftp_request { /** Reference counter */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** FTP control channel interface */ - struct xfer_interface control; + struct interface control; /** FTP data channel interface */ - struct xfer_interface data; + struct interface data; /** Current state */ enum ftp_state state; @@ -95,12 +96,9 @@ static void ftp_done ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p completed (%s)\n", ftp, strerror ( rc ) ); /* Close all data transfer interfaces */ - xfer_nullify ( &ftp->xfer ); - xfer_close ( &ftp->xfer, rc ); - xfer_nullify ( &ftp->control ); - xfer_close ( &ftp->control, rc ); - xfer_nullify ( &ftp->data ); - xfer_close ( &ftp->data, rc ); + intf_shutdown ( &ftp->data, rc ); + intf_shutdown ( &ftp->control, rc ); + intf_shutdown ( &ftp->xfer, rc ); } /***************************************************************************** @@ -167,26 +165,6 @@ static struct ftp_control_string ftp_strings[] = { }; /** - * Handle control channel being closed - * - * @v control FTP control channel interface - * @v rc Reason for close - * - * When the control channel is closed, the data channel must also be - * closed, if it is currently open. - */ -static void ftp_control_close ( struct xfer_interface *control, int rc ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); - - DBGC ( ftp, "FTP %p control connection closed: %s\n", - ftp, strerror ( rc ) ); - - /* Complete FTP operation */ - ftp_done ( ftp, rc ); -} - -/** * Parse FTP byte sequence value * * @v text Text string @@ -298,23 +276,25 @@ static void ftp_reply ( struct ftp_request *ftp ) { /** * Handle new data arriving on FTP control channel * - * @v control FTP control channel interface - * @v data New data - * @v len Length of new data + * @v ftp FTP request + * @v iob I/O buffer + * @v meta Data transfer metadata + * @ret rc Return status code * * Data is collected until a complete line is received, at which point * its information is passed to ftp_reply(). */ -static int ftp_control_deliver_raw ( struct xfer_interface *control, - const void *data, size_t len ) { - struct ftp_request *ftp = - container_of ( control, struct ftp_request, control ); +static int ftp_control_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + char *data = iobuf->data; + size_t len = iob_len ( iobuf ); char *recvbuf = ftp->recvbuf; size_t recvsize = ftp->recvsize; char c; while ( len-- ) { - c = * ( ( char * ) data++ ); + c = *(data++); switch ( c ) { case '\r' : case '\n' : @@ -351,19 +331,22 @@ static int ftp_control_deliver_raw ( struct xfer_interface *control, ftp->recvbuf = recvbuf; ftp->recvsize = recvsize; + /* Free I/O buffer */ + free_iob ( iobuf ); + return 0; } -/** FTP control channel operations */ -static struct xfer_interface_operations ftp_control_operations = { - .close = ftp_control_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = ftp_control_deliver_raw, +/** FTP control channel interface operations */ +static struct interface_operation ftp_control_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_control_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP control channel interface descriptor */ +static struct interface_descriptor ftp_control_desc = + INTF_DESC ( struct ftp_request, control, ftp_control_operations ); + /***************************************************************************** * * FTP data channel @@ -373,7 +356,7 @@ static struct xfer_interface_operations ftp_control_operations = { /** * Handle FTP data channel being closed * - * @v data FTP data channel interface + * @v ftp FTP request * @v rc Reason for closure * * When the data channel is closed, the control channel should be left @@ -382,9 +365,7 @@ static struct xfer_interface_operations ftp_control_operations = { * * If the data channel is closed due to an error, we abort the request. */ -static void ftp_data_closed ( struct xfer_interface *data, int rc ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static void ftp_data_closed ( struct ftp_request *ftp, int rc ) { DBGC ( ftp, "FTP %p data connection closed: %s\n", ftp, strerror ( rc ) ); @@ -400,16 +381,14 @@ static void ftp_data_closed ( struct xfer_interface *data, int rc ) { /** * Handle data delivery via FTP data channel * - * @v xfer FTP data channel interface + * @v ftp FTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int ftp_data_deliver_iob ( struct xfer_interface *data, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct ftp_request *ftp = - container_of ( data, struct ftp_request, data ); +static int ftp_data_deliver ( struct ftp_request *ftp, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { int rc; if ( ( rc = xfer_deliver_iob ( &ftp->xfer, iobuf ) ) != 0 ) { @@ -421,48 +400,31 @@ static int ftp_data_deliver_iob ( struct xfer_interface *data, return 0; } -/** FTP data channel operations */ -static struct xfer_interface_operations ftp_data_operations = { - .close = ftp_data_closed, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = ftp_data_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** FTP data channel interface operations */ +static struct interface_operation ftp_data_operations[] = { + INTF_OP ( xfer_deliver, struct ftp_request *, ftp_data_deliver ), + INTF_OP ( intf_close, struct ftp_request *, ftp_data_closed ), }; +/** FTP data channel interface descriptor */ +static struct interface_descriptor ftp_data_desc = + INTF_DESC ( struct ftp_request, data, ftp_data_operations ); + /***************************************************************************** * * Data transfer interface * */ -/** - * Close FTP data transfer interface - * - * @v xfer FTP data transfer interface - * @v rc Reason for close - */ -static void ftp_xfer_closed ( struct xfer_interface *xfer, int rc ) { - struct ftp_request *ftp = - container_of ( xfer, struct ftp_request, xfer ); - - DBGC ( ftp, "FTP %p data transfer interface closed: %s\n", - ftp, strerror ( rc ) ); - - ftp_done ( ftp, rc ); -} - /** FTP data transfer interface operations */ -static struct xfer_interface_operations ftp_xfer_operations = { - .close = ftp_xfer_closed, - .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 ftp_xfer_operations[] = { + INTF_OP ( intf_close, struct ftp_request *, ftp_done ), }; +/** FTP data transfer interface descriptor */ +static struct interface_descriptor ftp_xfer_desc = + INTF_DESC ( struct ftp_request, xfer, ftp_xfer_operations ); + /***************************************************************************** * * URI opener @@ -476,7 +438,7 @@ static struct xfer_interface_operations ftp_xfer_operations = { * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int ftp_open ( struct interface *xfer, struct uri *uri ) { struct ftp_request *ftp; struct sockaddr_tcpip server; int rc; @@ -492,10 +454,10 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { if ( ! ftp ) return -ENOMEM; ref_init ( &ftp->refcnt, ftp_free ); - xfer_init ( &ftp->xfer, &ftp_xfer_operations, &ftp->refcnt ); + intf_init ( &ftp->xfer, &ftp_xfer_desc, &ftp->refcnt ); + intf_init ( &ftp->control, &ftp_control_desc, &ftp->refcnt ); + intf_init ( &ftp->data, &ftp_data_desc, &ftp->refcnt ); ftp->uri = uri_get ( uri ); - xfer_init ( &ftp->control, &ftp_control_operations, &ftp->refcnt ); - xfer_init ( &ftp->data, &ftp_data_operations, &ftp->refcnt ); ftp->recvbuf = ftp->status_text; ftp->recvsize = sizeof ( ftp->status_text ) - 1; @@ -510,7 +472,7 @@ static int ftp_open ( struct xfer_interface *xfer, struct uri *uri ) { goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &ftp->xfer, xfer ); + intf_plug_plug ( &ftp->xfer, xfer ); ref_put ( &ftp->refcnt ); return 0; diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index d6a9fad7e..13c500d50 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -64,12 +64,12 @@ struct http_request { /** Reference count */ struct refcnt refcnt; /** Data transfer interface */ - struct xfer_interface xfer; + struct interface xfer; /** URI being fetched */ struct uri *uri; /** Transport layer interface */ - struct xfer_interface socket; + struct interface socket; /** TX process */ struct process process; @@ -125,10 +125,8 @@ static void http_done ( struct http_request *http, int rc ) { process_del ( &http->process ); /* Close all data transfer interfaces */ - xfer_nullify ( &http->socket ); - xfer_close ( &http->socket, rc ); - xfer_nullify ( &http->xfer ); - xfer_close ( &http->xfer, rc ); + intf_shutdown ( &http->socket, rc ); + intf_shutdown ( &http->xfer, rc ); } /** @@ -349,16 +347,14 @@ static int http_rx_data ( struct http_request *http, /** * Handle new data arriving via HTTP connection * - * @v socket Transport layer interface + * @v http HTTP request * @v iobuf I/O buffer * @v meta Data transfer metadata * @ret rc Return status code */ -static int http_socket_deliver_iob ( struct xfer_interface *socket, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); +static int http_socket_deliver ( struct http_request *http, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct http_line_handler *lh; char *line; ssize_t len; @@ -469,58 +465,25 @@ static void http_step ( struct process *process ) { } } -/** - * HTTP connection closed by network stack - * - * @v socket Transport layer interface - * @v rc Reason for close - */ -static void http_socket_close ( struct xfer_interface *socket, int rc ) { - struct http_request *http = - container_of ( socket, struct http_request, socket ); - - DBGC ( http, "HTTP %p socket closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} - -/** HTTP socket operations */ -static struct xfer_interface_operations http_socket_operations = { - .close = http_socket_close, - .vredirect = xfer_vreopen, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = http_socket_deliver_iob, - .deliver_raw = xfer_deliver_as_iob, +/** HTTP socket interface operations */ +static struct interface_operation http_socket_operations[] = { + INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ), + INTF_OP ( intf_close, struct http_request *, http_done ), }; -/** - * Close HTTP data transfer interface - * - * @v xfer Data transfer interface - * @v rc Reason for close - */ -static void http_xfer_close ( struct xfer_interface *xfer, int rc ) { - struct http_request *http = - container_of ( xfer, struct http_request, xfer ); - - DBGC ( http, "HTTP %p interface closed: %s\n", - http, strerror ( rc ) ); - - http_done ( http, rc ); -} +/** HTTP socket interface descriptor */ +static struct interface_descriptor http_socket_desc = + INTF_DESC ( struct http_request, socket, http_socket_operations ); /** HTTP data transfer interface operations */ -static struct xfer_interface_operations http_xfer_operations = { - .close = http_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 http_xfer_operations[] = { + INTF_OP ( intf_close, struct http_request *, http_done ), }; +/** HTTP data transfer interface descriptor */ +static struct interface_descriptor http_xfer_desc = + INTF_DESC ( struct http_request, xfer, http_xfer_operations ); + /** * Initiate an HTTP connection, with optional filter * @@ -530,13 +493,13 @@ static struct xfer_interface_operations http_xfer_operations = { * @v filter Filter to apply to socket, or NULL * @ret rc Return status code */ -int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, +int http_open_filter ( struct interface *xfer, struct uri *uri, unsigned int default_port, - int ( * filter ) ( struct xfer_interface *xfer, - struct xfer_interface **next ) ) { + int ( * filter ) ( struct interface *xfer, + struct interface **next ) ) { struct http_request *http; struct sockaddr_tcpip server; - struct xfer_interface *socket; + struct interface *socket; int rc; /* Sanity checks */ @@ -548,9 +511,9 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, if ( ! http ) return -ENOMEM; ref_init ( &http->refcnt, http_free ); - xfer_init ( &http->xfer, &http_xfer_operations, &http->refcnt ); + intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt ); http->uri = uri_get ( uri ); - xfer_init ( &http->socket, &http_socket_operations, &http->refcnt ); + intf_init ( &http->socket, &http_socket_desc, &http->refcnt ); process_init ( &http->process, http_step, &http->refcnt ); /* Open socket */ @@ -567,7 +530,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, goto err; /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &http->xfer, xfer ); + intf_plug_plug ( &http->xfer, xfer ); ref_put ( &http->refcnt ); return 0; @@ -586,7 +549,7 @@ int http_open_filter ( struct xfer_interface *xfer, struct uri *uri, * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int http_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int http_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTP_PORT, NULL ); } diff --git a/src/net/tcp/https.c b/src/net/tcp/https.c index b738f4167..805d108bb 100644 --- a/src/net/tcp/https.c +++ b/src/net/tcp/https.c @@ -40,7 +40,7 @@ FEATURE ( FEATURE_PROTOCOL, "HTTPS", DHCP_EB_FEATURE_HTTPS, 1 ); * @v uri Uniform Resource Identifier * @ret rc Return status code */ -static int https_open ( struct xfer_interface *xfer, struct uri *uri ) { +static int https_open ( struct interface *xfer, struct uri *uri ) { return http_open_filter ( xfer, uri, HTTPS_PORT, add_tls ); } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index 24cbda2c5..80c63a6b1 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <byteswap.h> #include <ipxe/vsprintf.h> #include <ipxe/socket.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> #include <ipxe/scsi.h> @@ -199,7 +200,7 @@ static int iscsi_open_connection ( struct iscsi_session *iscsi ) { static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) { /* Close all data transfer interfaces */ - xfer_close ( &iscsi->socket, rc ); + intf_restart ( &iscsi->socket, rc ); /* Clear connection status */ iscsi->status = 0; @@ -1435,9 +1436,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, /** * Receive new data * - * @v socket Transport layer interface - * @v data Received data - * @v len Length of received data + * @v iscsi iSCSI session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code * * This handles received PDUs. The receive strategy is to fill in @@ -1447,10 +1448,9 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data, * always has a full copy of the BHS available, even for portions of * the data in different packets to the BHS. */ -static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, - const void *data, size_t len ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static int iscsi_socket_deliver ( struct iscsi_session *iscsi, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; int ( * rx ) ( struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining ); @@ -1483,48 +1483,52 @@ static int iscsi_socket_deliver_raw ( struct xfer_interface *socket, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } frag_len = iscsi->rx_len - iscsi->rx_offset; - if ( frag_len > len ) - frag_len = len; + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); remaining = iscsi->rx_len - iscsi->rx_offset - frag_len; - if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) { + if ( ( rc = rx ( iscsi, iobuf->data, frag_len, + remaining ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not process received " "data: %s\n", iscsi, strerror ( rc ) ); iscsi_close_connection ( iscsi, rc ); iscsi_scsi_done ( iscsi, rc ); - return rc; + goto done; } iscsi->rx_offset += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* If all the data for this state has not yet been * received, stay in this state for now. */ - if ( iscsi->rx_offset != iscsi->rx_len ) - return 0; + if ( iscsi->rx_offset != iscsi->rx_len ) { + rc = 0; + goto done; + } iscsi->rx_state = next_state; iscsi->rx_offset = 0; } - return 0; + done: + /* Free I/O buffer */ + free_iob ( iobuf ); + return rc; } /** * Handle stream connection closure * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v rc Reason for close * */ -static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); +static void iscsi_socket_close ( struct iscsi_session *iscsi, int rc ) { /* Even a graceful close counts as an error for iSCSI */ if ( ! rc ) @@ -1552,15 +1556,13 @@ static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) { /** * Handle redirection event * - * @v socket Transport layer interface + * @v iscsi iSCSI session * @v type Location type * @v args Remaining arguments depend upon location type * @ret rc Return status code */ -static int iscsi_vredirect ( struct xfer_interface *socket, int type, +static int iscsi_vredirect ( struct iscsi_session *iscsi, int type, va_list args ) { - struct iscsi_session *iscsi = - container_of ( socket, struct iscsi_session, socket ); va_list tmp; struct sockaddr *peer; @@ -1578,20 +1580,20 @@ static int iscsi_vredirect ( struct xfer_interface *socket, int type, va_end ( tmp ); } - return xfer_vreopen ( socket, type, args ); + return xfer_vreopen ( &iscsi->socket, type, args ); } -/** iSCSI socket operations */ -static struct xfer_interface_operations iscsi_socket_operations = { - .close = iscsi_socket_close, - .vredirect = iscsi_vredirect, - .window = unlimited_xfer_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = iscsi_socket_deliver_raw, +/** iSCSI socket interface operations */ +static struct interface_operation iscsi_socket_operations[] = { + INTF_OP ( xfer_deliver, struct iscsi_session *, iscsi_socket_deliver ), + INTF_OP ( xfer_vredirect, struct iscsi_session *, iscsi_vredirect ), + INTF_OP ( intf_close, struct iscsi_session *, iscsi_socket_close ), }; +/** iSCSI socket interface descriptor */ +static struct interface_descriptor iscsi_socket_desc = + INTF_DESC ( struct iscsi_session, socket, iscsi_socket_operations ); /**************************************************************************** * @@ -1641,7 +1643,6 @@ void iscsi_detach ( struct scsi_device *scsi ) { struct iscsi_session *iscsi = container_of ( scsi->backend, struct iscsi_session, refcnt ); - xfer_nullify ( &iscsi->socket ); iscsi_close_connection ( iscsi, 0 ); process_del ( &iscsi->process ); scsi->command = scsi_detached_command; @@ -1793,7 +1794,7 @@ int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) { if ( ! iscsi ) return -ENOMEM; ref_init ( &iscsi->refcnt, iscsi_free ); - xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt ); + intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt ); process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt ); /* Parse root path */ |
