mirror of
https://github.com/curl/curl.git
synced 2026-07-24 00:37:23 +03:00
tftp: use connections meta hash
Use connection meta hash for state struct instead of union pointer at connectdata. Closes #17235
This commit is contained in:
parent
d57bdbf830
commit
378aa011e6
2 changed files with 47 additions and 62 deletions
106
lib/tftp.c
106
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue