aboutsummaryrefslogtreecommitdiffstats
path: root/core/fs/pxe/core.c
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2013-09-23 17:13:53 -0400
committerGene Cumm <gene.cumm@gmail.com>2013-09-23 17:13:53 -0400
commit131b9981b8dbf5fa1c014995f44b10b7b099fe12 (patch)
tree8f660bac2786b551872e46c1450a40c0029361da /core/fs/pxe/core.c
parentceb14335790f70378dddfbf0202d2bcda0c54a03 (diff)
downloadsyslinux-131b9981b8dbf5fa1c014995f44b10b7b099fe12.tar.gz
syslinux-131b9981b8dbf5fa1c014995f44b10b7b099fe12.tar.xz
syslinux-131b9981b8dbf5fa1c014995f44b10b7b099fe12.zip
PXELINUX: Use sendto() instead of connect()/send()/disconnect()
This commit prevents a race-condition on systems that have functional interrupts (observed with iPXE and select other Dell systems). Without this, the reply packet could be received by the core prior to the disconnect() call, see that it doesn't have a matching PCB (protocol control block, iirc) since the reply has a different far-end UDP port than the original request, and lwIP will discard the packet before PXELINUX can see it. net_core_sendto() instead of net_core_connect() net_core_send() net_core_disconnect() Commit message expanded with Matt Fleming's assistance Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
Diffstat (limited to 'core/fs/pxe/core.c')
-rw-r--r--core/fs/pxe/core.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/core/fs/pxe/core.c b/core/fs/pxe/core.c
index e330ba82..c1de8957 100644
--- a/core/fs/pxe/core.c
+++ b/core/fs/pxe/core.c
@@ -6,6 +6,8 @@
#include <net.h>
#include "pxe.h"
+#include <dprintf.h>
+
const struct url_scheme url_schemes[] = {
{ "tftp", tftp_open, 0 },
{ "http", http_open, O_DIRECTORY },
@@ -81,6 +83,7 @@ void net_core_connect(struct pxe_pvt_inode *socket, uint32_t ip,
struct net_private_lwip *priv = &socket->net.lwip;
struct ip_addr addr;
+ dprintf2("net_core_connect: %08X %04X\n", ntohl(ip), port);
addr.addr = ip;
netconn_connect(priv->conn, &addr, port);
}
@@ -174,6 +177,51 @@ out:
netbuf_delete(nbuf);
}
+ /**
+ * Send a UDP packet to a destination
+ *
+ * @param:socket, the open socket
+ * @param:data, data buffer to send
+ * @param:len, size of data bufer
+ * @param:ip, the ip address
+ * @param:port, the port number, host-byte order
+ */
+void net_core_sendto(struct pxe_pvt_inode *socket, const void *data,
+ size_t len, uint32_t ip, uint16_t port)
+{
+ struct netconn *conn = socket->net.lwip.conn;
+ struct ip_addr addr;
+ struct netbuf *nbuf;
+ void *pbuf;
+ int err;
+
+ nbuf = netbuf_new();
+ if (!nbuf) {
+ printf("netbuf allocation error\n");
+ return;
+ }
+
+ pbuf = netbuf_alloc(nbuf, len);
+ if (!pbuf) {
+ printf("pbuf allocation error\n");
+ goto out;
+ }
+
+ memcpy(pbuf, data, len);
+
+ dprintf("net_core_sendto: %08X %04X\n", ntohl(ip), port);
+ addr.addr = ip;
+
+ err = netconn_sendto(conn, nbuf, &addr, port);
+ if (err) {
+ printf("netconn_sendto error %d\n", err);
+ goto out;
+ }
+
+out:
+ netbuf_delete(nbuf);
+}
+
/**
* Network stack-specific initialization
*/