I think better than
dissector_add("udp.port", 0, xxx_handle);
is
dissector_add_handle("udp.port", xxx_handle);
Yes, the latter is the preferred way of registering the XXX dissector
as a protocol for a dissector that runs atop a particular protocol, but
that doesn't have a fixed "port" (selector) value for that protocol,
and that isn't a heuristic dissector for that protocol (which means you
need to use "Decode As..." or "-d" to use it).