Skip to content

Commit

Permalink
[interface] Allow for non-pass-through interface methods
Browse files Browse the repository at this point in the history
xfer_vredirect() should not be allowed to propagate to a pass-through
interface.  For example, when an HTTPS connection is opened, the
redirect message should cause the TLS layer to reopen the TCP socket,
rather than causing the HTTP layer to disconnect from the TLS layer.

Fix by allowing for non-pass-through interface methods, and setting
xfer_vredirect() to be one such method.

This is slightly ugly, in that it complicates the notion of an
interface method call by adding a "pass-through" / "non-pass-through"
piece of metadata.  However, the only current user of xfer_vredirect()
is iscsi.c, which uses it only because we don't yet have an
ioctl()-style call for retrieving the underlying socket address.
The new interface infrastructure allows for such a call to be created,
at which time this sole user of xfer_vredirect() can be removed,
xfer_vredirect() can cease to be an interface method and become simply
a wrapper around xfer_vreopen(), and the concept of a non-pass-through
interface method can be reverted.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jun 22, 2010
1 parent 4327d5d commit 65bc070
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
39 changes: 30 additions & 9 deletions src/core/interface.c
Expand Up @@ -151,29 +151,50 @@ static struct interface * intf_get_passthru ( struct interface *intf ) {
}

/**
* Get object interface destination and operation method
* Get object interface destination and operation method (without pass-through)
*
* @v intf Object interface
* @v type Operation type
* @ret dest Destination interface
* @ret func Implementing method, or NULL
*/
void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
struct interface **dest ) {
void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
void *type,
struct interface **dest ) {
struct interface_descriptor *desc;
struct interface_operation *op;
unsigned int i;

*dest = intf_get ( intf->dest );
desc = (*dest)->desc;
for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
if ( op->type == type )
return op->func;
}

return NULL;
}

/**
* Get object interface destination and operation method
*
* @v intf Object interface
* @v type Operation type
* @ret dest Destination interface
* @ret func Implementing method, or NULL
*/
void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
struct interface **dest ) {
void *func;

while ( 1 ) {

/* Search for an implementing method provided by the
* current destination interface.
*/
*dest = intf_get ( intf->dest );
desc = (*dest)->desc;
for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
if ( op->type == type )
return op->func;
}
func = intf_get_dest_op_no_passthru_untyped( intf, type, dest );
if ( func )
return func;

/* Pass through to the underlying interface, if applicable */
if ( ! ( intf = intf_get_passthru ( *dest ) ) )
Expand Down
2 changes: 1 addition & 1 deletion src/core/xfer.c
Expand Up @@ -56,7 +56,7 @@ static struct xfer_metadata dummy_metadata;
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 );
intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest );
void *object = intf_object ( dest );
int rc;

Expand Down
15 changes: 15 additions & 0 deletions src/include/ipxe/interface.h
Expand Up @@ -132,6 +132,9 @@ extern void intf_nullify ( struct interface *intf );
extern struct interface * intf_get ( struct interface *intf );
extern void intf_put ( struct interface *intf );
extern void * __attribute__ (( pure )) intf_object ( struct interface *intf );
extern void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
void *type,
struct interface **dest );
extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
struct interface **dest );

Expand Down Expand Up @@ -171,6 +174,18 @@ static inline void intf_init ( struct interface *intf,
.desc = &(descriptor), \
}

/**
* Get object interface destination and operation method (without pass-through)
*
* @v intf Object interface
* @v type Operation type
* @ret dest Destination interface
* @ret func Implementing method, or NULL
*/
#define intf_get_dest_op_no_passthru( intf, type, dest ) \
( ( type ## _TYPE ( void * ) * ) \
intf_get_dest_op_no_passthru_untyped ( intf, type, dest ) )

/**
* Get object interface destination and operation method
*
Expand Down

0 comments on commit 65bc070

Please sign in to comment.