diff options
Diffstat (limited to 'src/net')
| -rw-r--r-- | src/net/aoe.c | 12 | ||||
| -rw-r--r-- | src/net/tcp/ftp.c | 4 | ||||
| -rw-r--r-- | src/net/tcp/hello.c | 6 | ||||
| -rw-r--r-- | src/net/tcp/http.c | 84 | ||||
| -rw-r--r-- | src/net/tcp/iscsi.c | 16 | ||||
| -rw-r--r-- | src/net/udp/dhcp.c | 17 | ||||
| -rw-r--r-- | src/net/udp/tftp.c | 6 |
7 files changed, 107 insertions, 38 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c index 2dc5ed406..1c3cd1d2b 100644 --- a/src/net/aoe.c +++ b/src/net/aoe.c @@ -56,7 +56,7 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) { aoe->command = NULL; /* Mark async operation as complete */ - async_done ( &aoe->aop, rc ); + async_done ( &aoe->async, rc ); } /** @@ -309,17 +309,19 @@ void aoe_close ( struct aoe_session *aoe ) { * * @v aoe AoE session * @v command ATA command - * @ret aop Asynchronous operation + * @v parent Parent asynchronous operation + * @ret rc Return status code * * Only one command may be issued concurrently per session. This call * is non-blocking; use async_wait() to wait for the command to * complete. */ -struct async_operation * aoe_issue ( struct aoe_session *aoe, - struct ata_command *command ) { +int aoe_issue ( struct aoe_session *aoe, struct ata_command *command, + struct async *parent ) { aoe->command = command; aoe->status = 0; aoe->command_offset = 0; aoe_send_command ( aoe ); - return &aoe->aop; + async_init ( &aoe->async, &default_async_operations, parent ); + return 0; } diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index a857f7b7b..8a27f8cb6 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -83,7 +83,7 @@ static void ftp_done ( struct ftp_request *ftp, int rc ) { tcp_close ( &ftp->tcp_data ); /* Mark asynchronous operation as complete */ - async_done ( &ftp->aop, rc ); + async_done ( &ftp->async, rc ); } /** @@ -379,5 +379,5 @@ struct async_operation * ftp_get ( struct ftp_request *ftp ) { if ( ( rc = tcp_connect ( &ftp->tcp, &ftp->server, 0 ) ) != 0 ) ftp_done ( ftp, rc ); - return &ftp->aop; + return &ftp->async; } diff --git a/src/net/tcp/hello.c b/src/net/tcp/hello.c index 4de7e8729..25c079369 100644 --- a/src/net/tcp/hello.c +++ b/src/net/tcp/hello.c @@ -51,7 +51,7 @@ tcp_to_hello ( struct tcp_application *app ) { static void hello_closed ( struct tcp_application *app, int status ) { struct hello_request *hello = tcp_to_hello ( app ); - async_done ( &hello->aop, status ); + async_done ( &hello->async, status ); } static void hello_connected ( struct tcp_application *app ) { @@ -116,7 +116,7 @@ struct async_operation * say_hello ( struct hello_request *hello ) { hello->tcp.tcp_op = &hello_tcp_operations; if ( ( rc = tcp_connect ( &hello->tcp, &hello->server, 0 ) ) != 0 ) - async_done ( &hello->aop, rc ); + async_done ( &hello->async, rc ); - return &hello->aop; + return &hello->async; } diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index 22e24082e..dfa39f537 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -27,9 +27,11 @@ #include <stdlib.h> #include <string.h> #include <strings.h> -#include <vsprintf.h> +#include <errno.h> #include <assert.h> +#include <vsprintf.h> #include <gpxe/async.h> +#include <gpxe/uri.h> #include <gpxe/buffer.h> #include <gpxe/http.h> @@ -67,7 +69,7 @@ static void http_done ( struct http_request *http, int rc ) { } /* Mark async operation as complete */ - async_done ( &http->aop, rc ); + async_done ( &http->async, rc ); } /** @@ -303,12 +305,21 @@ static void http_newdata ( struct tcp_application *app, static void http_senddata ( struct tcp_application *app, void *buf, size_t len ) { struct http_request *http = tcp_to_http ( app ); + const char *path = http->uri->path; + const char *host = http->uri->host; + + if ( ! path ) + path = "/"; + + if ( ! host ) + host = ""; len = snprintf ( buf, len, - "GET /%s HTTP/1.1\r\n" + "GET %s HTTP/1.1\r\n" "User-Agent: gPXE/" VERSION "\r\n" "Host: %s\r\n" - "\r\n", http->filename, http->hostname ); + "\r\n", path, host ); + tcp_send ( app, ( buf + http->tx_offset ), ( len - http->tx_offset ) ); } @@ -347,16 +358,71 @@ static struct tcp_operations http_tcp_operations = { }; /** + * Reap asynchronous operation + * + * @v async Asynchronous operation + */ +static void http_reap ( struct async *async ) { + struct http_request *http = + container_of ( async, struct http_request, async ); + + free_uri ( http->uri ); + free ( http ); +} + +/** HTTP asynchronous operations */ +static struct async_operations http_async_operations = { + .reap = http_reap, +}; + +#warning "Quick name resolution hack" +#include <byteswap.h> + +/** * Initiate a HTTP connection * - * @v http a HTTP request + * @v uri Uniform Resource Identifier + * @v buffer Buffer into which to download file + * @v parent Parent asynchronous operation + * @ret rc Return status code + * + * If it returns success, this function takes ownership of the URI. */ -struct async_operation * http_get ( struct http_request *http ) { +int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) { + struct http_request *http; int rc; + /* Allocate and populate HTTP structure */ + http = malloc ( sizeof ( *http ) ); + if ( ! http ) { + rc = -ENOMEM; + goto err; + } + memset ( http, 0, sizeof ( *http ) ); + http->uri = uri; + http->buffer = buffer; http->tcp.tcp_op = &http_tcp_operations; - if ( ( rc = tcp_connect ( &http->tcp, &http->server, 0 ) ) != 0 ) - async_done ( &http->aop, rc ); - return &http->aop; +#warning "Quick name resolution hack" + union { + struct sockaddr_tcpip st; + struct sockaddr_in sin; + } server; + server.sin.sin_port = htons ( HTTP_PORT ); + server.sin.sin_family = AF_INET; + if ( inet_aton ( uri->host, &server.sin.sin_addr ) == 0 ) { + rc = -EINVAL; + goto err; + } + + if ( ( rc = tcp_connect ( &http->tcp, &server.st, 0 ) ) != 0 ) + goto err; + + async_init ( &http->async, &http_async_operations, parent ); + return 0; + + err: + DBGC ( http, "HTTP %p could not create request: %s\n", + http, strerror ( rc ) ); + return rc; } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index ae23cfe8e..09edf697d 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -121,7 +121,7 @@ static void iscsi_done ( struct iscsi_session *iscsi, int rc ) { iscsi->command = NULL; /* Mark asynchronous operation as complete */ - async_done ( &iscsi->aop, rc ); + async_done ( &iscsi->async, rc ); } /**************************************************************************** @@ -1208,10 +1208,11 @@ static struct tcp_operations iscsi_tcp_operations = { * * @v iscsi iSCSI session * @v command SCSI command - * @ret aop Asynchronous operation for this SCSI command + * @v parent Parent asynchronous operation + * @ret rc Return status code */ -struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, - struct scsi_command *command ) { +int iscsi_issue ( struct iscsi_session *iscsi, struct scsi_command *command, + struct async *parent ) { int rc; assert ( iscsi->command == NULL ); @@ -1219,7 +1220,7 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, if ( iscsi->instant_rc ) { /* Abort immediately rather than retrying */ - iscsi_done ( iscsi, iscsi->instant_rc ); + return iscsi->instant_rc; } else if ( iscsi->status ) { /* Session already open: issue command */ iscsi_start_command ( iscsi ); @@ -1231,11 +1232,12 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, 0 ) ) != 0 ) { DBGC ( iscsi, "iSCSI %p could not open TCP " "connection: %s\n", iscsi, strerror ( rc ) ); - iscsi_done ( iscsi, rc ); + return rc; } } - return &iscsi->aop; + async_init ( &iscsi->async, &default_async_operations, parent ); + return 0; } /** diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 8f8297018..a2d3db6bb 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -517,7 +517,7 @@ static void dhcp_done ( struct dhcp_session *dhcp, int rc ) { ref_del ( &dhcp->netdev_ref ); /* Mark async operation as complete */ - async_done ( &dhcp->aop, rc ); + async_done ( &dhcp->async, rc ); } /** Address for transmitting DHCP requests */ @@ -713,14 +713,15 @@ static void dhcp_forget_netdev ( struct reference *ref ) { * Initiate DHCP on a network interface * * @v dhcp DHCP session - * @ret aop Asynchronous operation + * @v parent Parent asynchronous operation + * @ret rc Return status code * * If the DHCP operation completes successfully, the * dhcp_session::options field will be filled in with the resulting * options block. The caller takes responsibility for eventually * calling free_dhcp_options(). */ -struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) { +int start_dhcp ( struct dhcp_session *dhcp, struct async *parent ) { int rc; /* Initialise DHCP session */ @@ -729,10 +730,8 @@ struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) { dhcp->state = DHCPDISCOVER; /* Bind to local port */ - if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 ) { - async_done ( &dhcp->aop, rc ); - goto out; - } + if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 ) + return rc; /* Add persistent reference to net device */ dhcp->netdev_ref.forget = dhcp_forget_netdev; @@ -741,6 +740,6 @@ struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) { /* Proof of concept: just send a single DHCPDISCOVER */ dhcp_send_request ( dhcp ); - out: - return &dhcp->aop; + async_init ( &dhcp->async, &default_async_operations, parent ); + return 0; } diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 6753e8380..69650ab0f 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -142,7 +142,7 @@ static void tftp_done ( struct tftp_session *tftp, int rc ) { udp_close ( &tftp->udp ); /* Mark async operation as complete */ - async_done ( &tftp->aop, rc ); + async_done ( &tftp->async, rc ); } /** @@ -477,7 +477,7 @@ struct async_operation * tftp_get ( struct tftp_session *tftp ) { /* Open UDP connection */ if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) { - async_done ( &tftp->aop, rc ); + async_done ( &tftp->async, rc ); goto out; } @@ -485,5 +485,5 @@ struct async_operation * tftp_get ( struct tftp_session *tftp ) { tftp_send_packet ( tftp ); out: - return &tftp->aop; + return &tftp->async; } |
