Home | History | Annotate | Download | only in lib

Lines Matching refs:state

123   tftp_state_t    state;
149 static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
150 static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
194 * Set timeouts based on state machine state.
200 static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
204 bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
206 time(&state->start_time);
209 timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
213 failf(state->conn->data, "Connection time-out");
220 state->max_time = state->start_time + maxtime;
226 state->retry_max = (int)timeout/5;
228 if(state->retry_max < 1)
230 state->retry_max = 1;
233 state->retry_time = (int)timeout/state->retry_max;
234 if(state->retry_time<1)
235 state->retry_time = 1;
244 state->max_time = state->start_time + maxtime;
250 state->retry_max = (int)timeout/5;
253 if(state->retry_max<3)
254 state->retry_max = 3;
256 if(state->retry_max>50)
257 state->retry_max = 50;
260 state->retry_time = (int)(timeout/state->retry_max);
261 if(state->retry_time<1)
262 state->retry_time = 1;
264 infof(state->conn->data,
265 "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
266 (int)state->state, (long)(state->max_time-state->start_time),
267 state->retry_time, state->retry_max);
270 time(&state->rx_time);
279 * Event handler for the START state
334 static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
338 struct Curl_easy *data = state->conn->data;
341 state->blksize = TFTP_BLKSIZE_DEFAULT;
373 else if(blksize > state->requested_blksize) {
382 state->blksize = (int)blksize;
384 state->blksize, "requested", state->requested_blksize);
407 static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
410 if(( strlen(option) + csize + 1) > (size_t)state->blksize)
416 static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
421 struct Curl_easy *data = state->conn->data;
425 state->state = TFTP_STATE_TX;
426 result = tftp_set_timeouts(state);
429 return tftp_tx(state, event);
432 static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
437 struct Curl_easy *data = state->conn->data;
441 state->state = TFTP_STATE_RX;
442 result = tftp_set_timeouts(state);
445 return tftp_rx(state, event);
448 static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
455 struct Curl_easy *data = state->conn->data;
467 state->retries++;
468 if(state->retries>state->retry_max) {
469 state->error = TFTP_ERR_NORESPONSE;
470 state->state = TFTP_STATE_FIN;
476 setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
477 state->conn->data->req.upload_fromhere =
478 (char *)state->spacket.data + 4;
479 if(data->state.infilesize != -1)
480 Curl_pgrsSetUploadSize(data, data->state.infilesize);
484 setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
489 result = Curl_urldecode(data, &state->conn->data->state.path[1], 0,
494 if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
500 snprintf((char *)state->spacket.data + 2,
501 state->blksize,
508 if(data->set.upload && (data->state.infilesize != -1))
510 data->state.infilesize);
514 sbytes += tftp_option_add(state, sbytes,
515 (char *)state->spacket.data + sbytes,
517 sbytes += tftp_option_add(state, sbytes,
518 (char *)state->spacket.data + sbytes, buf);
520 snprintf(buf, sizeof(buf), "%d", state->requested_blksize);
521 sbytes += tftp_option_add(state, sbytes,
522 (char *)state->spacket.data + sbytes,
524 sbytes += tftp_option_add(state, sbytes,
525 (char *)state->spacket.data + sbytes, buf);
528 snprintf(buf, sizeof(buf), "%d", state->retry_time);
529 sbytes += tftp_option_add(state, sbytes,
530 (char *)state->spacket.data + sbytes,
532 sbytes += tftp_option_add(state, sbytes,
533 (char *)state->spacket.data + sbytes, buf);
538 senddata = sendto(state->sockfd, (void *)state->spacket.data,
540 state->conn->ip_addr->ai_addr,
541 state->conn->ip_addr->ai_addrlen);
543 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
550 result = tftp_connect_for_tx(state, event);
553 result = tftp_connect_for_rx(state, event);
558 result = tftp_connect_for_tx(state, event);
562 result = tftp_connect_for_rx(state, event);
566 state->state = TFTP_STATE_FIN;
570 failf(state->conn->data, "tftp_send_first: internal error");
585 * Event handler for the RX state
588 static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
592 struct Curl_easy *data = state->conn->data;
598 rblock = getrpacketblock(&state->rpacket);
599 if(NEXT_BLOCKNUM(state->block) == rblock) {
601 state->retries = 0;
603 else if(state->block == rblock) {
612 rblock, NEXT_BLOCKNUM(state->block));
617 state->block = (unsigned short)rblock;
618 setpacketevent(&state->spacket, TFTP_EVENT_ACK);
619 setpacketblock(&state->spacket, state->block);
620 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
622 (struct sockaddr *)&state->remote_addr,
623 state->remote_addrlen);
625 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
630 if(state->rbytes < (ssize_t)state->blksize + 4) {
631 state->state = TFTP_STATE_FIN;
634 state->state = TFTP_STATE_RX;
636 time(&state->rx_time);
641 state->block = 0;
642 state->retries = 0;
643 setpacketevent(&state->spacket, TFTP_EVENT_ACK);
644 setpacketblock(&state->spacket, state->block);
645 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
647 (struct sockaddr *)&state->remote_addr,
648 state->remote_addrlen);
650 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
655 state->state = TFTP_STATE_RX;
656 time(&state->rx_time);
661 state->retries++;
664 NEXT_BLOCKNUM(state->block), state->retries);
665 if(state->retries > state->retry_max) {
666 state->error = TFTP_ERR_TIMEOUT;
667 state->state = TFTP_STATE_FIN;
671 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
673 (struct sockaddr *)&state->remote_addr,
674 state->remote_addrlen);
676 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
683 setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
684 setpacketblock(&state->spacket, state->block);
685 (void)sendto(state->sockfd, (void *)state->spacket.data,
687 (struct sockaddr *)&state->remote_addr,
688 state->remote_addrlen);
691 state->state = TFTP_STATE_FIN;
706 * Event handler for the TX state
709 static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
711 struct Curl_easy *data = state->conn->data;
724 rblock = getrpacketblock(&state->rpacket);
726 if(rblock != state->block &&
732 !(state->block == 0 && rblock == 65535)) {
735 rblock, state->block);
736 state->retries++;
738 if(state->retries>state->retry_max) {
740 state->block);
745 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
746 4 + state->sbytes, SEND_4TH_ARG,
747 (struct sockaddr *)&state->remote_addr,
748 state->remote_addrlen);
751 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
760 time(&state->rx_time);
761 state->block++;
764 state->block = 1; /* first data block is 1 when using OACK */
766 state->retries = 0;
767 setpacketevent(&state->spacket, TFTP_EVENT_DATA);
768 setpacketblock(&state->spacket, state->block);
769 if(state->block > 1 && state->sbytes < (int)state->blksize) {
770 state->state = TFTP_STATE_FIN;
778 state->sbytes = 0;
779 state->conn->data->req.upload_fromhere = (char *)state->spacket.data + 4;
781 result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
785 state->sbytes += cb;
786 state->conn->data->req.upload_fromhere += cb;
787 } while(state->sbytes < state->blksize && cb != 0);
789 sbytes = sendto(state->sockfd, (void *) state->spacket.data,
790 4 + state->sbytes, SEND_4TH_ARG,
791 (struct sockaddr *)&state->remote_addr,
792 state->remote_addrlen);
795 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
799 k->writebytecount += state->sbytes;
805 state->retries++;
807 " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
809 if(state->retries > state->retry_max) {
810 state->error = TFTP_ERR_TIMEOUT;
811 state->state = TFTP_STATE_FIN;
815 sbytes = sendto(state->sockfd, (void *)state->spacket.data,
816 4 + state->sbytes, SEND_4TH_ARG,
817 (struct sockaddr *)&state->remote_addr,
818 state->remote_addrlen);
821 failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
830 state->state = TFTP_STATE_FIN;
831 setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
832 setpacketblock(&state->spacket, state->block);
833 (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
834 (struct sockaddr *)&state->remote_addr,
835 state->remote_addrlen);
838 state->state = TFTP_STATE_FIN;
905 * The tftp state machine event dispatcher
908 static CURLcode tftp_state_machine(tftp_state_data_t *state,
912 struct Curl_easy *data = state->conn->data;
914 switch(state->state) {
917 result = tftp_send_first(state, event);
921 result = tftp_rx(state, event);
925 result = tftp_tx(state, event);
931 DEBUGF(infof(data, "STATE: %d\n", state->state));
932 failf(data, "%s", "Internal state machine error");
949 tftp_state_data_t *state = conn->proto.tftpc;
953 if(state) {
954 Curl_safefree(state->rpacket.data);
955 Curl_safefree(state->spacket.data);
956 free(state);
971 tftp_state_data_t *state;
976 state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
977 if(!state)
987 if(!state->rpacket.data) {
988 state->rpacket.data = calloc(1, blksize + 2 + 2);
990 if(!state->rpacket.data)
994 if(!state->spacket.data) {
995 state->spacket.data = calloc(1, blksize + 2 + 2);
997 if(!state->spacket.data)
1005 state->conn = conn;
1006 state->sockfd = state->conn->sock[FIRSTSOCKET];
1007 state->state = TFTP_STATE_START;
1008 state->error = TFTP_ERR_NONE;
1009 state->blksize = TFTP_BLKSIZE_DEFAULT;
1010 state->requested_blksize = blksize;
1012 ((struct sockaddr *)&state->local_addr)->sa_family =
1015 tftp_set_timeouts(state);
1031 rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
1059 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1068 if(state)
1069 result = tftp_translate_code(state->error);
1105 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1110 state->rbytes = (int)recvfrom(state->sockfd,
1111 (void *)state->rpacket.data,
1112 state->blksize + 4,
1116 if(state->remote_addrlen == 0) {
1117 memcpy(&state->remote_addr, &fromaddr, fromlen);
1118 state->remote_addrlen = fromlen;
1122 if(state->rbytes < 4) {
1125 state->event = TFTP_EVENT_TIMEOUT;
1129 unsigned short event = getrpacketevent(&state->rpacket);
1130 state->event = (tftp_event_t)event;
1132 switch(state->event) {
1135 if(state->rbytes > 4 &&
1136 (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
1138 (char *)state->rpacket.data + 4,
1139 state->rbytes-4);
1141 tftp_state_machine(state, TFTP_EVENT_ERROR);
1144 k->bytecount += state->rbytes-4;
1150 unsigned short error = getrpacketblock(&state->rpacket);
1151 state->error = (tftp_error_t)error;
1152 infof(data, "%s\n", (const char *)state->rpacket.data + 4);
1158 result = tftp_parse_option_ack(state,
1159 (const char *)state->rpacket.data + 2,
1160 state->rbytes-2);
1173 tftp_state_machine(state, TFTP_EVENT_ERROR);
1190 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1196 if(current > state->max_time) {
1198 (long)current, (long)state->max_time));
1199 state->error = TFTP_ERR_TIMEOUT;
1200 state->state = TFTP_STATE_FIN;
1203 if(current > state->rx_time + state->retry_time) {
1206 time(&state->rx_time); /* update even though we received nothing */
1212 return (long)(state->max_time - current);
1228 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1238 result = tftp_state_machine(state, event);
1241 *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
1248 rc = SOCKET_READABLE(state->sockfd, 0);
1254 state->event = TFTP_EVENT_ERROR;
1260 result = tftp_state_machine(state, state->event);
1263 *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
1290 /* The multi code doesn't have this logic for the DOING state so we
1292 state. */
1305 * Entry point for transfer from tftp_do, sarts state mach
1311 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1315 result = tftp_state_machine(state, TFTP_EVENT_INIT);
1317 if((state->state == TFTP_STATE_FIN) || result)
1341 tftp_state_data_t *state;
1352 state = (tftp_state_data_t *)conn->proto.tftpc;
1353 if(!state)
1362 result = tftp_translate_code(state->error);
1377 type = strstr(data->state.path, ";mode=");