Navigation


Changeset 658:f198d16fa7f4 in freeDiameter for libfdproto/dictionary.c


Ignore:
Timestamp:
Jan 14, 2011, 3:15:23 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Initial commit for 1.1.0:

  • Restructuring:
    • libfreeDiameter:
      • renamed folder & binary into libfdproto
      • renamed libfD.h into fdproto-internal.h
      • removed signals management (replaced by triggers in libfdcore)
  • freeDiameter split into:
    • libfdcore (most contents)
      • renamed fD.h into fdcore-internal.h
      • added core.c for framework init/shutdown.
      • new triggers mechanism in events.c.
  • freeDiameterd (main, command line parsing, signals management)
  • tests:
    • now in top-level directory tests.
  • other changes:
    • fd_dict_new now returns 0 on duplicate identical entries.
    • fixes in dict_legacy_xml
    • fixes in some dictionaries
    • moved FD_DEFAULT_CONF_FILENAME definition to freeDiameter-host.h
File:
1 moved

Legend:

Unmodified
Added
Removed
  • libfdproto/dictionary.c

    r602 r658  
    3434*********************************************************************************************************/
    3535
    36 #include "libfD.h"
     36#include "fdproto-internal.h"
    3737
    3838/* Names of the base types */
     
    323323                                                obj->objeyec, OBJECT_EYECATCHER,
    324324                                                obj->typeyec, _OBINFO(obj).eyecatcher);
     325                        } else {
     326                                TRACE_DEBUG(FULL, "Invalid object : NULL pointer");
    325327                        }
    326328                        return 0;
     
    552554}
    553555
    554 /* Compare two rule object by the AVP name that they refer (checks already performed) */
     556/* Compare two rule object by the AVP vendor & code that they refer (checks already performed) */
    555557static int order_rule_by_avpn ( struct dict_object *o1, struct dict_object *o2 )
    556558{
    557559        TRACE_ENTRY("%p %p", o1, o2);
    558560       
    559         return strcmp( o1->data.rule.rule_avp->data.avp.avp_name, o2->data.rule.rule_avp->data.avp.avp_name );
     561        return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor)
     562                ?: ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_code, o2->data.rule.rule_avp->data.avp.avp_code) ;
    560563}
    561564
     
    14961499        struct dict_object * new = NULL;
    14971500        struct dict_object * vendor = NULL;
     1501        struct dict_object * locref = NULL;
    14981502       
    14991503        TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref);
     
    15251529        if (type == DICT_AVP) {
    15261530                CHECK_FCT_DO(  fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ),
    1527                                 CHECK_PARAMS( vendor = NULL )  );
     1531                        { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); return EINVAL; }  );
    15281532               
    15291533                /* Also check if a parent is provided, that the type are the same */
     
    15681572                case DICT_VENDOR:
    15691573                        /* A vendor object is linked in the g_dict_vendors.list[0], by their id */
    1570                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &dict->dict_vendors.list[0], &new->list[0], (int (*)(void*, void *))order_vendor_by_id, (void **)ref ),
    1571                                         goto error_unlock  );
     1574                        ret = fd_list_insert_ordered ( &dict->dict_vendors.list[0], &new->list[0], (int (*)(void*, void *))order_vendor_by_id, (void **)&locref );
     1575                        if (ret)
     1576                                goto error_unlock;
    15721577                        break;
    15731578               
    15741579                case DICT_APPLICATION:
    15751580                        /* An application object is linked in the g_dict_applciations.list[0], by their id */
    1576                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &dict->dict_applications.list[0], &new->list[0], (int (*)(void*, void *))order_appli_by_id, (void **)ref ),
    1577                                         goto error_unlock  );
     1581                        ret = fd_list_insert_ordered ( &dict->dict_applications.list[0], &new->list[0], (int (*)(void*, void *))order_appli_by_id, (void **)&locref );
     1582                        if (ret)
     1583                                goto error_unlock;
    15781584                        break;
    15791585               
    15801586                case DICT_TYPE:
    15811587                        /* A type object is linked in g_list_types by its name */
    1582                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &dict->dict_types, &new->list[0], (int (*)(void*, void *))order_type_by_name, (void **)ref ),
    1583                                         goto error_unlock  );
     1588                        ret = fd_list_insert_ordered ( &dict->dict_types, &new->list[0], (int (*)(void*, void *))order_type_by_name, (void **)&locref );
     1589                        if (ret)
     1590                                goto error_unlock;
    15841591                        break;
    15851592               
    15861593                case DICT_ENUMVAL:
    15871594                        /* A type_enum object is linked in it's parent 'type' object lists 1 and 2 by its name and values */
    1588                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &parent->list[1], &new->list[0], (int (*)(void*, void *))order_enum_by_name, (void **)ref ),
    1589                                         goto error_unlock  );
    1590                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &parent->list[2], &new->list[1], (int (*)(void*, void *))order_enum_by_val, (void **)ref ),
    1591                                         { fd_list_unlink(&new->list[0]); goto error_unlock; }  );
     1595                        ret = fd_list_insert_ordered ( &parent->list[1], &new->list[0], (int (*)(void*, void *))order_enum_by_name, (void **)&locref );
     1596                        if (ret)
     1597                                goto error_unlock;
     1598                       
     1599                        ret = fd_list_insert_ordered ( &parent->list[2], &new->list[1], (int (*)(void*, void *))order_enum_by_val, (void **)&locref );
     1600                        if (ret) {
     1601                                fd_list_unlink(&new->list[0]);
     1602                                goto error_unlock;
     1603                        }
    15921604                        break;
    15931605               
    15941606                case DICT_AVP:
    15951607                        /* An avp object is linked in lists 1 and 2 of its vendor, by code and name */
    1596                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &vendor->list[1], &new->list[0], (int (*)(void*, void *))order_avp_by_code, (void **)ref ),
    1597                                         goto error_unlock  );
    1598                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &vendor->list[2], &new->list[1], (int (*)(void*, void *))order_avp_by_name, (void **)ref ),
    1599                                         { fd_list_unlink(&new->list[0]); goto error_unlock; }  );
     1608                        ret = fd_list_insert_ordered ( &vendor->list[1], &new->list[0], (int (*)(void*, void *))order_avp_by_code, (void **)&locref );
     1609                        if (ret)
     1610                                goto error_unlock;
     1611                       
     1612                        ret = fd_list_insert_ordered ( &vendor->list[2], &new->list[1], (int (*)(void*, void *))order_avp_by_name, (void **)&locref );
     1613                        if (ret) {
     1614                                fd_list_unlink(&new->list[0]);
     1615                                goto error_unlock;
     1616                        }
    16001617                        break;
    16011618                       
    16021619                case DICT_COMMAND:
    16031620                        /* A command object is linked in g_list_cmd_name and g_list_cmd_code by its name and code */
    1604                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &dict->dict_cmd_code, &new->list[1], (int (*)(void*, void *))order_cmd_by_codefl, (void **)ref ),
    1605                                         goto error_unlock  );
    1606                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &dict->dict_cmd_name, &new->list[0], (int (*)(void*, void *))order_cmd_by_name, (void **)ref ),
    1607                                         { fd_list_unlink(&new->list[1]); goto error_unlock; }  );
     1621                        ret = fd_list_insert_ordered ( &dict->dict_cmd_code, &new->list[1], (int (*)(void*, void *))order_cmd_by_codefl, (void **)&locref );
     1622                        if (ret)
     1623                                goto error_unlock;
     1624                       
     1625                        ret = fd_list_insert_ordered ( &dict->dict_cmd_name, &new->list[0], (int (*)(void*, void *))order_cmd_by_name, (void **)&locref );
     1626                        if (ret) {
     1627                                fd_list_unlink(&new->list[1]);
     1628                                goto error_unlock;
     1629                        }
    16081630                        break;
    16091631               
    16101632                case DICT_RULE:
    16111633                        /* A rule object is linked in list[2] of its parent command or AVP by the name of the AVP it refers */
    1612                         CHECK_FCT_DO(  ret = fd_list_insert_ordered ( &parent->list[2], &new->list[0], (int (*)(void*, void *))order_rule_by_avpn, (void **)ref ),
    1613                                         goto error_unlock  );
     1634                        ret = fd_list_insert_ordered ( &parent->list[2], &new->list[0], (int (*)(void*, void *))order_rule_by_avpn, (void **)&locref );
     1635                        if (ret)
     1636                                goto error_unlock;
    16141637                        break;
    16151638                       
     
    16321655error_unlock:
    16331656        CHECK_POSIX_DO(  pthread_rwlock_unlock(&dict->dict_lock),  /* continue */  );
     1657        if (ret == EEXIST) {
     1658                /* We have a duplicate key in locref. Check if the pointed object is the same or not */
     1659                switch (type) {
     1660                        case DICT_VENDOR:
     1661                                /* if we are here, it meas the two vendor id are identical */
     1662                                if (strcmp(locref->data.vendor.vendor_name, new->data.vendor.vendor_name)) {
     1663                                        TRACE_DEBUG(FULL, "Conflicting vendor name");
     1664                                        break;
     1665                                }
     1666                                /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */
     1667                                ret = 0;
     1668                                break;
     1669
     1670                        case DICT_APPLICATION:
     1671                                /* got same id */
     1672                                if (strcmp(locref->data.application.application_name, new->data.application.application_name)) {
     1673                                        TRACE_DEBUG(FULL, "Conflicting application name");
     1674                                        break;
     1675                                }
     1676                                ret = 0;
     1677                                break;
     1678
     1679                        case DICT_TYPE:
     1680                                /* got same name */
     1681                                if (locref->data.type.type_base != new->data.type.type_base) {
     1682                                        TRACE_DEBUG(FULL, "Conflicting base type");
     1683                                        break;
     1684                                }
     1685                                /* discard new definition only it a callback is provided and different from the previous one */
     1686                                if ((new->data.type.type_interpret) && (locref->data.type.type_interpret != new->data.type.type_interpret)) {
     1687                                        TRACE_DEBUG(FULL, "Conflicting interpret cb");
     1688                                        break;
     1689                                }
     1690                                if ((new->data.type.type_encode) && (locref->data.type.type_encode != new->data.type.type_encode)) {
     1691                                        TRACE_DEBUG(FULL, "Conflicting encode cb");
     1692                                        break;
     1693                                }
     1694                                if ((new->data.type.type_dump) && (locref->data.type.type_dump != new->data.type.type_dump)) {
     1695                                        TRACE_DEBUG(FULL, "Conflicting dump cb");
     1696                                        break;
     1697                                }
     1698                                ret = 0;
     1699                                break;
     1700
     1701                        case DICT_ENUMVAL:
     1702                                /* got either same name or same value. We check that both are true */
     1703                                if (order_enum_by_name(locref, new)) {
     1704                                        TRACE_DEBUG(FULL, "Conflicting enum name");
     1705                                        break;
     1706                                }
     1707                                if (order_enum_by_val(locref, new)) {
     1708                                        TRACE_DEBUG(FULL, "Conflicting enum value");
     1709                                        break;
     1710                                }
     1711                                ret = 0;
     1712                                break;
     1713
     1714                        case DICT_AVP:
     1715                                /* got either same name or code */
     1716                                if (order_avp_by_code(locref, new)) {
     1717                                        TRACE_DEBUG(FULL, "Conflicting AVP code");
     1718                                        break;
     1719                                }
     1720                                if (order_avp_by_name(locref, new)) {
     1721                                        TRACE_DEBUG(FULL, "Conflicting AVP name");
     1722                                        break;
     1723                                }
     1724                                if  (locref->data.avp.avp_vendor != new->data.avp.avp_vendor) {
     1725                                        TRACE_DEBUG(FULL, "Conflicting AVP vendor");
     1726                                        break;
     1727                                }
     1728                                if  (locref->data.avp.avp_flag_mask != new->data.avp.avp_flag_mask) {
     1729                                        TRACE_DEBUG(FULL, "Conflicting AVP flags mask");
     1730                                        break;
     1731                                }
     1732                                if  ((locref->data.avp.avp_flag_val & locref->data.avp.avp_flag_mask) != (new->data.avp.avp_flag_val & new->data.avp.avp_flag_mask)) {
     1733                                        TRACE_DEBUG(FULL, "Conflicting AVP flags value");
     1734                                        break;
     1735                                }
     1736                                if  (locref->data.avp.avp_basetype != new->data.avp.avp_basetype) {
     1737                                        TRACE_DEBUG(FULL, "Conflicting AVP base type");
     1738                                        break;
     1739                                }
     1740                                ret = 0;
     1741                                break;
     1742
     1743                        case DICT_COMMAND:
     1744                                /* We got either same name, or same code + R flag */
     1745                                if (order_cmd_by_name(locref, new)) {
     1746                                        TRACE_DEBUG(FULL, "Conflicting command name");
     1747                                        break;
     1748                                }
     1749                                if (locref->data.cmd.cmd_code != new->data.cmd.cmd_code) {
     1750                                        TRACE_DEBUG(FULL, "Conflicting command code");
     1751                                        break;
     1752                                }
     1753                                if (locref->data.cmd.cmd_flag_mask != new->data.cmd.cmd_flag_mask) {
     1754                                        TRACE_DEBUG(FULL, "Conflicting command flags mask %hhx:%hhx", locref->data.cmd.cmd_flag_mask, new->data.cmd.cmd_flag_mask);
     1755                                        break;
     1756                                }
     1757                                if ((locref->data.cmd.cmd_flag_val & locref->data.cmd.cmd_flag_mask) != (new->data.cmd.cmd_flag_val & new->data.cmd.cmd_flag_mask)) {
     1758                                        TRACE_DEBUG(FULL, "Conflicting command flags value");
     1759                                        break;
     1760                                }
     1761                                ret = 0;
     1762                                break;
     1763
     1764                        case DICT_RULE:
     1765                                /* Both rules point to the same AVPs */
     1766                                if (locref->data.rule.rule_position != new->data.rule.rule_position) {
     1767                                        TRACE_DEBUG(FULL, "Conflicting rule position");
     1768                                        break;
     1769                                }
     1770                                if ( ((locref->data.rule.rule_position == RULE_FIXED_HEAD) ||
     1771                                        (locref->data.rule.rule_position == RULE_FIXED_TAIL))
     1772                                    && (locref->data.rule.rule_order != new->data.rule.rule_order)) {
     1773                                        TRACE_DEBUG(FULL, "Conflicting rule order");
     1774                                        break;
     1775                                }
     1776                                if (locref->data.rule.rule_min != new->data.rule.rule_min) {
     1777                                        int r1 = locref->data.rule.rule_min;
     1778                                        int r2 = new->data.rule.rule_min;
     1779                                        int p  = locref->data.rule.rule_position;
     1780                                        if (  ((r1 != -1) && (r2 != -1)) /* none of the definitions contains the "default" value */
     1781                                           || ((p == RULE_OPTIONAL) && (r1 != 0) && (r2 != 0)) /* the other value is not 0 for an optional rule */
     1782                                           || ((r1 != 1) && (r2 != 1)) /* the other value is not 1 for another rule */
     1783                                        ) {
     1784                                                TRACE_DEBUG(FULL, "Conflicting rule min");
     1785                                                break;
     1786                                        }
     1787                                }
     1788                                if (locref->data.rule.rule_max != new->data.rule.rule_max) {
     1789                                        TRACE_DEBUG(FULL, "Conflicting rule max");
     1790                                        break;
     1791                                }
     1792                                ret = 0;
     1793                                break;
     1794                }
     1795                if (ret) {
     1796                        TRACE_DEBUG(INFO, "An existing object with different non-key data was found: EEXIST");
     1797                } else {
     1798                        TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error...");
     1799                }
     1800                if (ref)
     1801                        *ref = locref;
     1802        } else {
     1803                CHECK_FCT_DO( ret, ); /* log the error */
     1804        }
     1805
    16341806error_free:
    16351807        free(new);
Note: See TracChangeset for help on using the changeset viewer.