Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for include/freeDiameter/libfdproto.h


Ignore:
Timestamp:
Feb 9, 2011, 3:26:58 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • include/freeDiameter/libfdproto.h

    r705 r706  
    4545 *      DEBUG
    4646 *      MACROS
     47 *      OCTET STRINGS
    4748 *      THREADS
    4849 *      LISTS
     
    567568#endif /* BUFSIZ */
    568569
     570/* This gives the length of a const string */
     571#define CONSTSTRLEN( str ) (sizeof(str) - 1)
     572
     573
     574/*============================================================*/
     575/*                         BINARY STRINGS                     */
     576/*============================================================*/
     577
     578/* Compute a hash value of a binary string.
     579The hash must remain local to this machine, there is no guarantee that same input
     580will give same output on a different system (endianness) */
     581uint32_t fd_os_hash ( uint8_t * string, size_t len );
     582
     583/* This type used for binary strings that contain no \0 except as their last character.
     584It means some string operations can be used on it. */
     585typedef uint8_t * os0_t;
     586
     587/* Same as strdup but for os0_t strings */
     588os0_t os0dup_int(os0_t s, size_t l);
     589#define os0dup( _s, _l)  (void *)os0dup_int((os0_t)(_s), _l)
     590
     591/* Check that an octet string value can be used as os0_t */
     592static __inline__ int fd_os_is_valid_os0(uint8_t * os, size_t oslen) {
     593        /* The only situation where it is not valid is when it contains a \0 inside the octet string */
     594        return (memchr(os, '\0', oslen) == NULL);
     595}
     596
     597/* The following type denotes a verified DiameterIdentity value (that contains only pure letters, digits, hyphen, dot) */
     598typedef char * DiamId_t;
     599
     600/* Maximum length of a hostname we accept */
     601#ifndef HOST_NAME_MAX
     602#define HOST_NAME_MAX 512
     603#endif /* HOST_NAME_MAX */
     604
     605/* Check if a binary string contains a valid Diameter Identity value.
     606  rfc3588 states explicitely that such a Diameter Identity consists only of ASCII characters. */
     607int fd_os_is_valid_DiameterIdentity(uint8_t * os, size_t ossz);
     608
     609/* This checks a string is a valid DiameterIdentity and applies IDNA transformations otherwise (xn--...) */
     610int fd_os_validate_DiameterIdentity(char ** id, size_t * outsz, int memory /* 0: *id can be realloc'd. 1: *id must be malloc'd on output (was static) */ );
     611
     612/* Create an order relationship for binary strings (not needed to be \0 terminated).
     613   It does NOT mimic strings relationships so that it is more efficient. It is case sensitive.
     614   (the strings are actually first ordered by their lengh, then by their bytes contents)
     615   returns: -1 if os1 < os2;  +1 if os1 > os2;  0 if they are equal */
     616int fd_os_cmp_int(os0_t os1, size_t os1sz, os0_t os2, size_t os2sz);
     617#define fd_os_cmp(_o1, _l1, _o2, _l2)  fd_os_cmp_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2)
     618
     619/* A roughly case-insensitive variant, which actually only compares ASCII chars (0-127) in a case-insentitive maneer
     620  -- this should be OK with (old) DNS names. Not sure how it works with IDN...
     621  -- it also clearly does not support locales where a lowercase letter uses more space than upper case, such as ß -> ss
     622 It is slower than fd_os_cmp...
     623 This function should give the same order as fd_os_cmp, except when it finds 2 strings to be equal.
     624 Note that the result is NOT the same as strcasecmp !!!
     625 */
     626int fd_os_almostcasecmp_int(uint8_t * os1, size_t os1sz, uint8_t * os2, size_t os2sz);
     627#define fd_os_almostcasecmp(_o1, _l1, _o2, _l2)  fd_os_almostcasecmp_int((os0_t)(_o1), _l1, (os0_t)(_o2), _l2)
    569628
    570629
     
    602661}
    603662
    604 /* Force flushing the cache of a CPU before reading a shared memory area (use only for atomic reads such as int and void*) */
    605 extern pthread_mutex_t fd_cpu_mtx_dummy; /* only for the macro bellow, so that we have reasonably fresh pir_state value when needed */
    606 #define fd_cpu_flush_cache() {                          \
    607         (void)pthread_mutex_lock(&fd_cpu_mtx_dummy);    \
    608         (void)pthread_mutex_unlock(&fd_cpu_mtx_dummy);  \
    609 }
    610 
    611663
    612664/*************
     
    673725
    674726
    675 /*============================================================*/
    676 /*                          HASH                              */
    677 /*============================================================*/
    678 
    679 /* Compute a hash value of a string (session id, diameter id, ...) */
    680 uint32_t fd_hash ( char * string, size_t len );
    681 
    682 
    683727
    684728/*============================================================*/
     
    802846struct dict_vendor_data {
    803847        vendor_id_t      vendor_id;     /* ID of a vendor */
    804         char            *vendor_name;   /* The name of this vendor */
     848        char *           vendor_name;   /* The name of this vendor */
    805849};
    806850
     
    808852enum {
    809853        VENDOR_BY_ID = 10,      /* "what" points to a vendor_id_t */
    810         VENDOR_BY_NAME,         /* "what" points to a string */
     854        VENDOR_BY_NAME,         /* "what" points to a char * */
    811855        VENDOR_OF_APPLICATION   /* "what" points to a struct dict_object containing an application (see bellow) */
    812856};
     
    872916struct dict_application_data {
    873917        application_id_t         application_id;        /* ID of the application */
    874         char                    *application_name;      /* The name of this application */
     918        char *                   application_name;      /* The name of this application */
    875919};
    876920
     
    878922enum {
    879923        APPLICATION_BY_ID = 20,         /* "what" points to a application_id_t */
    880         APPLICATION_BY_NAME,            /* "what" points to a string */
     924        APPLICATION_BY_NAME,            /* "what" points to a char * */
    881925        APPLICATION_OF_TYPE,            /* "what" points to a struct dict_object containing a type object (see bellow) */
    882926        APPLICATION_OF_COMMAND          /* "what" points to a struct dict_object containing a command (see bellow) */
     
    947991                uint8_t *data;  /* bytes buffer */
    948992                size_t   len;   /* length of the data buffer */
    949         }           os;         /* Storage for an octet string, data is alloc'd and must be freed */
     993        }           os;         /* Storage for an octet string */
    950994        int32_t     i32;        /* integer 32 */
    951995        int64_t     i64;        /* integer 64 */
     
    10111055struct dict_type_data {
    10121056        enum dict_avp_basetype   type_base;     /* How the data of such AVP must be interpreted */
    1013         char                    *type_name;     /* The name of this type */
     1057        char *                   type_name;     /* The name of this type */
    10141058        dict_avpdata_interpret   type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */
    10151059        dict_avpdata_encode      type_encode;   /* cb to convert formatted data into an AVP value (or NULL) */
     
    10191063/* The criteria for searching a type object in the dictionary */
    10201064enum {
    1021         TYPE_BY_NAME = 30,              /* "what" points to a string */
     1065        TYPE_BY_NAME = 30,              /* "what" points to a char * */
    10221066        TYPE_OF_ENUMVAL,                /* "what" points to a struct dict_object containing an enumerated constant (DICT_ENUMVAL, see bellow). */
    10231067        TYPE_OF_AVP                     /* "what" points to a struct dict_object containing an AVP object. */
     
    10681112/* Type to hold data of named constants for AVP */
    10691113struct dict_enumval_data {
    1070         char            *enum_name;     /* The name of this constant */
     1114        char *           enum_name;     /* The name of this constant */
    10711115        union avp_value  enum_value;    /* Value of the constant. Union term depends on parent type's base type. */
    10721116};
     
    10801124        /* Identifier of the parent type, one of the following must not be NULL */
    10811125        struct dict_object      *type_obj;
    1082         char                    *type_name;
     1126        char *                   type_name;
    10831127       
    10841128        /* Search criteria for the constant */
     
    11831227        avp_code_t               avp_code;      /* Code of the avp */
    11841228        vendor_id_t              avp_vendor;    /* Vendor of the AVP, or 0 */
    1185         char                    *avp_name;      /* Name of this AVP */
     1229        char *                   avp_name;      /* Name of this AVP */
    11861230        uint8_t                  avp_flag_mask; /* Mask of fixed AVP flags */
    11871231        uint8_t                  avp_flag_val;  /* Values of the fixed flags */
     
    11921236enum {
    11931237        AVP_BY_CODE = 50,       /* "what" points to an avp_code_t, vendor is always 0 */
    1194         AVP_BY_NAME,            /* "what" points to a string, vendor is always 0 */
     1238        AVP_BY_NAME,            /* "what" points to a char *, vendor is always 0 */
    11951239        AVP_BY_CODE_AND_VENDOR, /* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_code are set */
    11961240        AVP_BY_NAME_AND_VENDOR, /* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_name are set */
     
    12021246        vendor_id_t      avp_vendor;
    12031247        avp_code_t       avp_code;
    1204         char            *avp_name;
     1248        char *           avp_name;
    12051249};
    12061250
     
    13101354struct dict_cmd_data {
    13111355        command_code_t   cmd_code;      /* code of the command */
    1312         char            *cmd_name;      /* Name of the command */
     1356        char *           cmd_name;      /* Name of the command */
    13131357        uint8_t          cmd_flag_mask; /* Mask of fixed-value flags */
    13141358        uint8_t          cmd_flag_val;  /* values of the fixed flags */
     
    13171361/* The criteria for searching an avp object in the dictionary */
    13181362enum {
    1319         CMD_BY_NAME = 60,       /* "what" points to a string */
     1363        CMD_BY_NAME = 60,       /* "what" points to a char * */
    13201364        CMD_BY_CODE_R,          /* "what" points to a command_code_t. The "Request" command is returned. */
    13211365        CMD_BY_CODE_A,          /* "what" points to a command_code_t. The "Answer" command is returned. */
     
    15901634 *  ENOMEM      : Not enough memory to complete the operation
    15911635 */
    1592 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, char * sid, void * opaque), void * opaque );
     1636int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, os0_t sid, void * opaque), void * opaque );
    15931637/* Macro to avoid casting everywhere */
    15941638#define fd_sess_handler_create( _handler, _cleanup, _opaque ) \
    1595         fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, char *, void *))(_cleanup), (void *)(_opaque) )
     1639        fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), (void *)(_opaque) )
    15961640
    15971641       
     
    16211665 * PARAMETERS:
    16221666 *  session       : The location where the session object will be created upon success.
    1623  *  diamId        : \0-terminated string containing a Diameter Identity.
    1624  *  opt           : Additional string. Usage is described bellow.
     1667 *  diamid        : a Diameter Identity, or NULL.
     1668 *  diamidlen     : if diamid is \0-terminated, this can be 0. Otherwise, the length of diamid.
     1669 *  opt           : Additional string, or NULL. Usage is described bellow.
    16251670 *  optlen        : if opt is \0-terminated, this can be 0. Otherwise, the length of opt.
    16261671 *
     
    16391684 *  ENOMEM      : Not enough memory to complete the operation
    16401685 */
    1641 int fd_sess_new ( struct session ** session, char * diamId, char * opt, size_t optlen );
     1686int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen );
    16421687
    16431688/*
     
    16451690 *
    16461691 * PARAMETERS:
    1647  *  sid         : pointer to a string containing a Session-Id (UTF-8).
     1692 *  sid         : pointer to a string containing a Session-Id (should be UTF-8).
    16481693 *  len         : length of the sid string (which does not need to be '\0'-terminated)
    16491694 *  session     : On success, pointer to the session object created / retrieved.
     
    16591704 *  ENOMEM      : Not enough memory to complete the operation
    16601705 */
    1661 int fd_sess_fromsid ( char * sid, size_t len, struct session ** session, int * isnew);
     1706int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * isnew);
    16621707
    16631708/*
     
    16661711 * PARAMETERS:
    16671712 *  session     : Pointer to a session object.
    1668  *  sid         : On success, the location of a (\0-terminated) string is stored here.
     1713 *  sid         : On success, the location of the sid is stored here.
    16691714 *
    16701715 * DESCRIPTION:
    16711716 *   Retrieve the session identifier (Session-Id) corresponding to a session object.
    1672  *  The returned sid is an UTF-8 string terminated by \0, suitable for calls to strlen and strcpy.
     1717 *  The returned sid is a \0-terminated binary string which might be UTF-8 (but there is no guarantee in the framework).
    16731718 *  It may be used for example to set the value of an AVP.
    16741719 *  Note that the sid string is not copied, just its reference... do not free it!
    16751720 *
    16761721 * RETURN VALUE:
    1677  *  0           : The sid parameter has been updated.
    1678  *  EINVAL      : A parameter is invalid.
    1679  */
    1680 int fd_sess_getsid ( struct session * session, char ** sid );
     1722 *  0           : The sid & len parameters have been updated.
     1723 *  EINVAL      : A parameter is invalid.
     1724 */
     1725int fd_sess_getsid ( struct session * session, os0_t * sid, size_t * sidlen );
    16811726
    16821727/*
     
    17111756 *
    17121757 * DESCRIPTION:
    1713  *   Destroys a session an all associated data, if any.
     1758 *   Destroys all associated states of a session, if any.
    17141759 * Equivalent to a session timeout expired, but the effect is immediate.
     1760 * The session itself is marked as deleted, and will be freed when it is not referenced
     1761 * by any message anymore.
    17151762 *
    17161763 * RETURN VALUE:
     
    17271774 *
    17281775 * DESCRIPTION:
    1729  *   Destroys the resources of a session, only if no session_state is associated with it.
    1730  *
    1731  * RETURN VALUE:
    1732  *  0           : The session no longer exists.
     1776 *   Equivalent to fd_sess_destroy, only if no session_state is associated with the session.
     1777 *  Otherwise, this function has no effect (except that it sets *session to NULL).
     1778 *
     1779 * RETURN VALUE:
     1780 *  0           : The session was reclaimed.
    17331781 *  EINVAL      : A parameter is invalid.
    17341782 */
     
    18021850void fd_rtd_free(struct rt_data ** rtd);
    18031851
    1804 /* Add a peer to the candidates list */
    1805 int  fd_rtd_candidate_add(struct rt_data * rtd, char * peerid, char * realm);
    1806 
    1807 /* Remove a peer from the candidates (if it is found) */
    1808 void fd_rtd_candidate_del(struct rt_data * rtd, char * peerid, size_t sz /* if !0, peerid does not need to be \0 terminated */);
     1852/* Add a peer to the candidates list. */
     1853int  fd_rtd_candidate_add(struct rt_data * rtd, DiamId_t peerid, size_t peeridlen, DiamId_t realm, size_t realmlen);
     1854
     1855/* Remove a peer from the candidates (if it is found). The search is case-insensitive. */
     1856void fd_rtd_candidate_del(struct rt_data * rtd, uint8_t * id, size_t idsz);
    18091857
    18101858/* Extract the list of valid candidates, and initialize their scores to 0 */
     
    18121860
    18131861/* If a peer returned a protocol error for this message, save it so that we don't try to send it there again */
    1814 int  fd_rtd_error_add(struct rt_data * rtd, char * sentto, uint8_t * origin, size_t originsz, uint32_t rcode);
     1862int  fd_rtd_error_add(struct rt_data * rtd, DiamId_t sentto, size_t senttolen, uint8_t * origin, size_t originsz, uint32_t rcode);
    18151863
    18161864/* The extracted list items have the following structure: */
    18171865struct rtd_candidate {
    18181866        struct fd_list  chain;  /* link in the list returned by the previous fct */
    1819         char *          diamid; /* the diameter Id of the peer */
    1820         char *          realm;  /* the diameter realm of the peer (if known) */
     1867        DiamId_t        diamid; /* the diameter Id of the peer */
     1868        size_t          diamidlen; /* cached size of the diamid string */
     1869        DiamId_t        realm;  /* the diameter realm of the peer */
     1870        size_t          realmlen; /* cached size of realm */
    18211871        int             score;  /* the current routing score for this peer, see fd_rt_out_register definition for details */
    18221872};
    18231873
    1824 /* Reorder the list of peers */
     1874/* Reorder the list of peers by score */
    18251875int  fd_rtd_candidate_reorder(struct fd_list * candidates);
    18261876
     
    22392289 * PARAMETERS:
    22402290 *  msg         : A msg object.
    2241  *  diamid      : The diameter id of the peer from which this message was received.
     2291 *  diamid,len  : The diameter id of the peer from which this message was received.
    22422292 *  add_rr      : if true, a Route-Record AVP is added to the message with content diamid. In that case, dict must be supplied.
    22432293 *  dict        : a dictionary with definition of Route-Record AVP (if add_rr is true)
     
    22522302 *  !0          : an error occurred.
    22532303 */
    2254 int fd_msg_source_set( struct msg * msg, char * diamid, int add_rr, struct dictionary * dict );
    2255 int fd_msg_source_get( struct msg * msg, char ** diamid );
     2304int fd_msg_source_set( struct msg * msg, DiamId_t diamid, size_t diamidlen, int add_rr, struct dictionary * dict );
     2305int fd_msg_source_get( struct msg * msg, DiamId_t *diamid, size_t * diamidlen );
    22562306
    22572307/*
     
    23702420 *  ENOMEM      : Unable to allocate enough memory to create the buffer object.
    23712421 */
    2372 int fd_msg_bufferize ( struct msg * msg, unsigned char ** buffer, size_t * len );
     2422int fd_msg_bufferize ( struct msg * msg, uint8_t ** buffer, size_t * len );
    23732423
    23742424/*
     
    23922442 *  EINVAL      : A parameter is invalid.
    23932443 */
    2394 int fd_msg_parse_buffer ( unsigned char ** buffer, size_t buflen, struct msg ** msg );
     2444int fd_msg_parse_buffer ( uint8_t ** buffer, size_t buflen, struct msg ** msg );
    23952445
    23962446/* Parsing Error Information structure */
     
    26542704 *  session     : The session corresponding to this object, if any.
    26552705 *  action      : Upon return, the action that must be taken on the message
     2706 *  error_code  : Upon return with action == DISP_ACT_ERROR, contains the error (such as "DIAMETER_UNABLE_TO_COMPLY")
    26562707 *
    26572708 * DESCRIPTION:
     
    26662717 *  (other errors)
    26672718 */
    2668 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code );
     2719int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code );
    26692720
    26702721
Note: See TracChangeset for help on using the changeset viewer.