From patchwork Thu Sep 13 05:55:00 2012 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: 183499 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0ECF12C0095 for ; Thu, 13 Sep 2012 15:55:06 +1000 (EST) Received: from localhost ([::1]:53238 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC2OG-0001VW-7T for incoming@patchwork.ozlabs.org; Thu, 13 Sep 2012 01:55:04 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52418) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC2Nj-0008Q0-6z for qemu-devel@nongnu.org; Thu, 13 Sep 2012 01:54:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TC2Nh-00042U-Fl for qemu-devel@nongnu.org; Thu, 13 Sep 2012 01:54:31 -0400 Received: from smtp1-g21.free.fr ([212.27.42.1]:43554) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC2Ng-000415-UK for qemu-devel@nongnu.org; Thu, 13 Sep 2012 01:54:29 -0400 Received: from localhost.localdomain (unknown [82.227.227.196]) by smtp1-g21.free.fr (Postfix) with ESMTP id 0A4E09400FD; Thu, 13 Sep 2012 07:54:16 +0200 (CEST) From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= To: qemu-devel@nongnu.org Date: Thu, 13 Sep 2012 07:55:00 +0200 Message-Id: <1347515701-5513-2-git-send-email-hpoussin@reactos.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1347515701-5513-1-git-send-email-hpoussin@reactos.org> References: <1347515701-5513-1-git-send-email-hpoussin@reactos.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 212.27.42.1 Cc: Jan Kiszka , =?UTF-8?q?Herv=C3=A9=20Poussineau?= Subject: [Qemu-devel] [PATCH v3 1/2] slirp: Handle more than 65535 blocks in TFTP transfers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org RFC 1350 does not mention block count roll-over. However, a lot of TFTP servers implement it to be able to transmit big files, so do it also. Current block size is 512 bytes, so TFTP files were limited to 32 MB. Signed-off-by: Hervé Poussineau --- slirp/tftp.c | 24 ++++++++++-------------- slirp/tftp.h | 1 + 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/slirp/tftp.c b/slirp/tftp.c index 520dbd6..c6a5df2 100644 --- a/slirp/tftp.c +++ b/slirp/tftp.c @@ -97,7 +97,7 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t *tp) return -1; } -static int tftp_read_data(struct tftp_session *spt, uint16_t block_nr, +static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr, uint8_t *buf, int len) { int bytes_read = 0; @@ -197,19 +197,14 @@ out: tftp_session_terminate(spt); } -static int tftp_send_data(struct tftp_session *spt, - uint16_t block_nr, - struct tftp_t *recv_tp) +static int tftp_send_next_block(struct tftp_session *spt, + struct tftp_t *recv_tp) { struct sockaddr_in saddr, daddr; struct mbuf *m; struct tftp_t *tp; int nobytes; - if (block_nr < 1) { - return -1; - } - m = m_get(spt->slirp); if (!m) { @@ -223,7 +218,7 @@ static int tftp_send_data(struct tftp_session *spt, m->m_data += sizeof(struct udpiphdr); tp->tp_op = htons(TFTP_DATA); - tp->x.tp_data.tp_block_nr = htons(block_nr); + tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff); saddr.sin_addr = recv_tp->ip.ip_dst; saddr.sin_port = recv_tp->udp.uh_dport; @@ -231,7 +226,7 @@ static int tftp_send_data(struct tftp_session *spt, daddr.sin_addr = spt->client_ip; daddr.sin_port = spt->client_port; - nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512); + nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512); if (nobytes < 0) { m_free(m); @@ -255,6 +250,7 @@ static int tftp_send_data(struct tftp_session *spt, tftp_session_terminate(spt); } + spt->block_nr++; return 0; } @@ -373,7 +369,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) } } - tftp_send_data(spt, 1, tp); + spt->block_nr = 0; + tftp_send_next_block(spt, tp); } static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen) @@ -386,9 +383,8 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen) return; } - if (tftp_send_data(&slirp->tftp_sessions[s], - ntohs(tp->x.tp_data.tp_block_nr) + 1, - tp) < 0) { + if (tftp_send_next_block(&slirp->tftp_sessions[s], + tp) < 0) { return; } } diff --git a/slirp/tftp.h b/slirp/tftp.h index 9c364ea..51704e4 100644 --- a/slirp/tftp.h +++ b/slirp/tftp.h @@ -37,6 +37,7 @@ struct tftp_session { struct in_addr client_ip; uint16_t client_port; + uint32_t block_nr; int timestamp; };