mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
CLEANUP: peers: factor the error handling code in peer_treet_updatemsg()
The error handling code was extremely repetitive and error-prone due to the numerous copy-pastes, some involving unlocks or free. Let's factor this out. The code could be further simplified, but 12 locations were already cleaned without taking risks.
This commit is contained in:
parent
4b2fd9bf71
commit
1e82a14c34
144
src/peers.c
144
src/peers.c
@ -1158,11 +1158,9 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
expire = MS_TO_TICKS(st->table->expire);
|
expire = MS_TO_TICKS(st->table->expire);
|
||||||
|
|
||||||
if (updt) {
|
if (updt) {
|
||||||
if (msg_len < sizeof(update)) {
|
if (msg_len < sizeof(update))
|
||||||
/* malformed message */
|
goto malformed_exit;
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&update, *msg_cur, sizeof(update));
|
memcpy(&update, *msg_cur, sizeof(update));
|
||||||
*msg_cur += sizeof(update);
|
*msg_cur += sizeof(update);
|
||||||
st->last_get = htonl(update);
|
st->last_get = htonl(update);
|
||||||
@ -1174,10 +1172,9 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
if (exp) {
|
if (exp) {
|
||||||
size_t expire_sz = sizeof expire;
|
size_t expire_sz = sizeof expire;
|
||||||
|
|
||||||
if (*msg_cur + expire_sz > msg_end) {
|
if (*msg_cur + expire_sz > msg_end)
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
goto malformed_exit;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&expire, *msg_cur, expire_sz);
|
memcpy(&expire, *msg_cur, expire_sz);
|
||||||
*msg_cur += expire_sz;
|
*msg_cur += expire_sz;
|
||||||
expire = ntohl(expire);
|
expire = ntohl(expire);
|
||||||
@ -1191,19 +1188,12 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
unsigned int to_read, to_store;
|
unsigned int to_read, to_store;
|
||||||
|
|
||||||
to_read = intdecode(msg_cur, msg_end);
|
to_read = intdecode(msg_cur, msg_end);
|
||||||
if (!*msg_cur) {
|
if (!*msg_cur)
|
||||||
/* malformed message */
|
goto malformed_free_newts;
|
||||||
stksess_free(st->table, newts);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
to_store = MIN(to_read, st->table->key_size - 1);
|
to_store = MIN(to_read, st->table->key_size - 1);
|
||||||
if (*msg_cur + to_store > msg_end) {
|
if (*msg_cur + to_store > msg_end)
|
||||||
/* malformed message */
|
goto malformed_free_newts;
|
||||||
stksess_free(st->table, newts);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(newts->key.key, *msg_cur, to_store);
|
memcpy(newts->key.key, *msg_cur, to_store);
|
||||||
newts->key.key[to_store] = 0;
|
newts->key.key[to_store] = 0;
|
||||||
@ -1212,24 +1202,18 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
else if (st->table->type == SMP_T_SINT) {
|
else if (st->table->type == SMP_T_SINT) {
|
||||||
unsigned int netinteger;
|
unsigned int netinteger;
|
||||||
|
|
||||||
if (*msg_cur + sizeof(netinteger) > msg_end) {
|
if (*msg_cur + sizeof(netinteger) > msg_end)
|
||||||
/* malformed message */
|
goto malformed_free_newts;
|
||||||
stksess_free(st->table, newts);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&netinteger, *msg_cur, sizeof(netinteger));
|
memcpy(&netinteger, *msg_cur, sizeof(netinteger));
|
||||||
netinteger = ntohl(netinteger);
|
netinteger = ntohl(netinteger);
|
||||||
memcpy(newts->key.key, &netinteger, sizeof(netinteger));
|
memcpy(newts->key.key, &netinteger, sizeof(netinteger));
|
||||||
*msg_cur += sizeof(netinteger);
|
*msg_cur += sizeof(netinteger);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (*msg_cur + st->table->key_size > msg_end) {
|
if (*msg_cur + st->table->key_size > msg_end)
|
||||||
/* malformed message */
|
goto malformed_free_newts;
|
||||||
stksess_free(st->table, newts);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(newts->key.key, *msg_cur, st->table->key_size);
|
memcpy(newts->key.key, *msg_cur, st->table->key_size);
|
||||||
*msg_cur += st->table->key_size;
|
*msg_cur += st->table->key_size;
|
||||||
}
|
}
|
||||||
@ -1244,62 +1228,34 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
|
|
||||||
for (data_type = 0 ; data_type < STKTABLE_DATA_TYPES ; data_type++) {
|
for (data_type = 0 ; data_type < STKTABLE_DATA_TYPES ; data_type++) {
|
||||||
|
uint64_t decoded_int;
|
||||||
|
|
||||||
if (!((1 << data_type) & st->remote_data))
|
if (!((1 << data_type) & st->remote_data))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
decoded_int = intdecode(msg_cur, msg_end);
|
||||||
|
if (!*msg_cur)
|
||||||
|
goto malformed_unlock;
|
||||||
|
|
||||||
switch (stktable_data_types[data_type].std_type) {
|
switch (stktable_data_types[data_type].std_type) {
|
||||||
case STD_T_SINT: {
|
case STD_T_SINT:
|
||||||
int data;
|
|
||||||
|
|
||||||
data = intdecode(msg_cur, msg_end);
|
|
||||||
if (!*msg_cur) {
|
|
||||||
/* malformed message */
|
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
||||||
if (data_ptr)
|
if (data_ptr)
|
||||||
stktable_data_cast(data_ptr, std_t_sint) = data;
|
stktable_data_cast(data_ptr, std_t_sint) = decoded_int;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case STD_T_UINT: {
|
|
||||||
unsigned int data;
|
|
||||||
|
|
||||||
data = intdecode(msg_cur, msg_end);
|
|
||||||
if (!*msg_cur) {
|
|
||||||
/* malformed message */
|
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case STD_T_UINT:
|
||||||
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
||||||
if (data_ptr)
|
if (data_ptr)
|
||||||
stktable_data_cast(data_ptr, std_t_uint) = data;
|
stktable_data_cast(data_ptr, std_t_uint) = decoded_int;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case STD_T_ULL: {
|
|
||||||
unsigned long long data;
|
|
||||||
|
|
||||||
data = intdecode(msg_cur, msg_end);
|
|
||||||
if (!*msg_cur) {
|
|
||||||
/* malformed message */
|
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case STD_T_ULL:
|
||||||
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
||||||
if (data_ptr)
|
if (data_ptr)
|
||||||
stktable_data_cast(data_ptr, std_t_ull) = data;
|
stktable_data_cast(data_ptr, std_t_ull) = decoded_int;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case STD_T_FRQP: {
|
case STD_T_FRQP: {
|
||||||
struct freq_ctr_period data;
|
struct freq_ctr_period data;
|
||||||
|
|
||||||
@ -1308,30 +1264,14 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
so we don't need to update the update the freq_ctr_period
|
so we don't need to update the update the freq_ctr_period
|
||||||
using its internal lock */
|
using its internal lock */
|
||||||
|
|
||||||
data.curr_tick = tick_add(now_ms, -intdecode(msg_cur, msg_end)) & ~0x1;
|
data.curr_tick = tick_add(now_ms, -decoded_int) & ~0x1;
|
||||||
if (!*msg_cur) {
|
|
||||||
/* malformed message */
|
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
data.curr_ctr = intdecode(msg_cur, msg_end);
|
data.curr_ctr = intdecode(msg_cur, msg_end);
|
||||||
if (!*msg_cur) {
|
if (!*msg_cur)
|
||||||
/* malformed message */
|
goto malformed_unlock;
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
data.prev_ctr = intdecode(msg_cur, msg_end);
|
data.prev_ctr = intdecode(msg_cur, msg_end);
|
||||||
if (!*msg_cur) {
|
if (!*msg_cur)
|
||||||
/* malformed message */
|
goto malformed_unlock;
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
|
||||||
stktable_touch_remote(st->table, ts, 1);
|
|
||||||
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
data_ptr = stktable_data_ptr(st->table, ts, data_type);
|
||||||
if (data_ptr)
|
if (data_ptr)
|
||||||
@ -1351,6 +1291,20 @@ static int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt,
|
|||||||
/* skip consumed message */
|
/* skip consumed message */
|
||||||
co_skip(si_oc(si), totl);
|
co_skip(si_oc(si), totl);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
malformed_unlock:
|
||||||
|
/* malformed message */
|
||||||
|
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
|
stktable_touch_remote(st->table, ts, 1);
|
||||||
|
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
malformed_free_newts:
|
||||||
|
/* malformed message */
|
||||||
|
stksess_free(st->table, newts);
|
||||||
|
malformed_exit:
|
||||||
|
appctx->st0 = PEER_SESS_ST_ERRPROTO;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user