iPXE
Functions | Variables
xfer.c File Reference

Data transfer interfaces. More...

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int xfer_vredirect (struct interface *intf, int type, va_list args)
 Send redirection event.
size_t xfer_window (struct interface *intf)
 Check flow control window.
void xfer_window_changed (struct interface *intf)
 Report change of flow control window.
struct io_bufferxfer_alloc_iob (struct interface *intf, size_t len)
 Allocate I/O buffer.
int xfer_deliver (struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Deliver datagram.
int xfer_redirect (struct interface *intf, int type,...)
 Send redirection event.
int xfer_deliver_iob (struct interface *intf, struct io_buffer *iobuf)
 Deliver datagram as I/O buffer without metadata.
int xfer_deliver_raw_meta (struct interface *intf, const void *data, size_t len, struct xfer_metadata *meta)
 Deliver datagram as raw data.
int xfer_deliver_raw (struct interface *intf, const void *data, size_t len)
 Deliver datagram as raw data without metadata.
int xfer_vprintf (struct interface *intf, const char *format, va_list args)
 Deliver formatted string.
int xfer_printf (struct interface *intf, const char *format,...)
 Deliver formatted string.
int xfer_seek (struct interface *intf, off_t offset)
 Seek to position.
int xfer_check_order (struct xfer_metadata *meta, size_t *pos, size_t len)
 Check that data is delivered strictly in order.

Variables

static struct xfer_metadata dummy_metadata
 Dummy transfer metadata.

Detailed Description

Data transfer interfaces.

Definition in file xfer.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int xfer_vredirect ( struct interface intf,
int  type,
va_list  args 
)

Send redirection event.

Parameters:
intfData transfer interface
typeNew location type
argsRemaining arguments depend upon location type
Return values:
rcReturn status code

Definition at line 62 of file xfer.c.

References DBGC, dest, intf_close(), INTF_COL, intf_get_dest_op_no_passthru, INTF_INIT, INTF_INTF_DBG, INTF_INTF_FMT, intf_object(), intf_plug(), intf_put(), intf_unplug(), null_intf_desc, op, rc, strerror(), xfer_vredirect(), xfer_vredirect_TYPE, xfer_vreopen(), and xfer_window_changed().

Referenced by xfer_redirect(), and xfer_vredirect().

                                                                      {
        struct interface tmp = INTF_INIT ( null_intf_desc );
        struct interface *dest;
        xfer_vredirect_TYPE ( void * ) *op =
                intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest );
        void *object = intf_object ( dest );
        int rc;

        DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect\n",
               INTF_INTF_DBG ( intf, dest ) );

        if ( op ) {
                rc = op ( object, type, args );
        } else {
                /* Default is to reopen the interface as instructed,
                 * then send xfer_window_changed() messages to both
                 * new child and parent interfaces.  Since our
                 * original child interface is likely to be closed and
                 * unplugged as a result of the call to
                 * xfer_vreopen(), we create a temporary interface in
                 * order to be able to send xfer_window_changed() to
                 * the parent.
                 *
                 * If redirection fails, then send intf_close() to the
                 * parent interface.
                 */
                intf_plug ( &tmp, dest );
                rc = xfer_vreopen ( dest, type, args );
                if ( rc == 0 ) {
                        xfer_window_changed ( dest );
                        xfer_window_changed ( &tmp );
                } else {
                        intf_close ( &tmp, rc );
                }
                intf_unplug ( &tmp );
        }

        if ( rc != 0 ) {
                DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " redirect "
                       "failed: %s\n", INTF_INTF_DBG ( intf, dest ),
                       strerror ( rc ) );
        }

        intf_put ( dest );
        return rc;
}
size_t xfer_window ( struct interface intf)

Check flow control window.

Parameters:
intfData transfer interface
Return values:
lenLength of window

Definition at line 115 of file xfer.c.

References dest, intf_get_dest_op, intf_object(), intf_put(), len, op, xfer_window(), and xfer_window_TYPE.

Referenced by efi_local_step(), fc_port_window_changed(), fcpcmd_send_wrdata(), http_step(), hw_step(), iscsi_tx_step(), nfs_mount_step(), nfs_pm_step(), nfs_step(), pinger_window_changed(), pxenv_tftp_open(), sanpath_step(), scsidev_step(), scsidev_window(), syslogs_window_changed(), tcp_xmit_sack(), tftp_send_packet(), tftp_send_rrq(), tls_cipherstream_window(), tls_plainstream_window(), tls_tx_step(), xcm_step(), and xfer_window().

                                              {
        struct interface *dest;
        xfer_window_TYPE ( void * ) *op =
                intf_get_dest_op ( intf, xfer_window, &dest );
        void *object = intf_object ( dest );
        size_t len;

        if ( op ) {
                len = op ( object );
        } else {
                /* Default is to provide an unlimited window */
                len = ~( ( size_t ) 0 );
        }

        intf_put ( dest );
        return len;
}
void xfer_window_changed ( struct interface intf)

Report change of flow control window.

Parameters:
intfData transfer interface

Note that this method is used to indicate only unsolicited changes in the flow control window. In particular, this method must not be called as part of the response to xfer_deliver(), since that could easily lead to an infinite loop. Callers of xfer_deliver() should assume that the flow control window will have changed without generating an xfer_window_changed() message.

Definition at line 145 of file xfer.c.

References intf_poke(), and xfer_window_changed().

Referenced by aoedev_config_done(), fcoe_expired(), fcoe_reset(), fcpdev_examine(), http_step(), ib_cmrc_changed(), iscsi_rx_login_response(), scsidev_ready(), srp_login_rsp(), tcp_rx(), tls_new_finished(), tls_tx_step(), xfer_vredirect(), and xfer_window_changed().

struct io_buffer* xfer_alloc_iob ( struct interface intf,
size_t  len 
) [read]

Allocate I/O buffer.

Parameters:
intfData transfer interface
lenI/O buffer payload length
Return values:
iobufI/O buffer

Definition at line 157 of file xfer.c.

References alloc_iob(), DBGC, dest, INTF_COL, intf_get_dest_op, INTF_INTF_DBG, INTF_INTF_FMT, intf_object(), intf_put(), op, xfer_alloc_iob(), and xfer_alloc_iob_TYPE.

Referenced by dhcp_tx(), dhcpv6_tx(), efi_local_step(), efi_pxe_udp_write(), fc_xchg_alloc_iob(), fcpcmd_send_cmnd(), fcpcmd_send_wrdata(), iscsi_tx_data_out(), iscsi_tx_login_request(), pinger_expired(), pxenv_udp_write(), slam_tx_nack(), srp_cmd(), srp_login(), tftp_send_ack(), tftp_send_error(), tftp_send_rrq(), tls_send_plaintext(), xfer_alloc_iob(), xfer_deliver_raw_meta(), and xfer_seek().

                                                                         {
        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 ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob %zd\n",
               INTF_INTF_DBG ( intf, 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 ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " alloc_iob "
                       "failed\n", INTF_INTF_DBG ( intf, dest ) );
        }

        intf_put ( dest );
        return iobuf;
}
int xfer_deliver ( struct interface intf,
struct io_buffer iobuf,
struct xfer_metadata meta 
)

Deliver datagram.

Parameters:
intfData transfer interface
iobufDatagram I/O buffer
metaData transfer metadata
Return values:
rcReturn status code

Definition at line 193 of file xfer.c.

References DBGC, dest, EPIPE, free_iob(), INTF_COL, intf_get_dest_op, INTF_INTF_DBG, INTF_INTF_FMT, intf_object(), intf_put(), iob_len(), op, rc, strerror(), xfer_deliver(), and xfer_deliver_TYPE.

Referenced by dhcp_tx(), efi_pxe_udp_write(), fc_xchg_rx(), fcpcmd_send_cmnd(), fcpcmd_send_wrdata(), http_conn_socket_deliver(), http_content_deliver(), peerblk_deliver(), peermux_block_deliver(), ping_rx(), pinger_expired(), pxenv_udp_write(), slam_mc_socket_deliver(), tftp_rx_data(), tftp_send_ack(), tftp_send_error(), udp_rx(), xfer_buffer(), xfer_deliver(), xfer_deliver_iob(), xfer_deliver_raw_meta(), and xfer_seek().

                                                {
        struct interface *dest;
        xfer_deliver_TYPE ( void * ) *op =
                intf_get_dest_op ( intf, xfer_deliver, &dest );
        void *object = intf_object ( dest );
        int rc;

        DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " deliver %zd\n",
               INTF_INTF_DBG ( intf, dest ), iob_len ( iobuf ) );

        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 ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT
                       " deliver failed: %s\n",
                       INTF_INTF_DBG ( intf, dest ), strerror ( rc ) );
        }

        intf_put ( dest );
        return rc;
}
int xfer_redirect ( struct interface intf,
int  type,
  ... 
)

Send redirection event.

Parameters:
intfData transfer interface
typeNew location type
...Remaining arguments depend upon location type
Return values:
rcReturn status code

Definition at line 237 of file xfer.c.

References rc, va_end, va_start, and xfer_vredirect().

Referenced by http_redirect(), and named_resolv_done().

                                                            {
        va_list args;
        int rc;

        va_start ( args, type );
        rc = xfer_vredirect ( intf, type, args );
        va_end ( args );
        return rc;
}
int xfer_deliver_iob ( struct interface intf,
struct io_buffer iobuf 
)

Deliver datagram as I/O buffer without metadata.

Parameters:
intfData transfer interface
iobufDatagram I/O buffer
Return values:
rcReturn status code

Definition at line 254 of file xfer.c.

References dummy_metadata, and xfer_deliver().

Referenced by dhcpv6_tx(), efi_local_step(), fc_xchg_tx(), fcoe_rx(), http_rx_chunk_data(), http_rx_transfer_identity(), http_tx_request(), ib_cmrc_complete_recv(), iscsi_tx_data_out(), iscsi_tx_login_request(), nfs_deliver(), oncrpc_call(), slam_tx_nack(), srp_cmd(), srp_login(), tcp_rx_data(), tftp_send_rrq(), tls_new_record(), and tls_send_plaintext().

                                                                         {
        return xfer_deliver ( intf, iobuf, &dummy_metadata );
}
int xfer_deliver_raw_meta ( struct interface intf,
const void *  data,
size_t  len,
struct xfer_metadata meta 
)

Deliver datagram as raw data.

Parameters:
intfData transfer interface
dataData
lenLength of data
metaData transfer metadata
Return values:
rcReturn status code

Definition at line 267 of file xfer.c.

References ENOMEM, iob_put, memcpy(), xfer_alloc_iob(), and xfer_deliver().

Referenced by fc_els_tx(), fc_ns_query_step(), peerdisc_socket_tx(), and xfer_deliver_raw().

                                                                     {
        struct io_buffer *iobuf;

        iobuf = xfer_alloc_iob ( intf, len );
        if ( ! iobuf )
                return -ENOMEM;

        memcpy ( iob_put ( iobuf, len ), data, len );
        return xfer_deliver ( intf, iobuf, meta );
}
int xfer_deliver_raw ( struct interface intf,
const void *  data,
size_t  len 
)

Deliver datagram as raw data without metadata.

Parameters:
intfData transfer interface
dataData
lenLength of data
Return values:
rcReturn status code

Definition at line 287 of file xfer.c.

References dummy_metadata, and xfer_deliver_raw_meta().

Referenced by dns_send_packet(), fcoe_fip_rx_els_response(), hw_step(), ib_cmrc_changed(), iscsi_tx_bhs(), ntp_request(), slam_finished(), xcm_step(), xfer_vprintf(), xsmp_tx_session(), and xsmp_tx_xve().

                                                                              {
        return xfer_deliver_raw_meta ( intf, data, len, &dummy_metadata );
}
int xfer_vprintf ( struct interface intf,
const char *  format,
va_list  args 
)

Deliver formatted string.

Parameters:
intfData transfer interface
formatFormat string
argsArguments corresponding to the format string
Return values:
rcReturn status code

Definition at line 299 of file xfer.c.

References free, len, rc, va_copy, va_end, vasprintf(), and xfer_deliver_raw().

Referenced by xfer_printf().

                                  {
        va_list args_tmp;
        char *buf;
        int len;
        int rc;

        /* Create temporary string */
        va_copy ( args_tmp, args );
        len = vasprintf ( &buf, format, args );
        va_end ( args_tmp );
        if ( len < 0 ) {
                rc = len;
                goto err_asprintf;
        }

        /* Transmit string */
        if ( ( rc = xfer_deliver_raw ( intf, buf, len ) ) != 0 )
                goto err_deliver;

 err_deliver:
        free ( buf );
 err_asprintf:
        return rc;
}
int xfer_printf ( struct interface intf,
const char *  format,
  ... 
)

Deliver formatted string.

Parameters:
intfData transfer interface
formatFormat string
...Arguments corresponding to the format string
Return values:
rcReturn status code

Definition at line 333 of file xfer.c.

References rc, va_end, va_start, and xfer_vprintf().

Referenced by ftp_next_state(), and syslog_send().

                                                                    {
        va_list args;
        int rc;

        va_start ( args, format );
        rc = xfer_vprintf ( intf, format, args );
        va_end ( args );
        return rc;
}
int xfer_seek ( struct interface intf,
off_t  offset 
)

Seek to position.

Parameters:
intfData transfer interface
offsetOffset to new position
Return values:
rcReturn status code

Definition at line 350 of file xfer.c.

References DBGC, ENOMEM, xfer_metadata::flags, INTF_COL, INTF_DBG, INTF_FMT, offset, xfer_alloc_iob(), xfer_deliver(), and XFER_FL_ABS_OFFSET.

Referenced by efi_local_step(), ftp_reply(), http_rx_chunk_len(), http_rx_headers(), nfs_deliver(), peermux_info_close(), slam_pull_header(), and tftp_presize().

                                                       {
        struct io_buffer *iobuf;
        struct xfer_metadata meta = {
                .flags = XFER_FL_ABS_OFFSET,
                .offset = offset,
        };

        DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " seek to %ld\n",
               INTF_DBG ( intf ), offset );

        /* Allocate and send a zero-length data buffer */
        iobuf = xfer_alloc_iob ( intf, 0 );
        if ( ! iobuf )
                return -ENOMEM;

        return xfer_deliver ( intf, iobuf, &meta );
}
int xfer_check_order ( struct xfer_metadata meta,
size_t pos,
size_t  len 
)

Check that data is delivered strictly in order.

Parameters:
metaData transfer metadata
posCurrent position
lenLength of data
Return values:
rcReturn status code

Definition at line 376 of file xfer.c.

References EPROTO, xfer_metadata::flags, len, xfer_metadata::offset, and XFER_FL_ABS_OFFSET.

Referenced by peerblk_raw_rx().

                                                                             {
        size_t new_pos;

        /* Allow out-of-order zero-length packets (as used by xfer_seek()) */
        if ( len == 0 )
                return 0;

        /* Calculate position of this delivery */
        new_pos = *pos;
        if ( meta->flags & XFER_FL_ABS_OFFSET )
                new_pos = 0;
        new_pos += meta->offset;

        /* Fail if delivery position is not equal to current position */
        if ( new_pos != *pos )
                return -EPROTO;

        /* Update current position */
        *pos += len;

        return 0;
}

Variable Documentation

struct xfer_metadata dummy_metadata [static]

Dummy transfer metadata.

This gets passed to xfer_interface::deliver() and equivalents when no metadata is available.

Definition at line 46 of file xfer.c.

Referenced by xfer_deliver_iob(), and xfer_deliver_raw().