Skip to content

Commit

Permalink
aaa_diameter: extend avps file to allow custom vendors
Browse files Browse the repository at this point in the history
  • Loading branch information
razvancrainea committed May 8, 2023
1 parent 1ebf1ee commit 008b861
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 19 deletions.
34 changes: 27 additions & 7 deletions modules/aaa_diameter/aaa_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,17 @@ static int dm_avps2json(void *root, cJSON *avps)

FD_CHECK_GT(fd_msg_avp_hdr(it, &h));

FD_CHECK_GT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE,
&h->avp_code, &obj, ENOENT));
if (h->avp_flags & AVP_FLAG_VENDOR) {
struct dict_avp_request ar;
memset(&ar, 0, sizeof ar);
ar.avp_code = h->avp_code;
ar.avp_vendor = h->avp_vendor;
FD_CHECK_GT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE_AND_VENDOR,
&ar, &obj, ENOENT));
} else {
FD_CHECK_GT(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE,
&h->avp_code, &obj, ENOENT));
}
FD_CHECK_GT(fd_dict_getval(obj, &dm_avp));

item = cJSON_CreateObject();
Expand All @@ -256,7 +265,7 @@ static int dm_avps2json(void *root, cJSON *avps)
goto out;
}

if (dm_avps2json(&it, val) != 0) {
if (dm_avps2json(it, val) != 0) {
cJSON_Delete(val);
LM_ERR("failed to encode Grouped AVP as JSON string (AVP: %s, code: %u)\n",
dm_avp.avp_name, dm_avp.avp_code);
Expand Down Expand Up @@ -432,6 +441,7 @@ static int dm_custom_cmd_reply(struct msg **_msg, struct avp * avp, struct sessi
int dm_register_callbacks(void)
{
struct disp_when data;
struct dict_object *vendor_dict;

/* accounting */
{
Expand Down Expand Up @@ -474,16 +484,26 @@ int dm_register_callbacks(void)
for (i = 0; i < n_app_ids; i++) {
/* Initialize the dictionary objects we use */
FD_CHECK_dict_search(DICT_APPLICATION, APPLICATION_BY_ID,
&app_ids[i], &data.app);
&app_defs[i].id, &data.app);

/* Register the dispatch callback */
FD_CHECK(fd_disp_register(dm_custom_cmd_reply,
DISP_HOW_APPID, &data, NULL, NULL));

if (app_defs[i].vendor != (unsigned int)-1) {
FD_CHECK_dict_search(DICT_VENDOR, VENDOR_BY_ID,
&app_defs[i].vendor, &vendor_dict);
} else {
vendor_dict = NULL;
}

/* Advertise support for the respective app */
FD_CHECK(fd_disp_app_support(data.app, NULL, 0, 1 ));
FD_CHECK(fd_disp_app_support(data.app,
vendor_dict,
(app_defs[i].auth?1:0),
(app_defs[i].auth?0:1)));

LM_DBG("registered a reply callback for App ID %d ...\n", app_ids[i]);
LM_DBG("registered a reply callback for App ID %d ...\n", app_defs[i].id);
}
}

Expand Down Expand Up @@ -1549,7 +1569,7 @@ int dm_build_avps(struct list_head *subavps, cJSON *array)
} else {
LM_DBG("AVP:: searching AVP by string: %s\n", avp->string);

FD_CHECK(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
FD_CHECK(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS,
avp->string, &obj, ENOENT));
FD_CHECK(fd_dict_getval(obj, &dm_avp));

Expand Down
127 changes: 117 additions & 10 deletions modules/aaa_diameter/app_opensips/avps.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ int parse_attr_def(char *line, FILE *fp)
{
struct dm_avp_def avps[128];
int avp_count = 0;
unsigned int vendor_id = -1;
size_t buflen = strlen(line);
int i, len = buflen, attr_len = strlen("ATTRIBUTE"), name_len, avp_code;
char *name, *nt_name, *newp, *p = line, *end = p + len;
Expand Down Expand Up @@ -617,6 +618,18 @@ int parse_attr_def(char *line, FILE *fp)
goto error;
}

/* skip over the type */
while (len > 0 && !isspace(*p)) { p++; len--; }

if (len > 0) {
vendor_id = strtol(p, &newp, 10);
if (vendor_id < 0)
goto error;

len -= newp - p;
p = newp;
}

if (avp_type != AVP_TYPE_GROUPED)
goto create_avp;

Expand Down Expand Up @@ -661,10 +674,10 @@ create_avp:;

struct dict_avp_data data = {
avp_code, /* Code */
0, /* Vendor */
(vendor_id != -1?vendor_id:0), /* Vendor */
nt_name, /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
(vendor_id != -1?AVP_FLAG_VENDOR:0)|AVP_FLAG_MANDATORY, /* Fixed flag values */
avp_type /* base type of data */
};

Expand All @@ -675,7 +688,7 @@ create_avp:;
(avps[i].pos == RULE_FIXED_HEAD), -1, avps[i].max_repeats};

FD_CHECK(fd_dict_search(fd_g_config->cnf_dict,
DICT_AVP, AVP_BY_NAME, avps[i].name, &data.rule_avp, 0));
DICT_AVP, AVP_BY_NAME_ALL_VENDORS, avps[i].name, &data.rule_avp, 0));

if (!data.rule_avp) {
printf("ERROR: failed to locate AVP: %s\n", avps[i].name);
Expand All @@ -685,8 +698,8 @@ create_avp:;
FD_CHECK_dict_new(DICT_RULE, &data, avp_ref, NULL);
}

LOG_DBG("registered custom AVP (%s, code %d, type %s, sub-avps: %d)\n",
nt_name, avp_code, avp_type2str(avp_type), avp_count);
LOG_DBG("registered custom AVP (%s, code %d, type %s, sub-avps: %d, vendor: %d)\n",
nt_name, avp_code, avp_type2str(avp_type), avp_count, vendor_id);

free(nt_name);
return 0;
Expand All @@ -695,13 +708,60 @@ create_avp:;
return -1;
}

int parse_app_vendor(char *line, FILE *fp)
{
unsigned int vendor_id = -1;
int len = strlen(line);
char *p = line, *newp, *vendor_name;

if (len < strlen("VENDOR") || memcmp(p, "VENDOR", 6))
return 1;

p += 6;
len -= 6;

while (isspace(*p)) { p++; len--; }

vendor_id = (unsigned int)strtoul(p, &newp, 10);
if (vendor_id < 0) {
printf("ERROR: bad Vendor ID: '... | %s'\n", p);
return -1;
}

len -= newp - p;
p = newp;

if (len <= 0) {
printf("ERROR: empty Vendor Name not allowed\n");
return -1;
}

vendor_name = p;
p += len - 1;

while (p > vendor_name && isspace(*p)) { p--; }
*(++p) = '\0';

struct dict_vendor_data vendor_reg = {vendor_id, vendor_name};
FD_CHECK_dict_new(DICT_VENDOR, &vendor_reg, NULL, NULL);

LOG_DBG("registered Vendor %d (%s)\n", vendor_id, vendor_name);

return 1;
}


struct _app_defs app_defs[64];
unsigned int n_app_ids;

unsigned int app_ids[64], n_app_ids;
int parse_app_def(char *line, FILE *fp)
{
unsigned int app_id = -1;
unsigned int vendor_id = -1;
unsigned char is_auth = 0;
int i, len = strlen(line);
char *p = line, *newp, *app_name;
struct dict_object *vendor_dict;

if (n_app_ids >= 64) {
printf("ERROR: max allowed Applications reached (64)\n");
Expand All @@ -716,6 +776,20 @@ int parse_app_def(char *line, FILE *fp)

while (isspace(*p)) { p++; len--; }

if (len >= strlen("-AUTH") && memcmp(p, "-AUTH", 5) == 0) {
is_auth = 1;

p += 5;
len -= 5;
while (isspace(*p)) { p++; len--; }
} else if (len >= strlen("-ACC") && memcmp(p, "-ACC", 4) == 0) {
is_auth = 0;

p += 4;
len -= 4;
while (isspace(*p)) { p++; len--; }
}

app_id = (unsigned int)strtoul(p, &newp, 10);
if (app_id < 0) {
printf("ERROR: bad Application ID: '... | %s'\n", p);
Expand All @@ -726,6 +800,29 @@ int parse_app_def(char *line, FILE *fp)
p = newp;

while (isspace(*p)) { p++; len--; }
if (*p == '/') {

/* Vendor ID is specified as well */
p++;
len--;
while (isspace(*p)) { p++; len--; }

vendor_id = (unsigned int)strtoul(p, &newp, 10);
if (vendor_id < 0) {
printf("ERROR: bad Vendor ID: '... | %s'\n", p);
return -1;
}

len -= newp - p;
p = newp;

while (isspace(*p)) { p++; len--; }

FD_CHECK_dict_search(DICT_VENDOR, VENDOR_BY_ID,
&vendor_id, &vendor_dict);
} else {
vendor_dict = NULL;
}

if (len <= 0) {
printf("ERROR: empty Application Name not allowed\n");
Expand All @@ -739,16 +836,18 @@ int parse_app_def(char *line, FILE *fp)
*(++p) = '\0';

struct dict_application_data app_reg = {app_id, app_name};
FD_CHECK_dict_new(DICT_APPLICATION, &app_reg, NULL, NULL);
FD_CHECK_dict_new(DICT_APPLICATION, &app_reg, vendor_dict, NULL);

LOG_DBG("registered Application %d (%s)\n", app_id, app_name);

/* store the App ID so OpenSIPS can register a reply cb later */
for (i = 0; i < n_app_ids; i++)
if (app_ids[i] == app_id)
if (app_defs[i].id == app_id)
return 1;

app_ids[n_app_ids++] = app_id;
app_defs[n_app_ids].auth = is_auth;
app_defs[n_app_ids].vendor = vendor_id;
app_defs[n_app_ids++].id = app_id;
return 1;
}

Expand Down Expand Up @@ -852,7 +951,7 @@ int parse_command_def(char *line, FILE *fp, int cmd_type)
(avps[i].pos == RULE_FIXED_HEAD), -1, avps[i].max_repeats};

FD_CHECK(fd_dict_search(fd_g_config->cnf_dict,
DICT_AVP, AVP_BY_NAME, avps[i].name, &data.rule_avp, 0));
DICT_AVP, AVP_BY_NAME_ALL_VENDORS, avps[i].name, &data.rule_avp, 0));

if (!data.rule_avp) {
printf("ERROR: failed to locate AVP: %s\n", avps[i].name);
Expand Down Expand Up @@ -921,6 +1020,14 @@ int parse_extra_avps(const char *extra_avps_file)
if (*p == '#' || p - line >= read)
continue;

rc = parse_app_vendor(p, fp);
if (rc < 0) {
ret = -1;
goto out;
} else if (rc == 0) {
continue;
}

rc = parse_attr_def(p, fp);
if (rc < 0) {
ret = -1;
Expand Down
7 changes: 6 additions & 1 deletion modules/aaa_diameter/app_opensips/avps.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@
int register_osips_avps(void);
int parse_extra_avps(const char *extra_avps_file);

extern unsigned int app_ids[];
struct _app_defs {
unsigned int id;
unsigned int vendor;
unsigned char auth;
};
extern struct _app_defs app_defs[];
extern unsigned int n_app_ids;

#endif /* _APP_OPENSIPS_AVPS_H */
2 changes: 1 addition & 1 deletion modules/aaa_diameter/peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ static int dm_pack_avps(void *root, struct list_head *subavps)
dm_avp = list_entry(it, struct dm_avp, list);

/* each AVP must be recognized, otherwise we abort the request */
FD_CHECK_dict_search(DICT_AVP, AVP_BY_NAME, dm_avp->name.s, &obj);
FD_CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, dm_avp->name.s, &obj);
FD_CHECK(fd_msg_avp_new(obj, 0, &subavp));
FD_CHECK(fd_dict_getval(obj, &savp_data));

Expand Down

0 comments on commit 008b861

Please sign in to comment.