From mboxrd@z Thu Jan 1 00:00:00 1970 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 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 13 Sep 2012 07:55:00 +0200 Message-Id: <1347515701-5513-2-git-send-email-hpoussin@reactos.org> 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 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v3 1/2] slirp: Handle more than 65535 blocks in TFTP transfers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Jan Kiszka , =?UTF-8?q?Herv=C3=A9=20Poussineau?= RFC 1350 does not mention block count roll-over. However, a lot of TFTP s= ervers 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=C3=A9 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; } =20 -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 =3D 0; @@ -197,19 +197,14 @@ out: tftp_session_terminate(spt); } =20 -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; =20 - if (block_nr < 1) { - return -1; - } - m =3D m_get(spt->slirp); =20 if (!m) { @@ -223,7 +218,7 @@ static int tftp_send_data(struct tftp_session *spt, m->m_data +=3D sizeof(struct udpiphdr); =20 tp->tp_op =3D htons(TFTP_DATA); - tp->x.tp_data.tp_block_nr =3D htons(block_nr); + tp->x.tp_data.tp_block_nr =3D htons((spt->block_nr + 1) & 0xffff); =20 saddr.sin_addr =3D recv_tp->ip.ip_dst; saddr.sin_port =3D recv_tp->udp.uh_dport; @@ -231,7 +226,7 @@ static int tftp_send_data(struct tftp_session *spt, daddr.sin_addr =3D spt->client_ip; daddr.sin_port =3D spt->client_port; =20 - nobytes =3D tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 51= 2); + nobytes =3D tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 5= 12); =20 if (nobytes < 0) { m_free(m); @@ -255,6 +250,7 @@ static int tftp_send_data(struct tftp_session *spt, tftp_session_terminate(spt); } =20 + spt->block_nr++; return 0; } =20 @@ -373,7 +369,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp= _t *tp, int pktlen) } } =20 - tftp_send_data(spt, 1, tp); + spt->block_nr =3D 0; + tftp_send_next_block(spt, tp); } =20 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; } =20 - 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 { =20 struct in_addr client_ip; uint16_t client_port; + uint32_t block_nr; =20 int timestamp; }; --=20 1.7.10.4