Skip to content

Commit

Permalink
Merge pull request #1766 from private-octopus/config-two-dash
Browse files Browse the repository at this point in the history
Config two dash
  • Loading branch information
huitema authored Oct 23, 2024
2 parents 0ba9cca + 1c516ae commit 959955e
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 24 deletions.
116 changes: 96 additions & 20 deletions picoquic/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,36 +517,76 @@ int picoquic_config_set_option(picoquic_quic_config_t* config, picoquic_option_e
return ret;
}

int picoquic_config_command_line(int opt, int * p_optind, int argc, char const ** argv, char const* optarg, picoquic_quic_config_t * config)
int picoquic_config_get_option_char_index(int opt)
{
int ret = 0;
int option_index = -1;
option_param_t params[5];
int nb_params = 0;

/* Get the parameters */
for (size_t i = 0; i < option_table_size; i++) {
if (option_table[i].option_letter == opt) {
option_index = (int)i;
break;
}
}
return option_index;
}

if (option_index == -1 || option_table[option_index].nb_params_required > 1) {
/* No options have more than one parameter */
fprintf(stderr, "Unknown or incorrect option: -%c\n", opt);
ret = -1;
int picoquic_config_get_option_name_index(char const * s, size_t l)
{
int option_index = -1;

for (size_t i = 0; i < option_table_size; i++) {
if (strncmp(s, option_table[i].option_name, l) == 0) {
option_index = (int)i;
break;
}
}
else {
if (option_table[option_index].nb_params_required > 0) {
params[0].param = optarg;
if (optarg == NULL){
fprintf(stderr, "option -%c requires %d arguments\n", opt, option_table[option_index].nb_params_required);
ret = -1;
}
else {
params[0].length = strlen(optarg);
nb_params++;
return option_index;
}

int picoquic_config_get_command_line_option_index(char const* opt_string)
{
int option_index = -1;

if (opt_string[0] == '-' && opt_string[1] != 0) {
if (opt_string[2] == 0) {
option_index = picoquic_config_get_option_char_index(opt_string[1]);
}
else if (opt_string[1] == '-' && opt_string[2] != 0) {
char const* opt_name = opt_string + 2;
option_index = picoquic_config_get_option_name_index(opt_name, strlen(opt_name));
}
}
return option_index;
}

int picoquic_get_command_line_option_value(int option_index, char const * opt_string, int* p_optind, const char** argv,
int argc, char const* optarg, picoquic_quic_config_t* config)
{
int ret = 0;
option_param_t params[5];
int nb_params = 0;

if (option_table[option_index].nb_params_required > 0) {
params[0].param = optarg;
if (optarg == NULL) {
fprintf(stderr, "option %s requires %d arguments\n", opt_string, option_table[option_index].nb_params_required);
ret = -1;
}
else {
params[0].length = strlen(optarg);
nb_params++;
while (nb_params < option_table[option_index].nb_params_required) {
if (*p_optind + 1 > argc) {
fprintf(stderr, "option %s requires %d arguments\n", opt_string, option_table[option_index].nb_params_required);
ret = -1;
break;
}
else {
params[nb_params].param = argv[*p_optind];
params[nb_params].length = (int)strlen(argv[*p_optind]);
nb_params++;
*p_optind += 1;
}
}
}
}
Expand All @@ -558,6 +598,43 @@ int picoquic_config_command_line(int opt, int * p_optind, int argc, char const *
return ret;
}

int picoquic_config_command_line(int opt, int * p_optind, int argc, char const ** argv, char const* optarg, picoquic_quic_config_t * config)
{
int ret = 0;
int option_index = -1;
char opt_string[3] = { '-', 0, 0 };

opt_string[1] = (char)opt;
option_index = picoquic_config_get_option_char_index(opt);

if (option_index == -1) {
fprintf(stderr, "Unknown option: -%c\n", opt);
ret = -1;
}
else {
ret = picoquic_get_command_line_option_value(option_index, opt_string, p_optind,
argv, argc, optarg, config);
}
return ret;
}

int picoquic_config_command_line_ex(char const * opt_string, int* p_optind, int argc, char const** argv, char const* optarg, picoquic_quic_config_t* config)
{
int ret = 0;
int option_index = -1;

option_index = picoquic_config_get_command_line_option_index(opt_string);

if (option_index == -1) {
fprintf(stderr, "Unknown option: %s\n", opt_string);
}
else {
ret = picoquic_get_command_line_option_value(option_index, opt_string, p_optind,
argv, argc, optarg, config);
}
return ret;
}

#if 0
/* Reading parameters from a file instead of the command line.
* Apparently never used, also not tested.
Expand Down Expand Up @@ -637,7 +714,6 @@ int picoquic_config_file(char const* file_name, picoquic_quic_config_t* config)

return ret;
}

#endif

/* Create a QUIC Context based on configuration data.
Expand Down
8 changes: 8 additions & 0 deletions picoquic/picoquic_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,15 @@ void picoquic_config_usage_file(FILE* F);
void picoquic_config_usage();
int picoquic_config_set_option(picoquic_quic_config_t* config, picoquic_option_enum_t option_num, const char* opt_val);

/* picoquic_config_command_line:
* parse options, with the restriction that all options must be identified by a single character, as in '-x'
*/
int picoquic_config_command_line(int opt, int* p_optind, int argc, char const** argv, char const* optarg, picoquic_quic_config_t* config);
/* picoquic_config_command_line:
* parse options, allowing both single character options (e.g. -X)
* and named option (e.g. --disable_block)
*/
int picoquic_config_command_line_ex(char const* opt_string, int* p_optind, int argc, char const** argv, char const* optarg, picoquic_quic_config_t* config);

#if 0
/* It does not seem anyone uses this, and it is not tested */
Expand Down
82 changes: 78 additions & 4 deletions picoquictest/config_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>

#include "picoquic.h"
#include "picoquic_internal.h"
#include "picoquic_utils.h"
#include "picoquic_config.h"
Expand Down Expand Up @@ -216,6 +217,29 @@ static const char* config_argv2[] = {
NULL
};

static const char * config_two[] = {
"--sni", "test.example.com",
"--alpn", "test",
"--outdir", "/data/w_out",
"--root_trust_file", "data/certs/root.pem",
"--cipher_suite", "20",
"--proposed_version", "ff000020",
"--force_zero_share",
"--idle_timeout", "1234567",
"--no_disk",
"--large_client_hello",
"--disable_block",
#ifndef PICOQUIC_WITHOUT_SSLKEYLOG
"--sslkeylog",
#endif
"--cnxid_length", "5",
"--ticket_file", "/data/tickets.bin",
"--token_file", "/data/tokens.bin",
"--version_upgrade", "00000002",
"--cwin_max", "1000000",
NULL
};

typedef struct st_config_error_test_t {
int nb_args;
char const* err_args[2];
Expand Down Expand Up @@ -433,6 +457,56 @@ static int config_parse_command_line_test(const picoquic_quic_config_t* expected
return (ret);
}

int config_test_parse_command_line_ex(const picoquic_quic_config_t* expected, const char** argv, int argc)
{
int ret = 0;
int opt_ind = 0;
picoquic_quic_config_t actual;

picoquic_config_init(&actual);

while (opt_ind < argc && ret == 0) {
const char* x = argv[opt_ind];
const char* optval = NULL;

if (x == NULL) {
/* could not parse to the end! */
DBG_PRINTF("Unexpected stop after %d arguments, expected %d", opt_ind, argc);
ret = -1;
break;
}
else if (x[0] != '-' || x[1] == 0 ||
(x[2] != 0 && x[1] != '-')) {
/* could not parse to the end! */
DBG_PRINTF("Unexpected argument: %s", x);
ret = -1;
break;
}
opt_ind++;
if (opt_ind < argc) {
optval = argv[opt_ind];
if (optval[0] == '-') {
optval = NULL;
}
else {
opt_ind++;
}
}
ret = picoquic_config_command_line_ex(x, &opt_ind, argc, argv, optval, &actual);
if (ret != 0) {
DBG_PRINTF("Could not parse opt %s", x);
}
}

if (ret == 0) {
ret = config_test_compare(expected, &actual);
}

picoquic_config_clear(&actual);

return (ret);
}

int config_set_option_test_one()
{
int ret = 0;
Expand Down Expand Up @@ -465,18 +539,18 @@ int config_option_test()
if (ret != 0) {
DBG_PRINTF("First config option test returns %d", ret);
}

if (ret == 0){
if (ret == 0) {
ret = config_parse_command_line_test(&param2, config_argv2, (int)(sizeof(config_argv2) / sizeof(char const*)) - 1);

if (ret != 0) {
DBG_PRINTF("Second config option test returns %d", ret);
}
}

if (ret == 0) {
ret = config_set_option_test_one();
ret = config_test_parse_command_line_ex(&param2, config_two, (int)(sizeof(config_two) / sizeof(char const*)) - 1);
if (ret != 0) {
DBG_PRINTF("Config set option test returns %d", ret);
DBG_PRINTF("Two dash config option test returns %d", ret);
}
}

Expand Down

0 comments on commit 959955e

Please sign in to comment.