aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-12 13:47:22 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-07-12 13:53:07 +0100
commit7ab8f23aa2140951608544ed557f7529cf32d98d (patch)
tree695692ac25cf676269cc63888d0c03486a91fc2b
parent3ede311eec28bba77f3469d4e0a834ac000f686e (diff)
downloadsyslinux-6.02-pre5.tar.gz
syslinux-6.02-pre5.tar.xz
syslinux-6.02-pre5.zip
efi, udp: implement receive timeoutsyslinux-6.02-pre5
We currently wait indefinitely in core_udp_recv() when reading packets. Implement a timeout, which is what all the other network stacks do. By timing out we are now able to handle packet loss on the network, e.g. we'll now re-send TFTP requests instead of waiting for ACK packets that will never come. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--efi/udp.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/efi/udp.c b/efi/udp.c
index 301074d0..db9bc8f9 100644
--- a/efi/udp.c
+++ b/efi/udp.c
@@ -182,6 +182,7 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len,
EFI_UDP4 *udp;
size_t size;
int rv = -1;
+ jiffies_t start;
(void)socket;
@@ -197,8 +198,19 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len,
if (status != EFI_SUCCESS)
goto bail;
- while (cb_status == -1)
+ start = jiffies();
+ while (cb_status == -1) {
+ /* 15ms receive timeout... */
+ if (jiffies() - start >= 15) {
+ if (jiffies() - start >= 30)
+ dprintf("Failed to cancel UDP\n");
+
+ uefi_call_wrapper(udp->Cancel, 2, udp, &token);
+ dprintf("core_udp_recv: timed out\n");
+ }
+
uefi_call_wrapper(udp->Poll, 1, udp);
+ }
if (cb_status == 0)
rv = 0;
@@ -206,6 +218,9 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len,
/* Reset */
cb_status = -1;
+ if (rv)
+ goto bail;
+
rxdata = token.Packet.RxData;
frag = &rxdata->FragmentTable[0];