Namespaces and inter-library private symbols
Nicolas.Williams at sun.com
Tue Nov 10 15:14:57 EST 2009
On Tue, Nov 10, 2009 at 02:08:18PM -0500, ghudson at mit.edu wrote:
> I'd like to get a consensus on how we should handle library functions
> which are not part of the public API but are used by other parts of
> the tree. Currently, we inconsistently do one of three things:
> 1. Use the accessor. (Examples: ASN.1 encoders as used by the pkinit
> module; HMAC as used by gss-krb5.)
I don't mind this, but it'd be nice to have a set of macros to hide the
> 2. Name the function krb5_foo, export it, but prototype it in k5-int.h
> instead of krb5.h. (Examples: krb5_get_cred_from_kdc as used by ksu;
> krb5_free_realm_tree as used by kdc.)
I don't mind this either.
> 3. Name the function krb5int_foo, export it, prototype it in k5-int.h,
> and use it directly from the other part of the tree. (Examples:
> krb5int_cc_default as used by gss-krb5; krb5int_init_context_kdc as
> used by kdc and libkadm5.)
Nor this. But I prefer (2), slightly.
> I would like to better understand why we have the accessor and when it
> should be used, if ever. I consider it an overly heavyweight solution
> to the problem. Tom tells me that the initial justification had
> something to do with Windows, but he didn't have details.
*shrug*. It's not heavyweight, but, rather, a way of building your own
light-weight run-time linker. It's... OK, not great, but there's
precedent (e.g., PKCS#11 is meant to be used in a similar way).
What you call the "accessor" approach may be particularly useful when
you might risk interposition at run-time and you want to ensure that you
don't (you dlopen() the exact object you want, dlsym() each function
from it, or a single function that outputs a pointer to a struct
containing the necessary function pointers).
> I think we have a partial consensus that (2) is bad, because those
> symbols can show up as available in an autoconf test even if they
> aren't part of the API in that version of Kerberos. We've continued
> to add new examples of (2) in recent work, however--examples are
> krb5_c_weak_enctype (recently renamed to krb5int_c_weak enctype) and
I don't think (2) is bad. Here's why: you must export symbols as far as
the _linker_ goes, no matter which of (1), (2), or (3) you pick, and in
_all_ cases you depend on a private header to obtain access to the
necessary C function prototype declarations -- (2) fits the bill with
minimal impact on the existing source.
The prefix that indicates "internal" is somewhat useful -- you know
instantly by looking at a function if it's internal -- but, what is
"internal"? Internal to a single library? To all of MIT krb5? To
third-party code that has an "interface contract" with MIT krb5? How
many prefixes do you actually need?
> I would like to see us move towards using (3) uniformly. If I receive
> no feedback, I will document this as the preferred practice in
> http://k5wiki.kerberos.org/wiki/Coding_style/Practices#Namespaces and
> start converting cases to that form as I run into them.
Certainly having a single style adopted uniformly would be good.
> A fourth option is to invent a new namespace for inter-library private
> symbols, so that we can easily differentiate between "internal to this
> library" and "internal to the krb5 tree." That might result in a lot
> of symbol renaming over time, though.
You can't invent a new namespace, only a new naming convention. I
recommend against it. I recommend that you concentrate efforts on
actual, useful features and bug fixes over mass symbol rename
More information about the krbdev