cURL / Mailing Lists / curl-library / Single Mail

curl-library

libcurl tftp large file transfer rollover at 32MB problem

From: NCarolina 350 <ncarolina350_at_gmail.com>
Date: Fri, 31 Jul 2009 11:26:36 -0400

Hi,
I am using curl 7.19.5 on x86 to transfer a large file using tftp. The file
is larger than 32MB. The file is being transferred incorrectly. Here's the
output when I run curl with the verbose option:

* About to connect() to 10.13.1.4 port 69 (#0)
* Trying 10.13.1.4... connected
* Connected to 10.13.1.4 (10.13.1.4) port 69 (#0)
* set timeouts for state 0; Total 300, retry 6 maxtry 50
* got option=(tsize) value=(41041920)
* tsize parsed from OACK (41041920)
* got option=(blksize) value=(512)
* blksize parsed from OACK (512) requested (512)
  % Total % Received % Xferd Average Speed Time Time Time
Current
                                 Dload Upload Total Spent Left
Speed
  0 39.1M 0 0 0 0 0 0 --:--:-- --:--:-- --:--:--
0* Connected for receive
* set timeouts for state 1; Total 3600, retry 15 maxtry 24
 76 39.1M 76 29.8M 0 0 2421k 0 0:00:16 0:00:12 0:00:04
2453k* Received unexpected DATA packet block 0
 99 39.1M 99 39.1M 0 0 2425k 0 0:00:16 0:00:16 --:--:--
2425k* Closing connection #0

At 32MB, libcurl says "Received unexpected DATA packet block 0". When I add
more debug statements, I see the expected block number is 0x10000 at that
point. The block number is a 2-byte number so it rolls over. When curl first
sends the option packet, it asks for tsize and requests 512 as the block
size. What is confusing to me is curl still writes [correct_size - 512]
bytes to the file. I would expect it to stop at 32MB -- since it doesn't
know about the rolled over blocks. It doesn't look like the (non-standard)
rollover option is implemented so I don't know why curl misplaces one block
and writes the rest of them without a problem.

Either way, I think the following logic can be added to the library
(pseudo-code):

parse_oack ()
{
    if ((tsize / blksize) > blksize*0x10000) {
        blksize = get_suitable_blksize(tsize); /* figures out a nice
number that won't roll over */
        tftp_request_opt (blksize); /* sends the new
blksize opt to the server */
    }
}

Does this make sense? Is there a better solution? I can sen da patch for
review next week if this approach makes sense. Thanks!
kursad
Received on 2009-07-31