~ubuntu-branches/ubuntu/saucy/curl/saucy-201307251546

« back to all changes in this revision

Viewing changes to lib/tftp.c

  • Committer: Bazaar Package Importer
  • Author(s): Ramakrishnan Muthukrishnan
  • Date: 2010-10-18 11:13:17 UTC
  • mto: (3.6.1 experimental) (1.3.1)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: james.westby@ubuntu.com-20101018111317-9rkas34ecwtq0upn
Tags: upstream-7.21.2
ImportĀ upstreamĀ versionĀ 7.21.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
169
169
static CURLcode tftp_disconnect(struct connectdata *conn);
170
170
static CURLcode tftp_do(struct connectdata *conn, bool *done);
171
171
static CURLcode tftp_done(struct connectdata *conn,
172
 
                               CURLcode, bool premature);
 
172
                          CURLcode, bool premature);
173
173
static CURLcode tftp_setup_connection(struct connectdata * conn);
174
174
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
175
175
static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
374
374
      }
375
375
      else if(blksize > TFTP_BLKSIZE_MAX) {
376
376
        failf(data, "%s (%d)", "blksize is larger than max supported",
377
 
                TFTP_BLKSIZE_MAX);
 
377
              TFTP_BLKSIZE_MAX);
378
378
        return CURLE_TFTP_ILLEGAL;
379
379
      }
380
380
      else if(blksize < TFTP_BLKSIZE_MIN) {
381
381
        failf(data, "%s (%d)", "blksize is smaller than min supported",
382
 
                TFTP_BLKSIZE_MIN);
 
382
              TFTP_BLKSIZE_MIN);
383
383
        return CURLE_TFTP_ILLEGAL;
384
384
      }
385
385
      else if (blksize > state->requested_blksize) {
387
387
         * support for the server requesting a bigger blksize than the client
388
388
         * requests */
389
389
        failf(data, "%s (%ld)",
390
 
                "server requested blksize larger than allocated", blksize);
 
390
              "server requested blksize larger than allocated", blksize);
391
391
        return CURLE_TFTP_ILLEGAL;
392
392
      }
393
393
 
394
394
      state->blksize = (int)blksize;
395
395
      infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
396
 
        state->blksize, "requested", state->requested_blksize);
 
396
            state->blksize, "requested", state->requested_blksize);
397
397
    }
398
398
    else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
399
399
      long tsize = 0;
716
716
  case TFTP_EVENT_ACK:
717
717
  case TFTP_EVENT_OACK:
718
718
    if (event == TFTP_EVENT_ACK) {
719
 
       /* Ack the packet */
720
 
       rblock = getrpacketblock(&state->rpacket);
721
 
 
722
 
       if(rblock != state->block) {
723
 
          /* This isn't the expected block.  Log it and up the retry counter */
724
 
          infof(data, "Received ACK for block %d, expecting %d\n",
725
 
                rblock, state->block);
726
 
          state->retries++;
727
 
          /* Bail out if over the maximum */
728
 
          if(state->retries>state->retry_max) {
729
 
             failf(data, "tftp_tx: giving up waiting for block %d ack",
730
 
                   state->block);
731
 
             res = CURLE_SEND_ERROR;
732
 
          }
733
 
          else {
734
 
             /* Re-send the data packet */
735
 
             sbytes = sendto(state->sockfd, (void *)&state->spacket,
736
 
                             4+state->sbytes, SEND_4TH_ARG,
737
 
                             (struct sockaddr *)&state->remote_addr,
738
 
                             state->remote_addrlen);
739
 
             /* Check all sbytes were sent */
740
 
             if(sbytes<0) {
741
 
                failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
742
 
                res = CURLE_SEND_ERROR;
743
 
             }
744
 
          }
745
 
          return res;
746
 
       }
747
 
       /* This is the expected packet.  Reset the counters and send the next
748
 
          block */
749
 
       time(&state->rx_time);
750
 
       state->block++;
751
 
    }
752
 
    else {
753
 
       state->block = 1; /* first data block is 1 when using OACK */
754
 
    }
 
719
      /* Ack the packet */
 
720
      rblock = getrpacketblock(&state->rpacket);
 
721
 
 
722
      if(rblock != state->block &&
 
723
         /* There's a bug in tftpd-hpa that causes it to send us an ack for
 
724
          * 65535 when the block number wraps to 0. So when we're expecting
 
725
          * 0, also accept 65535. See
 
726
          * http://syslinux.zytor.com/archives/2010-September/015253.html
 
727
          * */
 
728
         !(state->block == 0 && rblock == 65535)) {
 
729
        /* This isn't the expected block.  Log it and up the retry counter */
 
730
        infof(data, "Received ACK for block %d, expecting %d\n",
 
731
              rblock, state->block);
 
732
        state->retries++;
 
733
        /* Bail out if over the maximum */
 
734
        if(state->retries>state->retry_max) {
 
735
          failf(data, "tftp_tx: giving up waiting for block %d ack",
 
736
                state->block);
 
737
          res = CURLE_SEND_ERROR;
 
738
        }
 
739
        else {
 
740
          /* Re-send the data packet */
 
741
          sbytes = sendto(state->sockfd, (void *)&state->spacket,
 
742
                          4+state->sbytes, SEND_4TH_ARG,
 
743
                          (struct sockaddr *)&state->remote_addr,
 
744
                          state->remote_addrlen);
 
745
          /* Check all sbytes were sent */
 
746
          if(sbytes<0) {
 
747
            failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
 
748
            res = CURLE_SEND_ERROR;
 
749
          }
 
750
        }
 
751
        return res;
 
752
      }
 
753
      /* This is the expected packet.  Reset the counters and send the next
 
754
         block */
 
755
      time(&state->rx_time);
 
756
      state->block++;
 
757
    }
 
758
    else
 
759
      state->block = 1; /* first data block is 1 when using OACK */
 
760
 
755
761
    state->retries = 0;
756
762
    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
757
763
    setpacketblock(&state->spacket, state->block);
1032
1038
 *
1033
1039
 **********************************************************/
1034
1040
static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
1035
 
                               bool premature)
 
1041
                          bool premature)
1036
1042
{
1037
1043
  CURLcode code = CURLE_OK;
1038
1044
  tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1056
1062
 *
1057
1063
 **********************************************************/
1058
1064
static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
1059
 
                       int numsocks)
 
1065
                        int numsocks)
1060
1066
{
1061
1067
  if(!numsocks)
1062
1068
    return GETSOCK_BLANK;
1085
1091
  /* Receive the packet */
1086
1092
  fromlen = sizeof(fromaddr);
1087
1093
  state->rbytes = (int)recvfrom(state->sockfd,
1088
 
                                   (void *)state->rpacket.data,
1089
 
                                   state->blksize+4,
1090
 
                                   0,
1091
 
                                   (struct sockaddr *)&fromaddr,
1092
 
                                   &fromlen);
 
1094
                                (void *)state->rpacket.data,
 
1095
                                state->blksize+4,
 
1096
                                0,
 
1097
                                (struct sockaddr *)&fromaddr,
 
1098
                                &fromlen);
1093
1099
  if(state->remote_addrlen==0) {
1094
1100
    memcpy(&state->remote_addr, &fromaddr, fromlen);
1095
1101
    state->remote_addrlen = fromlen;
1129
1135
      break;
1130
1136
    case TFTP_EVENT_OACK:
1131
1137
      result = tftp_parse_option_ack(state,
1132
 
                                   (const char *)state->rpacket.data+2,
1133
 
                                   state->rbytes-2);
 
1138
                                     (const char *)state->rpacket.data+2,
 
1139
                                     state->rbytes-2);
1134
1140
      if(result)
1135
1141
        return result;
1136
1142
      break;
1182
1188
  /* there's a typecast below here since 'time_t' may in fact be larger than
1183
1189
     'long', but we estimate that a 'long' will still be able to hold number
1184
1190
     of seconds even if "only" 32 bit */
1185
 
  return (long) state->max_time-current;
 
1191
  return (long)(state->max_time - current);
1186
1192
}
1187
1193
 
1188
1194
 
1252
1258
 
1253
1259
    /* Force a progress callback if it's been too long */
1254
1260
    if (Curl_tvdiff(k->now, k->start) >= data->set.timeout) {
1255
 
       if(Curl_pgrsUpdate(conn)) {
1256
 
          tftp_state_machine(state, TFTP_EVENT_ERROR);
1257
 
          return CURLE_ABORTED_BY_CALLBACK;
1258
 
       }
1259
 
       k->start = k->now;
 
1261
      if(Curl_pgrsUpdate(conn)) {
 
1262
        tftp_state_machine(state, TFTP_EVENT_ERROR);
 
1263
        return CURLE_ABORTED_BY_CALLBACK;
 
1264
      }
 
1265
      k->start = k->now;
1260
1266
    }
1261
1267
 
1262
1268
    if(rc == -1) {
1283
1289
      else {
1284
1290
        result = tftp_receive_packet(conn);
1285
1291
        if (result == CURLE_OK)
1286
 
           transaction_start = Curl_tvnow();
 
1292
          transaction_start = Curl_tvnow();
1287
1293
 
1288
1294
        if(k->bytecountp)
1289
1295
          *k->bytecountp = k->bytecount; /* read count */
1455
1461
 
1456
1462
  /* If tftp_perform() returned an error, use that for return code. If it
1457
1463
     was OK, see if tftp_translate_code() has an error. */
1458
 
  if (code == CURLE_OK) 
 
1464
  if (code == CURLE_OK)
1459
1465
    /* If we have encountered an internal tftp error, translate it. */
1460
1466
    code = tftp_translate_code(state->error);
1461
1467