MINOR: spoe: Add a function to validate a version is supported

spoe_check_vsn() function can now be used to check if a version, converted
to an integer, via spoe_str_to_vsn() for instance, is supported. To do so,
the list of all supported version is now exported.
This commit is contained in:
Christopher Faulet 2024-07-22 18:55:28 +02:00
parent 735e4aecfc
commit f8fed07d3a
3 changed files with 28 additions and 15 deletions

View File

@ -95,6 +95,12 @@ enum spop_vars_scope {
#define SPOP_DATA_FL_FALSE 0x00 #define SPOP_DATA_FL_FALSE 0x00
#define SPOP_DATA_FL_TRUE 0x10 #define SPOP_DATA_FL_TRUE 0x10
struct spop_version {
char *str;
int min;
int max;
};
/* All supported SPOP data types */ /* All supported SPOP data types */
enum spop_data_type { enum spop_data_type {
SPOP_DATA_T_NULL = 0, SPOP_DATA_T_NULL = 0,

View File

@ -29,6 +29,8 @@
struct appctx; struct appctx;
extern const struct spop_version spop_supported_versions[];
struct spoe_agent *spoe_appctx_agent(struct appctx *appctx); struct spoe_agent *spoe_appctx_agent(struct appctx *appctx);
/* Encode a buffer. Its length <len> is encoded as a varint, followed by a copy /* Encode a buffer. Its length <len> is encoded as a varint, followed by a copy
@ -344,5 +346,21 @@ out:
return vsn; return vsn;
} }
/* Check if vsn, converted into an integer, is supported by looping on the list
* of supported versions. It return -1 on error and 0 on success.
*/
static inline int spoe_check_vsn(int vsn)
{
int i;
for (i = 0; spop_supported_versions[i].str != NULL; ++i) {
if (vsn >= spop_supported_versions[i].min &&
vsn <= spop_supported_versions[i].max)
break;
}
if (spop_supported_versions[i].str == NULL)
return -1;
return 0;
}
#endif /* _HAPROXY_SPOE_H */ #endif /* _HAPROXY_SPOE_H */

View File

@ -245,14 +245,8 @@ const char *spop_err_reasons[SPOP_ERR_ENTRIES] = {
#define SPOP_STATUS_CODE_KEY "status-code" #define SPOP_STATUS_CODE_KEY "status-code"
#define SPOP_MSG_KEY "message" #define SPOP_MSG_KEY "message"
struct spop_version {
char *str;
int min;
int max;
};
/* All supported versions */ /* All supported versions */
static struct spop_version spop_supported_versions[] = { const struct spop_version spop_supported_versions[] = {
/* 1.0 is now unsupported because of a bug about frame's flags*/ /* 1.0 is now unsupported because of a bug about frame's flags*/
{"2.0", 2000, 2000}, {"2.0", 2000, 2000},
{NULL, 0, 0} {NULL, 0, 0}
@ -1619,7 +1613,7 @@ static int spop_conn_handle_hello(struct spop_conn *spop_conn)
/* Check "version" K/V item */ /* Check "version" K/V item */
if (sz >= strlen(SPOP_VERSION_KEY) && !memcmp(str, SPOP_VERSION_KEY, strlen(SPOP_VERSION_KEY))) { if (sz >= strlen(SPOP_VERSION_KEY) && !memcmp(str, SPOP_VERSION_KEY, strlen(SPOP_VERSION_KEY))) {
int i, type = *p++; int type = *p++;
/* The value must be a string */ /* The value must be a string */
if ((type & SPOP_DATA_T_MASK) != SPOP_DATA_T_STR) { if ((type & SPOP_DATA_T_MASK) != SPOP_DATA_T_STR) {
@ -1633,15 +1627,10 @@ static int spop_conn_handle_hello(struct spop_conn *spop_conn)
vsn = spoe_str_to_vsn(str, sz); vsn = spoe_str_to_vsn(str, sz);
if (vsn == -1) { if (vsn == -1) {
spop_conn_error(spop_conn, SPOP_ERR_BAD_VSN); spop_conn_error(spop_conn, SPOP_ERR_INVALID);
goto fail; goto fail;
} }
for (i = 0; spop_supported_versions[i].str != NULL; ++i) { if (spoe_check_vsn(vsn) == -1) {
if (vsn >= spop_supported_versions[i].min &&
vsn <= spop_supported_versions[i].max)
break;
}
if (spop_supported_versions[i].str == NULL) {
spop_conn_error(spop_conn, SPOP_ERR_BAD_VSN); spop_conn_error(spop_conn, SPOP_ERR_BAD_VSN);
goto fail; goto fail;
} }