示例#1
0
文件: xfer.c 项目: baloo/ipxe
/**
 * Deliver datagram
 *
 * @v intf		Data transfer interface
 * @v iobuf		Datagram I/O buffer
 * @v meta		Data transfer metadata
 * @ret rc		Return status code
 */
int xfer_deliver ( struct interface *intf,
		   struct io_buffer *iobuf,
		   struct xfer_metadata *meta ) {
	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;
}
示例#2
0
文件: xfer.c 项目: baloo/ipxe
/**
 * Allocate I/O buffer
 *
 * @v intf		Data transfer interface
 * @v len		I/O buffer payload length
 * @ret iobuf		I/O buffer
 */
struct io_buffer * xfer_alloc_iob ( struct interface *intf, size_t len ) {
	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;
}
示例#3
0
文件: open.c 项目: eatnumber1/ipxe
/**
 * Open location
 *
 * @v intf		Data transfer interface
 * @v type		Location type
 * @v args		Remaining arguments depend upon location type
 * @ret rc		Return status code
 */
int xfer_vopen ( struct interface *intf, int type, va_list args ) {
    switch ( type ) {
    case LOCATION_URI_STRING: {
        const char *uri_string = va_arg ( args, const char * );

        return xfer_open_uri_string ( intf, uri_string );
    }
    case LOCATION_URI: {
        struct uri *uri = va_arg ( args, struct uri * );

        return xfer_open_uri ( intf, uri );
    }
    case LOCATION_SOCKET: {
        int semantics = va_arg ( args, int );
        struct sockaddr *peer = va_arg ( args, struct sockaddr * );
        struct sockaddr *local = va_arg ( args, struct sockaddr * );

        return xfer_open_socket ( intf, semantics, peer, local );
    }
    default:
        DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
               "open unsupported location type %d\n",
               INTF_DBG ( intf ), type );
        return -ENOTSUP;
    }
}
示例#4
0
文件: interface.c 项目: 3a9LL/panda
/**
 * Plug an object interface into a new destination object interface
 *
 * @v intf		Object interface
 * @v dest		New destination object interface
 *
 * 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.
 */
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 );
	intf_put ( intf->dest );
	intf->dest = dest;
}
示例#5
0
文件: xfer.c 项目: baloo/ipxe
/**
 * Send redirection event
 *
 * @v intf		Data transfer interface
 * @v type		New location type
 * @v args		Remaining arguments depend upon location type
 * @ret rc		Return status code
 */
int xfer_vredirect ( struct interface *intf, int type, va_list args ) {
	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.
		 */
		intf_plug ( &tmp, dest );
		rc = xfer_vreopen ( dest, type, args );
		if ( rc == 0 ) {
			xfer_window_changed ( dest );
			xfer_window_changed ( &tmp );
		}
		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;
}
示例#6
0
文件: open.c 项目: 42wim/ipxe
/**
 * Open socket
 *
 * @v intf		Data transfer interface
 * @v semantics		Communication semantics (e.g. SOCK_STREAM)
 * @v peer		Peer socket address
 * @v local		Local socket address, or NULL
 * @ret rc		Return status code
 */
int xfer_open_socket ( struct interface *intf, int semantics,
		       struct sockaddr *peer, struct sockaddr *local ) {
	struct socket_opener *opener;

	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
	       INTF_DBG ( intf ), socket_semantics_name ( semantics ),
	       socket_family_name ( peer->sa_family ) );

	for_each_table_entry ( opener, SOCKET_OPENERS ) {
		if ( ( opener->semantics == semantics ) &&
		     ( opener->family == peer->sa_family ) ) {
			return opener->open ( intf, peer, local );
		}
	}

	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
	       "unsupported socket type (%s,%s)\n",
	       INTF_DBG ( intf ), socket_semantics_name ( semantics ),
	       socket_family_name ( peer->sa_family ) );
	return -ENOTSUP;
}
示例#7
0
文件: interface.c 项目: 3a9LL/panda
/**
 * 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 );
}
示例#8
0
文件: open.c 项目: 42wim/ipxe
/**
 * Open URI
 *
 * @v intf		Data transfer interface
 * @v uri		URI
 * @ret rc		Return status code
 *
 * The URI will be regarded as being relative to the current working
 * URI (see churi()).
 */
int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
	struct uri_opener *opener;
	struct uri *resolved_uri;
	int rc;

	/* Resolve URI */
	resolved_uri = resolve_uri ( cwuri, uri );
	if ( ! resolved_uri ) {
		rc = -ENOMEM;
		goto err_resolve_uri;
	}

	/* Find opener which supports this URI scheme */
	opener = xfer_uri_opener ( resolved_uri->scheme );
	if ( ! opener ) {
		DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
		       "unsupported URI scheme \"%s\"\n",
		       INTF_DBG ( intf ), resolved_uri->scheme );
		rc = -ENOTSUP;
		goto err_opener;
	}

	/* Call opener */
	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
	       INTF_DBG ( intf ), resolved_uri->scheme );
	if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
		DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
		       "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
		goto err_open;
	}

 err_open:
 err_opener:
	uri_put ( resolved_uri );
 err_resolve_uri:
	return rc;
}
示例#9
0
文件: open.c 项目: 42wim/ipxe
/**
 * Open URI string
 *
 * @v intf		Data transfer interface
 * @v uri_string	URI string (e.g. "http://ipxe.org/kernel")
 * @ret rc		Return status code
 *
 * The URI will be regarded as being relative to the current working
 * URI (see churi()).
 */
int xfer_open_uri_string ( struct interface *intf,
			   const char *uri_string ) {
	struct uri *uri;
	int rc;

	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
	       INTF_DBG ( intf ), uri_string );

	uri = parse_uri ( uri_string );
	if ( ! uri )
		return -ENOMEM;

	rc = xfer_open_uri ( intf, uri );

	uri_put ( uri );
	return rc;
}
示例#10
0
文件: resolv.c 项目: 42wim/ipxe
/**
 * Name resolved
 *
 * @v intf		Object interface
 * @v sa		Completed socket address (if successful)
 */
void resolv_done ( struct interface *intf, struct sockaddr *sa ) {
	struct interface *dest;
	resolv_done_TYPE ( void * ) *op =
		intf_get_dest_op ( intf, resolv_done, &dest );
	void *object = intf_object ( dest );

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

	if ( op ) {
		op ( object, sa );
	} else {
		/* Default is to ignore resolutions */
	}

	intf_put ( dest );
}
示例#11
0
文件: interface.c 项目: 3a9LL/panda
/**
 * 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;
}
示例#12
0
文件: interface.c 项目: 3a9LL/panda
/**
 * 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 {
		/* Default is to ignore intf_close() */
	}

	intf_put ( dest );
}
示例#13
0
文件: xfer.c 项目: baloo/ipxe
/**
 * Seek to position
 *
 * @v intf		Data transfer interface
 * @v offset		Offset to new position
 * @ret rc		Return status code
 */
int xfer_seek ( struct interface *intf, off_t offset ) {
	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 );
}