From patchwork Mon Nov 21 19:45:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Herv=C3=A9_Poussineau?= X-Patchwork-Id: 9439975 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1F5A860469 for ; Mon, 21 Nov 2016 19:46:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 149252875A for ; Mon, 21 Nov 2016 19:46:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0871C287A4; Mon, 21 Nov 2016 19:46:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 037712875A for ; Mon, 21 Nov 2016 19:46:26 +0000 (UTC) Received: from localhost ([::1]:51461 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c8uXp-0005KU-Ay for patchwork-qemu-devel@patchwork.kernel.org; Mon, 21 Nov 2016 14:46:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40535) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c8uXW-0005Ja-Gp for qemu-devel@nongnu.org; Mon, 21 Nov 2016 14:46:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c8uXT-0003sE-UL for qemu-devel@nongnu.org; Mon, 21 Nov 2016 14:46:06 -0500 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]:38035) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c8uXT-0003r6-I4 for qemu-devel@nongnu.org; Mon, 21 Nov 2016 14:46:03 -0500 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp2-g21.free.fr (Postfix) with ESMTP id 7047E2003FF; Mon, 21 Nov 2016 20:45:56 +0100 (CET) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Mon, 21 Nov 2016 20:45:49 +0100 Message-Id: <1479757549-18672-1-git-send-email-hpoussin@reactos.org> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 2a01:e0c:1:1599::11 Subject: [Qemu-devel] [PATCH] slirp: support dynamic block size for TFTP transfers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Thibault , Jan Kiszka , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , Stefan Hajnoczi , hpa@zytor.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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;