From: Stefan Eissing Date: Wed, 30 Apr 2025 09:08:02 +0000 (+0200) Subject: tftp: use connections meta hash X-Git-Tag: curl-8_14_0~160 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=378aa011e6938c2b6397451f8062850f8b5d21b9;p=thirdparty%2Fcurl.git tftp: use connections meta hash Use connection meta hash for state struct instead of union pointer at connectdata. Closes #17235 --- diff --git a/lib/tftp.c b/lib/tftp.c index 2454e3e64f..24ce9af983 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -121,7 +121,10 @@ struct tftp_packet { unsigned char *data; }; -struct tftp_state_data { +/* meta key for storing protocol meta at connection */ +#define CURL_META_TFTP_CONN "meta:proto:tftp:conn" + +struct tftp_conn { tftp_state_t state; tftp_mode_t mode; tftp_error_t error; @@ -146,12 +149,9 @@ struct tftp_state_data { /* Forward declarations */ -static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event); -static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event); +static CURLcode tftp_rx(struct tftp_conn *state, tftp_event_t event); +static CURLcode tftp_tx(struct tftp_conn *state, tftp_event_t event); static CURLcode tftp_connect(struct Curl_easy *data, bool *done); -static CURLcode tftp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection); static CURLcode tftp_do(struct Curl_easy *data, bool *done); static CURLcode tftp_done(struct Curl_easy *data, CURLcode, bool premature); @@ -181,7 +181,7 @@ const struct Curl_handler Curl_handler_tftp = { tftp_getsock, /* doing_getsock */ ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ - tftp_disconnect, /* disconnect */ + ZERO_NULL, /* disconnect */ ZERO_NULL, /* write_resp */ ZERO_NULL, /* write_resp_hd */ ZERO_NULL, /* connection_check */ @@ -203,7 +203,7 @@ const struct Curl_handler Curl_handler_tftp = { * * **********************************************************/ -static CURLcode tftp_set_timeouts(struct tftp_state_data *state) +static CURLcode tftp_set_timeouts(struct tftp_conn *state) { time_t maxtime, timeout; timediff_t timeout_ms; @@ -310,7 +310,7 @@ static const char *tftp_option_get(const char *buf, size_t len, return &buf[loc]; } -static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, +static CURLcode tftp_parse_option_ack(struct tftp_conn *state, const char *ptr, int len) { const char *tmp = ptr; @@ -379,7 +379,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, return CURLE_OK; } -static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize, +static CURLcode tftp_option_add(struct tftp_conn *state, size_t *csize, char *buf, const char *option) { if(( strlen(option) + *csize + 1) > (size_t)state->blksize) @@ -389,7 +389,7 @@ static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize, return CURLE_OK; } -static CURLcode tftp_connect_for_tx(struct tftp_state_data *state, +static CURLcode tftp_connect_for_tx(struct tftp_conn *state, tftp_event_t event) { CURLcode result; @@ -405,7 +405,7 @@ static CURLcode tftp_connect_for_tx(struct tftp_state_data *state, return tftp_tx(state, event); } -static CURLcode tftp_connect_for_rx(struct tftp_state_data *state, +static CURLcode tftp_connect_for_rx(struct tftp_conn *state, tftp_event_t event) { CURLcode result; @@ -421,7 +421,7 @@ static CURLcode tftp_connect_for_rx(struct tftp_state_data *state, return tftp_rx(state, event); } -static CURLcode tftp_send_first(struct tftp_state_data *state, +static CURLcode tftp_send_first(struct tftp_conn *state, tftp_event_t event) { size_t sbytes; @@ -576,8 +576,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, * Event handler for the RX state * **********************************************************/ -static CURLcode tftp_rx(struct tftp_state_data *state, - tftp_event_t event) +static CURLcode tftp_rx(struct tftp_conn *state, tftp_event_t event) { ssize_t sbytes; int rblock; @@ -699,7 +698,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, * Event handler for the TX state * **********************************************************/ -static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) +static CURLcode tftp_tx(struct tftp_conn *state, tftp_event_t event) { struct Curl_easy *data = state->data; ssize_t sbytes; @@ -901,7 +900,7 @@ static CURLcode tftp_translate_code(tftp_error_t error) * The tftp state machine event dispatcher * **********************************************************/ -static CURLcode tftp_state_machine(struct tftp_state_data *state, +static CURLcode tftp_state_machine(struct tftp_conn *state, tftp_event_t event) { CURLcode result = CURLE_OK; @@ -933,28 +932,14 @@ static CURLcode tftp_state_machine(struct tftp_state_data *state, return result; } -/********************************************************** - * - * tftp_disconnect - * - * The disconnect callback - * - **********************************************************/ -static CURLcode tftp_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead_connection) +static void tftp_conn_dtor(void *key, size_t klen, void *entry) { - struct tftp_state_data *state = conn->proto.tftpc; - (void) data; - (void) dead_connection; - - /* done, free dynamically allocated pkt buffers */ - if(state) { - Curl_safefree(state->rpacket.data); - Curl_safefree(state->spacket.data); - free(state); - } - - return CURLE_OK; + struct tftp_conn *state = entry; + (void)key; + (void)klen; + Curl_safefree(state->rpacket.data); + Curl_safefree(state->spacket.data); + free(state); } /********************************************************** @@ -966,15 +951,16 @@ static CURLcode tftp_disconnect(struct Curl_easy *data, **********************************************************/ static CURLcode tftp_connect(struct Curl_easy *data, bool *done) { - struct tftp_state_data *state; + struct tftp_conn *state; int blksize; int need_blksize; struct connectdata *conn = data->conn; blksize = TFTP_BLKSIZE_DEFAULT; - state = conn->proto.tftpc = calloc(1, sizeof(struct tftp_state_data)); - if(!state) + state = calloc(1, sizeof(*state)); + if(!state || + Curl_conn_meta_set(conn, CURL_META_TFTP_CONN, state, tftp_conn_dtor)) return CURLE_OUT_OF_MEMORY; /* alloc pkt buffers based on specified blksize */ @@ -1061,7 +1047,7 @@ static CURLcode tftp_done(struct Curl_easy *data, CURLcode status, { CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - struct tftp_state_data *state = conn->proto.tftpc; + struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); (void)status; /* unused */ (void)premature; /* not used */ @@ -1098,12 +1084,11 @@ static int tftp_getsock(struct Curl_easy *data, * Called once select fires and data is ready on the socket * **********************************************************/ -static CURLcode tftp_receive_packet(struct Curl_easy *data) +static CURLcode tftp_receive_packet(struct Curl_easy *data, + struct tftp_conn *state) { curl_socklen_t fromlen; CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct tftp_state_data *state = conn->proto.tftpc; /* Receive the packet */ fromlen = sizeof(state->remote_addr); @@ -1182,12 +1167,10 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) * Check if timeouts have been reached * **********************************************************/ -static timediff_t tftp_state_timeout(struct Curl_easy *data, +static timediff_t tftp_state_timeout(struct tftp_conn *state, tftp_event_t *event) { time_t current; - struct connectdata *conn = data->conn; - struct tftp_state_data *state = conn->proto.tftpc; timediff_t timeout_ms; if(event) @@ -1222,11 +1205,14 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) tftp_event_t event; CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - struct tftp_state_data *state = conn->proto.tftpc; - timediff_t timeout_ms = tftp_state_timeout(data, &event); + struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); + timediff_t timeout_ms; *done = FALSE; + if(!state) + return CURLE_FAILED_INIT; + timeout_ms = tftp_state_timeout(state, &event); if(timeout_ms < 0) { failf(data, "TFTP response timeout"); return CURLE_OPERATION_TIMEDOUT; @@ -1252,7 +1238,7 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) state->event = TFTP_EVENT_ERROR; } else if(rc) { - result = tftp_receive_packet(data); + result = tftp_receive_packet(data, state); if(result) return result; result = tftp_state_machine(state, state->event); @@ -1307,9 +1293,11 @@ static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done) { CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - struct tftp_state_data *state = conn->proto.tftpc; + struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); *dophase_done = FALSE; + if(!state) + return CURLE_FAILED_INIT; result = tftp_state_machine(state, TFTP_EVENT_INIT); @@ -1337,21 +1325,21 @@ static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done) static CURLcode tftp_do(struct Curl_easy *data, bool *done) { - struct tftp_state_data *state; - CURLcode result; struct connectdata *conn = data->conn; + struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); + CURLcode result; *done = FALSE; - if(!conn->proto.tftpc) { + if(!state) { result = tftp_connect(data, done); if(result) return result; - } - state = conn->proto.tftpc; - if(!state) - return CURLE_TFTP_ILLEGAL; + state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); + if(!state) + return CURLE_TFTP_ILLEGAL; + } result = tftp_perform(data, done); diff --git a/lib/urldata.h b/lib/urldata.h index 8014f8412e..39f57695fe 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -870,9 +870,6 @@ struct connectdata { #ifdef USE_SSH struct ssh_conn sshc; #endif -#ifndef CURL_DISABLE_TFTP - struct tftp_state_data *tftpc; -#endif #ifndef CURL_DISABLE_IMAP struct imap_conn imapc; #endif