Changeset 1425:b09f1b4c9fad in freeDiameter
- Timestamp:
- Feb 19, 2020, 8:26:29 AM (4 years ago)
- Branch:
- default
- Phase:
- public
- committer:
- Luke Mewburn <luke@mewburn.net> 1582068430 -39600
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
include/freeDiameter/libfdcore.h
r1397 r1425 553 553 554 554 /* 555 * FUNCTION: fd_msg_add_result 556 * 557 * PARAMETERS: 558 * msg : A msg object -- it must be an answer. 559 * vendor : Vendor. If 0, add Result-Code else add Experimental-Result. 560 * restype : DICT_TYPE containing rescode (ex: from TYPE_BY_NAME "Enumerated(Result-Code)"). 561 * rescode : The name of the returned error code (ex: "DIAMETER_INVALID_AVP"). 562 * errormsg : (optional) human-readable error message to put in Error-Message AVP. 563 * optavp : (optional) If provided, the content will be put inside a Failed-AVP. 564 * type_id : 0 => nothing; 1 => adds Origin-Host and Origin-Realm with local info. 2=> adds Error-Reporting-Host. 565 * 566 * DESCRIPTION: 567 * This function adds a Result-Code AVP (if vendor is 0) or Experimental-Result AVP (vendor is not 0) 568 * to a message, and optionally 569 * - sets the 'E' error flag in the header, 570 * - adds Error-Message, Error-Reporting-Host and Failed-AVP AVPs. 571 * 572 * RETURN VALUE: 573 * 0 : Operation complete. 574 * !0 : an error occurred. 575 */ 576 int fd_msg_add_result( struct msg * msg, vendor_id_t vendor, struct dict_object * restype, char * rescode, char * errormsg, struct avp * optavp, int type_id ); 577 578 /* 555 579 * FUNCTION: fd_msg_rescode_set 556 580 * … … 562 586 * type_id : 0 => nothing; 1 => adds Origin-Host and Origin-Realm with local info. 2=> adds Error-Reporting-Host. 563 587 * 564 * DESCRIPTION: 565 * 588 * DESCRIPTION: 589 * This function adds a Result-Code AVP to a message, and optionally 566 590 * - sets the 'E' error flag in the header, 567 591 * - adds Error-Message, Error-Reporting-Host and Failed-AVP AVPs. 568 * 569 * RETURN VALUE: 570 * 0 : Operation complete. 571 * !0 : an error occurred. 592 * Uses fd_msg_add_result with vendor 0 and restype for Enumerated(Result-Code). 593 * 594 * RETURN VALUE: 595 * 0 : Operation complete. 596 * !0 : an error occurred. 572 597 */ 573 598 int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ); -
libfdcore/messages.c
r1383 r1425 43 43 static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */ 44 44 static struct dict_object * dict_avp_RC = NULL; /* Result-Code */ 45 static struct dict_object * dict_avp_ER = NULL; /* Experimental-Result */ 46 static struct dict_object * dict_avp_VI = NULL; /* Vendor-Id */ 47 static struct dict_object * dict_avp_ERC = NULL; /* Experimental-Result-Code */ 45 48 struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */ 46 49 struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */ … … 64 67 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT) ); 65 68 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &dict_avp_FAVP, ENOENT) ); 69 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result", &dict_avp_ER, ENOENT) ); 70 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Id", &dict_avp_VI, ENOENT) ); 71 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &dict_avp_ERC, ENOENT) ); 66 72 67 73 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", &fd_dict_avp_DC , ENOENT) ); … … 167 173 168 174 169 /* Add Result-Code and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */170 int fd_msg_ rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id )175 /* Add Result-Code or Experimental-Result, and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */ 176 int fd_msg_add_result( struct msg * msg, vendor_id_t vendor, struct dict_object * restype, char * rescode, char * errormsg, struct avp * optavp, int type_id ) 171 177 { 172 178 union avp_value val; 173 struct avp * avp_RC = NULL;174 struct avp * avp_EM = NULL;175 struct avp * avp_ERH = NULL;176 struct avp * avp_FAVP= NULL;177 179 uint32_t rc_val = 0; 178 180 int set_e_bit=0; 179 181 int std_err_msg=0; 180 182 181 TRACE_ENTRY("%p % s %p %p %d", msg, rescode, errormsg, optavp, type_id);182 183 CHECK_PARAMS( msg && res code );183 TRACE_ENTRY("%p %d %p %s %p %p %d", msg, vendor, restype, rescode, errormsg, optavp, type_id); 184 185 CHECK_PARAMS( msg && restype && rescode ); 184 186 185 187 /* Find the enum value corresponding to the rescode string, this will give the class of error */ 186 188 { 187 189 struct dict_object * enum_obj = NULL; 190 191 /* Search in the restype */ 188 192 struct dict_enumval_request req; 189 193 memset(&req, 0, sizeof(struct dict_enumval_request)); 190 191 /* First, get the enumerated type of the Result-Code AVP (this is fast, no need to cache the object) */ 192 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &(req.type_obj), ENOENT ) ); 194 req.type_obj = restype; 193 195 194 196 /* Now search for the value given as parameter */ … … 208 210 } 209 211 210 /* Create the Result-Code AVP */ 211 CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) ); 212 213 /* Set its value */ 214 memset(&val, 0, sizeof(val)); 215 val.u32 = rc_val; 216 CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) ); 217 218 /* Add it to the message */ 219 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) ); 212 if (vendor == 0) { 213 /* Vendor 0; create the Result-Code AVP */ 214 struct avp * avp_RC = NULL; 215 CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) ); 216 217 /* Set its value */ 218 memset(&val, 0, sizeof(val)); 219 val.u32 = rc_val; 220 CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) ); 221 222 /* Add it to the message */ 223 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) ); 224 } else { 225 /* Vendor !0; create the Experimental-Result AVP */ 226 struct avp * avp_ER = NULL; 227 CHECK_FCT( fd_msg_avp_new( dict_avp_ER, 0, &avp_ER ) ); 228 229 /* Create the Vendor-Id AVP and add to Experimental-Result */ 230 { 231 struct avp * avp_VI = NULL; 232 CHECK_FCT( fd_msg_avp_new( dict_avp_VI, 0, &avp_VI ) ); 233 234 /* Set Vendor-Id value to vendor */ 235 memset(&val, 0, sizeof(val)); 236 val.u32 = vendor; 237 CHECK_FCT( fd_msg_avp_setvalue( avp_VI, &val ) ); 238 239 /* Add it to Experimental-Result */ 240 CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_VI ) ); 241 } 242 243 /* Create the Experimental-Result-Code AVP and add to Experimental-Result */ 244 { 245 struct avp * avp_ERC = NULL; 246 CHECK_FCT( fd_msg_avp_new( dict_avp_ERC, 0, &avp_ERC ) ); 247 248 /* Set Experimental-Result-Code value to rc_val */ 249 memset(&val, 0, sizeof(val)); 250 val.u32 = rc_val; 251 CHECK_FCT( fd_msg_avp_setvalue( avp_ERC, &val ) ); 252 253 /* Add it to Experimental-Result */ 254 CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_ERC ) ); 255 } 256 257 /* Add it to the message */ 258 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ER ) ); 259 } 220 260 221 261 if (type_id == 2) { 222 262 /* Add the Error-Reporting-Host AVP */ 223 263 struct avp * avp_ERH = NULL; 224 264 CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) ); 225 265 … … 232 272 /* Add it to the message */ 233 273 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ERH ) ); 234 235 } 236 237 /* Now add the optavp in a FailedAVP if provided */ 274 } 275 276 /* Now add the optavp in a Failed-AVP if provided */ 238 277 if (optavp) { 278 struct avp * avp_FAVP= NULL; 239 279 struct avp * optavp_cpy = NULL; 240 280 struct avp_hdr *opt_hdr, *optcpy_hdr; … … 310 350 if (std_err_msg || errormsg) { 311 351 /* Add the Error-Message AVP */ 312 352 struct avp * avp_EM = NULL; 313 353 CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) ); 314 354 … … 330 370 331 371 return 0; 372 } 373 374 int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ) 375 { 376 struct dict_object * restype = NULL; 377 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &restype, ENOENT ) ); 378 return fd_msg_add_result(msg, 0, restype, rescode, errormsg, optavp, type_id); 332 379 } 333 380 -
tests/testmesg.c
r1423 r1425 283 283 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Application test", &application, ENOENT ) ); 284 284 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_COMMAND, &cmd_data , application, &command ) ); 285 ADD_RULE(command, 0, "Session-Id", RULE_FIXED_HEAD, 1, 1, 1); 286 ADD_RULE(command, 0, "Result-Code", RULE_OPTIONAL, 0, 1, 0); 287 ADD_RULE(command, 0, "Experimental-Result", RULE_OPTIONAL, 0, 1, 0); 288 ADD_RULE(command, 0, "Origin-Host", RULE_REQUIRED, 1, 1, 0); 289 ADD_RULE(command, 0, "Origin-Realm", RULE_REQUIRED, 1, 1, 0); 285 290 } 286 291 … … 317 322 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); 318 323 } 319 324 325 { 326 struct dict_object * type = NULL; 327 struct dict_type_data type_data = { AVP_TYPE_UNSIGNED32, "Enumerated(73565/Experimental-Result-Code)" }; 328 struct dict_avp_data avp_data = { 73576, 73565, "Experimental-Result-Code", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_UNSIGNED32 }; 329 struct dict_enumval_data val1 = { "DIAMETER_TEST_RESULT_1000", { .u32 = 1000 } }; 330 struct dict_enumval_data val2 = { "DIAMETER_TEST_RESULT_5000", { .u32 = 5000 } }; 331 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) ); 332 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) ); 333 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val1 , type, NULL ) ); 334 CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_ENUMVAL, &val2 , type, NULL ) ); 335 } 336 320 337 #if 0 321 338 { … … 1478 1495 } 1479 1496 1497 /* Test the fd_msg_add_result function for Result-Code */ 1498 { 1499 struct msg * msg = NULL; 1500 struct dict_object * avp_model = NULL; 1501 struct avp * rc = NULL; 1502 struct avp_hdr * avpdata = NULL; 1503 1504 { 1505 struct dict_object * cmd_model = NULL; 1506 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Test-Command-Answer", &cmd_model, ENOENT ) ); 1507 1508 /* Create a message */ 1509 CHECK( 0, fd_msg_new ( cmd_model, 0, &msg ) ); 1510 1511 /* Add a session id */ 1512 CHECK( 0, fd_msg_new_session( msg, (os0_t)"tm2", strlen("tm2") ) ); 1513 1514 /* Find the DICT_TYPE Enumerated(Result-Code) */ 1515 struct dict_object * restype = NULL; 1516 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)", &restype, ENOENT ) ); 1517 1518 /* Now test the behavior of fd_msg_add_result for Result-Code AVP */ 1519 CHECK( 0, fd_msg_add_result(msg, 0, restype, "DIAMETER_SUCCESS", NULL, NULL, 1) ); 1520 1521 LOG_D("%s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, msg, fd_g_config->cnf_dict, 0, 1)); 1522 } 1523 1524 /* Ensure Result-Code is present */ 1525 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &avp_model, ENOENT ) ); 1526 CHECK( 0, fd_msg_search_avp( msg, avp_model, &rc ) ); 1527 1528 /* Check the Result-Code AVP value is DIAMETER_SUCCESS */ 1529 CHECK( 0, fd_msg_avp_hdr ( rc, &avpdata ) ); 1530 CHECK( ER_DIAMETER_SUCCESS, avpdata->avp_value->u32 ); 1531 1532 /* Ensure Experimental-Result is missing */ 1533 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result", &avp_model, ENOENT ) ); 1534 CHECK( ENOENT, fd_msg_search_avp( msg, avp_model, NULL ) ); 1535 1536 /* Free msg */ 1537 CHECK( 0, fd_msg_free( msg ) ); 1538 } 1539 1540 /* Test the fd_msg_add_result function for Experimental-Result */ 1541 { 1542 struct msg * msg = NULL; 1543 struct dict_object * avp_model = NULL; 1544 struct avp * er = NULL; 1545 struct avp * erc = NULL; 1546 struct avp_hdr * avpdata = NULL; 1547 1548 { 1549 struct dict_object * cmd_model = NULL; 1550 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Test-Command-Answer", &cmd_model, ENOENT ) ); 1551 1552 /* Create a message */ 1553 CHECK( 0, fd_msg_new ( cmd_model, 0, &msg ) ); 1554 1555 /* Add a session id */ 1556 CHECK( 0, fd_msg_new_session( msg, (os0_t)"tm2", strlen("tm2") ) ); 1557 1558 /* Find the DICT_TYPE Enumerated(73565/Experimental-Result-Code) */ 1559 struct dict_object * restype = NULL; 1560 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_BY_NAME, "Enumerated(73565/Experimental-Result-Code)", &restype, ENOENT ) ); 1561 1562 /* Now test the behavior of fd_msg_add_result for Experimental-Result AVP */ 1563 CHECK( 0, fd_msg_add_result(msg, 73565, restype, "DIAMETER_TEST_RESULT_5000", NULL, NULL, 1) ); 1564 1565 LOG_D("%s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, msg, fd_g_config->cnf_dict, 0, 1)); 1566 } 1567 1568 /* Ensure Result-Code is missing */ 1569 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &avp_model, ENOENT ) ); 1570 CHECK( ENOENT, fd_msg_search_avp( msg, avp_model, NULL ) ); 1571 1572 /* Ensure Experimental-Result is present */ 1573 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result", &avp_model, ENOENT ) ); 1574 CHECK( 0, fd_msg_search_avp( msg, avp_model, &er ) ); 1575 1576 /* Ensure Experimental-Result-Code is present */ 1577 CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &avp_model, ENOENT ) ); 1578 CHECK( 0, fd_msg_search_avp( er, avp_model, &erc ) ); 1579 1580 /* Check the Experimental-Result-Code AVP value is 5000 */ 1581 CHECK( 0, fd_msg_avp_hdr ( erc, &avpdata ) ); 1582 CHECK( 5000, avpdata->avp_value->u32 ); 1583 1584 /* Free msg */ 1585 CHECK( 0, fd_msg_free( msg ) ); 1586 } 1587 1480 1588 /* Check IPv4 -> IPv6 and IPv6->IPv4 mapping */ 1481 1589 {
Note: See TracChangeset
for help on using the changeset viewer.