2007-04-27 00:44:52 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-07-20 20:55:45 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
* 02110-1301, USA.
|
2007-04-27 00:44:52 +02:00
|
|
|
*/
|
|
|
|
|
2009-05-01 16:41:06 +02:00
|
|
|
FILE_LICENCE ( GPL2_OR_LATER );
|
|
|
|
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
#include <string.h>
|
2010-04-19 21:16:01 +02:00
|
|
|
#include <ipxe/interface.h>
|
2007-04-27 00:44:52 +02:00
|
|
|
|
|
|
|
/** @file
|
|
|
|
*
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
* Object interfaces
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* The null interface
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2013-11-01 16:52:31 +01:00
|
|
|
/**
|
|
|
|
* Close null interface
|
|
|
|
*
|
|
|
|
* @v intf Null interface
|
|
|
|
* @v rc Reason for close
|
|
|
|
*/
|
|
|
|
static void null_intf_close ( struct interface *intf __unused,
|
|
|
|
int rc __unused ) {
|
|
|
|
|
|
|
|
/* Do nothing. In particular, do not call intf_restart(),
|
|
|
|
* since that would result in an infinite loop.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
/** Null interface operations */
|
2013-11-01 16:52:31 +01:00
|
|
|
static struct interface_operation null_intf_op[] = {
|
|
|
|
INTF_OP ( intf_close, struct interface *, null_intf_close ),
|
|
|
|
};
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
|
|
|
|
/** Null interface descriptor */
|
|
|
|
struct interface_descriptor null_intf_desc =
|
|
|
|
INTF_DESC_PURE ( null_intf_op );
|
|
|
|
|
|
|
|
/** The null interface */
|
|
|
|
struct interface null_intf = INTF_INIT ( null_intf_desc );
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Object interface plumbing
|
2007-04-27 00:44:52 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
* Plug an object interface into a new destination object interface
|
2007-04-27 00:44:52 +02:00
|
|
|
*
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
* @v intf Object interface
|
|
|
|
* @v dest New destination object interface
|
2007-04-27 00:44:52 +02:00
|
|
|
*
|
|
|
|
* The reference to the existing destination interface is dropped, a
|
|
|
|
* reference to the new destination interface is obtained, and the
|
|
|
|
* interface is updated to point to the new destination interface.
|
|
|
|
*
|
|
|
|
* Note that there is no "unplug" call; instead you must plug the
|
|
|
|
* interface into a null interface.
|
|
|
|
*/
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
void intf_plug ( struct interface *intf, struct interface *dest ) {
|
|
|
|
DBGC ( INTF_COL ( intf ),
|
|
|
|
"INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
|
|
|
|
INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );
|
|
|
|
intf_get ( dest );
|
2007-05-01 02:06:21 +02:00
|
|
|
intf_put ( intf->dest );
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
intf->dest = dest;
|
2007-04-27 00:44:52 +02:00
|
|
|
}
|
2007-04-30 03:23:01 +02:00
|
|
|
|
|
|
|
/**
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
* Plug two object interfaces together
|
2007-04-30 03:23:01 +02:00
|
|
|
*
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
* @v a Object interface A
|
|
|
|
* @v b Object interface B
|
2007-04-30 03:23:01 +02:00
|
|
|
*
|
|
|
|
* Plugs interface A into interface B, and interface B into interface
|
|
|
|
* A. (The basic plug() function is unidirectional; this function is
|
|
|
|
* merely a shorthand for two calls to plug(), hence the name.)
|
|
|
|
*/
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
void intf_plug_plug ( struct interface *a, struct interface *b ) {
|
|
|
|
intf_plug ( a, b );
|
|
|
|
intf_plug ( b, a );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unplug an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
*/
|
|
|
|
void intf_unplug ( struct interface *intf ) {
|
|
|
|
intf_plug ( intf, &null_intf );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ignore all further operations on an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
*/
|
|
|
|
void intf_nullify ( struct interface *intf ) {
|
|
|
|
intf->desc = &null_intf_desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Increment reference count on an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @ret intf Object interface
|
|
|
|
*/
|
|
|
|
struct interface * intf_get ( struct interface *intf ) {
|
|
|
|
ref_get ( intf->refcnt );
|
|
|
|
return intf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decrement reference count on an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
*/
|
|
|
|
void intf_put ( struct interface *intf ) {
|
|
|
|
ref_put ( intf->refcnt );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get pointer to object containing object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @ret object Containing object
|
|
|
|
*/
|
|
|
|
void * intf_object ( struct interface *intf ) {
|
|
|
|
return ( ( ( void * ) intf ) - intf->desc->offset );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get pass-through interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @ret passthru Pass-through interface, or NULL
|
|
|
|
*/
|
|
|
|
static struct interface * intf_get_passthru ( struct interface *intf ) {
|
|
|
|
struct interface_descriptor *desc = intf->desc;
|
|
|
|
|
|
|
|
if ( desc->passthru_offset ) {
|
|
|
|
return ( ( ( void * ) intf ) + desc->passthru_offset );
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
[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>
2010-06-22 20:12:40 +02:00
|
|
|
* Get object interface destination and operation method (without pass-through)
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @v type Operation type
|
|
|
|
* @ret dest Destination interface
|
|
|
|
* @ret func Implementing method, or NULL
|
|
|
|
*/
|
[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>
2010-06-22 20:12:40 +02:00
|
|
|
void * intf_get_dest_op_no_passthru_untyped ( struct interface *intf,
|
|
|
|
void *type,
|
|
|
|
struct interface **dest ) {
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
struct interface_descriptor *desc;
|
|
|
|
struct interface_operation *op;
|
|
|
|
unsigned int i;
|
|
|
|
|
[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>
2010-06-22 20:12:40 +02:00
|
|
|
*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;
|
|
|
|
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
while ( 1 ) {
|
[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>
2010-06-22 20:12:40 +02:00
|
|
|
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
/* Search for an implementing method provided by the
|
|
|
|
* current destination interface.
|
|
|
|
*/
|
[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>
2010-06-22 20:12:40 +02:00
|
|
|
func = intf_get_dest_op_no_passthru_untyped( intf, type, dest );
|
|
|
|
if ( func )
|
|
|
|
return func;
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
|
|
|
|
/* Pass through to the underlying interface, if applicable */
|
|
|
|
if ( ! ( intf = intf_get_passthru ( *dest ) ) )
|
|
|
|
return NULL;
|
|
|
|
intf_put ( *dest );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* Generic interface operations
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @v rc Reason for close
|
|
|
|
*
|
|
|
|
* Note that this function merely informs the destination object that
|
|
|
|
* the interface is about to be closed; it doesn't actually disconnect
|
|
|
|
* the interface. In most cases, you probably want to use
|
|
|
|
* intf_shutdown() or intf_restart() instead.
|
|
|
|
*/
|
|
|
|
void intf_close ( struct interface *intf, int rc ) {
|
|
|
|
struct interface *dest;
|
|
|
|
intf_close_TYPE ( void * ) *op =
|
|
|
|
intf_get_dest_op ( intf, intf_close, &dest );
|
|
|
|
void *object = intf_object ( dest );
|
|
|
|
|
|
|
|
DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " close (%s)\n",
|
|
|
|
INTF_INTF_DBG ( intf, dest ), strerror ( rc ) );
|
|
|
|
|
|
|
|
if ( op ) {
|
|
|
|
op ( object, rc );
|
|
|
|
} else {
|
2013-11-01 16:52:31 +01:00
|
|
|
/* Default is to restart the interface */
|
|
|
|
intf_restart ( dest, rc );
|
[interface] Expand object interface to allow for polymorphic interfaces
We have several types of object interface at present (data-xfer, job
control, name resolution), and there is some duplication of
functionality between them. For example, job_done(), job_kill() and
xfer_close() are almost isomorphic to each other.
This updated version of the object interface mechanism allows for each
interface to export an arbitrary list of supported operations.
Advantages include:
Operations methods now receive a pointer to the object, rather than
a pointer to the interface. This allows an object to, for example,
implement a single close() method that can handle close() operations
from any of its exposed interfaces.
The close() operation is implemented as a generic operation (rather
than having specific variants for data-xfer, job control, etc.).
This will allow functions such as monojob_wait() to be used to wait
for e.g. a name resolution to complete.
The amount of boilerplate code required in objects is reduced, not
least because it is no longer necessary to include per-interface
methods that simply use container_of() to derive a pointer to the
object and then tail-call to a common per-object method.
The cost of adding new operations is reduced; adding a new data-xfer
operation such as stat() no longer incurs the penalty of adding a
.stat member to the operations table of all existing data-xfer
interfaces.
The data-xfer, job control and name resolution interfaces have not yet
been updated to use the new interface mechanism, but the code will
still compile and run.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2008-06-12 20:43:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
intf_put ( dest );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shut down an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @v rc Reason for close
|
|
|
|
*
|
|
|
|
* Blocks further operations from being received via the interface,
|
|
|
|
* executes a close operation on the destination interface, and
|
|
|
|
* unplugs the interface.
|
|
|
|
*/
|
|
|
|
void intf_shutdown ( struct interface *intf, int rc ) {
|
|
|
|
|
|
|
|
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
|
|
|
|
INTF_DBG ( intf ), strerror ( rc ) );
|
|
|
|
|
|
|
|
/* Block further operations */
|
|
|
|
intf_nullify ( intf );
|
|
|
|
|
|
|
|
/* Notify destination of close */
|
|
|
|
intf_close ( intf, rc );
|
|
|
|
|
|
|
|
/* Unplug interface */
|
|
|
|
intf_unplug ( intf );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shut down and restart an object interface
|
|
|
|
*
|
|
|
|
* @v intf Object interface
|
|
|
|
* @v rc Reason for close
|
|
|
|
*
|
|
|
|
* Shuts down the interface, then unblocks operations that were
|
|
|
|
* blocked during shutdown.
|
|
|
|
*/
|
|
|
|
void intf_restart ( struct interface *intf, int rc ) {
|
|
|
|
struct interface_descriptor *desc = intf->desc;
|
|
|
|
|
|
|
|
/* Shut down the interface */
|
|
|
|
intf_shutdown ( intf, rc );
|
|
|
|
|
|
|
|
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " restarting\n",
|
|
|
|
INTF_DBG ( intf ) );
|
|
|
|
|
|
|
|
/* Restore the interface descriptor. Must be done after
|
|
|
|
* shutdown (rather than inhibiting intf_shutdown() from
|
|
|
|
* nullifying the descriptor) in order to avoid a potential
|
|
|
|
* infinite loop as the intf_close() operations on each side
|
|
|
|
* of the link call each other recursively.
|
|
|
|
*/
|
|
|
|
intf->desc = desc;
|
2007-04-30 03:23:01 +02:00
|
|
|
}
|