ogs_sockopt_t is added

This commit is contained in:
Sukchan Lee 2019-05-31 16:33:09 +09:00
parent f0c84d3037
commit 61d0573686
8 changed files with 187 additions and 112 deletions

@ -1 +1 @@
Subproject commit 38d47a768e767a2cb59ce391f5307a048ce49888
Subproject commit 54efd858c616fd81a7ebbdfd566fb631f98173ea

View File

@ -60,49 +60,48 @@ int context_read_file()
document = ogs_calloc(1, sizeof(yaml_document_t));
if (!yaml_parser_load(&parser, document)) {
ogs_fatal("Failed to parse configuration file '%s'", config->path);
switch (parser.error)
{
case YAML_MEMORY_ERROR:
ogs_error("Memory error: Not enough memory for parsing");
break;
case YAML_READER_ERROR:
if (parser.problem_value != -1)
ogs_error("Reader error - %s: #%X at %zd", parser.problem,
parser.problem_value, parser.problem_offset);
else
ogs_error("Reader error - %s at %zd", parser.problem,
parser.problem_offset);
break;
case YAML_SCANNER_ERROR:
if (parser.context)
ogs_error("Scanner error - %s at line %zu, column %zu"
"%s at line %zu, column %zu", parser.context,
parser.context_mark.line+1,
parser.context_mark.column+1,
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
else
ogs_error("Scanner error - %s at line %zu, column %zu",
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
break;
case YAML_PARSER_ERROR:
if (parser.context)
ogs_error("Parser error - %s at line %zu, column %zu"
"%s at line %zu, column %zu", parser.context,
parser.context_mark.line+1,
parser.context_mark.column+1,
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
else
ogs_error("Parser error - %s at line %zu, column %zu",
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
break;
default:
/* Couldn't happen. */
ogs_assert_if_reached();
break;
switch (parser.error) {
case YAML_MEMORY_ERROR:
ogs_error("Memory error: Not enough memory for parsing");
break;
case YAML_READER_ERROR:
if (parser.problem_value != -1)
ogs_error("Reader error - %s: #%X at %zd", parser.problem,
parser.problem_value, parser.problem_offset);
else
ogs_error("Reader error - %s at %zd", parser.problem,
parser.problem_offset);
break;
case YAML_SCANNER_ERROR:
if (parser.context)
ogs_error("Scanner error - %s at line %zu, column %zu"
"%s at line %zu, column %zu", parser.context,
parser.context_mark.line+1,
parser.context_mark.column+1,
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
else
ogs_error("Scanner error - %s at line %zu, column %zu",
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
break;
case YAML_PARSER_ERROR:
if (parser.context)
ogs_error("Parser error - %s at line %zu, column %zu"
"%s at line %zu, column %zu", parser.context,
parser.context_mark.line+1,
parser.context_mark.column+1,
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
else
ogs_error("Parser error - %s at line %zu, column %zu",
parser.problem, parser.problem_mark.line+1,
parser.problem_mark.column+1);
break;
default:
/* Couldn't happen. */
ogs_assert_if_reached();
break;
}
ogs_free(document);
@ -164,8 +163,7 @@ int context_parse_config()
ogs_assert(root_key);
if (!strcmp(root_key, "db_uri")) {
self.config.db_uri = ogs_yaml_iter_value(&root_iter);
}
else if (!strcmp(root_key, "logger")) {
} else if (!strcmp(root_key, "logger")) {
ogs_yaml_iter_t logger_iter;
ogs_yaml_iter_recurse(&root_iter, &logger_iter);
while (ogs_yaml_iter_next(&logger_iter)) {
@ -173,26 +171,21 @@ int context_parse_config()
ogs_assert(logger_key);
if (!strcmp(logger_key, "file")) {
self.config.logger.file = ogs_yaml_iter_value(&logger_iter);
}
else if (!strcmp(logger_key, "level")) {
} else if (!strcmp(logger_key, "level")) {
self.config.logger.level =
ogs_yaml_iter_value(&logger_iter);
}
else if (!strcmp(logger_key, "domain")) {
} else if (!strcmp(logger_key, "domain")) {
self.config.logger.domain =
ogs_yaml_iter_value(&logger_iter);
}
}
}
else if (!strcmp(root_key, "parameter"))
{
} else if (!strcmp(root_key, "parameter")) {
ogs_yaml_iter_t parameter_iter;
ogs_yaml_iter_recurse(&root_iter, &parameter_iter);
while (ogs_yaml_iter_next(&parameter_iter)) {
const char *parameter_key = ogs_yaml_iter_key(&parameter_iter);
ogs_assert(parameter_key);
if (!strcmp(parameter_key, "no_hss"))
{
if (!strcmp(parameter_key, "no_hss")) {
self.config.parameter.no_hss =
ogs_yaml_iter_bool(&parameter_iter);
} else if (!strcmp(parameter_key, "no_sgw")) {
@ -204,9 +197,6 @@ int context_parse_config()
} else if (!strcmp(parameter_key, "no_pcrf")) {
self.config.parameter.no_pcrf =
ogs_yaml_iter_bool(&parameter_iter);
} else if (!strcmp(parameter_key, "sctp_streams")) {
const char *v = ogs_yaml_iter_value(&parameter_iter);
if (v) self.config.parameter.sctp_streams = atoi(v);
} else if (!strcmp(parameter_key, "no_ipv4")) {
self.config.parameter.no_ipv4 =
ogs_yaml_iter_bool(&parameter_iter);
@ -225,6 +215,42 @@ int context_parse_config()
} else
ogs_warn("unknown key `%s`", parameter_key);
}
} else if (!strcmp(root_key, "sctp")) {
ogs_yaml_iter_t sctp_iter;
ogs_yaml_iter_recurse(&root_iter, &sctp_iter);
while (ogs_yaml_iter_next(&sctp_iter)) {
const char *sctp_key = ogs_yaml_iter_key(&sctp_iter);
ogs_assert(sctp_key);
if (!strcmp(sctp_key, "heartbit_interval")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.config.sockopt.sctp.heartbit_interval = atoi(v);
} else if (!strcmp(sctp_key, "rto_initial")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.config.sockopt.sctp.rto_initial = atoi(v);
} else if (!strcmp(sctp_key, "rto_min")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.config.sockopt.sctp.rto_min = atoi(v);
} else if (!strcmp(sctp_key, "rto_max")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.config.sockopt.sctp.rto_max = atoi(v);
} else if (!strcmp(sctp_key, "max_num_of_ostreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.config.sockopt.sctp.max_num_of_ostreams = atoi(v);
} else if (!strcmp(sctp_key, "max_num_of_istreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.config.sockopt.sctp.max_num_of_istreams = atoi(v);
} else if (!strcmp(sctp_key, "max_attempts")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) self.config.sockopt.sctp.max_attempts = atoi(v);
} else if (!strcmp(sctp_key, "max_initial_timeout")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v)
self.config.sockopt.sctp.max_initial_timeout = atoi(v);
} else
ogs_warn("unknown key `%s`", sctp_key);
}
}
}

View File

@ -30,7 +30,6 @@ typedef struct _config_t {
int no_pcrf;
/* Network */
int sctp_streams;
int no_ipv4;
int no_ipv6;
int prefer_ipv4;
@ -38,6 +37,8 @@ typedef struct _config_t {
int no_slaac;
} parameter;
ogs_sockopt_t sockopt;
} config_t;
#define MAX_DB_URI_LEN 256

View File

@ -1,6 +1,8 @@
#include <mongoc.h>
#include <yaml.h>
#include "ogs-sctp.h"
#include "asn1c/s1ap_message.h"
#include "gtp/gtp_xact.h"
#include "gtp/gtp_node.h"
@ -1396,7 +1398,12 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
enb->addr = addr;
enb->sock_type = mme_enb_sock_type(enb->sock);
enb->outbound_streams = context_self()->config.parameter.sctp_streams;
enb->outbound_streams = DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
if (context_self()->config.sockopt.sctp.max_num_of_ostreams) {
enb->outbound_streams =
context_self()->config.sockopt.sctp.max_num_of_ostreams;
ogs_info("[ENB] max_num_of_ostreams : %d", enb->outbound_streams);
}
ogs_list_init(&enb->enb_ue_list);

View File

@ -23,12 +23,9 @@
#define OGS_LOG_DOMAIN __ogs_sock_domain
static int subscribe_to_events(ogs_sock_t *sock);
static int set_paddrparams(ogs_sock_t *sock, uint32_t spp_hbinterval);
static int set_rtoinfo(ogs_sock_t *sock,
uint32_t srto_initial, uint32_t srto_min, uint32_t srto_max);
static int set_initmsg(ogs_sock_t *sock,
uint32_t sinit_num_ostreams, uint32_t sinit_max_instreams,
uint32_t sinit_max_attempts, uint32_t sinit_max_init_timeo);
static int set_paddrparams(ogs_sock_t *sock, ogs_sockopt_t *option);
static int set_rtoinfo(ogs_sock_t *sock, ogs_sockopt_t *option);
static int set_initmsg(ogs_sock_t *sock, ogs_sockopt_t *option);
int ogs_sctp_init(uint16_t port)
{
@ -43,14 +40,60 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
{
ogs_sock_t *new = NULL;
int rv;
#define DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30
uint16_t max_num_of_ostreams = DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
ogs_sockopt_t option = {
.sctp.heartbit_interval = 5000, /* 5 seconds */
.sctp.rto_initial = 3000, /* 3 seconds */
.sctp.rto_min = 1000, /* 1 seconds */
.sctp.rto_max = 5000, /* 5 seconds */
.sctp.max_num_of_ostreams = DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS,
.sctp.max_num_of_istreams = 65535,
.sctp.max_attempts = 4,
.sctp.max_initial_timeout = 8000 /* 8 seconds */
};
if (node) {
if (node->sctp.max_num_of_ostreams) {
max_num_of_ostreams = node->sctp.max_num_of_ostreams;
ogs_info("SCTP: Maximum number of output streams[%d]",
max_num_of_ostreams);
if (node->option.sctp.heartbit_interval) {
option.sctp.heartbit_interval = node->option.sctp.heartbit_interval;
ogs_debug("[SCTP] heartbit_interval - [%d]",
option.sctp.heartbit_interval);
}
if (node->option.sctp.rto_initial) {
option.sctp.rto_initial = node->option.sctp.rto_initial;
ogs_debug("[SCTP] rto_initial - [%d]",
option.sctp.rto_initial);
}
if (node->option.sctp.rto_min) {
option.sctp.rto_min = node->option.sctp.rto_min;
ogs_debug("[SCTP] rto_min - [%d]",
option.sctp.rto_min);
}
if (node->option.sctp.rto_max) {
option.sctp.rto_max = node->option.sctp.rto_max;
ogs_debug("[SCTP] rto_max - [%d]",
option.sctp.rto_max);
}
if (node->option.sctp.max_num_of_ostreams) {
option.sctp.max_num_of_ostreams =
node->option.sctp.max_num_of_ostreams;
ogs_debug("[SCTP] max_num_of_ostreams - [%d]",
option.sctp.max_num_of_ostreams);
}
if (node->option.sctp.max_num_of_istreams) {
option.sctp.max_num_of_istreams =
node->option.sctp.max_num_of_istreams;
ogs_debug("[SCTP] max_num_of_istreams - [%d]",
option.sctp.max_num_of_istreams);
}
if (node->option.sctp.max_attempts) {
option.sctp.max_attempts = node->option.sctp.max_attempts;
ogs_debug("[SCTP] max_attempts - [%d]",
option.sctp.max_attempts);
}
if (node->option.sctp.max_initial_timeout) {
option.sctp.max_initial_timeout =
node->option.sctp.max_initial_timeout;
ogs_debug("[SCTP] max_initial_timeout - [%d]",
option.sctp.max_initial_timeout);
}
}
@ -60,28 +103,13 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
rv = subscribe_to_events(new);
ogs_assert(rv == OGS_OK);
/* heartbit interval : 5 secs */
rv = set_paddrparams(new, 5000);
rv = set_paddrparams(new, &option);
ogs_assert(rv == OGS_OK);
/*
* RTO info
*
* initial : 3 secs
* min : 1 sec
* max : 5 secs
*/
rv = set_rtoinfo(new, 3000, 1000, 5000);
rv = set_rtoinfo(new, &option);
ogs_assert(rv == OGS_OK);
/*
* INITMSG
*
* max number of input streams : 65535
* max attemtps : 4
* max initial timeout : 8 secs
*/
rv = set_initmsg(new, max_num_of_ostreams, 65535, 4, 8000);
rv = set_initmsg(new, &option);
ogs_assert(rv == OGS_OK);
return new;
@ -304,12 +332,13 @@ static int subscribe_to_events(ogs_sock_t *sock)
return OGS_OK;
}
static int set_paddrparams(ogs_sock_t *sock, uint32_t spp_hbinterval)
static int set_paddrparams(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_paddrparams heartbeat;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(option);
memset(&heartbeat, 0, sizeof(heartbeat));
socklen = sizeof(heartbeat);
@ -320,12 +349,12 @@ static int set_paddrparams(ogs_sock_t *sock, uint32_t spp_hbinterval)
return OGS_ERROR;
}
ogs_trace("Old spp _flags = 0x%x hbinter = %d pathmax = %d",
ogs_trace("OLD spp_flags = 0x%x hbinter = %d pathmax = %d",
heartbeat.spp_flags,
heartbeat.spp_hbinterval,
heartbeat.spp_pathmaxrxt);
heartbeat.spp_hbinterval = spp_hbinterval;
heartbeat.spp_hbinterval = option->sctp.heartbit_interval;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&heartbeat, sizeof( heartbeat)) != 0) {
@ -334,7 +363,7 @@ static int set_paddrparams(ogs_sock_t *sock, uint32_t spp_hbinterval)
return OGS_ERROR;
}
ogs_trace("New spp _flags = 0x%x hbinter = %d pathmax = %d",
ogs_trace("NEW spp_flags = 0x%x hbinter = %d pathmax = %d",
heartbeat.spp_flags,
heartbeat.spp_hbinterval,
heartbeat.spp_pathmaxrxt);
@ -342,13 +371,13 @@ static int set_paddrparams(ogs_sock_t *sock, uint32_t spp_hbinterval)
return OGS_OK;
}
static int set_rtoinfo(ogs_sock_t *sock,
uint32_t srto_initial, uint32_t srto_min, uint32_t srto_max)
static int set_rtoinfo(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_rtoinfo rtoinfo;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(option);
memset(&rtoinfo, 0, sizeof(rtoinfo));
socklen = sizeof(rtoinfo);
@ -359,14 +388,14 @@ static int set_rtoinfo(ogs_sock_t *sock,
return OGS_ERROR;
}
ogs_trace("Old RTO (initial:%d max:%d min:%d)",
ogs_trace("OLD RTO (initial:%d max:%d min:%d)",
rtoinfo.srto_initial,
rtoinfo.srto_max,
rtoinfo.srto_min);
rtoinfo.srto_initial = srto_initial;
rtoinfo.srto_min = srto_min;
rtoinfo.srto_max = srto_max;
rtoinfo.srto_initial = option->sctp.rto_initial;
rtoinfo.srto_min = option->sctp.rto_min;
rtoinfo.srto_max = option->sctp.rto_max;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, sizeof(rtoinfo)) != 0) {
@ -382,15 +411,14 @@ static int set_rtoinfo(ogs_sock_t *sock,
return OGS_OK;
}
static int set_initmsg(ogs_sock_t *sock,
uint32_t sinit_num_ostreams, uint32_t sinit_max_instreams,
uint32_t sinit_max_attempts, uint32_t sinit_max_init_timeo)
static int set_initmsg(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_initmsg initmsg;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(sinit_num_ostreams > 1);
ogs_assert(option);
ogs_assert(option->sctp.max_num_of_ostreams > 1);
memset(&initmsg, 0, sizeof(initmsg));
socklen = sizeof(initmsg);
@ -407,10 +435,10 @@ static int set_initmsg(ogs_sock_t *sock,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
initmsg.sinit_num_ostreams = sinit_num_ostreams;
initmsg.sinit_max_instreams = sinit_max_instreams;
initmsg.sinit_max_attempts = sinit_max_attempts;
initmsg.sinit_max_init_timeo = sinit_max_init_timeo;
initmsg.sinit_num_ostreams = option->sctp.max_num_of_ostreams;
initmsg.sinit_max_instreams = option->sctp.max_num_of_istreams;
initmsg.sinit_max_attempts = option->sctp.max_attempts;
initmsg.sinit_max_init_timeo = option->sctp.max_initial_timeout;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0) {

View File

@ -30,6 +30,8 @@
extern "C" {
#endif
#define DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30
typedef struct ogs_sctp_info_s {
uint32_t ppid;
uint16_t stream_no;

View File

@ -13,10 +13,8 @@ void s1ap_server(ogs_socknode_t *snode, int type)
ogs_assert(snode);
if (context_self()->config.parameter.sctp_streams)
ogs_socknode_set_sctp_max_num_of_ostreams(snode,
context_self()->config.parameter.sctp_streams);
memcpy(&snode->option,
&context_self()->config.sockopt, sizeof(snode->option));
ogs_sctp_server(type, snode);
ogs_assert(snode->sock);

View File

@ -46,6 +46,19 @@ logger:
parameter:
no_ipv6: true
#
# sctp:
#
# o heartbit_interval : 5000 (5secs)
# o rto_initial : 3000 (3secs)
# o rto_min : 1000 (1sec)
# o rto_max : 5000 (5secs)
# o max_num_of_ostreams : 30
# o max_num_of_istreams : 65535
# o max_attempts : 4
# o max_initial_timeout : 8000(8secs)
sctp:
mme:
freeDiameter: mme.conf