tftp: send DACK until server receives it

This commit is contained in:
kYc0o 2017-03-30 15:16:37 +02:00
parent 1f70d172c6
commit 9ee1e1f156

View File

@ -39,13 +39,13 @@ static kernel_pid_t _tftp_kernel_pid;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define CT_HTONS(x) ((uint16_t)(( \ #define CT_HTONS(x) ((uint16_t)(( \
(((uint16_t)(x)) >> 8) & 0x00FF) | \ (((uint16_t)(x)) >> 8) & 0x00FF) | \
((((uint16_t)(x)) << 8) & 0xFF00))) ((((uint16_t)(x)) << 8) & 0xFF00)))
#else #else
#define CT_HTONS(x) ((uint16_t)x) #define CT_HTONS(x) ((uint16_t)x)
#endif #endif
#define MIN(a, b) ((a) > (b) ? (b) : (a)) #define MIN(a, b) ((a) > (b) ? (b) : (a))
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0])) #define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
#define TFTP_TIMEOUT_MSG 0x4000 #define TFTP_TIMEOUT_MSG 0x4000
@ -124,6 +124,8 @@ tftp_opt_t _tftp_options[] = {
* @brief The TFTP state * @brief The TFTP state
*/ */
typedef enum { typedef enum {
TS_APP_FAILED = -3,
TS_DUP = -2,
TS_FAILED = -1, TS_FAILED = -1,
TS_BUSY = 0, TS_BUSY = 0,
TS_FINISHED = 1 TS_FINISHED = 1
@ -559,7 +561,6 @@ tftp_state _tftp_state_processes(tftp_context_t *ctxt, msg_t *m)
{ {
gnrc_pktsnip_t *outbuf = gnrc_pktbuf_add(NULL, NULL, TFTP_DEFAULT_DATA_SIZE, gnrc_pktsnip_t *outbuf = gnrc_pktbuf_add(NULL, NULL, TFTP_DEFAULT_DATA_SIZE,
GNRC_NETTYPE_UNDEF); GNRC_NETTYPE_UNDEF);
/* check if this is an client start */ /* check if this is an client start */
if (!m) { if (!m) {
DEBUG("tftp: starting transaction as client\n"); DEBUG("tftp: starting transaction as client\n");
@ -688,10 +689,18 @@ tftp_state _tftp_state_processes(tftp_context_t *ctxt, msg_t *m)
case TO_DATA: { case TO_DATA: {
/* try to process the data */ /* try to process the data */
int proc = _tftp_process_data(ctxt, pkt); int proc = _tftp_process_data(ctxt, pkt);
if (proc < 0) {
if (proc == TS_APP_FAILED || proc == TS_FAILED) {
DEBUG("tftp: data not accepted\n"); DEBUG("tftp: data not accepted\n");
/* the data is not accepted return */ /* the data is not accepted return */
/* we are maybe releasing twice XXX*/
gnrc_pktbuf_release(outbuf); gnrc_pktbuf_release(outbuf);
return proc;
}
if (proc == TS_DUP) {
DEBUG("tftp: duplicated data received, acking...\n");
_tftp_send_dack(ctxt, outbuf, TO_ACK);
return TS_BUSY; return TS_BUSY;
} }
@ -724,7 +733,8 @@ tftp_state _tftp_state_processes(tftp_context_t *ctxt, msg_t *m)
} }
return TS_BUSY; return TS_BUSY;
} break; }
break;
case TO_ACK: { case TO_ACK: {
/* validate if this is the ACK we are waiting for */ /* validate if this is the ACK we are waiting for */
@ -902,9 +912,7 @@ tftp_state _tftp_send_dack(tftp_context_t *ctxt, gnrc_pktsnip_t *buf, tftp_opcod
tftp_state _tftp_send_error(tftp_context_t *ctxt, gnrc_pktsnip_t *buf, tftp_err_codes_t err, const char *err_msg) tftp_state _tftp_send_error(tftp_context_t *ctxt, gnrc_pktsnip_t *buf, tftp_err_codes_t err, const char *err_msg)
{ {
int strl = err_msg int strl = err_msg ? strlen(err_msg) + 1 : 0;
? strlen(err_msg) + 1
: 0;
(void) ctxt; (void) ctxt;
@ -1107,15 +1115,22 @@ int _tftp_process_data(tftp_context_t *ctxt, gnrc_pktsnip_t *buf)
uint16_t block_nr = byteorder_ntohs(pkt->block_nr); uint16_t block_nr = byteorder_ntohs(pkt->block_nr);
/* check if this is the packet we are waiting for */ /* check if this is the packet we are waiting for */
if (block_nr != (ctxt->block_nr + 1)) { if (block_nr > (ctxt->block_nr + 1)) {
DEBUG("tftp: not the packet we were wating for\n"); DEBUG("tftp: incorrect block_nr %d received from server, expected %d\n",
return TS_BUSY; block_nr, (ctxt->block_nr + 1));
return TS_FAILED;
}
if (block_nr < (ctxt->block_nr + 1)) {
DEBUG("tftp: not the packet we were wating for, expected %d, received %d\n",
(uint16_t)(ctxt->block_nr + 1), block_nr);
return TS_DUP;
} }
/* send the user data trough to the user application */ /* send the user data trough to the user application */
if (ctxt->data_cb(ctxt->block_nr * ctxt->block_size, pkt->data, buf->size - sizeof(tftp_packet_data_t)) < 0) { if (ctxt->data_cb(ctxt->block_nr * ctxt->block_size, pkt->data,
buf->size - sizeof(tftp_packet_data_t)) < 0) {
DEBUG("tftp: error in data callback\n"); DEBUG("tftp: error in data callback\n");
return TS_BUSY; return TS_APP_FAILED;
} }
/* return the number of data bytes received */ /* return the number of data bytes received */