diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-06-02 02:13:57 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-06-02 02:13:57 -0400 |
commit | 8312f7f60f9dfe88118163d38b8282abf04aac2f (patch) | |
tree | 0dcbcbd3f9e6b3362a920707895624bdc3adb1f5 /src/network/res_mkquery.c | |
parent | 1871f583f419f58bbcd921cda41c991994672c8a (diff) | |
download | musl-8312f7f60f9dfe88118163d38b8282abf04aac2f.tar.gz musl-8312f7f60f9dfe88118163d38b8282abf04aac2f.tar.bz2 musl-8312f7f60f9dfe88118163d38b8282abf04aac2f.tar.xz musl-8312f7f60f9dfe88118163d38b8282abf04aac2f.zip |
implement new dns backend, res_send and other legacy resolver functions
this is the second phase of the "resolver overhaul" project.
the key additions in this commit are the __res_msend and __res_mkquery
functions, which have been factored so as to provide a backend for
both the legacy res_* functions and the standard getaddrinfo and
getnameinfo functions. the latter however are still using the old
backend code; there is code duplication which still needs to be
removed, and this will be the next phase of the resolver overhaul.
__res_msend is derived from the old __dns_doqueries function, but
generalized to send arbitrary caller-provided packets in parallel
rather than producing the parallel queries itself. this allows it to
be used (completely trivially) as a backend for res_send. the
factored-out query generation code, with slightly more generality, is
now part of __res_mkquery.
Diffstat (limited to 'src/network/res_mkquery.c')
-rw-r--r-- | src/network/res_mkquery.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/network/res_mkquery.c b/src/network/res_mkquery.c new file mode 100644 index 00000000..f7e4e9c6 --- /dev/null +++ b/src/network/res_mkquery.c @@ -0,0 +1,41 @@ +#include <resolv.h> +#include <string.h> +#include <time.h> +#include "libc.h" + +int __res_mkquery(int op, const char *dname, int class, int type, + const unsigned char *data, int datalen, + const unsigned char *newrr, unsigned char *buf, int buflen) +{ + int id, i, j; + unsigned char q[280]; + struct timespec ts; + size_t l = strnlen(dname, 256); + + if (l-1>=254 || buflen<18+l || op>15u || class>255u || type>255u) + return -1; + + /* Construct query template - ID will be filled later */ + memset(q, 0, 18+l); + q[2] = op*8 + 1; + q[5] = 1; + memcpy((char *)q+13, dname, l); + for (i=13; q[i]; i=j+1) { + for (j=i; q[j] && q[j] != '.'; j++); + if (j-i-1u > 62u) return -1; + q[i-1] = j-i; + } + q[i+1] = type; + q[i+3] = class; + + /* Make a reasonably unpredictable id */ + clock_gettime(CLOCK_REALTIME, &ts); + id = ts.tv_nsec + ts.tv_nsec/65536UL & 0xffff; + q[0] = id/256; + q[1] = id; + + memcpy(buf, q, 18+l); + return 18+l; +} + +weak_alias(__res_mkquery, res_mkquery); |