]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[interface] Allow for non-pass-through interface methods
authorMichael Brown <mcb30@ipxe.org>
Tue, 22 Jun 2010 18:12:40 +0000 (19:12 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 22 Jun 2010 18:12:40 +0000 (19:12 +0100)
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>
src/core/interface.c
src/core/xfer.c
src/include/ipxe/interface.h

index f0c0ae643a1cb5697eb3c735d30cf23f2094100b..c69875ea6db37945a0d4a1a2a3ddd06fd1d0883c 100644 (file)
@@ -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 ) ) )
index 057ab8b3f75d3bcbc530b39af8a912a286629fe2..dce245f9ced6de58b76a019d50fc7178f1f06aa3 100644 (file)
@@ -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;
 
index 49add33060317bf3ea9e8140a1421be004c23302..a474aaad0af509cd75c7275f229b8b88055c3a52 100644 (file)
@@ -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 );
 
@@ -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
  *