*/
#define CMP(_a, _b) CMP_PREFER_SMALLER(_a, _b)
+/*
+ * Callbacks which make comparisons easier.
+ */
+#define CMP_RETURN(_field) do { \
+ ret = CMP(a->_field, b->_field); \
+ if (ret != 0) return ret; \
+ } while (0)
+
/** Remove const qualification from a pointer
*
* @param[in] _type The non-const version of the type.
/*
* Functions for tracking files by inode
*/
-static int _inode_cmp(void const *a, void const *b)
+static int _inode_cmp(void const *one, void const *two)
{
- cf_file_t const *one = a, *two = b;
+ cf_file_t const *a = one, *b = two;
int ret;
- ret = (one->buf.st_dev < two->buf.st_dev) - (one->buf.st_dev > two->buf.st_dev);
- if (ret != 0) return ret;
+ CMP_RETURN(buf.st_dev);
- return (one->buf.st_ino < two->buf.st_ino) - (one->buf.st_ino > two->buf.st_ino);
+ return CMP(a->buf.st_ino, b->buf.st_ino);
}
static int cf_file_open(CONF_SECTION *cs, char const *filename, bool from_dir, FILE **fp_p)
static int8_t filename_cmp(void const *one, void const *two)
{
- int rcode;
+ int ret;
cf_file_heap_t const *a = one;
cf_file_heap_t const *b = two;
- rcode = strcmp(a->filename, b->filename);
- if (rcode < 0) return -1;
- if (rcode > 0) return +1;
- return 0;
+ ret = strcmp(a->filename, b->filename);
+ return CMP(ret, 0);
}
* For CONF_ITEM_SECTION this is 'name1'.
* For CONF_ITEM_DATA this is 'type'.
*
- * @param[in] a First CONF_ITEM to compare.
- * @param[in] b Second CONF_ITEM to compare.
- * @return
- * - >0 if a > b.
- * - <0 if a < b.
- * - 0 if a == b.
+ * @param[in] one First CONF_ITEM to compare.
+ * @param[in] two Second CONF_ITEM to compare.
+ * @return CMP(one, two)
*/
-static inline int _cf_ident1_cmp(void const *a, void const *b)
+static inline int _cf_ident1_cmp(void const *one, void const *two)
{
+ int ret;
+
CONF_ITEM_TYPE type;
{
- CONF_ITEM const *one = a;
- CONF_ITEM const *two = b;
+ CONF_ITEM const *a = one;
+ CONF_ITEM const *b = two;
- if (one->type > two->type) return +1;
- if (one->type < two->type) return -1;
-
- type = one->type;
+ CMP_RETURN(type);
+ type = a->type;
}
switch (type) {
case CONF_ITEM_PAIR:
{
- CONF_PAIR const *one = a;
- CONF_PAIR const *two = b;
+ CONF_PAIR const *a = one;
+ CONF_PAIR const *b = two;
- return strcmp(one->attr, two->attr);
+ return strcmp(a->attr, b->attr);
}
case CONF_ITEM_SECTION:
{
- CONF_SECTION const *one = a;
- CONF_SECTION const *two = b;
+ CONF_SECTION const *a = one;
+ CONF_SECTION const *b = two;
- return strcmp(one->name1, two->name1);
+ return strcmp(a->name1, b->name1);
}
case CONF_ITEM_DATA:
{
- CONF_DATA const *one = a;
- CONF_DATA const *two = b;
+ CONF_DATA const *a = one;
+ CONF_DATA const *b = two;
- return strcmp(one->type, two->type);
+ return strcmp(a->type, b->type);
}
default:
* For CONF_ITEM_SECTION this is 'name2'.
* For CONF_ITEM_DATA this is 'name'.
*
- * @param[in] a First CONF_ITEM to compare.
- * @param[in] b Second CONF_ITEM to compare.
- * @return
- * - >0 if a > b.
- * - <0 if a < b.
- * - 0 if a == b.
+ * @param[in] one First CONF_ITEM to compare.
+ * @param[in] two Second CONF_ITEM to compare.
+ * @return CMP(one,two)
*/
-static inline int cf_ident2_cmp(void const *a, void const *b)
+static inline int cf_ident2_cmp(void const *one, void const *two)
{
- CONF_ITEM const *ci = a;
+ CONF_ITEM const *ci = one;
switch (ci->type) {
case CONF_ITEM_PAIR:
case CONF_ITEM_SECTION:
{
- CONF_SECTION const *one = a;
- CONF_SECTION const *two = b;
+ CONF_SECTION const *a = one;
+ CONF_SECTION const *b = two;
- if (!two->name2 && one->name2) return +1;
- if (two->name2 && !one->name2) return -1;
- if (!two->name2 && !one->name2) return 0;
+ if (!b->name2 && a->name2) return +1;
+ if (b->name2 && !a->name2) return -1;
+ if (!b->name2 && !a->name2) return 0;
- return strcmp(one->name2, two->name2);
+ return strcmp(a->name2, b->name2);
}
case CONF_ITEM_DATA:
{
- CONF_DATA const *one = a;
- CONF_DATA const *two = b;
+ CONF_DATA const *a = one;
+ CONF_DATA const *b = two;
- if (!two->name && one->name) return +1;
- if (two->name && !one->name) return -1;
- if (!two->name && !one->name) return 0;
+ if (!b->name && a->name) return +1;
+ if (b->name && !a->name) return -1;
+ if (!b->name && !a->name) return 0;
- return strcmp(one->name, two->name);
+ return strcmp(a->name, b->name);
}
default:
*
* @param[in] a First CONF_ITEM to compare.
* @param[in] b Second CONF_ITEM to compare.
- * @return
- * - >0 if a > b.
- * - <0 if a < b.
- * - 0 if a == b.
+ * @return CMP(a, b)
*/
static int _cf_ident2_cmp(void const *a, void const *b)
{
*/
if ((a->proto == IPPROTO_IP) || (b->proto == IPPROTO_IP)) return 0;
- return a->proto - b->proto;
+ return CMP(a->proto, b->proto);
}
#endif
fr_assert(a->data);
fr_assert(b->data);
- return (a->data > b->data) - (a->data < b->data);
+ return CMP(a->data, b->data);
}
static int dl_module_cmp(void const *one, void const *two)
static int map_proc_cmp(void const *one, void const *two)
{
map_proc_t const *a = one, *b = two;
+ int ret;
- if (a->length != b->length) return a->length - b->length;
+ CMP_RETURN(length);
- return memcmp(a->name, b->name, a->length);
+ ret = memcmp(a->name, b->name, a->length);
+ return CMP(ret, 0);
}
/** Unregister a map processor
/** Compares two last fired structures
*
- * @param a first pointer to compare.
- * @param b second pointer to compare.
- * @return
- * - -1 if a < b.
- * - +1 if b > a.
- * - 0 if both equal.
+ * @param one first pointer to compare.
+ * @param two second pointer to compare.
+ * @return CMP(one, two)
*/
-static int _trigger_last_fired_cmp(void const *a, void const *b)
+static int _trigger_last_fired_cmp(void const *one, void const *two)
{
- trigger_last_fired_t const *lf_a = a, *lf_b = b;
+ trigger_last_fired_t const *a = one, *b = two;
- return (lf_a->ci < lf_b->ci) - (lf_a->ci > lf_b->ci);
+ return CMP(a->ci, b->ci);
}
/** Set the global trigger section trigger_exec will search in, and register xlats
fr_listen_t const *a = one;
fr_listen_t const *b = two;
fr_ipaddr_t aip, bip;
- int rcode;
+ int ret;
/*
* The caller must ensure that the address field is set.
/*
* UDP vs TCP
*/
- rcode = a->app_io_addr->proto - b->app_io_addr->proto;
- if (rcode != 0) return rcode;
+ CMP_RETURN(app_io_addr->proto);
/*
* Check ports.
*/
- rcode = a->app_io_addr->inet.src_port - b->app_io_addr->inet.src_port;
- if (rcode != 0) return rcode;
+ CMP_RETURN(app_io_addr->inet.src_port);
/*
* Don't call fr_ipaddr_cmp(), as we need to do our own
/*
* Different address families.
*/
- rcode = a->app_io_addr->inet.src_ipaddr.af - b->app_io_addr->inet.src_ipaddr.af;
- if (rcode != 0) return rcode;
+ CMP_RETURN(app_io_addr->inet.src_ipaddr.af);
/*
* If both are bound to interfaces, AND the interfaces
* are different, then there is no conflict.
*/
if (a->app_io_addr->inet.src_ipaddr.scope_id && b->app_io_addr->inet.src_ipaddr.scope_id) {
- rcode = a->app_io_addr->inet.src_ipaddr.scope_id - b->app_io_addr->inet.src_ipaddr.scope_id;
- if (rcode != 0) return rcode;
+ CMP_RETURN(app_io_addr->inet.src_ipaddr.scope_id);
}
- rcode = a->app_io_addr->inet.src_ipaddr.prefix - b->app_io_addr->inet.src_ipaddr.prefix;
+ ret = a->app_io_addr->inet.src_ipaddr.prefix - b->app_io_addr->inet.src_ipaddr.prefix;
aip = a->app_io_addr->inet.src_ipaddr;
bip = b->app_io_addr->inet.src_ipaddr;
* Mask out the longer prefix to match the shorter
* prefix.
*/
- if (rcode < 0) {
+ if (ret < 0) {
fr_ipaddr_mask(&bip, a->app_io_addr->inet.src_ipaddr.prefix);
- } else if (rcode > 0) {
+ } else if (ret > 0) {
fr_ipaddr_mask(&aip, b->app_io_addr->inet.src_ipaddr.prefix);
}
/** Compare two virtual namespace callbacks
*
*/
-static int _virtual_namespace_cmp(void const *a, void const *b)
+static int _virtual_namespace_cmp(void const *one, void const *two)
{
- fr_virtual_namespace_t const *ns_a = a;
- fr_virtual_namespace_t const *ns_b = b;
+ fr_virtual_namespace_t const *a = one;
+ fr_virtual_namespace_t const *b = two;
+ int ret;
- return strcmp(ns_a->namespace, ns_b->namespace);
+ ret = strcmp(a->namespace, b->namespace);
+ return CMP(ret, 0);
}
/** Add a callback for a specific namespace
static int server_section_name_cmp(void const *one, void const *two)
{
- int rcode;
virtual_server_compile_t const *a = one;
virtual_server_compile_t const *b = two;
+ int ret;
- rcode = strcmp(a->name, b->name);
- if (rcode != 0) return rcode;
+ ret = strcmp(a->name, b->name);
+ ret = CMP(ret, 0);
+ if (ret != 0) return ret;
if (a->name2 == b->name2) return 0;
if ((a->name2 == CF_IDENT_ANY) && (b->name2 != CF_IDENT_ANY)) return -1;
if ((a->name2 != CF_IDENT_ANY) && (b->name2 == CF_IDENT_ANY)) return +1;
- return strcmp(a->name2, b->name2);
+ ret = strcmp(a->name2, b->name2);
+ return CMP(ret, 0);
}
/** Register name1 / name2 as allowed processing sections
a_len = strlen(a->name);
b_len = strlen(b->name);
- ret = (a_len > b_len) - (a_len < b_len);
+ ret = CMP(a_len, b_len);
if (ret != 0) return ret;
- return memcmp(a->name, b->name, a_len);
+ ret = memcmp(a->name, b->name, a_len);
+ return CMP(ret, 0);
}
/** Compare two xlat instances based on node pointer
*
- * @param[in] a First xlat expansion instance.
- * @param[in] b Second xlat expansion instance.
- * @return
- * - +1 if a > b.
- * - -1 if a < b.
- * - 0 if a == b.
+ * @param[in] one First xlat expansion instance.
+ * @param[in] two Second xlat expansion instance.
+ * @return CMP(one, two)
*/
-static int _xlat_inst_cmp(void const *a, void const *b)
+static int _xlat_inst_cmp(void const *one, void const *two)
{
- xlat_inst_t const *my_a = a, *my_b = b;
+ xlat_inst_t const *a = one, *b = two;
- return (my_a->node > my_b->node) - (my_a->node < my_b->node);
+ return CMP(a->node, b->node);
}
/** Compare two thread instances based on node pointer
*
- * @param[in] a First thread specific xlat expansion instance.
- * @param[in] b Second thread specific xlat expansion instance.
- * @return
- * - +1 if a > b.
- * - -1 if a < b.
- * - 0 if a == b.
+ * @param[in] one First thread specific xlat expansion instance.
+ * @param[in] two Second thread specific xlat expansion instance.
+ * @return CMP(one, two)
*/
-static int _xlat_thread_inst_cmp(void const *a, void const *b)
+static int _xlat_thread_inst_cmp(void const *one, void const *two)
{
- xlat_thread_inst_t const *my_a = a, *my_b = b;
+ xlat_thread_inst_t const *a = one, *b = two;
- return (my_a->node > my_b->node) - (my_a->node < my_b->node);
+ return CMP(a->node, b->node);
}
/** Destructor for xlat_thread_inst_t
fr_dict_t const *a = one;
fr_dict_t const *b = two;
- return a->root->attr - b->root->attr;
+ return CMP(a->root->attr, b->root->attr);
}
/** Wrap name hash function for fr_dict_attr_t
fr_dict_vendor_t const *a = one;
fr_dict_vendor_t const *b = two;
- return a->pen - b->pen;
+ return CMP(a->pen, b->pen);
}
/** Hash a enumeration name
/** Compare two file descriptor handles
*
- * @param[in] a the first file descriptor handle.
- * @param[in] b the second file descriptor handle.
- * @return
- * - +1 if a is more than b.
- * - -1 if a is less than b.
- * - 0 if both handles refer to the same file descriptor.
+ * @param[in] one the first file descriptor handle.
+ * @param[in] two the second file descriptor handle.
+ * @return CMP(one, two)
*/
-static int fr_event_fd_cmp(void const *a, void const *b)
+static int fr_event_fd_cmp(void const *one, void const *two)
{
- fr_event_fd_t const *ev_a = a, *ev_b = b;
+ fr_event_fd_t const *a = one, *b = two;
int ret;
- ret = (ev_a->fd < ev_b->fd) - (ev_a->fd > ev_b->fd);
- if (ret != 0) return ret;
+ CMP_RETURN(fd);
- return (ev_a->filter > ev_b->filter) - (ev_a->filter < ev_b->filter);
+ return CMP(a->filter, b->filter);
}
#ifdef LOCAL_PID
-static int8_t fr_event_pid_cmp(void const *a, void const *b)
+static int8_t fr_event_pid_cmp(void const *one, void const *two)
{
- fr_event_pid_t const *ev_a = a, *ev_b = b;
+ fr_event_pid_t const *a = one, *b = two;
- return CMP(ev_a->pid, ev_b->pid);
+ return CMP(a->pid, b->pid);
}
#endif
fr_event_counter_t const *b = two;
int ret;
- ret = (a->file > b->file) - (a->file < b->file);
- if (ret != 0) return ret;
+ CMP_RETURN(file);
- return (a->line > b->line) - (a->line < b->line);
+ return CMP(line);
}
*/
int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
{
- if (a->af != b->af) return a->af - b->af;
- if (a->prefix != b->prefix) return a->prefix - b->prefix;
+ int ret;
+
+ CMP_RETURN(af);
+ CMP_RETURN(prefix);
switch (a->af) {
case AF_INET:
- return memcmp(&a->addr.v4,
- &b->addr.v4,
- sizeof(a->addr.v4));
+ ret = memcmp(&a->addr.v4,
+ &b->addr.v4,
+ sizeof(a->addr.v4));
+ return CMP(ret, 0);
#ifdef HAVE_STRUCT_SOCKADDR_IN6
case AF_INET6:
- if (a->scope_id != b->scope_id) return a->scope_id - b->scope_id;
- return memcmp(&a->addr.v6, &b->addr.v6, sizeof(a->addr.v6));
+ CMP_RETURN(scope_id);
+ ret = memcmp(&a->addr.v6, &b->addr.v6, sizeof(a->addr.v6));
+ return CMP(ret, 0);
#endif
default:
typedef void (*fr_free_t)(void *);
typedef uint32_t (*fr_hash_t)(void const *);
-
/*
* Define TALLOC_DEBUG to check overflows with talloc.
* we can't use valgrind, because the memory used by
/** Compare two terminal elements for ordering purposes
*
- * @param[in] a first terminal to compare.
- * @param[in] b second terminal to compare.
- * @return
- * - >0 if a > b.
- * - 0 if a == b.
- * - <0 if a < b.
+ * @param[in] one first terminal to compare.
+ * @param[in] two second terminal to compare.
+ * @return CMP(one, two)
*/
-static inline int8_t terminal_cmp(void const *a, void const *b)
+static inline int8_t terminal_cmp(void const *one, void const *two)
{
- fr_sbuff_term_elem_t const *our_a = a;
- fr_sbuff_term_elem_t const *our_b = b;
-
- int8_t ret;
- int i_ret;
+ fr_sbuff_term_elem_t const *a = one;
+ fr_sbuff_term_elem_t const *b = two;
+ int ret;
- ret = (our_a->len > our_b->len) - (our_a->len < our_b->len);
- if (ret != 0) return ret;
+ CMP_RETURN(len);
- i_ret = memcmp(our_a->str, our_b->str, our_a->len);
- return (i_ret > 0) - (i_ret < 0);
+ ret = memcmp(a->str, b->str, a->len);
+ return CMP(ret, 0);
}
/** Merge two sets of terminal strings
*
* @param[in] one first sync to compare.
* @param[in] two second sync to compare.
- * @return the difference between the msgids.
+ * @return CMP(one, two)
*/
static int _sync_cmp(void const *one, void const *two)
{
sync_state_t const *a = one, *b = two;
- return a->msgid - b->msgid;
+ return CMP(a->msgid, b->msgid);
}
/** Destroy a sync (does not free config)
rlm_cache_entry_t const *a = one, *b = two;
int ret;
- ret = (a->key_len > b->key_len) - (a->key_len < b->key_len);
- if (ret != 0) return ret;
+ CMP_RETURN(key_len);
- return memcmp(a->key, b->key, a->key_len);
+ ret = memcmp(a->key, b->key, a->key_len);
+ return CMP(ret, 0);
}
/** Compare two entries by expiry time
{
rlm_cache_entry_t const *a = one, *b = two;
- return (a->expires > b->expires) - (a->expires < b->expires);
+ return CMP(a->expires, b->expires);
}
/** Cleanup a cache_rbtree instance
static int detail_cmp(void const *a, void const *b)
{
- return (a < b) - (a > b);
+ return CMP(a, b);
}
/*
/*
* No need to check IP, because "counter" is unique for each packet.
*/
- return (a->counter < b->counter) - (a->counter > b->counter);
+ return CMP(a->counter, b->counter);
}
static void mod_icmp_read(UNUSED fr_event_list_t *el, UNUSED int sockfd, UNUSED int flags, void *ctx)
{
isc_host_uid_t const *a = one;
isc_host_uid_t const *b = two;
-
- if ( a->client->vb_length < b->client->vb_length) return -1;
- if ( a->client->vb_length > b->client->vb_length) return +1;
+ int ret;
+
+ CMP_RETURN(client->vb_length);
return memcmp(a->client->vb_octets, b->client->vb_octets, a->client->vb_length);
}
len_a = talloc_array_length((uint8_t const *)a);
len_b = talloc_array_length((uint8_t const *)b);
- ret = (len_a > len_b) - (len_a < len_b);
+ ret = CMP(len_a, len_b);
if (ret != 0) return ret;
ret = memcmp(a, b, len_a);
- return (ret > 0) - (ret < 0);
+ return CMP(ret, 0);
}
/** Return the pools available across the cluster
/** Compare rounds of a transaction
*
*/
-static int sigtran_txn_cmp(void const *a, void const *b)
+static int sigtran_txn_cmp(void const *one, void const *two)
{
- sigtran_transaction_t const *a_tx = a; /* May be stack allocated */
- sigtran_transaction_t const *b_tx = b; /* May be stack allocated */
+ sigtran_transaction_t const *a = one; /* May be stack allocated */
+ sigtran_transaction_t const *b = two; /* May be stack allocated */
+ int ret;
- if (a_tx->ctx.otid > b_tx->ctx.otid) return +1;
- if (a_tx->ctx.otid < b_tx->ctx.otid) return -1;
+ CMP_RETURN(ctx.otid);
- if (a_tx->ctx.invoke_id > b_tx->ctx.invoke_id) return +1;
- if (a_tx->ctx.invoke_id < b_tx->ctx.invoke_id) return -1;
-
- return 0;
+ return CMP(a->ctx.invoke_id, b->ctx.invoke_id);
}
static void sigtran_tcap_timeout(void *data)
int ret;
/*
- * 256-way fanout.
+ * 256-way fanout for RADIUS IDs, then by FD. And then
+ * since there are sometimes multiple clients for one FD,
+ * source port. The comparison on dst_port is largely
+ * redundant with the comparison on FD, but it's not
+ * _completely_ redundant.
*/
- if (a->id < b->id) return -1;
- if (a->id > b->id) return +1;
-
- if (a->socket.fd < b->socket.fd) return -1;
- if (a->socket.fd > b->socket.fd) return +1;
-
- /*
- * Source ports are pretty much random.
- */
- ret = (int) a->socket.inet.src_port - (int) b->socket.inet.src_port;
- if (ret != 0) return ret;
+ CMP_RETURN(id);
+ CMP_RETURN(socket.fd);
+ CMP_RETURN(socket.inet.src_port);
+ CMP_RETURN(socket.inet.dst_port);
/*
* Usually many client IPs, and few server IPs
ret = fr_ipaddr_cmp(&a->socket.inet.src_ipaddr, &b->socket.inet.src_ipaddr);
if (ret != 0) return ret;
- /*
- * One socket can receive packets for multiple
- * destination IPs, so we check that before checking the
- * file descriptor.
- */
- ret = fr_ipaddr_cmp(&a->socket.inet.dst_ipaddr, &b->socket.inet.dst_ipaddr);
- if (ret != 0) return ret;
-
- /*
- * At this point, the order of comparing socket FDs
- * and/or destination ports doesn't matter. One of those
- * fields will make the socket unique, and the other is
- * pretty much redundant.
- */
- ret = (int) a->socket.inet.dst_port - (int) b->socket.inet.dst_port;
- return ret;
+ return fr_ipaddr_cmp(&a->socket.inet.dst_ipaddr, &b->socket.inet.dst_ipaddr);
}
/*