Changeset 658:f198d16fa7f4 in freeDiameter for libfdproto/dictionary.c
- Timestamp:
- Jan 14, 2011, 3:15:23 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
libfdproto/dictionary.c
r602 r658 34 34 *********************************************************************************************************/ 35 35 36 #include " libfD.h"36 #include "fdproto-internal.h" 37 37 38 38 /* Names of the base types */ … … 323 323 obj->objeyec, OBJECT_EYECATCHER, 324 324 obj->typeyec, _OBINFO(obj).eyecatcher); 325 } else { 326 TRACE_DEBUG(FULL, "Invalid object : NULL pointer"); 325 327 } 326 328 return 0; … … 552 554 } 553 555 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) */ 555 557 static int order_rule_by_avpn ( struct dict_object *o1, struct dict_object *o2 ) 556 558 { 557 559 TRACE_ENTRY("%p %p", o1, o2); 558 560 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) ; 560 563 } 561 564 … … 1496 1499 struct dict_object * new = NULL; 1497 1500 struct dict_object * vendor = NULL; 1501 struct dict_object * locref = NULL; 1498 1502 1499 1503 TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref); … … 1525 1529 if (type == DICT_AVP) { 1526 1530 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; } ); 1528 1532 1529 1533 /* Also check if a parent is provided, that the type are the same */ … … 1568 1572 case DICT_VENDOR: 1569 1573 /* 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; 1572 1577 break; 1573 1578 1574 1579 case DICT_APPLICATION: 1575 1580 /* 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; 1578 1584 break; 1579 1585 1580 1586 case DICT_TYPE: 1581 1587 /* 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; 1584 1591 break; 1585 1592 1586 1593 case DICT_ENUMVAL: 1587 1594 /* 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 } 1592 1604 break; 1593 1605 1594 1606 case DICT_AVP: 1595 1607 /* 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 } 1600 1617 break; 1601 1618 1602 1619 case DICT_COMMAND: 1603 1620 /* 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 } 1608 1630 break; 1609 1631 1610 1632 case DICT_RULE: 1611 1633 /* 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; 1614 1637 break; 1615 1638 … … 1632 1655 error_unlock: 1633 1656 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 1634 1806 error_free: 1635 1807 free(new);
Note: See TracChangeset
for help on using the changeset viewer.