summaryrefslogtreecommitdiffstats
path: root/src/net/tcp.c
diff options
context:
space:
mode:
authorMichael Brown2011-06-23 17:25:48 +0200
committerMichael Brown2011-06-28 15:45:08 +0200
commitc68bf14559d57170493e4eed21fd3c05309c351e (patch)
tree6a29c6bf990f12809db2508d70d76ec4ee362142 /src/net/tcp.c
parent[infiniband] Send xfer_window_changed() when CMRC connection is established (diff)
downloadipxe-c68bf14559d57170493e4eed21fd3c05309c351e.tar.gz
ipxe-c68bf14559d57170493e4eed21fd3c05309c351e.tar.xz
ipxe-c68bf14559d57170493e4eed21fd3c05309c351e.zip
[tcp] Send xfer_window_changed() when window opens
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcp.c')
-rw-r--r--src/net/tcp.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/src/net/tcp.c b/src/net/tcp.c
index fbcf279e..4df1aed5 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -392,6 +392,25 @@ static size_t tcp_xmit_win ( struct tcp_connection *tcp ) {
}
/**
+ * Check data-transfer flow control window
+ *
+ * @v tcp TCP connection
+ * @ret len Length of window
+ */
+static size_t tcp_xfer_window ( struct tcp_connection *tcp ) {
+
+ /* Not ready if data queue is non-empty. This imposes a limit
+ * of only one unACKed packet in the TX queue at any time; we
+ * do this to conserve memory usage.
+ */
+ if ( ! list_empty ( &tcp->tx_queue ) )
+ return 0;
+
+ /* Return TCP window length */
+ return tcp_xmit_win ( tcp );
+}
+
+/**
* Process TCP transmit queue
*
* @v tcp TCP connection
@@ -1084,6 +1103,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
unsigned int flags;
size_t len;
uint32_t seq_len;
+ size_t old_xfer_window;
int rc;
/* Sanity check packet */
@@ -1145,6 +1165,9 @@ static int tcp_rx ( struct io_buffer *iobuf,
goto discard;
}
+ /* Record old data-transfer window */
+ old_xfer_window = tcp_xfer_window ( tcp );
+
/* Handle ACK, if present */
if ( flags & TCP_ACK ) {
if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
@@ -1191,6 +1214,10 @@ static int tcp_rx ( struct io_buffer *iobuf,
start_timer_fixed ( &tcp->wait, ( 2 * TCP_MSL ) );
}
+ /* Notify application if window has changed */
+ if ( tcp_xfer_window ( tcp ) != old_xfer_window )
+ xfer_window_changed ( &tcp->xfer );
+
return 0;
discard:
@@ -1257,25 +1284,6 @@ static void tcp_xfer_close ( struct tcp_connection *tcp, int rc ) {
}
/**
- * Check flow control window
- *
- * @v tcp TCP connection
- * @ret len Length of window
- */
-static size_t tcp_xfer_window ( struct tcp_connection *tcp ) {
-
- /* Not ready if data queue is non-empty. This imposes a limit
- * of only one unACKed packet in the TX queue at any time; we
- * do this to conserve memory usage.
- */
- if ( ! list_empty ( &tcp->tx_queue ) )
- return 0;
-
- /* Return TCP window length */
- return tcp_xmit_win ( tcp );
-}
-
-/**
* Deliver datagram as I/O buffer
*
* @v tcp TCP connection