Navigation


Changeset 1425:b09f1b4c9fad in freeDiameter


Ignore:
Timestamp:
Feb 19, 2020, 8:26:29 AM (4 years ago)
Author:
Luke Mewburn <luke@mewburn.net>
Branch:
default
Phase:
public
committer:
Luke Mewburn <luke@mewburn.net> 1582068430 -39600
Message:

fd_msg_add_result: add function

Add fd_msg_add_result() as a superset of fd_msg_rescode_set()
to allow setting of either Result-Code or Experimental-Result (Grouped),
depending upon whether the supplied vendor is 0 or not.

Reimplement fd_msg_rescode_set() in terms of fd_msg_add_result().

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • include/freeDiameter/libfdcore.h

    r1397 r1425  
    553553
    554554/*
     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 */
     576int 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/*
    555579 * FUNCTION:    fd_msg_rescode_set
    556580 *
     
    562586 *  type_id     : 0 => nothing; 1 => adds Origin-Host and Origin-Realm with local info. 2=> adds Error-Reporting-Host.
    563587 *
    564  * DESCRIPTION: 
    565  *   This function adds a Result-Code AVP to a message, and optionally
     588 * DESCRIPTION:
     589 *  This function adds a Result-Code AVP to a message, and optionally
    566590 *  - sets the 'E' error flag in the header,
    567591 *  - 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.
    572597 */
    573598int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id );
  • libfdcore/messages.c

    r1383 r1425  
    4343static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */
    4444static struct dict_object * dict_avp_RC  = NULL; /* Result-Code */
     45static struct dict_object * dict_avp_ER  = NULL; /* Experimental-Result */
     46static struct dict_object * dict_avp_VI  = NULL; /* Vendor-Id */
     47static struct dict_object * dict_avp_ERC = NULL; /* Experimental-Result-Code */
    4548struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */
    4649struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */
     
    6467        CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT)  );
    6568        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)  );
    6672
    6773        CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause",   &fd_dict_avp_DC , ENOENT)  );
     
    167173
    168174
    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 */
     176int 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 )
    171177{
    172178        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;
    177179        uint32_t rc_val = 0;
    178180        int set_e_bit=0;
    179181        int std_err_msg=0;
    180182
    181         TRACE_ENTRY("%p %s %p %p %d", msg, rescode, errormsg, optavp, type_id);
    182 
    183         CHECK_PARAMS(  msg && rescode  );
     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  );
    184186
    185187        /* Find the enum value corresponding to the rescode string, this will give the class of error */
    186188        {
    187189                struct dict_object * enum_obj = NULL;
     190
     191                /* Search in the restype */
    188192                struct dict_enumval_request req;
    189193                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;
    193195
    194196                /* Now search for the value given as parameter */
     
    208210        }
    209211
    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        }
    220260
    221261        if (type_id == 2) {
    222262                /* Add the Error-Reporting-Host AVP */
    223 
     263                struct avp * avp_ERH = NULL;
    224264                CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) );
    225265
     
    232272                /* Add it to the message */
    233273                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 */
    238277        if (optavp) {
     278                struct avp * avp_FAVP= NULL;
    239279                struct avp * optavp_cpy = NULL;
    240280                struct avp_hdr *opt_hdr, *optcpy_hdr;
     
    310350        if (std_err_msg || errormsg) {
    311351                /* Add the Error-Message AVP */
    312 
     352                struct avp * avp_EM  = NULL;
    313353                CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) );
    314354
     
    330370
    331371        return 0;
     372}
     373
     374int 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);
    332379}
    333380
  • tests/testmesg.c

    r1423 r1425  
    283283                        CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Application test", &application, ENOENT ) );
    284284                        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);
    285290                }
    286291               
     
    317322                        CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) );
    318323                }
    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
    320337                #if 0
    321338                {
     
    14781495        }
    14791496
     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
    14801588        /* Check IPv4 -> IPv6 and IPv6->IPv4 mapping */
    14811589        {
Note: See TracChangeset for help on using the changeset viewer.