From: "Hervé Poussineau" <hpoussin@reactos.org>
To: qemu-devel@nongnu.org
Cc: hpa@zytor.com, "Stefan Hajnoczi" <stefanha@redhat.com>,
"Hervé Poussineau" <hpoussin@reactos.org>,
"Samuel Thibault" <samuel.thibault@ens-lyon.org>,
"Jan Kiszka" <jan.kiszka@siemens.com>
Subject: [Qemu-devel] [PATCH] slirp: support dynamic block size for TFTP transfers
Date: Mon, 21 Nov 2016 20:45:49 +0100 [thread overview]
Message-ID: <1479757549-18672-1-git-send-email-hpoussin@reactos.org> (raw)
The blocksize option is defined in RFC 1783.
We now support block sizes between 1 and 1432 bytes, instead of 512 only.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
slirp/tftp.c | 26 ++++++++++++++------------
slirp/tftp.h | 8 +++++---
2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/slirp/tftp.c b/slirp/tftp.c
index c185906..d53a657 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -72,6 +72,7 @@ static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas,
memset(spt, 0, sizeof(*spt));
spt->client_addr = *srcsas;
spt->fd = -1;
+ spt->block_size = 512;
spt->client_port = tp->udp.uh_sport;
spt->slirp = slirp;
@@ -115,7 +116,7 @@ static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr,
}
if (len) {
- lseek(spt->fd, block_nr * 512, SEEK_SET);
+ lseek(spt->fd, block_nr * spt->block_size, SEEK_SET);
bytes_read = read(spt->fd, buf, len);
}
@@ -189,7 +190,8 @@ static int tftp_send_oack(struct tftp_session *spt,
values[i]) + 1;
}
- m->m_len = sizeof(struct tftp_t) - 514 + n - sizeof(struct udphdr);
+ m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n
+ - sizeof(struct udphdr);
tftp_udp_output(spt, m, recv_tp);
return 0;
@@ -214,7 +216,7 @@ static void tftp_send_error(struct tftp_session *spt,
tp->x.tp_error.tp_error_code = htons(errorcode);
pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);
- m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg)
+ m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + strlen(msg)
- sizeof(struct udphdr);
tftp_udp_output(spt, m, recv_tp);
@@ -240,7 +242,8 @@ static void tftp_send_next_block(struct tftp_session *spt,
tp->tp_op = htons(TFTP_DATA);
tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff);
- nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512);
+ nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf,
+ spt->block_size);
if (nobytes < 0) {
m_free(m);
@@ -252,10 +255,11 @@ static void tftp_send_next_block(struct tftp_session *spt,
return;
}
- m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - sizeof(struct udphdr);
+ m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes)
+ - sizeof(struct udphdr);
tftp_udp_output(spt, m, recv_tp);
- if (nobytes == 512) {
+ if (nobytes == spt->block_size) {
tftp_session_update(spt);
}
else {
@@ -385,13 +389,11 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
} else if (strcasecmp(key, "blksize") == 0) {
int blksize = atoi(value);
- /* If blksize option is bigger than what we will
- * emit, accept the option with our packet size.
- * Otherwise, simply do as we didn't see the option.
- */
- if (blksize >= 512) {
+ /* Accept blksize up to our maximum size */
+ if (blksize > 0) {
+ spt->block_size = min(blksize, TFTP_BLOCKSIZE_MAX);
option_name[nb_options] = "blksize";
- option_value[nb_options] = 512;
+ option_value[nb_options] = spt->block_size;
nb_options++;
}
}
diff --git a/slirp/tftp.h b/slirp/tftp.h
index 2cd276d..9446dbc 100644
--- a/slirp/tftp.h
+++ b/slirp/tftp.h
@@ -15,6 +15,7 @@
#define TFTP_OACK 6
#define TFTP_FILENAME_MAX 512
+#define TFTP_BLOCKSIZE_MAX 1432
struct tftp_t {
struct udphdr udp;
@@ -22,13 +23,13 @@ struct tftp_t {
union {
struct {
uint16_t tp_block_nr;
- uint8_t tp_buf[512];
+ uint8_t tp_buf[TFTP_BLOCKSIZE_MAX];
} tp_data;
struct {
uint16_t tp_error_code;
- uint8_t tp_msg[512];
+ uint8_t tp_msg[TFTP_BLOCKSIZE_MAX];
} tp_error;
- char tp_buf[512 + 2];
+ char tp_buf[TFTP_BLOCKSIZE_MAX + 2];
} x;
} __attribute__((packed));
@@ -36,6 +37,7 @@ struct tftp_session {
Slirp *slirp;
char *filename;
int fd;
+ uint16_t block_size;
struct sockaddr_storage client_addr;
uint16_t client_port;
--
2.1.4
next reply other threads:[~2016-11-21 19:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-21 19:45 Hervé Poussineau [this message]
2016-11-21 19:49 ` [Qemu-devel] [PATCH] slirp: support dynamic block size for TFTP transfers no-reply
2016-11-21 19:51 ` H. Peter Anvin
2016-11-22 8:19 ` Thomas Huth
2016-12-20 23:03 ` Samuel Thibault
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1479757549-18672-1-git-send-email-hpoussin@reactos.org \
--to=hpoussin@reactos.org \
--cc=hpa@zytor.com \
--cc=jan.kiszka@siemens.com \
--cc=qemu-devel@nongnu.org \
--cc=samuel.thibault@ens-lyon.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).