Remove udns
This commit is contained in:
parent
0281e1acf6
commit
d923c94a0c
4
LICENSE
4
LICENSE
@ -15,10 +15,6 @@ are:
|
|||||||
- The SCONS build system, located at tools/scons. Copyrighted by the SCONS
|
- The SCONS build system, located at tools/scons. Copyrighted by the SCONS
|
||||||
Foundation. Released under an MIT license.
|
Foundation. Released under an MIT license.
|
||||||
|
|
||||||
- UDNS, an asynchronous DNS client, located at deps/udns. Copyrighted by
|
|
||||||
Michael Tokarev <mjt@corpit.ru>. Released under the GNU Lesser General
|
|
||||||
Public License version 2.1.
|
|
||||||
|
|
||||||
- C-Ares, an asynchronous DNS client, located at deps/c-ares. Copyright by
|
- C-Ares, an asynchronous DNS client, located at deps/c-ares. Copyright by
|
||||||
the Massachusetts Institute of Technology; authored by Greg Hudson,
|
the Massachusetts Institute of Technology; authored by Greg Hudson,
|
||||||
Daniel Stenberg and others. Released under an MIT license.
|
Daniel Stenberg and others. Released under an MIT license.
|
||||||
|
14
deps/udns/.cvsignore
vendored
14
deps/udns/.cvsignore
vendored
@ -1,14 +0,0 @@
|
|||||||
udns*.tar.gz
|
|
||||||
udns_codes.c
|
|
||||||
udns.3.html
|
|
||||||
*.lo
|
|
||||||
*_s
|
|
||||||
libudns.so.*
|
|
||||||
dnsget
|
|
||||||
ex-rdns
|
|
||||||
rblcheck
|
|
||||||
Makefile
|
|
||||||
config.h
|
|
||||||
config.status
|
|
||||||
config.log
|
|
||||||
build-stamp
|
|
504
deps/udns/COPYING.LGPL
vendored
504
deps/udns/COPYING.LGPL
vendored
@ -1,504 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
||||||
|
|
||||||
|
|
198
deps/udns/Makefile.in
vendored
198
deps/udns/Makefile.in
vendored
@ -1,198 +0,0 @@
|
|||||||
#! /usr/bin/make -rf
|
|
||||||
# $Id: Makefile.in,v 1.11 2007/01/15 21:19:08 mjt Exp $
|
|
||||||
# libudns Makefile
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
# This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
#
|
|
||||||
# This library is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
|
||||||
# License as published by the Free Software Foundation; either
|
|
||||||
# version 2.1 of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This library is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
|
||||||
# License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
# write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
# Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
NAME = udns
|
|
||||||
VERS = 0.0.9
|
|
||||||
SRCS = udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
|
|
||||||
udns_misc.c udns_XtoX.c \
|
|
||||||
udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
|
|
||||||
udns_rr_srv.c udns_rr_naptr.c udns_codes.c
|
|
||||||
USRCS = dnsget.c rblcheck.c ex-rdns.c
|
|
||||||
DEB = debian/copyright debian/changelog debian/control debian/rules
|
|
||||||
DIST = COPYING.LGPL udns.h udns.3 dnsget.1 rblcheck.1 $(SRCS) $(USRCS) \
|
|
||||||
NEWS TODO NOTES Makefile.in configure configure.lib \
|
|
||||||
inet_XtoX.c getopt.c
|
|
||||||
|
|
||||||
OBJS = $(SRCS:.c=.o) $(GEN:.c=.o)
|
|
||||||
LIB = lib$(NAME).a
|
|
||||||
LIBFL = -L. -l$(NAME)
|
|
||||||
|
|
||||||
SOVER = 0
|
|
||||||
SOBJS = $(OBJS:.o=.lo)
|
|
||||||
SOLIB = lib$(NAME)_s.so
|
|
||||||
SOLIBV = lib$(NAME).so.$(SOVER)
|
|
||||||
SOLIBFL= -L. -l$(NAME)_s
|
|
||||||
|
|
||||||
LIBS = $(LIB) $(SOLIBV)
|
|
||||||
|
|
||||||
UTILS = $(USRCS:.c=)
|
|
||||||
UOBJS = $(USRCS:.c=.o)
|
|
||||||
SOUTILS = $(USRCS:.c=_s)
|
|
||||||
|
|
||||||
NAMEPFX = $(NAME)-$(VERS)
|
|
||||||
|
|
||||||
CC = @CC@
|
|
||||||
RANLIB = @RANLIB@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CDEFS = @CDEFS@
|
|
||||||
PICFLAGS = -fPIC
|
|
||||||
AWK = awk
|
|
||||||
|
|
||||||
all: staticlib
|
|
||||||
|
|
||||||
.SUFFIXES: .c .o .lo
|
|
||||||
|
|
||||||
static: $(LIB) $(UTILS)
|
|
||||||
staticlib: $(LIB)
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
-rm -f $@
|
|
||||||
$(AR) rv $@ $(OBJS)
|
|
||||||
$(RANLIB) $(LIB)
|
|
||||||
.c.o:
|
|
||||||
$(CC) $(CFLAGS) $(CDEFS) -c $<
|
|
||||||
|
|
||||||
shared: $(SOLIBV) $(SOUTILS)
|
|
||||||
sharedlib: $(SOLIBV)
|
|
||||||
|
|
||||||
$(SOLIBV): $(SOBJS)
|
|
||||||
$(CC) -shared -Wl,--soname,$(SOLIBV) -o $@ $(SOBJS)
|
|
||||||
$(SOLIB): $(SOLIBV)
|
|
||||||
rm -f $@
|
|
||||||
ln -s $(SOLIBV) $@
|
|
||||||
.c.lo:
|
|
||||||
$(CC) $(CFLAGS) $(PICFLAGS) $(CDEFS) -o $@ -c $<
|
|
||||||
|
|
||||||
# udns_codes.c is generated from udns.h
|
|
||||||
udns_codes.c: udns.h
|
|
||||||
@echo Generating $@
|
|
||||||
@set -e; exec >$@.tmp; \
|
|
||||||
set T type C class R rcode; \
|
|
||||||
echo "/* Automatically generated. */"; \
|
|
||||||
echo "#include \"udns.h\""; \
|
|
||||||
while [ "$$1" ]; do \
|
|
||||||
echo; \
|
|
||||||
echo "const struct dns_nameval dns_$${2}tab[] = {"; \
|
|
||||||
$(AWK) "/^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \
|
|
||||||
{ printf \" {%s,\\\"%s\\\"},\\n\", \$$1, substr(\$$1,7) }" \
|
|
||||||
udns.h ; \
|
|
||||||
echo " {0,0}};"; \
|
|
||||||
echo "const char *dns_$${2}name(enum dns_$${2} code) {"; \
|
|
||||||
echo " static char nm[20];"; \
|
|
||||||
echo " switch(code) {"; \
|
|
||||||
$(AWK) "BEGIN{i=0} \
|
|
||||||
/^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \
|
|
||||||
{printf \" case %s: return dns_$${2}tab[%d].name;\\n\",\$$1,i++}\
|
|
||||||
" udns.h ; \
|
|
||||||
echo " }"; \
|
|
||||||
echo " return _dns_format_code(nm,\"$$2\",code);"; \
|
|
||||||
echo "}"; \
|
|
||||||
shift 2; \
|
|
||||||
done
|
|
||||||
@mv $@.tmp $@
|
|
||||||
|
|
||||||
udns.3.html: udns.3
|
|
||||||
groff -man -Thtml udns.3 > $@.tmp
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
dist: $(NAMEPFX).tar.gz
|
|
||||||
$(NAMEPFX).tar.gz: $(DIST) $(DEB)
|
|
||||||
mkdir $(NAMEPFX) $(NAMEPFX)/debian
|
|
||||||
ln $(DIST) $(NAMEPFX)
|
|
||||||
ln $(DEB) $(NAMEPFX)/debian
|
|
||||||
tar cvfz $@ $(NAMEPFX)
|
|
||||||
rm -rf $(NAMEPFX)
|
|
||||||
subdist:
|
|
||||||
cp -p $(DIST) $(TARGET)/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJS)
|
|
||||||
rm -f $(SOBJS)
|
|
||||||
rm -f $(UOBJS)
|
|
||||||
rm -f build-stamp config.log
|
|
||||||
distclean: clean
|
|
||||||
rm -f $(LIBS) $(SOLIB) udns.3.html
|
|
||||||
rm -f $(UTILS) $(SOUTILS)
|
|
||||||
rm -f config.status config.h Makefile
|
|
||||||
|
|
||||||
|
|
||||||
Makefile: configure configure.lib Makefile.in
|
|
||||||
./configure
|
|
||||||
@echo
|
|
||||||
@echo Please rerun make >&2
|
|
||||||
@exit 1
|
|
||||||
|
|
||||||
.PHONY: all static staticlib shared sharedlib dist clean distclean subdist \
|
|
||||||
depend dep deps
|
|
||||||
|
|
||||||
depend dep deps: $(SRCS) $(USRC)
|
|
||||||
@echo Generating deps for:
|
|
||||||
@echo \ $(SRCS)
|
|
||||||
@echo \ $(USRCS)
|
|
||||||
@sed '/^# depend/q' Makefile.in > Makefile.tmp
|
|
||||||
@set -e; \
|
|
||||||
for f in $(SRCS) $(USRCS); do \
|
|
||||||
echo $${f%.c}.o $${f%.c}.lo: $$f \
|
|
||||||
`sed -n 's/^#[ ]*include[ ]*"\(.*\)".*/\1/p' $$f`; \
|
|
||||||
done >> Makefile.tmp; \
|
|
||||||
for f in $(USRCS:.c=.o); do \
|
|
||||||
echo "$${f%.?}: $$f \$$(LIB)"; \
|
|
||||||
echo " \$$(CC) \$$(CFLAGS) -o \$$@ $$f \$$(LIBFL)"; \
|
|
||||||
echo "$${f%.?}_s: $$f \$$(SOLIB)"; \
|
|
||||||
echo " \$$(CC) \$$(CFLAGS) -o \$$@ $$f \$$(SOLIBFL)"; \
|
|
||||||
done >> Makefile.tmp ; \
|
|
||||||
if cmp Makefile.tmp Makefile.in >/dev/null 2>&1 ; then \
|
|
||||||
echo Makefile.in unchanged; rm -f Makefile.tmp; \
|
|
||||||
else \
|
|
||||||
echo Updating Makfile.in; mv -f Makefile.tmp Makefile.in ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# depend
|
|
||||||
udns_dn.o udns_dn.lo: udns_dn.c udns.h
|
|
||||||
udns_dntosp.o udns_dntosp.lo: udns_dntosp.c udns.h
|
|
||||||
udns_parse.o udns_parse.lo: udns_parse.c udns.h
|
|
||||||
udns_resolver.o udns_resolver.lo: udns_resolver.c config.h udns.h
|
|
||||||
udns_init.o udns_init.lo: udns_init.c config.h udns.h
|
|
||||||
udns_misc.o udns_misc.lo: udns_misc.c udns.h
|
|
||||||
udns_XtoX.o udns_XtoX.lo: udns_XtoX.c config.h udns.h inet_XtoX.c
|
|
||||||
udns_rr_a.o udns_rr_a.lo: udns_rr_a.c udns.h
|
|
||||||
udns_rr_ptr.o udns_rr_ptr.lo: udns_rr_ptr.c udns.h
|
|
||||||
udns_rr_mx.o udns_rr_mx.lo: udns_rr_mx.c udns.h
|
|
||||||
udns_rr_txt.o udns_rr_txt.lo: udns_rr_txt.c udns.h
|
|
||||||
udns_bl.o udns_bl.lo: udns_bl.c udns.h
|
|
||||||
udns_rr_srv.o udns_rr_srv.lo: udns_rr_srv.c udns.h
|
|
||||||
udns_rr_naptr.o udns_rr_naptr.lo: udns_rr_naptr.c udns.h
|
|
||||||
udns_codes.o udns_codes.lo: udns_codes.c udns.h
|
|
||||||
dnsget.o dnsget.lo: dnsget.c config.h udns.h getopt.c
|
|
||||||
rblcheck.o rblcheck.lo: rblcheck.c udns.h getopt.c
|
|
||||||
ex-rdns.o ex-rdns.lo: ex-rdns.c udns.h
|
|
||||||
dnsget: dnsget.o $(LIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ dnsget.o $(LIBFL)
|
|
||||||
dnsget_s: dnsget.o $(SOLIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ dnsget.o $(SOLIBFL)
|
|
||||||
rblcheck: rblcheck.o $(LIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ rblcheck.o $(LIBFL)
|
|
||||||
rblcheck_s: rblcheck.o $(SOLIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ rblcheck.o $(SOLIBFL)
|
|
||||||
ex-rdns: ex-rdns.o $(LIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ ex-rdns.o $(LIBFL)
|
|
||||||
ex-rdns_s: ex-rdns.o $(SOLIB)
|
|
||||||
$(CC) $(CFLAGS) -o $@ ex-rdns.o $(SOLIBFL)
|
|
85
deps/udns/NEWS
vendored
85
deps/udns/NEWS
vendored
@ -1,85 +0,0 @@
|
|||||||
$Id: NEWS,v 1.11 2007/01/15 21:19:08 mjt Exp $
|
|
||||||
|
|
||||||
User-visible changes in udns library. Recent changes on top.
|
|
||||||
|
|
||||||
0.0.9 (16 Jan 2007)
|
|
||||||
|
|
||||||
- incompat: minor API changes in dns_init() &friends. dns_init()
|
|
||||||
now requires extra `struct dns_ctx *' argument. Not bumped
|
|
||||||
soversion yet - I only expect one "release" with this change,
|
|
||||||
0.1 will have more changes and will increment so version
|
|
||||||
|
|
||||||
- many small bugfixes, here and there
|
|
||||||
|
|
||||||
- more robust FORMERR replies handling - not only such replies are now
|
|
||||||
recognized, but udns retries queries without EDNS0 extensions if tried
|
|
||||||
with, but server reported FORMERR
|
|
||||||
|
|
||||||
- portability changes, udns now includes getopt() implementation fo
|
|
||||||
the systems lacking it (mostly windows), and dns_ntop()&dns_pton(),
|
|
||||||
which are either just wrappers for system functions or reimplementations.
|
|
||||||
|
|
||||||
- build is now based on autoconf-like configuration
|
|
||||||
|
|
||||||
- NAPTR (RFC3403) RR decoding support
|
|
||||||
|
|
||||||
- new file NOTES which complements TODO somewhat, and includes some
|
|
||||||
important shortcomings
|
|
||||||
|
|
||||||
- many internal cleanups, including some preparations for better error
|
|
||||||
recovery, security and robustness (and thus API changes)
|
|
||||||
|
|
||||||
- removed some #defines which are now unused (like DNS_MAXSRCH)
|
|
||||||
|
|
||||||
- changed WIN32 to WINDOWS everywhere in preprocessor tests,
|
|
||||||
to be able to build it on win64 as well
|
|
||||||
|
|
||||||
0.0.8 (12 Sep 2005)
|
|
||||||
|
|
||||||
- added SRV records (rfc2782) parsing,
|
|
||||||
thanks to Thadeu Lima de Souza Cascardo for implementation.
|
|
||||||
|
|
||||||
- bugfixes:
|
|
||||||
o use uninitialized value when no reply, library died with assertion:
|
|
||||||
assert((status < 0 && result == 0) || (status >= 0 && result != 0)).
|
|
||||||
o on some OSes, struct sockaddr_in has additional fields, so
|
|
||||||
memcmp'ing two sockaddresses does not work.
|
|
||||||
|
|
||||||
- rblcheck(.1)
|
|
||||||
|
|
||||||
0.0.7 (20 Apr 2005)
|
|
||||||
|
|
||||||
- dnsget.1 manpage and several enhancements to dnsget.
|
|
||||||
|
|
||||||
- allow nameserver names for -n option of dnsget.
|
|
||||||
|
|
||||||
- API change: all dns_submit*() routines now does not expect
|
|
||||||
last `now' argument, since requests aren't sent immediately
|
|
||||||
anymore.
|
|
||||||
|
|
||||||
- API change: different application timer callback mechanism.
|
|
||||||
Udns now uses single per-context timer instead of per-query.
|
|
||||||
|
|
||||||
- don't assume DNS replies only contain backward DN pointers,
|
|
||||||
allow forward pointers too. Change parsing API.
|
|
||||||
|
|
||||||
- debianize
|
|
||||||
|
|
||||||
0.0.6 (08 Apr 2005)
|
|
||||||
|
|
||||||
- use double sorted list for requests (sorted by deadline).
|
|
||||||
This should significantly speed up timeout processing for
|
|
||||||
large number of requests.
|
|
||||||
|
|
||||||
- changed debugging interface, so it is finally useable
|
|
||||||
(still not documented).
|
|
||||||
|
|
||||||
- dnsget routine is now Officially Useable, and sometimes
|
|
||||||
even more useable than `host' from BIND distribution
|
|
||||||
(and sometimes not - dnsget does not have -C option
|
|
||||||
and TCP mode)
|
|
||||||
|
|
||||||
- Debian packaging in debian/ -- udns is now maintained as a
|
|
||||||
native Debian package.
|
|
||||||
|
|
||||||
- alot (and I really mean alot) of code cleanups all over.
|
|
222
deps/udns/NOTES
vendored
222
deps/udns/NOTES
vendored
@ -1,222 +0,0 @@
|
|||||||
Assorted notes about udns (library).
|
|
||||||
|
|
||||||
UDP-only mode
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
First of all, since udns is (currently) UDP-only, there are some
|
|
||||||
shortcomings.
|
|
||||||
|
|
||||||
It assumes that a reply will fit into a UDP buffer. With adoption of EDNS0,
|
|
||||||
and general robustness of IP stacks, in most cases it's not an issue. But
|
|
||||||
in some cases there may be problems:
|
|
||||||
|
|
||||||
- if an RRset is "very large" so it does not fit even in buffer of size
|
|
||||||
requested by the library (current default is 4096; some servers limits
|
|
||||||
it further), we will not see the reply, or will only see "damaged"
|
|
||||||
reply (depending on the server).
|
|
||||||
|
|
||||||
- many DNS servers ignores EDNS0 option requests. In this case, no matter
|
|
||||||
which buffer size udns library will request, such servers reply is limited
|
|
||||||
to 512 bytes (standard pre-EDNS0 DNS packet size). (Udns falls back to
|
|
||||||
non-EDNO0 query if EDNS0-enabled one received FORMERR or NOTIMPL error).
|
|
||||||
|
|
||||||
The problem is that with this, udns currently will not consider replies with
|
|
||||||
TC (truncation) bit set, and will treat such replies the same way as it
|
|
||||||
treats SERVFAIL replies, thus trying next server, or temp-failing the query
|
|
||||||
if no more servers to try. In other words, if the reply is really large, or
|
|
||||||
if the servers you're using don't support EDNS0, your application will be
|
|
||||||
unable to resolve a given name.
|
|
||||||
|
|
||||||
Yet it's not common situation - in practice, it's very rare.
|
|
||||||
|
|
||||||
Implementing TCP mode isn't difficult, but it complicates API significantly.
|
|
||||||
Currently udns uses only single UDP socket (or - maybe in the future - two,
|
|
||||||
see below), but in case of TCP, it will need to open and close sockets for
|
|
||||||
TCP connections left and right, and that have to be integrated into an
|
|
||||||
application's event loop in an easy and efficient way. Plus all the
|
|
||||||
timeouts - different for connect(), write, and several stages of read.
|
|
||||||
|
|
||||||
IPv6 vs IPv4 usage
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This is only relevant for nameservers reachable over IPv6, NOT for IPv6
|
|
||||||
queries. I.e., if you've IPv6 addresses in 'nameservers' line in your
|
|
||||||
/etc/resolv.conf file. Even more: if you have BOTH IPv6 AND IPv4 addresses
|
|
||||||
there. Or pass them to udns initialization routines.
|
|
||||||
|
|
||||||
Since udns uses a single UDP socket to communicate with all nameservers,
|
|
||||||
it should support both v4 and v6 communications. Most current platforms
|
|
||||||
supports this mode - using PF_INET6 socket and V4MAPPED addresses, i.e,
|
|
||||||
"tunnelling" IPv4 inside IPv6. But not all systems supports this. And
|
|
||||||
more, it has been said that such mode is deprecated.
|
|
||||||
|
|
||||||
So, list only IPv4 or only IPv6 addresses, but don't mix them, in your
|
|
||||||
/etc/resolv.conf.
|
|
||||||
|
|
||||||
An alternative is to use two sockets instead of 1 - one for IPv6 and one
|
|
||||||
for IPv4. For now I'm not sure if it's worth the complexity - again, of
|
|
||||||
the API, not the library itself (but this will not simplify library either).
|
|
||||||
|
|
||||||
Single socket for all queries
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Using single UDP socket for sending queries to all nameservers has obvious
|
|
||||||
advantages. First it's, again, trivial, simple to use API. And simple
|
|
||||||
library too. Also, after sending queries to all nameservers (in case first
|
|
||||||
didn't reply in time), we will be able to receive late reply from first
|
|
||||||
nameserver and accept it.
|
|
||||||
|
|
||||||
But this mode has disadvantages too. Most important is that it's much easier
|
|
||||||
to send fake reply to us, as the UDP port where we expects the reply to come
|
|
||||||
to is constant during the whole lifetime of an application. More secure
|
|
||||||
implementations uses random port for every single query. While port number
|
|
||||||
(16 bits integer) can not hold much randomness, it's still of some help.
|
|
||||||
Ok, udns is a stub resolver, so it expects sorta friendly environment, but
|
|
||||||
on LAN it's usually much easier to fire an attack, due to the speed of local
|
|
||||||
network, where a bad guy can generate alot of packets in a short time.
|
|
||||||
|
|
||||||
Choosing of DNS QueryID
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Currently, udns uses sequential number for query IDs. Which simplifies
|
|
||||||
attacks even more (c.f. the previous item about single UDP port), making
|
|
||||||
them nearly trivial. The library should use random number for query ID.
|
|
||||||
But there's no portable way to get random numbers, even on various flavors
|
|
||||||
of Unix. It's possible to use low bits from tv_nsec field returned by
|
|
||||||
gettimeofday() (current time, nanoseconds), but I wrote the library in
|
|
||||||
a way to avoid making system calls where possible, because many syscalls
|
|
||||||
means many context switches and slow processes as a result. Maybe use some
|
|
||||||
application-supplied callback to get random values will be a better way,
|
|
||||||
defaulting to gettimeofday() method.
|
|
||||||
|
|
||||||
Note that a single query - even if (re)sent to different nameservers, several
|
|
||||||
times (due to no reply received in time), uses the same qID assigned when it
|
|
||||||
was first dispatched. So we have: single UDP socket (fixed port number),
|
|
||||||
sequential (= trivially predictable) qIDs, and long lifetime of those qIDs.
|
|
||||||
This all makes (local) attacks against the library really trivial.
|
|
||||||
|
|
||||||
See also comments in udns_resolver.c, udns_newid().
|
|
||||||
|
|
||||||
And note that at least some other stub resolvers out there (like c-ares
|
|
||||||
for example) also uses sequential qID.
|
|
||||||
|
|
||||||
Assumptions about RRs returned
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Currently udns processes records in the reply it received sequentially.
|
|
||||||
This means that order of the records is significant. For example, if
|
|
||||||
we asked for foo.bar A, but the server returned that foo.bar is a CNAME
|
|
||||||
(alias) for bar.baz, and bar.baz, in turn, has address 1.2.3.4, when
|
|
||||||
the CNAME should come first in reply, followed by A. While DNS specs
|
|
||||||
does not say anything about order of records - it's an rrSET - unordered, -
|
|
||||||
I think an implementation which returns the records in "wrong" order is
|
|
||||||
somewhat insane...
|
|
||||||
|
|
||||||
CNAME recursion
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Another interesting point is the handling of CNAMEs returned as replies
|
|
||||||
to non-CNAME queries. If we asked for foo.bar A, but it's a CNAME, udns
|
|
||||||
expects BOTH the CNAME itself and the target DN to be present in the reply.
|
|
||||||
In other words, udns DOES NOT RECURSE CNAMES. If we asked for foo.bar A,
|
|
||||||
but only record in reply was that foo.bar is a CNAME for bar.baz, udns will
|
|
||||||
return no records to an application (NXDOMAIN). Strictly speaking, udns
|
|
||||||
should repeat the query asking for bar.baz A, and recurse. But since it's
|
|
||||||
stub resolver, recursive resolver should recurse for us instead.
|
|
||||||
|
|
||||||
It's not very difficult to implement, however. Probably with some (global?)
|
|
||||||
flag to en/dis-able the feature. Provided there's some demand for it.
|
|
||||||
|
|
||||||
To clarify: udns handles CNAME recursion in a single reply packet just fine.
|
|
||||||
|
|
||||||
Note also that standard gethostbyname() routine does not recurse in this
|
|
||||||
situation, too.
|
|
||||||
|
|
||||||
Error reporting
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Too many places in the code (various failure paths) sets generic "TEMPFAIL"
|
|
||||||
error condition. For example, if no nameserver replied to our query, an
|
|
||||||
application will get generic TEMPFAIL, instead of something like TIMEDOUT.
|
|
||||||
This probably should be fixed, but most applications don't care about the
|
|
||||||
exact reasons of failure - 4 common cases are already too much:
|
|
||||||
- query returned some valid data
|
|
||||||
- NXDOMAIN
|
|
||||||
- valid domain but no data of requested type - =NXDOMAIN in most cases
|
|
||||||
- temporary error - this one sometimes (incorrectly!) treated as NXDOMAIN
|
|
||||||
by (naive) applications.
|
|
||||||
DNS isn't yes/no, it's at least 3 variants, temp err being the 3rd important
|
|
||||||
case! And adding more variations for the temp error case is complicating things
|
|
||||||
even more - again, from an application writer standpoint. For diagnostics,
|
|
||||||
such more specific error cases are of good help.
|
|
||||||
|
|
||||||
Planned API changes
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
At least one thing I want to change for 0.1 version is a way how queries are
|
|
||||||
submitted and how replies are handled.
|
|
||||||
|
|
||||||
I want to made dns_query object to be owned by an application. So that instead
|
|
||||||
of udns library allocating it for the lifetime of query, it will be pre-
|
|
||||||
allocated by an application. This simplifies and enhances query submitting
|
|
||||||
interface, and complicates it a bit too, in simplest cases.
|
|
||||||
|
|
||||||
Currently, we have:
|
|
||||||
|
|
||||||
dns_submit_dn(dn, cls, typ, flags, parse, cbck, data)
|
|
||||||
dns_submit_p(name, cls, typ, flags, parse, cbck, data)
|
|
||||||
dns_submit_a4(ctx, name, flags, cbck, data)
|
|
||||||
|
|
||||||
and so on -- with many parameters missed for type-specific cases, but generic
|
|
||||||
cases being too complex for most common usage.
|
|
||||||
|
|
||||||
Instead, with dns_query being owned by an app, we will be able to separately
|
|
||||||
set up various parts of the query - domain name (various forms), type&class,
|
|
||||||
parser, flags, callback... and even change them at runtime. And we will also
|
|
||||||
be able to reuse query structures, instead of allocating/freeing them every
|
|
||||||
time. So the whole thing will look something like:
|
|
||||||
|
|
||||||
q = dns_alloc_query();
|
|
||||||
dns_submit(dns_q_flags(dns_q_a4(q, name, cbck), DNS_F_NOSRCH), data);
|
|
||||||
|
|
||||||
The idea is to have a set of functions accepting struct dns_query* and
|
|
||||||
returning it (so the calls can be "nested" like the above), to set up
|
|
||||||
relevant parts of the query - specific type of callback, conversion from
|
|
||||||
(type-specific) query parameters into a domain name (this is for type-
|
|
||||||
specific query initializers), and setting various flags and options and
|
|
||||||
type&class things.
|
|
||||||
|
|
||||||
One example where this is almost essential - if we want to support
|
|
||||||
per-query set of nameservers (which isn't at all useless: imagine a
|
|
||||||
high-volume mail server, were we want to direct DNSBL queries to a separate
|
|
||||||
set of nameservers, and rDNS queries to their own set and so on). Adding
|
|
||||||
another argument (set of nameservers to use) to EVERY query submitting
|
|
||||||
routine is.. insane. Especially since in 99% cases it will be set to
|
|
||||||
default NULL. But with such "nesting" of query initializers, it becomes
|
|
||||||
trivial.
|
|
||||||
|
|
||||||
Another way to do the same is to manipulate query object right after a
|
|
||||||
query has been submitted, but before any events processing (during this
|
|
||||||
time, query object is allocated and initialized, but no actual network
|
|
||||||
packets were sent - it will happen on the next event processing). But
|
|
||||||
this way it become impossible to perform syncronous resolver calls, since
|
|
||||||
those calls hide query objects they use internally.
|
|
||||||
|
|
||||||
Speaking of replies handling - the planned change is to stop using dynamic
|
|
||||||
memory (malloc) inside the library. That is, instead of allocating a buffer
|
|
||||||
for a reply dynamically in a parsing routine (or memdup'ing the raw reply
|
|
||||||
packet if no parsing routine is specified), I want udns to return the packet
|
|
||||||
buffer it uses internally, and change parsing routines to expect a buffer
|
|
||||||
for result. When parsing, a routine will return true amount of memory it
|
|
||||||
will need to place the result, regardless of whenever it has enough room
|
|
||||||
or not, so that an application can (re)allocate properly sized buffer and
|
|
||||||
call a parsing routine again.
|
|
||||||
|
|
||||||
Another modification I plan to include is to have an ability to work in
|
|
||||||
terms of domain names (DNs) as used with on-wire DNS packets, not only
|
|
||||||
with asciiz representations of them. For this to work, the above two
|
|
||||||
changes (query submission and result passing) have to be completed first
|
|
||||||
(esp. the query submission part), so that it will be possible to specify
|
|
||||||
some additional query flags (for example) to request domain names instead
|
|
||||||
of the text strings, and to allow easy query submissions with either DNs
|
|
||||||
or text strings.
|
|
69
deps/udns/TODO
vendored
69
deps/udns/TODO
vendored
@ -1,69 +0,0 @@
|
|||||||
$Id: TODO,v 1.13 2007/01/15 21:19:08 mjt Exp $
|
|
||||||
|
|
||||||
The following is mostly an internal, not user-visible stuff.
|
|
||||||
|
|
||||||
* rearrange an API to make dns_query object owned by application,
|
|
||||||
so that it'll look like this:
|
|
||||||
struct dns_query *q;
|
|
||||||
q = udns_query_alloc(ctx);
|
|
||||||
udns_query_set(q, options, domain_name, flags, ...);
|
|
||||||
udns_query_submit(ctx, q);
|
|
||||||
or
|
|
||||||
udns_query_resolve(ctx, q);
|
|
||||||
|
|
||||||
* allow NULL callbacks? Or provide separate resolver
|
|
||||||
context list of queries which are done but wich did not
|
|
||||||
have callback, and dns_pick() routine to retrieve results
|
|
||||||
from this query, i.e. allow non-callback usage? The
|
|
||||||
non-callback usage may be handy sometimes (any *good*
|
|
||||||
example?), but it will be difficult to provide type-safe
|
|
||||||
non-callback interface due to various RR-specific types
|
|
||||||
in use.
|
|
||||||
|
|
||||||
* DNS_OPT_FLAGS should be DNS_OPT_ADDFLAGS and DNS_OPT_SETFLAGS.
|
|
||||||
Currently one can't add a single flag bit but preserve
|
|
||||||
existing bits... at least not without retrieving all current
|
|
||||||
flags before, which isn't that bad anyway.
|
|
||||||
|
|
||||||
* dns_set_opts() may process flags too (such as aaonly etc)
|
|
||||||
|
|
||||||
* a way to disable $NSCACHEIP et al processing?
|
|
||||||
(with now separate dns_init() and dns_reset(), it has finer
|
|
||||||
control, but still no way to init from system files but ignore
|
|
||||||
environment variables and the like)
|
|
||||||
|
|
||||||
* initialize/open the context automatically, and be more
|
|
||||||
liberal about initialization in general?
|
|
||||||
|
|
||||||
* dns_init(ctx, do_open) - make the parameter opposite, aka
|
|
||||||
dns_init(ctx, skip_open) ?
|
|
||||||
|
|
||||||
* allow TCP queue?
|
|
||||||
|
|
||||||
* And oh, qID should really be random. Or... not.
|
|
||||||
See notes in udns_resolver.c, dns_newid().
|
|
||||||
|
|
||||||
* more accurate error reporting. Currently, udns always returns TEMPFAIL,
|
|
||||||
but don't specify why it happened (ENOMEM, timeout, etc).
|
|
||||||
|
|
||||||
* check the error value returned by recvfrom() and
|
|
||||||
sendto() and determine which errors to ignore.
|
|
||||||
|
|
||||||
* maybe merge dns_timeouts() and dns_ioevent(), to have
|
|
||||||
only one entry point for everything? For traditional
|
|
||||||
select-loop-based eventloop it may be easier, but for
|
|
||||||
callback-driven event loops the two should be separate.
|
|
||||||
Provide an option, or a single dns_events() entry point
|
|
||||||
for select-loop approach, or just call dns_ioevent()
|
|
||||||
from within dns_timeouts() (probably after renaming
|
|
||||||
it to be dns_events()) ?
|
|
||||||
|
|
||||||
* implement /etc/hosts lookup too, ala [c-]ares??
|
|
||||||
|
|
||||||
* sortlist support?
|
|
||||||
|
|
||||||
* windows port? Oh no please!.. At least, I can't do it myself
|
|
||||||
because of the lack of platform.
|
|
||||||
Ok ok, the Windows port is in progress. Christian Prahauser
|
|
||||||
from cosy.sbg.ac.at is helping with that.
|
|
||||||
Other folks done some more work in this area.
|
|
168
deps/udns/configure
vendored
168
deps/udns/configure
vendored
@ -1,168 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
# $Id: configure,v 1.4 2007/01/07 23:19:40 mjt Exp $
|
|
||||||
# autoconf-style configuration script
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
name=udns
|
|
||||||
|
|
||||||
if [ -f udns.h -a -f udns_resolver.c ] ; then :
|
|
||||||
else
|
|
||||||
echo "configure: error: sources not found at `pwd`" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
options="ipv6"
|
|
||||||
|
|
||||||
for opt in $options; do
|
|
||||||
eval enable_$opt=
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -f config.status ]; then
|
|
||||||
. ./config.status
|
|
||||||
fi
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
opt=`echo "$1" | sed 's/^--[^-]*-//'`
|
|
||||||
case "$opt" in
|
|
||||||
ipv6|stats|master_dump|zlib|dso) ;;
|
|
||||||
master-dump) opt=master_dump ;;
|
|
||||||
*) echo "configure: unrecognized option \`$1'" >&2; exit 1;;
|
|
||||||
esac
|
|
||||||
eval enable_$opt=$2
|
|
||||||
}
|
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--disable-*|--without-*|--no-*) enable "$1" n;;
|
|
||||||
--enable-*|--with-*) enable "$1" y;;
|
|
||||||
--help | --hel | --he | --h | -help | -hel | -he | -h )
|
|
||||||
cat <<EOF
|
|
||||||
configure: configure $name package.
|
|
||||||
Usage: ./configure [options]
|
|
||||||
where options are:
|
|
||||||
--enable-option, --with-option --
|
|
||||||
enable the named option/feature
|
|
||||||
--disable-option, --without-option, --no-option --
|
|
||||||
disable the named option/feature
|
|
||||||
--help - print this help and exit
|
|
||||||
Optional features (all enabled by default if system supports a feature):
|
|
||||||
ipv6 - enable/disable IP version 6 (IPv6) support
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*) echo "configure: unknown option \`$1'" >&2; exit 1 ;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
. ./configure.lib
|
|
||||||
|
|
||||||
ac_msg "configure"
|
|
||||||
ac_result "$name package"
|
|
||||||
|
|
||||||
ac_prog_c_compiler_v
|
|
||||||
ac_prog_ranlib_v
|
|
||||||
|
|
||||||
ac_ign ac_yesno "for getopt()" ac_have GETOPT ac_link <<EOF
|
|
||||||
#include <stdio.h>
|
|
||||||
extern int optind;
|
|
||||||
extern char *optarg;
|
|
||||||
extern int getopt(int, char **, char *);
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
getopt(argc, argv, "abc");
|
|
||||||
return optarg ? optind : 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
ac_ign \
|
|
||||||
ac_yesno "for inet_pton() && inet_ntop()" \
|
|
||||||
ac_have INET_PTON_NTOP \
|
|
||||||
ac_link <<EOF
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
int main() {
|
|
||||||
char buf[64];
|
|
||||||
long x = 0;
|
|
||||||
inet_pton(AF_INET, &x, buf);
|
|
||||||
return inet_ntop(AF_INET, &x, buf, sizeof(buf));
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if ac_yesno "for socklen_t" ac_compile <<EOF
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
int foo() { socklen_t len; len = 0; return len; }
|
|
||||||
EOF
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
ac_define socklen_t int
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ac_library_find_v 'socket and connect' "" "-lsocket -lnsl" <<EOF
|
|
||||||
int main() { socket(); connect(); return 0; }
|
|
||||||
EOF
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
ac_fatal "cannot find libraries needed for sockets"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ n != "$enable_ipv6" ]; then
|
|
||||||
if ac_yesno "for IPv6" ac_have IPv6 ac_compile <<EOF
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
int main() {
|
|
||||||
struct sockaddr_in6 sa;
|
|
||||||
sa.sin6_family = AF_INET6;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
then :
|
|
||||||
elif [ "$enable_ipv6" ]; then
|
|
||||||
ac_fatal "IPv6 is requested but not available"
|
|
||||||
fi
|
|
||||||
fi # !disable_ipv6?
|
|
||||||
|
|
||||||
if ac_yesno "for poll()" ac_have POLL ac_link <<EOF
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
int main() {
|
|
||||||
struct pollfd pfd[2];
|
|
||||||
return poll(pfd, 2, 10);
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
ac_ign ac_yesno "for sys/select.h" ac_have SYS_SELECT_H ac_cpp <<EOF
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
ac_config_h
|
|
||||||
ac_output Makefile
|
|
||||||
ac_msg "creating config.status"
|
|
||||||
rm -f config.status
|
|
||||||
{
|
|
||||||
echo "# automatically generated by configure to hold command-line options"
|
|
||||||
echo
|
|
||||||
found=
|
|
||||||
for opt in $options; do
|
|
||||||
eval val=\$enable_$opt
|
|
||||||
if [ -n "$val" ]; then
|
|
||||||
echo enable_$opt=$val
|
|
||||||
found=y
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ ! "$found" ]; then
|
|
||||||
echo "# (no options encountered)"
|
|
||||||
fi
|
|
||||||
} > config.status
|
|
||||||
ac_result ok
|
|
||||||
|
|
||||||
ac_result "all done."
|
|
||||||
exit 0
|
|
268
deps/udns/configure.lib
vendored
268
deps/udns/configure.lib
vendored
@ -1,268 +0,0 @@
|
|||||||
# configure.lib
|
|
||||||
# a library of shell routines for simple autoconf system
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
ac_substitutes=
|
|
||||||
rm -f conftest* config.log
|
|
||||||
exec 5>config.log
|
|
||||||
cat <<EOF >&5
|
|
||||||
This file contains any messages produced by compilers etc while
|
|
||||||
running configure, to aid debugging if configure script makes a mistake.
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
case `echo "a\c"` in
|
|
||||||
*c*) ac_en=-n ac_ec= ;;
|
|
||||||
*) ac_en= ac_ec='\c' ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
##### Messages
|
|
||||||
ac_msg() {
|
|
||||||
echo $ac_en "$*... $ac_ec"
|
|
||||||
echo ">>> $*" >&5
|
|
||||||
}
|
|
||||||
ac_checking() {
|
|
||||||
echo $ac_en "checking $*... $ac_ec"
|
|
||||||
echo ">>> checking $*" >&5
|
|
||||||
}
|
|
||||||
ac_result() {
|
|
||||||
echo "$1"
|
|
||||||
echo "=== $1" >&5
|
|
||||||
}
|
|
||||||
ac_fatal() {
|
|
||||||
echo "configure: fatal: $*" >&2
|
|
||||||
echo "=== FATAL: $*" >&5
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
ac_warning() {
|
|
||||||
echo "configure: warning: $*" >&2
|
|
||||||
echo "=== WARNING: $*" >&5
|
|
||||||
}
|
|
||||||
ac_ign() {
|
|
||||||
"$@" || :
|
|
||||||
}
|
|
||||||
|
|
||||||
# ac_run command...
|
|
||||||
# captures output in conftest.out
|
|
||||||
ac_run() {
|
|
||||||
# apparently UnixWare (for one) /bin/sh optimizes the following "if"
|
|
||||||
# "away", by checking if there's such a command BEFORE redirecting
|
|
||||||
# output. So error message (like "gcc: command not found") goes
|
|
||||||
# to stderr instead of to conftest.out, and `cat conftest.out' below
|
|
||||||
# fails.
|
|
||||||
if "$@" >conftest.out 2>&1; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "==== Command invocation failed. Command line was:" >&5
|
|
||||||
echo "$*" >&5
|
|
||||||
echo "==== compiler input was:" >&5
|
|
||||||
cat conftest.c >&5
|
|
||||||
echo "==== output was:" >&5
|
|
||||||
cat conftest.out >&5
|
|
||||||
echo "====" >&5
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# common case for ac_verbose: yes/no result
|
|
||||||
ac_yesno() {
|
|
||||||
ac_checking "$1"
|
|
||||||
shift
|
|
||||||
if "$@"; then
|
|
||||||
ac_result yes
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
ac_result no
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_subst() {
|
|
||||||
ac_substitutes="$ac_substitutes $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_define() {
|
|
||||||
CDEFS="$CDEFS -D$1=${2:-1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_have() {
|
|
||||||
ac_what=$1; shift
|
|
||||||
if "$@"; then
|
|
||||||
ac_define HAVE_$ac_what
|
|
||||||
eval ac_have_$ac_what=yes
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
eval ac_have_$ac_what=no
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
##### Compiling, linking
|
|
||||||
|
|
||||||
# run a compiler
|
|
||||||
ac_run_compiler() {
|
|
||||||
rm -f conftest*; cat >conftest.c
|
|
||||||
ac_run $CC $CFLAGS $CDEFS "$@" conftest.c
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_compile() {
|
|
||||||
ac_run_compiler -c
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_link() {
|
|
||||||
ac_run_compiler -o conftest $LIBS "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_cpp() {
|
|
||||||
ac_run_compiler -E "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
### check for C compiler. Set $CC, $CFLAGS etc
|
|
||||||
ac_prog_c_compiler_v() {
|
|
||||||
ac_checking "for C compiler"
|
|
||||||
rm -f conftest*
|
|
||||||
echo 'int main(int argc, char **argv) { return 0; }' >conftest.c
|
|
||||||
|
|
||||||
if [ -n "$CC" ]; then
|
|
||||||
if ac_run $CC -o conftest conftest.c && ac_run ./conftest; then
|
|
||||||
ac_result "\$CC ($CC)"
|
|
||||||
else
|
|
||||||
ac_result no
|
|
||||||
ac_fatal "\$CC ($CC) is not a working compiler"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
for cc in gcc cc ; do
|
|
||||||
if ac_run $cc -o conftest conftest.c && ac_run ./conftest; then
|
|
||||||
ac_result "$cc"
|
|
||||||
CC=$cc
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ -z "$CC" ]; then
|
|
||||||
ac_result no
|
|
||||||
ac_fatal "no working C compiler found in \$PATH. please set \$CC variable"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -z "$CFLAGS" ]; then
|
|
||||||
if ac_yesno "whenever C compiler ($CC) is GNU CC" \
|
|
||||||
ac_grep_cpp yEs_mAsTeR <<EOF
|
|
||||||
#ifdef __GNUC__
|
|
||||||
yEs_mAsTeR;
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
then
|
|
||||||
CFLAGS="-Wall -W -O2 -pipe"
|
|
||||||
else
|
|
||||||
CFLAGS=-O
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
cc="$CC $CFLAGS"
|
|
||||||
ccld="$cc"
|
|
||||||
if [ -n "$LDFLAGS" ]; then ccld="$ccld $LDFLAGS"; fi
|
|
||||||
if [ -n "$LIBS" ]; then ccld="$ccld $LIBS"; fi
|
|
||||||
if ac_yesno "whenever the C compiler ($ccld)
|
|
||||||
can produce executables" \
|
|
||||||
ac_compile_run <<EOF
|
|
||||||
int main() { return 0; }
|
|
||||||
EOF
|
|
||||||
then :
|
|
||||||
else
|
|
||||||
ac_fatal "no working C compiler found"
|
|
||||||
fi
|
|
||||||
LD='$(CC)'
|
|
||||||
[ -n "$AR" ] || AR=ar
|
|
||||||
[ -n "$ARFLAGS" ] || ARFLAGS=rv
|
|
||||||
[ -n "$AWK" ] || AWK=awk
|
|
||||||
ac_substitutes="$ac_substitutes CC CFLAGS CDEFS LD LDFLAGS LIBS AR ARFLAGS AWK"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ac_prog_ranlib_v() {
|
|
||||||
ac_checking "for ranlib"
|
|
||||||
if [ -n "$RANLIB" ]; then
|
|
||||||
ac_result "\$RANLIB ($RANLIB)"
|
|
||||||
else
|
|
||||||
ifs="$IFS"
|
|
||||||
IFS=:
|
|
||||||
for dir in $PATH; do
|
|
||||||
[ -n "$dir" ] || dir=.
|
|
||||||
if [ -f $dir/ranlib ]; then
|
|
||||||
RANLIB=ranlib
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
IFS="$ifs"
|
|
||||||
if [ -z "$RANLIB" ]; then ac_result no; RANLIB=:
|
|
||||||
else ac_result "$RANLIB"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
ac_substitutes="$ac_substitutes RANLIB"
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_library_find_v() {
|
|
||||||
ac_checking "for libraries needed for $1"
|
|
||||||
shift
|
|
||||||
fond=
|
|
||||||
rm -f conftest*; cat >conftest.c
|
|
||||||
for lib in "$@"; do
|
|
||||||
if ac_run $CC $CFLAGS $LDFLAGS conftest.c -o conftest $LIBS $lib; then
|
|
||||||
found=y
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ ! "$found" ]; then
|
|
||||||
ac_result "not found"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if [ -z "$lib" ]; then
|
|
||||||
ac_result "ok (none needed)"
|
|
||||||
else
|
|
||||||
ac_result "ok ($lib)"
|
|
||||||
LIBS="$LIBS $lib"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_compile_run() {
|
|
||||||
ac_link "$@" && ac_run ./conftest
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_grep_cpp() {
|
|
||||||
pattern="$1"; shift
|
|
||||||
ac_cpp "$@" && grep "$pattern" conftest.out >/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_output() {
|
|
||||||
for var in $ac_substitutes; do
|
|
||||||
eval echo "\"s|@$var@|\$$var|\""
|
|
||||||
done >conftest.sed
|
|
||||||
for file in "$@"; do
|
|
||||||
ac_msg "creating $file"
|
|
||||||
if [ -f $file.in ]; then
|
|
||||||
sed -f conftest.sed $file.in > $file.tmp
|
|
||||||
mv -f $file.tmp $file
|
|
||||||
ac_result ok
|
|
||||||
else
|
|
||||||
ac_result failed
|
|
||||||
ac_fatal "$file.in not found"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
rm -f conftest*
|
|
||||||
}
|
|
||||||
|
|
||||||
ac_config_h() {
|
|
||||||
h=${1:-config.h}
|
|
||||||
ac_msg "creating $h"
|
|
||||||
rm -f $1.tmp
|
|
||||||
echo "/* automatically generated by configure. */" > $h.tmp
|
|
||||||
echo "$CDEFS" | tr ' ' '
|
|
||||||
' | sed -e 's/^-D/#define /' -e 's/=/ /' >> $h.tmp
|
|
||||||
if [ -f $h ] && cmp -s $h.tmp $h ; then
|
|
||||||
rm -f $h.tmp
|
|
||||||
ac_result unchanged
|
|
||||||
else
|
|
||||||
mv -f $h.tmp $h
|
|
||||||
ac_result ok
|
|
||||||
fi
|
|
||||||
CDEFS=-DHAVE_CONFIG_H
|
|
||||||
}
|
|
136
deps/udns/debian/changelog
vendored
136
deps/udns/debian/changelog
vendored
@ -1,136 +0,0 @@
|
|||||||
udns (0.0.9) unstable; urgency=low
|
|
||||||
|
|
||||||
* s/EOVERFLOW/ENFILE, partly to make win32 happy
|
|
||||||
|
|
||||||
* several win32 fixes
|
|
||||||
|
|
||||||
* don't use `class' in udns.h, to make C++ happy
|
|
||||||
(thanks Markus Koetter for pointing this out)
|
|
||||||
|
|
||||||
* fixed CNAME handling in dnsget tool. Another Thank You! goes
|
|
||||||
to Markus Koetter.
|
|
||||||
|
|
||||||
* NAPTR (RFC3403) support, thanks to Mikael Magnusson
|
|
||||||
<mikma at users.sourceforge.net> for this.
|
|
||||||
|
|
||||||
* more Win32 fixes from Mikael Magnusson. I have to admit
|
|
||||||
I never tried to compile it on Win32.
|
|
||||||
|
|
||||||
* added NOTES file
|
|
||||||
|
|
||||||
* reworked initialisation stuff. Minor API changes -- new dns_reset(),
|
|
||||||
dns_init() now has one more argument, corrections to dns_close(),
|
|
||||||
dns_open(), dns_free(). Cleaned up *_internal() routines.
|
|
||||||
|
|
||||||
* moved dns_init() routine into separate file.
|
|
||||||
|
|
||||||
* reworked dn suffix searching. As a result, query only has
|
|
||||||
dnsq_dn[] field -- no header and EDNS0 "suffix", and query
|
|
||||||
packet is now formatted in dns_send()
|
|
||||||
|
|
||||||
* added inet_XtoX.c - public domain implementations of inet_pton()
|
|
||||||
and inet_ntop(), inet_aton() and inet_ntoa() routines.
|
|
||||||
|
|
||||||
* added getopt.c - public domain implementation of getopt() routine.
|
|
||||||
|
|
||||||
* switched to autoconf-style configuration
|
|
||||||
|
|
||||||
* introduce dns_random16() to generate query IDs
|
|
||||||
(currently based on gettimeofday.tv_usec)
|
|
||||||
|
|
||||||
* dnsget: fix printing of -t ANY and -c any records,
|
|
||||||
thanks to Jaroslaw Rafa
|
|
||||||
|
|
||||||
* implement dns_ntop() and dns_pton() as either wrappers or
|
|
||||||
reimplementations (using inet_XtoX.c) of inet_ntop() and inet_pton().
|
|
||||||
Too much troubles with portability - it was a complete mess, each
|
|
||||||
OS has its own problems with them.
|
|
||||||
And use those routines everywhere.
|
|
||||||
|
|
||||||
* s/WIN32/WINDOWS/g to allow building on WIN64. Oh well.
|
|
||||||
|
|
||||||
* try to find query by ID first, don't drop header-only replies early.
|
|
||||||
This is in order to support FORMERR replies from nameservers which
|
|
||||||
don't understand EDNS0.
|
|
||||||
|
|
||||||
* retry queries w/o EDNS0 if sent with it and if
|
|
||||||
server reported FORMERR or NOTIMPL
|
|
||||||
|
|
||||||
* fixed debian/copyright and debian/control
|
|
||||||
|
|
||||||
* rblcheck revamp
|
|
||||||
|
|
||||||
-- Michael Tokarev <mjt@corpit.ru> Tue, 16 Jan 2007 00:00:28 +0300
|
|
||||||
|
|
||||||
udns (0.0.8) unstable; urgency=low
|
|
||||||
|
|
||||||
* don't compare sockaddr_in's, but individual parts only
|
|
||||||
(on some OSes, there are additional fields in this structure
|
|
||||||
so memcmp() does not quite work)
|
|
||||||
|
|
||||||
* use dnsc_t instead of unsigned char for DNs everywhere
|
|
||||||
|
|
||||||
* SRV records (rfc2782) parsing, thanks to
|
|
||||||
Thadeu Lima de Souza Cascardo.
|
|
||||||
|
|
||||||
* manpage fixes
|
|
||||||
|
|
||||||
-- Michael Tokarev <mjt@corpit.ru> Mon, 12 Sep 2005 16:06:45 +0400
|
|
||||||
|
|
||||||
udns (0.0.7) unstable; urgency=low
|
|
||||||
|
|
||||||
* added dnsget.1 and rblcheck.1 manpages.
|
|
||||||
|
|
||||||
* internal: use generic list implementation in udns_resolver.c
|
|
||||||
|
|
||||||
* don't assume only backward DN pointers in replies, allow forward
|
|
||||||
pointers too. This is quite large change, involves changing
|
|
||||||
parsing API all over the places.
|
|
||||||
|
|
||||||
* internal: typedef dnsc_t and dnscc_t for [const] unsigned char, to
|
|
||||||
make function prototypes shorter to better fit on a single line.
|
|
||||||
|
|
||||||
* in parsing routines, verify (assert) that the query type
|
|
||||||
is the one we can handle.
|
|
||||||
|
|
||||||
* recognize names (and resolve them) as nameservers in dnsget.
|
|
||||||
|
|
||||||
* when new request is submitted, don't send it immediately, but
|
|
||||||
add it into the head of the active queue with deadline=0.
|
|
||||||
This will allow us to tweak some query settings before it will
|
|
||||||
be processed.
|
|
||||||
Note API change: removed `now' argument from all dns_submit_*()
|
|
||||||
routines.
|
|
||||||
|
|
||||||
* use single per-context user timer, not per-query.
|
|
||||||
Note API change: different user timer callback
|
|
||||||
|
|
||||||
* add dnsc_salen field -- length of the socket address used
|
|
||||||
|
|
||||||
* fix dns_set_opt(DNS_OPT_FLAGS) which didn't work before
|
|
||||||
|
|
||||||
* allow to set some options for a context wich is open but with no
|
|
||||||
active queries
|
|
||||||
|
|
||||||
-- Michael Tokarev <mjt@corpit.ru> Thu, 5 May 2005 23:14:29 +0400
|
|
||||||
|
|
||||||
udns (0.0.6) unstable; urgency=low
|
|
||||||
|
|
||||||
* 0.0.6 release.
|
|
||||||
ALOT of changes all over. Keep 'em in CVS logs!
|
|
||||||
|
|
||||||
-- Michael Tokarev <mjt@corpit.ru> Fri, 8 Apr 2005 19:51:38 +0400
|
|
||||||
|
|
||||||
udns (0.0.5) unstable; urgency=low
|
|
||||||
|
|
||||||
* Initial Release.
|
|
||||||
* Provides 3 packages:
|
|
||||||
libudns0 - shared library
|
|
||||||
libudns-dev - development files and static library
|
|
||||||
udns-utils - dnsget, rblcheck
|
|
||||||
|
|
||||||
-- Michael Tokarev <mjt@corpit.ru> Thu, 7 Apr 2005 00:05:24 +0400
|
|
||||||
|
|
||||||
Local variables:
|
|
||||||
mode: debian-changelog
|
|
||||||
End:
|
|
33
deps/udns/debian/control
vendored
33
deps/udns/debian/control
vendored
@ -1,33 +0,0 @@
|
|||||||
Source: udns
|
|
||||||
Priority: optional
|
|
||||||
Maintainer: Michael Tokarev <mjt@corpit.ru>
|
|
||||||
Build-Depends: debhelper (>= 4.0.0)
|
|
||||||
Standards-Version: 3.7.2
|
|
||||||
|
|
||||||
Package: libudns0
|
|
||||||
Section: libs
|
|
||||||
Architecture: any
|
|
||||||
Depends: ${shlibs:Depends}
|
|
||||||
Description: async-capable DNS stub resolver library
|
|
||||||
libudns0 package provides libudns shared library needed
|
|
||||||
to run programs using it
|
|
||||||
|
|
||||||
Package: libudns-dev
|
|
||||||
Section: libdevel
|
|
||||||
Architecture: any
|
|
||||||
Depends: libudns0 (= ${Source-Version})
|
|
||||||
Description: async-capable DNS stub resolver library, development files
|
|
||||||
This package provides development files needed
|
|
||||||
to build programs using udns library
|
|
||||||
|
|
||||||
Package: udns-utils
|
|
||||||
Section: net
|
|
||||||
Architecture: any
|
|
||||||
Depends: ${shlibs:Depends}
|
|
||||||
Conflicts: rblcheck
|
|
||||||
Description: Several DNS-related utilities built on top of udns library
|
|
||||||
This package includes the following utilities:
|
|
||||||
dnsget - a simple DNS query tool, like `host' or `dig' for usage from
|
|
||||||
a command line, and dnsip, dnsname etc for usage in scripts
|
|
||||||
rblcheck - DNSBL (rbl) checker
|
|
||||||
All the utilities are built using udns library
|
|
23
deps/udns/debian/copyright
vendored
23
deps/udns/debian/copyright
vendored
@ -1,23 +0,0 @@
|
|||||||
This is udns, written and maintained by Michael Tokarev <mjt@corpit.ru>
|
|
||||||
|
|
||||||
The original source can always be found at:
|
|
||||||
http://www.corpit.ru/mjt/udns.html
|
|
||||||
|
|
||||||
Copyright (C) 2005,2006,2007 Michael Tokarev
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
General Lesser Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
On Debian systems, the complete text of the GNU Lesser General
|
|
||||||
Public License can be found in `/usr/share/common-licenses/LGPL'.
|
|
93
deps/udns/debian/rules
vendored
93
deps/udns/debian/rules
vendored
@ -1,93 +0,0 @@
|
|||||||
#!/usr/bin/make -f
|
|
||||||
# -*- makefile -*-
|
|
||||||
# This file was originally written by Joey Hess and Craig Small.
|
|
||||||
# As a special exception, when this file is copied by dh-make into a
|
|
||||||
# dh-make output file, you may use that output file without restriction.
|
|
||||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
|
||||||
|
|
||||||
# Uncomment this to turn on verbose mode.
|
|
||||||
#export DH_VERBOSE=1
|
|
||||||
export DH_COMPAT=4
|
|
||||||
|
|
||||||
CFLAGS = -Wall -W -Wmissing-prototypes -g
|
|
||||||
CDEFS = -DHAVE_POOL
|
|
||||||
|
|
||||||
INSTALL = install
|
|
||||||
INSTALL_PROGRAM = $(INSTALL) -p
|
|
||||||
INSTALL_DATA = $(INSTALL) -p -m0644
|
|
||||||
|
|
||||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
|
|
||||||
CFLAGS += -O0
|
|
||||||
else
|
|
||||||
CFLAGS += -O2
|
|
||||||
endif
|
|
||||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
|
||||||
INSTALL_PROGRAM += -s
|
|
||||||
endif
|
|
||||||
ifeq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
|
|
||||||
# CDEFS += -DNDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
SOVER = 0
|
|
||||||
|
|
||||||
config.h: ./configure Makefile.in
|
|
||||||
dh_testdir
|
|
||||||
./configure --enable-ipv6
|
|
||||||
|
|
||||||
build: build-stamp
|
|
||||||
build-stamp: config.h
|
|
||||||
dh_testdir
|
|
||||||
$(MAKE) CFLAGS="$(CFLAGS)" SOVER=$(SOVER) \
|
|
||||||
staticlib sharedlib rblcheck_s dnsget_s
|
|
||||||
mv -f dnsget_s dnsget
|
|
||||||
mv -f rblcheck_s rblcheck
|
|
||||||
mv -f libudns_s.so libudns.so
|
|
||||||
echo
|
|
||||||
touch $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
dh_testdir
|
|
||||||
rm -f build-stamp
|
|
||||||
if [ -f Makefile ]; then $(MAKE) distclean; fi
|
|
||||||
dh_clean
|
|
||||||
|
|
||||||
install: build
|
|
||||||
dh_testdir
|
|
||||||
dh_testroot
|
|
||||||
dh_clean
|
|
||||||
dh_installdirs
|
|
||||||
dh_installdocs -A NEWS
|
|
||||||
|
|
||||||
# libudns
|
|
||||||
dh_install -plibudns$(SOVER) libudns.so.$(SOVER) usr/lib
|
|
||||||
|
|
||||||
# libudns-dev
|
|
||||||
dh_install -plibudns-dev libudns.a libudns.so usr/lib
|
|
||||||
dh_install -plibudns-dev udns.h usr/include
|
|
||||||
dh_installman -plibudns-dev udns.3
|
|
||||||
dh_installdocs -plibudns-dev TODO NOTES
|
|
||||||
dh_installexamples -plibudns-dev ex-rdns.c
|
|
||||||
|
|
||||||
# udns-utils
|
|
||||||
dh_install -pudns-utils dnsget rblcheck usr/bin
|
|
||||||
dh_installman -pudns-utils dnsget.1 rblcheck.1
|
|
||||||
|
|
||||||
binary-indep: build install
|
|
||||||
|
|
||||||
binary-arch: build install
|
|
||||||
dh_testdir
|
|
||||||
dh_testroot
|
|
||||||
dh_installchangelogs
|
|
||||||
dh_installdocs
|
|
||||||
dh_strip
|
|
||||||
dh_compress
|
|
||||||
dh_fixperms
|
|
||||||
dh_makeshlibs -V
|
|
||||||
dh_installdeb
|
|
||||||
dh_shlibdeps -L libudns$(SOVER) -l .
|
|
||||||
dh_gencontrol
|
|
||||||
dh_md5sums
|
|
||||||
dh_builddeb
|
|
||||||
|
|
||||||
binary: binary-indep binary-arch
|
|
||||||
.PHONY: build clean binary-indep binary-arch binary install
|
|
182
deps/udns/dnsget.1
vendored
182
deps/udns/dnsget.1
vendored
@ -1,182 +0,0 @@
|
|||||||
.\" $Id: dnsget.1,v 1.3 2005/04/20 00:55:34 mjt Exp $
|
|
||||||
.\" dnsget manpage
|
|
||||||
.\"
|
|
||||||
.\" Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
.\" This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
.\"
|
|
||||||
.\" This library is free software; you can redistribute it and/or
|
|
||||||
.\" modify it under the terms of the GNU Lesser General Public
|
|
||||||
.\" License as published by the Free Software Foundation; either
|
|
||||||
.\" version 2.1 of the License, or (at your option) any later version.
|
|
||||||
.\"
|
|
||||||
.\" This library is distributed in the hope that it will be useful,
|
|
||||||
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
.\" Lesser General Public License for more details.
|
|
||||||
.\"
|
|
||||||
.\" You should have received a copy of the GNU Lesser General Public
|
|
||||||
.\" License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
.\" write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
.\" Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
.TH dnsget 1 "Apr 2005" "User Utilities"
|
|
||||||
|
|
||||||
.SH NAME
|
|
||||||
dnsget \- DNS lookup utility
|
|
||||||
|
|
||||||
.SH SYNOPSYS
|
|
||||||
.B dnsget
|
|
||||||
.RB [\| \-v \||\| \-q \|]
|
|
||||||
.RB [\| \-c
|
|
||||||
.IR class \|]
|
|
||||||
.RB [\| \-t
|
|
||||||
.IR type \|]
|
|
||||||
.RB [\| \-o
|
|
||||||
.IR option : value \]
|
|
||||||
.IR name \|.\|.\|.
|
|
||||||
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.B dnsget
|
|
||||||
is a simple command-line to perform DNS lookups, similar to
|
|
||||||
.BR host (1)
|
|
||||||
and
|
|
||||||
.BR dig (1).
|
|
||||||
It is useable for both interactive/debugging scenarious and
|
|
||||||
in scripts.
|
|
||||||
The program is implemented using
|
|
||||||
.BR udns (3)
|
|
||||||
library.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
By default,
|
|
||||||
.B dnsget
|
|
||||||
produces a human-readable output, similar to
|
|
||||||
.RS
|
|
||||||
.nf
|
|
||||||
alias.example.com. CNAME www.example.com.
|
|
||||||
www.example.com. A 192.168.1.1
|
|
||||||
www.example.com. MX 10 mx.example.com.
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
which is just sufficient to see how a given name resolves.
|
|
||||||
Output format is controllable with
|
|
||||||
.B \-v
|
|
||||||
and
|
|
||||||
.B \-q
|
|
||||||
options -- the former increases verbosity level up to printing
|
|
||||||
the whole DNS contents of all packets sent and received, which
|
|
||||||
is suitable for debugging DNS problems, while the latter reduces
|
|
||||||
the level, making output more quiet, up to bare result with no
|
|
||||||
error messages, which is good for scripts.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
|
|
||||||
The following options are recognized by
|
|
||||||
.BR dnsget :
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-v
|
|
||||||
produce more detailed output. More
|
|
||||||
.BR \-v 's
|
|
||||||
means more details will be produced. With single
|
|
||||||
.BR \-v , dnsget
|
|
||||||
will print contents of all received DNS packets (in a readable format),
|
|
||||||
while with
|
|
||||||
.BR \-vv ,
|
|
||||||
it will output all outgoing DNS packets too.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-q
|
|
||||||
the opposite for \fB\-v\fR -- produce less detailed output.
|
|
||||||
With single
|
|
||||||
.BR \-q , dnsget
|
|
||||||
will only show (decoded) data from final DNS resource records (RR),
|
|
||||||
while
|
|
||||||
.B \-qq
|
|
||||||
also suppresses error messages.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\fB\-t \fItype\fR
|
|
||||||
request record(s) of the given type \fItype\fR. By default,
|
|
||||||
.B dnsget
|
|
||||||
will ask for IPv4 address (A) record, or for PTR record if the
|
|
||||||
argument in question is an IPv4 or IPv6 address. Recognized
|
|
||||||
types include A, AAAA, MX, TXT, CNAME, PTR, NS, SOA, ANY and
|
|
||||||
others.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\fB\-c \fIclass\fR
|
|
||||||
request DNS record(s) of the given class \fIclass\fR. By
|
|
||||||
default
|
|
||||||
.B dnsget
|
|
||||||
uses IN class. Valid classes include IN, CH, HS, ANY.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-a
|
|
||||||
(compatibility option). Equivalent to setting query type to
|
|
||||||
.B ANY
|
|
||||||
and increasing verbosity level
|
|
||||||
.RB ( \-v ).
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-C
|
|
||||||
(planned)
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-x
|
|
||||||
(planned)
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\fB\-o \fIoption\fR:\fIvalue\fR
|
|
||||||
Set resolver option \fIoption\fR to the value \fIvalue\fR
|
|
||||||
(may be specified several times). The same as setting
|
|
||||||
.RB $ RES_OPTIONS
|
|
||||||
environment variable. The following options are recognized:
|
|
||||||
.RS
|
|
||||||
.TP
|
|
||||||
\fBtimeout\fR:\fIsec\fR
|
|
||||||
Set initial query timeout to \fIsec\fR.
|
|
||||||
.TP
|
|
||||||
\fBattempts\fR:\fInum\fR
|
|
||||||
(re)try every query \fInum\fR times before failing.
|
|
||||||
.TP
|
|
||||||
\fBudpbuf\fR:\fIbytes\fR
|
|
||||||
set DNS UDP buffer size to \fIbytes\fR bytes. Valid values
|
|
||||||
are from 512 to 65535. If \fIbytes\fR is greather than 512,
|
|
||||||
EDNS0 (RFC 2671) extensions will be used.
|
|
||||||
.TP
|
|
||||||
\fBport\fR:\fInum\fR
|
|
||||||
Use given UDP port number \fInum\fR instead of the default port 53 (domain).
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.TP
|
|
||||||
\fB\-n \fInameserver\fR
|
|
||||||
Use the given nameserver(s) (may be specified more than once)
|
|
||||||
instead of the default. Using this option has the same same effect as
|
|
||||||
.RB $ NSCACHEIP
|
|
||||||
or
|
|
||||||
.RB $ NAMESERVERS
|
|
||||||
environment variables, with the only difference that only IPv4 addresses
|
|
||||||
are recognized for now, and it is possible to specify names (which will
|
|
||||||
be resolved using default settings) instead of IP addresses.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-h
|
|
||||||
print short help and exit.
|
|
||||||
|
|
||||||
.SH "RETURN VALUE"
|
|
||||||
When all names where resovled successefully,
|
|
||||||
.B dnsget
|
|
||||||
exits with zero exit status. If at least one name was not found,
|
|
||||||
.B dnsget
|
|
||||||
will exit with return code 100. If some other error occured during
|
|
||||||
name resolution, it will exit with code 99. In case of usage or
|
|
||||||
initialization error,
|
|
||||||
.B dnsget
|
|
||||||
will return 1.
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR host (1)
|
|
||||||
.BR dig (1)
|
|
||||||
.BR resolv.conf (5)
|
|
||||||
.BR udns (3).
|
|
726
deps/udns/dnsget.c
vendored
726
deps/udns/dnsget.c
vendored
@ -1,726 +0,0 @@
|
|||||||
/* $Id: dnsget.c,v 1.31 2007/01/08 01:14:44 mjt Exp $
|
|
||||||
simple host/dig-like application using UDNS library
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
#ifdef WINDOWS
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_GETOPT
|
|
||||||
# include "getopt.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef AF_INET6
|
|
||||||
# define AF_INET6 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *progname;
|
|
||||||
static int verbose = 1;
|
|
||||||
static int errors;
|
|
||||||
static int notfound;
|
|
||||||
|
|
||||||
/* verbosity level:
|
|
||||||
* <0 - bare result
|
|
||||||
* 0 - bare result and error messages
|
|
||||||
* 1 - readable result
|
|
||||||
* 2 - received packet contents and `trying ...' stuff
|
|
||||||
* 3 - sent and received packet contents
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void die(int errnum, const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fprintf(stderr, "%s: ", progname);
|
|
||||||
va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
|
|
||||||
if (errnum) fprintf(stderr, ": %s\n", strerror(errnum));
|
|
||||||
else putc('\n', stderr);
|
|
||||||
fflush(stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *dns_xntop(int af, const void *src) {
|
|
||||||
static char buf[6*5+4*4];
|
|
||||||
return dns_ntop(af, src, buf, sizeof(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct query {
|
|
||||||
const char *name; /* original query string */
|
|
||||||
unsigned char *dn; /* the DN being looked up */
|
|
||||||
enum dns_type qtyp; /* type of the query */
|
|
||||||
};
|
|
||||||
|
|
||||||
static void query_free(struct query *q) {
|
|
||||||
free(q->dn);
|
|
||||||
free(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct query *
|
|
||||||
query_new(const char *name, const unsigned char *dn, enum dns_type qtyp) {
|
|
||||||
struct query *q = malloc(sizeof(*q));
|
|
||||||
unsigned l = dns_dnlen(dn);
|
|
||||||
unsigned char *cdn = malloc(l);
|
|
||||||
if (!q || !cdn) die(0, "out of memory");
|
|
||||||
memcpy(cdn, dn, l);
|
|
||||||
q->name = name;
|
|
||||||
q->dn = cdn;
|
|
||||||
q->qtyp = qtyp;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum dns_class qcls = DNS_C_IN;
|
|
||||||
|
|
||||||
static void
|
|
||||||
dnserror(struct query *q, int errnum) {
|
|
||||||
if (verbose >= 0)
|
|
||||||
fprintf(stderr, "%s: unable to lookup %s record for %s: %s\n", progname,
|
|
||||||
dns_typename(q->qtyp), dns_dntosp(q->dn), dns_strerror(errnum));
|
|
||||||
if (errnum == DNS_E_NXDOMAIN || errnum == DNS_E_NODATA)
|
|
||||||
++notfound;
|
|
||||||
else
|
|
||||||
++errors;
|
|
||||||
query_free(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const unsigned char *
|
|
||||||
printtxt(const unsigned char *c) {
|
|
||||||
unsigned n = *c++;
|
|
||||||
const unsigned char *e = c + n;
|
|
||||||
if (verbose > 0) while(c < e) {
|
|
||||||
if (*c < ' ' || *c >= 127) printf("\\%02x", *c);
|
|
||||||
else if (*c == '\\' || *c == '"') printf("\\%c", *c);
|
|
||||||
else putchar(*c);
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fwrite(c, n, 1, stdout);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
printhex(const unsigned char *c, const unsigned char *e) {
|
|
||||||
while(c < e)
|
|
||||||
printf("%02x", *c++);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char to_b64[] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
static void
|
|
||||||
printb64(const unsigned char *c, const unsigned char *e) {
|
|
||||||
while(c < e) {
|
|
||||||
putchar(to_b64[c[0] >> 2]);
|
|
||||||
if (c+1 < e) {
|
|
||||||
putchar(to_b64[(c[0] & 0x3) << 4 | c[1] >> 4]);
|
|
||||||
if (c+2 < e) {
|
|
||||||
putchar(to_b64[(c[1] & 0xf) << 2 | c[2] >> 6]);
|
|
||||||
putchar(to_b64[c[2] & 0x3f]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
putchar(to_b64[(c[1] & 0xf) << 2]);
|
|
||||||
putchar('=');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
putchar(to_b64[(c[0] & 0x3) << 4]);
|
|
||||||
putchar('=');
|
|
||||||
putchar('=');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
printdate(time_t time) {
|
|
||||||
struct tm *tm = gmtime(&time);
|
|
||||||
printf("%04d%02d%02d%02d%02d%02d",
|
|
||||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
||||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
printrr(const struct dns_parse *p, struct dns_rr *rr) {
|
|
||||||
const unsigned char *pkt = p->dnsp_pkt;
|
|
||||||
const unsigned char *end = p->dnsp_end;
|
|
||||||
const unsigned char *dptr = rr->dnsrr_dptr;
|
|
||||||
const unsigned char *dend = rr->dnsrr_dend;
|
|
||||||
unsigned char *dn = rr->dnsrr_dn;
|
|
||||||
const unsigned char *c;
|
|
||||||
unsigned n;
|
|
||||||
|
|
||||||
if (verbose > 0) {
|
|
||||||
if (verbose > 1) {
|
|
||||||
if (!p->dnsp_rrl && !rr->dnsrr_dn[0] && rr->dnsrr_typ == DNS_T_OPT) {
|
|
||||||
printf(";EDNS0 OPT record (UDPsize: %d): %d bytes\n",
|
|
||||||
rr->dnsrr_cls, rr->dnsrr_dsz);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n = printf("%s.", dns_dntosp(rr->dnsrr_dn));
|
|
||||||
printf("%s%u\t%s\t%s\t",
|
|
||||||
n > 15 ? "\t" : n > 7 ? "\t\t" : "\t\t\t",
|
|
||||||
rr->dnsrr_ttl,
|
|
||||||
dns_classname(rr->dnsrr_cls),
|
|
||||||
dns_typename(rr->dnsrr_typ));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("%s. %s ", dns_dntosp(rr->dnsrr_dn), dns_typename(rr->dnsrr_typ));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(rr->dnsrr_typ) {
|
|
||||||
|
|
||||||
case DNS_T_CNAME:
|
|
||||||
case DNS_T_PTR:
|
|
||||||
case DNS_T_NS:
|
|
||||||
case DNS_T_MB:
|
|
||||||
case DNS_T_MD:
|
|
||||||
case DNS_T_MF:
|
|
||||||
case DNS_T_MG:
|
|
||||||
case DNS_T_MR:
|
|
||||||
if (dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN) <= 0) goto xperr;
|
|
||||||
printf("%s.", dns_dntosp(dn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_A:
|
|
||||||
if (rr->dnsrr_dsz != 4) goto xperr;
|
|
||||||
printf("%d.%d.%d.%d", dptr[0], dptr[1], dptr[2], dptr[3]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_AAAA:
|
|
||||||
if (rr->dnsrr_dsz != 16) goto xperr;
|
|
||||||
printf("%s", dns_xntop(AF_INET6, dptr));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_MX:
|
|
||||||
c = dptr + 2;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
|
|
||||||
printf("%d %s.", dns_get16(dptr), dns_dntosp(dn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_TXT:
|
|
||||||
/* first verify it */
|
|
||||||
for(c = dptr; c < dend; c += n) {
|
|
||||||
n = *c++;
|
|
||||||
if (c + n > dend) goto xperr;
|
|
||||||
}
|
|
||||||
c = dptr; n = 0;
|
|
||||||
while (c < dend) {
|
|
||||||
if (verbose > 0) printf(n++ ? "\" \"":"\"");
|
|
||||||
c = printtxt(c);
|
|
||||||
}
|
|
||||||
if (verbose > 0) putchar('"');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_HINFO: /* CPU, OS */
|
|
||||||
c = dptr;
|
|
||||||
n = *c++; if ((c += n) >= dend) goto xperr;
|
|
||||||
n = *c++; if ((c += n) != dend) goto xperr;
|
|
||||||
c = dptr;
|
|
||||||
if (verbose > 0) putchar('"');
|
|
||||||
c = printtxt(c);
|
|
||||||
if (verbose > 0) printf("\" \""); else putchar(' ');
|
|
||||||
printtxt(c);
|
|
||||||
if (verbose > 0) putchar('"');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_WKS:
|
|
||||||
c = dptr;
|
|
||||||
if (dptr + 4 + 2 >= end) goto xperr;
|
|
||||||
printf("%s %d", dns_xntop(AF_INET, dptr), dptr[4]);
|
|
||||||
c = dptr + 5;
|
|
||||||
for (n = 0; c < dend; ++c, n += 8) {
|
|
||||||
if (*c) {
|
|
||||||
unsigned b;
|
|
||||||
for (b = 0; b < 8; ++b)
|
|
||||||
if (*c & (1 << (7-b))) printf(" %d", n + b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_SRV: /* prio weight port targetDN */
|
|
||||||
c = dptr;
|
|
||||||
c += 2 + 2 + 2;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
|
|
||||||
c = dptr;
|
|
||||||
printf("%d %d %d %s.",
|
|
||||||
dns_get16(c+0), dns_get16(c+2), dns_get16(c+4),
|
|
||||||
dns_dntosp(dn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_NAPTR: /* order pref flags serv regexp repl */
|
|
||||||
c = dptr;
|
|
||||||
c += 4; /* order, pref */
|
|
||||||
for (n = 0; n < 3; ++n)
|
|
||||||
if (c >= dend) goto xperr;
|
|
||||||
else c += *c + 1;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr;
|
|
||||||
c = dptr;
|
|
||||||
printf("%u %u", dns_get16(c+0), dns_get16(c+2));
|
|
||||||
c += 4;
|
|
||||||
for(n = 0; n < 3; ++n) {
|
|
||||||
putchar(' ');
|
|
||||||
if (verbose > 0) putchar('"');
|
|
||||||
c = printtxt(c);
|
|
||||||
if (verbose > 0) putchar('"');
|
|
||||||
}
|
|
||||||
printf(" %s.", dns_dntosp(dn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_KEY: /* flags(2) proto(1) algo(1) pubkey */
|
|
||||||
c = dptr;
|
|
||||||
if (c + 2 + 1 + 1 > dend) goto xperr;
|
|
||||||
printf("%d %d %d", dns_get16(c), c[2], c[3]);
|
|
||||||
c += 2 + 1 + 1;
|
|
||||||
if (c < dend) {
|
|
||||||
putchar(' ');
|
|
||||||
printb64(c, dend);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_SIG:
|
|
||||||
/* type(2) algo(1) labels(1) ottl(4) sexp(4) sinc(4) tag(2) sdn sig */
|
|
||||||
c = dptr;
|
|
||||||
c += 2 + 1 + 1 + 4 + 4 + 4 + 2;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr;
|
|
||||||
printf("%d %u %u %u ",
|
|
||||||
dns_get16(dptr), dptr[2], dptr[3], dns_get32(dptr+4));
|
|
||||||
printdate(dns_get32(dptr+8));
|
|
||||||
putchar(' ');
|
|
||||||
printdate(dns_get32(dptr+12));
|
|
||||||
printf(" %d %s. ", dns_get16(dptr+10), dns_dntosp(dn));
|
|
||||||
printb64(c, dend);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if 0 /* unused RR types? */
|
|
||||||
case DNS_T_DS:
|
|
||||||
c = dptr;
|
|
||||||
if (c + 2 + 2 >= dend) goto xperr;
|
|
||||||
printf("%u %u %u ", dns_get16(c), c[2], c[3]);
|
|
||||||
printhex(c + 4, dend);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_NSEC:
|
|
||||||
c = dptr;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr;
|
|
||||||
printf("%s.", dns_dntosp(dn));
|
|
||||||
unfinished.
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
case DNS_T_SOA:
|
|
||||||
c = dptr;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
|
|
||||||
dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
|
|
||||||
c + 4*5 != dend)
|
|
||||||
goto xperr;
|
|
||||||
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
|
|
||||||
printf("%s. ", dns_dntosp(dn));
|
|
||||||
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
|
|
||||||
printf("%s. ", dns_dntosp(dn));
|
|
||||||
printf("%u %u %u %u %u",
|
|
||||||
dns_get32(dptr), dns_get32(dptr+4), dns_get32(dptr+8),
|
|
||||||
dns_get32(dptr+12), dns_get32(dptr+16));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_MINFO:
|
|
||||||
c = dptr;
|
|
||||||
if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
|
|
||||||
dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 ||
|
|
||||||
c != dend)
|
|
||||||
goto xperr;
|
|
||||||
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
|
|
||||||
printf("%s. ", dns_dntosp(dn));
|
|
||||||
dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN);
|
|
||||||
printf("%s.", dns_dntosp(dn));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_NULL:
|
|
||||||
default:
|
|
||||||
printhex(dptr, dend);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
return;
|
|
||||||
|
|
||||||
xperr:
|
|
||||||
printf("<parse error>\n");
|
|
||||||
++errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
printsection(struct dns_parse *p, int nrr, const char *sname) {
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r;
|
|
||||||
if (!nrr) return 0;
|
|
||||||
if (verbose > 1) printf("\n;; %s section (%d):\n", sname, nrr);
|
|
||||||
|
|
||||||
p->dnsp_rrl = nrr;
|
|
||||||
while((r = dns_nextrr(p, &rr)) > 0)
|
|
||||||
printrr(p, &rr);
|
|
||||||
if (r < 0) printf("<<ERROR>>\n");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dbgcb will only be called if verbose > 1 */
|
|
||||||
static void
|
|
||||||
dbgcb(int code, const struct sockaddr *sa, unsigned slen,
|
|
||||||
const unsigned char *pkt, int r,
|
|
||||||
const struct dns_query *unused_q, void *unused_data) {
|
|
||||||
struct dns_parse p;
|
|
||||||
const unsigned char *cur, *end;
|
|
||||||
int numqd;
|
|
||||||
|
|
||||||
if (code > 0) {
|
|
||||||
printf(";; trying %s.\n", dns_dntosp(dns_payload(pkt)));
|
|
||||||
printf(";; sending %d bytes query to ", r);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf(";; received %d bytes response from ", r);
|
|
||||||
if (sa->sa_family == AF_INET && slen >= sizeof(struct sockaddr_in))
|
|
||||||
printf("%s port %d\n",
|
|
||||||
dns_xntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr),
|
|
||||||
htons(((struct sockaddr_in*)sa)->sin_port));
|
|
||||||
#ifdef HAVE_IPv6
|
|
||||||
else if (sa->sa_family == AF_INET6 && slen >= sizeof(struct sockaddr_in6))
|
|
||||||
printf("%s port %d\n",
|
|
||||||
dns_xntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr),
|
|
||||||
htons(((struct sockaddr_in6*)sa)->sin6_port));
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
printf("<<unknown socket type %d>>\n", sa->sa_family);
|
|
||||||
if (code > 0 && verbose < 3) {
|
|
||||||
putchar('\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == -2) printf(";; reply from unexpected source\n");
|
|
||||||
if (code == -5) printf(";; reply to a query we didn't sent (or old)\n");
|
|
||||||
if (r < DNS_HSIZE) {
|
|
||||||
printf(";; short packet (%d bytes)\n", r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (dns_opcode(pkt) != 0)
|
|
||||||
printf(";; unexpected opcode %d\n", dns_opcode(pkt));
|
|
||||||
if (dns_tc(pkt) != 0)
|
|
||||||
printf(";; warning: TC bit set, probably incomplete reply\n");
|
|
||||||
|
|
||||||
printf(";; ->>HEADER<<- opcode: ");
|
|
||||||
switch(dns_opcode(pkt)) {
|
|
||||||
case 0: printf("QUERY"); break;
|
|
||||||
case 1: printf("IQUERY"); break;
|
|
||||||
case 2: printf("STATUS"); break;
|
|
||||||
default: printf("UNKNOWN(%u)", dns_opcode(pkt)); break;
|
|
||||||
}
|
|
||||||
printf(", status: %s, id: %d, size: %d\n;; flags:",
|
|
||||||
dns_rcodename(dns_rcode(pkt)), dns_qid(pkt), r);
|
|
||||||
if (dns_qr(pkt)) printf(" qr");
|
|
||||||
if (dns_rd(pkt)) printf(" rd");
|
|
||||||
if (dns_ra(pkt)) printf(" ra");
|
|
||||||
if (dns_aa(pkt)) printf(" aa");
|
|
||||||
if (dns_tc(pkt)) printf(" tc");
|
|
||||||
numqd = dns_numqd(pkt);
|
|
||||||
printf("; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d\n",
|
|
||||||
numqd, dns_numan(pkt), dns_numns(pkt), dns_numar(pkt));
|
|
||||||
if (numqd != 1)
|
|
||||||
printf(";; unexpected number of entries in QUERY section: %d\n",
|
|
||||||
numqd);
|
|
||||||
printf("\n;; QUERY SECTION (%d):\n", numqd);
|
|
||||||
cur = dns_payload(pkt);
|
|
||||||
end = pkt + r;
|
|
||||||
while(numqd--) {
|
|
||||||
if (dns_getdn(pkt, &cur, end, p.dnsp_dnbuf, DNS_MAXDN) <= 0 ||
|
|
||||||
cur + 4 > end) {
|
|
||||||
printf("; invalid query section\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r = printf(";%s.", dns_dntosp(p.dnsp_dnbuf));
|
|
||||||
printf("%s%s\t%s\n",
|
|
||||||
r > 23 ? "\t" : r > 15 ? "\t\t" : r > 7 ? "\t\t\t" : "\t\t\t\t",
|
|
||||||
dns_classname(dns_get16(cur+2)), dns_typename(dns_get16(cur)));
|
|
||||||
cur += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.dnsp_pkt = pkt;
|
|
||||||
p.dnsp_cur = p.dnsp_ans = cur;
|
|
||||||
p.dnsp_end = end;
|
|
||||||
p.dnsp_qdn = NULL;
|
|
||||||
p.dnsp_qcls = p.dnsp_qtyp = 0;
|
|
||||||
p.dnsp_ttl = 0xffffffffu;
|
|
||||||
p.dnsp_nrr = 0;
|
|
||||||
|
|
||||||
r = printsection(&p, dns_numan(pkt), "ANSWER");
|
|
||||||
if (r == 0)
|
|
||||||
r = printsection(&p, dns_numns(pkt), "AUTHORITY");
|
|
||||||
if (r == 0)
|
|
||||||
r = printsection(&p, dns_numar(pkt), "ADDITIONAL");
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnscb(struct dns_ctx *ctx, void *result, void *data) {
|
|
||||||
int r = dns_status(ctx);
|
|
||||||
struct query *q = data;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
unsigned nrr;
|
|
||||||
unsigned char dn[DNS_MAXDN];
|
|
||||||
const unsigned char *pkt, *cur, *end;
|
|
||||||
if (!result) {
|
|
||||||
dnserror(q, r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pkt = result; end = pkt + r; cur = dns_payload(pkt);
|
|
||||||
dns_getdn(pkt, &cur, end, dn, sizeof(dn));
|
|
||||||
dns_initparse(&p, NULL, pkt, cur, end);
|
|
||||||
p.dnsp_qcls = p.dnsp_qtyp = 0;
|
|
||||||
nrr = 0;
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
if (!dns_dnequal(dn, rr.dnsrr_dn)) continue;
|
|
||||||
if ((qcls == DNS_C_ANY || qcls == rr.dnsrr_cls) &&
|
|
||||||
(q->qtyp == DNS_T_ANY || q->qtyp == rr.dnsrr_typ))
|
|
||||||
++nrr;
|
|
||||||
else if (rr.dnsrr_typ == DNS_T_CNAME && !nrr) {
|
|
||||||
if (dns_getdn(pkt, &rr.dnsrr_dptr, end,
|
|
||||||
p.dnsp_dnbuf, sizeof(p.dnsp_dnbuf)) <= 0 ||
|
|
||||||
rr.dnsrr_dptr != rr.dnsrr_dend) {
|
|
||||||
r = DNS_E_PROTOCOL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (verbose == 1) {
|
|
||||||
printf("%s.", dns_dntosp(dn));
|
|
||||||
printf(" CNAME %s.\n", dns_dntosp(p.dnsp_dnbuf));
|
|
||||||
}
|
|
||||||
dns_dntodn(p.dnsp_dnbuf, dn, sizeof(dn));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!r && !nrr)
|
|
||||||
r = DNS_E_NODATA;
|
|
||||||
if (r < 0) {
|
|
||||||
dnserror(q, r);
|
|
||||||
free(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (verbose < 2) { /* else it is already printed by dbgfn */
|
|
||||||
dns_rewind(&p, NULL);
|
|
||||||
p.dnsp_qtyp = q->qtyp == DNS_T_ANY ? 0 : q->qtyp;
|
|
||||||
p.dnsp_qcls = qcls == DNS_C_ANY ? 0 : qcls;
|
|
||||||
while(dns_nextrr(&p, &rr))
|
|
||||||
printrr(&p, &rr);
|
|
||||||
}
|
|
||||||
free(result);
|
|
||||||
query_free(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int i;
|
|
||||||
int fd;
|
|
||||||
fd_set fds;
|
|
||||||
struct timeval tv;
|
|
||||||
time_t now;
|
|
||||||
char *ns[DNS_MAXSERV];
|
|
||||||
int nns = 0;
|
|
||||||
struct query *q;
|
|
||||||
enum dns_type qtyp = 0;
|
|
||||||
struct dns_ctx *nctx = NULL;
|
|
||||||
|
|
||||||
if (!(progname = strrchr(argv[0], '/'))) progname = argv[0];
|
|
||||||
else argv[0] = ++progname;
|
|
||||||
|
|
||||||
if (argc <= 1)
|
|
||||||
die(0, "try `%s -h' for help", progname);
|
|
||||||
|
|
||||||
if (dns_init(NULL, 0) < 0 || !(nctx = dns_new(NULL)))
|
|
||||||
die(errno, "unable to initialize dns library");
|
|
||||||
/* we keep two dns contexts: one may be needed to resolve
|
|
||||||
* nameservers if given as names, using default options.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while((i = getopt(argc, argv, "vqt:c:an:o:h")) != EOF) switch(i) {
|
|
||||||
case 'v': ++verbose; break;
|
|
||||||
case 'q': --verbose; break;
|
|
||||||
case 't':
|
|
||||||
if (optarg[0] == '*' && !optarg[1])
|
|
||||||
i = DNS_T_ANY;
|
|
||||||
else if ((i = dns_findtypename(optarg)) <= 0)
|
|
||||||
die(0, "unrecognized query type `%s'", optarg);
|
|
||||||
qtyp = i;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
if (optarg[0] == '*' && !optarg[1])
|
|
||||||
i = DNS_C_ANY;
|
|
||||||
else if ((i = dns_findclassname(optarg)) < 0)
|
|
||||||
die(0, "unrecognized query class `%s'", optarg);
|
|
||||||
qcls = i;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
qtyp = DNS_T_ANY;
|
|
||||||
++verbose;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
if (nns >= DNS_MAXSERV)
|
|
||||||
die(0, "too many nameservers, %d max", DNS_MAXSERV);
|
|
||||||
ns[nns++] = optarg;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
if (dns_set_opts(NULL, optarg) != 0)
|
|
||||||
die(0, "invalid option string: `%s'", optarg);
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
printf(
|
|
||||||
"%s: simple DNS query tool (using udns version %s)\n"
|
|
||||||
"Usage: %s [options] domain-name...\n"
|
|
||||||
"where options are:\n"
|
|
||||||
" -h - print this help and exit\n"
|
|
||||||
" -v - be more verbose\n"
|
|
||||||
" -q - be less verbose\n"
|
|
||||||
" -t type - set query type (A, AAA, PTR etc)\n"
|
|
||||||
" -c class - set query class (IN (default), CH, HS, *)\n"
|
|
||||||
" -a - equivalent to -t ANY -v\n"
|
|
||||||
" -n ns - use given nameserver(s) instead of default\n"
|
|
||||||
" (may be specified multiple times)\n"
|
|
||||||
" -o option:value - set resovler option (the same as setting $RES_OPTIONS):\n"
|
|
||||||
" timeout:sec - initial query timeout\n"
|
|
||||||
" attempts:num - number of attempt to resovle a query\n"
|
|
||||||
" ndots:num - if name has more than num dots, lookup it before search\n"
|
|
||||||
" port:num - port number for queries instead of default 53\n"
|
|
||||||
" udpbuf:num - size of UDP buffer (use EDNS0 if >512)\n"
|
|
||||||
" (may be specified more than once)\n"
|
|
||||||
, progname, dns_version(), progname);
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
die(0, "try `%s -h' for help", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind; argv += optind;
|
|
||||||
if (!argc)
|
|
||||||
die(0, "no name(s) to query specified");
|
|
||||||
|
|
||||||
if (nns) {
|
|
||||||
/* if nameservers given as names, resolve them.
|
|
||||||
* We only allow IPv4 nameservers as names for now.
|
|
||||||
* Ok, it is easy enouth to try both AAAA and A,
|
|
||||||
* but the question is what to do by default.
|
|
||||||
*/
|
|
||||||
struct sockaddr_in sin;
|
|
||||||
int j, r = 0, opened = 0;
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_port = htons(dns_set_opt(NULL, DNS_OPT_PORT, -1));
|
|
||||||
dns_add_serv(NULL, NULL);
|
|
||||||
for(i = 0; i < nns; ++i) {
|
|
||||||
if (dns_pton(AF_INET, ns[i], &sin.sin_addr) <= 0) {
|
|
||||||
struct dns_rr_a4 *rr;
|
|
||||||
if (!opened) {
|
|
||||||
if (dns_open(nctx) < 0)
|
|
||||||
die(errno, "unable to initialize dns context");
|
|
||||||
opened = 1;
|
|
||||||
}
|
|
||||||
rr = dns_resolve_a4(nctx, ns[i], 0);
|
|
||||||
if (!rr)
|
|
||||||
die(0, "unable to resolve nameserver %s: %s",
|
|
||||||
ns[i], dns_strerror(dns_status(nctx)));
|
|
||||||
for(j = 0; j < rr->dnsa4_nrr; ++j) {
|
|
||||||
sin.sin_addr = rr->dnsa4_addr[j];
|
|
||||||
if ((r = dns_add_serv_s(NULL, (struct sockaddr *)&sin)) < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(rr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = dns_add_serv_s(NULL, (struct sockaddr *)&sin);
|
|
||||||
if (r < 0)
|
|
||||||
die(errno, "unable to add nameserver %s",
|
|
||||||
dns_xntop(AF_INET, &sin.sin_addr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dns_free(nctx);
|
|
||||||
|
|
||||||
fd = dns_open(NULL);
|
|
||||||
if (fd < 0)
|
|
||||||
die(errno, "unable to initialize dns context");
|
|
||||||
|
|
||||||
if (verbose > 1)
|
|
||||||
dns_set_dbgfn(NULL, dbgcb);
|
|
||||||
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
char *name = argv[i];
|
|
||||||
union {
|
|
||||||
struct in_addr addr;
|
|
||||||
struct in6_addr addr6;
|
|
||||||
} a;
|
|
||||||
unsigned char dn[DNS_MAXDN];
|
|
||||||
enum dns_type l_qtyp = 0;
|
|
||||||
int abs;
|
|
||||||
if (dns_pton(AF_INET, name, &a.addr) > 0) {
|
|
||||||
dns_a4todn(&a.addr, 0, dn, sizeof(dn));
|
|
||||||
l_qtyp = DNS_T_PTR;
|
|
||||||
abs = 1;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_IPv6
|
|
||||||
else if (dns_pton(AF_INET6, name, &a.addr6) > 0) {
|
|
||||||
dns_a6todn(&a.addr6, 0, dn, sizeof(dn));
|
|
||||||
l_qtyp = DNS_T_PTR;
|
|
||||||
abs = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (!dns_ptodn(name, strlen(name), dn, sizeof(dn), &abs))
|
|
||||||
die(0, "invalid name `%s'\n", name);
|
|
||||||
else
|
|
||||||
l_qtyp = DNS_T_A;
|
|
||||||
if (qtyp) l_qtyp = qtyp;
|
|
||||||
q = query_new(name, dn, l_qtyp);
|
|
||||||
if (abs) abs = DNS_NOSRCH;
|
|
||||||
if (!dns_submit_dn(NULL, dn, qcls, l_qtyp, abs, 0, dnscb, q))
|
|
||||||
dnserror(q, dns_status(NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
now = 0;
|
|
||||||
while((i = dns_timeouts(NULL, -1, now)) > 0) {
|
|
||||||
FD_SET(fd, &fds);
|
|
||||||
tv.tv_sec = i;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
i = select(fd+1, &fds, 0, 0, &tv);
|
|
||||||
now = time(NULL);
|
|
||||||
if (i > 0) dns_ioevent(NULL, now);
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors ? 1 : notfound ? 100 : 0;
|
|
||||||
}
|
|
113
deps/udns/ex-rdns.c
vendored
113
deps/udns/ex-rdns.c
vendored
@ -1,113 +0,0 @@
|
|||||||
/* $Id: ex-rdns.c,v 1.8 2007/01/07 22:46:47 mjt Exp $
|
|
||||||
parallel rDNS resolver example - read IP addresses from stdin,
|
|
||||||
write domain names to stdout
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
static int curq;
|
|
||||||
|
|
||||||
static const char *n2ip(const unsigned char *c) {
|
|
||||||
static char b[sizeof("255.255.255.255")];
|
|
||||||
sprintf(b, "%u.%u.%u.%u", c[0], c[1], c[2], c[3]);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
static void dnscb(struct dns_ctx *ctx, struct dns_rr_ptr *rr, void *data) {
|
|
||||||
const char *ip = n2ip((unsigned char *)&data);
|
|
||||||
int i;
|
|
||||||
--curq;
|
|
||||||
if (rr) {
|
|
||||||
printf("%s", ip);
|
|
||||||
for(i = 0; i < rr->dnsptr_nrr; ++i)
|
|
||||||
printf(" %s", rr->dnsptr_ptr[i]);
|
|
||||||
putchar('\n');
|
|
||||||
free(rr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s: %s\n", ip, dns_strerror(dns_status(ctx)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int c, t;
|
|
||||||
time_t now;
|
|
||||||
int maxq = 10;
|
|
||||||
struct pollfd pfd;
|
|
||||||
char linebuf[1024];
|
|
||||||
char *eol;
|
|
||||||
int eof;
|
|
||||||
|
|
||||||
if (dns_init(NULL, 1) < 0) {
|
|
||||||
fprintf(stderr, "unable to initialize dns library\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
while((c = getopt(argc, argv, "m:r")) != EOF) switch(c) {
|
|
||||||
case 'm': maxq = atoi(optarg); break;
|
|
||||||
case 'r':
|
|
||||||
dns_set_opt(0, DNS_OPT_FLAGS,
|
|
||||||
dns_set_opt(0, DNS_OPT_FLAGS, -1) | DNS_NORD);
|
|
||||||
break;
|
|
||||||
default: return 1;
|
|
||||||
}
|
|
||||||
if (argc != optind) return 1;
|
|
||||||
|
|
||||||
pfd.fd = dns_sock(0);
|
|
||||||
pfd.events = POLLIN;
|
|
||||||
now = time(NULL);
|
|
||||||
c = optind;
|
|
||||||
eof = 0;
|
|
||||||
while(curq || !eof) {
|
|
||||||
if (!eof && curq < maxq) {
|
|
||||||
union { struct in_addr a; void *p; } pa;
|
|
||||||
if (!fgets(linebuf, sizeof(linebuf), stdin)) {
|
|
||||||
eof = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
eol = strchr(linebuf, '\n');
|
|
||||||
if (eol) *eol = '\0';
|
|
||||||
if (!linebuf[0]) continue;
|
|
||||||
if (dns_pton(AF_INET, linebuf, &pa.a) <= 0)
|
|
||||||
fprintf(stderr, "%s: invalid address\n", linebuf);
|
|
||||||
else if (dns_submit_a4ptr(0, &pa.a, dnscb, pa.p) == 0)
|
|
||||||
fprintf(stderr, "%s: unable to submit query: %s\n",
|
|
||||||
linebuf, dns_strerror(dns_status(0)));
|
|
||||||
else
|
|
||||||
++curq;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (curq) {
|
|
||||||
t = dns_timeouts(0, -1, now);
|
|
||||||
t = poll(&pfd, 1, c * 1000);
|
|
||||||
now = time(NULL);
|
|
||||||
if (t) dns_ioevent(0, now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
165
deps/udns/getopt.c
vendored
165
deps/udns/getopt.c
vendored
@ -1,165 +0,0 @@
|
|||||||
/* $Id: getopt.c,v 1.2 2007/01/07 23:19:19 mjt Exp $
|
|
||||||
* Simple getopt() implementation.
|
|
||||||
*
|
|
||||||
* Standard interface:
|
|
||||||
* extern int getopt(int argc, char *const *argv, const char *opts);
|
|
||||||
* extern int optind; current index in argv[]
|
|
||||||
* extern char *optarg; argument for the current option
|
|
||||||
* extern int optopt; the current option
|
|
||||||
* extern int opterr; to control error printing
|
|
||||||
*
|
|
||||||
* Some minor extensions:
|
|
||||||
* ignores leading `+' sign in opts[] (unemplemented GNU extension)
|
|
||||||
* handles optional arguments, in form "x::" in opts[]
|
|
||||||
* if opts[] starts with `:', will return `:' in case of missing required
|
|
||||||
* argument, instead of '?'.
|
|
||||||
*
|
|
||||||
* Compile with -DGETOPT_NO_OPTERR to never print errors internally.
|
|
||||||
* Compile with -DGETOPT_NO_STDIO to use write() calls instead of fprintf() for
|
|
||||||
* error reporting (ignored with -DGETOPT_NO_OPTERR).
|
|
||||||
* Compile with -DGETOPT_CLASS=static to get static linkage.
|
|
||||||
* Compile with -DGETOPT_MY to redefine all visible symbols to be prefixed
|
|
||||||
* with "my_", like my_getopt instead of getopt.
|
|
||||||
* Compile with -DTEST to get a test executable.
|
|
||||||
*
|
|
||||||
* Written by Michael Tokarev. Public domain.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifndef GETOPT_CLASS
|
|
||||||
# define GETOPT_CLASS
|
|
||||||
#endif
|
|
||||||
#ifdef GETOPT_MY
|
|
||||||
# define optarg my_optarg
|
|
||||||
# define optind my_optind
|
|
||||||
# define opterr my_opterr
|
|
||||||
# define optopt my_optopt
|
|
||||||
# define getopt my_getopt
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GETOPT_CLASS char *optarg /* = NULL */;
|
|
||||||
GETOPT_CLASS int optind = 1;
|
|
||||||
GETOPT_CLASS int opterr = 1;
|
|
||||||
GETOPT_CLASS int optopt;
|
|
||||||
|
|
||||||
static char *nextc /* = NULL */;
|
|
||||||
|
|
||||||
#if defined(GETOPT_NO_OPTERR)
|
|
||||||
|
|
||||||
#define printerr(argv, msg)
|
|
||||||
|
|
||||||
#elif defined(GETOPT_NO_STDIO)
|
|
||||||
|
|
||||||
extern int write(int, void *, int);
|
|
||||||
|
|
||||||
static void printerr(char *const *argv, const char *msg) {
|
|
||||||
if (opterr) {
|
|
||||||
char buf[64];
|
|
||||||
unsigned pl = strlen(argv[0]);
|
|
||||||
unsigned ml = strlen(msg);
|
|
||||||
char *p;
|
|
||||||
if (pl + /*": "*/2 + ml + /*" -- c\n"*/6 > sizeof(buf)) {
|
|
||||||
write(2, argv[0], pl);
|
|
||||||
p = buf;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(buf, argv[0], ml);
|
|
||||||
p = buf + pl;
|
|
||||||
}
|
|
||||||
*p++ = ':'; *p++ = ' ';
|
|
||||||
memcpy(p, msg, ml); p += ml;
|
|
||||||
*p++ = ' '; *p++ = '-'; *p++ = '-'; *p++ = ' ';
|
|
||||||
*p++ = optopt;
|
|
||||||
*p++ = '\n';
|
|
||||||
write(2, buf, p - buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
static void printerr(char *const *argv, const char *msg) {
|
|
||||||
if (opterr)
|
|
||||||
fprintf(stderr, "%s: %s -- %c\n", argv[0], msg, optopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GETOPT_CLASS int getopt(int argc, char *const *argv, const char *opts) {
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
optarg = 0;
|
|
||||||
if (*opts == '+') /* GNU extension (permutation) - isn't supported */
|
|
||||||
++opts;
|
|
||||||
|
|
||||||
if (!optind) { /* a way to reset things */
|
|
||||||
nextc = 0;
|
|
||||||
optind = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextc || !*nextc) { /* advance to the next argv element */
|
|
||||||
/* done scanning? */
|
|
||||||
if (optind >= argc)
|
|
||||||
return -1;
|
|
||||||
/* not an optional argument */
|
|
||||||
if (argv[optind][0] != '-')
|
|
||||||
return -1;
|
|
||||||
/* bare `-' */
|
|
||||||
if (argv[optind][1] == '\0')
|
|
||||||
return -1;
|
|
||||||
/* special case `--' argument */
|
|
||||||
if (argv[optind][1] == '-' && argv[optind][2] == '\0') {
|
|
||||||
++optind;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
nextc = argv[optind] + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
optopt = *nextc++;
|
|
||||||
if (!*nextc)
|
|
||||||
++optind;
|
|
||||||
p = strchr(opts, optopt);
|
|
||||||
if (!p || optopt == ':') {
|
|
||||||
printerr(argv, "illegal option");
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
if (p[1] == ':') {
|
|
||||||
if (*nextc) {
|
|
||||||
optarg = nextc;
|
|
||||||
nextc = NULL;
|
|
||||||
++optind;
|
|
||||||
}
|
|
||||||
else if (p[2] != ':') { /* required argument */
|
|
||||||
if (optind >= argc) {
|
|
||||||
printerr(argv, "option requires an argument");
|
|
||||||
return *opts == ':' ? ':' : '?';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
optarg = argv[optind++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return optopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int c;
|
|
||||||
while((c = getopt(argc, argv, "ab:c::")) != -1) switch(c) {
|
|
||||||
case 'a':
|
|
||||||
case 'b':
|
|
||||||
case 'c':
|
|
||||||
printf("option %c %s\n", c, optarg ? optarg : "(none)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for(c = optind; c < argc; ++c)
|
|
||||||
printf("non-opt: %s\n", argv[c]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
327
deps/udns/inet_XtoX.c
vendored
327
deps/udns/inet_XtoX.c
vendored
@ -1,327 +0,0 @@
|
|||||||
/* $Id: inet_XtoX.c,v 1.1 2006/12/04 01:55:39 mjt Exp $
|
|
||||||
* Simple implementation of the following functions:
|
|
||||||
* inet_ntop(), inet_ntoa(), inet_pton(), inet_aton().
|
|
||||||
*
|
|
||||||
* Differences from traditional implementaitons:
|
|
||||||
* o modifies destination buffers even on error return.
|
|
||||||
* o no fancy (hex, or 1.2) input support in inet_aton()
|
|
||||||
* o inet_aton() does not accept junk after an IP address.
|
|
||||||
* o inet_ntop(AF_INET) requires at least 16 bytes in dest,
|
|
||||||
* and inet_ntop(AF_INET6) at least 40 bytes
|
|
||||||
* (traditional inet_ntop() will try to fit anyway)
|
|
||||||
*
|
|
||||||
* Compile with -Dinet_XtoX_prefix=pfx_ to have pfx_*() instead of inet_*()
|
|
||||||
* Compile with -Dinet_XtoX_no_ntop or -Dinet_XtoX_no_pton
|
|
||||||
* to disable net2str or str2net conversions.
|
|
||||||
*
|
|
||||||
* #define inet_XtoX_prototypes and #include "this_file.c"
|
|
||||||
* to get function prototypes only (but not for inet_ntoa()).
|
|
||||||
* #define inet_XtoX_decl to be `static' for static visibility,
|
|
||||||
* or use __declspec(dllexport) or somesuch...
|
|
||||||
*
|
|
||||||
* Compile with -DTEST to test against stock implementation.
|
|
||||||
*
|
|
||||||
* Written by Michael Tokarev. Public domain.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef inet_XtoX_prototypes
|
|
||||||
|
|
||||||
struct in_addr;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
|
|
||||||
# include <netinet/in.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <arpa/inet.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <string.h>
|
|
||||||
# undef inet_XtoX_prefix
|
|
||||||
# define inet_XtoX_prefix mjt_inet_
|
|
||||||
# undef inet_XtoX_no_ntop
|
|
||||||
# undef inet_XtoX_no_pton
|
|
||||||
|
|
||||||
#else /* !TEST */
|
|
||||||
|
|
||||||
struct in_addr { /* declare it here to avoid messing with headers */
|
|
||||||
unsigned char x[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
||||||
|
|
||||||
#endif /* inet_XtoX_prototypes */
|
|
||||||
|
|
||||||
#ifndef inet_XtoX_prefix
|
|
||||||
# define inet_XtoX_prefix inet_
|
|
||||||
#endif
|
|
||||||
#ifndef inet_XtoX_decl
|
|
||||||
# define inet_XtoX_decl /*empty*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define cc2_(x,y) cc2__(x,y)
|
|
||||||
#define cc2__(x,y) x##y
|
|
||||||
#define fn(x) cc2_(inet_XtoX_prefix,x)
|
|
||||||
|
|
||||||
#ifndef inet_XtoX_no_ntop
|
|
||||||
|
|
||||||
inet_XtoX_decl const char *
|
|
||||||
fn(ntop)(int af, const void *src, char *dst, unsigned size);
|
|
||||||
|
|
||||||
#ifndef inet_XtoX_prototypes
|
|
||||||
|
|
||||||
static int mjt_ntop4(const void *_src, char *dst, int size) {
|
|
||||||
unsigned i, x, r;
|
|
||||||
char *p;
|
|
||||||
const unsigned char *s = _src;
|
|
||||||
if (size < 4*4) /* for simplicity, disallow non-max-size buffer */
|
|
||||||
return 0;
|
|
||||||
for (i = 0, p = dst; i < 4; ++i) {
|
|
||||||
if (i) *p++ = '.';
|
|
||||||
x = r = s[i];
|
|
||||||
if (x > 99) { *p++ = (char)(r / 100 + '0'); r %= 100; }
|
|
||||||
if (x > 9) { *p++ = (char)(r / 10 + '0'); r %= 10; }
|
|
||||||
*p++ = (char)(r + '0');
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *hexc(char *p, unsigned x) {
|
|
||||||
static char hex[16] = "0123456789abcdef";
|
|
||||||
if (x > 0x0fff) *p++ = hex[(x >>12) & 15];
|
|
||||||
if (x > 0x00ff) *p++ = hex[(x >> 8) & 15];
|
|
||||||
if (x > 0x000f) *p++ = hex[(x >> 4) & 15];
|
|
||||||
*p++ = hex[x & 15];
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mjt_ntop6(const void *_src, char *dst, int size) {
|
|
||||||
unsigned i;
|
|
||||||
unsigned short w[8];
|
|
||||||
unsigned bs = 0, cs = 0;
|
|
||||||
unsigned bl = 0, cl = 0;
|
|
||||||
char *p;
|
|
||||||
const unsigned char *s = _src;
|
|
||||||
|
|
||||||
if (size < 40) /* for simplicity, disallow non-max-size buffer */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for(i = 0; i < 8; ++i, s += 2) {
|
|
||||||
w[i] = (((unsigned short)(s[0])) << 8) | s[1];
|
|
||||||
if (!w[i]) {
|
|
||||||
if (!cl++) cs = i;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (cl > bl) bl = cl, bs = cs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cl > bl) bl = cl, bs = cs;
|
|
||||||
p = dst;
|
|
||||||
if (bl == 1)
|
|
||||||
bl = 0;
|
|
||||||
if (bl) {
|
|
||||||
for(i = 0; i < bs; ++i) {
|
|
||||||
if (i) *p++ = ':';
|
|
||||||
p = hexc(p, w[i]);
|
|
||||||
}
|
|
||||||
*p++ = ':';
|
|
||||||
i += bl;
|
|
||||||
if (i == 8)
|
|
||||||
*p++ = ':';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i = 0;
|
|
||||||
for(; i < 8; ++i) {
|
|
||||||
if (i) *p++ = ':';
|
|
||||||
if (i == 6 && !bs && (bl == 6 || (bl == 5 && w[5] == 0xffff)))
|
|
||||||
return mjt_ntop4(s - 4, p, size - (p - dst));
|
|
||||||
p = hexc(p, w[i]);
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inet_XtoX_decl const char *
|
|
||||||
fn(ntop)(int af, const void *src, char *dst, unsigned size) {
|
|
||||||
switch(af) {
|
|
||||||
/* don't use AF_*: don't mess with headers */
|
|
||||||
case 2: /* AF_INET */ if (mjt_ntop4(src, dst, size)) return dst; break;
|
|
||||||
case 10: /* AF_INET6 */ if (mjt_ntop6(src, dst, size)) return dst; break;
|
|
||||||
default: errno = EAFNOSUPPORT; return (char*)0;
|
|
||||||
}
|
|
||||||
errno = ENOSPC;
|
|
||||||
return (char*)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inet_XtoX_decl const char *
|
|
||||||
fn(ntoa)(struct in_addr addr) {
|
|
||||||
static char buf[4*4];
|
|
||||||
mjt_ntop4(&addr, buf, sizeof(buf));
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* inet_XtoX_prototypes */
|
|
||||||
#endif /* inet_XtoX_no_ntop */
|
|
||||||
|
|
||||||
#ifndef inet_XtoX_no_pton
|
|
||||||
|
|
||||||
inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst);
|
|
||||||
inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr);
|
|
||||||
|
|
||||||
#ifndef inet_XtoX_prototypes
|
|
||||||
|
|
||||||
static int mjt_pton4(const char *c, void *dst) {
|
|
||||||
unsigned char *a = dst;
|
|
||||||
unsigned n, o;
|
|
||||||
for (n = 0; n < 4; ++n) {
|
|
||||||
if (*c < '0' || *c > '9')
|
|
||||||
return 0;
|
|
||||||
o = *c++ - '0';
|
|
||||||
while(*c >= '0' && *c <= '9')
|
|
||||||
if ((o = o * 10 + (*c++ - '0')) > 255)
|
|
||||||
return 0;
|
|
||||||
if (*c++ != (n == 3 ? '\0' : '.'))
|
|
||||||
return 0;
|
|
||||||
*a++ = (unsigned char)o;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mjt_pton6(const char *c, void *dst) {
|
|
||||||
unsigned short w[8], *a = w, *z, *i;
|
|
||||||
unsigned v, o;
|
|
||||||
const char *sc;
|
|
||||||
unsigned char *d = dst;
|
|
||||||
if (*c != ':') z = (unsigned short*)0;
|
|
||||||
else if (*++c != ':') return 0;
|
|
||||||
else ++c, z = a;
|
|
||||||
i = 0;
|
|
||||||
for(;;) {
|
|
||||||
v = 0;
|
|
||||||
sc = c;
|
|
||||||
for(;;) {
|
|
||||||
if (*c >= '0' && *c <= '9') o = *c - '0';
|
|
||||||
else if (*c >= 'a' && *c <= 'f') o = *c - 'a' + 10;
|
|
||||||
else if (*c >= 'A' && *c <= 'F') o = *c - 'A' + 10;
|
|
||||||
else break;
|
|
||||||
v = (v << 4) | o;
|
|
||||||
if (v > 0xffff) return 0;
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
if (sc == c) {
|
|
||||||
if (z == a && !*c)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (*c == ':') {
|
|
||||||
if (a >= w + 8)
|
|
||||||
return 0;
|
|
||||||
*a++ = v;
|
|
||||||
if (*++c == ':') {
|
|
||||||
if (z)
|
|
||||||
return 0;
|
|
||||||
z = a;
|
|
||||||
if (!*++c)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!*c) {
|
|
||||||
if (a >= w + 8)
|
|
||||||
return 0;
|
|
||||||
*a++ = v;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (*c == '.') {
|
|
||||||
if (a > w + 6)
|
|
||||||
return 0;
|
|
||||||
if (!mjt_pton4(sc, d))
|
|
||||||
return 0;
|
|
||||||
*a++ = ((unsigned)(d[0]) << 8) | d[1];
|
|
||||||
*a++ = ((unsigned)(d[2]) << 8) | d[3];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
v = w + 8 - a;
|
|
||||||
if ((v && !z) || (!v && z))
|
|
||||||
return 0;
|
|
||||||
for(i = w; ; ++i) {
|
|
||||||
if (i == z)
|
|
||||||
while(v--) { *d++ = '\0'; *d++ = '\0'; }
|
|
||||||
if (i >= a)
|
|
||||||
break;
|
|
||||||
*d++ = (unsigned char)((*i >> 8) & 255);
|
|
||||||
*d++ = (unsigned char)(*i & 255);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst) {
|
|
||||||
switch(af) {
|
|
||||||
/* don't use AF_*: don't mess with headers */
|
|
||||||
case 2 /* AF_INET */: return mjt_pton4(src, dst);
|
|
||||||
case 10 /* AF_INET6 */: return mjt_pton6(src, dst);
|
|
||||||
default: errno = EAFNOSUPPORT; return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr) {
|
|
||||||
return mjt_pton4(src, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* inet_XtoX_prototypes */
|
|
||||||
|
|
||||||
#endif /* inet_XtoX_no_pton */
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int i;
|
|
||||||
char n0[16], n1[16];
|
|
||||||
char p0[64], p1[64];
|
|
||||||
int af = AF_INET;
|
|
||||||
int pl = sizeof(p0);
|
|
||||||
int r0, r1;
|
|
||||||
const char *s0, *s1;
|
|
||||||
|
|
||||||
while((i = getopt(argc, argv, "46a:p:")) != EOF) switch(i) {
|
|
||||||
case '4': af = AF_INET; break;
|
|
||||||
case '6': af = AF_INET6; break;
|
|
||||||
case 'a': case 'p': pl = atoi(optarg); break;
|
|
||||||
default: return 1;
|
|
||||||
}
|
|
||||||
for(i = optind; i < argc; ++i) {
|
|
||||||
char *a = argv[i];
|
|
||||||
|
|
||||||
printf("%s:\n", a);
|
|
||||||
r0 = inet_pton(af, a, n0);
|
|
||||||
printf(" p2n stock: %s\n",
|
|
||||||
(r0 < 0 ? "(notsupp)" : !r0 ? "(inval)" : fn(ntop)(af,n0,p0,sizeof(p0))));
|
|
||||||
r1 = fn(pton)(af, a, n1);
|
|
||||||
printf(" p2n this : %s\n",
|
|
||||||
(r1 < 0 ? "(notsupp)" : !r1 ? "(inval)" : fn(ntop)(af,n1,p1,sizeof(p1))));
|
|
||||||
|
|
||||||
if ((r0 > 0) != (r1 > 0) ||
|
|
||||||
(r0 > 0 && r1 > 0 && memcmp(n0, n1, af == AF_INET ? 4 : 16) != 0))
|
|
||||||
printf(" DIFFER!\n");
|
|
||||||
|
|
||||||
s0 = inet_ntop(af, n1, p0, pl);
|
|
||||||
printf(" n2p stock: %s\n", s0 ? s0 : "(inval)");
|
|
||||||
s1 = fn(ntop)(af, n1, p1, pl);
|
|
||||||
printf(" n2p this : %s\n", s1 ? s1 : "(inval)");
|
|
||||||
if ((s0 != 0) != (s1 != 0) ||
|
|
||||||
(s0 && s1 && strcmp(s0, s1) != 0))
|
|
||||||
printf(" DIFFER!\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
151
deps/udns/rblcheck.1
vendored
151
deps/udns/rblcheck.1
vendored
@ -1,151 +0,0 @@
|
|||||||
.\" $Id: rblcheck.1,v 1.1 2005/04/24 23:14:23 mjt Exp $
|
|
||||||
.\" rblckeck manpage
|
|
||||||
.\"
|
|
||||||
.\" Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
.\" This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
.\"
|
|
||||||
.\" This library is free software; you can redistribute it and/or
|
|
||||||
.\" modify it under the terms of the GNU Lesser General Public
|
|
||||||
.\" License as published by the Free Software Foundation; either
|
|
||||||
.\" version 2.1 of the License, or (at your option) any later version.
|
|
||||||
.\"
|
|
||||||
.\" This library is distributed in the hope that it will be useful,
|
|
||||||
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
.\" Lesser General Public License for more details.
|
|
||||||
.\"
|
|
||||||
.\" You should have received a copy of the GNU Lesser General Public
|
|
||||||
.\" License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
.\" write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
.\" Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
.TH rblckeck 1 "Apr 2005" "User Utilities"
|
|
||||||
|
|
||||||
.SH NAME
|
|
||||||
rblckeck \- DNSBL lookup utility
|
|
||||||
|
|
||||||
.SH SYNOPSYS
|
|
||||||
.B rblcheck
|
|
||||||
.RB [\| \-s
|
|
||||||
.IR zone \|]
|
|
||||||
.RB [\| \-S
|
|
||||||
.IR zone\-file \|]
|
|
||||||
.RB [\| \-c \|]
|
|
||||||
.RB [\| \-tmvq \|]
|
|
||||||
.RB [\| \-n
|
|
||||||
.IR nsaddr \|]
|
|
||||||
.IR address \|.\|.\|.
|
|
||||||
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.B rblcheck
|
|
||||||
is a simple command-line to perform DNSBL (DNS-based blocklists) lookups.
|
|
||||||
For every IP address (or a name, in which case it will be resolved to an
|
|
||||||
address first), the utility verifies whenever it is listed in a (list of)
|
|
||||||
DNS blocklists specified with
|
|
||||||
.B \-s
|
|
||||||
or
|
|
||||||
.B \-S
|
|
||||||
options, optionally obtains text assotiated with the listing (usually it
|
|
||||||
is either some description about the reason of the listing or an URL
|
|
||||||
referring to such a description), and displays results on standard output.
|
|
||||||
.PP
|
|
||||||
The program is implemented on top of
|
|
||||||
.BR udns (3)
|
|
||||||
library.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
|
|
||||||
The following options are recognized by
|
|
||||||
.BR rblcheck :
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-s \fIzone\fR
|
|
||||||
add the given \fIzone\fR DNSBL name to the list of active zones.
|
|
||||||
.TP
|
|
||||||
.B \-S \fIzone-file\fR
|
|
||||||
add list of zones from the named \fIzone-file\fR to the list of
|
|
||||||
active zones (the file specifies one zone as the first word on a
|
|
||||||
line, empty lines and lines starting with `#' character are ignored).
|
|
||||||
.TP
|
|
||||||
.B \-c
|
|
||||||
reset active zone list.
|
|
||||||
.TP
|
|
||||||
.B \-v
|
|
||||||
be more verbose, produce more detailed output.
|
|
||||||
.TP
|
|
||||||
.B \-q
|
|
||||||
the opposite for \fB\-v\fR -- produce less detailed output.
|
|
||||||
.TP
|
|
||||||
.B \-t
|
|
||||||
obtain text for listed addresses.
|
|
||||||
.TP
|
|
||||||
.B \-n \fInsaddr\fR
|
|
||||||
Use the given nameserver (given as IPv4 or IPv6 address) instead of the
|
|
||||||
default. The same effect may be achieved by setting $NSCACHEIP environment
|
|
||||||
variable.
|
|
||||||
.TP
|
|
||||||
.B \-m
|
|
||||||
stop after first hit, ie after the first address which is found to be
|
|
||||||
listed.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-h
|
|
||||||
print short help and exit.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
If no
|
|
||||||
.BR \-s ,
|
|
||||||
.BR \-S
|
|
||||||
and
|
|
||||||
.B \-c
|
|
||||||
options are given,
|
|
||||||
.B rblcheck
|
|
||||||
will try to obtain list of zones using $RBLCHECK_ZONES environment variable,
|
|
||||||
or ~/.rblcheckrc, or /etc/rblckechrc files, in that order. If no zones are
|
|
||||||
found, it will exit unsuccessefully.
|
|
||||||
|
|
||||||
.SH "RETURN VALUE"
|
|
||||||
When no addresses given are listed and no errors occured,
|
|
||||||
.B rblcheck
|
|
||||||
exits with code 0. If at least one address is listed,
|
|
||||||
.B rblcheck
|
|
||||||
returns 100. In case of DNS errors,
|
|
||||||
.B rblcheck
|
|
||||||
returns 2.
|
|
||||||
|
|
||||||
.SH ENVIRONMENT
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B $RBLCHECK_ZONES
|
|
||||||
if no
|
|
||||||
.BR \-s ,
|
|
||||||
.B \-S
|
|
||||||
or
|
|
||||||
.B \-c
|
|
||||||
option is given,
|
|
||||||
.B rblcheck
|
|
||||||
tries this variable to obtain list of DNSBL zones to check against.
|
|
||||||
|
|
||||||
.SH FILES
|
|
||||||
|
|
||||||
.TP
|
|
||||||
$HOME/.rblcheckrc and /etc/rblcheckrc
|
|
||||||
if no
|
|
||||||
.BR \-s ,
|
|
||||||
.B \-S
|
|
||||||
or
|
|
||||||
.B \-c
|
|
||||||
option is given, and no $RBLCHECK_ZONES environment variable is set,
|
|
||||||
.B rblcheck
|
|
||||||
will try the two files (the first one that exists) to obtain list of
|
|
||||||
DNSBL zones to check against.
|
|
||||||
Each line specifies one zone (only first word in each line is used).
|
|
||||||
Empty lines and lines starting with `#' character are ignored.
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR dnsget (1)
|
|
||||||
.BR resolv.conf (5)
|
|
||||||
.BR udns (3).
|
|
||||||
|
|
||||||
.SH AUTHOR
|
|
||||||
This program and manual pages are written by Michael Tokarev.
|
|
377
deps/udns/rblcheck.c
vendored
377
deps/udns/rblcheck.c
vendored
@ -1,377 +0,0 @@
|
|||||||
/* $Id: rblcheck.c,v 1.14 2007/01/10 02:52:51 mjt Exp $
|
|
||||||
dnsbl (rbl) checker application
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#ifdef WINDOWS
|
|
||||||
# include <winsock2.h>
|
|
||||||
#else
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#include <time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
#ifndef HAVE_GETOPT
|
|
||||||
# include "getopt.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *version = "udns-rblcheck 0.2";
|
|
||||||
static char *progname;
|
|
||||||
|
|
||||||
static void error(int die, const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
fprintf(stderr, "%s: ", progname);
|
|
||||||
va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
|
|
||||||
putc('\n', stderr);
|
|
||||||
fflush(stderr);
|
|
||||||
if (die)
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct rblookup {
|
|
||||||
struct ipcheck *parent;
|
|
||||||
struct in_addr key;
|
|
||||||
const char *zone;
|
|
||||||
struct dns_rr_a4 *addr;
|
|
||||||
struct dns_rr_txt *txt;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipcheck {
|
|
||||||
const char *name;
|
|
||||||
int naddr;
|
|
||||||
int listed;
|
|
||||||
struct rblookup *lookup;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define notlisted ((void*)1)
|
|
||||||
|
|
||||||
static int nzones, nzalloc;
|
|
||||||
static const char **zones;
|
|
||||||
|
|
||||||
static int do_txt;
|
|
||||||
static int stopfirst;
|
|
||||||
static int verbose = 1;
|
|
||||||
/* verbosity level:
|
|
||||||
* <0 - only bare As/TXTs
|
|
||||||
* 0 - what RBL result
|
|
||||||
* 1(default) - what is listed by RBL: result
|
|
||||||
* 2 - what is[not ]listed by RBL: result, name lookups
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int listed;
|
|
||||||
static int failures;
|
|
||||||
|
|
||||||
static void *ecalloc(int size, int cnt) {
|
|
||||||
void *t = calloc(size, cnt);
|
|
||||||
if (!t)
|
|
||||||
error(1, "out of memory");
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addzone(const char *zone) {
|
|
||||||
if (nzones >= nzalloc) {
|
|
||||||
const char **zs = (const char**)ecalloc(sizeof(char*), (nzalloc += 16));
|
|
||||||
if (zones) {
|
|
||||||
memcpy(zs, zones, nzones * sizeof(char*));
|
|
||||||
free(zones);
|
|
||||||
}
|
|
||||||
zones = zs;
|
|
||||||
}
|
|
||||||
zones[nzones++] = zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int addzonefile(const char *fname) {
|
|
||||||
FILE *f = fopen(fname, "r");
|
|
||||||
char linebuf[2048];
|
|
||||||
if (!f)
|
|
||||||
return 0;
|
|
||||||
while(fgets(linebuf, sizeof(linebuf), f)) {
|
|
||||||
char *p = linebuf, *e;
|
|
||||||
while(*p == ' ' || *p == '\t') ++p;
|
|
||||||
if (*p == '#' || *p == '\n') continue;
|
|
||||||
e = p;
|
|
||||||
while(*e && *e != ' ' && *e != '\t' && *e != '\n')
|
|
||||||
++e;
|
|
||||||
*e = '\0';
|
|
||||||
addzone(p);
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dnserror(struct rblookup *ipl, const char *what) {
|
|
||||||
char buf[4*4];
|
|
||||||
error(0, "unable to %s for %s (%s): %s",
|
|
||||||
what, dns_ntop(AF_INET, &ipl->key, buf, sizeof(buf)),
|
|
||||||
ipl->zone, dns_strerror(dns_status(0)));
|
|
||||||
++failures;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void display_result(struct ipcheck *ipc) {
|
|
||||||
int j;
|
|
||||||
struct rblookup *l, *le;
|
|
||||||
char buf[4*4];
|
|
||||||
if (!ipc->naddr) return;
|
|
||||||
for (l = ipc->lookup, le = l + nzones * ipc->naddr; l < le; ++l) {
|
|
||||||
if (!l->addr) continue;
|
|
||||||
if (verbose < 2 && l->addr == notlisted) continue;
|
|
||||||
if (verbose >= 0) {
|
|
||||||
dns_ntop(AF_INET, &l->key, buf, sizeof(buf));
|
|
||||||
if (ipc->name) printf("%s[%s]", ipc->name, buf);
|
|
||||||
else printf("%s", buf);
|
|
||||||
}
|
|
||||||
if (l->addr == notlisted) {
|
|
||||||
printf(" is NOT listed by %s\n", l->zone);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (verbose >= 1)
|
|
||||||
printf(" is listed by %s: ", l->zone);
|
|
||||||
else if (verbose >= 0)
|
|
||||||
printf(" %s ", l->zone);
|
|
||||||
if (verbose >= 1 || !do_txt)
|
|
||||||
for (j = 0; j < l->addr->dnsa4_nrr; ++j)
|
|
||||||
printf("%s%s", j ? " " : "",
|
|
||||||
dns_ntop(AF_INET, &l->addr->dnsa4_addr[j], buf, sizeof(buf)));
|
|
||||||
if (!do_txt) ;
|
|
||||||
else if (l->txt) {
|
|
||||||
for(j = 0; j < l->txt->dnstxt_nrr; ++j) {
|
|
||||||
unsigned char *t = l->txt->dnstxt_txt[j].txt;
|
|
||||||
unsigned char *e = t + l->txt->dnstxt_txt[j].len;
|
|
||||||
printf("%s\"", verbose > 0 ? "\n\t" : j ? " " : "");
|
|
||||||
while(t < e) {
|
|
||||||
if (*t < ' ' || *t >= 127) printf("\\x%02x", *t);
|
|
||||||
else if (*t == '\\' || *t == '"') printf("\\%c", *t);
|
|
||||||
else putchar(*t);
|
|
||||||
++t;
|
|
||||||
}
|
|
||||||
putchar('"');
|
|
||||||
}
|
|
||||||
free(l->txt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("%s<no text available>", verbose > 0 ? "\n\t" : "");
|
|
||||||
free(l->addr);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
free(ipc->lookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void txtcb(struct dns_ctx *ctx, struct dns_rr_txt *r, void *data) {
|
|
||||||
struct rblookup *ipl = data;
|
|
||||||
if (r) {
|
|
||||||
ipl->txt = r;
|
|
||||||
++ipl->parent->listed;
|
|
||||||
}
|
|
||||||
else if (dns_status(ctx) != DNS_E_NXDOMAIN)
|
|
||||||
dnserror(ipl, "lookup DNSBL TXT record");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void a4cb(struct dns_ctx *ctx, struct dns_rr_a4 *r, void *data) {
|
|
||||||
struct rblookup *ipl = data;
|
|
||||||
if (r) {
|
|
||||||
ipl->addr = r;
|
|
||||||
++listed;
|
|
||||||
if (do_txt) {
|
|
||||||
if (dns_submit_a4dnsbl_txt(0, &ipl->key, ipl->zone, txtcb, ipl))
|
|
||||||
return;
|
|
||||||
dnserror(ipl, "submit DNSBL TXT record");
|
|
||||||
}
|
|
||||||
++ipl->parent->listed;
|
|
||||||
}
|
|
||||||
else if (dns_status(ctx) != DNS_E_NXDOMAIN)
|
|
||||||
dnserror(ipl, "lookup DNSBL A record");
|
|
||||||
else
|
|
||||||
ipl->addr = notlisted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
submit_a_queries(struct ipcheck *ipc,
|
|
||||||
int naddr, const struct in_addr *addr) {
|
|
||||||
int z, a;
|
|
||||||
struct rblookup *rl = ecalloc(sizeof(*rl), nzones * naddr);
|
|
||||||
ipc->lookup = rl;
|
|
||||||
ipc->naddr = naddr;
|
|
||||||
for(a = 0; a < naddr; ++a) {
|
|
||||||
for(z = 0; z < nzones; ++z) {
|
|
||||||
rl->key = addr[a];
|
|
||||||
rl->zone = zones[z];
|
|
||||||
rl->parent = ipc;
|
|
||||||
if (!dns_submit_a4dnsbl(0, &rl->key, rl->zone, a4cb, rl))
|
|
||||||
dnserror(rl, "submit DNSBL A query");
|
|
||||||
++rl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void namecb(struct dns_ctx *ctx, struct dns_rr_a4 *rr, void *data) {
|
|
||||||
struct ipcheck *ipc = data;
|
|
||||||
if (rr) {
|
|
||||||
submit_a_queries(ipc, rr->dnsa4_nrr, rr->dnsa4_addr);
|
|
||||||
free(rr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error(0, "unable to lookup `%s': %s",
|
|
||||||
ipc->name, dns_strerror(dns_status(ctx)));
|
|
||||||
++failures;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int submit(struct ipcheck *ipc) {
|
|
||||||
struct in_addr addr;
|
|
||||||
if (dns_pton(AF_INET, ipc->name, &addr) > 0) {
|
|
||||||
submit_a_queries(ipc, 1, &addr);
|
|
||||||
ipc->name = NULL;
|
|
||||||
}
|
|
||||||
else if (!dns_submit_a4(0, ipc->name, 0, namecb, ipc)) {
|
|
||||||
error(0, "unable to submit name query for %s: %s\n",
|
|
||||||
ipc->name, dns_strerror(dns_status(0)));
|
|
||||||
++failures;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void waitdns(struct ipcheck *ipc) {
|
|
||||||
struct timeval tv;
|
|
||||||
fd_set fds;
|
|
||||||
int c;
|
|
||||||
int fd = dns_sock(NULL);
|
|
||||||
time_t now = 0;
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
while((c = dns_timeouts(NULL, -1, now)) > 0) {
|
|
||||||
FD_SET(fd, &fds);
|
|
||||||
tv.tv_sec = c;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
c = select(fd+1, &fds, NULL, NULL, &tv);
|
|
||||||
now = time(NULL);
|
|
||||||
if (c > 0)
|
|
||||||
dns_ioevent(NULL, now);
|
|
||||||
if (stopfirst && ipc->listed)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int c;
|
|
||||||
struct ipcheck ipc;
|
|
||||||
char *nameserver = NULL;
|
|
||||||
int zgiven = 0;
|
|
||||||
|
|
||||||
if (!(progname = strrchr(argv[0], '/'))) progname = argv[0];
|
|
||||||
else argv[0] = ++progname;
|
|
||||||
|
|
||||||
while((c = getopt(argc, argv, "hqtvms:S:cn:")) != EOF) switch(c) {
|
|
||||||
case 's': ++zgiven; addzone(optarg); break;
|
|
||||||
case 'S':
|
|
||||||
++zgiven;
|
|
||||||
if (addzonefile(optarg)) break;
|
|
||||||
error(1, "unable to read zonefile `%s'", optarg);
|
|
||||||
case 'c': ++zgiven; nzones = 0; break;
|
|
||||||
case 'q': --verbose; break;
|
|
||||||
case 'v': ++verbose; break;
|
|
||||||
case 't': do_txt = 1; break;
|
|
||||||
case 'n': nameserver = optarg; break;
|
|
||||||
case 'm': ++stopfirst; break;
|
|
||||||
case 'h':
|
|
||||||
printf("%s: %s (udns library version %s).\n",
|
|
||||||
progname, version, dns_version());
|
|
||||||
printf("Usage is: %s [options] address..\n", progname);
|
|
||||||
printf(
|
|
||||||
"Where options are:\n"
|
|
||||||
" -h - print this help and exit\n"
|
|
||||||
" -s service - add the service (DNSBL zone) to the serice list\n"
|
|
||||||
" -S service-file - add the DNSBL zone(s) read from the given file\n"
|
|
||||||
" -c - clear service list\n"
|
|
||||||
" -v - increase verbosity level (more -vs => more verbose)\n"
|
|
||||||
" -q - decrease verbosity level (opposite of -v)\n"
|
|
||||||
" -t - obtain and print TXT records if any\n"
|
|
||||||
" -m - stop checking after first address match in any list\n"
|
|
||||||
" -n ipaddr - use the given nameserver instead of the default\n"
|
|
||||||
"(if no -s or -S option is given, use $RBLCHECK_ZONES, ~/.rblcheckrc\n"
|
|
||||||
"or /etc/rblcheckrc in that order)\n"
|
|
||||||
);
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
error(1, "use `%s -h' for help", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!zgiven) {
|
|
||||||
char *s = getenv("RBLCHECK_ZONES");
|
|
||||||
if (s) {
|
|
||||||
char *k;
|
|
||||||
s = strdup(s);
|
|
||||||
for(k = strtok(s, " \t"); k; k = strtok(NULL, " \t"))
|
|
||||||
addzone(k);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
else { /* probably worthless on windows? */
|
|
||||||
char *path;
|
|
||||||
char *home = getenv("HOME");
|
|
||||||
if (!home) home = ".";
|
|
||||||
path = malloc(strlen(home) + 1 + sizeof(".rblcheckrc"));
|
|
||||||
sprintf(path, "%s/.rblcheckrc", home);
|
|
||||||
if (!addzonefile(path))
|
|
||||||
addzonefile("/etc/rblcheckrc");
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!nzones)
|
|
||||||
error(1, "no service (zone) list specified (-s or -S option)");
|
|
||||||
|
|
||||||
argv += optind;
|
|
||||||
argc -= optind;
|
|
||||||
|
|
||||||
if (!argc)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dns_init(NULL, 0) < 0)
|
|
||||||
error(1, "unable to initialize DNS library: %s", strerror(errno));
|
|
||||||
if (nameserver) {
|
|
||||||
dns_add_serv(NULL, NULL);
|
|
||||||
if (dns_add_serv(NULL, nameserver) < 0)
|
|
||||||
error(1, "wrong IP address for a nameserver: `%s'", nameserver);
|
|
||||||
}
|
|
||||||
if (dns_open(NULL) < 0)
|
|
||||||
error(1, "unable to initialize DNS library: %s", strerror(errno));
|
|
||||||
|
|
||||||
for (c = 0; c < argc; ++c) {
|
|
||||||
if (c && (verbose > 1 || (verbose == 1 && do_txt))) putchar('\n');
|
|
||||||
memset(&ipc, 0, sizeof(ipc));
|
|
||||||
ipc.name = argv[c];
|
|
||||||
submit(&ipc);
|
|
||||||
waitdns(&ipc);
|
|
||||||
display_result(&ipc);
|
|
||||||
if (stopfirst > 1 && listed) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return listed ? 100 : failures ? 2 : 0;
|
|
||||||
}
|
|
1351
deps/udns/udns.3
vendored
1351
deps/udns/udns.3
vendored
File diff suppressed because it is too large
Load Diff
745
deps/udns/udns.h
vendored
745
deps/udns/udns.h
vendored
@ -1,745 +0,0 @@
|
|||||||
/* $Id: udns.h,v 1.51 2007/01/15 21:19:08 mjt Exp $
|
|
||||||
header file for the UDNS library.
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UDNS_VERSION /* include guard */
|
|
||||||
|
|
||||||
#define UDNS_VERSION "0.0.9"
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
# ifdef UDNS_DYNAMIC_LIBRARY
|
|
||||||
# ifdef DNS_LIBRARY_BUILD
|
|
||||||
# define UDNS_API __declspec(dllexport)
|
|
||||||
# define UDNS_DATA_API __declspec(dllexport)
|
|
||||||
# else
|
|
||||||
# define UDNS_API __declspec(dllimport)
|
|
||||||
# define UDNS_DATA_API __declspec(dllimport)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UDNS_API
|
|
||||||
# define UDNS_API
|
|
||||||
#endif
|
|
||||||
#ifndef UDNS_DATA_API
|
|
||||||
# define UDNS_DATA_API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h> /* for time_t */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* forward declarations if sockets stuff isn't #include'd */
|
|
||||||
struct in_addr;
|
|
||||||
struct in6_addr;
|
|
||||||
struct sockaddr;
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** Common definitions **************************************/
|
|
||||||
|
|
||||||
UDNS_API const char *
|
|
||||||
dns_version(void);
|
|
||||||
|
|
||||||
struct dns_ctx;
|
|
||||||
struct dns_query;
|
|
||||||
|
|
||||||
/* shorthand for [const] unsigned char */
|
|
||||||
typedef unsigned char dnsc_t;
|
|
||||||
typedef const unsigned char dnscc_t;
|
|
||||||
|
|
||||||
#define DNS_MAXDN 255 /* max DN length */
|
|
||||||
#define DNS_DNPAD 1 /* padding for DN buffers */
|
|
||||||
#define DNS_MAXLABEL 63 /* max DN label length */
|
|
||||||
#define DNS_MAXNAME 1024 /* max asciiz domain name length */
|
|
||||||
#define DNS_HSIZE 12 /* DNS packet header size */
|
|
||||||
#define DNS_PORT 53 /* default domain port */
|
|
||||||
#define DNS_MAXSERV 6 /* max servers to consult */
|
|
||||||
#define DNS_MAXPACKET 512 /* max traditional-DNS UDP packet size */
|
|
||||||
#define DNS_EDNS0PACKET 4096 /* EDNS0 packet size to use */
|
|
||||||
|
|
||||||
enum dns_class { /* DNS RR Classes */
|
|
||||||
DNS_C_INVALID = 0, /* invalid class */
|
|
||||||
DNS_C_IN = 1, /* Internet */
|
|
||||||
DNS_C_CH = 3, /* CHAOS */
|
|
||||||
DNS_C_HS = 4, /* HESIOD */
|
|
||||||
DNS_C_ANY = 255 /* wildcard */
|
|
||||||
};
|
|
||||||
|
|
||||||
enum dns_type { /* DNS RR Types */
|
|
||||||
DNS_T_INVALID = 0, /* Cookie. */
|
|
||||||
DNS_T_A = 1, /* Host address. */
|
|
||||||
DNS_T_NS = 2, /* Authoritative server. */
|
|
||||||
DNS_T_MD = 3, /* Mail destination. */
|
|
||||||
DNS_T_MF = 4, /* Mail forwarder. */
|
|
||||||
DNS_T_CNAME = 5, /* Canonical name. */
|
|
||||||
DNS_T_SOA = 6, /* Start of authority zone. */
|
|
||||||
DNS_T_MB = 7, /* Mailbox domain name. */
|
|
||||||
DNS_T_MG = 8, /* Mail group member. */
|
|
||||||
DNS_T_MR = 9, /* Mail rename name. */
|
|
||||||
DNS_T_NULL = 10, /* Null resource record. */
|
|
||||||
DNS_T_WKS = 11, /* Well known service. */
|
|
||||||
DNS_T_PTR = 12, /* Domain name pointer. */
|
|
||||||
DNS_T_HINFO = 13, /* Host information. */
|
|
||||||
DNS_T_MINFO = 14, /* Mailbox information. */
|
|
||||||
DNS_T_MX = 15, /* Mail routing information. */
|
|
||||||
DNS_T_TXT = 16, /* Text strings. */
|
|
||||||
DNS_T_RP = 17, /* Responsible person. */
|
|
||||||
DNS_T_AFSDB = 18, /* AFS cell database. */
|
|
||||||
DNS_T_X25 = 19, /* X_25 calling address. */
|
|
||||||
DNS_T_ISDN = 20, /* ISDN calling address. */
|
|
||||||
DNS_T_RT = 21, /* Router. */
|
|
||||||
DNS_T_NSAP = 22, /* NSAP address. */
|
|
||||||
DNS_T_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
|
|
||||||
DNS_T_SIG = 24, /* Security signature. */
|
|
||||||
DNS_T_KEY = 25, /* Security key. */
|
|
||||||
DNS_T_PX = 26, /* X.400 mail mapping. */
|
|
||||||
DNS_T_GPOS = 27, /* Geographical position (withdrawn). */
|
|
||||||
DNS_T_AAAA = 28, /* Ip6 Address. */
|
|
||||||
DNS_T_LOC = 29, /* Location Information. */
|
|
||||||
DNS_T_NXT = 30, /* Next domain (security). */
|
|
||||||
DNS_T_EID = 31, /* Endpoint identifier. */
|
|
||||||
DNS_T_NIMLOC = 32, /* Nimrod Locator. */
|
|
||||||
DNS_T_SRV = 33, /* Server Selection. */
|
|
||||||
DNS_T_ATMA = 34, /* ATM Address */
|
|
||||||
DNS_T_NAPTR = 35, /* Naming Authority PoinTeR */
|
|
||||||
DNS_T_KX = 36, /* Key Exchange */
|
|
||||||
DNS_T_CERT = 37, /* Certification record */
|
|
||||||
DNS_T_A6 = 38, /* IPv6 address (deprecates AAAA) */
|
|
||||||
DNS_T_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
|
|
||||||
DNS_T_SINK = 40, /* Kitchen sink (experimentatl) */
|
|
||||||
DNS_T_OPT = 41, /* EDNS0 option (meta-RR) */
|
|
||||||
DNS_T_DS = 43, /* DNSSEC */
|
|
||||||
DNS_T_NSEC = 47, /* DNSSEC */
|
|
||||||
DNS_T_TSIG = 250, /* Transaction signature. */
|
|
||||||
DNS_T_IXFR = 251, /* Incremental zone transfer. */
|
|
||||||
DNS_T_AXFR = 252, /* Transfer zone of authority. */
|
|
||||||
DNS_T_MAILB = 253, /* Transfer mailbox records. */
|
|
||||||
DNS_T_MAILA = 254, /* Transfer mail agent records. */
|
|
||||||
DNS_T_ANY = 255, /* Wildcard match. */
|
|
||||||
DNS_T_ZXFR = 256, /* BIND-specific, nonstandard. */
|
|
||||||
DNS_T_MAX = 65536
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** Domain Names (DNs) **************************************/
|
|
||||||
|
|
||||||
/* return length of the DN */
|
|
||||||
UDNS_API unsigned
|
|
||||||
dns_dnlen(dnscc_t *dn);
|
|
||||||
|
|
||||||
/* return #of labels in a DN */
|
|
||||||
UDNS_API unsigned
|
|
||||||
dns_dnlabels(dnscc_t *dn);
|
|
||||||
|
|
||||||
/* lower- and uppercase single DN char */
|
|
||||||
#define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c))
|
|
||||||
#define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
|
|
||||||
|
|
||||||
/* compare the DNs, return dnlen of equal or 0 if not */
|
|
||||||
UDNS_API unsigned
|
|
||||||
dns_dnequal(dnscc_t *dn1, dnscc_t *dn2);
|
|
||||||
|
|
||||||
/* copy one DN to another, size checking */
|
|
||||||
UDNS_API unsigned
|
|
||||||
dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz);
|
|
||||||
|
|
||||||
/* convert asciiz string of length namelen (0 to use strlen) to DN */
|
|
||||||
UDNS_API int
|
|
||||||
dns_ptodn(const char *name, unsigned namelen,
|
|
||||||
dnsc_t *dn, unsigned dnsiz, int *isabs);
|
|
||||||
|
|
||||||
/* simpler form of dns_ptodn() */
|
|
||||||
#define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0)
|
|
||||||
|
|
||||||
UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14];
|
|
||||||
#define DNS_A4RSIZE 30
|
|
||||||
UDNS_API int
|
|
||||||
dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
|
|
||||||
dnsc_t *dn, unsigned dnsiz);
|
|
||||||
UDNS_API int
|
|
||||||
dns_a4ptodn(const struct in_addr *addr, const char *tname,
|
|
||||||
dnsc_t *dn, unsigned dnsiz);
|
|
||||||
UDNS_API dnsc_t *
|
|
||||||
dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne);
|
|
||||||
|
|
||||||
UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10];
|
|
||||||
#define DNS_A6RSIZE 74
|
|
||||||
UDNS_API int
|
|
||||||
dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
|
|
||||||
dnsc_t *dn, unsigned dnsiz);
|
|
||||||
UDNS_API int
|
|
||||||
dns_a6ptodn(const struct in6_addr *addr, const char *tname,
|
|
||||||
dnsc_t *dn, unsigned dnsiz);
|
|
||||||
UDNS_API dnsc_t *
|
|
||||||
dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne);
|
|
||||||
|
|
||||||
/* convert DN into asciiz string */
|
|
||||||
UDNS_API int
|
|
||||||
dns_dntop(dnscc_t *dn, char *name, unsigned namesiz);
|
|
||||||
|
|
||||||
/* convert DN into asciiz string, using static buffer (NOT thread-safe!) */
|
|
||||||
UDNS_API const char *
|
|
||||||
dns_dntosp(dnscc_t *dn);
|
|
||||||
|
|
||||||
/* return buffer size (incl. null byte) required for asciiz form of a DN */
|
|
||||||
UDNS_API unsigned
|
|
||||||
dns_dntop_size(dnscc_t *dn);
|
|
||||||
|
|
||||||
/* either wrappers or reimplementations for inet_ntop() and inet_pton() */
|
|
||||||
UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size);
|
|
||||||
UDNS_API int dns_pton(int af, const char *src, void *dst);
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** DNS raw packet layout ***********************************/
|
|
||||||
|
|
||||||
enum dns_rcode { /* reply codes */
|
|
||||||
DNS_R_NOERROR = 0, /* ok, no error */
|
|
||||||
DNS_R_FORMERR = 1, /* format error */
|
|
||||||
DNS_R_SERVFAIL = 2, /* server failed */
|
|
||||||
DNS_R_NXDOMAIN = 3, /* domain does not exists */
|
|
||||||
DNS_R_NOTIMPL = 4, /* not implemented */
|
|
||||||
DNS_R_REFUSED = 5, /* query refused */
|
|
||||||
/* these are for BIND_UPDATE */
|
|
||||||
DNS_R_YXDOMAIN = 6, /* Name exists */
|
|
||||||
DNS_R_YXRRSET = 7, /* RRset exists */
|
|
||||||
DNS_R_NXRRSET = 8, /* RRset does not exist */
|
|
||||||
DNS_R_NOTAUTH = 9, /* Not authoritative for zone */
|
|
||||||
DNS_R_NOTZONE = 10, /* Zone of record different from zone section */
|
|
||||||
/*ns_r_max = 11,*/
|
|
||||||
/* The following are TSIG extended errors */
|
|
||||||
DNS_R_BADSIG = 16,
|
|
||||||
DNS_R_BADKEY = 17,
|
|
||||||
DNS_R_BADTIME = 18
|
|
||||||
};
|
|
||||||
|
|
||||||
static __inline unsigned dns_get16(dnscc_t *s) {
|
|
||||||
return ((unsigned)s[0]<<8) | s[1];
|
|
||||||
}
|
|
||||||
static __inline unsigned dns_get32(dnscc_t *s) {
|
|
||||||
return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16)
|
|
||||||
| ((unsigned)s[2]<<8) | s[3];
|
|
||||||
}
|
|
||||||
static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) {
|
|
||||||
*d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d;
|
|
||||||
}
|
|
||||||
static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) {
|
|
||||||
*d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255);
|
|
||||||
*d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return pseudo-random 16bits number */
|
|
||||||
UDNS_API unsigned dns_random16(void);
|
|
||||||
|
|
||||||
/* DNS Header layout */
|
|
||||||
enum {
|
|
||||||
/* bytes 0:1 - query ID */
|
|
||||||
DNS_H_QID1 = 0,
|
|
||||||
DNS_H_QID2 = 1,
|
|
||||||
DNS_H_QID = DNS_H_QID1,
|
|
||||||
#define dns_qid(pkt) dns_get16((pkt)+DNS_H_QID)
|
|
||||||
/* byte 2: flags1 */
|
|
||||||
DNS_H_F1 = 2,
|
|
||||||
DNS_HF1_QR = 0x80, /* query response flag */
|
|
||||||
#define dns_qr(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_QR)
|
|
||||||
DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */
|
|
||||||
#define dns_opcode(pkt) (((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3)
|
|
||||||
DNS_HF1_AA = 0x04, /* auth answer */
|
|
||||||
#define dns_aa(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_AA)
|
|
||||||
DNS_HF1_TC = 0x02, /* truncation flag */
|
|
||||||
#define dns_tc(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_TC)
|
|
||||||
DNS_HF1_RD = 0x01, /* recursion desired (may be set in query) */
|
|
||||||
#define dns_rd(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_RD)
|
|
||||||
/* byte 3: flags2 */
|
|
||||||
DNS_H_F2 = 3,
|
|
||||||
DNS_HF2_RA = 0x80, /* recursion available */
|
|
||||||
#define dns_ra(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RA)
|
|
||||||
DNS_HF2_Z = 0x70, /* reserved */
|
|
||||||
DNS_HF2_RCODE = 0x0f, /* response code, DNS_R_XXX above */
|
|
||||||
#define dns_rcode(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RCODE)
|
|
||||||
/* bytes 4:5: qdcount, numqueries */
|
|
||||||
DNS_H_QDCNT1 = 4,
|
|
||||||
DNS_H_QDCNT2 = 5,
|
|
||||||
DNS_H_QDCNT = DNS_H_QDCNT1,
|
|
||||||
#define dns_numqd(pkt) dns_get16((pkt)+4)
|
|
||||||
/* bytes 6:7: ancount, numanswers */
|
|
||||||
DNS_H_ANCNT1 = 6,
|
|
||||||
DNS_H_ANCNT2 = 7,
|
|
||||||
DNS_H_ANCNT = DNS_H_ANCNT1,
|
|
||||||
#define dns_numan(pkt) dns_get16((pkt)+6)
|
|
||||||
/* bytes 8:9: nscount, numauthority */
|
|
||||||
DNS_H_NSCNT1 = 8,
|
|
||||||
DNS_H_NSCNT2 = 9,
|
|
||||||
DNS_H_NSCNT = DNS_H_NSCNT1,
|
|
||||||
#define dns_numns(pkt) dns_get16((pkt)+8)
|
|
||||||
/* bytes 10:11: arcount, numadditional */
|
|
||||||
DNS_H_ARCNT1 = 10,
|
|
||||||
DNS_H_ARCNT2 = 11,
|
|
||||||
DNS_H_ARCNT = DNS_H_ARCNT1,
|
|
||||||
#define dns_numar(pkt) dns_get16((pkt)+10)
|
|
||||||
#define dns_payload(pkt) ((pkt)+DNS_HSIZE)
|
|
||||||
};
|
|
||||||
|
|
||||||
/* packet buffer: start at pkt, end before pkte, current pos *curp.
|
|
||||||
* extract a DN and set *curp to the next byte after DN in packet.
|
|
||||||
* return -1 on error, 0 if dnsiz is too small, or dnlen on ok.
|
|
||||||
*/
|
|
||||||
UDNS_API int
|
|
||||||
dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end,
|
|
||||||
dnsc_t *dn, unsigned dnsiz);
|
|
||||||
|
|
||||||
/* skip the DN at position cur in packet ending before pkte,
|
|
||||||
* return pointer to the next byte after the DN or NULL on error */
|
|
||||||
UDNS_API dnscc_t *
|
|
||||||
dns_skipdn(dnscc_t *end, dnscc_t *cur);
|
|
||||||
|
|
||||||
struct dns_rr { /* DNS Resource Record */
|
|
||||||
dnsc_t dnsrr_dn[DNS_MAXDN]; /* the DN of the RR */
|
|
||||||
enum dns_class dnsrr_cls; /* Class */
|
|
||||||
enum dns_type dnsrr_typ; /* Type */
|
|
||||||
unsigned dnsrr_ttl; /* Time-To-Live (TTL) */
|
|
||||||
unsigned dnsrr_dsz; /* data size */
|
|
||||||
dnscc_t *dnsrr_dptr; /* pointer to start of data */
|
|
||||||
dnscc_t *dnsrr_dend; /* past end of data */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dns_parse { /* RR/packet parsing state */
|
|
||||||
dnscc_t *dnsp_pkt; /* start of the packet */
|
|
||||||
dnscc_t *dnsp_end; /* end of the packet */
|
|
||||||
dnscc_t *dnsp_cur; /* current packet position */
|
|
||||||
dnscc_t *dnsp_ans; /* start of answer section */
|
|
||||||
int dnsp_rrl; /* number of RRs left to go */
|
|
||||||
int dnsp_nrr; /* RR count so far */
|
|
||||||
unsigned dnsp_ttl; /* TTL value so far */
|
|
||||||
dnscc_t *dnsp_qdn; /* the RR DN we're looking for */
|
|
||||||
enum dns_class dnsp_qcls; /* RR class we're looking for or 0 */
|
|
||||||
enum dns_type dnsp_qtyp; /* RR type we're looking for or 0 */
|
|
||||||
dnsc_t dnsp_dnbuf[DNS_MAXDN]; /* domain buffer */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* initialize the parse structure */
|
|
||||||
UDNS_API void
|
|
||||||
dns_initparse(struct dns_parse *p, dnscc_t *qdn,
|
|
||||||
dnscc_t *pkt, dnscc_t *cur, dnscc_t *end);
|
|
||||||
|
|
||||||
/* search next RR, <0=error, 0=no more RRs, >0 = found. */
|
|
||||||
UDNS_API int
|
|
||||||
dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
|
|
||||||
|
|
||||||
UDNS_API void
|
|
||||||
dns_rewind(struct dns_parse *p, dnscc_t *qdn);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** Resolver Context ****************************************/
|
|
||||||
|
|
||||||
/* default resolver context */
|
|
||||||
UDNS_DATA_API extern struct dns_ctx dns_defctx;
|
|
||||||
|
|
||||||
/* reset resolver context to default state, close it if open, drop queries */
|
|
||||||
UDNS_API void
|
|
||||||
dns_reset(struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* reset resolver context and read in system configuration */
|
|
||||||
UDNS_API int
|
|
||||||
dns_init(struct dns_ctx *ctx, int do_open);
|
|
||||||
|
|
||||||
/* return new resolver context with the same settings as copy */
|
|
||||||
UDNS_API struct dns_ctx *
|
|
||||||
dns_new(const struct dns_ctx *copy);
|
|
||||||
|
|
||||||
/* free resolver context returned by dns_new(); all queries are dropped */
|
|
||||||
UDNS_API void
|
|
||||||
dns_free(struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* add nameserver for a resolver context (or reset nslist if serv==NULL) */
|
|
||||||
UDNS_API int
|
|
||||||
dns_add_serv(struct dns_ctx *ctx, const char *serv);
|
|
||||||
|
|
||||||
/* add nameserver using struct sockaddr structure (with ports) */
|
|
||||||
UDNS_API int
|
|
||||||
dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa);
|
|
||||||
|
|
||||||
/* add search list element for a resolver context (or reset it if srch==NULL) */
|
|
||||||
UDNS_API int
|
|
||||||
dns_add_srch(struct dns_ctx *ctx, const char *srch);
|
|
||||||
|
|
||||||
/* set options for a resolver context */
|
|
||||||
UDNS_API int
|
|
||||||
dns_set_opts(struct dns_ctx *ctx, const char *opts);
|
|
||||||
|
|
||||||
enum dns_opt { /* options */
|
|
||||||
DNS_OPT_FLAGS, /* flags, DNS_F_XXX */
|
|
||||||
DNS_OPT_TIMEOUT, /* timeout in secounds */
|
|
||||||
DNS_OPT_NTRIES, /* number of retries */
|
|
||||||
DNS_OPT_NDOTS, /* ndots */
|
|
||||||
DNS_OPT_UDPSIZE, /* EDNS0 UDP size */
|
|
||||||
DNS_OPT_PORT, /* port to use */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* set or get (if val<0) an option */
|
|
||||||
UDNS_API int
|
|
||||||
dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val);
|
|
||||||
|
|
||||||
enum dns_flags {
|
|
||||||
DNS_NOSRCH = 0x00010000, /* do not perform search */
|
|
||||||
DNS_NORD = 0x00020000, /* request no recursion */
|
|
||||||
DNS_AAONLY = 0x00040000, /* set AA flag in queries */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* set the debug function pointer */
|
|
||||||
typedef void
|
|
||||||
(dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen,
|
|
||||||
dnscc_t *pkt, int plen,
|
|
||||||
const struct dns_query *q, void *data);
|
|
||||||
UDNS_API void
|
|
||||||
dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn);
|
|
||||||
|
|
||||||
/* open and return UDP socket */
|
|
||||||
UDNS_API int
|
|
||||||
dns_open(struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* return UDP socket or -1 if not open */
|
|
||||||
UDNS_API int
|
|
||||||
dns_sock(const struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* close the UDP socket */
|
|
||||||
UDNS_API void
|
|
||||||
dns_close(struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* return number of requests queued */
|
|
||||||
UDNS_API int
|
|
||||||
dns_active(const struct dns_ctx *ctx);
|
|
||||||
|
|
||||||
/* return status of the last operation */
|
|
||||||
UDNS_API int
|
|
||||||
dns_status(const struct dns_ctx *ctx);
|
|
||||||
UDNS_API void
|
|
||||||
dns_setstatus(struct dns_ctx *ctx, int status);
|
|
||||||
|
|
||||||
/* handle I/O event on UDP socket */
|
|
||||||
UDNS_API void
|
|
||||||
dns_ioevent(struct dns_ctx *ctx, time_t now);
|
|
||||||
|
|
||||||
/* process any timeouts, return time in secounds to the
|
|
||||||
* next timeout (or -1 if none) but not greather than maxwait */
|
|
||||||
UDNS_API int
|
|
||||||
dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now);
|
|
||||||
|
|
||||||
/* define timer requesting routine to use */
|
|
||||||
typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data);
|
|
||||||
UDNS_API void
|
|
||||||
dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data);
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** Making Queries ******************************************/
|
|
||||||
|
|
||||||
/* query callback routine */
|
|
||||||
typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data);
|
|
||||||
|
|
||||||
/* query parse routine: raw DNS => application structure */
|
|
||||||
typedef int
|
|
||||||
dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **res);
|
|
||||||
|
|
||||||
enum dns_status {
|
|
||||||
DNS_E_NOERROR = 0, /* ok, not an error */
|
|
||||||
DNS_E_TEMPFAIL = -1, /* timeout, SERVFAIL or similar */
|
|
||||||
DNS_E_PROTOCOL = -2, /* got garbled reply */
|
|
||||||
DNS_E_NXDOMAIN = -3, /* domain does not exists */
|
|
||||||
DNS_E_NODATA = -4, /* domain exists but no data of reqd type */
|
|
||||||
DNS_E_NOMEM = -5, /* out of memory while processing */
|
|
||||||
DNS_E_BADQUERY = -6 /* the query is malformed */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* submit generic DN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_dn(struct dns_ctx *ctx,
|
|
||||||
dnscc_t *dn, int qcls, int qtyp, int flags,
|
|
||||||
dns_parse_fn *parse, dns_query_fn *cbck, void *data);
|
|
||||||
/* submit generic name query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_p(struct dns_ctx *ctx,
|
|
||||||
const char *name, int qcls, int qtyp, int flags,
|
|
||||||
dns_parse_fn *parse, dns_query_fn *cbck, void *data);
|
|
||||||
|
|
||||||
/* cancel the given async query in progress */
|
|
||||||
UDNS_API int
|
|
||||||
dns_cancel(struct dns_ctx *ctx, struct dns_query *q);
|
|
||||||
|
|
||||||
/* resolve a generic query, return the answer */
|
|
||||||
UDNS_API void *
|
|
||||||
dns_resolve_dn(struct dns_ctx *ctx,
|
|
||||||
dnscc_t *qdn, int qcls, int qtyp, int flags,
|
|
||||||
dns_parse_fn *parse);
|
|
||||||
UDNS_API void *
|
|
||||||
dns_resolve_p(struct dns_ctx *ctx,
|
|
||||||
const char *qname, int qcls, int qtyp, int flags,
|
|
||||||
dns_parse_fn *parse);
|
|
||||||
UDNS_API void *
|
|
||||||
dns_resolve(struct dns_ctx *ctx, struct dns_query *q);
|
|
||||||
|
|
||||||
|
|
||||||
/* Specific RR handlers */
|
|
||||||
|
|
||||||
#define dns_rr_common(prefix) \
|
|
||||||
char *prefix##_cname; /* canonical name */ \
|
|
||||||
char *prefix##_qname; /* original query name */ \
|
|
||||||
unsigned prefix##_ttl; /* TTL value */ \
|
|
||||||
int prefix##_nrr /* number of records */
|
|
||||||
|
|
||||||
struct dns_rr_null { /* NULL RRset, aka RRset template */
|
|
||||||
dns_rr_common(dnsn);
|
|
||||||
};
|
|
||||||
|
|
||||||
UDNS_API int
|
|
||||||
dns_stdrr_size(const struct dns_parse *p);
|
|
||||||
UDNS_API void *
|
|
||||||
dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p);
|
|
||||||
|
|
||||||
struct dns_rr_a4 { /* the A RRset */
|
|
||||||
dns_rr_common(dnsa4);
|
|
||||||
struct in_addr *dnsa4_addr; /* array of addresses, naddr elements */
|
|
||||||
};
|
|
||||||
|
|
||||||
UDNS_API dns_parse_fn dns_parse_a4; /* A RR parsing routine */
|
|
||||||
typedef void /* A query callback routine */
|
|
||||||
dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data);
|
|
||||||
|
|
||||||
/* submit A IN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_a4_fn *cbck, void *data);
|
|
||||||
|
|
||||||
/* resolve A IN query */
|
|
||||||
UDNS_API struct dns_rr_a4 *
|
|
||||||
dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_rr_a6 { /* the AAAA RRset */
|
|
||||||
dns_rr_common(dnsa6);
|
|
||||||
struct in6_addr *dnsa6_addr; /* array of addresses, naddr elements */
|
|
||||||
};
|
|
||||||
|
|
||||||
UDNS_API dns_parse_fn dns_parse_a6; /* A RR parsing routine */
|
|
||||||
typedef void /* A query callback routine */
|
|
||||||
dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data);
|
|
||||||
|
|
||||||
/* submit AAAA IN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_a6_fn *cbck, void *data);
|
|
||||||
|
|
||||||
/* resolve AAAA IN query */
|
|
||||||
UDNS_API struct dns_rr_a6 *
|
|
||||||
dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_rr_ptr { /* the PTR RRset */
|
|
||||||
dns_rr_common(dnsptr);
|
|
||||||
char **dnsptr_ptr; /* array of PTRs */
|
|
||||||
};
|
|
||||||
|
|
||||||
UDNS_API dns_parse_fn dns_parse_ptr; /* PTR RR parsing routine */
|
|
||||||
typedef void /* PTR query callback */
|
|
||||||
dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data);
|
|
||||||
/* submit PTR IN in-addr.arpa query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
|
|
||||||
dns_query_ptr_fn *cbck, void *data);
|
|
||||||
/* resolve PTR IN in-addr.arpa query */
|
|
||||||
UDNS_API struct dns_rr_ptr *
|
|
||||||
dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr);
|
|
||||||
|
|
||||||
/* the same as above, but for ip6.arpa */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
|
|
||||||
dns_query_ptr_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_rr_ptr *
|
|
||||||
dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr);
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_mx { /* single MX RR */
|
|
||||||
int priority; /* MX priority */
|
|
||||||
char *name; /* MX name */
|
|
||||||
};
|
|
||||||
struct dns_rr_mx { /* the MX RRset */
|
|
||||||
dns_rr_common(dnsmx);
|
|
||||||
struct dns_mx *dnsmx_mx; /* array of MXes */
|
|
||||||
};
|
|
||||||
UDNS_API dns_parse_fn dns_parse_mx; /* MX RR parsing routine */
|
|
||||||
typedef void /* MX RR callback */
|
|
||||||
dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data);
|
|
||||||
/* submit MX IN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_mx_fn *cbck, void *data);
|
|
||||||
/* resolve MX IN query */
|
|
||||||
UDNS_API struct dns_rr_mx *
|
|
||||||
dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_txt { /* single TXT record */
|
|
||||||
int len; /* length of the text */
|
|
||||||
dnsc_t *txt; /* pointer to text buffer. May contain nulls. */
|
|
||||||
};
|
|
||||||
struct dns_rr_txt { /* the TXT RRset */
|
|
||||||
dns_rr_common(dnstxt);
|
|
||||||
struct dns_txt *dnstxt_txt; /* array of TXT records */
|
|
||||||
};
|
|
||||||
UDNS_API dns_parse_fn dns_parse_txt; /* TXT RR parsing routine */
|
|
||||||
typedef void /* TXT RR callback */
|
|
||||||
dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data);
|
|
||||||
/* submit TXT query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
|
|
||||||
dns_query_txt_fn *cbck, void *data);
|
|
||||||
/* resolve TXT query */
|
|
||||||
UDNS_API struct dns_rr_txt *
|
|
||||||
dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_srv { /* single SRV RR */
|
|
||||||
int priority; /* SRV priority */
|
|
||||||
int weight; /* SRV weight */
|
|
||||||
int port; /* SRV port */
|
|
||||||
char *name; /* SRV name */
|
|
||||||
};
|
|
||||||
struct dns_rr_srv { /* the SRV RRset */
|
|
||||||
dns_rr_common(dnssrv);
|
|
||||||
struct dns_srv *dnssrv_srv; /* array of SRVes */
|
|
||||||
};
|
|
||||||
UDNS_API dns_parse_fn dns_parse_srv; /* SRV RR parsing routine */
|
|
||||||
typedef void /* SRV RR callback */
|
|
||||||
dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data);
|
|
||||||
/* submit SRV IN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_srv(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *srv, const char *proto,
|
|
||||||
int flags, dns_query_srv_fn *cbck, void *data);
|
|
||||||
/* resolve SRV IN query */
|
|
||||||
UDNS_API struct dns_rr_srv *
|
|
||||||
dns_resolve_srv(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *srv, const char *proto,
|
|
||||||
int flags);
|
|
||||||
|
|
||||||
/* NAPTR (RFC3403) RR type */
|
|
||||||
struct dns_naptr { /* single NAPTR RR */
|
|
||||||
int order; /* NAPTR order */
|
|
||||||
int preference; /* NAPTR preference */
|
|
||||||
char *flags; /* NAPTR flags */
|
|
||||||
char *service; /* NAPTR service */
|
|
||||||
char *regexp; /* NAPTR regexp */
|
|
||||||
char *replacement; /* NAPTR replacement */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dns_rr_naptr { /* the NAPTR RRset */
|
|
||||||
dns_rr_common(dnsnaptr);
|
|
||||||
struct dns_naptr *dnsnaptr_naptr; /* array of NAPTRes */
|
|
||||||
};
|
|
||||||
UDNS_API dns_parse_fn dns_parse_naptr; /* NAPTR RR parsing routine */
|
|
||||||
typedef void /* NAPTR RR callback */
|
|
||||||
dns_query_naptr_fn(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_naptr *result, void *data);
|
|
||||||
/* submit NAPTR IN query */
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_naptr_fn *cbck, void *data);
|
|
||||||
/* resolve NAPTR IN query */
|
|
||||||
UDNS_API struct dns_rr_naptr *
|
|
||||||
dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a4dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_rr_a4 *
|
|
||||||
dns_resolve_a4dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl);
|
|
||||||
UDNS_API struct dns_rr_txt *
|
|
||||||
dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl);
|
|
||||||
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a6dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_rr_a4 *
|
|
||||||
dns_resolve_a6dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl);
|
|
||||||
UDNS_API struct dns_rr_txt *
|
|
||||||
dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl);
|
|
||||||
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_rhsbl(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *rhsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_query *
|
|
||||||
dns_submit_rhsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *rhsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data);
|
|
||||||
UDNS_API struct dns_rr_a4 *
|
|
||||||
dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl);
|
|
||||||
UDNS_API struct dns_rr_txt *
|
|
||||||
dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl);
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/**************** Names, Names ********************************************/
|
|
||||||
|
|
||||||
struct dns_nameval {
|
|
||||||
int val;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
UDNS_DATA_API extern const struct dns_nameval dns_classtab[];
|
|
||||||
UDNS_DATA_API extern const struct dns_nameval dns_typetab[];
|
|
||||||
UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[];
|
|
||||||
UDNS_API int
|
|
||||||
dns_findname(const struct dns_nameval *nv, const char *name);
|
|
||||||
#define dns_findclassname(cls) dns_findname(dns_classtab, (cls))
|
|
||||||
#define dns_findtypename(type) dns_findname(dns_typetab, (type))
|
|
||||||
#define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode))
|
|
||||||
|
|
||||||
UDNS_API const char *dns_classname(enum dns_class cls);
|
|
||||||
UDNS_API const char *dns_typename(enum dns_type type);
|
|
||||||
UDNS_API const char *dns_rcodename(enum dns_rcode rcode);
|
|
||||||
const char *_dns_format_code(char *buf, const char *prefix, int code);
|
|
||||||
|
|
||||||
UDNS_API const char *dns_strerror(int errnum);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* include guard */
|
|
50
deps/udns/udns_XtoX.c
vendored
50
deps/udns/udns_XtoX.c
vendored
@ -1,50 +0,0 @@
|
|||||||
/* $Id: udns_XtoX.c,v 1.1 2007/01/07 22:20:39 mjt Exp $
|
|
||||||
udns_ntop() and udns_pton() routines, which are either
|
|
||||||
- wrappers for inet_ntop() and inet_pton() or
|
|
||||||
- reimplementations of those routines.
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_INET_PTON_NTOP
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
const char *dns_ntop(int af, const void *src, char *dst, int size) {
|
|
||||||
return inet_ntop(af, src, dst, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_pton(int af, const char *src, void *dst) {
|
|
||||||
return inet_pton(af, src, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define inet_XtoX_prefix udns_
|
|
||||||
#include "inet_XtoX.c"
|
|
||||||
|
|
||||||
#endif
|
|
160
deps/udns/udns_bl.c
vendored
160
deps/udns/udns_bl.c
vendored
@ -1,160 +0,0 @@
|
|||||||
/* $Id: udns_bl.c,v 1.10 2005/09/12 10:55:21 mjt Exp $
|
|
||||||
DNSBL stuff
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "udns.h"
|
|
||||||
#ifndef NULL
|
|
||||||
# define NULL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a4dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
|
|
||||||
dns_parse_a4, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
|
|
||||||
dns_parse_txt, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_a4 *
|
|
||||||
dns_resolve_a4dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl) {
|
|
||||||
return (struct dns_rr_a4 *)
|
|
||||||
dns_resolve(ctx, dns_submit_a4dnsbl(ctx, addr, dnsbl, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_txt *
|
|
||||||
dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in_addr *addr, const char *dnsbl) {
|
|
||||||
return (struct dns_rr_txt *)
|
|
||||||
dns_resolve(ctx, dns_submit_a4dnsbl_txt(ctx, addr, dnsbl, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a6dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
|
|
||||||
dns_parse_a4, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
|
|
||||||
dns_parse_txt, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_a4 *
|
|
||||||
dns_resolve_a6dnsbl(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl) {
|
|
||||||
return (struct dns_rr_a4 *)
|
|
||||||
dns_resolve(ctx, dns_submit_a6dnsbl(ctx, addr, dnsbl, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_txt *
|
|
||||||
dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
|
|
||||||
const struct in6_addr *addr, const char *dnsbl) {
|
|
||||||
return (struct dns_rr_txt *)
|
|
||||||
dns_resolve(ctx, dns_submit_a6dnsbl_txt(ctx, addr, dnsbl, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
dns_rhsbltodn(const char *name, const char *rhsbl, dnsc_t dn[DNS_MAXDN])
|
|
||||||
{
|
|
||||||
int l = dns_sptodn(name, dn, DNS_MAXDN);
|
|
||||||
if (l <= 0) return 0;
|
|
||||||
l = dns_sptodn(rhsbl, dn+l-1, DNS_MAXDN-l+1);
|
|
||||||
if (l <= 0) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl,
|
|
||||||
dns_query_a4_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (!dns_rhsbltodn(name, rhsbl, dn)) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH,
|
|
||||||
dns_parse_a4, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl,
|
|
||||||
dns_query_txt_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
if (!dns_rhsbltodn(name, rhsbl, dn)) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH,
|
|
||||||
dns_parse_txt, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_a4 *
|
|
||||||
dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl) {
|
|
||||||
return (struct dns_rr_a4*)
|
|
||||||
dns_resolve(ctx, dns_submit_rhsbl(ctx, name, rhsbl, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_txt *
|
|
||||||
dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl)
|
|
||||||
{
|
|
||||||
return (struct dns_rr_txt*)
|
|
||||||
dns_resolve(ctx, dns_submit_rhsbl_txt(ctx, name, rhsbl, 0, 0));
|
|
||||||
}
|
|
382
deps/udns/udns_dn.c
vendored
382
deps/udns/udns_dn.c
vendored
@ -1,382 +0,0 @@
|
|||||||
/* $Id: udns_dn.c,v 1.7 2006/11/28 22:45:20 mjt Exp $
|
|
||||||
domain names manipulation routines
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
unsigned dns_dnlen(dnscc_t *dn) {
|
|
||||||
register dnscc_t *d = dn;
|
|
||||||
while(*d)
|
|
||||||
d += 1 + *d;
|
|
||||||
return (unsigned)(d - dn) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned dns_dnlabels(register dnscc_t *dn) {
|
|
||||||
register unsigned l = 0;
|
|
||||||
while(*dn)
|
|
||||||
++l, dn += 1 + *dn;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned dns_dnequal(register dnscc_t *dn1, register dnscc_t *dn2) {
|
|
||||||
register unsigned c;
|
|
||||||
dnscc_t *dn = dn1;
|
|
||||||
for(;;) {
|
|
||||||
if ((c = *dn1++) != *dn2++)
|
|
||||||
return 0;
|
|
||||||
if (!c)
|
|
||||||
return (unsigned)(dn1 - dn);
|
|
||||||
while(c--) {
|
|
||||||
if (DNS_DNLC(*dn1) != DNS_DNLC(*dn2))
|
|
||||||
return 0;
|
|
||||||
++dn1; ++dn2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz) {
|
|
||||||
unsigned sdnlen = dns_dnlen(sdn);
|
|
||||||
if (ddnsiz < sdnlen)
|
|
||||||
return 0;
|
|
||||||
memcpy(ddn, sdn, sdnlen);
|
|
||||||
return sdnlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_ptodn(const char *name, unsigned namelen,
|
|
||||||
dnsc_t *dn, unsigned dnsiz, int *isabs)
|
|
||||||
{
|
|
||||||
dnsc_t *dp; /* current position in dn (len byte first) */
|
|
||||||
dnsc_t *const de /* end of dn: last byte that can be filled up */
|
|
||||||
= dn + (dnsiz >= DNS_MAXDN ? DNS_MAXDN : dnsiz) - 1;
|
|
||||||
dnscc_t *np = (dnscc_t *)name;
|
|
||||||
dnscc_t *ne = np + (namelen ? namelen : strlen((char*)np));
|
|
||||||
dnsc_t *llab; /* start of last label (llab[-1] will be length) */
|
|
||||||
unsigned c; /* next input character, or length of last label */
|
|
||||||
|
|
||||||
if (!dnsiz)
|
|
||||||
return 0;
|
|
||||||
dp = llab = dn + 1;
|
|
||||||
|
|
||||||
while(np < ne) {
|
|
||||||
|
|
||||||
if (*np == '.') { /* label delimiter */
|
|
||||||
c = dp - llab; /* length of the label */
|
|
||||||
if (!c) { /* empty label */
|
|
||||||
if (np == (dnscc_t *)name && np + 1 == ne) {
|
|
||||||
/* special case for root dn, aka `.' */
|
|
||||||
++np;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -1; /* zero label */
|
|
||||||
}
|
|
||||||
if (c > DNS_MAXLABEL)
|
|
||||||
return -1; /* label too long */
|
|
||||||
llab[-1] = (dnsc_t)c; /* update len of last label */
|
|
||||||
llab = ++dp; /* start new label, llab[-1] will be len of it */
|
|
||||||
++np;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check whenever we may put out one more byte */
|
|
||||||
if (dp >= de) /* too long? */
|
|
||||||
return dnsiz >= DNS_MAXDN ? -1 : 0;
|
|
||||||
if (*np != '\\') { /* non-escape, simple case */
|
|
||||||
*dp++ = *np++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* handle \-style escape */
|
|
||||||
/* note that traditionally, domain names (gethostbyname etc)
|
|
||||||
* used decimal \dd notation, not octal \ooo (RFC1035), so
|
|
||||||
* we're following this tradition here.
|
|
||||||
*/
|
|
||||||
if (++np == ne)
|
|
||||||
return -1; /* bad escape */
|
|
||||||
else if (*np >= '0' && *np <= '9') { /* decimal number */
|
|
||||||
/* we allow not only exactly 3 digits as per RFC1035,
|
|
||||||
* but also 2 or 1, for better usability. */
|
|
||||||
c = *np++ - '0';
|
|
||||||
if (np < ne && *np >= '0' && *np <= '9') { /* 2digits */
|
|
||||||
c = c * 10 + *np++ - '0';
|
|
||||||
if (np < ne && *np >= '0' && *np <= '9') {
|
|
||||||
c = c * 10 + *np++ - '0';
|
|
||||||
if (c > 255)
|
|
||||||
return -1; /* bad escape */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = *np++;
|
|
||||||
*dp++ = (dnsc_t)c; /* place next out byte */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c = dp - llab) > DNS_MAXLABEL)
|
|
||||||
return -1; /* label too long */
|
|
||||||
if ((llab[-1] = (dnsc_t)c) != 0) {
|
|
||||||
*dp++ = 0;
|
|
||||||
if (isabs)
|
|
||||||
*isabs = 0;
|
|
||||||
}
|
|
||||||
else if (isabs)
|
|
||||||
*isabs = 1;
|
|
||||||
|
|
||||||
return dp - dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
dnscc_t dns_inaddr_arpa_dn[14] = "\07in-addr\04arpa";
|
|
||||||
|
|
||||||
dnsc_t *
|
|
||||||
dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne) {
|
|
||||||
dnsc_t *p;
|
|
||||||
unsigned n;
|
|
||||||
dnscc_t *s = ((dnscc_t *)addr) + 4;
|
|
||||||
while(--s >= (dnscc_t *)addr) {
|
|
||||||
n = *s;
|
|
||||||
p = dn + 1;
|
|
||||||
if (n > 99) {
|
|
||||||
if (p + 2 > dne) return 0;
|
|
||||||
*p++ = n / 100 + '0';
|
|
||||||
*p++ = (n % 100 / 10) + '0';
|
|
||||||
*p = n % 10 + '0';
|
|
||||||
}
|
|
||||||
else if (n > 9) {
|
|
||||||
if (p + 1 > dne) return 0;
|
|
||||||
*p++ = n / 10 + '0';
|
|
||||||
*p = n % 10 + '0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (p > dne) return 0;
|
|
||||||
*p = n + '0';
|
|
||||||
}
|
|
||||||
*dn = p - dn;
|
|
||||||
dn = p + 1;
|
|
||||||
}
|
|
||||||
return dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
|
|
||||||
dnsc_t *dn, unsigned dnsiz) {
|
|
||||||
dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz);
|
|
||||||
dnsc_t *p;
|
|
||||||
unsigned l;
|
|
||||||
p = dns_a4todn_(addr, dn, dne);
|
|
||||||
if (!p) return 0;
|
|
||||||
if (!tdn)
|
|
||||||
tdn = dns_inaddr_arpa_dn;
|
|
||||||
l = dns_dnlen(tdn);
|
|
||||||
if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0;
|
|
||||||
memcpy(p, tdn, l);
|
|
||||||
return (p + l) - dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_a4ptodn(const struct in_addr *addr, const char *tname,
|
|
||||||
dnsc_t *dn, unsigned dnsiz) {
|
|
||||||
dnsc_t *p;
|
|
||||||
int r;
|
|
||||||
if (!tname)
|
|
||||||
return dns_a4todn(addr, NULL, dn, dnsiz);
|
|
||||||
p = dns_a4todn_(addr, dn, dn + dnsiz);
|
|
||||||
if (!p) return 0;
|
|
||||||
r = dns_sptodn(tname, p, dnsiz - (p - dn));
|
|
||||||
return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dnscc_t dns_ip6_arpa_dn[10] = "\03ip6\04arpa";
|
|
||||||
|
|
||||||
dnsc_t *
|
|
||||||
dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne) {
|
|
||||||
unsigned n;
|
|
||||||
dnscc_t *s = ((dnscc_t *)addr) + 16;
|
|
||||||
if (dn + 64 > dne) return 0;
|
|
||||||
while(--s >= (dnscc_t *)addr) {
|
|
||||||
*dn++ = 1;
|
|
||||||
n = *s & 0x0f;
|
|
||||||
*dn++ = n > 9 ? n + 'a' - 10 : n + '0';
|
|
||||||
*dn++ = 1;
|
|
||||||
n = *s >> 4;
|
|
||||||
*dn++ = n > 9 ? n + 'a' - 10 : n + '0';
|
|
||||||
}
|
|
||||||
return dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
|
|
||||||
dnsc_t *dn, unsigned dnsiz) {
|
|
||||||
dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz);
|
|
||||||
dnsc_t *p;
|
|
||||||
unsigned l;
|
|
||||||
p = dns_a6todn_(addr, dn, dne);
|
|
||||||
if (!p) return 0;
|
|
||||||
if (!tdn)
|
|
||||||
tdn = dns_ip6_arpa_dn;
|
|
||||||
l = dns_dnlen(tdn);
|
|
||||||
if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0;
|
|
||||||
memcpy(p, tdn, l);
|
|
||||||
return (p + l) - dn;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_a6ptodn(const struct in6_addr *addr, const char *tname,
|
|
||||||
dnsc_t *dn, unsigned dnsiz) {
|
|
||||||
dnsc_t *p;
|
|
||||||
int r;
|
|
||||||
if (!tname)
|
|
||||||
return dns_a6todn(addr, NULL, dn, dnsiz);
|
|
||||||
p = dns_a6todn_(addr, dn, dn + dnsiz);
|
|
||||||
if (!p) return 0;
|
|
||||||
r = dns_sptodn(tname, p, dnsiz - (p - dn));
|
|
||||||
return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return size of buffer required to convert the dn into asciiz string.
|
|
||||||
* Keep in sync with dns_dntop() below.
|
|
||||||
*/
|
|
||||||
unsigned dns_dntop_size(dnscc_t *dn) {
|
|
||||||
unsigned size = 0; /* the size reqd */
|
|
||||||
dnscc_t *le; /* label end */
|
|
||||||
|
|
||||||
while(*dn) {
|
|
||||||
/* *dn is the length of the next label, non-zero */
|
|
||||||
if (size)
|
|
||||||
++size; /* for the dot */
|
|
||||||
le = dn + *dn + 1;
|
|
||||||
++dn;
|
|
||||||
do {
|
|
||||||
switch(*dn) {
|
|
||||||
case '.':
|
|
||||||
case '\\':
|
|
||||||
/* Special modifiers in zone files. */
|
|
||||||
case '"':
|
|
||||||
case ';':
|
|
||||||
case '@':
|
|
||||||
case '$':
|
|
||||||
size += 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (*dn <= 0x20 || *dn >= 0x7f)
|
|
||||||
/* \ddd decimal notation */
|
|
||||||
size += 4;
|
|
||||||
else
|
|
||||||
size += 1;
|
|
||||||
}
|
|
||||||
} while(++dn < le);
|
|
||||||
}
|
|
||||||
size += 1; /* zero byte at the end - string terminator */
|
|
||||||
return size > DNS_MAXNAME ? 0 : size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert the dn into asciiz string.
|
|
||||||
* Keep in sync with dns_dntop_size() above.
|
|
||||||
*/
|
|
||||||
int dns_dntop(dnscc_t *dn, char *name, unsigned namesiz) {
|
|
||||||
char *np = name; /* current name ptr */
|
|
||||||
char *const ne = name + namesiz; /* end of name */
|
|
||||||
dnscc_t *le; /* label end */
|
|
||||||
|
|
||||||
while(*dn) {
|
|
||||||
/* *dn is the length of the next label, non-zero */
|
|
||||||
if (np != name) {
|
|
||||||
if (np >= ne) goto toolong;
|
|
||||||
*np++ = '.';
|
|
||||||
}
|
|
||||||
le = dn + *dn + 1;
|
|
||||||
++dn;
|
|
||||||
do {
|
|
||||||
switch(*dn) {
|
|
||||||
case '.':
|
|
||||||
case '\\':
|
|
||||||
/* Special modifiers in zone files. */
|
|
||||||
case '"':
|
|
||||||
case ';':
|
|
||||||
case '@':
|
|
||||||
case '$':
|
|
||||||
if (np + 2 > ne) goto toolong;
|
|
||||||
*np++ = '\\';
|
|
||||||
*np++ = *dn;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (*dn <= 0x20 || *dn >= 0x7f) {
|
|
||||||
/* \ddd decimal notation */
|
|
||||||
if (np + 4 >= ne) goto toolong;
|
|
||||||
*np++ = '\\';
|
|
||||||
*np++ = '0' + (*dn / 100);
|
|
||||||
*np++ = '0' + ((*dn % 100) / 10);
|
|
||||||
*np++ = '0' + (*dn % 10);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (np >= ne) goto toolong;
|
|
||||||
*np++ = *dn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(++dn < le);
|
|
||||||
}
|
|
||||||
if (np >= ne) goto toolong;
|
|
||||||
*np++ = '\0';
|
|
||||||
return np - name;
|
|
||||||
toolong:
|
|
||||||
return namesiz >= DNS_MAXNAME ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int i;
|
|
||||||
int sz;
|
|
||||||
dnsc_t dn[DNS_MAXDN+10];
|
|
||||||
dnsc_t *dl, *dp;
|
|
||||||
int isabs;
|
|
||||||
|
|
||||||
sz = (argc > 1) ? atoi(argv[1]) : 0;
|
|
||||||
|
|
||||||
for(i = 2; i < argc; ++i) {
|
|
||||||
int r = dns_ptodn(argv[i], 0, dn, sz, &isabs);
|
|
||||||
printf("%s: ", argv[i]);
|
|
||||||
if (r < 0) printf("error\n");
|
|
||||||
else if (!r) printf("buffer too small\n");
|
|
||||||
else {
|
|
||||||
printf("len=%d dnlen=%d size=%d name:",
|
|
||||||
r, dns_dnlen(dn), dns_dntop_size(dn));
|
|
||||||
dl = dn;
|
|
||||||
while(*dl) {
|
|
||||||
printf(" %d=", *dl);
|
|
||||||
dp = dl + 1;
|
|
||||||
dl = dp + *dl;
|
|
||||||
while(dp < dl) {
|
|
||||||
if (*dp <= ' ' || *dp >= 0x7f)
|
|
||||||
printf("\\%03d", *dp);
|
|
||||||
else if (*dp == '.' || *dp == '\\')
|
|
||||||
printf("\\%c", *dp);
|
|
||||||
else
|
|
||||||
putchar(*dp);
|
|
||||||
++dp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isabs) putchar('.');
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TEST */
|
|
30
deps/udns/udns_dntosp.c
vendored
30
deps/udns/udns_dntosp.c
vendored
@ -1,30 +0,0 @@
|
|||||||
/* $Id: udns_dntosp.c,v 1.5 2005/04/19 21:48:09 mjt Exp $
|
|
||||||
dns_dntosp() = convert DN to asciiz string using static buffer
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
static char name[DNS_MAXNAME];
|
|
||||||
|
|
||||||
const char *dns_dntosp(dnscc_t *dn) {
|
|
||||||
return dns_dntop(dn, name, sizeof(name)) > 0 ? name : 0;
|
|
||||||
}
|
|
231
deps/udns/udns_init.c
vendored
231
deps/udns/udns_init.c
vendored
@ -1,231 +0,0 @@
|
|||||||
/* $Id: udns_init.c,v 1.6 2007/01/08 00:41:38 mjt Exp $
|
|
||||||
resolver initialisation stuff
|
|
||||||
|
|
||||||
Copyright (C) 2006 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
#ifdef WINDOWS
|
|
||||||
# include <winsock2.h> /* includes <windows.h> */
|
|
||||||
# include <iphlpapi.h> /* for dns server addresses etc */
|
|
||||||
#else
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <fcntl.h>
|
|
||||||
#endif /* !WINDOWS */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
#define ISSPACE(x) (x == ' ' || x == '\t' || x == '\r' || x == '\n')
|
|
||||||
|
|
||||||
static const char space[] = " \t\r\n";
|
|
||||||
|
|
||||||
static void dns_set_serv_internal(struct dns_ctx *ctx, char *serv) {
|
|
||||||
dns_add_serv(ctx, NULL);
|
|
||||||
for(serv = strtok(serv, space); serv; serv = strtok(NULL, space))
|
|
||||||
dns_add_serv(ctx, serv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) {
|
|
||||||
dns_add_srch(ctx, NULL);
|
|
||||||
for(srch = strtok(srch, space); srch; srch = strtok(NULL, space))
|
|
||||||
dns_add_srch(ctx, srch);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
|
|
||||||
#ifndef NO_IPHLPAPI
|
|
||||||
/* Apparently, some systems does not have proper headers for IPHLPAIP to work.
|
|
||||||
* The best is to upgrade headers, but here's another, ugly workaround for
|
|
||||||
* this: compile with -DNO_IPHLPAPI.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef DWORD (WINAPI *GetAdaptersAddressesFunc)(
|
|
||||||
ULONG Family, DWORD Flags, PVOID Reserved,
|
|
||||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
|
||||||
PULONG pOutBufLen);
|
|
||||||
|
|
||||||
static int dns_initns_iphlpapi(struct dns_ctx *ctx) {
|
|
||||||
HANDLE h_iphlpapi;
|
|
||||||
GetAdaptersAddressesFunc pfnGetAdAddrs;
|
|
||||||
PIP_ADAPTER_ADDRESSES pAddr, pAddrBuf;
|
|
||||||
PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr;
|
|
||||||
ULONG ulOutBufLen;
|
|
||||||
DWORD dwRetVal;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
h_iphlpapi = LoadLibrary("iphlpapi.dll");
|
|
||||||
if (!h_iphlpapi)
|
|
||||||
return -1;
|
|
||||||
pfnGetAdAddrs = (GetAdaptersAddressesFunc)
|
|
||||||
GetProcAddress(h_iphlpapi, "GetAdaptersAddresses");
|
|
||||||
if (!pfnGetAdAddrs) goto freelib;
|
|
||||||
ulOutBufLen = 0;
|
|
||||||
dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, NULL, &ulOutBufLen);
|
|
||||||
if (dwRetVal != ERROR_BUFFER_OVERFLOW) goto freelib;
|
|
||||||
pAddrBuf = malloc(ulOutBufLen);
|
|
||||||
if (!pAddrBuf) goto freelib;
|
|
||||||
dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, pAddrBuf, &ulOutBufLen);
|
|
||||||
if (dwRetVal != ERROR_SUCCESS) goto freemem;
|
|
||||||
for (pAddr = pAddrBuf; pAddr; pAddr = pAddr->Next)
|
|
||||||
for (pDnsAddr = pAddr->FirstDnsServerAddress;
|
|
||||||
pDnsAddr;
|
|
||||||
pDnsAddr = pDnsAddr->Next)
|
|
||||||
dns_add_serv_s(ctx, pDnsAddr->Address.lpSockaddr);
|
|
||||||
ret = 0;
|
|
||||||
freemem:
|
|
||||||
free(pAddrBuf);
|
|
||||||
freelib:
|
|
||||||
FreeLibrary(h_iphlpapi);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* NO_IPHLPAPI */
|
|
||||||
|
|
||||||
#define dns_initns_iphlpapi(ctx) (-1)
|
|
||||||
|
|
||||||
#endif /* NO_IPHLPAPI */
|
|
||||||
|
|
||||||
static int dns_initns_registry(struct dns_ctx *ctx) {
|
|
||||||
LONG res;
|
|
||||||
HKEY hk;
|
|
||||||
DWORD type = REG_EXPAND_SZ | REG_SZ;
|
|
||||||
DWORD len;
|
|
||||||
char valBuf[1024];
|
|
||||||
|
|
||||||
#define REGKEY_WINNT "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
|
|
||||||
#define REGKEY_WIN9x "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
|
|
||||||
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINNT, 0, KEY_QUERY_VALUE, &hk);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WIN9x,
|
|
||||||
0, KEY_QUERY_VALUE, &hk);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
return -1;
|
|
||||||
len = sizeof(valBuf) - 1;
|
|
||||||
res = RegQueryValueEx(hk, "NameServer", NULL, &type, (BYTE*)valBuf, &len);
|
|
||||||
if (res != ERROR_SUCCESS || !len || !valBuf[0]) {
|
|
||||||
len = sizeof(valBuf) - 1;
|
|
||||||
res = RegQueryValueEx(hk, "DhcpNameServer", NULL, &type,
|
|
||||||
(BYTE*)valBuf, &len);
|
|
||||||
}
|
|
||||||
RegCloseKey(hk);
|
|
||||||
if (res != ERROR_SUCCESS || !len || !valBuf[0])
|
|
||||||
return -1;
|
|
||||||
valBuf[len] = '\0';
|
|
||||||
/* nameservers are stored as a whitespace-seperate list:
|
|
||||||
* "192.168.1.1 123.21.32.12" */
|
|
||||||
dns_set_serv_internal(ctx, valBuf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
|
|
||||||
static int dns_init_resolvconf(struct dns_ctx *ctx) {
|
|
||||||
char *v;
|
|
||||||
char buf[2049]; /* this buffer is used to hold /etc/resolv.conf */
|
|
||||||
int has_srch = 0;
|
|
||||||
|
|
||||||
/* read resolv.conf... */
|
|
||||||
{ int fd = open("/etc/resolv.conf", O_RDONLY);
|
|
||||||
if (fd >= 0) {
|
|
||||||
int l = read(fd, buf, sizeof(buf) - 1);
|
|
||||||
close(fd);
|
|
||||||
buf[l < 0 ? 0 : l] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
buf[0] = '\0';
|
|
||||||
}
|
|
||||||
if (buf[0]) { /* ...and parse it */
|
|
||||||
char *line, *nextline;
|
|
||||||
line = buf;
|
|
||||||
do {
|
|
||||||
nextline = strchr(line, '\n');
|
|
||||||
if (nextline) *nextline++ = '\0';
|
|
||||||
v = line;
|
|
||||||
while(*v && !ISSPACE(*v)) ++v;
|
|
||||||
if (!*v) continue;
|
|
||||||
*v++ = '\0';
|
|
||||||
while(ISSPACE(*v)) ++v;
|
|
||||||
if (!*v) continue;
|
|
||||||
if (strcmp(line, "domain") == 0) {
|
|
||||||
dns_set_srch_internal(ctx, strtok(v, space));
|
|
||||||
has_srch = 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(line, "search") == 0) {
|
|
||||||
dns_set_srch_internal(ctx, v);
|
|
||||||
has_srch = 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(line, "nameserver") == 0)
|
|
||||||
dns_add_serv(ctx, strtok(v, space));
|
|
||||||
else if (strcmp(line, "options") == 0)
|
|
||||||
dns_set_opts(ctx, v);
|
|
||||||
} while((line = nextline) != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[sizeof(buf)-1] = '\0';
|
|
||||||
|
|
||||||
/* get list of nameservers from env. vars. */
|
|
||||||
if ((v = getenv("NSCACHEIP")) != NULL ||
|
|
||||||
(v = getenv("NAMESERVERS")) != NULL) {
|
|
||||||
strncpy(buf, v, sizeof(buf) - 1);
|
|
||||||
dns_set_serv_internal(ctx, buf);
|
|
||||||
}
|
|
||||||
/* if $LOCALDOMAIN is set, use it for search list */
|
|
||||||
if ((v = getenv("LOCALDOMAIN")) != NULL) {
|
|
||||||
strncpy(buf, v, sizeof(buf) - 1);
|
|
||||||
dns_set_srch_internal(ctx, buf);
|
|
||||||
has_srch = 1;
|
|
||||||
}
|
|
||||||
if ((v = getenv("RES_OPTIONS")) != NULL)
|
|
||||||
dns_set_opts(ctx, v);
|
|
||||||
|
|
||||||
/* if still no search list, use local domain name */
|
|
||||||
if (has_srch &&
|
|
||||||
gethostname(buf, sizeof(buf) - 1) == 0 &&
|
|
||||||
(v = strchr(buf, '.')) != NULL &&
|
|
||||||
*++v != '\0')
|
|
||||||
dns_add_srch(ctx, v);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !WINDOWS */
|
|
||||||
|
|
||||||
int dns_init(struct dns_ctx *ctx, int do_open) {
|
|
||||||
if (!ctx)
|
|
||||||
ctx = &dns_defctx;
|
|
||||||
dns_reset(ctx);
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
if (dns_initns_iphlpapi(ctx) != 0)
|
|
||||||
dns_initns_registry(ctx);
|
|
||||||
/*XXX WINDOWS: probably good to get default domain and search list too...
|
|
||||||
* And options. Something is in registry. */
|
|
||||||
/*XXX WINDOWS: maybe environment variables are also useful? */
|
|
||||||
#else
|
|
||||||
dns_init_resolvconf(ctx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return do_open ? dns_open(ctx) : 0;
|
|
||||||
}
|
|
67
deps/udns/udns_misc.c
vendored
67
deps/udns/udns_misc.c
vendored
@ -1,67 +0,0 @@
|
|||||||
/* $Id: udns_misc.c,v 1.8 2005/04/05 22:51:32 mjt Exp $
|
|
||||||
miscellaneous routines
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
int dns_findname(const struct dns_nameval *nv, const char *name) {
|
|
||||||
register const char *a, *b;
|
|
||||||
for(; nv->name; ++nv)
|
|
||||||
for(a = name, b = nv->name; ; ++a, ++b)
|
|
||||||
if (DNS_DNUC(*a) != *b) break;
|
|
||||||
else if (!*a) return nv->val;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *_dns_format_code(char *buf, const char *prefix, int code) {
|
|
||||||
char *bp = buf;
|
|
||||||
unsigned c, n;
|
|
||||||
do *bp++ = DNS_DNUC(*prefix);
|
|
||||||
while(*++prefix);
|
|
||||||
*bp++ = '#';
|
|
||||||
if (code < 0) code = -code, *bp++ = '-';
|
|
||||||
n = 0; c = code;
|
|
||||||
do ++n;
|
|
||||||
while((c /= 10));
|
|
||||||
c = code;
|
|
||||||
bp[n--] = '\0';
|
|
||||||
do bp[n--] = c % 10 + '0';
|
|
||||||
while((c /= 10));
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *dns_strerror(int err) {
|
|
||||||
if (err >= 0) return "successeful completion";
|
|
||||||
switch(err) {
|
|
||||||
case DNS_E_TEMPFAIL: return "temporary failure in name resolution";
|
|
||||||
case DNS_E_PROTOCOL: return "protocol error";
|
|
||||||
case DNS_E_NXDOMAIN: return "domain name does not exist";
|
|
||||||
case DNS_E_NODATA: return "valid domain but no data of requested type";
|
|
||||||
case DNS_E_NOMEM: return "out of memory";
|
|
||||||
case DNS_E_BADQUERY: return "malformed query";
|
|
||||||
default: return "unknown error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *dns_version(void) {
|
|
||||||
return UDNS_VERSION;
|
|
||||||
}
|
|
169
deps/udns/udns_parse.c
vendored
169
deps/udns/udns_parse.c
vendored
@ -1,169 +0,0 @@
|
|||||||
/* $Id: udns_parse.c,v 1.14 2005/09/12 10:55:21 mjt Exp $
|
|
||||||
raw DNS packet parsing routines
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
dnscc_t *dns_skipdn(dnscc_t *cur, dnscc_t *end) {
|
|
||||||
unsigned c;
|
|
||||||
for(;;) {
|
|
||||||
if (cur >= end)
|
|
||||||
return NULL;
|
|
||||||
c = *cur++;
|
|
||||||
if (!c)
|
|
||||||
return cur;
|
|
||||||
if (c & 192) /* jump */
|
|
||||||
return cur + 1 >= end ? NULL : cur + 1;
|
|
||||||
cur += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_getdn(dnscc_t *pkt, dnscc_t **cur, dnscc_t *end,
|
|
||||||
register dnsc_t *dn, unsigned dnsiz) {
|
|
||||||
unsigned c;
|
|
||||||
dnscc_t *pp = *cur; /* current packet pointer */
|
|
||||||
dnsc_t *dp = dn; /* current dn pointer */
|
|
||||||
dnsc_t *const de /* end of the DN dest */
|
|
||||||
= dn + (dnsiz < DNS_MAXDN ? dnsiz : DNS_MAXDN);
|
|
||||||
dnscc_t *jump = NULL; /* ptr after first jump if any */
|
|
||||||
unsigned loop = 100; /* jump loop counter */
|
|
||||||
|
|
||||||
for(;;) { /* loop by labels */
|
|
||||||
if (pp >= end) /* reached end of packet? */
|
|
||||||
return -1;
|
|
||||||
c = *pp++; /* length of the label */
|
|
||||||
if (!c) { /* empty label: terminate */
|
|
||||||
if (dn >= de) /* can't fit terminator */
|
|
||||||
goto noroom;
|
|
||||||
*dp++ = 0;
|
|
||||||
/* return next pos: either after the first jump or current */
|
|
||||||
*cur = jump ? jump : pp;
|
|
||||||
return dp - dn;
|
|
||||||
}
|
|
||||||
if (c & 192) { /* jump */
|
|
||||||
if (pp >= end) /* eop instead of jump pos */
|
|
||||||
return -1;
|
|
||||||
if (!jump) jump = pp + 1; /* remember first jump */
|
|
||||||
else if (!--loop) return -1; /* too many jumps */
|
|
||||||
c = ((c & ~192) << 8) | *pp; /* new pos */
|
|
||||||
if (c < DNS_HSIZE) /* don't allow jump into the header */
|
|
||||||
return -1;
|
|
||||||
pp = pkt + c;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c > DNS_MAXLABEL) /* too long label? */
|
|
||||||
return -1;
|
|
||||||
if (pp + c > end) /* label does not fit in packet? */
|
|
||||||
return -1;
|
|
||||||
if (dp + c + 1 > de) /* if enouth room for the label */
|
|
||||||
goto noroom;
|
|
||||||
*dp++ = c; /* label length */
|
|
||||||
memcpy(dp, pp, c); /* and the label itself */
|
|
||||||
dp += c;
|
|
||||||
pp += c; /* advance to the next label */
|
|
||||||
}
|
|
||||||
noroom:
|
|
||||||
return dnsiz < DNS_MAXDN ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dns_rewind(struct dns_parse *p, dnscc_t *qdn) {
|
|
||||||
p->dnsp_qdn = qdn;
|
|
||||||
p->dnsp_cur = p->dnsp_ans;
|
|
||||||
p->dnsp_rrl = dns_numan(p->dnsp_pkt);
|
|
||||||
p->dnsp_ttl = 0xffffffffu;
|
|
||||||
p->dnsp_nrr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dns_initparse(struct dns_parse *p, dnscc_t *qdn,
|
|
||||||
dnscc_t *pkt, dnscc_t *cur, dnscc_t *end) {
|
|
||||||
p->dnsp_pkt = pkt;
|
|
||||||
p->dnsp_end = end;
|
|
||||||
p->dnsp_rrl = dns_numan(pkt);
|
|
||||||
p->dnsp_qdn = qdn;
|
|
||||||
assert(cur + 4 <= end);
|
|
||||||
if ((p->dnsp_qtyp = dns_get16(cur+0)) == DNS_T_ANY) p->dnsp_qtyp = 0;
|
|
||||||
if ((p->dnsp_qcls = dns_get16(cur+2)) == DNS_C_ANY) p->dnsp_qcls = 0;
|
|
||||||
p->dnsp_cur = p->dnsp_ans = cur + 4;
|
|
||||||
p->dnsp_ttl = 0xffffffffu;
|
|
||||||
p->dnsp_nrr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_nextrr(struct dns_parse *p, struct dns_rr *rr) {
|
|
||||||
dnscc_t *cur = p->dnsp_cur;
|
|
||||||
while(p->dnsp_rrl > 0) {
|
|
||||||
--p->dnsp_rrl;
|
|
||||||
if (dns_getdn(p->dnsp_pkt, &cur, p->dnsp_end,
|
|
||||||
rr->dnsrr_dn, sizeof(rr->dnsrr_dn)) <= 0)
|
|
||||||
return -1;
|
|
||||||
if (cur + 10 > p->dnsp_end)
|
|
||||||
return -1;
|
|
||||||
rr->dnsrr_typ = dns_get16(cur);
|
|
||||||
rr->dnsrr_cls = dns_get16(cur+2);
|
|
||||||
rr->dnsrr_ttl = dns_get32(cur+4);
|
|
||||||
rr->dnsrr_dsz = dns_get16(cur+8);
|
|
||||||
rr->dnsrr_dptr = cur = cur + 10;
|
|
||||||
rr->dnsrr_dend = cur = cur + rr->dnsrr_dsz;
|
|
||||||
if (cur > p->dnsp_end)
|
|
||||||
return -1;
|
|
||||||
if (p->dnsp_qdn && !dns_dnequal(p->dnsp_qdn, rr->dnsrr_dn))
|
|
||||||
continue;
|
|
||||||
if ((!p->dnsp_qcls || p->dnsp_qcls == rr->dnsrr_cls) &&
|
|
||||||
(!p->dnsp_qtyp || p->dnsp_qtyp == rr->dnsrr_typ)) {
|
|
||||||
p->dnsp_cur = cur;
|
|
||||||
++p->dnsp_nrr;
|
|
||||||
if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (p->dnsp_qdn && rr->dnsrr_typ == DNS_T_CNAME && !p->dnsp_nrr) {
|
|
||||||
if (dns_getdn(p->dnsp_pkt, &rr->dnsrr_dptr, p->dnsp_end,
|
|
||||||
p->dnsp_dnbuf, sizeof(p->dnsp_dnbuf)) <= 0 ||
|
|
||||||
rr->dnsrr_dptr != rr->dnsrr_dend)
|
|
||||||
return -1;
|
|
||||||
p->dnsp_qdn = p->dnsp_dnbuf;
|
|
||||||
if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p->dnsp_cur = cur;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dns_stdrr_size(const struct dns_parse *p) {
|
|
||||||
return
|
|
||||||
dns_dntop_size(p->dnsp_qdn) +
|
|
||||||
(p->dnsp_qdn == dns_payload(p->dnsp_pkt) ? 0 :
|
|
||||||
dns_dntop_size(dns_payload(p->dnsp_pkt)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void *dns_stdrr_finish(struct dns_rr_null *ret, char *cp,
|
|
||||||
const struct dns_parse *p) {
|
|
||||||
cp += dns_dntop(p->dnsp_qdn, (ret->dnsn_cname = cp), DNS_MAXNAME);
|
|
||||||
if (p->dnsp_qdn == dns_payload(p->dnsp_pkt))
|
|
||||||
ret->dnsn_qname = ret->dnsn_cname;
|
|
||||||
else
|
|
||||||
dns_dntop(dns_payload(p->dnsp_pkt), (ret->dnsn_qname = cp), DNS_MAXNAME);
|
|
||||||
ret->dnsn_ttl = p->dnsp_ttl;
|
|
||||||
return ret;
|
|
||||||
}
|
|
1294
deps/udns/udns_resolver.c
vendored
1294
deps/udns/udns_resolver.c
vendored
File diff suppressed because it is too large
Load Diff
123
deps/udns/udns_rr_a.c
vendored
123
deps/udns/udns_rr_a.c
vendored
@ -1,123 +0,0 @@
|
|||||||
/* $Id: udns_rr_a.c,v 1.16 2007/01/09 04:44:51 mjt Exp $
|
|
||||||
parse/query A/AAAA IN records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#ifndef WINDOWS
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
/* here, we use common routine to parse both IPv4 and IPv6 addresses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* this structure should match dns_rr_a[46] */
|
|
||||||
struct dns_rr_a {
|
|
||||||
dns_rr_common(dnsa);
|
|
||||||
unsigned char *dnsa_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
dns_parse_a(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result, unsigned dsize) {
|
|
||||||
struct dns_rr_a *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* first, validate and count number of addresses */
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0)
|
|
||||||
if (rr.dnsrr_dsz != dsize)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
else if (!p.dnsp_nrr)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
ret = malloc(sizeof(*ret) + dsize * p.dnsp_nrr + dns_stdrr_size(&p));
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
|
|
||||||
ret->dnsa_nrr = p.dnsp_nrr;
|
|
||||||
ret->dnsa_addr = (unsigned char*)(ret+1);
|
|
||||||
|
|
||||||
/* copy the RRs */
|
|
||||||
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r)
|
|
||||||
memcpy(ret->dnsa_addr + dsize * r, rr.dnsrr_dptr, dsize);
|
|
||||||
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret,
|
|
||||||
(char *)(ret->dnsa_addr + dsize * p.dnsp_nrr), &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_a4(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
#ifdef AF_INET
|
|
||||||
assert(sizeof(struct in_addr) == 4);
|
|
||||||
#endif
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_A);
|
|
||||||
return dns_parse_a(qdn, pkt, cur, end, result, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_a4_fn *cbck, void *data) {
|
|
||||||
return
|
|
||||||
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_A, flags,
|
|
||||||
dns_parse_a4, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_a4 *
|
|
||||||
dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags) {
|
|
||||||
return (struct dns_rr_a4 *)
|
|
||||||
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_A, flags, dns_parse_a4);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_a6(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
#ifdef AF_INET6
|
|
||||||
assert(sizeof(struct in6_addr) == 16);
|
|
||||||
#endif
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_AAAA);
|
|
||||||
return dns_parse_a(qdn, pkt, cur, end, result, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_a6_fn *cbck, void *data) {
|
|
||||||
return
|
|
||||||
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags,
|
|
||||||
dns_parse_a6, (dns_query_fn*)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_a6 *
|
|
||||||
dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags) {
|
|
||||||
return (struct dns_rr_a6 *)
|
|
||||||
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags, dns_parse_a6);
|
|
||||||
}
|
|
91
deps/udns/udns_rr_mx.c
vendored
91
deps/udns/udns_rr_mx.c
vendored
@ -1,91 +0,0 @@
|
|||||||
/* $Id: udns_rr_mx.c,v 1.13 2005/04/20 06:44:34 mjt Exp $
|
|
||||||
parse/query MX IN records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_mx(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
struct dns_rr_mx *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r, l;
|
|
||||||
char *sp;
|
|
||||||
dnsc_t mx[DNS_MAXDN];
|
|
||||||
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_MX);
|
|
||||||
|
|
||||||
/* first, validate the answer and count size of the result */
|
|
||||||
l = 0;
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
cur = rr.dnsrr_dptr + 2;
|
|
||||||
r = dns_getdn(pkt, &cur, end, mx, sizeof(mx));
|
|
||||||
if (r <= 0 || cur != rr.dnsrr_dend)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
l += dns_dntop_size(mx);
|
|
||||||
}
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (!p.dnsp_nrr)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
/* next, allocate and set up result */
|
|
||||||
l += dns_stdrr_size(&p);
|
|
||||||
ret = malloc(sizeof(*ret) + sizeof(struct dns_mx) * p.dnsp_nrr + l);
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
ret->dnsmx_nrr = p.dnsp_nrr;
|
|
||||||
ret->dnsmx_mx = (struct dns_mx *)(ret+1);
|
|
||||||
|
|
||||||
/* and 3rd, fill in result, finally */
|
|
||||||
sp = (char*)(ret->dnsmx_mx + p.dnsp_nrr);
|
|
||||||
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
|
|
||||||
ret->dnsmx_mx[r].name = sp;
|
|
||||||
cur = rr.dnsrr_dptr;
|
|
||||||
ret->dnsmx_mx[r].priority = dns_get16(cur);
|
|
||||||
cur += 2;
|
|
||||||
dns_getdn(pkt, &cur, end, mx, sizeof(mx));
|
|
||||||
sp += dns_dntop(mx, sp, DNS_MAXNAME);
|
|
||||||
}
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_mx_fn *cbck, void *data) {
|
|
||||||
return
|
|
||||||
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_MX, flags,
|
|
||||||
dns_parse_mx, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_mx *
|
|
||||||
dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags) {
|
|
||||||
return (struct dns_rr_mx *)
|
|
||||||
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_MX, flags, dns_parse_mx);
|
|
||||||
}
|
|
128
deps/udns/udns_rr_naptr.c
vendored
128
deps/udns/udns_rr_naptr.c
vendored
@ -1,128 +0,0 @@
|
|||||||
/* $Id: udns_rr_naptr.c,v 1.1 2006/11/28 22:58:04 mjt Exp $
|
|
||||||
parse/query NAPTR IN records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
Copyright (C) 2006 Mikael Magnusson <mikma@users.sourceforge.net>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
/* Get a single string for NAPTR record, pretty much like a DN label.
|
|
||||||
* String length is in first byte in *cur, so it can't be >255.
|
|
||||||
*/
|
|
||||||
static int dns_getstr(dnscc_t **cur, dnscc_t *ep, char *buf)
|
|
||||||
{
|
|
||||||
unsigned l;
|
|
||||||
dnscc_t *cp = *cur;
|
|
||||||
|
|
||||||
l = *cp++;
|
|
||||||
if (cp + l > ep)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (buf) {
|
|
||||||
memcpy(buf, cp, l);
|
|
||||||
buf[l] = '\0';
|
|
||||||
}
|
|
||||||
cp += l;
|
|
||||||
|
|
||||||
*cur = cp;
|
|
||||||
return l + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_naptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
struct dns_rr_naptr *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r, l;
|
|
||||||
char *sp;
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_NAPTR);
|
|
||||||
|
|
||||||
/* first, validate the answer and count size of the result */
|
|
||||||
l = 0;
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
int i;
|
|
||||||
dnscc_t *ep = rr.dnsrr_dend;
|
|
||||||
|
|
||||||
/* first 4 bytes: order & preference */
|
|
||||||
cur = rr.dnsrr_dptr + 4;
|
|
||||||
|
|
||||||
/* flags, services and regexp */
|
|
||||||
for (i = 0; i < 3; i++) {
|
|
||||||
r = dns_getstr(&cur, ep, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
l += r;
|
|
||||||
}
|
|
||||||
/* replacement */
|
|
||||||
r = dns_getdn(pkt, &cur, end, dn, sizeof(dn));
|
|
||||||
if (r <= 0 || cur != rr.dnsrr_dend)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
l += dns_dntop_size(dn);
|
|
||||||
}
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (!p.dnsp_nrr)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
/* next, allocate and set up result */
|
|
||||||
l += dns_stdrr_size(&p);
|
|
||||||
ret = malloc(sizeof(*ret) + sizeof(struct dns_naptr) * p.dnsp_nrr + l);
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
ret->dnsnaptr_nrr = p.dnsp_nrr;
|
|
||||||
ret->dnsnaptr_naptr = (struct dns_naptr *)(ret+1);
|
|
||||||
|
|
||||||
/* and 3rd, fill in result, finally */
|
|
||||||
sp = (char*)(&ret->dnsnaptr_naptr[p.dnsp_nrr]);
|
|
||||||
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
|
|
||||||
cur = rr.dnsrr_dptr;
|
|
||||||
ret->dnsnaptr_naptr[r].order = dns_get16(cur); cur += 2;
|
|
||||||
ret->dnsnaptr_naptr[r].preference = dns_get16(cur); cur += 2;
|
|
||||||
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].flags = sp));
|
|
||||||
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].service = sp));
|
|
||||||
sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].regexp = sp));
|
|
||||||
dns_getdn(pkt, &cur, end, dn, sizeof(dn));
|
|
||||||
sp += dns_dntop(dn, (ret->dnsnaptr_naptr[r].replacement = sp), DNS_MAXNAME);
|
|
||||||
}
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
|
|
||||||
dns_query_naptr_fn *cbck, void *data) {
|
|
||||||
return
|
|
||||||
dns_submit_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags,
|
|
||||||
dns_parse_naptr, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_naptr *
|
|
||||||
dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags) {
|
|
||||||
return (struct dns_rr_naptr *)
|
|
||||||
dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags, dns_parse_naptr);
|
|
||||||
}
|
|
109
deps/udns/udns_rr_ptr.c
vendored
109
deps/udns/udns_rr_ptr.c
vendored
@ -1,109 +0,0 @@
|
|||||||
/* $Id: udns_rr_ptr.c,v 1.15 2005/09/12 11:21:06 mjt Exp $
|
|
||||||
parse/query PTR records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_ptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
struct dns_rr_ptr *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r, l, c;
|
|
||||||
char *sp;
|
|
||||||
dnsc_t ptr[DNS_MAXDN];
|
|
||||||
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_PTR);
|
|
||||||
|
|
||||||
/* first, validate the answer and count size of the result */
|
|
||||||
l = c = 0;
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
cur = rr.dnsrr_dptr;
|
|
||||||
r = dns_getdn(pkt, &cur, end, ptr, sizeof(ptr));
|
|
||||||
if (r <= 0 || cur != rr.dnsrr_dend)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
l += dns_dntop_size(ptr);
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (!c)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
/* next, allocate and set up result */
|
|
||||||
ret = malloc(sizeof(*ret) + sizeof(char **) * c + l + dns_stdrr_size(&p));
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
ret->dnsptr_nrr = c;
|
|
||||||
ret->dnsptr_ptr = (char **)(ret+1);
|
|
||||||
|
|
||||||
/* and 3rd, fill in result, finally */
|
|
||||||
sp = (char*)(ret->dnsptr_ptr + c);
|
|
||||||
c = 0;
|
|
||||||
dns_rewind(&p, qdn);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
ret->dnsptr_ptr[c] = sp;
|
|
||||||
cur = rr.dnsrr_dptr;
|
|
||||||
dns_getdn(pkt, &cur, end, ptr, sizeof(ptr));
|
|
||||||
sp += dns_dntop(ptr, sp, DNS_MAXNAME);
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
|
|
||||||
dns_query_ptr_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_A4RSIZE];
|
|
||||||
dns_a4todn(addr, 0, dn, sizeof(dn));
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH,
|
|
||||||
dns_parse_ptr, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_ptr *
|
|
||||||
dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr) {
|
|
||||||
return (struct dns_rr_ptr *)
|
|
||||||
dns_resolve(ctx, dns_submit_a4ptr(ctx, addr, NULL, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
|
|
||||||
dns_query_ptr_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_A6RSIZE];
|
|
||||||
dns_a6todn(addr, 0, dn, sizeof(dn));
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH,
|
|
||||||
dns_parse_ptr, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_ptr *
|
|
||||||
dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr) {
|
|
||||||
return (struct dns_rr_ptr *)
|
|
||||||
dns_resolve(ctx, dns_submit_a6ptr(ctx, addr, NULL, NULL));
|
|
||||||
}
|
|
154
deps/udns/udns_rr_srv.c
vendored
154
deps/udns/udns_rr_srv.c
vendored
@ -1,154 +0,0 @@
|
|||||||
/* $Id: udns_rr_srv.c,v 1.2 2005/09/12 12:26:22 mjt Exp $
|
|
||||||
parse/query SRV IN (rfc2782) records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Copyright 2005 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
|
|
||||||
|
|
||||||
2005-09-11:
|
|
||||||
Changed MX parser file into a SRV parser file
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_srv(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
struct dns_rr_srv *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r, l;
|
|
||||||
char *sp;
|
|
||||||
dnsc_t srv[DNS_MAXDN];
|
|
||||||
|
|
||||||
assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_SRV);
|
|
||||||
|
|
||||||
/* first, validate the answer and count size of the result */
|
|
||||||
l = 0;
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
cur = rr.dnsrr_dptr + 6;
|
|
||||||
r = dns_getdn(pkt, &cur, end, srv, sizeof(srv));
|
|
||||||
if (r <= 0 || cur != rr.dnsrr_dend)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
l += dns_dntop_size(srv);
|
|
||||||
}
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (!p.dnsp_nrr)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
/* next, allocate and set up result */
|
|
||||||
l += dns_stdrr_size(&p);
|
|
||||||
ret = malloc(sizeof(*ret) + sizeof(struct dns_srv) * p.dnsp_nrr + l);
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
ret->dnssrv_nrr = p.dnsp_nrr;
|
|
||||||
ret->dnssrv_srv = (struct dns_srv *)(ret+1);
|
|
||||||
|
|
||||||
/* and 3rd, fill in result, finally */
|
|
||||||
sp = (char*)(ret->dnssrv_srv + p.dnsp_nrr);
|
|
||||||
for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
|
|
||||||
ret->dnssrv_srv[r].name = sp;
|
|
||||||
cur = rr.dnsrr_dptr;
|
|
||||||
ret->dnssrv_srv[r].priority = dns_get16(cur);
|
|
||||||
ret->dnssrv_srv[r].weight = dns_get16(cur+2);
|
|
||||||
ret->dnssrv_srv[r].port = dns_get16(cur+4);
|
|
||||||
cur += 6;
|
|
||||||
dns_getdn(pkt, &cur, end, srv, sizeof(srv));
|
|
||||||
sp += dns_dntop(srv, sp, DNS_MAXNAME);
|
|
||||||
}
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a single service or proto name prepending an undescore (_),
|
|
||||||
* according to rfc2782 rules.
|
|
||||||
* Return 0 or the label length.
|
|
||||||
* Routing assumes dn holds enouth space for a single DN label. */
|
|
||||||
static unsigned add_sname(dnsc_t *dn, const char *sn) {
|
|
||||||
unsigned l;
|
|
||||||
l = dns_ptodn(sn, 0, dn + 1, DNS_MAXLABEL-1, NULL);
|
|
||||||
if (l <= 1 || l - 2 != dn[1])
|
|
||||||
/* Should we really check if sn is exactly one label? Do we care? */
|
|
||||||
return 0;
|
|
||||||
dn[0] = l - 1;
|
|
||||||
dn[1] = '_';
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Construct a domain name for SRV query from the given name, service and
|
|
||||||
* protocol (service may be NULL in which case protocol isn't used).
|
|
||||||
* Return negative value on error (malformed query),
|
|
||||||
* or addition query flag(s) to use.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
build_srv_dn(dnsc_t *dn, const char *name, const char *srv, const char *proto)
|
|
||||||
{
|
|
||||||
unsigned p = 0, l;
|
|
||||||
int isabs;
|
|
||||||
if (srv) {
|
|
||||||
l = add_sname(dn + p, srv);
|
|
||||||
if (!l)
|
|
||||||
return -1;
|
|
||||||
p += l;
|
|
||||||
l = add_sname(dn + p, proto);
|
|
||||||
if (!l)
|
|
||||||
return -1;
|
|
||||||
p += l;
|
|
||||||
}
|
|
||||||
l = dns_ptodn(name, 0, dn + p, DNS_MAXDN - p, &isabs);
|
|
||||||
if (!l)
|
|
||||||
return -1;
|
|
||||||
return isabs ? DNS_NOSRCH : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_srv(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *srv, const char *proto,
|
|
||||||
int flags, dns_query_srv_fn *cbck, void *data) {
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
int r = build_srv_dn(dn, name, srv, proto);
|
|
||||||
if (r < 0) {
|
|
||||||
dns_setstatus (ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r,
|
|
||||||
dns_parse_srv, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_srv *
|
|
||||||
dns_resolve_srv(struct dns_ctx *ctx,
|
|
||||||
const char *name, const char *srv, const char *proto, int flags)
|
|
||||||
{
|
|
||||||
dnsc_t dn[DNS_MAXDN];
|
|
||||||
int r = build_srv_dn(dn, name, srv, proto);
|
|
||||||
if (r < 0) {
|
|
||||||
dns_setstatus(ctx, DNS_E_BADQUERY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (struct dns_rr_srv *)
|
|
||||||
dns_resolve_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r, dns_parse_srv);
|
|
||||||
}
|
|
98
deps/udns/udns_rr_txt.c
vendored
98
deps/udns/udns_rr_txt.c
vendored
@ -1,98 +0,0 @@
|
|||||||
/* $Id: udns_rr_txt.c,v 1.15 2006/11/28 22:45:20 mjt Exp $
|
|
||||||
parse/query TXT records
|
|
||||||
|
|
||||||
Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
|
|
||||||
This file is part of UDNS library, an async DNS stub resolver.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library, in file named COPYING.LGPL; if not,
|
|
||||||
write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "udns.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
dns_parse_txt(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
|
|
||||||
void **result) {
|
|
||||||
struct dns_rr_txt *ret;
|
|
||||||
struct dns_parse p;
|
|
||||||
struct dns_rr rr;
|
|
||||||
int r, l;
|
|
||||||
dnsc_t *sp;
|
|
||||||
dnscc_t *cp, *ep;
|
|
||||||
|
|
||||||
assert(dns_get16(cur+0) == DNS_T_TXT);
|
|
||||||
|
|
||||||
/* first, validate the answer and count size of the result */
|
|
||||||
l = 0;
|
|
||||||
dns_initparse(&p, qdn, pkt, cur, end);
|
|
||||||
while((r = dns_nextrr(&p, &rr)) > 0) {
|
|
||||||
cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend;
|
|
||||||
while(cp < ep) {
|
|
||||||
r = *cp++;
|
|
||||||
if (cp + r > ep)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
l += r;
|
|
||||||
cp += r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (r < 0)
|
|
||||||
return DNS_E_PROTOCOL;
|
|
||||||
if (!p.dnsp_nrr)
|
|
||||||
return DNS_E_NODATA;
|
|
||||||
|
|
||||||
/* next, allocate and set up result */
|
|
||||||
l += (sizeof(struct dns_txt) + 1) * p.dnsp_nrr + dns_stdrr_size(&p);
|
|
||||||
ret = malloc(sizeof(*ret) + l);
|
|
||||||
if (!ret)
|
|
||||||
return DNS_E_NOMEM;
|
|
||||||
ret->dnstxt_nrr = p.dnsp_nrr;
|
|
||||||
ret->dnstxt_txt = (struct dns_txt *)(ret+1);
|
|
||||||
|
|
||||||
/* and 3rd, fill in result, finally */
|
|
||||||
sp = (dnsc_t*)(ret->dnstxt_txt + p.dnsp_nrr);
|
|
||||||
for(dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr) > 0; ++r) {
|
|
||||||
ret->dnstxt_txt[r].txt = sp;
|
|
||||||
cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend;
|
|
||||||
while(cp < ep) {
|
|
||||||
l = *cp++;
|
|
||||||
memcpy(sp, cp, l);
|
|
||||||
sp += l;
|
|
||||||
cp += l;
|
|
||||||
}
|
|
||||||
ret->dnstxt_txt[r].len = sp - ret->dnstxt_txt[r].txt;
|
|
||||||
*sp++ = '\0';
|
|
||||||
}
|
|
||||||
dns_stdrr_finish((struct dns_rr_null *)ret, (char*)sp, &p);
|
|
||||||
*result = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_query *
|
|
||||||
dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
|
|
||||||
dns_query_txt_fn *cbck, void *data) {
|
|
||||||
return
|
|
||||||
dns_submit_p(ctx, name, qcls, DNS_T_TXT, flags,
|
|
||||||
dns_parse_txt, (dns_query_fn *)cbck, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dns_rr_txt *
|
|
||||||
dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags) {
|
|
||||||
return (struct dns_rr_txt *)
|
|
||||||
dns_resolve_p(ctx, name, qcls, DNS_T_TXT, flags, dns_parse_txt);
|
|
||||||
}
|
|
148
lib/dns.js
148
lib/dns.js
@ -1,4 +1,72 @@
|
|||||||
var dns = process.binding('dns');
|
var dns = process.binding('cares');
|
||||||
|
|
||||||
|
|
||||||
|
var watchers = {};
|
||||||
|
var activeWatchers = {};
|
||||||
|
|
||||||
|
|
||||||
|
var timer = new process.Timer();
|
||||||
|
|
||||||
|
timer.callback = function () {
|
||||||
|
for (var socket in activeWatchers) {
|
||||||
|
var s = parseInt(socket);
|
||||||
|
channel.processFD( watchers[socket].read ? s : dns.SOCKET_BAD
|
||||||
|
, watchers[socket].write ? s : dns.SOCKET_BAD
|
||||||
|
);
|
||||||
|
}
|
||||||
|
updateTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateTimer() {
|
||||||
|
timer.stop();
|
||||||
|
|
||||||
|
for (var socket in activeWatchers) { // if !empty(activeWatchers)
|
||||||
|
var max = 20000;
|
||||||
|
var timeout = channel.timeout(max);
|
||||||
|
|
||||||
|
timer.start(timeout, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var channel = new dns.Channel({SOCK_STATE_CB: function (socket, read, write) {
|
||||||
|
var watcher;
|
||||||
|
|
||||||
|
if (socket in watchers) {
|
||||||
|
watcher = watchers[socket].watcher;
|
||||||
|
} else {
|
||||||
|
watcher = new process.IOWatcher();
|
||||||
|
watchers[socket] = { read: read
|
||||||
|
, write: write
|
||||||
|
, watcher: watcher
|
||||||
|
};
|
||||||
|
|
||||||
|
watcher.callback = function(read, write) {
|
||||||
|
channel.processFD( read ? socket : dns.SOCKET_BAD
|
||||||
|
, write ? socket : dns.SOCKET_BAD
|
||||||
|
);
|
||||||
|
updateTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher.set(socket, read == 1, write == 1);
|
||||||
|
|
||||||
|
if (!(read || write)) {
|
||||||
|
watcher.stop();
|
||||||
|
delete activeWatchers[socket];
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
watcher.start();
|
||||||
|
activeWatchers[socket] = watcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTimer();
|
||||||
|
}});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exports.resolve = function (domain, type_, callback_) {
|
exports.resolve = function (domain, type_, callback_) {
|
||||||
var type, callback;
|
var type, callback;
|
||||||
@ -19,38 +87,64 @@ exports.resolve = function (domain, type_, callback_) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.resolve4 = dns.resolve4;
|
|
||||||
exports.resolve6 = dns.resolve6;
|
|
||||||
exports.resolveMx = dns.resolveMx;
|
|
||||||
exports.resolveTxt = dns.resolveTxt;
|
|
||||||
exports.resolveSrv = dns.resolveSrv;
|
|
||||||
exports.reverse = dns.reverse;
|
|
||||||
|
|
||||||
// ERROR CODES
|
exports.getHostByName = function (domain, callback) {
|
||||||
|
channel.getHostByName(domain, dns.AF_INET, callback);
|
||||||
|
};
|
||||||
|
|
||||||
// timeout, SERVFAIL or similar.
|
// Easy DNS A/AAAA look up
|
||||||
exports.TEMPFAIL = dns.TEMPFAIL;
|
exports.lookup = function (domain, callback) {
|
||||||
|
var addressType = dns.isIP(domain);
|
||||||
|
if (addressType) {
|
||||||
|
process.nextTick(function () {
|
||||||
|
callback(null, domain, addressType);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
channel.getHostByName(domain, dns.AF_INET, function (err, domains4) {
|
||||||
|
if (domains4 && domains4.length) {
|
||||||
|
callback(null, domains4[0], 4);
|
||||||
|
} else {
|
||||||
|
channel.getHostByName(domain, dns.AF_INET6, function (err, domains6) {
|
||||||
|
if (domains6 && domains6.length) {
|
||||||
|
callback(null, domains6[0], 6);
|
||||||
|
} else {
|
||||||
|
callback(err, []);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// got garbled reply.
|
|
||||||
exports.PROTOCOL = dns.PROTOCOL;
|
|
||||||
|
|
||||||
// domain does not exists.
|
exports.resolve4 = function(domain, callback) { channel.query(domain, dns.A, callback) };
|
||||||
exports.NXDOMAIN = dns.NXDOMAIN;
|
exports.resolve6 = function(domain, callback) { channel.query(domain, dns.AAAA, callback) };
|
||||||
|
exports.resolveTxt = function(domain, callback) { channel.query(domain, dns.TXT, callback) };
|
||||||
|
exports.resolveSrv = function(domain, callback) { channel.query(domain, dns.SRV, callback) };
|
||||||
|
exports.reverse = function(domain, callback) { channel.query(domain, dns.PTR, callback) };
|
||||||
|
exports.resolveNs = function(domain, callback) { channel.query(domain, dns.NS, callback) };
|
||||||
|
|
||||||
// domain exists but no data of reqd type.
|
|
||||||
exports.NODATA = dns.NODATA;
|
|
||||||
|
|
||||||
// out of memory while processing.
|
|
||||||
exports.NOMEM = dns.NOMEM;
|
|
||||||
|
|
||||||
// the query is malformed.
|
|
||||||
exports.BADQUERY = dns.BADQUERY;
|
|
||||||
|
|
||||||
var resolveMap = {
|
var resolveMap = {
|
||||||
'A': exports.resolve4,
|
'A' : exports.resolve4,
|
||||||
'AAAA': exports.resolve6,
|
'AAAA': exports.resolve6,
|
||||||
'MX': exports.resolveMx,
|
'TXT' : exports.resolveTxt,
|
||||||
'TXT': exports.resolveTxt,
|
'SRV' : exports.resolveSrv,
|
||||||
'SRV': exports.resolveSrv,
|
'PTR' : exports.resolvePtr,
|
||||||
'PTR': exports.reverse,
|
'NS' : exports.resolveNs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ERROR CODES
|
||||||
|
exports.NODATA = dns.NODATA;
|
||||||
|
exports.FORMERR = dns.FORMERR;
|
||||||
|
exports.BADRESP = dns.BADRESP;
|
||||||
|
exports.NOTFOUND = dns.NOTFOUND;
|
||||||
|
exports.BADNAME = dns.BADNAME;
|
||||||
|
exports.TIMEOUT = dns.TIMEOUT;
|
||||||
|
exports.CONNREFUSED = dns.CONNREFUSED;
|
||||||
|
exports.NOMEM = dns.NOMEM;
|
||||||
|
exports.DESTRUCTION = dns.DESTRUCTION;
|
||||||
|
|
||||||
|
exports.NOTIMP = dns.NOTIMP;
|
||||||
|
exports.EREFUSED = dns.EREFUSED;
|
||||||
|
exports.SERVFAIL = dns.SERVFAIL;
|
||||||
|
150
lib/dns_cares.js
150
lib/dns_cares.js
@ -1,150 +0,0 @@
|
|||||||
var dns = process.binding('cares');
|
|
||||||
|
|
||||||
|
|
||||||
var watchers = {};
|
|
||||||
var activeWatchers = {};
|
|
||||||
|
|
||||||
|
|
||||||
var timer = new process.Timer();
|
|
||||||
|
|
||||||
timer.callback = function () {
|
|
||||||
for (var socket in activeWatchers) {
|
|
||||||
var s = parseInt(socket);
|
|
||||||
channel.processFD( watchers[socket].read ? s : dns.SOCKET_BAD
|
|
||||||
, watchers[socket].write ? s : dns.SOCKET_BAD
|
|
||||||
);
|
|
||||||
}
|
|
||||||
updateTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function updateTimer() {
|
|
||||||
timer.stop();
|
|
||||||
|
|
||||||
for (var socket in activeWatchers) { // if !empty(activeWatchers)
|
|
||||||
var max = 20000;
|
|
||||||
var timeout = channel.timeout(max);
|
|
||||||
|
|
||||||
timer.start(timeout, 0);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var channel = new dns.Channel({SOCK_STATE_CB: function (socket, read, write) {
|
|
||||||
var watcher;
|
|
||||||
|
|
||||||
if (socket in watchers) {
|
|
||||||
watcher = watchers[socket].watcher;
|
|
||||||
} else {
|
|
||||||
watcher = new process.IOWatcher();
|
|
||||||
watchers[socket] = { read: read
|
|
||||||
, write: write
|
|
||||||
, watcher: watcher
|
|
||||||
};
|
|
||||||
|
|
||||||
watcher.callback = function(read, write) {
|
|
||||||
channel.processFD( read ? socket : dns.SOCKET_BAD
|
|
||||||
, write ? socket : dns.SOCKET_BAD
|
|
||||||
);
|
|
||||||
updateTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watcher.set(socket, read == 1, write == 1);
|
|
||||||
|
|
||||||
if (!(read || write)) {
|
|
||||||
watcher.stop();
|
|
||||||
delete activeWatchers[socket];
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
watcher.start();
|
|
||||||
activeWatchers[socket] = watcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTimer();
|
|
||||||
}});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exports.resolve = function (domain, type_, callback_) {
|
|
||||||
var type, callback;
|
|
||||||
if (typeof(type_) == 'string') {
|
|
||||||
type = type_;
|
|
||||||
callback = callback_;
|
|
||||||
} else {
|
|
||||||
type = 'A';
|
|
||||||
callback = arguments[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
var resolveFunc = resolveMap[type];
|
|
||||||
|
|
||||||
if (typeof(resolveFunc) == 'function') {
|
|
||||||
resolveFunc(domain, callback);
|
|
||||||
} else {
|
|
||||||
throw new Error('Unknown type "' + type + '"');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
exports.getHostByName = function (domain, callback) {
|
|
||||||
channel.getHostByName(domain, dns.AF_INET, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Easy DNS A/AAAA look up
|
|
||||||
exports.lookup = function (domain, callback) {
|
|
||||||
var addressType = dns.isIP(domain);
|
|
||||||
if (addressType) {
|
|
||||||
process.nextTick(function () {
|
|
||||||
callback(null, domain, addressType);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
channel.getHostByName(domain, dns.AF_INET, function (err, domains4) {
|
|
||||||
if (domains4 && domains4.length) {
|
|
||||||
callback(null, domains4[0], 4);
|
|
||||||
} else {
|
|
||||||
channel.getHostByName(domain, dns.AF_INET6, function (err, domains6) {
|
|
||||||
if (domains6 && domains6.length) {
|
|
||||||
callback(null, domains6[0], 6);
|
|
||||||
} else {
|
|
||||||
callback(err, []);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
exports.resolve4 = function(domain, callback) { channel.query(domain, dns.A, callback) };
|
|
||||||
exports.resolve6 = function(domain, callback) { channel.query(domain, dns.AAAA, callback) };
|
|
||||||
exports.resolveTxt = function(domain, callback) { channel.query(domain, dns.TXT, callback) };
|
|
||||||
exports.resolveSrv = function(domain, callback) { channel.query(domain, dns.SRV, callback) };
|
|
||||||
exports.reverse = function(domain, callback) { channel.query(domain, dns.PTR, callback) };
|
|
||||||
exports.resolveNs = function(domain, callback) { channel.query(domain, dns.NS, callback) };
|
|
||||||
|
|
||||||
|
|
||||||
var resolveMap = {
|
|
||||||
'A' : exports.resolve4,
|
|
||||||
'AAAA': exports.resolve6,
|
|
||||||
'TXT' : exports.resolveTxt,
|
|
||||||
'SRV' : exports.resolveSrv,
|
|
||||||
'PTR' : exports.resolvePtr,
|
|
||||||
'NS' : exports.resolveNs,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ERROR CODES
|
|
||||||
exports.NODATA = dns.NODATA;
|
|
||||||
exports.FORMERR = dns.FORMERR;
|
|
||||||
exports.BADRESP = dns.BADRESP;
|
|
||||||
exports.NOTFOUND = dns.NOTFOUND;
|
|
||||||
exports.BADNAME = dns.BADNAME;
|
|
||||||
exports.TIMEOUT = dns.TIMEOUT;
|
|
||||||
exports.CONNREFUSED = dns.CONNREFUSED;
|
|
||||||
exports.NOMEM = dns.NOMEM;
|
|
||||||
exports.DESTRUCTION = dns.DESTRUCTION;
|
|
||||||
|
|
||||||
exports.NOTIMP = dns.NOTIMP;
|
|
||||||
exports.EREFUSED = dns.EREFUSED;
|
|
||||||
exports.SERVFAIL = dns.SERVFAIL;
|
|
@ -1,7 +1,7 @@
|
|||||||
var sys = require("sys");
|
var sys = require("sys");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var events = require("events");
|
var events = require("events");
|
||||||
var dns = require('dns_cares');
|
var dns = require('dns');
|
||||||
|
|
||||||
var kMinPoolSpace = 128;
|
var kMinPoolSpace = 128;
|
||||||
var kPoolSize = 40*1024;
|
var kPoolSize = 40*1024;
|
||||||
|
11
src/node.cc
11
src/node.cc
@ -18,7 +18,6 @@
|
|||||||
#include <node_io_watcher.h>
|
#include <node_io_watcher.h>
|
||||||
#include <node_net2.h>
|
#include <node_net2.h>
|
||||||
#include <node_events.h>
|
#include <node_events.h>
|
||||||
#include <node_dns.h>
|
|
||||||
#include <node_cares.h>
|
#include <node_cares.h>
|
||||||
#include <node_net.h>
|
#include <node_net.h>
|
||||||
#include <node_file.h>
|
#include <node_file.h>
|
||||||
@ -1186,15 +1185,6 @@ static Handle<Value> Binding(const Arguments& args) {
|
|||||||
binding_cache->Set(module, exports);
|
binding_cache->Set(module, exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!strcmp(*module_v, "dns")) {
|
|
||||||
if (binding_cache->Has(module)) {
|
|
||||||
exports = binding_cache->Get(module)->ToObject();
|
|
||||||
} else {
|
|
||||||
exports = Object::New();
|
|
||||||
DNS::Initialize(exports);
|
|
||||||
binding_cache->Set(module, exports);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (!strcmp(*module_v, "cares")) {
|
} else if (!strcmp(*module_v, "cares")) {
|
||||||
if (binding_cache->Has(module)) {
|
if (binding_cache->Has(module)) {
|
||||||
exports = binding_cache->Get(module)->ToObject();
|
exports = binding_cache->Get(module)->ToObject();
|
||||||
@ -1276,7 +1266,6 @@ static Handle<Value> Binding(const Arguments& args) {
|
|||||||
exports->Set(String::New("buffer"), String::New(native_buffer));
|
exports->Set(String::New("buffer"), String::New(native_buffer));
|
||||||
exports->Set(String::New("child_process"),String::New(native_child_process));
|
exports->Set(String::New("child_process"),String::New(native_child_process));
|
||||||
exports->Set(String::New("dns"), String::New(native_dns));
|
exports->Set(String::New("dns"), String::New(native_dns));
|
||||||
exports->Set(String::New("dns_cares"), String::New(native_dns_cares));
|
|
||||||
exports->Set(String::New("events"), String::New(native_events));
|
exports->Set(String::New("events"), String::New(native_events));
|
||||||
exports->Set(String::New("file"), String::New(native_file));
|
exports->Set(String::New("file"), String::New(native_file));
|
||||||
exports->Set(String::New("fs"), String::New(native_fs));
|
exports->Set(String::New("fs"), String::New(native_fs));
|
||||||
|
514
src/node_dns.cc
514
src/node_dns.cc
@ -1,514 +0,0 @@
|
|||||||
// Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
|
|
||||||
#include <node_dns.h>
|
|
||||||
#include <node.h>
|
|
||||||
|
|
||||||
#include <stdlib.h> /* exit() */
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <v8.h>
|
|
||||||
#include <ev.h>
|
|
||||||
#include <udns.h>
|
|
||||||
|
|
||||||
namespace node {
|
|
||||||
|
|
||||||
using namespace v8;
|
|
||||||
|
|
||||||
static ev_io io_watcher;
|
|
||||||
static ev_timer timer_watcher;
|
|
||||||
|
|
||||||
static Persistent<String> errno_symbol;
|
|
||||||
static Persistent<String> exchange_symbol;
|
|
||||||
static Persistent<String> priority_symbol;
|
|
||||||
static Persistent<String> weight_symbol;
|
|
||||||
static Persistent<String> port_symbol;
|
|
||||||
static Persistent<String> name_symbol;
|
|
||||||
|
|
||||||
static inline void set_timeout() {
|
|
||||||
int maxwait = 20;
|
|
||||||
int wait = dns_timeouts(NULL, maxwait, ev_now(EV_DEFAULT_UC));
|
|
||||||
|
|
||||||
ev_timer_stop(EV_DEFAULT_UC_ &timer_watcher);
|
|
||||||
|
|
||||||
if (!dns_active(NULL)) return;
|
|
||||||
|
|
||||||
if (wait >= 0) {
|
|
||||||
ev_timer_set(&timer_watcher, static_cast<double>(wait), 0.0);
|
|
||||||
ev_timer_start(EV_DEFAULT_UC_ &timer_watcher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void maybe_start() {
|
|
||||||
ev_io_start(EV_DEFAULT_UC_ &io_watcher);
|
|
||||||
set_timeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ioevent(EV_P_ ev_io *_watcher, int revents) {
|
|
||||||
assert(revents == EV_READ);
|
|
||||||
assert(_watcher == &io_watcher);
|
|
||||||
dns_ioevent(NULL, ev_now(EV_DEFAULT_UC));
|
|
||||||
if (!dns_active(NULL)) ev_io_stop(EV_DEFAULT_UC_ &io_watcher);
|
|
||||||
set_timeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timeout(EV_P_ ev_timer *_watcher, int revents) {
|
|
||||||
assert(revents == EV_TIMEOUT);
|
|
||||||
assert(_watcher == &timer_watcher);
|
|
||||||
set_timeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ResolveError(Handle<Function> *cb) {
|
|
||||||
HandleScope scope;
|
|
||||||
int status = dns_status(NULL);
|
|
||||||
assert(status < 0);
|
|
||||||
|
|
||||||
Local<Value> e = Exception::Error(String::NewSymbol(dns_strerror(status)));
|
|
||||||
Local<Object> obj = e->ToObject();
|
|
||||||
obj->Set(errno_symbol, Integer::New(status));
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 1, &e);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterResolveA4(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_a4 *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnsa4_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnsa4_ttl);
|
|
||||||
|
|
||||||
Local<Array> addresses = Array::New(result->dnsa4_nrr);
|
|
||||||
for (int i = 0; i < result->dnsa4_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
char ip[INET_ADDRSTRLEN];
|
|
||||||
dns_ntop(AF_INET, &(result->dnsa4_addr[i]), ip, INET_ADDRSTRLEN);
|
|
||||||
Local<String> address = String::New(ip);
|
|
||||||
|
|
||||||
addresses->Set(Integer::New(i), address);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), addresses, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterResolveA6(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_a6 *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnsa6_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnsa6_ttl);
|
|
||||||
|
|
||||||
Local<Array> addresses = Array::New(result->dnsa6_nrr);
|
|
||||||
for (int i = 0; i < result->dnsa6_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
char ip[INET6_ADDRSTRLEN];
|
|
||||||
dns_ntop(AF_INET6, &(result->dnsa6_addr[i]), ip, INET6_ADDRSTRLEN);
|
|
||||||
Local<String> address = String::New(ip);
|
|
||||||
|
|
||||||
addresses->Set(Integer::New(i), address);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), addresses, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterResolveMX(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_mx *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnsmx_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnsmx_ttl);
|
|
||||||
|
|
||||||
Local<Array> exchanges = Array::New(result->dnsmx_nrr);
|
|
||||||
for (int i = 0; i < result->dnsmx_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
Local<Object> exchange = Object::New();
|
|
||||||
|
|
||||||
struct dns_mx *mx = &(result->dnsmx_mx[i]);
|
|
||||||
exchange->Set(exchange_symbol, String::New(mx->name));
|
|
||||||
exchange->Set(priority_symbol, Integer::New(mx->priority));
|
|
||||||
|
|
||||||
exchanges->Set(Integer::New(i), exchange);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), exchanges, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterResolveTXT(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_txt *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnstxt_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnstxt_ttl);
|
|
||||||
|
|
||||||
Local<Array> records = Array::New(result->dnstxt_nrr);
|
|
||||||
for (int i = 0; i < result->dnstxt_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
struct dns_txt *record = &(result->dnstxt_txt[i]);
|
|
||||||
const char *txt = (const char *)record->txt;
|
|
||||||
records->Set(Integer::New(i), String::New(txt));
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), records, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterResolveSRV(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_srv *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnssrv_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnssrv_ttl);
|
|
||||||
|
|
||||||
Local<Array> records = Array::New(result->dnssrv_nrr);
|
|
||||||
for (int i = 0; i < result->dnssrv_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
Local<Object> record = Object::New();
|
|
||||||
|
|
||||||
struct dns_srv *srv = &(result->dnssrv_srv[i]);
|
|
||||||
record->Set(priority_symbol, Integer::New(srv->priority));
|
|
||||||
record->Set(weight_symbol, Integer::New(srv->weight));
|
|
||||||
record->Set(port_symbol, Integer::New(srv->port));
|
|
||||||
record->Set(name_symbol, String::New(srv->name));
|
|
||||||
|
|
||||||
records->Set(Integer::New(i), record);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), records, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveA(int type, const Arguments& args) {
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
if (args.Length() == 0 || !args[0]->IsString()) {
|
|
||||||
return ThrowException(Exception::Error(
|
|
||||||
String::New("Argument must be a string.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args[1]->IsFunction()) {
|
|
||||||
return ThrowException(Exception::Error(
|
|
||||||
String::New("Missing callback argument")));
|
|
||||||
}
|
|
||||||
|
|
||||||
String::Utf8Value name(args[0]->ToString());
|
|
||||||
|
|
||||||
struct dns_query *query;
|
|
||||||
switch (type) {
|
|
||||||
case DNS_T_A:
|
|
||||||
query = dns_submit_a4(NULL, *name, 0, AfterResolveA4, cb_persist(args[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_AAAA:
|
|
||||||
query = dns_submit_a6(NULL, *name, 0, AfterResolveA6, cb_persist(args[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_MX:
|
|
||||||
query = dns_submit_mx(NULL, *name, 0, AfterResolveMX, cb_persist(args[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_TXT:
|
|
||||||
query = dns_submit_txt(NULL, *name, DNS_C_IN, 0, AfterResolveTXT, cb_persist(args[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DNS_T_SRV:
|
|
||||||
query = dns_submit_srv(NULL, *name, NULL, NULL, 0, AfterResolveSRV, cb_persist(args[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ThrowException(Exception::Error(String::New("Unsupported type")));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(query); // TODO(ry) better error handling.
|
|
||||||
|
|
||||||
maybe_start();
|
|
||||||
|
|
||||||
return Undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveA4(const Arguments& args) {
|
|
||||||
return ResolveA(DNS_T_A, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveA6(const Arguments& args) {
|
|
||||||
return ResolveA(DNS_T_AAAA, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveMX(const Arguments& args) {
|
|
||||||
return ResolveA(DNS_T_MX, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveTXT(const Arguments& args) {
|
|
||||||
return ResolveA(DNS_T_TXT, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> ResolveSRV(const Arguments& args) {
|
|
||||||
return ResolveA(DNS_T_SRV, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AfterReverse(struct dns_ctx *ctx,
|
|
||||||
struct dns_rr_ptr *result,
|
|
||||||
void *data) {
|
|
||||||
assert(ctx == &dns_defctx);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
Persistent<Function> *cb = cb_unwrap(data);
|
|
||||||
|
|
||||||
if (result == NULL) {
|
|
||||||
ResolveError(cb);
|
|
||||||
cb_destroy(cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* canonical name */
|
|
||||||
Local<String> cname = String::New(result->dnsptr_cname);
|
|
||||||
|
|
||||||
/* Time-To-Live (TTL) value */
|
|
||||||
Local<Integer> ttl = Integer::New(result->dnsptr_ttl);
|
|
||||||
|
|
||||||
Local<Array> domains = Array::New();
|
|
||||||
|
|
||||||
for (int i = 0; i < result->dnsptr_nrr; i++) {
|
|
||||||
HandleScope loop_scope;
|
|
||||||
|
|
||||||
Local<String> domain = String::New(result->dnsptr_ptr[i]);
|
|
||||||
domains->Set(Integer::New(i), domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[4] = { Local<Value>::New(Null()), domains, ttl, cname };
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
|
||||||
|
|
||||||
(*cb)->Call(Context::GetCurrent()->Global(), 4, argv);
|
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
FatalException(try_catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb_destroy(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Handle<Value> Reverse(const Arguments& args) {
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
if (args.Length() == 0 || !args[0]->IsString()) {
|
|
||||||
return ThrowException(Exception::Error(
|
|
||||||
String::New("Argument must be a string.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args[1]->IsFunction()) {
|
|
||||||
return ThrowException(Exception::Error(
|
|
||||||
String::New("Missing callback argument")));
|
|
||||||
}
|
|
||||||
|
|
||||||
String::Utf8Value ip_address(args[0]->ToString());
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct in_addr addr;
|
|
||||||
struct in6_addr addr6;
|
|
||||||
} a;
|
|
||||||
|
|
||||||
bool v4;
|
|
||||||
|
|
||||||
if (dns_pton(AF_INET, *ip_address, &a.addr) > 0) {
|
|
||||||
v4 = true;
|
|
||||||
} else if (dns_pton(AF_INET6, *ip_address, &a.addr6) > 0) {
|
|
||||||
v4 = false;
|
|
||||||
} else {
|
|
||||||
return ThrowException(Exception::Error(String::New("Invalid IP address")));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct dns_query *query;
|
|
||||||
|
|
||||||
if (v4) {
|
|
||||||
query = dns_submit_a4ptr(NULL, &a.addr, AfterReverse, cb_persist(args[1]));
|
|
||||||
} else {
|
|
||||||
query = dns_submit_a6ptr(NULL, &a.addr6, AfterReverse, cb_persist(args[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(query); // TODO(ry) better error handling.
|
|
||||||
|
|
||||||
maybe_start();
|
|
||||||
|
|
||||||
return Undefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DNS::Initialize(Handle<Object> target) {
|
|
||||||
if (dns_init(NULL, 0) < 0) {
|
|
||||||
fprintf(stderr, "Error initializing UDNS context\n");
|
|
||||||
exit(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = dns_open(NULL);
|
|
||||||
|
|
||||||
ev_io_init(&io_watcher, ioevent, fd, EV_READ);
|
|
||||||
ev_init(&timer_watcher, timeout);
|
|
||||||
|
|
||||||
HandleScope scope;
|
|
||||||
|
|
||||||
errno_symbol = NODE_PSYMBOL("errno");
|
|
||||||
|
|
||||||
exchange_symbol = NODE_PSYMBOL("exchange");
|
|
||||||
priority_symbol = NODE_PSYMBOL("priority");
|
|
||||||
weight_symbol = NODE_PSYMBOL("weight");
|
|
||||||
port_symbol = NODE_PSYMBOL("port");
|
|
||||||
name_symbol = NODE_PSYMBOL("name");
|
|
||||||
|
|
||||||
target->Set(String::NewSymbol("TEMPFAIL"), Integer::New(DNS_E_TEMPFAIL));
|
|
||||||
target->Set(String::NewSymbol("PROTOCOL"), Integer::New(DNS_E_PROTOCOL));
|
|
||||||
target->Set(String::NewSymbol("NXDOMAIN"), Integer::New(DNS_E_NXDOMAIN));
|
|
||||||
target->Set(String::NewSymbol("NODATA"), Integer::New(DNS_E_NODATA));
|
|
||||||
target->Set(String::NewSymbol("NOMEM"), Integer::New(DNS_E_NOMEM));
|
|
||||||
target->Set(String::NewSymbol("BADQUERY"), Integer::New(DNS_E_BADQUERY));
|
|
||||||
|
|
||||||
Local<FunctionTemplate> resolve4 = FunctionTemplate::New(ResolveA4);
|
|
||||||
target->Set(String::NewSymbol("resolve4"), resolve4->GetFunction());
|
|
||||||
|
|
||||||
Local<FunctionTemplate> resolve6 = FunctionTemplate::New(ResolveA6);
|
|
||||||
target->Set(String::NewSymbol("resolve6"), resolve6->GetFunction());
|
|
||||||
|
|
||||||
Local<FunctionTemplate> resolveMx = FunctionTemplate::New(ResolveMX);
|
|
||||||
target->Set(String::NewSymbol("resolveMx"), resolveMx->GetFunction());
|
|
||||||
|
|
||||||
Local<FunctionTemplate> resolveTxt = FunctionTemplate::New(ResolveTXT);
|
|
||||||
target->Set(String::NewSymbol("resolveTxt"), resolveTxt->GetFunction());
|
|
||||||
|
|
||||||
Local<FunctionTemplate> resolveSrv = FunctionTemplate::New(ResolveSRV);
|
|
||||||
target->Set(String::NewSymbol("resolveSrv"), resolveSrv->GetFunction());
|
|
||||||
|
|
||||||
Local<FunctionTemplate> reverse = FunctionTemplate::New(Reverse);
|
|
||||||
target->Set(String::NewSymbol("reverse"), reverse->GetFunction());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace node
|
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
|
|
||||||
#ifndef SRC_DNS_H_
|
|
||||||
#define SRC_DNS_H_
|
|
||||||
|
|
||||||
#include <node.h>
|
|
||||||
#include <v8.h>
|
|
||||||
|
|
||||||
namespace node {
|
|
||||||
|
|
||||||
class DNS {
|
|
||||||
public:
|
|
||||||
static void Initialize(v8::Handle<v8::Object> target);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace node
|
|
||||||
#endif // SRC_DNS_H_
|
|
@ -1,6 +1,6 @@
|
|||||||
require("../common");
|
require("../common");
|
||||||
|
|
||||||
var dns = require("dns_cares"),
|
var dns = require("dns"),
|
||||||
child_process = require("child_process"),
|
child_process = require("child_process"),
|
||||||
sys = require("sys");
|
sys = require("sys");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
require('../common');
|
require('../common');
|
||||||
|
|
||||||
var dns = require("dns_cares");
|
var dns = require("dns");
|
||||||
|
|
||||||
|
|
||||||
// Try resolution without callback
|
// Try resolution without callback
|
||||||
|
43
wscript
43
wscript
@ -157,10 +157,6 @@ def configure(conf):
|
|||||||
if not Options.options.system:
|
if not Options.options.system:
|
||||||
conf.sub_config('deps/libev')
|
conf.sub_config('deps/libev')
|
||||||
conf.sub_config('deps/c-ares')
|
conf.sub_config('deps/c-ares')
|
||||||
if sys.platform.startswith("sunos"):
|
|
||||||
conf_subproject(conf, 'deps/udns', 'LIBS="-lsocket -lnsl" ./configure')
|
|
||||||
else:
|
|
||||||
conf_subproject(conf, 'deps/udns', './configure')
|
|
||||||
else:
|
else:
|
||||||
if not conf.check(lib='v8', uselib_store='V8'):
|
if not conf.check(lib='v8', uselib_store='V8'):
|
||||||
conf.fatal("Cannot find V8")
|
conf.fatal("Cannot find V8")
|
||||||
@ -168,8 +164,6 @@ def configure(conf):
|
|||||||
conf.fatal("Cannot find libev")
|
conf.fatal("Cannot find libev")
|
||||||
if not conf.check(lib='cares', uselib_store='CARES'):
|
if not conf.check(lib='cares', uselib_store='CARES'):
|
||||||
conf.fatal("Cannot find c-ares")
|
conf.fatal("Cannot find c-ares")
|
||||||
if not conf.check(lib='udns', uselib_store='UDNS'):
|
|
||||||
conf.fatal("Cannot find udns")
|
|
||||||
|
|
||||||
conf.define("HAVE_CONFIG_H", 1)
|
conf.define("HAVE_CONFIG_H", 1)
|
||||||
|
|
||||||
@ -213,36 +207,6 @@ def configure(conf):
|
|||||||
conf.env.append_value('CXXFLAGS', ['-DNDEBUG', '-O3'])
|
conf.env.append_value('CXXFLAGS', ['-DNDEBUG', '-O3'])
|
||||||
conf.write_config_header("config.h")
|
conf.write_config_header("config.h")
|
||||||
|
|
||||||
def build_udns(bld):
|
|
||||||
default_build_dir = bld.srcnode.abspath(bld.env_of_name("default"))
|
|
||||||
|
|
||||||
default_dir = join(default_build_dir, "deps/udns")
|
|
||||||
|
|
||||||
static_lib = bld.env["staticlib_PATTERN"] % "udns"
|
|
||||||
|
|
||||||
rule = 'cd "%s" && make'
|
|
||||||
|
|
||||||
default = bld.new_task_gen(
|
|
||||||
target= join("deps/udns", static_lib),
|
|
||||||
rule= rule % default_dir,
|
|
||||||
before= "cxx",
|
|
||||||
install_path= None
|
|
||||||
)
|
|
||||||
|
|
||||||
bld.env["CPPPATH_UDNS"] = "deps/udns"
|
|
||||||
t = join(bld.srcnode.abspath(bld.env_of_name("default")), default.target)
|
|
||||||
bld.env_of_name('default')["LINKFLAGS_UDNS"] = [t]
|
|
||||||
|
|
||||||
if bld.env["USE_DEBUG"]:
|
|
||||||
debug_build_dir = bld.srcnode.abspath(bld.env_of_name("debug"))
|
|
||||||
debug_dir = join(debug_build_dir, "deps/udns")
|
|
||||||
debug = default.clone("debug")
|
|
||||||
debug.rule = rule % debug_dir
|
|
||||||
t = join(bld.srcnode.abspath(bld.env_of_name("debug")), debug.target)
|
|
||||||
bld.env_of_name('debug')["LINKFLAGS_UDNS"] = [t]
|
|
||||||
|
|
||||||
bld.install_files('${PREFIX}/include/node/', 'deps/udns/udns.h')
|
|
||||||
|
|
||||||
|
|
||||||
def v8_cmd(bld, variant):
|
def v8_cmd(bld, variant):
|
||||||
scons = join(cwd, 'tools/scons/scons.py')
|
scons = join(cwd, 'tools/scons/scons.py')
|
||||||
@ -308,7 +272,6 @@ def build(bld):
|
|||||||
|
|
||||||
if not bld.env["USE_SYSTEM"]:
|
if not bld.env["USE_SYSTEM"]:
|
||||||
bld.add_subdirs('deps/libeio deps/libev deps/c-ares')
|
bld.add_subdirs('deps/libeio deps/libev deps/c-ares')
|
||||||
build_udns(bld)
|
|
||||||
build_v8(bld)
|
build_v8(bld)
|
||||||
else:
|
else:
|
||||||
bld.add_subdirs('deps/libeio')
|
bld.add_subdirs('deps/libeio')
|
||||||
@ -413,7 +376,6 @@ def build(bld):
|
|||||||
src/node_io_watcher.cc
|
src/node_io_watcher.cc
|
||||||
src/node_child_process.cc
|
src/node_child_process.cc
|
||||||
src/node_constants.cc
|
src/node_constants.cc
|
||||||
src/node_dns.cc
|
|
||||||
src/node_cares.cc
|
src/node_cares.cc
|
||||||
src/node_events.cc
|
src/node_events.cc
|
||||||
src/node_file.cc
|
src/node_file.cc
|
||||||
@ -431,7 +393,6 @@ def build(bld):
|
|||||||
deps/v8/include
|
deps/v8/include
|
||||||
deps/libev
|
deps/libev
|
||||||
deps/c-ares
|
deps/c-ares
|
||||||
deps/udns
|
|
||||||
deps/libeio
|
deps/libeio
|
||||||
deps/evcom
|
deps/evcom
|
||||||
deps/http_parser
|
deps/http_parser
|
||||||
@ -443,7 +404,7 @@ def build(bld):
|
|||||||
|
|
||||||
node.add_objects = 'cares ev eio evcom http_parser coupling'
|
node.add_objects = 'cares ev eio evcom http_parser coupling'
|
||||||
node.uselib_local = ''
|
node.uselib_local = ''
|
||||||
node.uselib = 'RT GNUTLS GPGERROR UDNS CARES V8 EXECINFO DL KVM SOCKET NSL'
|
node.uselib = 'RT GNUTLS GPGERROR CARES V8 EXECINFO DL KVM SOCKET NSL'
|
||||||
else:
|
else:
|
||||||
node.includes = """
|
node.includes = """
|
||||||
src/
|
src/
|
||||||
@ -454,7 +415,7 @@ def build(bld):
|
|||||||
"""
|
"""
|
||||||
node.add_objects = 'eio evcom http_parser coupling'
|
node.add_objects = 'eio evcom http_parser coupling'
|
||||||
node.uselib_local = 'eio'
|
node.uselib_local = 'eio'
|
||||||
node.uselib = 'RT EV GNUTLS GPGERROR UDNS CARES V8 EXECINFO DL KVM SOCKET NSL'
|
node.uselib = 'RT EV GNUTLS GPGERROR CARES V8 EXECINFO DL KVM SOCKET NSL'
|
||||||
|
|
||||||
node.install_path = '${PREFIX}/lib'
|
node.install_path = '${PREFIX}/lib'
|
||||||
node.install_path = '${PREFIX}/bin'
|
node.install_path = '${PREFIX}/bin'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user