*/
typedef void (*fr_app_process_set_t)(void const *instance, REQUEST *request);
+/** Set the priority of a packet
+ *
+ * @param[in] instance of the #fr_app_t.
+ * @param[in] buffer raw packet
+ * @param[in] buflen length of the packet
+ * @return
+ * -1 - error, drop the packet
+ * 0 - no error, but we still drop the packet
+ * * - the priority of this packet
+ */
+typedef int (*fr_app_priority_get_t)(void const *instance, uint8_t const *buffer, size_t buflen);
+
/** Called by the network thread to pass an event list for the module to use for timer events
*/
typedef void (*fr_app_event_list_set_t)(void *instance, fr_event_list_t *el, void *nr);
///< Here for convenience, so that encode operations common
///< to all #fr_app_io_t can be performed by the #fr_app_t.
fr_app_process_set_t process_set;
+ fr_app_priority_get_t priority; //!< function to get priority of a packet
} fr_app_t;
/** Public structure describing an application (protocol) specialisation
}
+static int mod_priority(void const *instance, uint8_t const *buffer, UNUSED size_t buflen)
+{
+ proto_radius_t const *inst = talloc_get_type_abort_const(instance, proto_radius_t);
+
+ rad_assert(buffer[0] > 0);
+ rad_assert(buffer[0] < FR_MAX_PACKET_CODE);
+
+ /*
+ * Disallowed packet
+ */
+ if (!inst->priorities[buffer[0]]) {
+ DEBUG("proto_radius - Ignoring unsupported packet code %d", buffer[0]);
+ return -1;
+ }
+
+ /*
+ * @todo - if we cared, we could also return -1 for "this
+ * is a bad packet". But that's really only for
+ * mod_inject, as we assume that app_io->read() always
+ * returns good packets.
+ */
+
+ /*
+ * Return the configured priority.
+ */
+ return inst->priorities[buffer[0]];
+}
+
/** Open listen sockets/connect to external event source
*
* @param[in] instance Ctx data for this application.
.open = mod_open,
.decode = mod_decode,
.encode = mod_encode,
- .process_set = mod_process_set
+ .process_set = mod_process_set,
+ .priority = mod_priority
};