intermediate

This commit is contained in:
Sukchan Lee 2017-07-30 22:29:27 +09:00
parent 0c6abd3501
commit abf87a0673
12 changed files with 448 additions and 57 deletions

View File

@ -25,10 +25,27 @@ static int s6a_config_apply_internal()
fd_g_config->cnf_diamrlm = s6a_config->cnf_diamrlm;
fd_os_validate_DiameterIdentity(
&fd_g_config->cnf_diamrlm, &fd_g_config->cnf_diamrlm_len, 1);
if (s6a_config->cnf_addr == NULL)
return CORE_ERROR;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
if (s6a_config->cnf_addr == NULL)
return CORE_ERROR;
ret = getaddrinfo(s6a_config->cnf_addr, NULL, &hints, &ai);
if (ret)
return CORE_ERROR;
fd_ep_add_merge( &fd_g_config->cnf_endpoints,
ai->ai_addr, ai->ai_addrlen, EP_FL_CONF),
freeaddrinfo(ai);
#if 0
if (s6a_config->cnf_port)
fd_g_config->cnf_port = s6a_config->cnf_port;
if (s6a_config->cnf_port_tls)
fd_g_config->cnf_port_tls = s6a_config->cnf_port_tls;
#endif
memset(&fddpi, 0, sizeof(fddpi));
fddpi.config.pic_flags.persist = PI_PRST_ALWAYS;
@ -44,7 +61,9 @@ static int s6a_config_apply_internal()
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
ret = getaddrinfo("127.0.0.1", NULL, &hints, &ai);
if (s6a_config->pi_addr == NULL)
return CORE_ERROR;
ret = getaddrinfo(s6a_config->pi_addr, NULL, &hints, &ai);
if (ret)
return CORE_ERROR;
@ -83,13 +102,9 @@ status_t s6a_config_apply()
#define HSS_IDENTITY "hss.localdomain"
#define HSS_REALM "localdomain"
#define HSS_PORT 30868
#define HSS_SECURE_PORT 30869
#define MME_IDENTITY "mme.localdomain"
#define MME_REALM "localdomain"
#define MME_PORT DIAMETER_PORT
#define MME_SECURE_PORT DIAMETER_SECURE_PORT
static int s6a_common_config(void)
{
@ -115,10 +130,14 @@ char *s6a_hss_config()
s6a_config->cnf_diamid = HSS_IDENTITY;
s6a_config->cnf_diamrlm = HSS_REALM;
s6a_config->cnf_port = HSS_PORT;
s6a_config->cnf_port_tls = HSS_SECURE_PORT;
s6a_config->cnf_addr = "10.1.35.214";
#if 0
s6a_config->cnf_port = DIAMETER_PORT;
s6a_config->cnf_port_tls = DIAMETER_SECURE_PORT;
#endif
s6a_config->pi_diamid = MME_IDENTITY;
s6a_config->pic_port = MME_PORT;
s6a_config->pi_addr = "10.1.35.215";
s6a_config->pic_port = DIAMETER_PORT;
rv = file_stat(&file_info, conffile, FILE_INFO_TYPE);
if (rv == CORE_OK && file_info.filetype == FILE_REG)
@ -139,8 +158,14 @@ char *s6a_mme_config()
s6a_config->cnf_diamid = MME_IDENTITY;
s6a_config->cnf_diamrlm = MME_REALM;
s6a_config->cnf_addr = "10.1.35.215";
#if 0
s6a_config->cnf_port = DIAMETER_PORT;
s6a_config->cnf_port_tls = DIAMETER_SECURE_PORT;
#endif
s6a_config->pi_diamid = HSS_IDENTITY;
s6a_config->pic_port = HSS_PORT;
s6a_config->pi_addr = "10.1.35.214";
s6a_config->pic_port = DIAMETER_PORT;
rv = file_stat(&file_info, conffile, FILE_INFO_TYPE);
if (rv == CORE_OK && file_info.filetype == FILE_REG)

View File

@ -15,7 +15,7 @@ status_t s6a_config_apply();
int s6a_fd_init(const char *conffile)
{
int ret;
gnutls_global_set_log_function(s6a_gnutls_log_func);
gnutls_global_set_log_level(TRACE_MODULE);

View File

@ -51,6 +51,8 @@ struct s6a_config_t {
char *cnf_diamid;
/* Diameter realm of the local peer, default to realm part of cnf_diamid */
char *cnf_diamrlm;
/* IP address of the local peer */
char *cnf_addr;
/* the local port for legacy Diameter (default: 3868) in host byte order */
c_uint16_t cnf_port;
@ -60,6 +62,7 @@ struct s6a_config_t {
/* (supposedly) UTF-8, \0 terminated.
* The Diameter Identity of the remote peer. */
char *pi_diamid;
char *pi_addr; /* IP address of the remote peer */
c_uint16_t pic_port; /* port to connect to. 0: default. */
int mode; /* default MODE_MME | MODE_HSS */

View File

@ -5,6 +5,8 @@
#include <mongoc.h>
#include "s6a_lib.h"
#include "context.h"
#include "hss_context.h"
@ -47,6 +49,239 @@ status_t hss_context_final(void)
return CORE_OK;
}
static status_t hss_context_prepare()
{
self.mme_s6a_port = DIAMETER_PORT;
self.mme_s6a_tls_port = DIAMETER_SECURE_PORT;
self.hss_s6a_port = DIAMETER_PORT;
self.hss_s6a_tls_port = DIAMETER_SECURE_PORT;
return CORE_OK;
}
static status_t hss_context_validation()
{
if (self.s6a_config_path == NULL)
{
if (self.hss_s6a_addr == NULL)
{
d_error("No HSS.S6A_CONFIG_PATH or HSS.NETWORK.S6A_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.mme_s6a_addr == NULL)
{
d_error("No HSS.S6A_CONFIG_PATH or MME.NETWORK.S6A_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
}
return CORE_OK;
}
status_t hss_context_parse_config()
{
status_t rv;
config_t *config = &context_self()->config;
char *json = config->json;
jsmntok_t *token = config->token;
typedef enum {
START, ROOT,
HSS_START, HSS_ROOT,
MME_START, MME_ROOT,
SKIP, STOP
} parse_state;
parse_state state = START;
parse_state stack = STOP;
size_t root_tokens = 0;
size_t hss_tokens = 0;
size_t mme_tokens = 0;
size_t skip_tokens = 0;
int i, j, m, n;
int arr, size;
rv = hss_context_prepare();
if (rv != CORE_OK) return rv;
for (i = 0, j = 1; j > 0; i++, j--)
{
jsmntok_t *t = &token[i];
j += t->size;
switch (state)
{
case START:
{
state = ROOT;
root_tokens = t->size;
break;
}
case ROOT:
{
if (jsmntok_equal(json, t, "HSS") == 0)
{
state = HSS_START;
}
else if (jsmntok_equal(json, t, "MME") == 0)
{
state = MME_START;
}
else
{
state = SKIP;
stack = ROOT;
skip_tokens = t->size;
root_tokens--;
if (root_tokens == 0) state = STOP;
}
break;
}
case HSS_START:
{
state = HSS_ROOT;
hss_tokens = t->size;
break;
}
case HSS_ROOT:
{
if (jsmntok_equal(json, t, "S6A_CONFIG_PATH") == 0)
{
self.s6a_config_path = jsmntok_to_string(json, t+1);
}
else if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S6A_ADDR") == 0)
{
self.hss_s6a_addr =
jsmntok_to_string(json, t+m+1);
}
else if (jsmntok_equal(json, t+m, "S6A_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.hss_s6a_port = atoi(v);
}
else if (jsmntok_equal(
json, t+m, "S6A_TLS_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.hss_s6a_tls_port = atoi(v);
}
}
}
}
state = SKIP;
stack = HSS_ROOT;
skip_tokens = t->size;
hss_tokens--;
if (hss_tokens == 0) stack = ROOT;
break;
}
case MME_START:
{
state = MME_ROOT;
mme_tokens = t->size;
break;
}
case MME_ROOT:
{
if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S6A_ADDR") == 0)
{
self.mme_s6a_addr =
jsmntok_to_string(json, t+m+1);
}
else if (jsmntok_equal(json, t+m, "S6A_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.mme_s6a_port = atoi(v);
}
else if (jsmntok_equal(
json, t+m, "S6A_TLS_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.mme_s6a_tls_port = atoi(v);
}
}
}
}
state = SKIP;
stack = MME_ROOT;
skip_tokens = t->size;
mme_tokens--;
if (mme_tokens == 0) stack = ROOT;
break;
}
case SKIP:
{
skip_tokens += t->size;
skip_tokens--;
if (skip_tokens == 0) state = stack;
break;
}
case STOP:
{
break;
}
default:
{
d_error("Failed to parse configuration in the state(%u)",
state);
break;
}
}
}
rv = hss_context_validation();
if (rv != CORE_OK) return rv;
return CORE_OK;
}
status_t hss_db_init()
{
if (context_self()->db_client && context_self()->db_name)

View File

@ -47,6 +47,14 @@ typedef struct _hss_db_subscription_data_t {
} hss_db_subscription_data_t;
typedef struct _hss_context_t {
char* s6a_config_path; /* HSS S6A Configuration File Path */
char* hss_s6a_addr; /* HSS S6A local address (STIRNG)*/
c_uint16_t hss_s6a_port; /* HSS S6A local port */
c_uint16_t hss_s6a_tls_port; /* HSS S6A local TLS port */
char* mme_s6a_addr; /* HSS S6A local address (STIRNG)*/
c_uint16_t mme_s6a_port; /* HSS S6A local port */
c_uint16_t mme_s6a_tls_port; /* HSS S6A local TLS port */
void *subscriberCollection;
mutex_id db_lock;
} hss_context_t;
@ -55,6 +63,8 @@ CORE_DECLARE(status_t) hss_context_init(void);
CORE_DECLARE(status_t) hss_context_final(void);
CORE_DECLARE(hss_context_t*) hss_self(void);
CORE_DECLARE(status_t) hss_context_parse_config(void);
CORE_DECLARE(status_t) hss_db_init(void);
CORE_DECLARE(status_t) hss_db_final(void);

View File

@ -1,20 +1,18 @@
#define TRACE_MODULE _hss_init
#include "s6a_lib.h"
#include "hss_context.h"
#include "hss_s6a_handler.h"
status_t hss_initialize(void)
{
status_t rv;
int ret;
ret = s6a_init(MODE_HSS);
if (ret != 0) return CORE_ERROR;
rv = hss_context_init();
if (rv != CORE_OK) return rv;
rv = hss_context_parse_config();
if (rv != CORE_OK) return rv;
rv = hss_db_init();
if (rv != CORE_OK) return rv;
@ -29,7 +27,6 @@ void hss_terminate(void)
hss_s6a_final();
hss_db_final();
hss_context_final();
s6a_final();
return;
}

View File

@ -486,6 +486,10 @@ out:
status_t hss_s6a_init(void)
{
struct disp_when data;
int ret;
ret = s6a_init(MODE_HSS);
if (ret != 0) return CORE_ERROR;
memset(&data, 0, sizeof(data));
data.app = s6a_appli;
@ -518,4 +522,6 @@ void hss_s6a_final(void)
if (hdl_ulr) {
(void) fd_disp_unregister(&hdl_ulr, NULL);
}
s6a_final();
}

View File

@ -6,6 +6,7 @@
#include "gtp_path.h"
#include "s1ap_message.h"
#include "s6a_lib.h"
#include "context.h"
#include "nas_conv.h"
@ -63,10 +64,50 @@ status_t mme_context_init()
return CORE_OK;
}
status_t mme_context_final()
{
d_assert(context_initialized == 1, return CORE_ERROR,
"MME context already has been finalized");
mme_sgw_remove_all();
mme_enb_remove_all();
d_assert(self.mme_ue_s1ap_id_hash, , "Null param");
hash_destroy(self.mme_ue_s1ap_id_hash);
d_assert(self.imsi_ue_hash, , "Null param");
hash_destroy(self.imsi_ue_hash);
d_assert(self.guti_ue_hash, , "Null param");
hash_destroy(self.guti_ue_hash);
pool_final(&mme_pdn_pool);
index_final(&mme_bearer_pool);
index_final(&mme_sess_pool);
index_final(&mme_ue_pool);
index_final(&enb_ue_pool);
index_final(&mme_enb_pool);
pool_final(&mme_sgw_pool);
context_initialized = 0;
return CORE_OK;
}
mme_context_t* mme_self()
{
return &self;
}
static status_t mme_context_prepare()
{
self.relative_capacity = 0xff;
self.mme_s6a_port = DIAMETER_PORT;
self.mme_s6a_tls_port = DIAMETER_SECURE_PORT;
self.hss_s6a_port = DIAMETER_PORT;
self.hss_s6a_tls_port = DIAMETER_SECURE_PORT;
self.s1ap_port = S1AP_SCTP_PORT;
self.s11_port = GTPV2_C_UDP_PORT;
@ -75,6 +116,21 @@ static status_t mme_context_prepare()
static status_t mme_context_validation()
{
if (self.s6a_config_path == NULL)
{
if (self.mme_s6a_addr == NULL)
{
d_error("No MME.S6A_CONFIG_PATH or MME.NETWORK.S6A_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
if (self.hss_s6a_addr == NULL)
{
d_error("No MME.S6A_CONFIG_PATH or HSS.NETWORK.S6A_ADDR in '%s'",
context_self()->config.path);
return CORE_ERROR;
}
}
if (self.s1ap_addr == 0)
{
d_error("No MME.NEWORK.S1AP_ADDR in '%s'",
@ -167,6 +223,7 @@ status_t mme_context_parse_config()
typedef enum {
START, ROOT,
HSS_START, HSS_ROOT,
MME_START, MME_ROOT,
SGW_START, SGW_ROOT,
SKIP, STOP
@ -175,6 +232,7 @@ status_t mme_context_parse_config()
parse_state stack = STOP;
size_t root_tokens = 0;
size_t hss_tokens = 0;
size_t mme_tokens = 0;
size_t sgw_tokens = 0;
size_t skip_tokens = 0;
@ -201,7 +259,11 @@ status_t mme_context_parse_config()
}
case ROOT:
{
if (jsmntok_equal(json, t, "MME") == 0)
if (jsmntok_equal(json, t, "HSS") == 0)
{
state = HSS_START;
}
else if (jsmntok_equal(json, t, "MME") == 0)
{
state = MME_START;
}
@ -221,6 +283,59 @@ status_t mme_context_parse_config()
break;
}
case HSS_START:
{
state = HSS_ROOT;
hss_tokens = t->size;
break;
}
case HSS_ROOT:
{
if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
size = 1;
if ((t+1)->type == JSMN_ARRAY)
{
m = 2;
}
for (arr = 0; arr < size; arr++)
{
for (n = 1; n > 0; m++, n--)
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S6A_ADDR") == 0)
{
self.hss_s6a_addr =
jsmntok_to_string(json, t+m+1);
}
else if (jsmntok_equal(json, t+m, "S6A_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.hss_s6a_port = atoi(v);
}
else if (jsmntok_equal(
json, t+m, "S6A_TLS_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.hss_s6a_tls_port = atoi(v);
}
}
}
}
state = SKIP;
stack = HSS_ROOT;
skip_tokens = t->size;
hss_tokens--;
if (hss_tokens == 0) stack = ROOT;
break;
}
case MME_START:
{
state = MME_ROOT;
@ -235,6 +350,10 @@ status_t mme_context_parse_config()
char *v = jsmntok_to_string(json, t+1);
if (v) self.relative_capacity = atoi(v);
}
else if (jsmntok_equal(json, t, "S6A_CONFIG_PATH") == 0)
{
self.s6a_config_path = jsmntok_to_string(json, t+1);
}
else if (jsmntok_equal(json, t, "NETWORK") == 0)
{
m = 1;
@ -251,7 +370,23 @@ status_t mme_context_parse_config()
{
n += (t+m)->size;
if (jsmntok_equal(json, t+m, "S1AP_ADDR") == 0)
if (jsmntok_equal(json, t+m, "S6A_ADDR") == 0)
{
self.mme_s6a_addr =
jsmntok_to_string(json, t+m+1);
}
else if (jsmntok_equal(json, t+m, "S6A_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.mme_s6a_port = atoi(v);
}
else if (jsmntok_equal(
json, t+m, "S6A_TLS_PORT") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.mme_s6a_tls_port = atoi(v);
}
else if (jsmntok_equal(json, t+m, "S1AP_ADDR") == 0)
{
char *v = jsmntok_to_string(json, t+m+1);
if (v) self.s1ap_addr = inet_addr(v);
@ -644,42 +779,6 @@ status_t mme_context_parse_config()
return CORE_OK;
}
status_t mme_context_final()
{
d_assert(context_initialized == 1, return CORE_ERROR,
"MME context already has been finalized");
mme_sgw_remove_all();
mme_enb_remove_all();
d_assert(self.mme_ue_s1ap_id_hash, , "Null param");
hash_destroy(self.mme_ue_s1ap_id_hash);
d_assert(self.imsi_ue_hash, , "Null param");
hash_destroy(self.imsi_ue_hash);
d_assert(self.guti_ue_hash, , "Null param");
hash_destroy(self.guti_ue_hash);
pool_final(&mme_pdn_pool);
index_final(&mme_bearer_pool);
index_final(&mme_sess_pool);
index_final(&mme_ue_pool);
index_final(&enb_ue_pool);
index_final(&mme_enb_pool);
pool_final(&mme_sgw_pool);
context_initialized = 0;
return CORE_OK;
}
mme_context_t* mme_self()
{
return &self;
}
mme_sgw_t* mme_sgw_add()
{
mme_sgw_t *sgw = NULL;

View File

@ -40,6 +40,14 @@ typedef struct _served_gummei {
} served_gummei_t;
typedef struct _mme_context_t {
char* s6a_config_path; /* MME S6A Configuration File Path */
char* mme_s6a_addr; /* MME S6A local address (STIRNG)*/
c_uint16_t mme_s6a_port; /* MME S6A local port */
c_uint16_t mme_s6a_tls_port; /* MME S6A local TLS port */
char* hss_s6a_addr; /* HSS S6A local address (STIRNG)*/
c_uint16_t hss_s6a_port; /* HSS S6A local port */
c_uint16_t hss_s6a_tls_port; /* HSS S6A local TLS port */
c_uint32_t s1ap_addr; /* MME S1AP local address */
c_uint16_t s1ap_port; /* MME S1AP local port */
net_sock_t *s1ap_sock; /* MME S1AP local listen socket */
@ -268,10 +276,11 @@ typedef struct _mme_bearer_t {
} mme_bearer_t;
CORE_DECLARE(status_t) mme_context_init(void);
CORE_DECLARE(status_t) mme_context_parse_config(void);
CORE_DECLARE(status_t) mme_context_final(void);
CORE_DECLARE(mme_context_t*) mme_self(void);
CORE_DECLARE(status_t) mme_context_parse_config(void);
CORE_DECLARE(mme_sgw_t*) mme_sgw_add(void);
CORE_DECLARE(status_t) mme_sgw_remove(mme_sgw_t *sgw);
CORE_DECLARE(status_t) mme_sgw_remove_all(void);

View File

@ -1,5 +1,6 @@
#!/bin/sh
ifconfig eth1:hss 10.1.35.214/24 up
ifconfig eth1:mme 10.1.35.215/24 up
ifconfig eth1:sgw_s5 10.1.35.216/24 up
ifconfig eth1:sgw_s11 10.1.35.217/24 up

View File

@ -1,5 +1,6 @@
#!/bin/sh
ifconfig en0 alias 10.1.35.214 netmask 255.255.255.255
ifconfig en0 alias 10.1.35.215 netmask 255.255.255.255
ifconfig en0 alias 10.1.35.216 netmask 255.255.255.255
ifconfig en0 alias 10.1.35.217 netmask 255.255.255.255

View File

@ -4,18 +4,23 @@
HSS :
{
S6A_CONFIG_PATH : "@prefix@/etc/hss_fd.conf"
#S6A_CONFIG_PATH : "@prefix@/etc/hss_fd.conf",
NETWORK :
{
S6A_ADDR : "10.1.35.214"
}
}
MME :
{
S6A_CONFIG_PATH : "@prefix@/etc/mme_fd.conf",
#S6A_CONFIG_PATH : "@prefix@/etc/mme_fd.conf",
DEFAULT_PAGING_DRX : "v64",
#RELATIVE_CAPACITY : 255,
NETWORK :
{
S6A_ADDR : "10.1.35.215",
S1AP_ADDR : "10.1.35.215",
S11_ADDR: "10.1.35.215",
}