diff options
author | Michael Brown <mcb30@ipxe.org> | 2010-06-16 01:31:29 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2010-06-22 15:50:31 +0100 |
commit | 4327d5d39f101f1df0ace6c03f3b3ada5f6a6213 (patch) | |
tree | ccf92bdfd23046b6c7f64f87b57350f02f63ad6f /src/net/tls.c | |
parent | 7b4fbd93a5f45355e4e5d30e5d34c310f6d30c05 (diff) | |
download | ipxe-4327d5d39f101f1df0ace6c03f3b3ada5f6a6213.tar.gz |
[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/tls.c')
-rw-r--r-- | src/net/tls.c | 164 |
1 files changed, 72 insertions, 92 deletions
diff --git a/src/net/tls.c b/src/net/tls.c index 8825c5c1..a9d62758 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -35,9 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/sha1.h> #include <ipxe/aes.h> #include <ipxe/rsa.h> +#include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/open.h> -#include <ipxe/filter.h> #include <ipxe/asn1.h> #include <ipxe/x509.h> #include <ipxe/tls.h> @@ -107,10 +107,8 @@ static void tls_close ( struct tls_session *tls, int rc ) { process_del ( &tls->process ); /* Close ciphertext and plaintext streams */ - xfer_nullify ( &tls->cipherstream.xfer ); - xfer_close ( &tls->cipherstream.xfer, rc ); - xfer_nullify ( &tls->plainstream.xfer ); - xfer_close ( &tls->plainstream.xfer, rc ); + intf_shutdown ( &tls->cipherstream, rc ); + intf_shutdown ( &tls->plainstream, rc ); } /****************************************************************************** @@ -1030,7 +1028,7 @@ static int tls_new_record ( struct tls_session *tls, case TLS_TYPE_HANDSHAKE: return tls_new_handshake ( tls, data, len ); case TLS_TYPE_DATA: - return xfer_deliver_raw ( &tls->plainstream.xfer, data, len ); + return xfer_deliver_raw ( &tls->plainstream, data, len ); default: /* RFC4346 says that we should just ignore unknown * record types. @@ -1209,8 +1207,7 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, /* Allocate ciphertext */ ciphertext_len = ( sizeof ( *tlshdr ) + plaintext_len ); - ciphertext = xfer_alloc_iob ( &tls->cipherstream.xfer, - ciphertext_len ); + ciphertext = xfer_alloc_iob ( &tls->cipherstream, ciphertext_len ); if ( ! ciphertext ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for " "ciphertext\n", tls, ciphertext_len ); @@ -1234,9 +1231,8 @@ static int tls_send_plaintext ( struct tls_session *tls, unsigned int type, plaintext = NULL; /* Send ciphertext */ - rc = xfer_deliver_iob ( &tls->cipherstream.xfer, ciphertext ); - ciphertext = NULL; - if ( rc != 0 ) { + if ( ( rc = xfer_deliver_iob ( &tls->cipherstream, + iob_disown ( ciphertext ) ) ) != 0 ) { DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n", tls, strerror ( rc ) ); goto done; @@ -1436,65 +1432,60 @@ static int tls_new_ciphertext ( struct tls_session *tls, */ /** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_plainstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); - - tls_close ( tls, rc ); -} - -/** * Check flow control window * - * @v xfer Plainstream data transfer interface + * @v tls TLS session * @ret len Length of window */ -static size_t tls_plainstream_window ( struct xfer_interface *xfer ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static size_t tls_plainstream_window ( struct tls_session *tls ) { /* Block window unless we are ready to accept data */ if ( tls->tx_state != TLS_TX_DATA ) return 0; - return filter_window ( xfer ); + return xfer_window ( &tls->cipherstream ); } /** * Deliver datagram as raw data * - * @v xfer Plainstream data transfer interface - * @v data Data buffer - * @v len Length of data buffer + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int tls_plainstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, plainstream.xfer ); +static int tls_plainstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *meta __unused ) { + int rc; /* Refuse unless we are ready to accept data */ - if ( tls->tx_state != TLS_TX_DATA ) - return -ENOTCONN; + if ( tls->tx_state != TLS_TX_DATA ) { + rc = -ENOTCONN; + goto done; + } + + if ( ( rc = tls_send_plaintext ( tls, TLS_TYPE_DATA, iobuf->data, + iob_len ( iobuf ) ) ) != 0 ) + goto done; - return tls_send_plaintext ( tls, TLS_TYPE_DATA, data, len ); + done: + free_iob ( iobuf ); + return rc; } -/** TLS plaintext stream operations */ -static struct xfer_interface_operations tls_plainstream_operations = { - .close = tls_plainstream_close, - .vredirect = ignore_xfer_vredirect, - .window = tls_plainstream_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_plainstream_deliver_raw, +/** TLS plaintext stream interface operations */ +static struct interface_operation tls_plainstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, tls_plainstream_deliver ), + INTF_OP ( xfer_window, struct tls_session *, tls_plainstream_window ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS plaintext stream interface descriptor */ +static struct interface_descriptor tls_plainstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, plainstream, + tls_plainstream_ops, cipherstream ); + /****************************************************************************** * * Ciphertext stream operations @@ -1503,19 +1494,6 @@ static struct xfer_interface_operations tls_plainstream_operations = { */ /** - * Close interface - * - * @v xfer Plainstream data transfer interface - * @v rc Reason for close - */ -static void tls_cipherstream_close ( struct xfer_interface *xfer, int rc ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); - - tls_close ( tls, rc ); -} - -/** * Handle received TLS header * * @v tls TLS session @@ -1569,22 +1547,21 @@ static int tls_newdata_process_data ( struct tls_session *tls ) { /** * Receive new ciphertext * - * @v app Stream application - * @v data Data received - * @v len Length of received data + * @v tls TLS session + * @v iobuf I/O buffer + * @v meta Data transfer metadat * @ret rc Return status code */ -static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { - struct tls_session *tls = - container_of ( xfer, struct tls_session, cipherstream.xfer ); +static int tls_cipherstream_deliver ( struct tls_session *tls, + struct io_buffer *iobuf, + struct xfer_metadata *xfer __unused ) { size_t frag_len; void *buf; size_t buf_len; int ( * process ) ( struct tls_session *tls ); int rc; - while ( len ) { + while ( iob_len ( iobuf ) ) { /* Select buffer according to current state */ switch ( tls->rx_state ) { case TLS_RX_HEADER: @@ -1599,41 +1576,46 @@ static int tls_cipherstream_deliver_raw ( struct xfer_interface *xfer, break; default: assert ( 0 ); - return -EINVAL; + rc = -EINVAL; + goto done; } /* Copy data portion to buffer */ frag_len = ( buf_len - tls->rx_rcvd ); - if ( frag_len > len ) - frag_len = len; - memcpy ( ( buf + tls->rx_rcvd ), data, frag_len ); + if ( frag_len > iob_len ( iobuf ) ) + frag_len = iob_len ( iobuf ); + memcpy ( ( buf + tls->rx_rcvd ), iobuf->data, frag_len ); tls->rx_rcvd += frag_len; - data += frag_len; - len -= frag_len; + iob_pull ( iobuf, frag_len ); /* Process data if buffer is now full */ if ( tls->rx_rcvd == buf_len ) { if ( ( rc = process ( tls ) ) != 0 ) { tls_close ( tls, rc ); - return rc; + goto done; } tls->rx_rcvd = 0; } } + rc = 0; - return 0; + done: + free_iob ( iobuf ); + return rc; } -/** TLS ciphertext stream operations */ -static struct xfer_interface_operations tls_cipherstream_operations = { - .close = tls_cipherstream_close, - .vredirect = xfer_vreopen, - .window = filter_window, - .alloc_iob = default_xfer_alloc_iob, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = tls_cipherstream_deliver_raw, +/** TLS ciphertext stream interface operations */ +static struct interface_operation tls_cipherstream_ops[] = { + INTF_OP ( xfer_deliver, struct tls_session *, + tls_cipherstream_deliver ), + INTF_OP ( intf_close, struct tls_session *, tls_close ), }; +/** TLS ciphertext stream interface descriptor */ +static struct interface_descriptor tls_cipherstream_desc = + INTF_DESC_PASSTHRU ( struct tls_session, cipherstream, + tls_cipherstream_ops, plainstream ); + /****************************************************************************** * * Controlling process @@ -1652,7 +1634,7 @@ static void tls_step ( struct process *process ) { int rc; /* Wait for cipherstream to become ready */ - if ( ! xfer_window ( &tls->cipherstream.xfer ) ) + if ( ! xfer_window ( &tls->cipherstream ) ) return; switch ( tls->tx_state ) { @@ -1723,7 +1705,7 @@ static void tls_step ( struct process *process ) { ****************************************************************************** */ -int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { +int add_tls ( struct interface *xfer, struct interface **next ) { struct tls_session *tls; /* Allocate and initialise TLS structure */ @@ -1732,9 +1714,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { return -ENOMEM; memset ( tls, 0, sizeof ( *tls ) ); ref_init ( &tls->refcnt, free_tls ); - filter_init ( &tls->plainstream, &tls_plainstream_operations, - &tls->cipherstream, &tls_cipherstream_operations, - &tls->refcnt ); + intf_init ( &tls->plainstream, &tls_plainstream_desc, &tls->refcnt ); + intf_init ( &tls->cipherstream, &tls_cipherstream_desc, &tls->refcnt ); tls_clear_cipher ( tls, &tls->tx_cipherspec ); tls_clear_cipher ( tls, &tls->tx_cipherspec_pending ); tls_clear_cipher ( tls, &tls->rx_cipherspec ); @@ -1751,9 +1732,8 @@ int add_tls ( struct xfer_interface *xfer, struct xfer_interface **next ) { process_init ( &tls->process, tls_step, &tls->refcnt ); /* Attach to parent interface, mortalise self, and return */ - xfer_plug_plug ( &tls->plainstream.xfer, xfer ); - *next = &tls->cipherstream.xfer; + intf_plug_plug ( &tls->plainstream, xfer ); + *next = &tls->cipherstream; ref_put ( &tls->refcnt ); return 0; } - |