aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-04-26 15:36:41 -0700
committerH. Peter Anvin <hpa@zytor.com>2012-04-26 15:36:41 -0700
commit0dc83abe6a1f4ada9ecf15096539931e842b49f7 (patch)
treee1d3a72531f249d104d2be49f448d898fb86c0f3
parent6029b7afd344cd6a8cd686db1786d763d57669e4 (diff)
downloadsyslinux-0dc83abe6a1f4ada9ecf15096539931e842b49f7.tar.gz
syslinux-0dc83abe6a1f4ada9ecf15096539931e842b49f7.tar.xz
syslinux-0dc83abe6a1f4ada9ecf15096539931e842b49f7.zip
pxe, tftp: Unify UDP send and use pbuf memory
The spec says memory using netbuf_ref() isn't allowed to change, so use pbuf memory. This seems to avoid an assert in the lwip stack. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/pxe/tftp.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/core/fs/pxe/tftp.c b/core/fs/pxe/tftp.c
index f1e22435..9897e803 100644
--- a/core/fs/pxe/tftp.c
+++ b/core/fs/pxe/tftp.c
@@ -44,6 +44,39 @@ static void tftp_close_file(struct inode *inode)
}
}
+/*
+ * Send a UDP packet.
+ */
+static void udp_send(struct netconn *conn, const void *data, size_t len)
+{
+ 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);
+
+ err = netconn_send(conn, nbuf);
+ if (err) {
+ printf("netconn_send error %d\n", err);
+ goto out;
+ }
+
+out:
+ netbuf_delete(nbuf);
+}
+
/**
* Send an ERROR packet. This is used to terminate a connection.
*
@@ -59,7 +92,6 @@ static void tftp_error(struct inode *inode, uint16_t errnum,
uint16_t err_num;
char err_msg[64];
} __packed err_buf;
- struct netbuf *nbuf;
int len = min(strlen(errstr), sizeof(err_buf.err_msg)-1);
struct pxe_pvt_inode *socket = PVT(inode);
@@ -68,11 +100,7 @@ static void tftp_error(struct inode *inode, uint16_t errnum,
memcpy(err_buf.err_msg, errstr, len);
err_buf.err_msg[len] = '\0';
- nbuf = netbuf_new();
- netbuf_ref(nbuf, &err_buf, 4 + len + 1);
- netconn_send(socket->conn, nbuf);
- /* If something goes wrong, there is nothing we can do, anyway... */
- netbuf_delete(nbuf);
+ udp_send(socket->conn, &err_buf, 4 + len + 1);
}
/**
@@ -84,23 +112,14 @@ static void tftp_error(struct inode *inode, uint16_t errnum,
*/
static void ack_packet(struct inode *inode, uint16_t ack_num)
{
- err_t err;
static uint16_t ack_packet_buf[2];
- struct netbuf *nbuf;
struct pxe_pvt_inode *socket = PVT(inode);
/* Packet number to ack */
ack_packet_buf[0] = TFTP_ACK;
ack_packet_buf[1] = htons(ack_num);
- nbuf = netbuf_new();
- netbuf_ref(nbuf, ack_packet_buf, 4);
- err = netconn_send(socket->conn, nbuf);
- netbuf_delete(nbuf);
- (void)err;
-#if 0
- printf("sent %s\n", err ? "FAILED" : "OK");
-#endif
+ udp_send(socket->conn, ack_packet_buf, 4);
}
/*
@@ -291,11 +310,9 @@ sendreq:
return; /* No file available... */
oldtime = jiffies();
- nbuf = netbuf_new();
- netbuf_ref(nbuf, rrq_packet_buf, rrq_len);
addr.addr = url->ip;
- netconn_sendto(socket->conn, nbuf, &addr, url->port);
- netbuf_delete(nbuf);
+ netconn_connect(socket->conn, &addr, url->port);
+ udp_send(socket->conn, rrq_packet_buf, rrq_len);
/* If the WRITE call fails, we let the timeout take care of it... */
wait_pkt: