diff options
| author | Michael Brown | 2006-12-28 00:09:46 +0100 |
|---|---|---|
| committer | Michael Brown | 2006-12-28 00:09:46 +0100 |
| commit | 61ed298bc7dc60c84fea456444e853a73de0c901 (patch) | |
| tree | 99978dfeb667df0f79356cc4132f99922e2fd803 /src/net/tcp | |
| parent | Keep running the main processing loop while waiting for input. (diff) | |
| download | ipxe-61ed298bc7dc60c84fea456444e853a73de0c901.tar.gz ipxe-61ed298bc7dc60c84fea456444e853a73de0c901.tar.xz ipxe-61ed298bc7dc60c84fea456444e853a73de0c901.zip | |
Merge changes from mcb-tcp-fixes branch.
Diffstat (limited to 'src/net/tcp')
| -rw-r--r-- | src/net/tcp/ftp.c | 158 | ||||
| -rw-r--r-- | src/net/tcp/hello.c | 44 | ||||
| -rw-r--r-- | src/net/tcp/http.c | 48 | ||||
| -rw-r--r-- | src/net/tcp/iscsi.c | 87 |
4 files changed, 157 insertions, 180 deletions
diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index 6082d97db..1bdf81353 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -58,49 +58,31 @@ static inline const void * ftp_string_data ( struct ftp_request *ftp, } /** - * Get FTP request from control TCP connection + * Get FTP request from control TCP application * - * @v conn TCP connection + * @v app TCP application * @ret ftp FTP request */ -static inline struct ftp_request * tcp_to_ftp ( struct tcp_connection *conn ) { - return container_of ( conn, struct ftp_request, tcp ); +static inline struct ftp_request * tcp_to_ftp ( struct tcp_application *app ) { + return container_of ( app, struct ftp_request, tcp ); } /** - * Set overall FTP operation status + * Mark FTP operation as complete * * @v ftp FTP request * @v rc Return status code - * - * Set the return status that will eventually be returned via - * ftp_done(). If multiple errors are flagged, only the first will be - * returned. */ -static void ftp_set_status ( struct ftp_request *ftp, int rc ) { - if ( ! ftp->rc ) - ftp->rc = rc; -} +static void ftp_done ( struct ftp_request *ftp, int rc ) { -/** - * Clear overall FTP operation status - * - * @v ftp FTP request - */ -static void ftp_clear_status ( struct ftp_request *ftp ) { - ftp->rc = 0; -} + DBG ( "FTP %p completed with status %d\n", ftp, rc ); -/** - * Mark FTP operation as complete - * - * @v ftp FTP request - */ -static void ftp_done ( struct ftp_request *ftp ) { - - DBG ( "FTP %p completed with status %d\n", ftp, ftp->rc ); + /* Close both TCP connections */ + tcp_close ( &ftp->tcp ); + tcp_close ( &ftp->tcp_data ); - async_done ( &ftp->aop, ftp->rc ); + /* Mark asynchronous operation as complete */ + async_done ( &ftp->aop, rc ); } /** @@ -131,7 +113,7 @@ static void ftp_parse_value ( char **text, uint8_t *value, size_t len ) { * * @v ftp FTP request * - * This is called once we have received a complete repsonse line. + * This is called once we have received a complete response line. */ static void ftp_reply ( struct ftp_request *ftp ) { char status_major = ftp->status_text[0]; @@ -147,21 +129,31 @@ static void ftp_reply ( struct ftp_request *ftp ) { * fatal error. */ if ( ! ( ( status_major == '2' ) || - ( ( status_major == '3' ) && ( ftp->state == FTP_USER ) ) ) ) - goto err; + ( ( status_major == '3' ) && ( ftp->state == FTP_USER ) ) ) ){ + /* Flag protocol error and close connections */ + ftp_done ( ftp, -EPROTO ); + } /* Open passive connection when we get "PASV" response */ if ( ftp->state == FTP_PASV ) { char *ptr = ftp->passive_text; - struct sockaddr_in *sin = - ( struct sockaddr_in * ) &ftp->tcp_data.peer; - - sin->sin_family = AF_INET; - ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_addr, - sizeof ( sin->sin_addr ) ); - ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_port, - sizeof ( sin->sin_port ) ); - tcp_connect ( &ftp->tcp_data ); + union { + struct sockaddr_in sin; + struct sockaddr_tcpip st; + } sa; + int rc; + + sa.sin.sin_family = AF_INET; + ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_addr, + sizeof ( sa.sin.sin_addr ) ); + ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_port, + sizeof ( sa.sin.sin_port ) ); + if ( ( rc = tcp_connect ( &ftp->tcp_data, &sa.st, 0 ) ) != 0 ){ + DBG ( "FTP %p could not create data connection\n", + ftp ); + ftp_done ( ftp, rc ); + return; + } } /* Move to next state */ @@ -176,26 +168,21 @@ static void ftp_reply ( struct ftp_request *ftp ) { } return; - - err: - /* Flag protocol error and close connections */ - ftp_set_status ( ftp, -EPROTO ); - tcp_close ( &ftp->tcp ); } /** * Handle new data arriving on FTP control channel * - * @v conn TCP connection + * @v app TCP application * @v data New data * @v len Length of new data * * Data is collected until a complete line is received, at which point * its information is passed to ftp_reply(). */ -static void ftp_newdata ( struct tcp_connection *conn, +static void ftp_newdata ( struct tcp_application *app, void *data, size_t len ) { - struct ftp_request *ftp = tcp_to_ftp ( conn ); + struct ftp_request *ftp = tcp_to_ftp ( app ); char *recvbuf = ftp->recvbuf; size_t recvsize = ftp->recvsize; char c; @@ -242,10 +229,10 @@ static void ftp_newdata ( struct tcp_connection *conn, /** * Handle acknowledgement of data sent on FTP control channel * - * @v conn TCP connection + * @v app TCP application */ -static void ftp_acked ( struct tcp_connection *conn, size_t len ) { - struct ftp_request *ftp = tcp_to_ftp ( conn ); +static void ftp_acked ( struct tcp_application *app, size_t len ) { + struct ftp_request *ftp = tcp_to_ftp ( app ); /* Mark off ACKed portion of the currently-transmitted data */ ftp->already_sent += len; @@ -254,13 +241,13 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) { /** * Construct data to send on FTP control channel * - * @v conn TCP connection + * @v app TCP application * @v buf Temporary data buffer * @v len Length of temporary data buffer */ -static void ftp_senddata ( struct tcp_connection *conn, +static void ftp_senddata ( struct tcp_application *app, void *buf, size_t len ) { - struct ftp_request *ftp = tcp_to_ftp ( conn ); + struct ftp_request *ftp = tcp_to_ftp ( app ); const struct ftp_string *string; /* Send the as-yet-unACKed portion of the string for the @@ -269,31 +256,24 @@ static void ftp_senddata ( struct tcp_connection *conn, string = &ftp_strings[ftp->state]; len = snprintf ( buf, len, string->format, ftp_string_data ( ftp, string->data_offset ) ); - tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent ); + tcp_send ( app, buf + ftp->already_sent, len - ftp->already_sent ); } /** * Handle control channel being closed * - * @v conn TCP connection + * @v app TCP application * * When the control channel is closed, the data channel must also be * closed, if it is currently open. */ -static void ftp_closed ( struct tcp_connection *conn, int status ) { - struct ftp_request *ftp = tcp_to_ftp ( conn ); +static void ftp_closed ( struct tcp_application *app, int status ) { + struct ftp_request *ftp = tcp_to_ftp ( app ); DBG ( "FTP %p control connection closed (status %d)\n", ftp, status ); - /* Close data channel and record status */ - ftp_set_status ( ftp, status ); - tcp_close ( &ftp->tcp_data ); - - /* Mark FTP operation as complete if we are the last - * connection to close - */ - if ( tcp_closed ( &ftp->tcp_data ) ) - ftp_done ( ftp ); + /* Complete FTP operation */ + ftp_done ( ftp, status ); } /** FTP control channel operations */ @@ -311,20 +291,20 @@ static struct tcp_operations ftp_tcp_operations = { */ /** - * Get FTP request from data TCP connection + * Get FTP request from data TCP application * - * @v conn TCP connection + * @v app TCP application * @ret ftp FTP request */ static inline struct ftp_request * -tcp_to_ftp_data ( struct tcp_connection *conn ) { - return container_of ( conn, struct ftp_request, tcp_data ); +tcp_to_ftp_data ( struct tcp_application *app ) { + return container_of ( app, struct ftp_request, tcp_data ); } /** * Handle data channel being closed * - * @v conn TCP connection + * @v app TCP application * * When the data channel is closed, the control channel should be left * alone; the server will send a completion message via the control @@ -332,36 +312,28 @@ tcp_to_ftp_data ( struct tcp_connection *conn ) { * * If the data channel is closed due to an error, we abort the request. */ -static void ftp_data_closed ( struct tcp_connection *conn, int status ) { - struct ftp_request *ftp = tcp_to_ftp_data ( conn ); +static void ftp_data_closed ( struct tcp_application *app, int status ) { + struct ftp_request *ftp = tcp_to_ftp_data ( app ); DBG ( "FTP %p data connection closed (status %d)\n", ftp, status ); /* If there was an error, close control channel and record status */ - if ( status ) { - ftp_set_status ( ftp, status ); - tcp_close ( &ftp->tcp ); - } - - /* Mark FTP operation as complete if we are the last - * connection to close - */ - if ( tcp_closed ( &ftp->tcp ) ) - ftp_done ( ftp ); + if ( status ) + ftp_done ( ftp, status ); } /** * Handle new data arriving on the FTP data channel * - * @v conn TCP connection + * @v app TCP application * @v data New data * @v len Length of new data * * Data is handed off to the callback registered in the FTP request. */ -static void ftp_data_newdata ( struct tcp_connection *conn, +static void ftp_data_newdata ( struct tcp_application *app, void *data, size_t len ) { - struct ftp_request *ftp = tcp_to_ftp_data ( conn ); + struct ftp_request *ftp = tcp_to_ftp_data ( app ); ftp->callback ( data, len ); } @@ -384,14 +356,16 @@ static struct tcp_operations ftp_data_tcp_operations = { * @v ftp FTP request */ struct async_operation * ftp_get ( struct ftp_request *ftp ) { - + int rc; + DBG ( "FTP %p fetching %s\n", ftp, ftp->filename ); ftp->tcp.tcp_op = &ftp_tcp_operations; ftp->tcp_data.tcp_op = &ftp_data_tcp_operations; ftp->recvbuf = ftp->status_text; ftp->recvsize = sizeof ( ftp->status_text ) - 1; - ftp_clear_status ( ftp ); - tcp_connect ( &ftp->tcp ); + if ( ( rc = tcp_connect ( &ftp->tcp, &ftp->server, 0 ) ) != 0 ) + ftp_done ( ftp, rc ); + return &ftp->aop; } diff --git a/src/net/tcp/hello.c b/src/net/tcp/hello.c index d74e52f9f..4de7e8729 100644 --- a/src/net/tcp/hello.c +++ b/src/net/tcp/hello.c @@ -10,9 +10,9 @@ * "Hello world" TCP protocol * * This file implements a trivial TCP-based protocol. It connects to - * the server specified in hello_request::tcp and transmits a single - * message (hello_request::message). Any data received from the - * server will be passed to the callback function, + * the server specified in hello_request::server and transmits a + * single message (hello_request::message). Any data received from + * the server will be passed to the callback function, * hello_request::callback(), and once the connection has been closed, * the asynchronous operation associated with the request will be * marked as complete. @@ -26,13 +26,13 @@ * } * * struct hello_request hello = { + * .server = { + * ... + * }, * .message = "hello world!", * .callback = my_callback, * }; * - * hello.sin.sin_addr.s_addr = ... server IP address ... - * hello.sin.sin_port = ... server port ... - * * rc = async_wait ( say_hello ( &hello ) ); * * @endcode @@ -44,25 +44,25 @@ */ static inline struct hello_request * -tcp_to_hello ( struct tcp_connection *conn ) { - return container_of ( conn, struct hello_request, tcp ); +tcp_to_hello ( struct tcp_application *app ) { + return container_of ( app, struct hello_request, tcp ); } -static void hello_closed ( struct tcp_connection *conn, int status ) { - struct hello_request *hello = tcp_to_hello ( conn ); +static void hello_closed ( struct tcp_application *app, int status ) { + struct hello_request *hello = tcp_to_hello ( app ); async_done ( &hello->aop, status ); } -static void hello_connected ( struct tcp_connection *conn ) { - struct hello_request *hello = tcp_to_hello ( conn ); +static void hello_connected ( struct tcp_application *app ) { + struct hello_request *hello = tcp_to_hello ( app ); hello->remaining = strlen ( hello->message ); hello->state = HELLO_SENDING_MESSAGE; } -static void hello_acked ( struct tcp_connection *conn, size_t len ) { - struct hello_request *hello = tcp_to_hello ( conn ); +static void hello_acked ( struct tcp_application *app, size_t len ) { + struct hello_request *hello = tcp_to_hello ( app ); hello->message += len; hello->remaining -= len; @@ -84,18 +84,18 @@ static void hello_acked ( struct tcp_connection *conn, size_t len ) { } } -static void hello_newdata ( struct tcp_connection *conn, void *data, +static void hello_newdata ( struct tcp_application *app, void *data, size_t len ) { - struct hello_request *hello = tcp_to_hello ( conn ); + struct hello_request *hello = tcp_to_hello ( app ); hello->callback ( data, len ); } -static void hello_senddata ( struct tcp_connection *conn, +static void hello_senddata ( struct tcp_application *app, void *buf __unused, size_t len __unused ) { - struct hello_request *hello = tcp_to_hello ( conn ); + struct hello_request *hello = tcp_to_hello ( app ); - tcp_send ( conn, hello->message, hello->remaining ); + tcp_send ( app, hello->message, hello->remaining ); } static struct tcp_operations hello_tcp_operations = { @@ -112,7 +112,11 @@ static struct tcp_operations hello_tcp_operations = { * @v hello "Hello world" request */ struct async_operation * say_hello ( struct hello_request *hello ) { + int rc; + hello->tcp.tcp_op = &hello_tcp_operations; - tcp_connect ( &hello->tcp ); + if ( ( rc = tcp_connect ( &hello->tcp, &hello->server, 0 ) ) != 0 ) + async_done ( &hello->aop, rc ); + return &hello->aop; } diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index 01f0aeacb..3bba8b338 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -39,28 +39,28 @@ */ static inline struct http_request * -tcp_to_http ( struct tcp_connection *conn ) { - return container_of ( conn, struct http_request, tcp ); +tcp_to_http ( struct tcp_application *app ) { + return container_of ( app, struct http_request, tcp ); } /** * Close an HTTP connection * - * @v conn a TCP Connection + * @v app a TCP Application * @v status connection status at close */ -static void http_closed ( struct tcp_connection *conn, int status ) { - struct http_request *http = tcp_to_http ( conn ); +static void http_closed ( struct tcp_application *app, int status ) { + struct http_request *http = tcp_to_http ( app ); async_done ( &http->aop, status ); } /** * Callback after a TCP connection is established * - * @v conn a TCP Connection + * @v app a TCP Application */ -static void http_connected ( struct tcp_connection *conn ) { - struct http_request *http = tcp_to_http ( conn ); +static void http_connected ( struct tcp_application *app ) { + struct http_request *http = tcp_to_http ( app ); http->state = HTTP_REQUEST_FILE; } @@ -68,11 +68,11 @@ static void http_connected ( struct tcp_connection *conn ) { /** * Callback for when TCP data is acknowledged * - * @v conn a TCP Connection + * @v app a TCP Application * @v len the length of data acked */ -static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ ((unused)) ) { - struct http_request *http = tcp_to_http ( conn ); +static void http_acked ( struct tcp_application *app, size_t len __attribute__ ((unused)) ) { + struct http_request *http = tcp_to_http ( app ); // assume that the whole GET request was sent in on epacket @@ -84,7 +84,7 @@ static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ ( case HTTP_RECV_FILE: break; case HTTP_DONE: - //tcp_close(conn); + //tcp_close(app); break; default: break; @@ -95,13 +95,13 @@ static void http_acked ( struct tcp_connection *conn, size_t len __attribute__ ( /** * Callback when new TCP data is recieved * - * @v conn a TCP Connection + * @v app a TCP Application * @v data a pointer to the data recieved * @v len length of data buffer */ -static void http_newdata ( struct tcp_connection *conn, void *data, +static void http_newdata ( struct tcp_application *app, void *data, size_t len ) { - struct http_request *http = tcp_to_http ( conn ); + struct http_request *http = tcp_to_http ( app ); char *content_length; char *start = data; char *rcp; int rc; @@ -142,7 +142,7 @@ static void http_newdata ( struct tcp_connection *conn, void *data, //printf("File recv is %d\n", http->file_recv); if ( http->file_recv == http->file_size ){ http->state = HTTP_DONE; - tcp_close(conn); + tcp_close(app); } break; case HTTP_REQUEST_FILE: @@ -155,10 +155,10 @@ static void http_newdata ( struct tcp_connection *conn, void *data, /** * Callback for sending TCP data * - * @v conn a TCP Connection + * @v app a TCP Application */ -static void http_senddata ( struct tcp_connection *conn, void *buf, size_t len ) { - struct http_request *http = tcp_to_http ( conn ); +static void http_senddata ( struct tcp_application *app, void *buf, size_t len ) { + struct http_request *http = tcp_to_http ( app ); switch ( http->state ){ case HTTP_REQUEST_FILE: @@ -166,13 +166,13 @@ static void http_senddata ( struct tcp_connection *conn, void *buf, size_t len ) printf("%s\n",(char *)buf); // string is: GET <file> HTTP/1.0\r\n\r\n - tcp_send ( conn, buf, len); + tcp_send ( app, buf, len); break; case HTTP_PARSE_HEADER: case HTTP_RECV_FILE: break; case HTTP_DONE: - //tcp_close(conn) + //tcp_close(app) break; default: break; @@ -193,8 +193,12 @@ static struct tcp_operations http_tcp_operations = { * @v http a HTTP request */ struct async_operation * get_http ( struct http_request *http ) { + int rc; + http->tcp.tcp_op = &http_tcp_operations; http->state = HTTP_REQUEST_FILE; - tcp_connect ( &http->tcp ); + if ( ( rc = tcp_connect ( &http->tcp, &http->server, 0 ) ) != 0 ) + async_done ( &http->aop, rc ); + return &http->aop; } diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index a0137dc56..f3e5e3247 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -720,11 +720,14 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data, /* Check for login redirection */ if ( response->status_class == ISCSI_STATUS_REDIRECT ) { DBG ( "iSCSI %p redirecting to new server\n", iscsi ); - /* Close the TCP connection; our TCP closed() method - * will take care of the reconnection once this - * connection has been cleanly terminated. - */ tcp_close ( &iscsi->tcp ); + iscsi->status = 0; + if ( ( rc = tcp_connect ( &iscsi->tcp, &iscsi->target, + 0 ) ) != 0 ) { + DBG ( "iSCSI %p could not open TCP connection\n", + iscsi ); + iscsi_done ( iscsi, rc ); + } return; } @@ -778,8 +781,8 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data, */ static inline struct iscsi_session * -tcp_to_iscsi ( struct tcp_connection *conn ) { - return container_of ( conn, struct iscsi_session, tcp ); +tcp_to_iscsi ( struct tcp_application *app ) { + return container_of ( app, struct iscsi_session, tcp ); } /** @@ -859,8 +862,8 @@ static void iscsi_tx_done ( struct iscsi_session *iscsi ) { * Updates iscsi->tx_offset and, if applicable, transitions to the * next TX state. */ -static void iscsi_acked ( struct tcp_connection *conn, size_t len ) { - struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); +static void iscsi_acked ( struct tcp_application *app, size_t len ) { + struct iscsi_session *iscsi = tcp_to_iscsi ( app ); struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; enum iscsi_tx_state next_state; @@ -916,9 +919,9 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) { * * Constructs data to be sent for the current TX state */ -static void iscsi_senddata ( struct tcp_connection *conn, +static void iscsi_senddata ( struct tcp_application *app, void *buf, size_t len ) { - struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); + struct iscsi_session *iscsi = tcp_to_iscsi ( app ); struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; static const char pad[] = { '\0', '\0', '\0' }; @@ -927,7 +930,7 @@ static void iscsi_senddata ( struct tcp_connection *conn, /* Nothing to send */ break; case ISCSI_TX_BHS: - tcp_send ( conn, &iscsi->tx_bhs.bytes[iscsi->tx_offset], + tcp_send ( app, &iscsi->tx_bhs.bytes[iscsi->tx_offset], ( sizeof ( iscsi->tx_bhs ) - iscsi->tx_offset ) ); break; case ISCSI_TX_AHS: @@ -938,7 +941,7 @@ static void iscsi_senddata ( struct tcp_connection *conn, iscsi_tx_data ( iscsi, buf, len ); break; case ISCSI_TX_DATA_PADDING: - tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths ) + tcp_send ( app, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths ) - iscsi->tx_offset ) ); break; default: @@ -1029,7 +1032,7 @@ static void iscsi_rx_bhs ( struct iscsi_session *iscsi, void *data, /** * Receive new data * - * @v tcp TCP connection + * @v tcp TCP application * @v data Received data * @v len Length of received data * @@ -1040,9 +1043,9 @@ static void iscsi_rx_bhs ( struct iscsi_session *iscsi, void *data, * always has a full copy of the BHS available, even for portions of * the data in different packets to the BHS. */ -static void iscsi_newdata ( struct tcp_connection *conn, void *data, +static void iscsi_newdata ( struct tcp_application *app, void *data, size_t len ) { - struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); + struct iscsi_session *iscsi = tcp_to_iscsi ( app ); struct iscsi_bhs_common *common = &iscsi->rx_bhs.common; void ( *process ) ( struct iscsi_session *iscsi, void *data, size_t len, size_t remaining ); @@ -1098,38 +1101,28 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data, } } -#warning "Remove me soon" -static struct tcp_operations iscsi_tcp_operations; - /** * Handle TCP connection closure * - * @v conn TCP connection + * @v app TCP application * @v status Error code, if any * */ -static void iscsi_closed ( struct tcp_connection *conn, int status ) { - struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); - int session_status = iscsi->status; +static void iscsi_closed ( struct tcp_application *app, int status ) { + struct iscsi_session *iscsi = tcp_to_iscsi ( app ); + int rc; /* Clear session status */ iscsi->status = 0; - /* If we are deliberately closing down, exit cleanly */ - if ( session_status & ISCSI_STATUS_CLOSING ) { - iscsi_done ( iscsi, status ); - return; - } - /* Retry connection if within the retry limit, otherwise fail */ if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) { DBG ( "iSCSI %p retrying connection\n", iscsi ); - /* Re-copy address to handle redirection */ - memset ( &iscsi->tcp, 0, sizeof ( iscsi->tcp ) ); - iscsi->tcp.tcp_op = &iscsi_tcp_operations; - memcpy ( &iscsi->tcp.peer, &iscsi->target, - sizeof ( iscsi->tcp.peer ) ); - tcp_connect ( conn ); + if ( ( rc = tcp_connect ( app, &iscsi->target, 0 ) ) != 0 ) { + DBG ( "iSCSI %p could not open TCP connection\n", + iscsi ); + iscsi_done ( iscsi, rc ); + } } else { printf ( "iSCSI %p retry count exceeded\n", iscsi ); iscsi_done ( iscsi, status ); @@ -1139,11 +1132,11 @@ static void iscsi_closed ( struct tcp_connection *conn, int status ) { /** * Handle TCP connection opening * - * @v conn TCP connection + * @v app TCP application * */ -static void iscsi_connected ( struct tcp_connection *conn ) { - struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); +static void iscsi_connected ( struct tcp_application *app ) { + struct iscsi_session *iscsi = tcp_to_iscsi ( app ); /* Set connected flag and reset retry count */ iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE | @@ -1179,6 +1172,8 @@ static struct tcp_operations iscsi_tcp_operations = { */ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, struct scsi_command *command ) { + int rc; + assert ( iscsi->command == NULL ); iscsi->command = command; @@ -1198,9 +1193,12 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, } else { /* Session not open: initiate login */ iscsi->tcp.tcp_op = &iscsi_tcp_operations; - memcpy ( &iscsi->tcp.peer, &iscsi->target, - sizeof ( iscsi->tcp.peer ) ); - tcp_connect ( &iscsi->tcp ); + if ( ( rc = tcp_connect ( &iscsi->tcp, &iscsi->target, + 0 ) ) != 0 ) { + DBG ( "iSCSI %p could not open TCP connection\n", + iscsi ); + iscsi_done ( iscsi, rc ); + } } return &iscsi->aop; @@ -1212,10 +1210,7 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi, * @v iscsi iSCSI session * @ret aop Asynchronous operation */ -struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) { - if ( iscsi->status ) { - iscsi->status |= ISCSI_STATUS_CLOSING; - tcp_close ( &iscsi->tcp ); - } - return &iscsi->aop; +void iscsi_shutdown ( struct iscsi_session *iscsi ) { + iscsi->status = 0; + tcp_close ( &iscsi->tcp ); } |
