Browse Source

[interface] Allow for non-pass-through interface methods

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>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
65bc070b05
3 changed files with 46 additions and 10 deletions
  1. 30
    9
      src/core/interface.c
  2. 1
    1
      src/core/xfer.c
  3. 15
    0
      src/include/ipxe/interface.h

+ 30
- 9
src/core/interface.c View File

151
 }
151
 }
152
 
152
 
153
 /**
153
 /**
154
- * Get object interface destination and operation method
154
+ * Get object interface destination and operation method (without pass-through)
155
  *
155
  *
156
  * @v intf		Object interface
156
  * @v intf		Object interface
157
  * @v type		Operation type
157
  * @v type		Operation type
158
  * @ret dest		Destination interface
158
  * @ret dest		Destination interface
159
  * @ret func		Implementing method, or NULL
159
  * @ret func		Implementing method, or NULL
160
  */
160
  */
161
-void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
162
-				  struct interface **dest ) {
161
+void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
162
+					      void *type,
163
+					      struct interface **dest ) {
163
 	struct interface_descriptor *desc;
164
 	struct interface_descriptor *desc;
164
 	struct interface_operation *op;
165
 	struct interface_operation *op;
165
 	unsigned int i;
166
 	unsigned int i;
166
 
167
 
168
+	*dest = intf_get ( intf->dest );
169
+	desc = (*dest)->desc;
170
+	for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
171
+		if ( op->type == type )
172
+			return op->func;
173
+	}
174
+
175
+	return NULL;
176
+}
177
+
178
+/**
179
+ * Get object interface destination and operation method
180
+ *
181
+ * @v intf		Object interface
182
+ * @v type		Operation type
183
+ * @ret dest		Destination interface
184
+ * @ret func		Implementing method, or NULL
185
+ */
186
+void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
187
+				  struct interface **dest ) {
188
+	void *func;
189
+
167
 	while ( 1 ) {
190
 	while ( 1 ) {
191
+
168
 		/* Search for an implementing method provided by the
192
 		/* Search for an implementing method provided by the
169
 		 * current destination interface.
193
 		 * current destination interface.
170
 		 */
194
 		 */
171
-		*dest = intf_get ( intf->dest );
172
-		desc = (*dest)->desc;
173
-		for ( i = desc->num_op, op = desc->op ; i ; i--, op++ ) {
174
-			if ( op->type == type )
175
-				return op->func;
176
-		}
195
+		func = intf_get_dest_op_no_passthru_untyped( intf, type, dest );
196
+		if ( func )
197
+			return func;
177
 
198
 
178
 		/* Pass through to the underlying interface, if applicable */
199
 		/* Pass through to the underlying interface, if applicable */
179
 		if ( ! ( intf = intf_get_passthru ( *dest ) ) )
200
 		if ( ! ( intf = intf_get_passthru ( *dest ) ) )

+ 1
- 1
src/core/xfer.c View File

56
 int xfer_vredirect ( struct interface *intf, int type, va_list args ) {
56
 int xfer_vredirect ( struct interface *intf, int type, va_list args ) {
57
 	struct interface *dest;
57
 	struct interface *dest;
58
 	xfer_vredirect_TYPE ( void * ) *op =
58
 	xfer_vredirect_TYPE ( void * ) *op =
59
-		intf_get_dest_op ( intf, xfer_vredirect, &dest );
59
+		intf_get_dest_op_no_passthru ( intf, xfer_vredirect, &dest );
60
 	void *object = intf_object ( dest );
60
 	void *object = intf_object ( dest );
61
 	int rc;
61
 	int rc;
62
 
62
 

+ 15
- 0
src/include/ipxe/interface.h View File

132
 extern struct interface * intf_get ( struct interface *intf );
132
 extern struct interface * intf_get ( struct interface *intf );
133
 extern void intf_put ( struct interface *intf );
133
 extern void intf_put ( struct interface *intf );
134
 extern void * __attribute__ (( pure )) intf_object ( struct interface *intf );
134
 extern void * __attribute__ (( pure )) intf_object ( struct interface *intf );
135
+extern void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
136
+						     void *type,
137
+						     struct interface **dest );
135
 extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
138
 extern void * intf_get_dest_op_untyped ( struct interface *intf, void *type,
136
 					 struct interface **dest );
139
 					 struct interface **dest );
137
 
140
 
171
 		.desc = &(descriptor),		\
174
 		.desc = &(descriptor),		\
172
 	}
175
 	}
173
 
176
 
177
+/**
178
+ * Get object interface destination and operation method (without pass-through)
179
+ *
180
+ * @v intf		Object interface
181
+ * @v type		Operation type
182
+ * @ret dest		Destination interface
183
+ * @ret func		Implementing method, or NULL
184
+ */
185
+#define intf_get_dest_op_no_passthru( intf, type, dest )		\
186
+	( ( type ## _TYPE ( void * ) * )				\
187
+	  intf_get_dest_op_no_passthru_untyped ( intf, type, dest ) )
188
+
174
 /**
189
 /**
175
  * Get object interface destination and operation method
190
  * Get object interface destination and operation method
176
  *
191
  *

Loading…
Cancel
Save