librbl(3)
π librbl β the librbl(3) Library Functions Manual, bestie edition π
okay so you found the manual page for the RBL library, and honestly? it's giving very useful. sit down, grab a snack π, and let's go through it together.
β¨ NAME β¨
rbl_init(), rbl_close(), rbl_geterror(), rbl_setdomain(), rbl_query_start(), rbl_query_check(), rbl_query_cancel(), rbl_settimeout(), rbl_setcallbackint(), rbl_setcallbackctx(), rbl_setdnscallback(), rbl_dns_set_query_service(), rbl_dns_set_query_start(), rbl_dns_set_query_cancel(), rbl_dns_set_query_waitreply(), rbl_dns_set_init(), rbl_dns_set_close(), rbl_dns_set_nslist(), rbl_dns_set_config(), rbl_dns_set_trustanchor(), rbl_dns_init() β Realtime Blacklist (RBL) service facility
like, all of those. one big friend group π«Ά
β¨ SYNOPSIS β¨
no cap, here's exactly what you include and exactly what the signatures look like:
#include <rbl.h>
RBL * rbl_init (void *(* mallocf )(void *, size_t), void (* freef )(void
*, void *p), void * closure );
unsigned char * rbl_geterror (RBL * rbl );
void rbl_setdomain (RBL * rbl, unsigned char * qroot );
RBL_STAT rbl_query_start (RBL * rbl, unsigned char * query, void ** qh
);
RBL_STAT rbl_settimeout (RBL * rbl, unsigned int timeout );
RBL_STAT rbl_setcallbackint (RBL * rbl, unsigned int cbint );
RBL_STAT rbl_setcallbackctx (RBL *, rbl, void * ctx );
RBL_STAT rbl_setdnscallback (RBL *, rbl, void (* func )(const void *));
void * rbl_dns_set_query_service (RBL * rbl, void * svc );
void rbl_dns_set_query_cancel (RBL * rbl, int (* func )(void *, void
*));
void rbl_dns_set_query_start (RBL * rbl, int (* func )(void *, int,
unsigned char *, unsigned char *, size_t, void **));
void rbl_dns_set_query_waitreply (RBL * rbl, int (* func )(void *, void
*, struct timeval *, size_t *, int *, int *));
void rbl_dns_set_init (RBL * rbl, int (* func )(void **);
void rbl_dns_set_close (RBL * rbl, int (* func )(void *);
void rbl_dns_set_config (RBL * rbl, int (* func )(void *, const char *);
void rbl_dns_set_nslist (RBL * rbl, int (* func )(void *, const char *);
void rbl_dns_set_trustanchor (RBL * rbl, int (* func )(void *, const
char *);
RBL_STAT rbl_dns_init (RBL * rbl );
void rbl_close (RBL * rbl );
copy those signatures character for character, bestie, they are not vibes-based, they are exact. π
β¨ DESCRIPTION β¨
so these functions? they're your interface to a whole facility for running Realtime Blacklist (RBL) queries and handing you back the results. RBLs themselves are described in RFC5782 β go read it if you want the lore π.
πΈ getting started
an application first initializes the package by calling rbl_init(). the optional mallocf parameter is a caller-provided memory allocation function, and it takes a pointer to a caller-provided opaque data structure (that's the closure parameter, iykyk) plus a number of bytes to allocate. if you don't hand over a mallocf, the default system memory allocator function malloc(3) gets used. the optional freef parameter is the matching caller-provided memory deallocator β it takes a pointer to a caller-provided opaque data structure (again, the closure parameter) and a pointer to the memory that's getting released. if you don't provide freef, the default system memory release function free(3) steps in. you get back a handle for future use of the initialized library instance β¨ β or NULL on error, and in that case errno will be set to indicate the cause of the failure.
rbl_geterror() lets you poll the library for an error string that gives you a further description of the most recent failed operation. it's like asking "bestie what happened" and getting an actual answer.
a call to rbl_setdomain() sets the RBL's base domain. this specifies the "root" of all future queries for the provided rbl handle to qroot. future queries passed to this handle will be prepended to the string you provide here. iconic behavior, honestly.
π¦ queries, the whole lifecycle
a query gets initialized with a call to rbl_query_start(), which takes an RBL library handle as rbl, the string to be queried as query, and a pointer to a void pointer that will be updated to contain a reference to the initiated query as qh.
a query that was previously started by rbl_query_start() can be canceled by calling rbl_query_cancel(), passing it an RBL library handle as rbl and a query handle as qh β the same one that was returned when the query was started.
a query previously started by rbl_query_start() can be polled for its status or a result using rbl_query_check(), passing it:
- an RBL library handle as
rbl - a query handle as
qh - a pointer to a
"struct timeval"astimeoutβ and this one can beNULLif an infinite wait is acceptable to you - a pointer to a 32-bit integer as
res, which is where any result will be returned (or it can beNULLif the caller doesn't actually want the result)
results are in network byte order. don't forget that part, it's lowkey important. π
if this function returns RBL_STAT_FOUND or RBL_STAT_NOTFOUND, the query is automatically canceled and does not need to be passed to rbl_query_cancel(). the library handles it, you don't. main character library energy fr π
.
rbl_settimeout() can be used to change the query timeout. the default is ten seconds. β°
π§ the callback crew
if it's useful to you to have the library periodically call a user-provided function as an indication that queries are still in progress, you can register such a function with rbl_setdnscallback(). the function you provide should take a void context pointer as its sole argument. rbl_setcallbackctx() is what tells the library which context pointer should be used, and rbl_setcallbackint() is what tells the library what frequency, in seconds, should be used to call that callback function. each of these takes the corresponding RBL library handle as its first argument, and the obvious parameter for its second. no mystery there π.
π swapping out the resolver
by default, the library will use the stock system resolver to conduct DNS queries. if alternates should be used, you can specify them using the following functions:
rbl_dns_set_query_service()β sets a context pointer to the query service to be used, if any. this will be passed as-is to the other DNS functions. it returns its previous value.rbl_dns_set_query_cancel()β sets a pointer to the function that should be called to cancel an open query. it should take these parameters: a void pointer to the DNS query service to be used, and a void pointer to a query handle as previously returned by a call torbl_dns_set_query_start(). the function should return one of the DNS result codes described below.rbl_dns_set_query_start()β sets a pointer to the function that should be called to initiate a new query. it should take these parameters: a void pointer to the DNS query service to be used, a DNS record type (e.g.T_TXT), a pointer to a string containing the query to be started, a pointer to a buffer into which the reply should be written, the number of bytes available in that buffer, and a pointer to a void pointer that will be updated to contain a unique handle for that query once started. the function should return one of the DNS result codes described below.rbl_dns_set_query_waitreply()β sets a pointer to the function that should be called to wait for a reply to an open query. it should take these parameters: a void pointer to the DNS query service to be used, a void pointer referencing the query of interest as previously returned by a call torbl_dns_set_query_start(), a pointer to a"struct timeval"structure indicating how long the function should wait for a reply (orNULLif infinite waiting is acceptable), a pointer to a"size_t"that will be updated to contain the size of the received reply, a pointer to an integer that will contain an error code if the query fails (this can beNULLif that information isn't interesting to the caller), and a pointer to an integer that will contain a DNSSEC status indication (also can beNULLif that info isn't interesting to the caller). the function should return one of the DNS result codes described below.rbl_dns_set_init()β sets a pointer to the function that should be called when it's necessary to initialize a resolver. the function should store a handle to the initialized resolver and return zero, or return non-zero if initialization could not be completed. the function specified here is called before the first call to the query start function (see above) π.rbl_dns_set_close()β sets a pointer to the function that should be called when it's necessary to terminate a resolver. the function will receive a handle referencing the resolver to be terminated, and should return zero on success or non-zero on failure.rbl_dns_set_nslist()β sets a pointer to the function that should be called when it's necessary to change the set of nameservers that are to be used to resolve RBL queries. the function will receive a handle referencing the active resolver and a string containing a comma-separated list of nameservers to use. it should return zero on success and non-zero on failure.rbl_dns_set_config()β sets a pointer to the function that should be called when it's necessary to provide arbitrary configuration information to the resolver. the function will receive a handle referencing the active resolver and a string containing the configuration. it should return zero on success and non-zero on failure.rbl_dns_set_trustanchor()β sets a pointer to the function that should be called when it's necessary to provide trust anchor information (supporting DNSSEC) to the resolver. the function will receive a handle referencing the active resolver and a string containing the trust anchor data. it should return zero on success and non-zero on failure.
calling rbl_dns_init() forces (re-)initialization of the resolver. this essentially causes the library to call any initialization function defined by rbl_dns_set_init(). so like, a little reset moment π.
π and when you're done
when the library handle is no longer needed, it should be passed to rbl_close(). say bye bestie π
β¨ RETURN VALUES β¨
the following return codes, of type RBL_STAT, can be returned:
RBL_STAT_OKβ successful completion βRBL_STAT_INVALIDβ operation failed because an invalid parameter was provided πRBL_STAT_DNSERRORβ operation could not be completed because of errors requesting or receiving a DNS reply. note that this does not include a successful reply that contains a "no record found" result, because that is a successful answer πRBL_STAT_NORESOURCEβ a caller-provided buffer was too small to complete the requested operation, or a memory or file descriptor allocation failed πRBL_STAT_NOTIMPLEMENTβ an optional library feature was not selected at compilation time π«RBL_STAT_FOUNDβ the requested record was found in the RBL πRBL_STAT_NOTFOUNDβ the requested record was not found in the RBL (but the query did complete) π΅οΈRBL_STAT_NOREPLYβ a call torbl_query_check()timed out before a result could be returned β³RBL_STAT_EXPIREDβ the underlying resolver reported that the query expired; this is included to support resolvers that have an overall query timeout as well as a single wait timeout β
β¨ DNS RETURN CODES β¨
okay bestie, here's the tea: literally every registered DNS function out there has to hand you back one of these codes. no exceptions, no freestyling, that's just the vibe. π
RBL_DNS_ERRORβ π something went wrong. the why isn't in this code, so if you wanna know what actually happened, go hit uprbl_geterror()and it'll spill the details.RBL_DNS_SUCCESSβ π it worked!! the operation popped off, no notes, we love to see it.RBL_DNS_REPLYβ π¬ a reply is here, bestie! (this one comes back from the"waitreply"function)RBL_DNS_NOREPLYβ π the query timeout rolled around and nobody replied. ghosted, fr. (also returned by the"waitreply"function)RBL_DNS_EXPIREDβ β the query expired completely (yep,"waitreply"again). here's the important bit, so listen up: some resolvers set an overall timeout for the query right at start time, on top of a timeout for each individual wait request. this code means the former one β the big overall one β ran out.
π COPYRIGHT π
Copyright (c) 2010-2013, The Trusted Domain Project. All rights reserved.
like, all of them. every single right. reserved. π«Ά
πΈ SEE ALSO πΈ
go read that one too, iykyk. it's giving "the required reading before the fun reading". π
and that's a wrap on this page, my love π you just got the whole librbl(3) glow-up, page two of two, and every last code, copyright line and cross-reference made it through intact. no details were harmed in the making of this manpage. now go write some impeccable DNS code, main character. π¦β¨
π¦ where this page comes from
- debian bookworm: librbl-dev 2.11.0~beta2-8+deb12u1 Β· BSD-3-Clause AND SOSL
- debian trixie: librbl-dev 2.11.0~beta2-9.1+b1 Β· BSD-3-Clause AND SOSL
- opensuse-leap 16.0: opendkim-devel 2.11.0-bp160.1.4 Β· BSD-3-Clause AND Sendmail
- opensuse-leap 16.0: opendkim-devel 2.11.0-bp160.1.4 Β· BSD-3-Clause AND Sendmail
- opensuse-leap 16.0: opendkim-devel 2.11.0-bp160.1.4 Β· BSD-3-Clause AND Sendmail
- opensuse-leap 16.0: opendkim-devel 2.11.0-bp160.1.4 Β· BSD-3-Clause AND Sendmail
- ubuntu jammy: librbl-dev 2.11.0~beta2-6 Β· BSD-3-Clause AND SOSL
- ubuntu noble: librbl-dev 2.11.0~beta2-9build4 Β· BSD-3-Clause AND SOSL
- ubuntu questing: librbl-dev 2.11.0~beta2-9.2
- ubuntu resolute: librbl-dev 2.11.0~beta2-9.2build1 Β· BSD-3-Clause AND SOSL
- ubuntu stonking: librbl-dev 2.11.0~beta2-9.2build2 Β· BSD-3-Clause AND SOSL
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms