cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curl-tracker mailing list Archives

[ curl-Bugs-2723236 ] TFTP file transfer issue in Curl 7.19.4

From: SourceForge.net <noreply_at_sourceforge.net>
Date: Tue, 31 Mar 2009 12:24:46 +0000

Bugs item #2723236, was opened at 2009-03-31 14:20
Message generated for change (Comment added) made by bagder
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=2723236&group_id=976

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: TFTP
Group: wrong behaviour
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Vijay G (vijayg23333)
Assigned to: Daniel Stenberg (bagder)
Summary: TFTP file transfer issue in Curl 7.19.4

Initial Comment:
In Curl lib 7.19.4, tftp_tx() is not handling the case for TFTP_EVENT_OACK. This case should be added in tftp_tx(). In tftp_rx(), this case is already handled.
In RFC 2348,it is given as "If the server is willing to accept the blocksize option, it sends an Option Acknowledgment (OACK) to the client."
I was not able to upload files, as we are not handling this scenario.

----------------------------------------------------------------------

>Comment By: Daniel Stenberg (bagder)
Date: 2009-03-31 14:24

Message:
Please make the patch with 'diff -u' and post that here instead of a full
code snippet.

----------------------------------------------------------------------

Comment By: Vijay G (vijayg23333)
Date: 2009-03-31 14:24

Message:
Ignore the line #ifndef CURL_DISABLE_PROGRESS.

I have added the case statement for TFTP_EVENT_OACK to fix the issue.

----------------------------------------------------------------------

Comment By: Vijay G (vijayg23333)
Date: 2009-03-31 14:22

Message:
The patch for this issue is

/**********************************************************
 *
 * tftp_tx
 *
 * Event handler for the TX state
 *
 **********************************************************/
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
{
  struct SessionHandle *data = state->conn->data;
  int sbytes;
  int rblock;
  CURLcode res = CURLE_OK;
  struct SingleRequest *k = &data->req;

  switch(event) {

  case TFTP_EVENT_ACK:
    /* Ack the packet */
    rblock = getrpacketblock(&state->rpacket);

    if(rblock != state->block) {
      /* This isn't the expected block. Log it and up the retry counter
*/
      infof(data, "Received ACK for block %d, expecting %d\n",
            rblock, state->block);
      state->retries++;
      /* Bail out if over the maximum */
      if(state->retries>state->retry_max) {
        failf(data, "tftp_tx: giving up waiting for block %d ack",
              state->block);
        res = CURLE_SEND_ERROR;
      }
      else {
        /* Re-send the data packet */
        sbytes = sendto(state->sockfd, (void *)&state->spacket,
                        4+state->sbytes, SEND_4TH_ARG,
                        (struct sockaddr *)&state->remote_addr,
                        state->remote_addrlen);
        /* Check all sbytes were sent */
        if(sbytes<0) {
          failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
          res = CURLE_SEND_ERROR;
        }
      }
      return res;
    }
    /* This is the expected packet. Reset the counters and send the next
       block */
    state->block++;
    state->retries = 0;
    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
    setpacketblock(&state->spacket, state->block);
    if(state->block > 1 && state->sbytes < state->blksize) {
      state->state = TFTP_STATE_FIN;
      return CURLE_OK;
    }
    res = Curl_fillreadbuffer(state->conn, state->blksize,
                              (int *)&state->sbytes);
    if(res)
      return res;
    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
                    4+state->sbytes, SEND_4TH_ARG,
                    (struct sockaddr *)&state->remote_addr,
                    state->remote_addrlen);
    /* Check all sbytes were sent */
    if(sbytes<0) {
      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
      return CURLE_SEND_ERROR;
    }
    /* Update the progress meter */
    k->writebytecount += state->sbytes;
    Curl_pgrsSetUploadCounter(data, k->writebytecount);
    break;
case TFTP_EVENT_OACK:
 /* This is the expected packet. Reset the counters and send the next
       block */
    state->block++;
    state->retries = 0;
    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
    setpacketblock(&state->spacket, state->block);
    if(state->block > 1 && state->sbytes < state->blksize) {
      state->state = TFTP_STATE_FIN;
      return CURLE_OK;
    }
    res = Curl_fillreadbuffer(state->conn, state->blksize,
                              (int *)&state->sbytes);
    if(res)
      return res;
    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
                    4+state->sbytes, SEND_4TH_ARG,
                    (struct sockaddr *)&state->remote_addr,
                    state->remote_addrlen);
    /* Check all sbytes were sent */
    if(sbytes<0) {
      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
      return CURLE_SEND_ERROR;
    }
    /* Update the progress meter */
    k->writebytecount += state->sbytes;
#ifndef CURL_DISABLE_PROGRESS
    Curl_pgrsSetUploadCounter(data, k->writebytecount);
#endif
   
break;

  case TFTP_EVENT_TIMEOUT:
    /* Increment the retry counter and log the timeout */
    state->retries++;
    infof(data, "Timeout waiting for block %d ACK. "
          " Retries = %d\n", state->retries);
    /* Decide if we've had enough */
    if(state->retries > state->retry_max) {
      state->error = TFTP_ERR_TIMEOUT;
      state->state = TFTP_STATE_FIN;
    }
    else {
      /* Re-send the data packet */
      sbytes = sendto(state->sockfd, (void *)state->spacket.data,
                      4+state->sbytes, SEND_4TH_ARG,
                      (struct sockaddr *)&state->remote_addr,
                      state->remote_addrlen);
      /* Check all sbytes were sent */
      if(sbytes<0) {
        failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
        return CURLE_SEND_ERROR;
      }
      /* since this was a re-send, we remain at the still byte position */
      Curl_pgrsSetUploadCounter(data, k->writebytecount);
    }
    break;

  case TFTP_EVENT_ERROR:
    state->state = TFTP_STATE_FIN;
    break;

  default:
    failf(data, "%s", "tftp_tx: internal error");
    break;
  }

  return res;
}

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=2723236&group_id=976
Received on 2009-03-31

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET