Navigation


Changeset 1092:e40374ddfeef in freeDiameter for libfdproto


Ignore:
Timestamp:
May 6, 2013, 12:30:34 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/messages.c

    r1085 r1092  
    8989        int                      avp_eyec;              /* Must be equal to MSG_AVP_EYEC */
    9090        struct dict_object      *avp_model;             /* If not NULL, pointer to the dictionary object of this avp */
     91        struct {
     92                avp_code_t       mnf_code;             
     93                vendor_id_t      mnf_vendor;           
     94        }                        avp_model_not_found;   /* When model resolution has failed, store a copy of the data here to avoid searching again */
    9195        struct avp_hdr           avp_public;            /* AVP data that can be managed by other modules */
    9296       
     
    113117        int                      msg_eyec;              /* Must be equal to MSG_MSG_EYEC */
    114118        struct dict_object      *msg_model;             /* If not NULL, pointer to the dictionary object of this message */
     119        struct {
     120                command_code_t   mnf_code;
     121                uint8_t          mnf_flags;             
     122        }                        msg_model_not_found;   /* When model resolution has failed, store a copy of the data here to avoid searching again */
    115123        struct msg_hdr           msg_public;            /* Message data that can be managed by extensions. */
    116124       
     
    347355        /* Add the Session-Id AVP if session is known */
    348356        if (sess && dict) {
    349                 struct dict_object * sess_id_avp;
     357                static struct dict_object * sess_id_avp = NULL;
    350358                os0_t sid;
    351359                size_t sidlen;
     
    353361                union avp_value val;
    354362               
    355                 CHECK_FCT( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT) );
     363                if (!sess_id_avp) {
     364                        CHECK_FCT( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT) );
     365                }
    356366                CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ) );
    357367                CHECK_FCT( fd_msg_avp_new ( sess_id_avp, 0, &avp ) );
     
    19691979        }
    19701980       
    1971         /* Now try and resolve the model from the avp code and vendor */
    1972         if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
    1973                 struct dict_avp_request_ex avpreq;
    1974                 memset(&avpreq, 0, sizeof(avpreq));
    1975                 avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor;
    1976                 avpreq.avp_data.avp_code = avp->avp_public.avp_code;
    1977                 CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0));
    1978         } else {
    1979                 /* no vendor */
    1980                 CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &avp->avp_public.avp_code, &avp->avp_model, 0));
     1981        /* Check if we already searched for this model without success */
     1982        if ((avp->avp_model_not_found.mnf_code != avp->avp_public.avp_code)
     1983        ||  (avp->avp_model_not_found.mnf_vendor != avp->avp_public.avp_vendor)) {
     1984       
     1985                /* Now try and resolve the model from the avp code and vendor */
     1986                if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
     1987                        struct dict_avp_request_ex avpreq;
     1988                        memset(&avpreq, 0, sizeof(avpreq));
     1989                        avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor;
     1990                        avpreq.avp_data.avp_code = avp->avp_public.avp_code;
     1991                        CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0));
     1992                } else {
     1993                        /* no vendor */
     1994                        CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &avp->avp_public.avp_code, &avp->avp_model, 0));
     1995                }
     1996               
     1997                if (!avp->avp_model) {
     1998                        avp->avp_model_not_found.mnf_code = avp->avp_public.avp_code;
     1999                        avp->avp_model_not_found.mnf_vendor = avp->avp_public.avp_vendor;
     2000                }
    19812001        }
    19822002       
     
    21432163        CHECK_PARAMS(  CHECK_MSG(msg)  );
    21442164       
     2165        /* First, check if we already have a model. */
     2166        if (msg->msg_model != NULL) {
     2167                /* Check if this model is still valid for the message data */
     2168                enum dict_object_type    dicttype;
     2169                struct dict_cmd_data     data;
     2170                ASSERT(((fd_dict_gettype(msg->msg_model, &dicttype) == 0) && (dicttype == DICT_COMMAND)));
     2171                (void)fd_dict_getval( msg->msg_model, &data);
     2172                if ((data.cmd_code != msg->msg_public.msg_code)
     2173                ||  ((data.cmd_flag_val & data.cmd_flag_mask) != (msg->msg_public.msg_flags && data.cmd_flag_mask))) {
     2174                        msg->msg_model = NULL;
     2175                } else {
     2176                        goto chain;
     2177                }
     2178        }
     2179       
     2180        /* Check if we already searched for this model without success */
     2181        if ((msg->msg_model_not_found.mnf_code == msg->msg_public.msg_code)
     2182        && (msg->msg_model_not_found.mnf_flags == msg->msg_public.msg_flags)) {
     2183                goto no_model;
     2184        } else {
     2185                msg->msg_model_not_found.mnf_code = 0;
     2186        }
     2187       
    21452188        /* Look for the model from the header */
    21462189        CHECK_FCT_DO( ret = fd_dict_search ( dict, DICT_COMMAND,
     
    21492192                        &msg->msg_model, ENOTSUP),
    21502193                {
    2151                         if ((ret == ENOTSUP) && (error_info)) {
    2152                                 error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED";
    2153                                 error_info->pei_protoerr = 1;
     2194                        if (ret == ENOTSUP) {
     2195                                /* update the model not found info */
     2196                                msg->msg_model_not_found.mnf_code = msg->msg_public.msg_code;
     2197                                msg->msg_model_not_found.mnf_flags = msg->msg_public.msg_flags;
     2198                                goto no_model;
    21542199                        }
    21552200                        return ret;
    21562201                } );
    2157        
     2202chain: 
    21582203        if (!only_hdr) {
    21592204                /* Then process the children */
     
    21682213       
    21692214        return ret;
     2215no_model:
     2216        if (error_info) {
     2217                error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED";
     2218                error_info->pei_protoerr = 1;
     2219        }
     2220        return ENOTSUP;
    21702221}
    21712222
Note: See TracChangeset for help on using the changeset viewer.