mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Fix godeps
This commit is contained in:
		
							
								
								
									
										30
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										30
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -676,11 +676,6 @@
 | 
			
		||||
			"ImportPath": "github.com/coreos/go-semver/semver",
 | 
			
		||||
			"Rev": "568e959cd89871e61434c1143528d9162da89ef2"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/coreos/go-systemd/activation",
 | 
			
		||||
			"Comment": "v8-2-g4484981",
 | 
			
		||||
			"Rev": "4484981625c1a6a2ecb40a390fcb6a9bcfee76e3"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/coreos/go-systemd/daemon",
 | 
			
		||||
			"Comment": "v8-2-g4484981",
 | 
			
		||||
@@ -2141,31 +2136,6 @@
 | 
			
		||||
			"ImportPath": "github.com/shurcooL/sanitized_anchor_name",
 | 
			
		||||
			"Rev": "10ef21a441db47d8b13ebcc5fd2310f636973c77"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/skynetservices/skydns/cache",
 | 
			
		||||
			"Comment": "2.5.3a-41-g00ade30",
 | 
			
		||||
			"Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/skynetservices/skydns/metrics",
 | 
			
		||||
			"Comment": "2.5.3a-41-g00ade30",
 | 
			
		||||
			"Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/skynetservices/skydns/msg",
 | 
			
		||||
			"Comment": "2.5.3a-41-g00ade30",
 | 
			
		||||
			"Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/skynetservices/skydns/server",
 | 
			
		||||
			"Comment": "2.5.3a-41-g00ade30",
 | 
			
		||||
			"Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/skynetservices/skydns/singleflight",
 | 
			
		||||
			"Comment": "2.5.3a-41-g00ade30",
 | 
			
		||||
			"Rev": "00ade3024f047d26130abf161900e0adb72a06f1"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/spf13/afero",
 | 
			
		||||
			"Rev": "b28a7effac979219c2a2ed6205a4d70e4b1bcd02"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										344
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										344
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -23236,205 +23236,6 @@ Apache License
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coreos/go-systemd/activation licensed under: =
 | 
			
		||||
 | 
			
		||||
Apache License
 | 
			
		||||
Version 2.0, January 2004
 | 
			
		||||
http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
1. Definitions.
 | 
			
		||||
 | 
			
		||||
"License" shall mean the terms and conditions for use, reproduction, and
 | 
			
		||||
distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
 | 
			
		||||
owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
"Legal Entity" shall mean the union of the acting entity and all other entities
 | 
			
		||||
that control, are controlled by, or are under common control with that entity.
 | 
			
		||||
For the purposes of this definition, "control" means (i) the power, direct or
 | 
			
		||||
indirect, to cause the direction or management of such entity, whether by
 | 
			
		||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
 | 
			
		||||
permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
"Source" form shall mean the preferred form for making modifications, including
 | 
			
		||||
but not limited to software source code, documentation source, and configuration
 | 
			
		||||
files.
 | 
			
		||||
 | 
			
		||||
"Object" form shall mean any form resulting from mechanical transformation or
 | 
			
		||||
translation of a Source form, including but not limited to compiled object code,
 | 
			
		||||
generated documentation, and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
 | 
			
		||||
available under the License, as indicated by a copyright notice that is included
 | 
			
		||||
in or attached to the work (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
 | 
			
		||||
is based on (or derived from) the Work and for which the editorial revisions,
 | 
			
		||||
annotations, elaborations, or other modifications represent, as a whole, an
 | 
			
		||||
original work of authorship. For the purposes of this License, Derivative Works
 | 
			
		||||
shall not include works that remain separable from, or merely link (or bind by
 | 
			
		||||
name) to the interfaces of, the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
"Contribution" shall mean any work of authorship, including the original version
 | 
			
		||||
of the Work and any modifications or additions to that Work or Derivative Works
 | 
			
		||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
 | 
			
		||||
by the copyright owner or by an individual or Legal Entity authorized to submit
 | 
			
		||||
on behalf of the copyright owner. For the purposes of this definition,
 | 
			
		||||
"submitted" means any form of electronic, verbal, or written communication sent
 | 
			
		||||
to the Licensor or its representatives, including but not limited to
 | 
			
		||||
communication on electronic mailing lists, source code control systems, and
 | 
			
		||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
 | 
			
		||||
the purpose of discussing and improving the Work, but excluding communication
 | 
			
		||||
that is conspicuously marked or otherwise designated in writing by the copyright
 | 
			
		||||
owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
 | 
			
		||||
of whom a Contribution has been received by Licensor and subsequently
 | 
			
		||||
incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
2. Grant of Copyright License.
 | 
			
		||||
 | 
			
		||||
Subject to the terms and conditions of this License, each Contributor hereby
 | 
			
		||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
 | 
			
		||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
publicly display, publicly perform, sublicense, and distribute the Work and such
 | 
			
		||||
Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
3. Grant of Patent License.
 | 
			
		||||
 | 
			
		||||
Subject to the terms and conditions of this License, each Contributor hereby
 | 
			
		||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
 | 
			
		||||
irrevocable (except as stated in this section) patent license to make, have
 | 
			
		||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
 | 
			
		||||
such license applies only to those patent claims licensable by such Contributor
 | 
			
		||||
that are necessarily infringed by their Contribution(s) alone or by combination
 | 
			
		||||
of their Contribution(s) with the Work to which such Contribution(s) was
 | 
			
		||||
submitted. If You institute patent litigation against any entity (including a
 | 
			
		||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
 | 
			
		||||
Contribution incorporated within the Work constitutes direct or contributory
 | 
			
		||||
patent infringement, then any patent licenses granted to You under this License
 | 
			
		||||
for that Work shall terminate as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
4. Redistribution.
 | 
			
		||||
 | 
			
		||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
 | 
			
		||||
in any medium, with or without modifications, and in Source or Object form,
 | 
			
		||||
provided that You meet the following conditions:
 | 
			
		||||
 | 
			
		||||
You must give any other recipients of the Work or Derivative Works a copy of
 | 
			
		||||
this License; and
 | 
			
		||||
You must cause any modified files to carry prominent notices stating that You
 | 
			
		||||
changed the files; and
 | 
			
		||||
You must retain, in the Source form of any Derivative Works that You distribute,
 | 
			
		||||
all copyright, patent, trademark, and attribution notices from the Source form
 | 
			
		||||
of the Work, excluding those notices that do not pertain to any part of the
 | 
			
		||||
Derivative Works; and
 | 
			
		||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
 | 
			
		||||
Derivative Works that You distribute must include a readable copy of the
 | 
			
		||||
attribution notices contained within such NOTICE file, excluding those notices
 | 
			
		||||
that do not pertain to any part of the Derivative Works, in at least one of the
 | 
			
		||||
following places: within a NOTICE text file distributed as part of the
 | 
			
		||||
Derivative Works; within the Source form or documentation, if provided along
 | 
			
		||||
with the Derivative Works; or, within a display generated by the Derivative
 | 
			
		||||
Works, if and wherever such third-party notices normally appear. The contents of
 | 
			
		||||
the NOTICE file are for informational purposes only and do not modify the
 | 
			
		||||
License. You may add Your own attribution notices within Derivative Works that
 | 
			
		||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
 | 
			
		||||
provided that such additional attribution notices cannot be construed as
 | 
			
		||||
modifying the License.
 | 
			
		||||
You may add Your own copyright statement to Your modifications and may provide
 | 
			
		||||
additional or different license terms and conditions for use, reproduction, or
 | 
			
		||||
distribution of Your modifications, or for any such Derivative Works as a whole,
 | 
			
		||||
provided Your use, reproduction, and distribution of the Work otherwise complies
 | 
			
		||||
with the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
5. Submission of Contributions.
 | 
			
		||||
 | 
			
		||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
 | 
			
		||||
for inclusion in the Work by You to the Licensor shall be under the terms and
 | 
			
		||||
conditions of this License, without any additional terms or conditions.
 | 
			
		||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
 | 
			
		||||
any separate license agreement you may have executed with Licensor regarding
 | 
			
		||||
such Contributions.
 | 
			
		||||
 | 
			
		||||
6. Trademarks.
 | 
			
		||||
 | 
			
		||||
This License does not grant permission to use the trade names, trademarks,
 | 
			
		||||
service marks, or product names of the Licensor, except as required for
 | 
			
		||||
reasonable and customary use in describing the origin of the Work and
 | 
			
		||||
reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
7. Disclaimer of Warranty.
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, Licensor provides the
 | 
			
		||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
 | 
			
		||||
including, without limitation, any warranties or conditions of TITLE,
 | 
			
		||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
 | 
			
		||||
solely responsible for determining the appropriateness of using or
 | 
			
		||||
redistributing the Work and assume any risks associated with Your exercise of
 | 
			
		||||
permissions under this License.
 | 
			
		||||
 | 
			
		||||
8. Limitation of Liability.
 | 
			
		||||
 | 
			
		||||
In no event and under no legal theory, whether in tort (including negligence),
 | 
			
		||||
contract, or otherwise, unless required by applicable law (such as deliberate
 | 
			
		||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
liable to You for damages, including any direct, indirect, special, incidental,
 | 
			
		||||
or consequential damages of any character arising as a result of this License or
 | 
			
		||||
out of the use or inability to use the Work (including but not limited to
 | 
			
		||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
 | 
			
		||||
any and all other commercial damages or losses), even if such Contributor has
 | 
			
		||||
been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
9. Accepting Warranty or Additional Liability.
 | 
			
		||||
 | 
			
		||||
While redistributing the Work or Derivative Works thereof, You may choose to
 | 
			
		||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
 | 
			
		||||
other liability obligations and/or rights consistent with this License. However,
 | 
			
		||||
in accepting such obligations, You may act only on Your own behalf and on Your
 | 
			
		||||
sole responsibility, not on behalf of any other Contributor, and only if You
 | 
			
		||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
 | 
			
		||||
incurred by, or claims asserted against, such Contributor by reason of your
 | 
			
		||||
accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
APPENDIX: How to apply the Apache License to your work
 | 
			
		||||
 | 
			
		||||
To apply the Apache License to your work, attach the following boilerplate
 | 
			
		||||
notice, with the fields enclosed by brackets "[]" replaced with your own
 | 
			
		||||
identifying information. (Don't include the brackets!) The text should be
 | 
			
		||||
enclosed in the appropriate comment syntax for the file format. We also
 | 
			
		||||
recommend that a file or class name and description of purpose be included on
 | 
			
		||||
the same "printed page" as the copyright notice for easier identification within
 | 
			
		||||
third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/coreos/go-systemd/LICENSE 19cbd64715b51267a47bf3750cc6a8a5  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coreos/go-systemd/daemon licensed under: =
 | 
			
		||||
 | 
			
		||||
@@ -67078,151 +66879,6 @@ THE SOFTWARE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/cache licensed under: =
 | 
			
		||||
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/LICENSE 132bec980d83cb58e26698e7f4832569  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/metrics licensed under: =
 | 
			
		||||
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/LICENSE 132bec980d83cb58e26698e7f4832569  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/msg licensed under: =
 | 
			
		||||
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/LICENSE 132bec980d83cb58e26698e7f4832569  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/server licensed under: =
 | 
			
		||||
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/LICENSE 132bec980d83cb58e26698e7f4832569  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/singleflight licensed under: =
 | 
			
		||||
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/skynetservices/skydns/LICENSE 132bec980d83cb58e26698e7f4832569  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/spf13/afero licensed under: =
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							@@ -1946,16 +1946,6 @@ go_library(
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/coreos/go-systemd/activation",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "github.com/coreos/go-systemd/activation/files.go",
 | 
			
		||||
        "github.com/coreos/go-systemd/activation/listeners.go",
 | 
			
		||||
        "github.com/coreos/go-systemd/activation/packetconns.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/coreos/go-systemd/daemon",
 | 
			
		||||
    srcs = ["github.com/coreos/go-systemd/daemon/sdnotify.go"],
 | 
			
		||||
@@ -6036,66 +6026,6 @@ go_library(
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/skynetservices/skydns/cache",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "github.com/skynetservices/skydns/cache/cache.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/cache/hit.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = ["//vendor:github.com/miekg/dns"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/skynetservices/skydns/metrics",
 | 
			
		||||
    srcs = ["github.com/skynetservices/skydns/metrics/metrics.go"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//vendor:github.com/miekg/dns",
 | 
			
		||||
        "//vendor:github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/skynetservices/skydns/msg",
 | 
			
		||||
    srcs = ["github.com/skynetservices/skydns/msg/service.go"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = ["//vendor:github.com/miekg/dns"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/skynetservices/skydns/server",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "github.com/skynetservices/skydns/server/backend.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/config.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/dnssec.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/doc.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/exchange.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/forwarding.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/log.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/msg.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/nsec3.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/server.go",
 | 
			
		||||
        "github.com/skynetservices/skydns/server/stub.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//vendor:github.com/coreos/etcd/client",
 | 
			
		||||
        "//vendor:github.com/coreos/go-systemd/activation",
 | 
			
		||||
        "//vendor:github.com/miekg/dns",
 | 
			
		||||
        "//vendor:github.com/skynetservices/skydns/cache",
 | 
			
		||||
        "//vendor:github.com/skynetservices/skydns/metrics",
 | 
			
		||||
        "//vendor:github.com/skynetservices/skydns/msg",
 | 
			
		||||
        "//vendor:github.com/skynetservices/skydns/singleflight",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/skynetservices/skydns/singleflight",
 | 
			
		||||
    srcs = ["github.com/skynetservices/skydns/singleflight/singleflight.go"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "github.com/spf13/afero",
 | 
			
		||||
    srcs = [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/github.com/coreos/go-systemd/activation/files.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/coreos/go-systemd/activation/files.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,52 +0,0 @@
 | 
			
		||||
// Copyright 2015 CoreOS, Inc.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package activation implements primitives for systemd socket activation.
 | 
			
		||||
package activation
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// based on: https://gist.github.com/alberts/4640792
 | 
			
		||||
const (
 | 
			
		||||
	listenFdsStart = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Files(unsetEnv bool) []*os.File {
 | 
			
		||||
	if unsetEnv {
 | 
			
		||||
		defer os.Unsetenv("LISTEN_PID")
 | 
			
		||||
		defer os.Unsetenv("LISTEN_FDS")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
 | 
			
		||||
	if err != nil || pid != os.Getpid() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
 | 
			
		||||
	if err != nil || nfds == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	files := make([]*os.File, 0, nfds)
 | 
			
		||||
	for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
 | 
			
		||||
		syscall.CloseOnExec(fd)
 | 
			
		||||
		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return files
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								vendor/github.com/coreos/go-systemd/activation/listeners.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/coreos/go-systemd/activation/listeners.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,62 +0,0 @@
 | 
			
		||||
// Copyright 2015 CoreOS, Inc.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package activation
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"net"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Listeners returns a slice containing a net.Listener for each matching socket type
 | 
			
		||||
// passed to this process.
 | 
			
		||||
//
 | 
			
		||||
// The order of the file descriptors is preserved in the returned slice.
 | 
			
		||||
// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
 | 
			
		||||
// corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener}
 | 
			
		||||
func Listeners(unsetEnv bool) ([]net.Listener, error) {
 | 
			
		||||
	files := Files(unsetEnv)
 | 
			
		||||
	listeners := make([]net.Listener, len(files))
 | 
			
		||||
 | 
			
		||||
	for i, f := range files {
 | 
			
		||||
		if pc, err := net.FileListener(f); err == nil {
 | 
			
		||||
			listeners[i] = pc
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return listeners, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TLSListeners returns a slice containing a net.listener for each matching TCP socket type
 | 
			
		||||
// passed to this process.
 | 
			
		||||
// It uses default Listeners func and forces TCP sockets handlers to use TLS based on tlsConfig.
 | 
			
		||||
func TLSListeners(unsetEnv bool, tlsConfig *tls.Config) ([]net.Listener, error) {
 | 
			
		||||
	listeners, err := Listeners(unsetEnv)
 | 
			
		||||
 | 
			
		||||
	if listeners == nil || err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if tlsConfig != nil && err == nil {
 | 
			
		||||
		tlsConfig.NextProtos = []string{"http/1.1"}
 | 
			
		||||
 | 
			
		||||
		for i, l := range listeners {
 | 
			
		||||
			// Activate TLS only for TCP sockets
 | 
			
		||||
			if l.Addr().Network() == "tcp" {
 | 
			
		||||
				listeners[i] = tls.NewListener(l, tlsConfig)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return listeners, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								vendor/github.com/coreos/go-systemd/activation/packetconns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/coreos/go-systemd/activation/packetconns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,37 +0,0 @@
 | 
			
		||||
// Copyright 2015 CoreOS, Inc.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package activation
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// PacketConns returns a slice containing a net.PacketConn for each matching socket type
 | 
			
		||||
// passed to this process.
 | 
			
		||||
//
 | 
			
		||||
// The order of the file descriptors is preserved in the returned slice.
 | 
			
		||||
// Nil values are used to fill any gaps. For example if systemd were to return file descriptors
 | 
			
		||||
// corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn}
 | 
			
		||||
func PacketConns(unsetEnv bool) ([]net.PacketConn, error) {
 | 
			
		||||
	files := Files(unsetEnv)
 | 
			
		||||
	conns := make([]net.PacketConn, len(files))
 | 
			
		||||
 | 
			
		||||
	for i, f := range files {
 | 
			
		||||
		if pc, err := net.FilePacketConn(f); err == nil {
 | 
			
		||||
			conns[i] = pc
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return conns, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/github.com/skynetservices/skydns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/skynetservices/skydns/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,21 +0,0 @@
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2013 The SkyDNS Authors
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										167
									
								
								vendor/github.com/skynetservices/skydns/cache/cache.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										167
									
								
								vendor/github.com/skynetservices/skydns/cache/cache.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,167 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
// Cache that holds RRs and for DNSSEC an RRSIG.
 | 
			
		||||
 | 
			
		||||
// TODO(miek): there is a lot of copying going on to copy myself out of data
 | 
			
		||||
// races. This should be optimized.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/sha1"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Elem hold an answer and additional section that returned from the cache.
 | 
			
		||||
// The signature is put in answer, extra is empty there. This wastes some memory.
 | 
			
		||||
type elem struct {
 | 
			
		||||
	expiration time.Time // time added + TTL, after this the elem is invalid
 | 
			
		||||
	msg        *dns.Msg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cache is a cache that holds on the a number of RRs or DNS messages. The cache
 | 
			
		||||
// eviction is randomized.
 | 
			
		||||
type Cache struct {
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
 | 
			
		||||
	capacity int
 | 
			
		||||
	m        map[string]*elem
 | 
			
		||||
	ttl      time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New returns a new cache with the capacity and the ttl specified.
 | 
			
		||||
func New(capacity, ttl int) *Cache {
 | 
			
		||||
	c := new(Cache)
 | 
			
		||||
	c.m = make(map[string]*elem)
 | 
			
		||||
	c.capacity = capacity
 | 
			
		||||
	c.ttl = time.Duration(ttl) * time.Second
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Cache) Capacity() int { return c.capacity }
 | 
			
		||||
 | 
			
		||||
func (c *Cache) Remove(s string) {
 | 
			
		||||
	c.Lock()
 | 
			
		||||
	delete(c.m, s)
 | 
			
		||||
	c.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EvictRandom removes a random member a the cache.
 | 
			
		||||
// Must be called under a write lock.
 | 
			
		||||
func (c *Cache) EvictRandom() {
 | 
			
		||||
	clen := len(c.m)
 | 
			
		||||
	if clen < c.capacity {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	i := c.capacity - clen
 | 
			
		||||
	for k, _ := range c.m {
 | 
			
		||||
		delete(c.m, k)
 | 
			
		||||
		i--
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InsertMessage inserts a message in the Cache. We will cache it for ttl seconds, which
 | 
			
		||||
// should be a small (60...300) integer.
 | 
			
		||||
func (c *Cache) InsertMessage(s string, msg *dns.Msg) {
 | 
			
		||||
	if c.capacity <= 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.Lock()
 | 
			
		||||
	if _, ok := c.m[s]; !ok {
 | 
			
		||||
		c.m[s] = &elem{time.Now().UTC().Add(c.ttl), msg.Copy()}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	c.EvictRandom()
 | 
			
		||||
	c.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InsertSignature inserts a signature, the expiration time is used as the cache ttl.
 | 
			
		||||
func (c *Cache) InsertSignature(s string, sig *dns.RRSIG) {
 | 
			
		||||
	if c.capacity <= 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	c.Lock()
 | 
			
		||||
 | 
			
		||||
	if _, ok := c.m[s]; !ok {
 | 
			
		||||
		m := ((int64(sig.Expiration) - time.Now().Unix()) / (1 << 31)) - 1
 | 
			
		||||
		if m < 0 {
 | 
			
		||||
			m = 0
 | 
			
		||||
		}
 | 
			
		||||
		t := time.Unix(int64(sig.Expiration)-(m*(1<<31)), 0).UTC()
 | 
			
		||||
		c.m[s] = &elem{t, &dns.Msg{Answer: []dns.RR{dns.Copy(sig)}}}
 | 
			
		||||
	}
 | 
			
		||||
	c.EvictRandom()
 | 
			
		||||
	c.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Search returns a dns.Msg, the expiration time and a boolean indicating if we found something
 | 
			
		||||
// in the cache.
 | 
			
		||||
func (c *Cache) Search(s string) (*dns.Msg, time.Time, bool) {
 | 
			
		||||
	if c.capacity <= 0 {
 | 
			
		||||
		return nil, time.Time{}, false
 | 
			
		||||
	}
 | 
			
		||||
	c.RLock()
 | 
			
		||||
	if e, ok := c.m[s]; ok {
 | 
			
		||||
		e1 := e.msg.Copy()
 | 
			
		||||
		c.RUnlock()
 | 
			
		||||
		return e1, e.expiration, true
 | 
			
		||||
	}
 | 
			
		||||
	c.RUnlock()
 | 
			
		||||
	return nil, time.Time{}, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Key creates a hash key from a question section. It creates a different key
 | 
			
		||||
// for requests with DNSSEC.
 | 
			
		||||
func Key(q dns.Question, dnssec, tcp bool) string {
 | 
			
		||||
	h := sha1.New()
 | 
			
		||||
	i := append([]byte(q.Name), packUint16(q.Qtype)...)
 | 
			
		||||
	if dnssec {
 | 
			
		||||
		i = append(i, byte(255))
 | 
			
		||||
	}
 | 
			
		||||
	if tcp {
 | 
			
		||||
		i = append(i, byte(254))
 | 
			
		||||
	}
 | 
			
		||||
	return string(h.Sum(i))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Key uses the name, type and rdata, which is serialized and then hashed as the key for the lookup.
 | 
			
		||||
func KeyRRset(rrs []dns.RR) string {
 | 
			
		||||
	h := sha1.New()
 | 
			
		||||
	i := []byte(rrs[0].Header().Name)
 | 
			
		||||
	i = append(i, packUint16(rrs[0].Header().Rrtype)...)
 | 
			
		||||
	for _, r := range rrs {
 | 
			
		||||
		switch t := r.(type) { // we only do a few type, serialize these manually
 | 
			
		||||
		case *dns.SOA:
 | 
			
		||||
			// We only fiddle with the serial so store that.
 | 
			
		||||
			i = append(i, packUint32(t.Serial)...)
 | 
			
		||||
		case *dns.SRV:
 | 
			
		||||
			i = append(i, packUint16(t.Priority)...)
 | 
			
		||||
			i = append(i, packUint16(t.Weight)...)
 | 
			
		||||
			i = append(i, packUint16(t.Weight)...)
 | 
			
		||||
			i = append(i, []byte(t.Target)...)
 | 
			
		||||
		case *dns.A:
 | 
			
		||||
			i = append(i, []byte(t.A)...)
 | 
			
		||||
		case *dns.AAAA:
 | 
			
		||||
			i = append(i, []byte(t.AAAA)...)
 | 
			
		||||
		case *dns.NSEC3:
 | 
			
		||||
			i = append(i, []byte(t.NextDomain)...)
 | 
			
		||||
			// Bitmap does not differentiate in SkyDNS.
 | 
			
		||||
		case *dns.DNSKEY:
 | 
			
		||||
		case *dns.NS:
 | 
			
		||||
		case *dns.TXT:
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return string(h.Sum(i))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func packUint16(i uint16) []byte { return []byte{byte(i >> 8), byte(i)} }
 | 
			
		||||
func packUint32(i uint32) []byte { return []byte{byte(i >> 24), byte(i >> 16), byte(i >> 8), byte(i)} }
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/github.com/skynetservices/skydns/cache/hit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/skynetservices/skydns/cache/hit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,31 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Hit returns a dns message from the cache. If the message's TTL is expired nil
 | 
			
		||||
// is returned and the message is removed from the cache.
 | 
			
		||||
func (c *Cache) Hit(question dns.Question, dnssec, tcp bool, msgid uint16) *dns.Msg {
 | 
			
		||||
	key := Key(question, dnssec, tcp)
 | 
			
		||||
	m1, exp, hit := c.Search(key)
 | 
			
		||||
	if hit {
 | 
			
		||||
		// Cache hit! \o/
 | 
			
		||||
		if time.Since(exp) < 0 {
 | 
			
		||||
			m1.Id = msgid
 | 
			
		||||
			m1.Compress = true
 | 
			
		||||
			// Even if something ended up with the TC bit *in* the cache, set it to off
 | 
			
		||||
			m1.Truncated = false
 | 
			
		||||
			return m1
 | 
			
		||||
		}
 | 
			
		||||
		// Expired! /o\
 | 
			
		||||
		c.Remove(key)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										186
									
								
								vendor/github.com/skynetservices/skydns/metrics/metrics.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										186
									
								
								vendor/github.com/skynetservices/skydns/metrics/metrics.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,186 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package metrics
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	Port      = os.Getenv("PROMETHEUS_PORT")
 | 
			
		||||
	Path      = envOrDefault("PROMETHEUS_PATH", "/metrics")
 | 
			
		||||
	Namespace = envOrDefault("PROMETHEUS_NAMESPACE", "skydns")
 | 
			
		||||
	Subsystem = envOrDefault("PROMETHEUS_SUBSYSTEM", "skydns")
 | 
			
		||||
 | 
			
		||||
	requestCount    *prometheus.CounterVec
 | 
			
		||||
	requestDuration *prometheus.HistogramVec
 | 
			
		||||
	responseSize    *prometheus.HistogramVec
 | 
			
		||||
	errorCount      *prometheus.CounterVec
 | 
			
		||||
	cacheMiss       *prometheus.CounterVec
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	System    string
 | 
			
		||||
	Cause     string
 | 
			
		||||
	CacheType string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	Auth    System = "auth"
 | 
			
		||||
	Cache   System = "cache"
 | 
			
		||||
	Rec     System = "recursive"
 | 
			
		||||
	Reverse System = "reverse"
 | 
			
		||||
	Stub    System = "stub"
 | 
			
		||||
 | 
			
		||||
	Nxdomain  Cause = "nxdomain"
 | 
			
		||||
	Nodata    Cause = "nodata"
 | 
			
		||||
	Truncated Cause = "truncated"
 | 
			
		||||
	Refused   Cause = "refused"
 | 
			
		||||
	Overflow  Cause = "overflow"
 | 
			
		||||
	Fail      Cause = "servfail"
 | 
			
		||||
 | 
			
		||||
	Response  CacheType = "response"
 | 
			
		||||
	Signature CacheType = "signature"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func defineMetrics() {
 | 
			
		||||
	requestCount = prometheus.NewCounterVec(prometheus.CounterOpts{
 | 
			
		||||
		Namespace: Namespace,
 | 
			
		||||
		Subsystem: Subsystem,
 | 
			
		||||
		Name:      "dns_request_count_total",
 | 
			
		||||
		Help:      "Counter of DNS requests made.",
 | 
			
		||||
	}, []string{"system"})
 | 
			
		||||
 | 
			
		||||
	requestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
 | 
			
		||||
		Namespace: Namespace,
 | 
			
		||||
		Subsystem: Subsystem,
 | 
			
		||||
		Name:      "dns_request_duration_seconds",
 | 
			
		||||
		Help:      "Histogram of the time (in seconds) each request took to resolve.",
 | 
			
		||||
		Buckets:   append([]float64{0.001, 0.003}, prometheus.DefBuckets...),
 | 
			
		||||
	}, []string{"system"})
 | 
			
		||||
 | 
			
		||||
	responseSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{
 | 
			
		||||
		Namespace: Namespace,
 | 
			
		||||
		Subsystem: Subsystem,
 | 
			
		||||
		Name:      "dns_response_size_bytes",
 | 
			
		||||
		Help:      "Size of the returns response in bytes.",
 | 
			
		||||
		Buckets: []float64{0, 512, 1024, 1500, 2048, 4096,
 | 
			
		||||
			8192, 12288, 16384, 20480, 24576, 28672, 32768, 36864,
 | 
			
		||||
			40960, 45056, 49152, 53248, 57344, 61440, 65536,
 | 
			
		||||
		},
 | 
			
		||||
	}, []string{"system"})
 | 
			
		||||
 | 
			
		||||
	errorCount = prometheus.NewCounterVec(prometheus.CounterOpts{
 | 
			
		||||
		Namespace: Namespace,
 | 
			
		||||
		Subsystem: Subsystem,
 | 
			
		||||
		Name:      "dns_error_count_total",
 | 
			
		||||
		Help:      "Counter of DNS requests resulting in an error.",
 | 
			
		||||
	}, []string{"system", "cause"})
 | 
			
		||||
 | 
			
		||||
	cacheMiss = prometheus.NewCounterVec(prometheus.CounterOpts{
 | 
			
		||||
		Namespace: Namespace,
 | 
			
		||||
		Subsystem: Subsystem,
 | 
			
		||||
		Name:      "dns_cachemiss_count_total",
 | 
			
		||||
		Help:      "Counter of DNS requests that result in a cache miss.",
 | 
			
		||||
	}, []string{"cache"})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Metrics registers the DNS metrics to Prometheus, and starts the internal metrics
 | 
			
		||||
// server if the environment variable PROMETHEUS_PORT is set.
 | 
			
		||||
func Metrics() error {
 | 
			
		||||
	// We do this in a function instead of using var + init(), because we want to
 | 
			
		||||
	// able to set Namespace and/or Subsystem.
 | 
			
		||||
	if Port == "" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := strconv.Atoi(Port)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Errorf("bad port for prometheus: %s", Port)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defineMetrics()
 | 
			
		||||
 | 
			
		||||
	prometheus.MustRegister(requestCount)
 | 
			
		||||
	prometheus.MustRegister(requestDuration)
 | 
			
		||||
	prometheus.MustRegister(responseSize)
 | 
			
		||||
	prometheus.MustRegister(errorCount)
 | 
			
		||||
	prometheus.MustRegister(cacheMiss)
 | 
			
		||||
 | 
			
		||||
	http.Handle(Path, prometheus.Handler())
 | 
			
		||||
	go func() {
 | 
			
		||||
		fmt.Errorf("%s", http.ListenAndServe(":"+Port, nil))
 | 
			
		||||
	}()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReportDuration(resp *dns.Msg, start time.Time, sys System) {
 | 
			
		||||
	if requestDuration == nil || responseSize == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rlen := float64(0)
 | 
			
		||||
	if resp != nil {
 | 
			
		||||
		rlen = float64(resp.Len())
 | 
			
		||||
	}
 | 
			
		||||
	requestDuration.WithLabelValues(string(sys)).Observe(float64(time.Since(start)) / float64(time.Second))
 | 
			
		||||
	responseSize.WithLabelValues(string(sys)).Observe(rlen)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReportRequestCount(req *dns.Msg, sys System) {
 | 
			
		||||
	if requestCount == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	requestCount.WithLabelValues(string(sys)).Inc()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReportErrorCount(resp *dns.Msg, sys System) {
 | 
			
		||||
	if resp == nil || errorCount == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if resp.Truncated {
 | 
			
		||||
		errorCount.WithLabelValues(string(sys), string(Truncated)).Inc()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if resp.Len() > dns.MaxMsgSize {
 | 
			
		||||
		errorCount.WithLabelValues(string(sys), string(Overflow)).Inc()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch resp.Rcode {
 | 
			
		||||
	case dns.RcodeServerFailure:
 | 
			
		||||
		errorCount.WithLabelValues(string(sys), string(Fail)).Inc()
 | 
			
		||||
	case dns.RcodeRefused:
 | 
			
		||||
		errorCount.WithLabelValues(string(sys), string(Refused)).Inc()
 | 
			
		||||
	case dns.RcodeNameError:
 | 
			
		||||
		errorCount.WithLabelValues(string(sys), string(Nxdomain)).Inc()
 | 
			
		||||
		// nodata ??
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReportCacheMiss(ca CacheType) {
 | 
			
		||||
	if cacheMiss == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cacheMiss.WithLabelValues(string(ca)).Inc()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func envOrDefault(env, def string) string {
 | 
			
		||||
	e := os.Getenv(env)
 | 
			
		||||
	if e != "" {
 | 
			
		||||
		return e
 | 
			
		||||
	}
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										221
									
								
								vendor/github.com/skynetservices/skydns/msg/service.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										221
									
								
								vendor/github.com/skynetservices/skydns/msg/service.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,221 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package msg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// PathPrefix is the prefix used to store SkyDNS data in the backend.
 | 
			
		||||
// It defaults to `skydns`.
 | 
			
		||||
// You can change it by set `path-prefix` configuration or SKYDNS_PATH_PREFIX env. variable.
 | 
			
		||||
// Then:
 | 
			
		||||
// 	The SkyDNS's configuration object should be stored under the key "/mydns/config";
 | 
			
		||||
// 	The etcd path of domain `service.staging.skydns.local.` will be "/mydns/local/skydns/staging/service".
 | 
			
		||||
var PathPrefix string = "skydns"
 | 
			
		||||
 | 
			
		||||
// This *is* the rdata from a SRV record, but with a twist.
 | 
			
		||||
// Host (Target in SRV) must be a domain name, but if it looks like an IP
 | 
			
		||||
// address (4/6), we will treat it like an IP address.
 | 
			
		||||
type Service struct {
 | 
			
		||||
	Host     string `json:"host,omitempty"`
 | 
			
		||||
	Port     int    `json:"port,omitempty"`
 | 
			
		||||
	Priority int    `json:"priority,omitempty"`
 | 
			
		||||
	Weight   int    `json:"weight,omitempty"`
 | 
			
		||||
	Text     string `json:"text,omitempty"`
 | 
			
		||||
	Mail     bool   `json:"mail,omitempty"` // Be an MX record. Priority becomes Preference.
 | 
			
		||||
	Ttl      uint32 `json:"ttl,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// When a SRV record with a "Host: IP-address" is added, we synthesize
 | 
			
		||||
	// a srv.Target domain name.  Normally we convert the full Key where
 | 
			
		||||
	// the record lives to a DNS name and use this as the srv.Target.  When
 | 
			
		||||
	// TargetStrip > 0 we strip the left most TargetStrip labels from the
 | 
			
		||||
	// DNS name.
 | 
			
		||||
	TargetStrip int `json:"targetstrip,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Group is used to group (or *not* to group) different services
 | 
			
		||||
	// together. Services with an identical Group are returned in the same
 | 
			
		||||
	// answer.
 | 
			
		||||
	Group string `json:"group,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Etcd key where we found this service and ignored from json un-/marshalling
 | 
			
		||||
	Key string `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSRV returns a new SRV record based on the Service.
 | 
			
		||||
func (s *Service) NewSRV(name string, weight uint16) *dns.SRV {
 | 
			
		||||
	host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip)
 | 
			
		||||
 | 
			
		||||
	return &dns.SRV{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: s.Ttl},
 | 
			
		||||
		Priority: uint16(s.Priority), Weight: weight, Port: uint16(s.Port), Target: host}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMX returns a new MX record based on the Service.
 | 
			
		||||
func (s *Service) NewMX(name string) *dns.MX {
 | 
			
		||||
	host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip)
 | 
			
		||||
 | 
			
		||||
	return &dns.MX{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: s.Ttl},
 | 
			
		||||
		Preference: uint16(s.Priority), Mx: host}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewA returns a new A record based on the Service.
 | 
			
		||||
func (s *Service) NewA(name string, ip net.IP) *dns.A {
 | 
			
		||||
	return &dns.A{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: s.Ttl}, A: ip}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAAAA returns a new AAAA record based on the Service.
 | 
			
		||||
func (s *Service) NewAAAA(name string, ip net.IP) *dns.AAAA {
 | 
			
		||||
	return &dns.AAAA{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: s.Ttl}, AAAA: ip}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCNAME returns a new CNAME record based on the Service.
 | 
			
		||||
func (s *Service) NewCNAME(name string, target string) *dns.CNAME {
 | 
			
		||||
	return &dns.CNAME{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: s.Ttl}, Target: target}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewNS returns a new NS record based on the Service.
 | 
			
		||||
func (s *Service) NewNS(name string, target string) *dns.NS {
 | 
			
		||||
	return &dns.NS{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: s.Ttl}, Ns: target}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTXT returns a new TXT record based on the Service.
 | 
			
		||||
func (s *Service) NewTXT(name string) *dns.TXT {
 | 
			
		||||
	return &dns.TXT{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: s.Ttl}, Txt: split255(s.Text)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewPTR returns a new PTR record based on the Service.
 | 
			
		||||
func (s *Service) NewPTR(name string, ttl uint32) *dns.PTR {
 | 
			
		||||
	return &dns.PTR{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: ttl}, Ptr: dns.Fqdn(s.Host)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// As Path, but if a name contains wildcards (* or any), the name will be
 | 
			
		||||
// chopped of before the (first) wildcard, and we do a highler evel search and
 | 
			
		||||
// later find the matching names.  So service.*.skydns.local, will look for all
 | 
			
		||||
// services under skydns.local and will later check for names that match
 | 
			
		||||
// service.*.skydns.local.  If a wildcard is found the returned bool is true.
 | 
			
		||||
func PathWithWildcard(s string) (string, bool) {
 | 
			
		||||
	l := dns.SplitDomainName(s)
 | 
			
		||||
	for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 {
 | 
			
		||||
		l[i], l[j] = l[j], l[i]
 | 
			
		||||
	}
 | 
			
		||||
	for i, k := range l {
 | 
			
		||||
		if k == "*" || k == "any" {
 | 
			
		||||
			return path.Join(append([]string{"/" + PathPrefix + "/"}, l[:i]...)...), true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return path.Join(append([]string{"/" + PathPrefix + "/"}, l...)...), false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Path converts a domainname to an etcd path. If s looks like service.staging.skydns.local.,
 | 
			
		||||
// the resulting key will be /skydns/local/skydns/staging/service .
 | 
			
		||||
func Path(s string) string {
 | 
			
		||||
	l := dns.SplitDomainName(s)
 | 
			
		||||
	for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 {
 | 
			
		||||
		l[i], l[j] = l[j], l[i]
 | 
			
		||||
	}
 | 
			
		||||
	return path.Join(append([]string{"/" + PathPrefix + "/"}, l...)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Domain is the opposite of Path.
 | 
			
		||||
func Domain(s string) string {
 | 
			
		||||
	l := strings.Split(s, "/")
 | 
			
		||||
	// start with 1, to strip /skydns
 | 
			
		||||
	for i, j := 1, len(l)-1; i < j; i, j = i+1, j-1 {
 | 
			
		||||
		l[i], l[j] = l[j], l[i]
 | 
			
		||||
	}
 | 
			
		||||
	return dns.Fqdn(strings.Join(l[1:len(l)-1], "."))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Group checks the services in sx, it looks for a Group attribute on the shortest
 | 
			
		||||
// keys. If there are multiple shortest keys *and* the group attribute disagrees (and
 | 
			
		||||
// is not empty), we don't consider it a group.
 | 
			
		||||
// If a group is found, only services with *that* group (or no group) will be returned.
 | 
			
		||||
func Group(sx []Service) []Service {
 | 
			
		||||
	if len(sx) == 0 {
 | 
			
		||||
		return sx
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Shortest key with group attribute sets the group for this set.
 | 
			
		||||
	group := sx[0].Group
 | 
			
		||||
	slashes := strings.Count(sx[0].Key, "/")
 | 
			
		||||
	length := make([]int, len(sx))
 | 
			
		||||
	for i, s := range sx {
 | 
			
		||||
		x := strings.Count(s.Key, "/")
 | 
			
		||||
		length[i] = x
 | 
			
		||||
		if x < slashes {
 | 
			
		||||
			if s.Group == "" {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			slashes = x
 | 
			
		||||
			group = s.Group
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if group == "" {
 | 
			
		||||
		return sx
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret := []Service{} // with slice-tricks in sx we can prolly save this allocation (TODO)
 | 
			
		||||
 | 
			
		||||
	for i, s := range sx {
 | 
			
		||||
		if s.Group == "" {
 | 
			
		||||
			ret = append(ret, s)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Disagreement on the same level
 | 
			
		||||
		if length[i] == slashes && s.Group != group {
 | 
			
		||||
			return sx
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if s.Group == group {
 | 
			
		||||
			ret = append(ret, s)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Split255 splits a string into 255 byte chunks.
 | 
			
		||||
func split255(s string) []string {
 | 
			
		||||
	if len(s) < 255 {
 | 
			
		||||
		return []string{s}
 | 
			
		||||
	}
 | 
			
		||||
	sx := []string{}
 | 
			
		||||
	p, i := 0, 255
 | 
			
		||||
	for {
 | 
			
		||||
		if i <= len(s) {
 | 
			
		||||
			sx = append(sx, s[p:i])
 | 
			
		||||
		} else {
 | 
			
		||||
			sx = append(sx, s[p:])
 | 
			
		||||
			break
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		p, i = p+255, i+255
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// targetStrip strips "targetstrip" labels from the left side of the fully qualified name.
 | 
			
		||||
func targetStrip(name string, targetStrip int) string {
 | 
			
		||||
	if targetStrip == 0 {
 | 
			
		||||
		return name
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset, end := 0, false
 | 
			
		||||
	for i := 0; i < targetStrip; i++ {
 | 
			
		||||
		offset, end = dns.NextLabel(name, offset)
 | 
			
		||||
	}
 | 
			
		||||
	if end {
 | 
			
		||||
		// We overshot the name, use the orignal one.
 | 
			
		||||
		offset = 0
 | 
			
		||||
	}
 | 
			
		||||
	name = name[offset:]
 | 
			
		||||
	return name
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								vendor/github.com/skynetservices/skydns/server/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/skynetservices/skydns/server/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,46 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import "github.com/skynetservices/skydns/msg"
 | 
			
		||||
 | 
			
		||||
type Backend interface {
 | 
			
		||||
	Records(name string, exact bool) ([]msg.Service, error)
 | 
			
		||||
	ReverseRecord(name string) (*msg.Service, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FirstBackend exposes the Backend interface over multiple Backends, returning
 | 
			
		||||
// the first Backend that answers the provided record request. If no Backend answers
 | 
			
		||||
// a record request, the last error seen will be returned.
 | 
			
		||||
type FirstBackend []Backend
 | 
			
		||||
 | 
			
		||||
// FirstBackend implements Backend
 | 
			
		||||
var _ Backend = FirstBackend{}
 | 
			
		||||
 | 
			
		||||
func (g FirstBackend) Records(name string, exact bool) (records []msg.Service, err error) {
 | 
			
		||||
	var lastError error
 | 
			
		||||
	for _, backend := range g {
 | 
			
		||||
		if records, err = backend.Records(name, exact); err == nil && len(records) > 0 {
 | 
			
		||||
			return records, nil
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			lastError = err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, lastError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g FirstBackend) ReverseRecord(name string) (record *msg.Service, err error) {
 | 
			
		||||
	var lastError error
 | 
			
		||||
	for _, backend := range g {
 | 
			
		||||
		if record, err = backend.ReverseRecord(name); err == nil && record != nil {
 | 
			
		||||
			return record, nil
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			lastError = err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, lastError
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										157
									
								
								vendor/github.com/skynetservices/skydns/server/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										157
									
								
								vendor/github.com/skynetservices/skydns/server/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,157 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	SCacheCapacity = 10000
 | 
			
		||||
	RCacheCapacity = 100000
 | 
			
		||||
	RCacheTtl      = 60
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Config provides options to the SkyDNS resolver.
 | 
			
		||||
type Config struct {
 | 
			
		||||
	// The ip:port SkyDNS should be listening on for incoming DNS requests.
 | 
			
		||||
	DnsAddr string `json:"dns_addr,omitempty"`
 | 
			
		||||
	// bind to port(s) activated by systemd. If set to true, this overrides DnsAddr.
 | 
			
		||||
	Systemd bool `json:"systemd,omitempty"`
 | 
			
		||||
	// The domain SkyDNS is authoritative for, defaults to skydns.local.
 | 
			
		||||
	Domain string `json:"domain,omitempty"`
 | 
			
		||||
	// Domain pointing to a key where service info is stored when being queried
 | 
			
		||||
	// for local.dns.skydns.local.
 | 
			
		||||
	Local string `json:"local,omitempty"`
 | 
			
		||||
	// The hostmaster responsible for this domain, defaults to hostmaster.<Domain>.
 | 
			
		||||
	Hostmaster string `json:"hostmaster,omitempty"`
 | 
			
		||||
	DNSSEC     string `json:"dnssec,omitempty"`
 | 
			
		||||
	// Round robin A/AAAA replies. Default is true.
 | 
			
		||||
	RoundRobin bool `json:"round_robin,omitempty"`
 | 
			
		||||
	// Round robin selection of nameservers from among those listed, rather than have all forwarded requests try the first listed server first every time.
 | 
			
		||||
	NSRotate bool `json:"ns_rotate,omitempty"`
 | 
			
		||||
	// List of ip:port, separated by commas of recursive nameservers to forward queries to.
 | 
			
		||||
	Nameservers []string `json:"nameservers,omitempty"`
 | 
			
		||||
	// Never provide a recursive service.
 | 
			
		||||
	NoRec       bool          `json:"no_rec,omitempty"`
 | 
			
		||||
	ReadTimeout time.Duration `json:"read_timeout,omitempty"`
 | 
			
		||||
	// Default priority on SRV records when none is given. Defaults to 10.
 | 
			
		||||
	Priority uint16 `json:"priority"`
 | 
			
		||||
	// Default TTL, in seconds, when none is given in etcd. Defaults to 3600.
 | 
			
		||||
	Ttl uint32 `json:"ttl,omitempty"`
 | 
			
		||||
	// Minimum TTL, in seconds, for NXDOMAIN responses. Defaults to 300.
 | 
			
		||||
	MinTtl uint32 `json:"min_ttl,omitempty"`
 | 
			
		||||
	// SCache, capacity of the signature cache in signatures stored.
 | 
			
		||||
	SCache int `json:"scache,omitempty"`
 | 
			
		||||
	// RCache, capacity of response cache in resource records stored.
 | 
			
		||||
	RCache int `json:"rcache,omitempty"`
 | 
			
		||||
	// RCacheTtl, how long to cache in seconds.
 | 
			
		||||
	RCacheTtl int `json:"rcache_ttl,omitempty"`
 | 
			
		||||
	// How many labels a name should have before we allow forwarding. Default to 2.
 | 
			
		||||
	Ndots int `json:"ndot,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// DNSSEC key material
 | 
			
		||||
	PubKey  *dns.DNSKEY   `json:"-"`
 | 
			
		||||
	KeyTag  uint16        `json:"-"`
 | 
			
		||||
	PrivKey crypto.Signer `json:"-"`
 | 
			
		||||
 | 
			
		||||
	Verbose bool `json:"-"`
 | 
			
		||||
 | 
			
		||||
	Version bool
 | 
			
		||||
 | 
			
		||||
	// some predefined string "constants"
 | 
			
		||||
	localDomain string // "local.dns." + config.Domain
 | 
			
		||||
	dnsDomain   string // "ns.dns". + config.Domain
 | 
			
		||||
 | 
			
		||||
	// Stub zones support. Pointer to a map that we refresh when we see
 | 
			
		||||
	// an update. Map contains domainname -> nameserver:port
 | 
			
		||||
	stub *map[string][]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetDefaults(config *Config) error {
 | 
			
		||||
	if config.ReadTimeout == 0 {
 | 
			
		||||
		config.ReadTimeout = 2 * time.Second
 | 
			
		||||
	}
 | 
			
		||||
	if config.DnsAddr == "" {
 | 
			
		||||
		config.DnsAddr = "127.0.0.1:53"
 | 
			
		||||
	}
 | 
			
		||||
	if config.Domain == "" {
 | 
			
		||||
		config.Domain = "skydns.local."
 | 
			
		||||
	}
 | 
			
		||||
	if config.Hostmaster == "" {
 | 
			
		||||
		config.Hostmaster = appendDomain("hostmaster", config.Domain)
 | 
			
		||||
	}
 | 
			
		||||
	// People probably don't know that SOA's email addresses cannot
 | 
			
		||||
	// contain @-signs, replace them with dots
 | 
			
		||||
	config.Hostmaster = dns.Fqdn(strings.Replace(config.Hostmaster, "@", ".", -1))
 | 
			
		||||
	if config.MinTtl == 0 {
 | 
			
		||||
		config.MinTtl = 60
 | 
			
		||||
	}
 | 
			
		||||
	if config.Ttl == 0 {
 | 
			
		||||
		config.Ttl = 3600
 | 
			
		||||
	}
 | 
			
		||||
	if config.Priority == 0 {
 | 
			
		||||
		config.Priority = 10
 | 
			
		||||
	}
 | 
			
		||||
	if config.RCache < 0 {
 | 
			
		||||
		config.RCache = 0
 | 
			
		||||
	}
 | 
			
		||||
	if config.SCache < 0 {
 | 
			
		||||
		config.SCache = 0
 | 
			
		||||
	}
 | 
			
		||||
	if config.RCacheTtl == 0 {
 | 
			
		||||
		config.RCacheTtl = RCacheTtl
 | 
			
		||||
	}
 | 
			
		||||
	if config.Ndots <= 0 {
 | 
			
		||||
		config.Ndots = 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(config.Nameservers) == 0 {
 | 
			
		||||
		c, err := dns.ClientConfigFromFile("/etc/resolv.conf")
 | 
			
		||||
		if !os.IsNotExist(err) {
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			for _, s := range c.Servers {
 | 
			
		||||
				config.Nameservers = append(config.Nameservers, net.JoinHostPort(s, c.Port))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	config.Domain = dns.Fqdn(strings.ToLower(config.Domain))
 | 
			
		||||
	if config.DNSSEC != "" {
 | 
			
		||||
		// For some reason the + are replaces by spaces in etcd. Re-replace them
 | 
			
		||||
		keyfile := strings.Replace(config.DNSSEC, " ", "+", -1)
 | 
			
		||||
		k, p, err := ParseKeyFile(keyfile)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if k.Header().Name != dns.Fqdn(config.Domain) {
 | 
			
		||||
			return fmt.Errorf("ownername of DNSKEY must match SkyDNS domain")
 | 
			
		||||
		}
 | 
			
		||||
		k.Header().Ttl = config.Ttl
 | 
			
		||||
		config.PubKey = k
 | 
			
		||||
		config.KeyTag = k.KeyTag()
 | 
			
		||||
		config.PrivKey = p
 | 
			
		||||
	}
 | 
			
		||||
	config.localDomain = appendDomain("local.dns", config.Domain)
 | 
			
		||||
	config.dnsDomain = appendDomain("ns.dns", config.Domain)
 | 
			
		||||
	stubmap := make(map[string][]string)
 | 
			
		||||
	config.stub = &stubmap
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func appendDomain(s1, s2 string) string {
 | 
			
		||||
	if len(s2) > 0 && s2[0] == '.' {
 | 
			
		||||
		return s1 + s2
 | 
			
		||||
	}
 | 
			
		||||
	return s1 + "." + s2
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										177
									
								
								vendor/github.com/skynetservices/skydns/server/dnssec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										177
									
								
								vendor/github.com/skynetservices/skydns/server/dnssec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,177 +0,0 @@
 | 
			
		||||
// Copyright (c) 2013 Erik St. Martin, Brian Ketelsen. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto"
 | 
			
		||||
	"crypto/ecdsa"
 | 
			
		||||
	"crypto/rsa"
 | 
			
		||||
	"os"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/skynetservices/skydns/cache"
 | 
			
		||||
	"github.com/skynetservices/skydns/metrics"
 | 
			
		||||
	"github.com/skynetservices/skydns/singleflight"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
var (
 | 
			
		||||
	inflight = &singleflight.Group{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ParseKeyFile read a DNSSEC keyfile as generated by dnssec-keygen or other
 | 
			
		||||
// utilities. It add ".key" for the public key and ".private" for the private key.
 | 
			
		||||
func ParseKeyFile(file string) (*dns.DNSKEY, crypto.Signer, error) {
 | 
			
		||||
	f, e := os.Open(file + ".key")
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		return nil, nil, e
 | 
			
		||||
	}
 | 
			
		||||
	k, e := dns.ReadRR(f, file+".key")
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		return nil, nil, e
 | 
			
		||||
	}
 | 
			
		||||
	f, e = os.Open(file + ".private")
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		return nil, nil, e
 | 
			
		||||
	}
 | 
			
		||||
	p, e := k.(*dns.DNSKEY).ReadPrivateKey(f, file+".private")
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		return nil, nil, e
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if v, ok := p.(*rsa.PrivateKey); ok {
 | 
			
		||||
		return k.(*dns.DNSKEY), v, nil
 | 
			
		||||
	}
 | 
			
		||||
	if v, ok := p.(*ecdsa.PrivateKey); ok {
 | 
			
		||||
		return k.(*dns.DNSKEY), v, nil
 | 
			
		||||
	}
 | 
			
		||||
	return k.(*dns.DNSKEY), nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sign signs a message m, it takes care of negative or nodata responses as
 | 
			
		||||
// well by synthesising NSEC3 records. It will also cache the signatures, using
 | 
			
		||||
// a hash of the signed data as a key.
 | 
			
		||||
// We also fake the origin TTL in the signature, because we don't want to
 | 
			
		||||
// throw away signatures when services decide to have longer TTL. So we just
 | 
			
		||||
// set the origTTL to 60.
 | 
			
		||||
// TODO(miek): revisit origTTL
 | 
			
		||||
func (s *server) Sign(m *dns.Msg, bufsize uint16) {
 | 
			
		||||
	now := time.Now().UTC()
 | 
			
		||||
	incep := uint32(now.Add(-3 * time.Hour).Unix())     // 2+1 hours, be sure to catch daylight saving time and such
 | 
			
		||||
	expir := uint32(now.Add(7 * 24 * time.Hour).Unix()) // sign for a week
 | 
			
		||||
 | 
			
		||||
	for _, r := range rrSets(m.Answer) {
 | 
			
		||||
		if r[0].Header().Rrtype == dns.TypeRRSIG {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if !dns.IsSubDomain(s.config.Domain, r[0].Header().Name) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if sig, err := s.signSet(r, now, incep, expir); err == nil {
 | 
			
		||||
			m.Answer = append(m.Answer, sig)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, r := range rrSets(m.Ns) {
 | 
			
		||||
		if r[0].Header().Rrtype == dns.TypeRRSIG {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if !dns.IsSubDomain(s.config.Domain, r[0].Header().Name) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if sig, err := s.signSet(r, now, incep, expir); err == nil {
 | 
			
		||||
			m.Ns = append(m.Ns, sig)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, r := range rrSets(m.Extra) {
 | 
			
		||||
		if r[0].Header().Rrtype == dns.TypeRRSIG || r[0].Header().Rrtype == dns.TypeOPT {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if !dns.IsSubDomain(s.config.Domain, r[0].Header().Name) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if sig, err := s.signSet(r, now, incep, expir); err == nil {
 | 
			
		||||
			m.Extra = append(m.Extra, sig)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	o := new(dns.OPT)
 | 
			
		||||
	o.Hdr.Name = "."
 | 
			
		||||
	o.Hdr.Rrtype = dns.TypeOPT
 | 
			
		||||
	o.SetDo()
 | 
			
		||||
	o.SetUDPSize(4096) // TODO(miek): echo client
 | 
			
		||||
	m.Extra = append(m.Extra, o)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) signSet(r []dns.RR, now time.Time, incep, expir uint32) (*dns.RRSIG, error) {
 | 
			
		||||
	key := cache.KeyRRset(r)
 | 
			
		||||
	if m, exp, hit := s.scache.Search(key); hit { // There can only be one sig in this cache.
 | 
			
		||||
		// Is it still valid 24 hours from now?
 | 
			
		||||
		if now.Add(+24*time.Hour).Sub(exp) < -24*time.Hour {
 | 
			
		||||
			return m.Answer[0].(*dns.RRSIG), nil
 | 
			
		||||
		}
 | 
			
		||||
		s.scache.Remove(key)
 | 
			
		||||
	}
 | 
			
		||||
	if s.config.Verbose {
 | 
			
		||||
		logf("scache miss for %s type %d", r[0].Header().Name, r[0].Header().Rrtype)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	metrics.ReportCacheMiss("signature")
 | 
			
		||||
 | 
			
		||||
	sig, err := inflight.Do(key, func() (interface{}, error) {
 | 
			
		||||
		sig1 := s.NewRRSIG(incep, expir)
 | 
			
		||||
		sig1.Header().Ttl = r[0].Header().Ttl
 | 
			
		||||
		if r[0].Header().Rrtype == dns.TypeTXT {
 | 
			
		||||
			sig1.OrigTtl = 0
 | 
			
		||||
		}
 | 
			
		||||
		e := sig1.Sign(s.config.PrivKey, r)
 | 
			
		||||
		if e != nil {
 | 
			
		||||
			logf("failed to sign: %s", e.Error())
 | 
			
		||||
		}
 | 
			
		||||
		return sig1, e
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	s.scache.InsertSignature(key, sig.(*dns.RRSIG))
 | 
			
		||||
	return dns.Copy(sig.(*dns.RRSIG)).(*dns.RRSIG), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) NewRRSIG(incep, expir uint32) *dns.RRSIG {
 | 
			
		||||
	sig := new(dns.RRSIG)
 | 
			
		||||
	sig.Hdr.Rrtype = dns.TypeRRSIG
 | 
			
		||||
	sig.Hdr.Ttl = s.config.Ttl
 | 
			
		||||
	sig.OrigTtl = s.config.Ttl
 | 
			
		||||
	sig.Algorithm = s.config.PubKey.Algorithm
 | 
			
		||||
	sig.KeyTag = s.config.KeyTag
 | 
			
		||||
	sig.Inception = incep
 | 
			
		||||
	sig.Expiration = expir
 | 
			
		||||
	sig.SignerName = s.config.PubKey.Hdr.Name
 | 
			
		||||
	return sig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type rrset struct {
 | 
			
		||||
	qname string
 | 
			
		||||
	qtype uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rrSets(rrs []dns.RR) map[rrset][]dns.RR {
 | 
			
		||||
	m := make(map[rrset][]dns.RR)
 | 
			
		||||
	for _, r := range rrs {
 | 
			
		||||
		if s, ok := m[rrset{r.Header().Name, r.Header().Rrtype}]; ok {
 | 
			
		||||
			s = append(s, r)
 | 
			
		||||
			m[rrset{r.Header().Name, r.Header().Rrtype}] = s
 | 
			
		||||
		} else {
 | 
			
		||||
			s := make([]dns.RR, 1, 3)
 | 
			
		||||
			s[0] = r
 | 
			
		||||
			m[rrset{r.Header().Name, r.Header().Rrtype}] = s
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(m) > 0 {
 | 
			
		||||
		return m
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/skynetservices/skydns/server/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/skynetservices/skydns/server/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package server provides a DNS server implementation that handles DNS
 | 
			
		||||
// queries. To answer a query, the server asks the provided Backend for
 | 
			
		||||
// DNS records, which are then converted to the proper answers.
 | 
			
		||||
package server
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/github.com/skynetservices/skydns/server/exchange.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/skynetservices/skydns/server/exchange.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,34 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import "github.com/miekg/dns"
 | 
			
		||||
 | 
			
		||||
// exchangeMsg returns a new dns message based on name, type, bufsize and dnssec.
 | 
			
		||||
func newExchangeMsg(name string, typ, bufsize uint16, dnssec bool) *dns.Msg {
 | 
			
		||||
	m := new(dns.Msg)
 | 
			
		||||
	m.SetQuestion(name, typ)
 | 
			
		||||
	m.SetEdns0(bufsize, dnssec)
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// exchangeWithRetry sends message m to server, but retries on ServerFailure.
 | 
			
		||||
func exchangeWithRetry(c *dns.Client, m *dns.Msg, server string) (*dns.Msg, error) {
 | 
			
		||||
	r, _, err := c.Exchange(m, server)
 | 
			
		||||
	if err == nil && r.Rcode == dns.RcodeServerFailure {
 | 
			
		||||
		// redo the query
 | 
			
		||||
		r, _, err = c.Exchange(m, server)
 | 
			
		||||
	}
 | 
			
		||||
	return r, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) randomNameserverID(id uint16) int {
 | 
			
		||||
	nsid := 0
 | 
			
		||||
	if s.config.NSRotate {
 | 
			
		||||
		// Use request Id for "random" nameserver selection.
 | 
			
		||||
		nsid = int(id) % len(s.config.Nameservers)
 | 
			
		||||
	}
 | 
			
		||||
	return nsid
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								vendor/github.com/skynetservices/skydns/server/forwarding.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										125
									
								
								vendor/github.com/skynetservices/skydns/server/forwarding.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,125 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ServeDNSForward forwards a request to a nameservers and returns the response.
 | 
			
		||||
func (s *server) ServeDNSForward(w dns.ResponseWriter, req *dns.Msg) *dns.Msg {
 | 
			
		||||
	if s.config.NoRec {
 | 
			
		||||
		m := s.ServerFailure(req)
 | 
			
		||||
		w.WriteMsg(m)
 | 
			
		||||
		return m
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(s.config.Nameservers) == 0 || dns.CountLabel(req.Question[0].Name) < s.config.Ndots {
 | 
			
		||||
		if s.config.Verbose {
 | 
			
		||||
			if len(s.config.Nameservers) == 0 {
 | 
			
		||||
				logf("can not forward, no nameservers defined")
 | 
			
		||||
			} else {
 | 
			
		||||
				logf("can not forward, name too short (less than %d labels): `%s'", s.config.Ndots, req.Question[0].Name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		m := s.ServerFailure(req)
 | 
			
		||||
		m.RecursionAvailable = true // this is still true
 | 
			
		||||
		w.WriteMsg(m)
 | 
			
		||||
		return m
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		r   *dns.Msg
 | 
			
		||||
		err error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	nsid := s.randomNameserverID(req.Id)
 | 
			
		||||
	try := 0
 | 
			
		||||
Redo:
 | 
			
		||||
	if isTCP(w) {
 | 
			
		||||
		r, err = exchangeWithRetry(s.dnsTCPclient, req, s.config.Nameservers[nsid])
 | 
			
		||||
	} else {
 | 
			
		||||
		r, err = exchangeWithRetry(s.dnsUDPclient, req, s.config.Nameservers[nsid])
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		r.Compress = true
 | 
			
		||||
		r.Id = req.Id
 | 
			
		||||
		w.WriteMsg(r)
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
	// Seen an error, this can only mean, "server not reached", try again
 | 
			
		||||
	// but only if we have not exausted our nameservers.
 | 
			
		||||
	if try < len(s.config.Nameservers) {
 | 
			
		||||
		try++
 | 
			
		||||
		nsid = (nsid + 1) % len(s.config.Nameservers)
 | 
			
		||||
		goto Redo
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logf("failure to forward request %q", err)
 | 
			
		||||
	m := s.ServerFailure(req)
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeDNSReverse is the handler for DNS requests for the reverse zone. If nothing is found
 | 
			
		||||
// locally the request is forwarded to the forwarder for resolution.
 | 
			
		||||
func (s *server) ServeDNSReverse(w dns.ResponseWriter, req *dns.Msg) *dns.Msg {
 | 
			
		||||
	m := new(dns.Msg)
 | 
			
		||||
	m.SetReply(req)
 | 
			
		||||
	m.Compress = true
 | 
			
		||||
	m.Authoritative = false // Set to false, because I don't know what to do wrt DNSSEC.
 | 
			
		||||
	m.RecursionAvailable = true
 | 
			
		||||
	var err error
 | 
			
		||||
	if m.Answer, err = s.PTRRecords(req.Question[0]); err == nil {
 | 
			
		||||
		// TODO(miek): Reverse DNSSEC. We should sign this, but requires a key....and more
 | 
			
		||||
		// Probably not worth the hassle?
 | 
			
		||||
		if err := w.WriteMsg(m); err != nil {
 | 
			
		||||
			logf("failure to return reply %q", err)
 | 
			
		||||
		}
 | 
			
		||||
		return m
 | 
			
		||||
	}
 | 
			
		||||
	// Always forward if not found locally.
 | 
			
		||||
	return s.ServeDNSForward(w, req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Lookup looks up name,type using the recursive nameserver defines
 | 
			
		||||
// in the server's config. If none defined it returns an error.
 | 
			
		||||
func (s *server) Lookup(n string, t, bufsize uint16, dnssec bool) (*dns.Msg, error) {
 | 
			
		||||
	if len(s.config.Nameservers) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("no nameservers configured can not lookup name")
 | 
			
		||||
	}
 | 
			
		||||
	if dns.CountLabel(n) < s.config.Ndots {
 | 
			
		||||
		return nil, fmt.Errorf("name has fewer than %d labels", s.config.Ndots)
 | 
			
		||||
	}
 | 
			
		||||
	m := newExchangeMsg(n, t, bufsize, dnssec)
 | 
			
		||||
 | 
			
		||||
	nsid := s.randomNameserverID(m.Id)
 | 
			
		||||
	try := 0
 | 
			
		||||
Redo:
 | 
			
		||||
	r, err := exchangeWithRetry(s.dnsUDPclient, m, s.config.Nameservers[nsid])
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		if r.Rcode != dns.RcodeSuccess {
 | 
			
		||||
			return nil, fmt.Errorf("rcode %d is not equal to success", r.Rcode)
 | 
			
		||||
		}
 | 
			
		||||
		// Reset TTLs to rcache TTL to make some of the other code
 | 
			
		||||
		// and the tests not care about TTLs
 | 
			
		||||
		for _, rr := range r.Answer {
 | 
			
		||||
			rr.Header().Ttl = uint32(s.config.RCacheTtl)
 | 
			
		||||
		}
 | 
			
		||||
		for _, rr := range r.Extra {
 | 
			
		||||
			rr.Header().Ttl = uint32(s.config.RCacheTtl)
 | 
			
		||||
		}
 | 
			
		||||
		return r, nil
 | 
			
		||||
	}
 | 
			
		||||
	// Seen an error, this can only mean, "server not reached", try again
 | 
			
		||||
	// but only if we have not exausted our nameservers.
 | 
			
		||||
	if try < len(s.config.Nameservers) {
 | 
			
		||||
		try++
 | 
			
		||||
		nsid = (nsid + 1) % len(s.config.Nameservers)
 | 
			
		||||
		goto Redo
 | 
			
		||||
	}
 | 
			
		||||
	return nil, fmt.Errorf("failure to lookup name")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/github.com/skynetservices/skydns/server/log.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/skynetservices/skydns/server/log.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,17 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import "log"
 | 
			
		||||
 | 
			
		||||
// printf calls log.Printf with the parameters given.
 | 
			
		||||
func logf(format string, a ...interface{}) {
 | 
			
		||||
	log.Printf("skydns: "+format, a...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fatalf calls log.Fatalf with the parameters given.
 | 
			
		||||
func fatalf(format string, a ...interface{}) {
 | 
			
		||||
	log.Fatalf("skydns: "+format, a...)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/github.com/skynetservices/skydns/server/msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/skynetservices/skydns/server/msg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,54 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import "github.com/miekg/dns"
 | 
			
		||||
 | 
			
		||||
// Fit will make m fit the size. If a message is larger than size then entire
 | 
			
		||||
// additional section is dropped. If it is still to large and the transport
 | 
			
		||||
// is udp we return a truncated message.
 | 
			
		||||
// If the transport is tcp we are going to drop RR from the answer section
 | 
			
		||||
// until it fits. When this is case the returned bool is true.
 | 
			
		||||
func Fit(m *dns.Msg, size int, tcp bool) (*dns.Msg, bool) {
 | 
			
		||||
	if m.Len() > size {
 | 
			
		||||
		// Check for OPT Records at the end and keep those. TODO(miek)
 | 
			
		||||
		m.Extra = nil
 | 
			
		||||
	}
 | 
			
		||||
	if m.Len() < size {
 | 
			
		||||
		return m, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// With TCP setting TC does not mean anything.
 | 
			
		||||
	if !tcp {
 | 
			
		||||
		m.Truncated = true
 | 
			
		||||
		// fall through here, so we at least return a message that can
 | 
			
		||||
		// fit the udp buffer.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Additional section is gone, binary search until we have length that fits.
 | 
			
		||||
	min, max := 0, len(m.Answer)
 | 
			
		||||
	original := make([]dns.RR, len(m.Answer))
 | 
			
		||||
	copy(original, m.Answer)
 | 
			
		||||
	for {
 | 
			
		||||
		if min == max {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		mid := (min + max) / 2
 | 
			
		||||
		m.Answer = original[:mid]
 | 
			
		||||
 | 
			
		||||
		if m.Len() < size {
 | 
			
		||||
			min++
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		max = mid
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	if max > 1 {
 | 
			
		||||
		max--
 | 
			
		||||
	}
 | 
			
		||||
	m.Answer = m.Answer[:max]
 | 
			
		||||
	return m, true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								vendor/github.com/skynetservices/skydns/server/nsec3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										155
									
								
								vendor/github.com/skynetservices/skydns/server/nsec3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,155 +0,0 @@
 | 
			
		||||
// Copyright (c) 2013 Erik St. Martin, Brian Ketelsen. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base32"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Do DNSSEC NXDOMAIN with NSEC3 whitelies: rfc 7129, appendix B.
 | 
			
		||||
// The closest encloser will be qname - the left most label and the
 | 
			
		||||
// next closer will be the full qname which we then will deny.
 | 
			
		||||
// Idem for source of synthesis.
 | 
			
		||||
 | 
			
		||||
func (s *server) Denial(m *dns.Msg) {
 | 
			
		||||
	if m.Rcode == dns.RcodeNameError {
 | 
			
		||||
		// ce is qname minus the left label
 | 
			
		||||
		idx := dns.Split(m.Question[0].Name)
 | 
			
		||||
		ce := m.Question[0].Name[idx[1]:]
 | 
			
		||||
 | 
			
		||||
		nsec3ce, nsec3wildcard := newNSEC3CEandWildcard(s.config.Domain, ce, s.config.MinTtl)
 | 
			
		||||
		// Add ce and wildcard
 | 
			
		||||
		m.Ns = append(m.Ns, nsec3ce)
 | 
			
		||||
		m.Ns = append(m.Ns, nsec3wildcard)
 | 
			
		||||
		// Deny Qname nsec3
 | 
			
		||||
		m.Ns = append(m.Ns, s.newNSEC3NameError(m.Question[0].Name))
 | 
			
		||||
	}
 | 
			
		||||
	if m.Rcode == dns.RcodeSuccess && len(m.Ns) == 1 {
 | 
			
		||||
		// NODATA
 | 
			
		||||
		if _, ok := m.Ns[0].(*dns.SOA); ok {
 | 
			
		||||
			m.Ns = append(m.Ns, s.newNSEC3NoData(m.Question[0].Name))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func packBase32(s string) []byte {
 | 
			
		||||
	b32len := base32.HexEncoding.DecodedLen(len(s))
 | 
			
		||||
	buf := make([]byte, b32len)
 | 
			
		||||
	n, _ := base32.HexEncoding.Decode(buf, []byte(s))
 | 
			
		||||
	buf = buf[:n]
 | 
			
		||||
	return buf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func unpackBase32(b []byte) string {
 | 
			
		||||
	b32 := make([]byte, base32.HexEncoding.EncodedLen(len(b)))
 | 
			
		||||
	base32.HexEncoding.Encode(b32, b)
 | 
			
		||||
	return string(b32)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newNSEC3NameError returns the NSEC3 record needed to denial qname.
 | 
			
		||||
func (s *server) newNSEC3NameError(qname string) *dns.NSEC3 {
 | 
			
		||||
	n := new(dns.NSEC3)
 | 
			
		||||
	n.Hdr.Class = dns.ClassINET
 | 
			
		||||
	n.Hdr.Rrtype = dns.TypeNSEC3
 | 
			
		||||
	n.Hdr.Ttl = s.config.MinTtl
 | 
			
		||||
	n.Hash = dns.SHA1
 | 
			
		||||
	n.Flags = 0
 | 
			
		||||
	n.Salt = ""
 | 
			
		||||
	n.TypeBitMap = []uint16{}
 | 
			
		||||
 | 
			
		||||
	covername := dns.HashName(qname, dns.SHA1, 0, "")
 | 
			
		||||
 | 
			
		||||
	buf := packBase32(covername)
 | 
			
		||||
	byteArith(buf, false) // one before
 | 
			
		||||
	n.Hdr.Name = appendDomain(strings.ToLower(unpackBase32(buf)), s.config.Domain)
 | 
			
		||||
	byteArith(buf, true) // one next
 | 
			
		||||
	byteArith(buf, true) // and another one
 | 
			
		||||
	n.NextDomain = unpackBase32(buf)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newNSEC3NoData returns the NSEC3 record needed to denial the types
 | 
			
		||||
func (s *server) newNSEC3NoData(qname string) *dns.NSEC3 {
 | 
			
		||||
	n := new(dns.NSEC3)
 | 
			
		||||
	n.Hdr.Class = dns.ClassINET
 | 
			
		||||
	n.Hdr.Rrtype = dns.TypeNSEC3
 | 
			
		||||
	n.Hdr.Ttl = s.config.MinTtl
 | 
			
		||||
	n.Hash = dns.SHA1
 | 
			
		||||
	n.Flags = 0
 | 
			
		||||
	n.Salt = ""
 | 
			
		||||
	n.TypeBitMap = []uint16{dns.TypeA, dns.TypeAAAA, dns.TypeSRV, dns.TypeRRSIG}
 | 
			
		||||
 | 
			
		||||
	n.Hdr.Name = dns.HashName(qname, dns.SHA1, 0, "")
 | 
			
		||||
	buf := packBase32(n.Hdr.Name)
 | 
			
		||||
	byteArith(buf, true) // one next
 | 
			
		||||
	n.NextDomain = unpackBase32(buf)
 | 
			
		||||
 | 
			
		||||
	n.Hdr.Name += appendDomain("", s.config.Domain)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newNSEC3CEandWildcard returns the NSEC3 for the closest encloser
 | 
			
		||||
// and the NSEC3 that denies that wildcard at that level.
 | 
			
		||||
func newNSEC3CEandWildcard(apex, ce string, ttl uint32) (*dns.NSEC3, *dns.NSEC3) {
 | 
			
		||||
	n1 := new(dns.NSEC3)
 | 
			
		||||
	n1.Hdr.Class = dns.ClassINET
 | 
			
		||||
	n1.Hdr.Rrtype = dns.TypeNSEC3
 | 
			
		||||
	n1.Hdr.Ttl = ttl
 | 
			
		||||
	n1.Hash = dns.SHA1
 | 
			
		||||
	n1.Flags = 0
 | 
			
		||||
	n1.Iterations = 0
 | 
			
		||||
	n1.Salt = ""
 | 
			
		||||
	// for the apex we need another bitmap
 | 
			
		||||
	n1.TypeBitMap = []uint16{dns.TypeA, dns.TypeAAAA, dns.TypeSRV, dns.TypeRRSIG}
 | 
			
		||||
	prev := dns.HashName(ce, dns.SHA1, n1.Iterations, n1.Salt)
 | 
			
		||||
	n1.Hdr.Name = strings.ToLower(prev) + "." + apex
 | 
			
		||||
	buf := packBase32(prev)
 | 
			
		||||
	byteArith(buf, true) // one next
 | 
			
		||||
	n1.NextDomain = unpackBase32(buf)
 | 
			
		||||
 | 
			
		||||
	n2 := new(dns.NSEC3)
 | 
			
		||||
	n2.Hdr.Class = dns.ClassINET
 | 
			
		||||
	n2.Hdr.Rrtype = dns.TypeNSEC3
 | 
			
		||||
	n2.Hdr.Ttl = ttl
 | 
			
		||||
	n2.Hash = dns.SHA1
 | 
			
		||||
	n2.Flags = 0
 | 
			
		||||
	n2.Iterations = 0
 | 
			
		||||
	n2.Salt = ""
 | 
			
		||||
 | 
			
		||||
	prev = dns.HashName("*."+ce, dns.SHA1, n2.Iterations, n2.Salt)
 | 
			
		||||
	buf = packBase32(prev)
 | 
			
		||||
	byteArith(buf, false) // one before
 | 
			
		||||
	n2.Hdr.Name = appendDomain(strings.ToLower(unpackBase32(buf)), apex)
 | 
			
		||||
	byteArith(buf, true) // one next
 | 
			
		||||
	byteArith(buf, true) // and another one
 | 
			
		||||
	n2.NextDomain = unpackBase32(buf)
 | 
			
		||||
 | 
			
		||||
	return n1, n2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// byteArith adds either 1 or -1 to b, there is no check for under- or overflow.
 | 
			
		||||
func byteArith(b []byte, x bool) {
 | 
			
		||||
	if x {
 | 
			
		||||
		for i := len(b) - 1; i >= 0; i-- {
 | 
			
		||||
			if b[i] == 255 {
 | 
			
		||||
				b[i] = 0
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			b[i]++
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for i := len(b) - 1; i >= 0; i-- {
 | 
			
		||||
		if b[i] == 0 {
 | 
			
		||||
			b[i] = 255
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		b[i]--
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										889
									
								
								vendor/github.com/skynetservices/skydns/server/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										889
									
								
								vendor/github.com/skynetservices/skydns/server/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,889 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/skynetservices/skydns/cache"
 | 
			
		||||
	"github.com/skynetservices/skydns/metrics"
 | 
			
		||||
	"github.com/skynetservices/skydns/msg"
 | 
			
		||||
 | 
			
		||||
	etcd "github.com/coreos/etcd/client"
 | 
			
		||||
	"github.com/coreos/go-systemd/activation"
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const Version = "2.5.3a"
 | 
			
		||||
 | 
			
		||||
type server struct {
 | 
			
		||||
	backend Backend
 | 
			
		||||
	config  *Config
 | 
			
		||||
 | 
			
		||||
	group        *sync.WaitGroup
 | 
			
		||||
	dnsUDPclient *dns.Client // used for forwarding queries
 | 
			
		||||
	dnsTCPclient *dns.Client // used for forwarding queries
 | 
			
		||||
	scache       *cache.Cache
 | 
			
		||||
	rcache       *cache.Cache
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New returns a new SkyDNS server.
 | 
			
		||||
func New(backend Backend, config *Config) *server {
 | 
			
		||||
	return &server{
 | 
			
		||||
		backend: backend,
 | 
			
		||||
		config:  config,
 | 
			
		||||
 | 
			
		||||
		group:        new(sync.WaitGroup),
 | 
			
		||||
		scache:       cache.New(config.SCache, 0),
 | 
			
		||||
		rcache:       cache.New(config.RCache, config.RCacheTtl),
 | 
			
		||||
		dnsUDPclient: &dns.Client{Net: "udp", ReadTimeout: config.ReadTimeout, WriteTimeout: config.ReadTimeout, SingleInflight: true},
 | 
			
		||||
		dnsTCPclient: &dns.Client{Net: "tcp", ReadTimeout: config.ReadTimeout, WriteTimeout: config.ReadTimeout, SingleInflight: true},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run is a blocking operation that starts the server listening on the DNS ports.
 | 
			
		||||
func (s *server) Run() error {
 | 
			
		||||
	mux := dns.NewServeMux()
 | 
			
		||||
	mux.Handle(".", s)
 | 
			
		||||
 | 
			
		||||
	dnsReadyMsg := func(addr, net string) {
 | 
			
		||||
		if s.config.DNSSEC == "" {
 | 
			
		||||
			logf("ready for queries on %s for %s://%s [rcache %d]", s.config.Domain, net, addr, s.config.RCache)
 | 
			
		||||
		} else {
 | 
			
		||||
			logf("ready for queries on %s for %s://%s [rcache %d], signing with %s [scache %d]", s.config.Domain, net, addr, s.config.RCache, s.config.DNSSEC, s.config.SCache)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.config.Systemd {
 | 
			
		||||
		packetConns, err := activation.PacketConns(false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		listeners, err := activation.Listeners(true)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if len(packetConns) == 0 && len(listeners) == 0 {
 | 
			
		||||
			return fmt.Errorf("no UDP or TCP sockets supplied by systemd")
 | 
			
		||||
		}
 | 
			
		||||
		for _, p := range packetConns {
 | 
			
		||||
			if u, ok := p.(*net.UDPConn); ok {
 | 
			
		||||
				s.group.Add(1)
 | 
			
		||||
				go func() {
 | 
			
		||||
					defer s.group.Done()
 | 
			
		||||
					if err := dns.ActivateAndServe(nil, u, mux); err != nil {
 | 
			
		||||
						fatalf("%s", err)
 | 
			
		||||
					}
 | 
			
		||||
				}()
 | 
			
		||||
				dnsReadyMsg(u.LocalAddr().String(), "udp")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for _, l := range listeners {
 | 
			
		||||
			if t, ok := l.(*net.TCPListener); ok {
 | 
			
		||||
				s.group.Add(1)
 | 
			
		||||
				go func() {
 | 
			
		||||
					defer s.group.Done()
 | 
			
		||||
					if err := dns.ActivateAndServe(t, nil, mux); err != nil {
 | 
			
		||||
						fatalf("%s", err)
 | 
			
		||||
					}
 | 
			
		||||
				}()
 | 
			
		||||
				dnsReadyMsg(t.Addr().String(), "tcp")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		s.group.Add(1)
 | 
			
		||||
		go func() {
 | 
			
		||||
			defer s.group.Done()
 | 
			
		||||
			if err := dns.ListenAndServe(s.config.DnsAddr, "tcp", mux); err != nil {
 | 
			
		||||
				fatalf("%s", err)
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
		dnsReadyMsg(s.config.DnsAddr, "tcp")
 | 
			
		||||
		s.group.Add(1)
 | 
			
		||||
		go func() {
 | 
			
		||||
			defer s.group.Done()
 | 
			
		||||
			if err := dns.ListenAndServe(s.config.DnsAddr, "udp", mux); err != nil {
 | 
			
		||||
				fatalf("%s", err)
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
		dnsReadyMsg(s.config.DnsAddr, "udp")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.group.Wait()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop stops a server.
 | 
			
		||||
func (s *server) Stop() {
 | 
			
		||||
	// TODO(miek)
 | 
			
		||||
	//s.group.Add(-2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeDNS is the handler for DNS requests, responsible for parsing DNS request, possibly forwarding
 | 
			
		||||
// it to a real dns server and returning a response.
 | 
			
		||||
func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
 | 
			
		||||
	m := new(dns.Msg)
 | 
			
		||||
	m.SetReply(req)
 | 
			
		||||
	m.Authoritative = true
 | 
			
		||||
	m.RecursionAvailable = true
 | 
			
		||||
	m.Compress = true
 | 
			
		||||
 | 
			
		||||
	bufsize := uint16(512)
 | 
			
		||||
	dnssec := false
 | 
			
		||||
	tcp := false
 | 
			
		||||
	start := time.Now()
 | 
			
		||||
 | 
			
		||||
	q := req.Question[0]
 | 
			
		||||
	name := strings.ToLower(q.Name)
 | 
			
		||||
 | 
			
		||||
	if q.Qtype == dns.TypeANY {
 | 
			
		||||
		m.Authoritative = false
 | 
			
		||||
		m.Rcode = dns.RcodeRefused
 | 
			
		||||
		m.RecursionAvailable = false
 | 
			
		||||
		m.RecursionDesired = false
 | 
			
		||||
		m.Compress = false
 | 
			
		||||
		w.WriteMsg(m)
 | 
			
		||||
 | 
			
		||||
		metrics.ReportRequestCount(m, metrics.Auth)
 | 
			
		||||
		metrics.ReportDuration(m, start, metrics.Auth)
 | 
			
		||||
		metrics.ReportErrorCount(m, metrics.Auth)
 | 
			
		||||
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if o := req.IsEdns0(); o != nil {
 | 
			
		||||
		bufsize = o.UDPSize()
 | 
			
		||||
		dnssec = o.Do()
 | 
			
		||||
	}
 | 
			
		||||
	if bufsize < 512 {
 | 
			
		||||
		bufsize = 512
 | 
			
		||||
	}
 | 
			
		||||
	// with TCP we can send 64K
 | 
			
		||||
	if tcp = isTCP(w); tcp {
 | 
			
		||||
		bufsize = dns.MaxMsgSize - 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.config.Verbose {
 | 
			
		||||
		logf("received DNS Request for %q from %q with type %d", q.Name, w.RemoteAddr(), q.Qtype)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check cache first.
 | 
			
		||||
	m1 := s.rcache.Hit(q, dnssec, tcp, m.Id)
 | 
			
		||||
	if m1 != nil {
 | 
			
		||||
		metrics.ReportRequestCount(req, metrics.Cache)
 | 
			
		||||
 | 
			
		||||
		if send := s.overflowOrTruncated(w, m1, int(bufsize), metrics.Cache); send {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Still round-robin even with hits from the cache.
 | 
			
		||||
		// Only shuffle A and AAAA records with each other.
 | 
			
		||||
		if q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA {
 | 
			
		||||
			s.RoundRobin(m1.Answer)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := w.WriteMsg(m1); err != nil {
 | 
			
		||||
			logf("failure to return reply %q", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		metrics.ReportDuration(m1, start, metrics.Cache)
 | 
			
		||||
		metrics.ReportErrorCount(m1, metrics.Cache)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for zone, ns := range *s.config.stub {
 | 
			
		||||
		if strings.HasSuffix(name, "." + zone) || name == zone {
 | 
			
		||||
			metrics.ReportRequestCount(req, metrics.Stub)
 | 
			
		||||
 | 
			
		||||
			resp := s.ServeDNSStubForward(w, req, ns)
 | 
			
		||||
			if resp != nil {
 | 
			
		||||
				s.rcache.InsertMessage(cache.Key(q, dnssec, tcp), resp)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			metrics.ReportDuration(resp, start, metrics.Stub)
 | 
			
		||||
			metrics.ReportErrorCount(resp, metrics.Stub)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the qname is local.ds.skydns.local. and s.config.Local != "", substitute that name.
 | 
			
		||||
	if s.config.Local != "" && name == s.config.localDomain {
 | 
			
		||||
		name = s.config.Local
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if q.Qtype == dns.TypePTR && strings.HasSuffix(name, ".in-addr.arpa.") || strings.HasSuffix(name, ".ip6.arpa.") {
 | 
			
		||||
		metrics.ReportRequestCount(req, metrics.Reverse)
 | 
			
		||||
 | 
			
		||||
		resp := s.ServeDNSReverse(w, req)
 | 
			
		||||
		if resp != nil {
 | 
			
		||||
			s.rcache.InsertMessage(cache.Key(q, dnssec, tcp), resp)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		metrics.ReportDuration(resp, start, metrics.Reverse)
 | 
			
		||||
		metrics.ReportErrorCount(resp, metrics.Reverse)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if q.Qclass != dns.ClassCHAOS && !strings.HasSuffix(name, "." +s.config.Domain) && name != s.config.Domain {
 | 
			
		||||
		metrics.ReportRequestCount(req, metrics.Rec)
 | 
			
		||||
 | 
			
		||||
		resp := s.ServeDNSForward(w, req)
 | 
			
		||||
		if resp != nil {
 | 
			
		||||
			s.rcache.InsertMessage(cache.Key(q, dnssec, tcp), resp)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		metrics.ReportDuration(resp, start, metrics.Rec)
 | 
			
		||||
		metrics.ReportErrorCount(resp, metrics.Rec)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	metrics.ReportCacheMiss(metrics.Response)
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		metrics.ReportDuration(m, start, metrics.Auth)
 | 
			
		||||
		metrics.ReportErrorCount(m, metrics.Auth)
 | 
			
		||||
 | 
			
		||||
		if m.Rcode == dns.RcodeServerFailure {
 | 
			
		||||
			if err := w.WriteMsg(m); err != nil {
 | 
			
		||||
				logf("failure to return reply %q", err)
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// Set TTL to the minimum of the RRset and dedup the message, i.e. remove identical RRs.
 | 
			
		||||
		m = s.dedup(m)
 | 
			
		||||
 | 
			
		||||
		minttl := s.config.Ttl
 | 
			
		||||
		if len(m.Answer) > 1 {
 | 
			
		||||
			for _, r := range m.Answer {
 | 
			
		||||
				if r.Header().Ttl < minttl {
 | 
			
		||||
					minttl = r.Header().Ttl
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			for _, r := range m.Answer {
 | 
			
		||||
				r.Header().Ttl = minttl
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if dnssec {
 | 
			
		||||
			if s.config.PubKey != nil {
 | 
			
		||||
				m.AuthenticatedData = true
 | 
			
		||||
				s.Denial(m)
 | 
			
		||||
				s.Sign(m, bufsize)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if send := s.overflowOrTruncated(w, m, int(bufsize), metrics.Auth); send {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.rcache.InsertMessage(cache.Key(q, dnssec, tcp), m)
 | 
			
		||||
 | 
			
		||||
		if err := w.WriteMsg(m); err != nil {
 | 
			
		||||
			logf("failure to return reply %q", err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if name == s.config.Domain {
 | 
			
		||||
		if q.Qtype == dns.TypeSOA {
 | 
			
		||||
			m.Answer = []dns.RR{s.NewSOA()}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if q.Qtype == dns.TypeDNSKEY {
 | 
			
		||||
			if s.config.PubKey != nil {
 | 
			
		||||
				m.Answer = []dns.RR{s.config.PubKey}
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if q.Qclass == dns.ClassCHAOS {
 | 
			
		||||
		if q.Qtype == dns.TypeTXT {
 | 
			
		||||
			switch name {
 | 
			
		||||
			case "authors.bind.":
 | 
			
		||||
				fallthrough
 | 
			
		||||
			case s.config.Domain:
 | 
			
		||||
				hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 | 
			
		||||
				authors := []string{"Erik St. Martin", "Brian Ketelsen", "Miek Gieben", "Michael Crosby"}
 | 
			
		||||
				for _, a := range authors {
 | 
			
		||||
					m.Answer = append(m.Answer, &dns.TXT{Hdr: hdr, Txt: []string{a}})
 | 
			
		||||
				}
 | 
			
		||||
				for j := 0; j < len(authors)*(int(dns.Id())%4+1); j++ {
 | 
			
		||||
					q := int(dns.Id()) % len(authors)
 | 
			
		||||
					p := int(dns.Id()) % len(authors)
 | 
			
		||||
					if q == p {
 | 
			
		||||
						p = (p + 1) % len(authors)
 | 
			
		||||
					}
 | 
			
		||||
					m.Answer[q], m.Answer[p] = m.Answer[p], m.Answer[q]
 | 
			
		||||
				}
 | 
			
		||||
				return
 | 
			
		||||
			case "version.bind.":
 | 
			
		||||
				fallthrough
 | 
			
		||||
			case "version.server.":
 | 
			
		||||
				hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 | 
			
		||||
				m.Answer = []dns.RR{&dns.TXT{Hdr: hdr, Txt: []string{Version}}}
 | 
			
		||||
				return
 | 
			
		||||
			case "hostname.bind.":
 | 
			
		||||
				fallthrough
 | 
			
		||||
			case "id.server.":
 | 
			
		||||
				// TODO(miek): machine name to return
 | 
			
		||||
				hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassCHAOS, Ttl: 0}
 | 
			
		||||
				m.Answer = []dns.RR{&dns.TXT{Hdr: hdr, Txt: []string{"localhost"}}}
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// still here, fail
 | 
			
		||||
		m.SetReply(req)
 | 
			
		||||
		m.SetRcode(req, dns.RcodeServerFailure)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch q.Qtype {
 | 
			
		||||
	case dns.TypeNS:
 | 
			
		||||
		if name != s.config.Domain {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		// Lookup s.config.DnsDomain
 | 
			
		||||
		records, extra, err := s.NSRecords(q, s.config.dnsDomain)
 | 
			
		||||
		if isEtcdNameError(err, s) {
 | 
			
		||||
			m = s.NameError(req)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = append(m.Answer, records...)
 | 
			
		||||
		m.Extra = append(m.Extra, extra...)
 | 
			
		||||
	case dns.TypeA, dns.TypeAAAA:
 | 
			
		||||
		records, err := s.AddressRecords(q, name, nil, bufsize, dnssec, false)
 | 
			
		||||
		if isEtcdNameError(err, s) {
 | 
			
		||||
			m = s.NameError(req)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = append(m.Answer, records...)
 | 
			
		||||
	case dns.TypeTXT:
 | 
			
		||||
		records, err := s.TXTRecords(q, name)
 | 
			
		||||
		if isEtcdNameError(err, s) {
 | 
			
		||||
			m = s.NameError(req)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = append(m.Answer, records...)
 | 
			
		||||
	case dns.TypeCNAME:
 | 
			
		||||
		records, err := s.CNAMERecords(q, name)
 | 
			
		||||
		if isEtcdNameError(err, s) {
 | 
			
		||||
			m = s.NameError(req)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = append(m.Answer, records...)
 | 
			
		||||
	case dns.TypeMX:
 | 
			
		||||
		records, extra, err := s.MXRecords(q, name, bufsize, dnssec)
 | 
			
		||||
		if isEtcdNameError(err, s) {
 | 
			
		||||
			m = s.NameError(req)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = append(m.Answer, records...)
 | 
			
		||||
		m.Extra = append(m.Extra, extra...)
 | 
			
		||||
	default:
 | 
			
		||||
		fallthrough // also catch other types, so that they return NODATA
 | 
			
		||||
	case dns.TypeSRV:
 | 
			
		||||
		records, extra, err := s.SRVRecords(q, name, bufsize, dnssec)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if isEtcdNameError(err, s) {
 | 
			
		||||
				m = s.NameError(req)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			logf("got error from backend: %s", err)
 | 
			
		||||
			if q.Qtype == dns.TypeSRV { // Otherwise NODATA
 | 
			
		||||
				m = s.ServerFailure(req)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// if we are here again, check the types, because an answer may only
 | 
			
		||||
		// be given for SRV. All other types should return NODATA, the
 | 
			
		||||
		// NXDOMAIN part is handled in the above code. TODO(miek): yes this
 | 
			
		||||
		// can be done in a more elegant manor.
 | 
			
		||||
		if q.Qtype == dns.TypeSRV {
 | 
			
		||||
			m.Answer = append(m.Answer, records...)
 | 
			
		||||
			m.Extra = append(m.Extra, extra...)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(m.Answer) == 0 { // NODATA response
 | 
			
		||||
		m.Ns = []dns.RR{s.NewSOA()}
 | 
			
		||||
		m.Ns[0].Header().Ttl = s.config.MinTtl
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) AddressRecords(q dns.Question, name string, previousRecords []dns.RR, bufsize uint16, dnssec, both bool) (records []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services = msg.Group(services)
 | 
			
		||||
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		ip := net.ParseIP(serv.Host)
 | 
			
		||||
		switch {
 | 
			
		||||
		case ip == nil:
 | 
			
		||||
			// Try to resolve as CNAME if it's not an IP, but only if we don't create loops.
 | 
			
		||||
			if q.Name == dns.Fqdn(serv.Host) {
 | 
			
		||||
				logf("CNAME loop detected: %q -> %q", q.Name, q.Name)
 | 
			
		||||
				// x CNAME x is a direct loop, don't add those
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			newRecord := serv.NewCNAME(q.Name, dns.Fqdn(serv.Host))
 | 
			
		||||
			if len(previousRecords) > 7 {
 | 
			
		||||
				logf("CNAME lookup limit of 8 exceeded for %s", newRecord)
 | 
			
		||||
				// don't add it, and just continue
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if s.isDuplicateCNAME(newRecord, previousRecords) {
 | 
			
		||||
				logf("CNAME loop detected for record %s", newRecord)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			nextRecords, err := s.AddressRecords(dns.Question{Name: dns.Fqdn(serv.Host), Qtype: q.Qtype, Qclass: q.Qclass},
 | 
			
		||||
				strings.ToLower(dns.Fqdn(serv.Host)), append(previousRecords, newRecord), bufsize, dnssec, both)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				// Only have we found something we should add the CNAME and the IP addresses.
 | 
			
		||||
				if len(nextRecords) > 0 {
 | 
			
		||||
					records = append(records, newRecord)
 | 
			
		||||
					records = append(records, nextRecords...)
 | 
			
		||||
				}
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			// This means we can not complete the CNAME, try to look else where.
 | 
			
		||||
			target := newRecord.Target
 | 
			
		||||
			if dns.IsSubDomain(s.config.Domain, target) {
 | 
			
		||||
				// We should already have found it
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			m1, e1 := s.Lookup(target, q.Qtype, bufsize, dnssec)
 | 
			
		||||
			if e1 != nil {
 | 
			
		||||
				logf("incomplete CNAME chain from %q: %s", target, e1)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			// Len(m1.Answer) > 0 here is well?
 | 
			
		||||
			records = append(records, newRecord)
 | 
			
		||||
			records = append(records, m1.Answer...)
 | 
			
		||||
			continue
 | 
			
		||||
		case ip.To4() != nil && (q.Qtype == dns.TypeA || both):
 | 
			
		||||
			records = append(records, serv.NewA(q.Name, ip.To4()))
 | 
			
		||||
		case ip.To4() == nil && (q.Qtype == dns.TypeAAAA || both):
 | 
			
		||||
			records = append(records, serv.NewAAAA(q.Name, ip.To16()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s.RoundRobin(records)
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NSRecords returns NS records from etcd.
 | 
			
		||||
func (s *server) NSRecords(q dns.Question, name string) (records []dns.RR, extra []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services = msg.Group(services)
 | 
			
		||||
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		ip := net.ParseIP(serv.Host)
 | 
			
		||||
		switch {
 | 
			
		||||
		case ip == nil:
 | 
			
		||||
			return nil, nil, fmt.Errorf("NS record must be an IP address")
 | 
			
		||||
		case ip.To4() != nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			records = append(records, serv.NewNS(q.Name, serv.Host))
 | 
			
		||||
			extra = append(extra, serv.NewA(serv.Host, ip.To4()))
 | 
			
		||||
		case ip.To4() == nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			records = append(records, serv.NewNS(q.Name, serv.Host))
 | 
			
		||||
			extra = append(extra, serv.NewAAAA(serv.Host, ip.To16()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, extra, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SRVRecords returns SRV records from etcd.
 | 
			
		||||
// If the Target is not a name but an IP address, a name is created.
 | 
			
		||||
func (s *server) SRVRecords(q dns.Question, name string, bufsize uint16, dnssec bool) (records []dns.RR, extra []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services = msg.Group(services)
 | 
			
		||||
 | 
			
		||||
	// Looping twice to get the right weight vs priority
 | 
			
		||||
	w := make(map[int]int)
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		weight := 100
 | 
			
		||||
		if serv.Weight != 0 {
 | 
			
		||||
			weight = serv.Weight
 | 
			
		||||
		}
 | 
			
		||||
		if _, ok := w[serv.Priority]; !ok {
 | 
			
		||||
			w[serv.Priority] = weight
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		w[serv.Priority] += weight
 | 
			
		||||
	}
 | 
			
		||||
	lookup := make(map[string]bool)
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		w1 := 100.0 / float64(w[serv.Priority])
 | 
			
		||||
		if serv.Weight == 0 {
 | 
			
		||||
			w1 *= 100
 | 
			
		||||
		} else {
 | 
			
		||||
			w1 *= float64(serv.Weight)
 | 
			
		||||
		}
 | 
			
		||||
		weight := uint16(math.Floor(w1))
 | 
			
		||||
		ip := net.ParseIP(serv.Host)
 | 
			
		||||
		switch {
 | 
			
		||||
		case ip == nil:
 | 
			
		||||
			srv := serv.NewSRV(q.Name, weight)
 | 
			
		||||
			records = append(records, srv)
 | 
			
		||||
 | 
			
		||||
			if _, ok := lookup[srv.Target]; ok {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			lookup[srv.Target] = true
 | 
			
		||||
 | 
			
		||||
			if !dns.IsSubDomain(s.config.Domain, srv.Target) {
 | 
			
		||||
				m1, e1 := s.Lookup(srv.Target, dns.TypeA, bufsize, dnssec)
 | 
			
		||||
				if e1 == nil {
 | 
			
		||||
					extra = append(extra, m1.Answer...)
 | 
			
		||||
				}
 | 
			
		||||
				m1, e1 = s.Lookup(srv.Target, dns.TypeAAAA, bufsize, dnssec)
 | 
			
		||||
				if e1 == nil {
 | 
			
		||||
					// If we have seen CNAME's we *assume* that they are already added.
 | 
			
		||||
					for _, a := range m1.Answer {
 | 
			
		||||
						if _, ok := a.(*dns.CNAME); !ok {
 | 
			
		||||
							extra = append(extra, a)
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			// Internal name, we should have some info on them, either v4 or v6
 | 
			
		||||
			// Clients expect a complete answer, because we are a recursor in their
 | 
			
		||||
			// view.
 | 
			
		||||
			addr, e1 := s.AddressRecords(dns.Question{srv.Target, dns.ClassINET, dns.TypeA},
 | 
			
		||||
				srv.Target, nil, bufsize, dnssec, true)
 | 
			
		||||
			if e1 == nil {
 | 
			
		||||
				extra = append(extra, addr...)
 | 
			
		||||
			}
 | 
			
		||||
		case ip.To4() != nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			srv := serv.NewSRV(q.Name, weight)
 | 
			
		||||
 | 
			
		||||
			records = append(records, srv)
 | 
			
		||||
			extra = append(extra, serv.NewA(srv.Target, ip.To4()))
 | 
			
		||||
		case ip.To4() == nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			srv := serv.NewSRV(q.Name, weight)
 | 
			
		||||
 | 
			
		||||
			records = append(records, srv)
 | 
			
		||||
			extra = append(extra, serv.NewAAAA(srv.Target, ip.To16()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, extra, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MXRecords returns MX records from etcd.
 | 
			
		||||
// If the Target is not a name but an IP address, a name is created.
 | 
			
		||||
func (s *server) MXRecords(q dns.Question, name string, bufsize uint16, dnssec bool) (records []dns.RR, extra []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lookup := make(map[string]bool)
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		if !serv.Mail {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		ip := net.ParseIP(serv.Host)
 | 
			
		||||
		switch {
 | 
			
		||||
		case ip == nil:
 | 
			
		||||
			mx := serv.NewMX(q.Name)
 | 
			
		||||
			records = append(records, mx)
 | 
			
		||||
			if _, ok := lookup[mx.Mx]; ok {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			lookup[mx.Mx] = true
 | 
			
		||||
 | 
			
		||||
			if !dns.IsSubDomain(s.config.Domain, mx.Mx) {
 | 
			
		||||
				m1, e1 := s.Lookup(mx.Mx, dns.TypeA, bufsize, dnssec)
 | 
			
		||||
				if e1 == nil {
 | 
			
		||||
					extra = append(extra, m1.Answer...)
 | 
			
		||||
				}
 | 
			
		||||
				m1, e1 = s.Lookup(mx.Mx, dns.TypeAAAA, bufsize, dnssec)
 | 
			
		||||
				if e1 == nil {
 | 
			
		||||
					// If we have seen CNAME's we *assume* that they are already added.
 | 
			
		||||
					for _, a := range m1.Answer {
 | 
			
		||||
						if _, ok := a.(*dns.CNAME); !ok {
 | 
			
		||||
							extra = append(extra, a)
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			// Internal name
 | 
			
		||||
			addr, e1 := s.AddressRecords(dns.Question{mx.Mx, dns.ClassINET, dns.TypeA},
 | 
			
		||||
				mx.Mx, nil, bufsize, dnssec, true)
 | 
			
		||||
			if e1 == nil {
 | 
			
		||||
				extra = append(extra, addr...)
 | 
			
		||||
			}
 | 
			
		||||
		case ip.To4() != nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			records = append(records, serv.NewMX(q.Name))
 | 
			
		||||
			extra = append(extra, serv.NewA(serv.Host, ip.To4()))
 | 
			
		||||
		case ip.To4() == nil:
 | 
			
		||||
			serv.Host = msg.Domain(serv.Key)
 | 
			
		||||
			records = append(records, serv.NewMX(q.Name))
 | 
			
		||||
			extra = append(extra, serv.NewAAAA(serv.Host, ip.To16()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, extra, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) CNAMERecords(q dns.Question, name string) (records []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services = msg.Group(services)
 | 
			
		||||
 | 
			
		||||
	if len(services) > 0 {
 | 
			
		||||
		serv := services[0]
 | 
			
		||||
		if ip := net.ParseIP(serv.Host); ip == nil {
 | 
			
		||||
			records = append(records, serv.NewCNAME(q.Name, dns.Fqdn(serv.Host)))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) TXTRecords(q dns.Question, name string) (records []dns.RR, err error) {
 | 
			
		||||
	services, err := s.backend.Records(name, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services = msg.Group(services)
 | 
			
		||||
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		if serv.Text == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		records = append(records, serv.NewTXT(q.Name))
 | 
			
		||||
	}
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) PTRRecords(q dns.Question) (records []dns.RR, err error) {
 | 
			
		||||
	name := strings.ToLower(q.Name)
 | 
			
		||||
	serv, err := s.backend.ReverseRecord(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	records = append(records, serv.NewPTR(q.Name, serv.Ttl))
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SOA returns a SOA record for this SkyDNS instance.
 | 
			
		||||
func (s *server) NewSOA() dns.RR {
 | 
			
		||||
	return &dns.SOA{Hdr: dns.RR_Header{Name: s.config.Domain, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: s.config.Ttl},
 | 
			
		||||
		Ns:      appendDomain("ns.dns", s.config.Domain),
 | 
			
		||||
		Mbox:    s.config.Hostmaster,
 | 
			
		||||
		Serial:  uint32(time.Now().Truncate(time.Hour).Unix()),
 | 
			
		||||
		Refresh: 28800,
 | 
			
		||||
		Retry:   7200,
 | 
			
		||||
		Expire:  604800,
 | 
			
		||||
		Minttl:  s.config.MinTtl,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) isDuplicateCNAME(r *dns.CNAME, records []dns.RR) bool {
 | 
			
		||||
	for _, rec := range records {
 | 
			
		||||
		if v, ok := rec.(*dns.CNAME); ok {
 | 
			
		||||
			if v.Target == r.Target {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) NameError(req *dns.Msg) *dns.Msg {
 | 
			
		||||
	m := new(dns.Msg)
 | 
			
		||||
	m.SetRcode(req, dns.RcodeNameError)
 | 
			
		||||
	m.Ns = []dns.RR{s.NewSOA()}
 | 
			
		||||
	m.Ns[0].Header().Ttl = s.config.MinTtl
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) ServerFailure(req *dns.Msg) *dns.Msg {
 | 
			
		||||
	m := new(dns.Msg)
 | 
			
		||||
	m.SetRcode(req, dns.RcodeServerFailure)
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *server) RoundRobin(rrs []dns.RR) {
 | 
			
		||||
	if !s.config.RoundRobin {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// If we have more than 1 CNAME don't touch the packet, because some stub resolver (=glibc)
 | 
			
		||||
	// can't deal with the returned packet if the CNAMEs need to be accesses in the reverse order.
 | 
			
		||||
	cname := 0
 | 
			
		||||
	for _, r := range rrs {
 | 
			
		||||
		if r.Header().Rrtype == dns.TypeCNAME {
 | 
			
		||||
			cname++
 | 
			
		||||
			if cname > 1 {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch l := len(rrs); l {
 | 
			
		||||
	case 2:
 | 
			
		||||
		if dns.Id()%2 == 0 {
 | 
			
		||||
			rrs[0], rrs[1] = rrs[1], rrs[0]
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		for j := 0; j < l*(int(dns.Id())%4+1); j++ {
 | 
			
		||||
			q := int(dns.Id()) % l
 | 
			
		||||
			p := int(dns.Id()) % l
 | 
			
		||||
			if q == p {
 | 
			
		||||
				p = (p + 1) % l
 | 
			
		||||
			}
 | 
			
		||||
			rrs[q], rrs[p] = rrs[p], rrs[q]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dedup will de-duplicate a message on a per section basis.
 | 
			
		||||
// Multiple identical (same name, class, type and rdata) RRs will be coalesced into one.
 | 
			
		||||
func (s *server) dedup(m *dns.Msg) *dns.Msg {
 | 
			
		||||
	// Answer section
 | 
			
		||||
	ma := make(map[string]dns.RR)
 | 
			
		||||
	for _, a := range m.Answer {
 | 
			
		||||
		// Or use Pack()... Think this function also could be placed in go dns.
 | 
			
		||||
		s1 := a.Header().Name
 | 
			
		||||
		s1 += strconv.Itoa(int(a.Header().Class))
 | 
			
		||||
		s1 += strconv.Itoa(int(a.Header().Rrtype))
 | 
			
		||||
		// there can only be one CNAME for an ownername
 | 
			
		||||
		if a.Header().Rrtype == dns.TypeCNAME {
 | 
			
		||||
			if _, ok := ma[s1]; ok {
 | 
			
		||||
				// already exist, randomly overwrite if roundrobin is true
 | 
			
		||||
				// Note: even with roundrobin *off* this depends on the
 | 
			
		||||
				// order we get the names.
 | 
			
		||||
				if s.config.RoundRobin && dns.Id()%2 == 0 {
 | 
			
		||||
					ma[s1] = a
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ma[s1] = a
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for i := 1; i <= dns.NumField(a); i++ {
 | 
			
		||||
			s1 += dns.Field(a, i)
 | 
			
		||||
		}
 | 
			
		||||
		ma[s1] = a
 | 
			
		||||
	}
 | 
			
		||||
	// Only is our map is smaller than the #RR in the answer section we should reset the RRs
 | 
			
		||||
	// in the section it self
 | 
			
		||||
	if len(ma) < len(m.Answer) {
 | 
			
		||||
		i := 0
 | 
			
		||||
		for _, v := range ma {
 | 
			
		||||
			m.Answer[i] = v
 | 
			
		||||
			i++
 | 
			
		||||
		}
 | 
			
		||||
		m.Answer = m.Answer[:len(ma)]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Additional section
 | 
			
		||||
	me := make(map[string]dns.RR)
 | 
			
		||||
	for _, e := range m.Extra {
 | 
			
		||||
		s1 := e.Header().Name
 | 
			
		||||
		s1 += strconv.Itoa(int(e.Header().Class))
 | 
			
		||||
		s1 += strconv.Itoa(int(e.Header().Rrtype))
 | 
			
		||||
		// there can only be one CNAME for an ownername
 | 
			
		||||
		if e.Header().Rrtype == dns.TypeCNAME {
 | 
			
		||||
			if _, ok := me[s1]; ok {
 | 
			
		||||
				// already exist, randomly overwrite if roundrobin is true
 | 
			
		||||
				if s.config.RoundRobin && dns.Id()%2 == 0 {
 | 
			
		||||
					me[s1] = e
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			me[s1] = e
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for i := 1; i <= dns.NumField(e); i++ {
 | 
			
		||||
			s1 += dns.Field(e, i)
 | 
			
		||||
		}
 | 
			
		||||
		me[s1] = e
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(me) < len(m.Extra) {
 | 
			
		||||
		i := 0
 | 
			
		||||
		for _, v := range me {
 | 
			
		||||
			m.Extra[i] = v
 | 
			
		||||
			i++
 | 
			
		||||
		}
 | 
			
		||||
		m.Extra = m.Extra[:len(me)]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// overflowOrTruncated writes back an error to the client if the message does not fit.
 | 
			
		||||
// It updates prometheus metrics. If something has been written to the client, true
 | 
			
		||||
// will be returned.
 | 
			
		||||
func (s *server) overflowOrTruncated(w dns.ResponseWriter, m *dns.Msg, bufsize int, sy metrics.System) bool {
 | 
			
		||||
	switch isTCP(w) {
 | 
			
		||||
	case true:
 | 
			
		||||
		if _, overflow := Fit(m, dns.MaxMsgSize, true); overflow {
 | 
			
		||||
			metrics.ReportErrorCount(m, sy)
 | 
			
		||||
			msgFail := s.ServerFailure(m)
 | 
			
		||||
			w.WriteMsg(msgFail)
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case false:
 | 
			
		||||
		// Overflow with udp always results in TC.
 | 
			
		||||
		Fit(m, bufsize, false)
 | 
			
		||||
		metrics.ReportErrorCount(m, sy)
 | 
			
		||||
		if m.Truncated {
 | 
			
		||||
			w.WriteMsg(m)
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isTCP returns true if the client is connecting over TCP.
 | 
			
		||||
func isTCP(w dns.ResponseWriter) bool {
 | 
			
		||||
	_, ok := w.RemoteAddr().(*net.TCPAddr)
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// etcNameError return a NameError to the client if the error
 | 
			
		||||
// returned from etcd has ErrorCode == 100.
 | 
			
		||||
func isEtcdNameError(err error, s *server) bool {
 | 
			
		||||
	if e, ok := err.(etcd.Error); ok && e.Code == etcd.ErrorCodeKeyNotFound {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("error from backend: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										124
									
								
								vendor/github.com/skynetservices/skydns/server/stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										124
									
								
								vendor/github.com/skynetservices/skydns/server/stub.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,124 +0,0 @@
 | 
			
		||||
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by The MIT License (MIT) that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
	"github.com/skynetservices/skydns/msg"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const ednsStubCode = dns.EDNS0LOCALSTART + 10
 | 
			
		||||
 | 
			
		||||
// ednsStub is the EDNS0 record we add to stub queries. Queries which have this record are
 | 
			
		||||
// not forwarded again.
 | 
			
		||||
var ednsStub = func() *dns.OPT {
 | 
			
		||||
	o := new(dns.OPT)
 | 
			
		||||
	o.Hdr.Name = "."
 | 
			
		||||
	o.Hdr.Rrtype = dns.TypeOPT
 | 
			
		||||
	e := new(dns.EDNS0_LOCAL)
 | 
			
		||||
	e.Code = ednsStubCode
 | 
			
		||||
	e.Data = []byte{1}
 | 
			
		||||
	o.Option = append(o.Option, e)
 | 
			
		||||
	return o
 | 
			
		||||
}()
 | 
			
		||||
 | 
			
		||||
// Look in .../dns/stub/<domain>/xx for msg.Services. Loop through them
 | 
			
		||||
// extract <domain> and add them as forwarders (ip:port-combos) for
 | 
			
		||||
// the stub zones. Only numeric (i.e. IP address) hosts are used.
 | 
			
		||||
func (s *server) UpdateStubZones() {
 | 
			
		||||
	stubmap := make(map[string][]string)
 | 
			
		||||
 | 
			
		||||
	services, err := s.backend.Records("stub.dns."+s.config.Domain, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("stub zone update failed: %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, serv := range services {
 | 
			
		||||
		if serv.Port == 0 {
 | 
			
		||||
			serv.Port = 53
 | 
			
		||||
		}
 | 
			
		||||
		ip := net.ParseIP(serv.Host)
 | 
			
		||||
		if ip == nil {
 | 
			
		||||
			logf("stub zone non-address %s seen for: %s", serv.Key, serv.Host)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		domain := msg.Domain(serv.Key)
 | 
			
		||||
		// Chop of left most label, because that is used as the nameserver place holder
 | 
			
		||||
		// and drop the right most labels that belong to localDomain.
 | 
			
		||||
		labels := dns.SplitDomainName(domain)
 | 
			
		||||
		domain = dns.Fqdn(strings.Join(labels[1:len(labels)-dns.CountLabel(s.config.localDomain)], "."))
 | 
			
		||||
 | 
			
		||||
		// If the remaining name equals s.config.LocalDomain we ignore it.
 | 
			
		||||
		if domain == s.config.localDomain {
 | 
			
		||||
			logf("not adding stub zone for my own domain")
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		stubmap[domain] = append(stubmap[domain], net.JoinHostPort(serv.Host, strconv.Itoa(serv.Port)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.config.stub = &stubmap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeDNSStubForward forwards a request to a nameservers and returns the response.
 | 
			
		||||
func (s *server) ServeDNSStubForward(w dns.ResponseWriter, req *dns.Msg, ns []string) *dns.Msg {
 | 
			
		||||
	// Check EDNS0 Stub option, if set drop the packet.
 | 
			
		||||
	option := req.IsEdns0()
 | 
			
		||||
	if option != nil {
 | 
			
		||||
		for _, o := range option.Option {
 | 
			
		||||
			if o.Option() == ednsStubCode && len(o.(*dns.EDNS0_LOCAL).Data) == 1 &&
 | 
			
		||||
				o.(*dns.EDNS0_LOCAL).Data[0] == 1 {
 | 
			
		||||
				// Maybe log source IP here?
 | 
			
		||||
				logf("not fowarding stub request to another stub")
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add a custom EDNS0 option to the packet, so we can detect loops
 | 
			
		||||
	// when 2 stubs are forwarding to each other.
 | 
			
		||||
	if option != nil {
 | 
			
		||||
		option.Option = append(option.Option, &dns.EDNS0_LOCAL{ednsStubCode, []byte{1}})
 | 
			
		||||
	} else {
 | 
			
		||||
		req.Extra = append(req.Extra, ednsStub)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		r   *dns.Msg
 | 
			
		||||
		err error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Use request Id for "random" nameserver selection.
 | 
			
		||||
	nsid := int(req.Id) % len(ns)
 | 
			
		||||
	try := 0
 | 
			
		||||
Redo:
 | 
			
		||||
	if isTCP(w) {
 | 
			
		||||
		r, err = exchangeWithRetry(s.dnsTCPclient, req, ns[nsid])
 | 
			
		||||
	} else {
 | 
			
		||||
		r, err = exchangeWithRetry(s.dnsUDPclient, req, ns[nsid])
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		r.Compress = true
 | 
			
		||||
		r.Id = req.Id
 | 
			
		||||
		w.WriteMsg(r)
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
	// Seen an error, this can only mean, "server not reached", try again
 | 
			
		||||
	// but only if we have not exausted our nameservers.
 | 
			
		||||
	if try < len(ns) {
 | 
			
		||||
		try++
 | 
			
		||||
		nsid = (nsid + 1) % len(ns)
 | 
			
		||||
		goto Redo
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logf("failure to forward stub request %q", err)
 | 
			
		||||
	m := s.ServerFailure(req)
 | 
			
		||||
	w.WriteMsg(m)
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/skynetservices/skydns/singleflight/singleflight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/skynetservices/skydns/singleflight/singleflight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,64 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2012 Google Inc.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Package singleflight provides a duplicate function call suppression
 | 
			
		||||
// mechanism.
 | 
			
		||||
package singleflight
 | 
			
		||||
 | 
			
		||||
import "sync"
 | 
			
		||||
 | 
			
		||||
// call is an in-flight or completed Do call
 | 
			
		||||
type call struct {
 | 
			
		||||
	wg  sync.WaitGroup
 | 
			
		||||
	val interface{}
 | 
			
		||||
	err error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Group represents a class of work and forms a namespace in which
 | 
			
		||||
// units of work can be executed with duplicate suppression.
 | 
			
		||||
type Group struct {
 | 
			
		||||
	mu sync.Mutex       // protects m
 | 
			
		||||
	m  map[string]*call // lazily initialized
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Do executes and returns the results of the given function, making
 | 
			
		||||
// sure that only one execution is in-flight for a given key at a
 | 
			
		||||
// time. If a duplicate comes in, the duplicate caller waits for the
 | 
			
		||||
// original to complete and receives the same results.
 | 
			
		||||
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
 | 
			
		||||
	g.mu.Lock()
 | 
			
		||||
	if g.m == nil {
 | 
			
		||||
		g.m = make(map[string]*call)
 | 
			
		||||
	}
 | 
			
		||||
	if c, ok := g.m[key]; ok {
 | 
			
		||||
		g.mu.Unlock()
 | 
			
		||||
		c.wg.Wait()
 | 
			
		||||
		return c.val, c.err
 | 
			
		||||
	}
 | 
			
		||||
	c := new(call)
 | 
			
		||||
	c.wg.Add(1)
 | 
			
		||||
	g.m[key] = c
 | 
			
		||||
	g.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	c.val, c.err = fn()
 | 
			
		||||
	c.wg.Done()
 | 
			
		||||
 | 
			
		||||
	g.mu.Lock()
 | 
			
		||||
	delete(g.m, key)
 | 
			
		||||
	g.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	return c.val, c.err
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user