tftp.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2021, Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. ***************************************************************************/
  22. #include "curl_setup.h"
  23. #ifndef CURL_DISABLE_TFTP
  24. #ifdef HAVE_NETINET_IN_H
  25. #include <netinet/in.h>
  26. #endif
  27. #ifdef HAVE_NETDB_H
  28. #include <netdb.h>
  29. #endif
  30. #ifdef HAVE_ARPA_INET_H
  31. #include <arpa/inet.h>
  32. #endif
  33. #ifdef HAVE_NET_IF_H
  34. #include <net/if.h>
  35. #endif
  36. #ifdef HAVE_SYS_IOCTL_H
  37. #include <sys/ioctl.h>
  38. #endif
  39. #ifdef HAVE_SYS_PARAM_H
  40. #include <sys/param.h>
  41. #endif
  42. #include "urldata.h"
  43. #include <curl/curl.h>
  44. #include "transfer.h"
  45. #include "sendf.h"
  46. #include "tftp.h"
  47. #include "progress.h"
  48. #include "connect.h"
  49. #include "strerror.h"
  50. #include "sockaddr.h" /* required for Curl_sockaddr_storage */
  51. #include "multiif.h"
  52. #include "url.h"
  53. #include "strcase.h"
  54. #include "speedcheck.h"
  55. #include "select.h"
  56. #include "escape.h"
  57. /* The last 3 #include files should be in this order */
  58. #include "curl_printf.h"
  59. #include "curl_memory.h"
  60. #include "memdebug.h"
  61. /* RFC2348 allows the block size to be negotiated */
  62. #define TFTP_BLKSIZE_DEFAULT 512
  63. #define TFTP_BLKSIZE_MIN 8
  64. #define TFTP_BLKSIZE_MAX 65464
  65. #define TFTP_OPTION_BLKSIZE "blksize"
  66. /* from RFC2349: */
  67. #define TFTP_OPTION_TSIZE "tsize"
  68. #define TFTP_OPTION_INTERVAL "timeout"
  69. typedef enum {
  70. TFTP_MODE_NETASCII = 0,
  71. TFTP_MODE_OCTET
  72. } tftp_mode_t;
  73. typedef enum {
  74. TFTP_STATE_START = 0,
  75. TFTP_STATE_RX,
  76. TFTP_STATE_TX,
  77. TFTP_STATE_FIN
  78. } tftp_state_t;
  79. typedef enum {
  80. TFTP_EVENT_NONE = -1,
  81. TFTP_EVENT_INIT = 0,
  82. TFTP_EVENT_RRQ = 1,
  83. TFTP_EVENT_WRQ = 2,
  84. TFTP_EVENT_DATA = 3,
  85. TFTP_EVENT_ACK = 4,
  86. TFTP_EVENT_ERROR = 5,
  87. TFTP_EVENT_OACK = 6,
  88. TFTP_EVENT_TIMEOUT
  89. } tftp_event_t;
  90. typedef enum {
  91. TFTP_ERR_UNDEF = 0,
  92. TFTP_ERR_NOTFOUND,
  93. TFTP_ERR_PERM,
  94. TFTP_ERR_DISKFULL,
  95. TFTP_ERR_ILLEGAL,
  96. TFTP_ERR_UNKNOWNID,
  97. TFTP_ERR_EXISTS,
  98. TFTP_ERR_NOSUCHUSER, /* This will never be triggered by this code */
  99. /* The remaining error codes are internal to curl */
  100. TFTP_ERR_NONE = -100,
  101. TFTP_ERR_TIMEOUT,
  102. TFTP_ERR_NORESPONSE
  103. } tftp_error_t;
  104. struct tftp_packet {
  105. unsigned char *data;
  106. };
  107. struct tftp_state_data {
  108. tftp_state_t state;
  109. tftp_mode_t mode;
  110. tftp_error_t error;
  111. tftp_event_t event;
  112. struct Curl_easy *data;
  113. curl_socket_t sockfd;
  114. int retries;
  115. int retry_time;
  116. int retry_max;
  117. time_t start_time;
  118. time_t max_time;
  119. time_t rx_time;
  120. struct Curl_sockaddr_storage local_addr;
  121. struct Curl_sockaddr_storage remote_addr;
  122. curl_socklen_t remote_addrlen;
  123. int rbytes;
  124. int sbytes;
  125. int blksize;
  126. int requested_blksize;
  127. unsigned short block;
  128. struct tftp_packet rpacket;
  129. struct tftp_packet spacket;
  130. };
  131. /* Forward declarations */
  132. static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
  133. static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
  134. static CURLcode tftp_connect(struct Curl_easy *data, bool *done);
  135. static CURLcode tftp_disconnect(struct Curl_easy *data,
  136. struct connectdata *conn,
  137. bool dead_connection);
  138. static CURLcode tftp_do(struct Curl_easy *data, bool *done);
  139. static CURLcode tftp_done(struct Curl_easy *data,
  140. CURLcode, bool premature);
  141. static CURLcode tftp_setup_connection(struct Curl_easy *data,
  142. struct connectdata *conn);
  143. static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done);
  144. static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done);
  145. static int tftp_getsock(struct Curl_easy *data, struct connectdata *conn,
  146. curl_socket_t *socks);
  147. static CURLcode tftp_translate_code(tftp_error_t error);
  148. /*
  149. * TFTP protocol handler.
  150. */
  151. const struct Curl_handler Curl_handler_tftp = {
  152. "TFTP", /* scheme */
  153. tftp_setup_connection, /* setup_connection */
  154. tftp_do, /* do_it */
  155. tftp_done, /* done */
  156. ZERO_NULL, /* do_more */
  157. tftp_connect, /* connect_it */
  158. tftp_multi_statemach, /* connecting */
  159. tftp_doing, /* doing */
  160. tftp_getsock, /* proto_getsock */
  161. tftp_getsock, /* doing_getsock */
  162. ZERO_NULL, /* domore_getsock */
  163. ZERO_NULL, /* perform_getsock */
  164. tftp_disconnect, /* disconnect */
  165. ZERO_NULL, /* readwrite */
  166. ZERO_NULL, /* connection_check */
  167. PORT_TFTP, /* defport */
  168. CURLPROTO_TFTP, /* protocol */
  169. CURLPROTO_TFTP, /* family */
  170. PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
  171. };
  172. /**********************************************************
  173. *
  174. * tftp_set_timeouts -
  175. *
  176. * Set timeouts based on state machine state.
  177. * Use user provided connect timeouts until DATA or ACK
  178. * packet is received, then use user-provided transfer timeouts
  179. *
  180. *
  181. **********************************************************/
  182. static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
  183. {
  184. time_t maxtime, timeout;
  185. timediff_t timeout_ms;
  186. bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
  187. time(&state->start_time);
  188. /* Compute drop-dead time */
  189. timeout_ms = Curl_timeleft(state->data, NULL, start);
  190. if(timeout_ms < 0) {
  191. /* time-out, bail out, go home */
  192. failf(state->data, "Connection time-out");
  193. return CURLE_OPERATION_TIMEDOUT;
  194. }
  195. if(start) {
  196. maxtime = (time_t)(timeout_ms + 500) / 1000;
  197. state->max_time = state->start_time + maxtime;
  198. /* Set per-block timeout to total */
  199. timeout = maxtime;
  200. /* Average restart after 5 seconds */
  201. state->retry_max = (int)timeout/5;
  202. if(state->retry_max < 1)
  203. /* avoid division by zero below */
  204. state->retry_max = 1;
  205. /* Compute the re-start interval to suit the timeout */
  206. state->retry_time = (int)timeout/state->retry_max;
  207. if(state->retry_time<1)
  208. state->retry_time = 1;
  209. }
  210. else {
  211. if(timeout_ms > 0)
  212. maxtime = (time_t)(timeout_ms + 500) / 1000;
  213. else
  214. maxtime = 3600;
  215. state->max_time = state->start_time + maxtime;
  216. /* Set per-block timeout to total */
  217. timeout = maxtime;
  218. /* Average reposting an ACK after 5 seconds */
  219. state->retry_max = (int)timeout/5;
  220. }
  221. /* But bound the total number */
  222. if(state->retry_max<3)
  223. state->retry_max = 3;
  224. if(state->retry_max>50)
  225. state->retry_max = 50;
  226. /* Compute the re-ACK interval to suit the timeout */
  227. state->retry_time = (int)(timeout/state->retry_max);
  228. if(state->retry_time<1)
  229. state->retry_time = 1;
  230. infof(state->data,
  231. "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
  232. (int)state->state, (long)(state->max_time-state->start_time),
  233. state->retry_time, state->retry_max);
  234. /* init RX time */
  235. time(&state->rx_time);
  236. return CURLE_OK;
  237. }
  238. /**********************************************************
  239. *
  240. * tftp_set_send_first
  241. *
  242. * Event handler for the START state
  243. *
  244. **********************************************************/
  245. static void setpacketevent(struct tftp_packet *packet, unsigned short num)
  246. {
  247. packet->data[0] = (unsigned char)(num >> 8);
  248. packet->data[1] = (unsigned char)(num & 0xff);
  249. }
  250. static void setpacketblock(struct tftp_packet *packet, unsigned short num)
  251. {
  252. packet->data[2] = (unsigned char)(num >> 8);
  253. packet->data[3] = (unsigned char)(num & 0xff);
  254. }
  255. static unsigned short getrpacketevent(const struct tftp_packet *packet)
  256. {
  257. return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
  258. }
  259. static unsigned short getrpacketblock(const struct tftp_packet *packet)
  260. {
  261. return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
  262. }
  263. static size_t tftp_strnlen(const char *string, size_t maxlen)
  264. {
  265. const char *end = memchr(string, '\0', maxlen);
  266. return end ? (size_t) (end - string) : maxlen;
  267. }
  268. static const char *tftp_option_get(const char *buf, size_t len,
  269. const char **option, const char **value)
  270. {
  271. size_t loc;
  272. loc = tftp_strnlen(buf, len);
  273. loc++; /* NULL term */
  274. if(loc >= len)
  275. return NULL;
  276. *option = buf;
  277. loc += tftp_strnlen(buf + loc, len-loc);
  278. loc++; /* NULL term */
  279. if(loc > len)
  280. return NULL;
  281. *value = &buf[strlen(*option) + 1];
  282. return &buf[loc];
  283. }
  284. static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
  285. const char *ptr, int len)
  286. {
  287. const char *tmp = ptr;
  288. struct Curl_easy *data = state->data;
  289. /* if OACK doesn't contain blksize option, the default (512) must be used */
  290. state->blksize = TFTP_BLKSIZE_DEFAULT;
  291. while(tmp < ptr + len) {
  292. const char *option, *value;
  293. tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
  294. if(tmp == NULL) {
  295. failf(data, "Malformed ACK packet, rejecting");
  296. return CURLE_TFTP_ILLEGAL;
  297. }
  298. infof(data, "got option=(%s) value=(%s)\n", option, value);
  299. if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
  300. long blksize;
  301. blksize = strtol(value, NULL, 10);
  302. if(!blksize) {
  303. failf(data, "invalid blocksize value in OACK packet");
  304. return CURLE_TFTP_ILLEGAL;
  305. }
  306. if(blksize > TFTP_BLKSIZE_MAX) {
  307. failf(data, "%s (%d)", "blksize is larger than max supported",
  308. TFTP_BLKSIZE_MAX);
  309. return CURLE_TFTP_ILLEGAL;
  310. }
  311. else if(blksize < TFTP_BLKSIZE_MIN) {
  312. failf(data, "%s (%d)", "blksize is smaller than min supported",
  313. TFTP_BLKSIZE_MIN);
  314. return CURLE_TFTP_ILLEGAL;
  315. }
  316. else if(blksize > state->requested_blksize) {
  317. /* could realloc pkt buffers here, but the spec doesn't call out
  318. * support for the server requesting a bigger blksize than the client
  319. * requests */
  320. failf(data, "%s (%ld)",
  321. "server requested blksize larger than allocated", blksize);
  322. return CURLE_TFTP_ILLEGAL;
  323. }
  324. state->blksize = (int)blksize;
  325. infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
  326. state->blksize, "requested", state->requested_blksize);
  327. }
  328. else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
  329. long tsize = 0;
  330. tsize = strtol(value, NULL, 10);
  331. infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize);
  332. /* tsize should be ignored on upload: Who cares about the size of the
  333. remote file? */
  334. if(!data->set.upload) {
  335. if(!tsize) {
  336. failf(data, "invalid tsize -:%s:- value in OACK packet", value);
  337. return CURLE_TFTP_ILLEGAL;
  338. }
  339. Curl_pgrsSetDownloadSize(data, tsize);
  340. }
  341. }
  342. }
  343. return CURLE_OK;
  344. }
  345. static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize,
  346. char *buf, const char *option)
  347. {
  348. if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
  349. return CURLE_TFTP_ILLEGAL;
  350. strcpy(buf, option);
  351. *csize += strlen(option) + 1;
  352. return CURLE_OK;
  353. }
  354. static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
  355. tftp_event_t event)
  356. {
  357. CURLcode result;
  358. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  359. struct Curl_easy *data = state->data;
  360. infof(data, "%s\n", "Connected for transmit");
  361. #endif
  362. state->state = TFTP_STATE_TX;
  363. result = tftp_set_timeouts(state);
  364. if(result)
  365. return result;
  366. return tftp_tx(state, event);
  367. }
  368. static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
  369. tftp_event_t event)
  370. {
  371. CURLcode result;
  372. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  373. struct Curl_easy *data = state->data;
  374. infof(data, "%s\n", "Connected for receive");
  375. #endif
  376. state->state = TFTP_STATE_RX;
  377. result = tftp_set_timeouts(state);
  378. if(result)
  379. return result;
  380. return tftp_rx(state, event);
  381. }
  382. static CURLcode tftp_send_first(struct tftp_state_data *state,
  383. tftp_event_t event)
  384. {
  385. size_t sbytes;
  386. ssize_t senddata;
  387. const char *mode = "octet";
  388. char *filename;
  389. struct Curl_easy *data = state->data;
  390. CURLcode result = CURLE_OK;
  391. /* Set ascii mode if -B flag was used */
  392. if(data->set.prefer_ascii)
  393. mode = "netascii";
  394. switch(event) {
  395. case TFTP_EVENT_INIT: /* Send the first packet out */
  396. case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
  397. /* Increment the retry counter, quit if over the limit */
  398. state->retries++;
  399. if(state->retries>state->retry_max) {
  400. state->error = TFTP_ERR_NORESPONSE;
  401. state->state = TFTP_STATE_FIN;
  402. return result;
  403. }
  404. if(data->set.upload) {
  405. /* If we are uploading, send an WRQ */
  406. setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
  407. state->data->req.upload_fromhere =
  408. (char *)state->spacket.data + 4;
  409. if(data->state.infilesize != -1)
  410. Curl_pgrsSetUploadSize(data, data->state.infilesize);
  411. }
  412. else {
  413. /* If we are downloading, send an RRQ */
  414. setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
  415. }
  416. /* As RFC3617 describes the separator slash is not actually part of the
  417. file name so we skip the always-present first letter of the path
  418. string. */
  419. result = Curl_urldecode(data, &state->data->state.up.path[1], 0,
  420. &filename, NULL, REJECT_ZERO);
  421. if(result)
  422. return result;
  423. if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
  424. failf(data, "TFTP file name too long");
  425. free(filename);
  426. return CURLE_TFTP_ILLEGAL; /* too long file name field */
  427. }
  428. msnprintf((char *)state->spacket.data + 2,
  429. state->blksize,
  430. "%s%c%s%c", filename, '\0', mode, '\0');
  431. sbytes = 4 + strlen(filename) + strlen(mode);
  432. /* optional addition of TFTP options */
  433. if(!data->set.tftp_no_options) {
  434. char buf[64];
  435. /* add tsize option */
  436. if(data->set.upload && (data->state.infilesize != -1))
  437. msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
  438. data->state.infilesize);
  439. else
  440. strcpy(buf, "0"); /* the destination is large enough */
  441. result = tftp_option_add(state, &sbytes,
  442. (char *)state->spacket.data + sbytes,
  443. TFTP_OPTION_TSIZE);
  444. if(result == CURLE_OK)
  445. result = tftp_option_add(state, &sbytes,
  446. (char *)state->spacket.data + sbytes, buf);
  447. /* add blksize option */
  448. msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
  449. if(result == CURLE_OK)
  450. result = tftp_option_add(state, &sbytes,
  451. (char *)state->spacket.data + sbytes,
  452. TFTP_OPTION_BLKSIZE);
  453. if(result == CURLE_OK)
  454. result = tftp_option_add(state, &sbytes,
  455. (char *)state->spacket.data + sbytes, buf);
  456. /* add timeout option */
  457. msnprintf(buf, sizeof(buf), "%d", state->retry_time);
  458. if(result == CURLE_OK)
  459. result = tftp_option_add(state, &sbytes,
  460. (char *)state->spacket.data + sbytes,
  461. TFTP_OPTION_INTERVAL);
  462. if(result == CURLE_OK)
  463. result = tftp_option_add(state, &sbytes,
  464. (char *)state->spacket.data + sbytes, buf);
  465. if(result != CURLE_OK) {
  466. failf(data, "TFTP buffer too small for options");
  467. free(filename);
  468. return CURLE_TFTP_ILLEGAL;
  469. }
  470. }
  471. /* the typecase for the 3rd argument is mostly for systems that do
  472. not have a size_t argument, like older unixes that want an 'int' */
  473. senddata = sendto(state->sockfd, (void *)state->spacket.data,
  474. (SEND_TYPE_ARG3)sbytes, 0,
  475. data->conn->ip_addr->ai_addr,
  476. data->conn->ip_addr->ai_addrlen);
  477. if(senddata != (ssize_t)sbytes) {
  478. char buffer[STRERROR_LEN];
  479. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  480. }
  481. free(filename);
  482. break;
  483. case TFTP_EVENT_OACK:
  484. if(data->set.upload) {
  485. result = tftp_connect_for_tx(state, event);
  486. }
  487. else {
  488. result = tftp_connect_for_rx(state, event);
  489. }
  490. break;
  491. case TFTP_EVENT_ACK: /* Connected for transmit */
  492. result = tftp_connect_for_tx(state, event);
  493. break;
  494. case TFTP_EVENT_DATA: /* Connected for receive */
  495. result = tftp_connect_for_rx(state, event);
  496. break;
  497. case TFTP_EVENT_ERROR:
  498. state->state = TFTP_STATE_FIN;
  499. break;
  500. default:
  501. failf(state->data, "tftp_send_first: internal error");
  502. break;
  503. }
  504. return result;
  505. }
  506. /* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit
  507. boundary */
  508. #define NEXT_BLOCKNUM(x) (((x) + 1)&0xffff)
  509. /**********************************************************
  510. *
  511. * tftp_rx
  512. *
  513. * Event handler for the RX state
  514. *
  515. **********************************************************/
  516. static CURLcode tftp_rx(struct tftp_state_data *state,
  517. tftp_event_t event)
  518. {
  519. ssize_t sbytes;
  520. int rblock;
  521. struct Curl_easy *data = state->data;
  522. char buffer[STRERROR_LEN];
  523. switch(event) {
  524. case TFTP_EVENT_DATA:
  525. /* Is this the block we expect? */
  526. rblock = getrpacketblock(&state->rpacket);
  527. if(NEXT_BLOCKNUM(state->block) == rblock) {
  528. /* This is the expected block. Reset counters and ACK it. */
  529. state->retries = 0;
  530. }
  531. else if(state->block == rblock) {
  532. /* This is the last recently received block again. Log it and ACK it
  533. again. */
  534. infof(data, "Received last DATA packet block %d again.\n", rblock);
  535. }
  536. else {
  537. /* totally unexpected, just log it */
  538. infof(data,
  539. "Received unexpected DATA packet block %d, expecting block %d\n",
  540. rblock, NEXT_BLOCKNUM(state->block));
  541. break;
  542. }
  543. /* ACK this block. */
  544. state->block = (unsigned short)rblock;
  545. setpacketevent(&state->spacket, TFTP_EVENT_ACK);
  546. setpacketblock(&state->spacket, state->block);
  547. sbytes = sendto(state->sockfd, (void *)state->spacket.data,
  548. 4, SEND_4TH_ARG,
  549. (struct sockaddr *)&state->remote_addr,
  550. state->remote_addrlen);
  551. if(sbytes < 0) {
  552. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  553. return CURLE_SEND_ERROR;
  554. }
  555. /* Check if completed (That is, a less than full packet is received) */
  556. if(state->rbytes < (ssize_t)state->blksize + 4) {
  557. state->state = TFTP_STATE_FIN;
  558. }
  559. else {
  560. state->state = TFTP_STATE_RX;
  561. }
  562. time(&state->rx_time);
  563. break;
  564. case TFTP_EVENT_OACK:
  565. /* ACK option acknowledgement so we can move on to data */
  566. state->block = 0;
  567. state->retries = 0;
  568. setpacketevent(&state->spacket, TFTP_EVENT_ACK);
  569. setpacketblock(&state->spacket, state->block);
  570. sbytes = sendto(state->sockfd, (void *)state->spacket.data,
  571. 4, SEND_4TH_ARG,
  572. (struct sockaddr *)&state->remote_addr,
  573. state->remote_addrlen);
  574. if(sbytes < 0) {
  575. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  576. return CURLE_SEND_ERROR;
  577. }
  578. /* we're ready to RX data */
  579. state->state = TFTP_STATE_RX;
  580. time(&state->rx_time);
  581. break;
  582. case TFTP_EVENT_TIMEOUT:
  583. /* Increment the retry count and fail if over the limit */
  584. state->retries++;
  585. infof(data,
  586. "Timeout waiting for block %d ACK. Retries = %d\n",
  587. NEXT_BLOCKNUM(state->block), state->retries);
  588. if(state->retries > state->retry_max) {
  589. state->error = TFTP_ERR_TIMEOUT;
  590. state->state = TFTP_STATE_FIN;
  591. }
  592. else {
  593. /* Resend the previous ACK */
  594. sbytes = sendto(state->sockfd, (void *)state->spacket.data,
  595. 4, SEND_4TH_ARG,
  596. (struct sockaddr *)&state->remote_addr,
  597. state->remote_addrlen);
  598. if(sbytes<0) {
  599. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  600. return CURLE_SEND_ERROR;
  601. }
  602. }
  603. break;
  604. case TFTP_EVENT_ERROR:
  605. setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
  606. setpacketblock(&state->spacket, state->block);
  607. (void)sendto(state->sockfd, (void *)state->spacket.data,
  608. 4, SEND_4TH_ARG,
  609. (struct sockaddr *)&state->remote_addr,
  610. state->remote_addrlen);
  611. /* don't bother with the return code, but if the socket is still up we
  612. * should be a good TFTP client and let the server know we're done */
  613. state->state = TFTP_STATE_FIN;
  614. break;
  615. default:
  616. failf(data, "%s", "tftp_rx: internal error");
  617. return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for
  618. this */
  619. }
  620. return CURLE_OK;
  621. }
  622. /**********************************************************
  623. *
  624. * tftp_tx
  625. *
  626. * Event handler for the TX state
  627. *
  628. **********************************************************/
  629. static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
  630. {
  631. struct Curl_easy *data = state->data;
  632. ssize_t sbytes;
  633. CURLcode result = CURLE_OK;
  634. struct SingleRequest *k = &data->req;
  635. size_t cb; /* Bytes currently read */
  636. char buffer[STRERROR_LEN];
  637. switch(event) {
  638. case TFTP_EVENT_ACK:
  639. case TFTP_EVENT_OACK:
  640. if(event == TFTP_EVENT_ACK) {
  641. /* Ack the packet */
  642. int rblock = getrpacketblock(&state->rpacket);
  643. if(rblock != state->block &&
  644. /* There's a bug in tftpd-hpa that causes it to send us an ack for
  645. * 65535 when the block number wraps to 0. So when we're expecting
  646. * 0, also accept 65535. See
  647. * http://syslinux.zytor.com/archives/2010-September/015253.html
  648. * */
  649. !(state->block == 0 && rblock == 65535)) {
  650. /* This isn't the expected block. Log it and up the retry counter */
  651. infof(data, "Received ACK for block %d, expecting %d\n",
  652. rblock, state->block);
  653. state->retries++;
  654. /* Bail out if over the maximum */
  655. if(state->retries>state->retry_max) {
  656. failf(data, "tftp_tx: giving up waiting for block %d ack",
  657. state->block);
  658. result = CURLE_SEND_ERROR;
  659. }
  660. else {
  661. /* Re-send the data packet */
  662. sbytes = sendto(state->sockfd, (void *)state->spacket.data,
  663. 4 + state->sbytes, SEND_4TH_ARG,
  664. (struct sockaddr *)&state->remote_addr,
  665. state->remote_addrlen);
  666. /* Check all sbytes were sent */
  667. if(sbytes<0) {
  668. failf(data, "%s", Curl_strerror(SOCKERRNO,
  669. buffer, sizeof(buffer)));
  670. result = CURLE_SEND_ERROR;
  671. }
  672. }
  673. return result;
  674. }
  675. /* This is the expected packet. Reset the counters and send the next
  676. block */
  677. time(&state->rx_time);
  678. state->block++;
  679. }
  680. else
  681. state->block = 1; /* first data block is 1 when using OACK */
  682. state->retries = 0;
  683. setpacketevent(&state->spacket, TFTP_EVENT_DATA);
  684. setpacketblock(&state->spacket, state->block);
  685. if(state->block > 1 && state->sbytes < state->blksize) {
  686. state->state = TFTP_STATE_FIN;
  687. return CURLE_OK;
  688. }
  689. /* TFTP considers data block size < 512 bytes as an end of session. So
  690. * in some cases we must wait for additional data to build full (512 bytes)
  691. * data block.
  692. * */
  693. state->sbytes = 0;
  694. state->data->req.upload_fromhere = (char *)state->spacket.data + 4;
  695. do {
  696. result = Curl_fillreadbuffer(data, state->blksize - state->sbytes, &cb);
  697. if(result)
  698. return result;
  699. state->sbytes += (int)cb;
  700. state->data->req.upload_fromhere += cb;
  701. } while(state->sbytes < state->blksize && cb != 0);
  702. sbytes = sendto(state->sockfd, (void *) state->spacket.data,
  703. 4 + state->sbytes, SEND_4TH_ARG,
  704. (struct sockaddr *)&state->remote_addr,
  705. state->remote_addrlen);
  706. /* Check all sbytes were sent */
  707. if(sbytes<0) {
  708. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  709. return CURLE_SEND_ERROR;
  710. }
  711. /* Update the progress meter */
  712. k->writebytecount += state->sbytes;
  713. Curl_pgrsSetUploadCounter(data, k->writebytecount);
  714. break;
  715. case TFTP_EVENT_TIMEOUT:
  716. /* Increment the retry counter and log the timeout */
  717. state->retries++;
  718. infof(data, "Timeout waiting for block %d ACK. "
  719. " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
  720. /* Decide if we've had enough */
  721. if(state->retries > state->retry_max) {
  722. state->error = TFTP_ERR_TIMEOUT;
  723. state->state = TFTP_STATE_FIN;
  724. }
  725. else {
  726. /* Re-send the data packet */
  727. sbytes = sendto(state->sockfd, (void *)state->spacket.data,
  728. 4 + state->sbytes, SEND_4TH_ARG,
  729. (struct sockaddr *)&state->remote_addr,
  730. state->remote_addrlen);
  731. /* Check all sbytes were sent */
  732. if(sbytes<0) {
  733. failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  734. return CURLE_SEND_ERROR;
  735. }
  736. /* since this was a re-send, we remain at the still byte position */
  737. Curl_pgrsSetUploadCounter(data, k->writebytecount);
  738. }
  739. break;
  740. case TFTP_EVENT_ERROR:
  741. state->state = TFTP_STATE_FIN;
  742. setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
  743. setpacketblock(&state->spacket, state->block);
  744. (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
  745. (struct sockaddr *)&state->remote_addr,
  746. state->remote_addrlen);
  747. /* don't bother with the return code, but if the socket is still up we
  748. * should be a good TFTP client and let the server know we're done */
  749. state->state = TFTP_STATE_FIN;
  750. break;
  751. default:
  752. failf(data, "tftp_tx: internal error, event: %i", (int)(event));
  753. break;
  754. }
  755. return result;
  756. }
  757. /**********************************************************
  758. *
  759. * tftp_translate_code
  760. *
  761. * Translate internal error codes to CURL error codes
  762. *
  763. **********************************************************/
  764. static CURLcode tftp_translate_code(tftp_error_t error)
  765. {
  766. CURLcode result = CURLE_OK;
  767. if(error != TFTP_ERR_NONE) {
  768. switch(error) {
  769. case TFTP_ERR_NOTFOUND:
  770. result = CURLE_TFTP_NOTFOUND;
  771. break;
  772. case TFTP_ERR_PERM:
  773. result = CURLE_TFTP_PERM;
  774. break;
  775. case TFTP_ERR_DISKFULL:
  776. result = CURLE_REMOTE_DISK_FULL;
  777. break;
  778. case TFTP_ERR_UNDEF:
  779. case TFTP_ERR_ILLEGAL:
  780. result = CURLE_TFTP_ILLEGAL;
  781. break;
  782. case TFTP_ERR_UNKNOWNID:
  783. result = CURLE_TFTP_UNKNOWNID;
  784. break;
  785. case TFTP_ERR_EXISTS:
  786. result = CURLE_REMOTE_FILE_EXISTS;
  787. break;
  788. case TFTP_ERR_NOSUCHUSER:
  789. result = CURLE_TFTP_NOSUCHUSER;
  790. break;
  791. case TFTP_ERR_TIMEOUT:
  792. result = CURLE_OPERATION_TIMEDOUT;
  793. break;
  794. case TFTP_ERR_NORESPONSE:
  795. result = CURLE_COULDNT_CONNECT;
  796. break;
  797. default:
  798. result = CURLE_ABORTED_BY_CALLBACK;
  799. break;
  800. }
  801. }
  802. else
  803. result = CURLE_OK;
  804. return result;
  805. }
  806. /**********************************************************
  807. *
  808. * tftp_state_machine
  809. *
  810. * The tftp state machine event dispatcher
  811. *
  812. **********************************************************/
  813. static CURLcode tftp_state_machine(struct tftp_state_data *state,
  814. tftp_event_t event)
  815. {
  816. CURLcode result = CURLE_OK;
  817. struct Curl_easy *data = state->data;
  818. switch(state->state) {
  819. case TFTP_STATE_START:
  820. DEBUGF(infof(data, "TFTP_STATE_START\n"));
  821. result = tftp_send_first(state, event);
  822. break;
  823. case TFTP_STATE_RX:
  824. DEBUGF(infof(data, "TFTP_STATE_RX\n"));
  825. result = tftp_rx(state, event);
  826. break;
  827. case TFTP_STATE_TX:
  828. DEBUGF(infof(data, "TFTP_STATE_TX\n"));
  829. result = tftp_tx(state, event);
  830. break;
  831. case TFTP_STATE_FIN:
  832. infof(data, "%s\n", "TFTP finished");
  833. break;
  834. default:
  835. DEBUGF(infof(data, "STATE: %d\n", state->state));
  836. failf(data, "%s", "Internal state machine error");
  837. result = CURLE_TFTP_ILLEGAL;
  838. break;
  839. }
  840. return result;
  841. }
  842. /**********************************************************
  843. *
  844. * tftp_disconnect
  845. *
  846. * The disconnect callback
  847. *
  848. **********************************************************/
  849. static CURLcode tftp_disconnect(struct Curl_easy *data,
  850. struct connectdata *conn, bool dead_connection)
  851. {
  852. struct tftp_state_data *state = conn->proto.tftpc;
  853. (void) data;
  854. (void) dead_connection;
  855. /* done, free dynamically allocated pkt buffers */
  856. if(state) {
  857. Curl_safefree(state->rpacket.data);
  858. Curl_safefree(state->spacket.data);
  859. free(state);
  860. }
  861. return CURLE_OK;
  862. }
  863. /**********************************************************
  864. *
  865. * tftp_connect
  866. *
  867. * The connect callback
  868. *
  869. **********************************************************/
  870. static CURLcode tftp_connect(struct Curl_easy *data, bool *done)
  871. {
  872. struct tftp_state_data *state;
  873. int blksize;
  874. int need_blksize;
  875. struct connectdata *conn = data->conn;
  876. blksize = TFTP_BLKSIZE_DEFAULT;
  877. state = conn->proto.tftpc = calloc(1, sizeof(struct tftp_state_data));
  878. if(!state)
  879. return CURLE_OUT_OF_MEMORY;
  880. /* alloc pkt buffers based on specified blksize */
  881. if(data->set.tftp_blksize) {
  882. blksize = (int)data->set.tftp_blksize;
  883. if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN)
  884. return CURLE_TFTP_ILLEGAL;
  885. }
  886. need_blksize = blksize;
  887. /* default size is the fallback when no OACK is received */
  888. if(need_blksize < TFTP_BLKSIZE_DEFAULT)
  889. need_blksize = TFTP_BLKSIZE_DEFAULT;
  890. if(!state->rpacket.data) {
  891. state->rpacket.data = calloc(1, need_blksize + 2 + 2);
  892. if(!state->rpacket.data)
  893. return CURLE_OUT_OF_MEMORY;
  894. }
  895. if(!state->spacket.data) {
  896. state->spacket.data = calloc(1, need_blksize + 2 + 2);
  897. if(!state->spacket.data)
  898. return CURLE_OUT_OF_MEMORY;
  899. }
  900. /* we don't keep TFTP connections up basically because there's none or very
  901. * little gain for UDP */
  902. connclose(conn, "TFTP");
  903. state->data = data;
  904. state->sockfd = conn->sock[FIRSTSOCKET];
  905. state->state = TFTP_STATE_START;
  906. state->error = TFTP_ERR_NONE;
  907. state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
  908. state->requested_blksize = blksize;
  909. ((struct sockaddr *)&state->local_addr)->sa_family =
  910. (CURL_SA_FAMILY_T)(conn->ip_addr->ai_family);
  911. tftp_set_timeouts(state);
  912. if(!conn->bits.bound) {
  913. /* If not already bound, bind to any interface, random UDP port. If it is
  914. * reused or a custom local port was desired, this has already been done!
  915. *
  916. * We once used the size of the local_addr struct as the third argument
  917. * for bind() to better work with IPv6 or whatever size the struct could
  918. * have, but we learned that at least Tru64, AIX and IRIX *requires* the
  919. * size of that argument to match the exact size of a 'sockaddr_in' struct
  920. * when running IPv4-only.
  921. *
  922. * Therefore we use the size from the address we connected to, which we
  923. * assume uses the same IP version and thus hopefully this works for both
  924. * IPv4 and IPv6...
  925. */
  926. int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
  927. conn->ip_addr->ai_addrlen);
  928. if(rc) {
  929. char buffer[STRERROR_LEN];
  930. failf(data, "bind() failed; %s",
  931. Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  932. return CURLE_COULDNT_CONNECT;
  933. }
  934. conn->bits.bound = TRUE;
  935. }
  936. Curl_pgrsStartNow(data);
  937. *done = TRUE;
  938. return CURLE_OK;
  939. }
  940. /**********************************************************
  941. *
  942. * tftp_done
  943. *
  944. * The done callback
  945. *
  946. **********************************************************/
  947. static CURLcode tftp_done(struct Curl_easy *data, CURLcode status,
  948. bool premature)
  949. {
  950. CURLcode result = CURLE_OK;
  951. struct connectdata *conn = data->conn;
  952. struct tftp_state_data *state = conn->proto.tftpc;
  953. (void)status; /* unused */
  954. (void)premature; /* not used */
  955. if(Curl_pgrsDone(data))
  956. return CURLE_ABORTED_BY_CALLBACK;
  957. /* If we have encountered an error */
  958. if(state)
  959. result = tftp_translate_code(state->error);
  960. return result;
  961. }
  962. /**********************************************************
  963. *
  964. * tftp_getsock
  965. *
  966. * The getsock callback
  967. *
  968. **********************************************************/
  969. static int tftp_getsock(struct Curl_easy *data,
  970. struct connectdata *conn, curl_socket_t *socks)
  971. {
  972. (void)data;
  973. socks[0] = conn->sock[FIRSTSOCKET];
  974. return GETSOCK_READSOCK(0);
  975. }
  976. /**********************************************************
  977. *
  978. * tftp_receive_packet
  979. *
  980. * Called once select fires and data is ready on the socket
  981. *
  982. **********************************************************/
  983. static CURLcode tftp_receive_packet(struct Curl_easy *data)
  984. {
  985. struct Curl_sockaddr_storage fromaddr;
  986. curl_socklen_t fromlen;
  987. CURLcode result = CURLE_OK;
  988. struct connectdata *conn = data->conn;
  989. struct tftp_state_data *state = conn->proto.tftpc;
  990. struct SingleRequest *k = &data->req;
  991. /* Receive the packet */
  992. fromlen = sizeof(fromaddr);
  993. state->rbytes = (int)recvfrom(state->sockfd,
  994. (void *)state->rpacket.data,
  995. state->blksize + 4,
  996. 0,
  997. (struct sockaddr *)&fromaddr,
  998. &fromlen);
  999. if(state->remote_addrlen == 0) {
  1000. memcpy(&state->remote_addr, &fromaddr, fromlen);
  1001. state->remote_addrlen = fromlen;
  1002. }
  1003. /* Sanity check packet length */
  1004. if(state->rbytes < 4) {
  1005. failf(data, "Received too short packet");
  1006. /* Not a timeout, but how best to handle it? */
  1007. state->event = TFTP_EVENT_TIMEOUT;
  1008. }
  1009. else {
  1010. /* The event is given by the TFTP packet time */
  1011. unsigned short event = getrpacketevent(&state->rpacket);
  1012. state->event = (tftp_event_t)event;
  1013. switch(state->event) {
  1014. case TFTP_EVENT_DATA:
  1015. /* Don't pass to the client empty or retransmitted packets */
  1016. if(state->rbytes > 4 &&
  1017. (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
  1018. result = Curl_client_write(data, CLIENTWRITE_BODY,
  1019. (char *)state->rpacket.data + 4,
  1020. state->rbytes-4);
  1021. if(result) {
  1022. tftp_state_machine(state, TFTP_EVENT_ERROR);
  1023. return result;
  1024. }
  1025. k->bytecount += state->rbytes-4;
  1026. Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount);
  1027. }
  1028. break;
  1029. case TFTP_EVENT_ERROR:
  1030. {
  1031. unsigned short error = getrpacketblock(&state->rpacket);
  1032. char *str = (char *)state->rpacket.data + 4;
  1033. size_t strn = state->rbytes - 4;
  1034. state->error = (tftp_error_t)error;
  1035. if(tftp_strnlen(str, strn) < strn)
  1036. infof(data, "TFTP error: %s\n", str);
  1037. break;
  1038. }
  1039. case TFTP_EVENT_ACK:
  1040. break;
  1041. case TFTP_EVENT_OACK:
  1042. result = tftp_parse_option_ack(state,
  1043. (const char *)state->rpacket.data + 2,
  1044. state->rbytes-2);
  1045. if(result)
  1046. return result;
  1047. break;
  1048. case TFTP_EVENT_RRQ:
  1049. case TFTP_EVENT_WRQ:
  1050. default:
  1051. failf(data, "%s", "Internal error: Unexpected packet");
  1052. break;
  1053. }
  1054. /* Update the progress meter */
  1055. if(Curl_pgrsUpdate(data)) {
  1056. tftp_state_machine(state, TFTP_EVENT_ERROR);
  1057. return CURLE_ABORTED_BY_CALLBACK;
  1058. }
  1059. }
  1060. return result;
  1061. }
  1062. /**********************************************************
  1063. *
  1064. * tftp_state_timeout
  1065. *
  1066. * Check if timeouts have been reached
  1067. *
  1068. **********************************************************/
  1069. static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event)
  1070. {
  1071. time_t current;
  1072. struct connectdata *conn = data->conn;
  1073. struct tftp_state_data *state = conn->proto.tftpc;
  1074. if(event)
  1075. *event = TFTP_EVENT_NONE;
  1076. time(&current);
  1077. if(current > state->max_time) {
  1078. DEBUGF(infof(data, "timeout: %ld > %ld\n",
  1079. (long)current, (long)state->max_time));
  1080. state->error = TFTP_ERR_TIMEOUT;
  1081. state->state = TFTP_STATE_FIN;
  1082. return 0;
  1083. }
  1084. if(current > state->rx_time + state->retry_time) {
  1085. if(event)
  1086. *event = TFTP_EVENT_TIMEOUT;
  1087. time(&state->rx_time); /* update even though we received nothing */
  1088. }
  1089. /* there's a typecast below here since 'time_t' may in fact be larger than
  1090. 'long', but we estimate that a 'long' will still be able to hold number
  1091. of seconds even if "only" 32 bit */
  1092. return (long)(state->max_time - current);
  1093. }
  1094. /**********************************************************
  1095. *
  1096. * tftp_multi_statemach
  1097. *
  1098. * Handle single RX socket event and return
  1099. *
  1100. **********************************************************/
  1101. static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
  1102. {
  1103. tftp_event_t event;
  1104. CURLcode result = CURLE_OK;
  1105. struct connectdata *conn = data->conn;
  1106. struct tftp_state_data *state = conn->proto.tftpc;
  1107. long timeout_ms = tftp_state_timeout(data, &event);
  1108. *done = FALSE;
  1109. if(timeout_ms <= 0) {
  1110. failf(data, "TFTP response timeout");
  1111. return CURLE_OPERATION_TIMEDOUT;
  1112. }
  1113. if(event != TFTP_EVENT_NONE) {
  1114. result = tftp_state_machine(state, event);
  1115. if(result)
  1116. return result;
  1117. *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
  1118. if(*done)
  1119. /* Tell curl we're done */
  1120. Curl_setup_transfer(data, -1, -1, FALSE, -1);
  1121. }
  1122. else {
  1123. /* no timeouts to handle, check our socket */
  1124. int rc = SOCKET_READABLE(state->sockfd, 0);
  1125. if(rc == -1) {
  1126. /* bail out */
  1127. int error = SOCKERRNO;
  1128. char buffer[STRERROR_LEN];
  1129. failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer)));
  1130. state->event = TFTP_EVENT_ERROR;
  1131. }
  1132. else if(rc != 0) {
  1133. result = tftp_receive_packet(data);
  1134. if(result)
  1135. return result;
  1136. result = tftp_state_machine(state, state->event);
  1137. if(result)
  1138. return result;
  1139. *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
  1140. if(*done)
  1141. /* Tell curl we're done */
  1142. Curl_setup_transfer(data, -1, -1, FALSE, -1);
  1143. }
  1144. /* if rc == 0, then select() timed out */
  1145. }
  1146. return result;
  1147. }
  1148. /**********************************************************
  1149. *
  1150. * tftp_doing
  1151. *
  1152. * Called from multi.c while DOing
  1153. *
  1154. **********************************************************/
  1155. static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done)
  1156. {
  1157. CURLcode result;
  1158. result = tftp_multi_statemach(data, dophase_done);
  1159. if(*dophase_done) {
  1160. DEBUGF(infof(data, "DO phase is complete\n"));
  1161. }
  1162. else if(!result) {
  1163. /* The multi code doesn't have this logic for the DOING state so we
  1164. provide it for TFTP since it may do the entire transfer in this
  1165. state. */
  1166. if(Curl_pgrsUpdate(data))
  1167. result = CURLE_ABORTED_BY_CALLBACK;
  1168. else
  1169. result = Curl_speedcheck(data, Curl_now());
  1170. }
  1171. return result;
  1172. }
  1173. /**********************************************************
  1174. *
  1175. * tftp_peform
  1176. *
  1177. * Entry point for transfer from tftp_do, sarts state mach
  1178. *
  1179. **********************************************************/
  1180. static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done)
  1181. {
  1182. CURLcode result = CURLE_OK;
  1183. struct connectdata *conn = data->conn;
  1184. struct tftp_state_data *state = conn->proto.tftpc;
  1185. *dophase_done = FALSE;
  1186. result = tftp_state_machine(state, TFTP_EVENT_INIT);
  1187. if((state->state == TFTP_STATE_FIN) || result)
  1188. return result;
  1189. tftp_multi_statemach(data, dophase_done);
  1190. if(*dophase_done)
  1191. DEBUGF(infof(data, "DO phase is complete\n"));
  1192. return result;
  1193. }
  1194. /**********************************************************
  1195. *
  1196. * tftp_do
  1197. *
  1198. * The do callback
  1199. *
  1200. * This callback initiates the TFTP transfer
  1201. *
  1202. **********************************************************/
  1203. static CURLcode tftp_do(struct Curl_easy *data, bool *done)
  1204. {
  1205. struct tftp_state_data *state;
  1206. CURLcode result;
  1207. struct connectdata *conn = data->conn;
  1208. *done = FALSE;
  1209. if(!conn->proto.tftpc) {
  1210. result = tftp_connect(data, done);
  1211. if(result)
  1212. return result;
  1213. }
  1214. state = conn->proto.tftpc;
  1215. if(!state)
  1216. return CURLE_TFTP_ILLEGAL;
  1217. result = tftp_perform(data, done);
  1218. /* If tftp_perform() returned an error, use that for return code. If it
  1219. was OK, see if tftp_translate_code() has an error. */
  1220. if(!result)
  1221. /* If we have encountered an internal tftp error, translate it. */
  1222. result = tftp_translate_code(state->error);
  1223. return result;
  1224. }
  1225. static CURLcode tftp_setup_connection(struct Curl_easy *data,
  1226. struct connectdata *conn)
  1227. {
  1228. char *type;
  1229. conn->transport = TRNSPRT_UDP;
  1230. /* TFTP URLs support an extension like ";mode=<typecode>" that
  1231. * we'll try to get now! */
  1232. type = strstr(data->state.up.path, ";mode=");
  1233. if(!type)
  1234. type = strstr(conn->host.rawalloc, ";mode=");
  1235. if(type) {
  1236. char command;
  1237. *type = 0; /* it was in the middle of the hostname */
  1238. command = Curl_raw_toupper(type[6]);
  1239. switch(command) {
  1240. case 'A': /* ASCII mode */
  1241. case 'N': /* NETASCII mode */
  1242. data->set.prefer_ascii = TRUE;
  1243. break;
  1244. case 'O': /* octet mode */
  1245. case 'I': /* binary mode */
  1246. default:
  1247. /* switch off ASCII */
  1248. data->set.prefer_ascii = FALSE;
  1249. break;
  1250. }
  1251. }
  1252. return CURLE_OK;
  1253. }
  1254. #endif