Merge branch 'v1.5' into master
This commit is contained in:
commit
bf43149d7e
293 changed files with 23915 additions and 1441 deletions
|
@ -54,7 +54,7 @@ deploy:
|
||||||
on:
|
on:
|
||||||
repo: containous/traefik
|
repo: containous/traefik
|
||||||
- provider: pages
|
- provider: pages
|
||||||
edge: true
|
edge: false
|
||||||
github_token: ${GITHUB_TOKEN}
|
github_token: ${GITHUB_TOKEN}
|
||||||
local_dir: site
|
local_dir: site
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
|
|
16
Gopkg.lock
generated
16
Gopkg.lock
generated
|
@ -879,9 +879,10 @@
|
||||||
source = "https://github.com/containous/mesos-dns.git"
|
source = "https://github.com/containous/mesos-dns.git"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
name = "github.com/miekg/dns"
|
name = "github.com/miekg/dns"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "8060d9f51305bbe024b99679454e62f552cd0b0b"
|
revision = "906238edc6eb0ddface4a1923f6d41ef2a5ca59b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -1256,29 +1257,36 @@
|
||||||
packages = [
|
packages = [
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"blowfish",
|
"blowfish",
|
||||||
|
"ed25519",
|
||||||
|
"ed25519/internal/edwards25519",
|
||||||
"ocsp",
|
"ocsp",
|
||||||
"pbkdf2",
|
"pbkdf2",
|
||||||
"scrypt",
|
"scrypt",
|
||||||
"ssh/terminal"
|
"ssh/terminal"
|
||||||
]
|
]
|
||||||
revision = "13931e22f9e72ea58bb73048bc752b48c6d4d4ac"
|
revision = "91a49db82a88618983a78a06c1cbd4e00ab749ab"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/net"
|
name = "golang.org/x/net"
|
||||||
packages = [
|
packages = [
|
||||||
|
"bpf",
|
||||||
"context",
|
"context",
|
||||||
"context/ctxhttp",
|
"context/ctxhttp",
|
||||||
"http2",
|
"http2",
|
||||||
"http2/hpack",
|
"http2/hpack",
|
||||||
"idna",
|
"idna",
|
||||||
|
"internal/iana",
|
||||||
|
"internal/socket",
|
||||||
"internal/timeseries",
|
"internal/timeseries",
|
||||||
|
"ipv4",
|
||||||
|
"ipv6",
|
||||||
"lex/httplex",
|
"lex/httplex",
|
||||||
"proxy",
|
"proxy",
|
||||||
"trace",
|
"trace",
|
||||||
"websocket"
|
"websocket"
|
||||||
]
|
]
|
||||||
revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
|
revision = "22ae77b79946ea320088417e4d50825671d82d57"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "golang.org/x/oauth2"
|
name = "golang.org/x/oauth2"
|
||||||
|
@ -1565,6 +1573,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "b748d60cfaddd7ff38c63bdf1004ae7dc2dcd084b220076f8eed2a8971c8e234"
|
inputs-digest = "bca5f65f32c7bfc2696eccbebe4145ce6dae7745894d111d3fa32c4d25008049"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
12
Gopkg.toml
12
Gopkg.toml
|
@ -254,6 +254,18 @@
|
||||||
name = "github.com/mailgun/timetools"
|
name = "github.com/mailgun/timetools"
|
||||||
revision = "7e6055773c5137efbeb3bd2410d705fe10ab6bfd"
|
revision = "7e6055773c5137efbeb3bd2410d705fe10ab6bfd"
|
||||||
|
|
||||||
|
[[override]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/miekg/dns"
|
||||||
|
#
|
||||||
|
#[[override]]
|
||||||
|
# name = "golang.org/x/crypto"
|
||||||
|
# revision = "13931e22f9e72ea58bb73048bc752b48c6d4d4ac"
|
||||||
|
#
|
||||||
|
#[[override]]
|
||||||
|
# name = "golang.org/x/net"
|
||||||
|
# revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
|
||||||
|
|
||||||
[prune]
|
[prune]
|
||||||
non-go = true
|
non-go = true
|
||||||
go-tests = true
|
go-tests = true
|
||||||
|
|
|
@ -243,7 +243,7 @@ entryPoint = "https"
|
||||||
Specify the entryPoint to use during the challenges.
|
Specify the entryPoint to use during the challenges.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
defaultEntryPoints = ["http", "http"]
|
defaultEntryPoints = ["http", "https"]
|
||||||
|
|
||||||
[entryPoints]
|
[entryPoints]
|
||||||
[entryPoints.http]
|
[entryPoints.http]
|
||||||
|
@ -399,11 +399,9 @@ Each domain & SANs will lead to a certificate request.
|
||||||
### `dnsProvider` (Deprecated)
|
### `dnsProvider` (Deprecated)
|
||||||
|
|
||||||
!!! danger "DEPRECATED"
|
!!! danger "DEPRECATED"
|
||||||
This option is deprecated.
|
This option is deprecated, use [dnsChallenge.provider](/configuration/acme/#acmednschallenge) instead.
|
||||||
Please refer to [DNS challenge provider section](/configuration/acme/#provider)
|
|
||||||
|
|
||||||
### `delayDontCheckDNS` (Deprecated)
|
### `delayDontCheckDNS` (Deprecated)
|
||||||
|
|
||||||
!!! danger "DEPRECATED"
|
!!! danger "DEPRECATED"
|
||||||
This option is deprecated.
|
This option is deprecated, use [dnsChallenge.delayBeforeCheck](/configuration/acme/#acmednschallenge) instead.
|
||||||
Please refer to [DNS challenge delayBeforeCheck section](/configuration/acme/#delaybeforecheck)
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ For more customization, see [entry points](/configuration/entrypoints/) document
|
||||||
| Path | Method | Description |
|
| Path | Method | Description |
|
||||||
|-----------------------------------------------------------------|------------------|-------------------------------------------|
|
|-----------------------------------------------------------------|------------------|-------------------------------------------|
|
||||||
| `/` | `GET` | Provides a simple HTML frontend of Træfik |
|
| `/` | `GET` | Provides a simple HTML frontend of Træfik |
|
||||||
| `/health` | `GET` | json health metrics |
|
| `/health` | `GET` | JSON health metrics |
|
||||||
| `/api` | `GET` | Configuration for all providers |
|
| `/api` | `GET` | Configuration for all providers |
|
||||||
| `/api/providers` | `GET` | Providers |
|
| `/api/providers` | `GET` | Providers |
|
||||||
| `/api/providers/{provider}` | `GET`, `PUT` | Get or update provider (1) |
|
| `/api/providers/{provider}` | `GET`, `PUT` | Get or update provider (1) |
|
||||||
|
@ -62,7 +62,102 @@ For more customization, see [entry points](/configuration/entrypoints/) document
|
||||||
For compatibility reason, when you activate the rest provider, you can use `web` or `rest` as `provider` value.
|
For compatibility reason, when you activate the rest provider, you can use `web` or `rest` as `provider` value.
|
||||||
But be careful, in the configuration for all providers the key is still `web`.
|
But be careful, in the configuration for all providers the key is still `web`.
|
||||||
|
|
||||||
### Provider configurations
|
### Address / Port
|
||||||
|
|
||||||
|
You can define a custom address/port like this:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.foo]
|
||||||
|
address = ":8082"
|
||||||
|
|
||||||
|
[entryPoints.bar]
|
||||||
|
address = ":8083"
|
||||||
|
|
||||||
|
[ping]
|
||||||
|
entryPoint = "foo"
|
||||||
|
|
||||||
|
[api]
|
||||||
|
entryPoint = "bar"
|
||||||
|
```
|
||||||
|
|
||||||
|
In the above example, you would access a regular path, administration panel, and health-check as follows:
|
||||||
|
|
||||||
|
* Regular path: `http://hostname:80/path`
|
||||||
|
* Admin Panel: `http://hostname:8083/`
|
||||||
|
* Ping URL: `http://hostname:8082/ping`
|
||||||
|
|
||||||
|
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
||||||
|
Otherwise, you are likely to expose _all_ services via that entry point.
|
||||||
|
|
||||||
|
### Custom Path
|
||||||
|
|
||||||
|
You can define a custom path like this:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.foo]
|
||||||
|
address = ":8080"
|
||||||
|
|
||||||
|
[entryPoints.bar]
|
||||||
|
address = ":8081"
|
||||||
|
|
||||||
|
# Activate API and Dashboard
|
||||||
|
[api]
|
||||||
|
entryPoint = "bar"
|
||||||
|
dashboard = true
|
||||||
|
|
||||||
|
[file]
|
||||||
|
[backends]
|
||||||
|
[backends.backend1]
|
||||||
|
[backends.backend1.servers.server1]
|
||||||
|
url = "http://127.0.0.1:8081"
|
||||||
|
|
||||||
|
[frontends]
|
||||||
|
[frontends.frontend1]
|
||||||
|
entryPoints = ["foo"]
|
||||||
|
backend = "backend1"
|
||||||
|
[frontends.frontend1.routes.test_1]
|
||||||
|
rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
You can define the authentication like this:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.foo]
|
||||||
|
address=":8080"
|
||||||
|
[entryPoints.foo.auth]
|
||||||
|
[entryPoints.foo.auth.basic]
|
||||||
|
users = [
|
||||||
|
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||||
|
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[api]
|
||||||
|
entrypoint="foo"
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information, see [entry points](/configuration/entrypoints/) .
|
||||||
|
|
||||||
|
### Provider call example
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -s "http://localhost:8080/api" | jq .
|
curl -s "http://localhost:8080/api" | jq .
|
||||||
|
|
|
@ -29,9 +29,10 @@ Træfik can be configured:
|
||||||
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -XPUT @file "http://localhost:8080/api"
|
curl -XPUT @file "http://localhost:8080/api/providers/rest"
|
||||||
```
|
```
|
||||||
with `@file`
|
|
||||||
|
with `@file`:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"frontends": {
|
"frontends": {
|
||||||
|
|
|
@ -386,41 +386,6 @@ curl -s "http://localhost:8080/api" | jq .
|
||||||
|
|
||||||
### Deprecation compatibility
|
### Deprecation compatibility
|
||||||
|
|
||||||
#### Path
|
|
||||||
|
|
||||||
As the web provider is deprecated, you can handle the `Path` option like this:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
defaultEntryPoints = ["http"]
|
|
||||||
|
|
||||||
[entryPoints]
|
|
||||||
[entryPoints.http]
|
|
||||||
address = ":80"
|
|
||||||
|
|
||||||
[entryPoints.dashboard]
|
|
||||||
address = ":8080"
|
|
||||||
|
|
||||||
[entryPoints.api]
|
|
||||||
address = ":8081"
|
|
||||||
|
|
||||||
# Activate API and Dashboard
|
|
||||||
[api]
|
|
||||||
entryPoint = "api"
|
|
||||||
|
|
||||||
[file]
|
|
||||||
[backends]
|
|
||||||
[backends.backend1]
|
|
||||||
[backends.backend1.servers.server1]
|
|
||||||
url = "http://127.0.0.1:8081"
|
|
||||||
|
|
||||||
[frontends]
|
|
||||||
[frontends.frontend1]
|
|
||||||
entryPoints = ["dashboard"]
|
|
||||||
backend = "backend1"
|
|
||||||
[frontends.frontend1.routes.test_1]
|
|
||||||
rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
|
|
||||||
As the web provider is deprecated, you can handle the `Address` option like this:
|
As the web provider is deprecated, you can handle the `Address` option like this:
|
||||||
|
@ -432,28 +397,64 @@ defaultEntryPoints = ["http"]
|
||||||
[entryPoints.http]
|
[entryPoints.http]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
|
|
||||||
[entryPoints.ping]
|
[entryPoints.foo]
|
||||||
address = ":8082"
|
address = ":8082"
|
||||||
|
|
||||||
[entryPoints.api]
|
[entryPoints.bar]
|
||||||
address = ":8083"
|
address = ":8083"
|
||||||
|
|
||||||
[ping]
|
[ping]
|
||||||
entryPoint = "ping"
|
entryPoint = "foo"
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
entryPoint = "api"
|
entryPoint = "bar"
|
||||||
```
|
```
|
||||||
|
|
||||||
In the above example, you would access a regular path, administration panel, and health-check as follows:
|
In the above example, you would access a regular path, administration panel, and health-check as follows:
|
||||||
|
|
||||||
* Regular path: `http://hostname:80/foo`
|
* Regular path: `http://hostname:80/path`
|
||||||
* Admin Panel: `http://hostname:8083/`
|
* Admin Panel: `http://hostname:8083/`
|
||||||
* Ping URL: `http://hostname:8082/ping`
|
* Ping URL: `http://hostname:8082/ping`
|
||||||
|
|
||||||
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
||||||
Otherwise, you are likely to expose _all_ services via that entry point.
|
Otherwise, you are likely to expose _all_ services via that entry point.
|
||||||
|
|
||||||
|
#### Path
|
||||||
|
|
||||||
|
As the web provider is deprecated, you can handle the `Path` option like this:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.foo]
|
||||||
|
address = ":8080"
|
||||||
|
|
||||||
|
[entryPoints.bar]
|
||||||
|
address = ":8081"
|
||||||
|
|
||||||
|
# Activate API and Dashboard
|
||||||
|
[api]
|
||||||
|
entryPoint = "bar"
|
||||||
|
dashboard = true
|
||||||
|
|
||||||
|
[file]
|
||||||
|
[backends]
|
||||||
|
[backends.backend1]
|
||||||
|
[backends.backend1.servers.server1]
|
||||||
|
url = "http://127.0.0.1:8081"
|
||||||
|
|
||||||
|
[frontends]
|
||||||
|
[frontends.frontend1]
|
||||||
|
entryPoints = ["foo"]
|
||||||
|
backend = "backend1"
|
||||||
|
[frontends.frontend1.routes.test_1]
|
||||||
|
rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix"
|
||||||
|
```
|
||||||
|
|
||||||
#### Authentication
|
#### Authentication
|
||||||
|
|
||||||
As the web provider is deprecated, you can handle the `auth` option like this:
|
As the web provider is deprecated, you can handle the `auth` option like this:
|
||||||
|
@ -465,17 +466,17 @@ defaultEntryPoints = ["http"]
|
||||||
[entryPoints.http]
|
[entryPoints.http]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
|
|
||||||
[entryPoints.api]
|
[entryPoints.foo]
|
||||||
address=":8080"
|
address=":8080"
|
||||||
[entryPoints.api.auth]
|
[entryPoints.foo.auth]
|
||||||
[entryPoints.api.auth.basic]
|
[entryPoints.foo.auth.basic]
|
||||||
users = [
|
users = [
|
||||||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
entrypoint="api"
|
entrypoint="foo"
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information, see [entry points](/configuration/entrypoints/) .
|
For more information, see [entry points](/configuration/entrypoints/) .
|
||||||
|
|
|
@ -21,24 +21,67 @@
|
||||||
!!! warning
|
!!! warning
|
||||||
Even if you have authentication configured on entry point, the `/ping` path of the api is excluded from authentication.
|
Even if you have authentication configured on entry point, the `/ping` path of the api is excluded from authentication.
|
||||||
|
|
||||||
## Example
|
## Examples
|
||||||
|
|
||||||
|
The `/ping` health-check URL is enabled with the command-line `--ping` or config file option `[ping]`.
|
||||||
|
Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you would access them as follows:
|
||||||
|
|
||||||
|
* Regular path: `http://hostname:80/foo`
|
||||||
|
* Admin panel: `http://hostname:8080/`
|
||||||
|
* Ping URL: `http://hostname:8080/ping`
|
||||||
|
|
||||||
|
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your administration panel's port.
|
||||||
|
In many environments, the security staff may not _allow_ you to expose it.
|
||||||
|
|
||||||
|
You have two options:
|
||||||
|
|
||||||
|
* Enable `/ping` on a regular entry point
|
||||||
|
* Enable `/ping` on a dedicated port
|
||||||
|
|
||||||
|
### Ping health check on a regular entry point
|
||||||
|
|
||||||
|
To proxy `/ping` from a regular entry point to the administration one without exposing the panel, do the following:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[ping]
|
||||||
|
entryPoint = "http"
|
||||||
|
|
||||||
```shell
|
|
||||||
curl -sv "http://localhost:8080/ping"
|
|
||||||
```
|
```
|
||||||
```shell
|
|
||||||
* Trying ::1...
|
The above link `ping` on the `http` entry point and then expose it on port `80`
|
||||||
* Connected to localhost (::1) port 8080 (#0)
|
|
||||||
> GET /ping HTTP/1.1
|
### Enable ping health check on dedicated port
|
||||||
> Host: localhost:8080
|
|
||||||
> User-Agent: curl/7.43.0
|
If you do not want to or cannot expose the health-check on a regular entry point - e.g. your security rules do not allow it, or you have a conflicting path - then you can enable health-check on its own entry point.
|
||||||
> Accept: */*
|
Use the following configuration:
|
||||||
>
|
|
||||||
< HTTP/1.1 200 OK
|
```toml
|
||||||
< Date: Thu, 25 Aug 2016 01:35:36 GMT
|
defaultEntryPoints = ["http"]
|
||||||
< Content-Length: 2
|
|
||||||
< Content-Type: text/plain; charset=utf-8
|
[entryPoints]
|
||||||
<
|
[entryPoints.http]
|
||||||
* Connection #0 to host localhost left intact
|
address = ":80"
|
||||||
OK
|
[entryPoints.ping]
|
||||||
|
address = ":8082"
|
||||||
|
|
||||||
|
[ping]
|
||||||
|
entryPoint = "ping"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The above is similar to the previous example, but instead of enabling `/ping` on the _default_ entry point, we enable it on a _dedicated_ entry point.
|
||||||
|
|
||||||
|
In the above example, you would access a regular path and health-check as follows:
|
||||||
|
|
||||||
|
* Regular path: `http://hostname:80/foo`
|
||||||
|
* Ping URL: `http://hostname:8082/ping`
|
||||||
|
|
||||||
|
Note the dedicated port `:8082` for `/ping`.
|
||||||
|
|
||||||
|
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
||||||
|
Otherwise, you are likely to expose _all_ services via this entry point.
|
||||||
|
|
|
@ -335,68 +335,3 @@ providersThrottleDuration = "5s"
|
||||||
[respondingTimeouts]
|
[respondingTimeouts]
|
||||||
idleTimeout = "360s"
|
idleTimeout = "360s"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ping Health Check
|
|
||||||
|
|
||||||
The `/ping` health-check URL is enabled with the command-line `--ping` or config file option `[ping]`.
|
|
||||||
Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you would access them as follows:
|
|
||||||
|
|
||||||
* Regular path: `http://hostname:80/foo`
|
|
||||||
* Admin panel: `http://hostname:8080/`
|
|
||||||
* Ping URL: `http://hostname:8080/ping`
|
|
||||||
|
|
||||||
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your administration panel's port.
|
|
||||||
In many environments, the security staff may not _allow_ you to expose it.
|
|
||||||
|
|
||||||
You have two options:
|
|
||||||
|
|
||||||
* Enable `/ping` on a regular entry point
|
|
||||||
* Enable `/ping` on a dedicated port
|
|
||||||
|
|
||||||
### Enable ping health check on a regular entry point
|
|
||||||
|
|
||||||
To proxy `/ping` from a regular entry point to the administration one without exposing the panel, do the following:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
defaultEntryPoints = ["http"]
|
|
||||||
|
|
||||||
[entryPoints]
|
|
||||||
[entryPoints.http]
|
|
||||||
address = ":80"
|
|
||||||
|
|
||||||
[ping]
|
|
||||||
entryPoint = "http"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
The above link `ping` on the `http` entry point and then expose it on port `80`
|
|
||||||
|
|
||||||
### Enable ping health check on dedicated port
|
|
||||||
|
|
||||||
If you do not want to or cannot expose the health-check on a regular entry point - e.g. your security rules do not allow it, or you have a conflicting path - then you can enable health-check on its own entry point.
|
|
||||||
Use the following configuration:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
defaultEntryPoints = ["http"]
|
|
||||||
|
|
||||||
[entryPoints]
|
|
||||||
[entryPoints.http]
|
|
||||||
address = ":80"
|
|
||||||
[entryPoints.ping]
|
|
||||||
address = ":8082"
|
|
||||||
|
|
||||||
[ping]
|
|
||||||
entryPoint = "ping"
|
|
||||||
```
|
|
||||||
|
|
||||||
The above is similar to the previous example, but instead of enabling `/ping` on the _default_ entry point, we enable it on a _dedicated_ entry point.
|
|
||||||
|
|
||||||
In the above example, you would access a regular path and health-check as follows:
|
|
||||||
|
|
||||||
* Regular path: `http://hostname:80/foo`
|
|
||||||
* Ping URL: `http://hostname:8082/ping`
|
|
||||||
|
|
||||||
Note the dedicated port `:8082` for `/ping`.
|
|
||||||
|
|
||||||
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
|
||||||
Otherwise, you are likely to expose _all_ services via this entry point.
|
|
||||||
|
|
299
vendor/github.com/miekg/dns/client.go
generated
vendored
299
vendor/github.com/miekg/dns/client.go
generated
vendored
|
@ -4,10 +4,12 @@ package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@ const tcpIdleTimeout time.Duration = 8 * time.Second
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
net.Conn // a net.Conn holding the connection
|
net.Conn // a net.Conn holding the connection
|
||||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
|
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||||
rtt time.Duration
|
rtt time.Duration
|
||||||
t time.Time
|
t time.Time
|
||||||
tsigRequestMAC string
|
tsigRequestMAC string
|
||||||
|
@ -29,11 +31,15 @@ type Client struct {
|
||||||
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
||||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||||
TLSConfig *tls.Config // TLS connection configuration
|
TLSConfig *tls.Config // TLS connection configuration
|
||||||
Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero
|
Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more
|
||||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
|
||||||
|
// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
|
||||||
|
// Client.Dialer) or context.Context.Deadline (see the deprecated ExchangeContext)
|
||||||
|
Timeout time.Duration
|
||||||
|
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
|
||||||
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||||
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
|
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||||
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
|
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
|
||||||
group singleflight
|
group singleflight
|
||||||
}
|
}
|
||||||
|
@ -43,93 +49,11 @@ type Client struct {
|
||||||
// will it fall back to TCP in case of truncation.
|
// will it fall back to TCP in case of truncation.
|
||||||
// See client.Exchange for more information on setting larger buffer sizes.
|
// See client.Exchange for more information on setting larger buffer sizes.
|
||||||
func Exchange(m *Msg, a string) (r *Msg, err error) {
|
func Exchange(m *Msg, a string) (r *Msg, err error) {
|
||||||
var co *Conn
|
client := Client{Net: "udp"}
|
||||||
co, err = DialTimeout("udp", a, dnsTimeout)
|
r, _, err = client.Exchange(m, a)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer co.Close()
|
|
||||||
|
|
||||||
opt := m.IsEdns0()
|
|
||||||
// If EDNS0 is used use that for size.
|
|
||||||
if opt != nil && opt.UDPSize() >= MinMsgSize {
|
|
||||||
co.UDPSize = opt.UDPSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
co.SetWriteDeadline(time.Now().Add(dnsTimeout))
|
|
||||||
if err = co.WriteMsg(m); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
co.SetReadDeadline(time.Now().Add(dnsTimeout))
|
|
||||||
r, err = co.ReadMsg()
|
|
||||||
if err == nil && r.Id != m.Id {
|
|
||||||
err = ErrId
|
|
||||||
}
|
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
|
||||||
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
|
||||||
// This function is going away, but can easily be mimicked:
|
|
||||||
//
|
|
||||||
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
|
||||||
// co.WriteMsg(m)
|
|
||||||
// in, _ := co.ReadMsg()
|
|
||||||
// co.Close()
|
|
||||||
//
|
|
||||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
|
||||||
println("dns: this function is deprecated")
|
|
||||||
co := new(Conn)
|
|
||||||
co.Conn = c
|
|
||||||
if err = co.WriteMsg(m); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
r, err = co.ReadMsg()
|
|
||||||
if err == nil && r.Id != m.Id {
|
|
||||||
err = ErrId
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exchange performs a synchronous query. It sends the message m to the address
|
|
||||||
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
|
||||||
//
|
|
||||||
// c := new(dns.Client)
|
|
||||||
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
|
||||||
//
|
|
||||||
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
|
||||||
// case of truncation.
|
|
||||||
// It is up to the caller to create a message that allows for larger responses to be
|
|
||||||
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
|
||||||
// buffer, see SetEdns0. Messsages without an OPT RR will fallback to the historic limit
|
|
||||||
// of 512 bytes.
|
|
||||||
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
|
||||||
if !c.SingleInflight {
|
|
||||||
return c.exchange(m, a)
|
|
||||||
}
|
|
||||||
// This adds a bunch of garbage, TODO(miek).
|
|
||||||
t := "nop"
|
|
||||||
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
|
||||||
t = t1
|
|
||||||
}
|
|
||||||
cl := "nop"
|
|
||||||
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
|
||||||
cl = cl1
|
|
||||||
}
|
|
||||||
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
|
||||||
return c.exchange(m, a)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return r, rtt, err
|
|
||||||
}
|
|
||||||
if shared {
|
|
||||||
return r.Copy(), rtt, nil
|
|
||||||
}
|
|
||||||
return r, rtt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) dialTimeout() time.Duration {
|
func (c *Client) dialTimeout() time.Duration {
|
||||||
if c.Timeout != 0 {
|
if c.Timeout != 0 {
|
||||||
return c.Timeout
|
return c.Timeout
|
||||||
|
@ -154,37 +78,88 @@ func (c *Client) writeTimeout() time.Duration {
|
||||||
return dnsTimeout
|
return dnsTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
// Dial connects to the address on the named network.
|
||||||
var co *Conn
|
func (c *Client) Dial(address string) (conn *Conn, err error) {
|
||||||
|
// create a new dialer with the appropriate timeout
|
||||||
|
var d net.Dialer
|
||||||
|
if c.Dialer == nil {
|
||||||
|
d = net.Dialer{}
|
||||||
|
} else {
|
||||||
|
d = net.Dialer(*c.Dialer)
|
||||||
|
}
|
||||||
|
d.Timeout = c.getTimeoutForRequest(c.writeTimeout())
|
||||||
|
|
||||||
network := "udp"
|
network := "udp"
|
||||||
tls := false
|
useTLS := false
|
||||||
|
|
||||||
switch c.Net {
|
switch c.Net {
|
||||||
case "tcp-tls":
|
case "tcp-tls":
|
||||||
network = "tcp"
|
network = "tcp"
|
||||||
tls = true
|
useTLS = true
|
||||||
case "tcp4-tls":
|
case "tcp4-tls":
|
||||||
network = "tcp4"
|
network = "tcp4"
|
||||||
tls = true
|
useTLS = true
|
||||||
case "tcp6-tls":
|
case "tcp6-tls":
|
||||||
network = "tcp6"
|
network = "tcp6"
|
||||||
tls = true
|
useTLS = true
|
||||||
default:
|
default:
|
||||||
if c.Net != "" {
|
if c.Net != "" {
|
||||||
network = c.Net
|
network = c.Net
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var deadline time.Time
|
conn = new(Conn)
|
||||||
if c.Timeout != 0 {
|
if useTLS {
|
||||||
deadline = time.Now().Add(c.Timeout)
|
conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
|
||||||
|
} else {
|
||||||
|
conn.Conn, err = d.Dial(network, address)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange performs a synchronous query. It sends the message m to the address
|
||||||
|
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
||||||
|
//
|
||||||
|
// c := new(dns.Client)
|
||||||
|
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
||||||
|
//
|
||||||
|
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
||||||
|
// case of truncation.
|
||||||
|
// It is up to the caller to create a message that allows for larger responses to be
|
||||||
|
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
||||||
|
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
|
||||||
|
// of 512 bytes
|
||||||
|
// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
|
||||||
|
// attribute appropriately
|
||||||
|
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
|
||||||
|
if !c.SingleInflight {
|
||||||
|
return c.exchange(m, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tls {
|
t := "nop"
|
||||||
co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout())
|
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
||||||
} else {
|
t = t1
|
||||||
co, err = DialTimeout(network, a, c.dialTimeout())
|
|
||||||
}
|
}
|
||||||
|
cl := "nop"
|
||||||
|
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
||||||
|
cl = cl1
|
||||||
|
}
|
||||||
|
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
||||||
|
return c.exchange(m, address)
|
||||||
|
})
|
||||||
|
if r != nil && shared {
|
||||||
|
r = r.Copy()
|
||||||
|
}
|
||||||
|
return r, rtt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||||
|
var co *Conn
|
||||||
|
|
||||||
|
co, err = c.Dial(a)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
|
@ -202,12 +177,13 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
co.TsigSecret = c.TsigSecret
|
co.TsigSecret = c.TsigSecret
|
||||||
co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout()))
|
// write with the appropriate write timeout
|
||||||
|
co.SetWriteDeadline(time.Now().Add(c.getTimeoutForRequest(c.writeTimeout())))
|
||||||
if err = co.WriteMsg(m); err != nil {
|
if err = co.WriteMsg(m); err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout()))
|
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
|
||||||
r, err = co.ReadMsg()
|
r, err = co.ReadMsg()
|
||||||
if err == nil && r.Id != m.Id {
|
if err == nil && r.Id != m.Id {
|
||||||
err = ErrId
|
err = ErrId
|
||||||
|
@ -216,8 +192,10 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadMsg reads a message from the connection co.
|
// ReadMsg reads a message from the connection co.
|
||||||
// If the received message contains a TSIG record the transaction
|
// If the received message contains a TSIG record the transaction signature
|
||||||
// signature is verified.
|
// is verified. This method always tries to return the message, however if an
|
||||||
|
// error is returned there are no guarantees that the returned message is a
|
||||||
|
// valid representation of the packet read.
|
||||||
func (co *Conn) ReadMsg() (*Msg, error) {
|
func (co *Conn) ReadMsg() (*Msg, error) {
|
||||||
p, err := co.ReadMsgHeader(nil)
|
p, err := co.ReadMsgHeader(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -226,14 +204,11 @@ func (co *Conn) ReadMsg() (*Msg, error) {
|
||||||
|
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
if err := m.Unpack(p); err != nil {
|
if err := m.Unpack(p); err != nil {
|
||||||
// If ErrTruncated was returned, we still want to allow the user to use
|
// If an error was returned, we still want to allow the user to use
|
||||||
// the message, but naively they can just check err if they don't want
|
// the message, but naively they can just check err if they don't want
|
||||||
// to use a truncated message
|
// to use an erroneous message
|
||||||
if err == ErrTruncated {
|
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if t := m.IsTsig(); t != nil {
|
if t := m.IsTsig(); t != nil {
|
||||||
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
|
||||||
return m, ErrSecret
|
return m, ErrSecret
|
||||||
|
@ -300,6 +275,18 @@ func tcpMsgLen(t io.Reader) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As seen with my local router/switch, returns 1 byte on the above read,
|
||||||
|
// resulting a a ShortRead. Just write it out (instead of loop) and read the
|
||||||
|
// other byte.
|
||||||
|
if n == 1 {
|
||||||
|
n1, err := t.Read(p[1:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
n += n1
|
||||||
|
}
|
||||||
|
|
||||||
if n != 2 {
|
if n != 2 {
|
||||||
return 0, ErrShortRead
|
return 0, ErrShortRead
|
||||||
}
|
}
|
||||||
|
@ -400,10 +387,28 @@ func (co *Conn) Write(p []byte) (n int, err error) {
|
||||||
n, err := io.Copy(w, bytes.NewReader(p))
|
n, err := io.Copy(w, bytes.NewReader(p))
|
||||||
return int(n), err
|
return int(n), err
|
||||||
}
|
}
|
||||||
n, err = co.Conn.(*net.UDPConn).Write(p)
|
n, err = co.Conn.Write(p)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the appropriate timeout for a specific request
|
||||||
|
func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration {
|
||||||
|
var requestTimeout time.Duration
|
||||||
|
if c.Timeout != 0 {
|
||||||
|
requestTimeout = c.Timeout
|
||||||
|
} else {
|
||||||
|
requestTimeout = timeout
|
||||||
|
}
|
||||||
|
// net.Dialer.Timeout has priority if smaller than the timeouts computed so
|
||||||
|
// far
|
||||||
|
if c.Dialer != nil && c.Dialer.Timeout != 0 {
|
||||||
|
if c.Dialer.Timeout < requestTimeout {
|
||||||
|
requestTimeout = c.Dialer.Timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requestTimeout
|
||||||
|
}
|
||||||
|
|
||||||
// Dial connects to the address on the named network.
|
// Dial connects to the address on the named network.
|
||||||
func Dial(network, address string) (conn *Conn, err error) {
|
func Dial(network, address string) (conn *Conn, err error) {
|
||||||
conn = new(Conn)
|
conn = new(Conn)
|
||||||
|
@ -414,10 +419,43 @@ func Dial(network, address string) (conn *Conn, err error) {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExchangeContext performs a synchronous UDP query, like Exchange. It
|
||||||
|
// additionally obeys deadlines from the passed Context.
|
||||||
|
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||||
|
client := Client{Net: "udp"}
|
||||||
|
r, _, err = client.ExchangeContext(ctx, m, a)
|
||||||
|
// ignorint rtt to leave the original ExchangeContext API unchanged, but
|
||||||
|
// this function will go away
|
||||||
|
return r, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
||||||
|
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
||||||
|
// This function is going away, but can easily be mimicked:
|
||||||
|
//
|
||||||
|
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
||||||
|
// co.WriteMsg(m)
|
||||||
|
// in, _ := co.ReadMsg()
|
||||||
|
// co.Close()
|
||||||
|
//
|
||||||
|
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||||
|
println("dns: ExchangeConn: this function is deprecated")
|
||||||
|
co := new(Conn)
|
||||||
|
co.Conn = c
|
||||||
|
if err = co.WriteMsg(m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r, err = co.ReadMsg()
|
||||||
|
if err == nil && r.Id != m.Id {
|
||||||
|
err = ErrId
|
||||||
|
}
|
||||||
|
return r, err
|
||||||
|
}
|
||||||
|
|
||||||
// DialTimeout acts like Dial but takes a timeout.
|
// DialTimeout acts like Dial but takes a timeout.
|
||||||
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
|
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
|
||||||
conn = new(Conn)
|
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}}
|
||||||
conn.Conn, err = net.DialTimeout(network, address, timeout)
|
conn, err = client.Dial(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -426,8 +464,12 @@ func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, er
|
||||||
|
|
||||||
// DialWithTLS connects to the address on the named network with TLS.
|
// DialWithTLS connects to the address on the named network with TLS.
|
||||||
func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
|
func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
|
||||||
conn = new(Conn)
|
if !strings.HasSuffix(network, "-tls") {
|
||||||
conn.Conn, err = tls.Dial(network, address, tlsConfig)
|
network += "-tls"
|
||||||
|
}
|
||||||
|
client := Client{Net: network, TLSConfig: tlsConfig}
|
||||||
|
conn, err = client.Dial(address)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -436,20 +478,29 @@ func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, er
|
||||||
|
|
||||||
// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
|
// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
|
||||||
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
|
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
|
||||||
var dialer net.Dialer
|
if !strings.HasSuffix(network, "-tls") {
|
||||||
dialer.Timeout = timeout
|
network += "-tls"
|
||||||
|
}
|
||||||
conn = new(Conn)
|
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
|
||||||
conn.Conn, err = tls.DialWithDialer(&dialer, network, address, tlsConfig)
|
conn, err = client.Dial(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
|
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||||
if deadline.IsZero() {
|
// context, if present. If there is both a context deadline and a configured
|
||||||
return time.Now().Add(timeout)
|
// timeout on the client, the earliest of the two takes effect.
|
||||||
|
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||||
|
var timeout time.Duration
|
||||||
|
if deadline, ok := ctx.Deadline(); !ok {
|
||||||
|
timeout = 0
|
||||||
|
} else {
|
||||||
|
timeout = deadline.Sub(time.Now())
|
||||||
}
|
}
|
||||||
return deadline
|
// not passing the context to the underlying calls, as the API does not support
|
||||||
|
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
|
||||||
|
c.Dialer = &net.Dialer{Timeout: timeout}
|
||||||
|
return c.Exchange(m, a)
|
||||||
}
|
}
|
||||||
|
|
48
vendor/github.com/miekg/dns/clientconfig.go
generated
vendored
48
vendor/github.com/miekg/dns/clientconfig.go
generated
vendored
|
@ -2,6 +2,7 @@ package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -25,8 +26,13 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
return ClientConfigFromReader(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientConfigFromReader works like ClientConfigFromFile but takes an io.Reader as argument
|
||||||
|
func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) {
|
||||||
c := new(ClientConfig)
|
c := new(ClientConfig)
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(resolvconf)
|
||||||
c.Servers = make([]string, 0)
|
c.Servers = make([]string, 0)
|
||||||
c.Search = make([]string, 0)
|
c.Search = make([]string, 0)
|
||||||
c.Port = "53"
|
c.Port = "53"
|
||||||
|
@ -73,8 +79,10 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
|
||||||
switch {
|
switch {
|
||||||
case len(s) >= 6 && s[:6] == "ndots:":
|
case len(s) >= 6 && s[:6] == "ndots:":
|
||||||
n, _ := strconv.Atoi(s[6:])
|
n, _ := strconv.Atoi(s[6:])
|
||||||
if n < 1 {
|
if n < 0 {
|
||||||
n = 1
|
n = 0
|
||||||
|
} else if n > 15 {
|
||||||
|
n = 15
|
||||||
}
|
}
|
||||||
c.Ndots = n
|
c.Ndots = n
|
||||||
case len(s) >= 8 && s[:8] == "timeout:":
|
case len(s) >= 8 && s[:8] == "timeout:":
|
||||||
|
@ -83,7 +91,7 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
|
||||||
n = 1
|
n = 1
|
||||||
}
|
}
|
||||||
c.Timeout = n
|
c.Timeout = n
|
||||||
case len(s) >= 8 && s[:9] == "attempts:":
|
case len(s) >= 9 && s[:9] == "attempts:":
|
||||||
n, _ := strconv.Atoi(s[9:])
|
n, _ := strconv.Atoi(s[9:])
|
||||||
if n < 1 {
|
if n < 1 {
|
||||||
n = 1
|
n = 1
|
||||||
|
@ -97,3 +105,35 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NameList returns all of the names that should be queried based on the
|
||||||
|
// config. It is based off of go's net/dns name building, but it does not
|
||||||
|
// check the length of the resulting names.
|
||||||
|
func (c *ClientConfig) NameList(name string) []string {
|
||||||
|
// if this domain is already fully qualified, no append needed.
|
||||||
|
if IsFqdn(name) {
|
||||||
|
return []string{name}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if the name has more labels than Ndots. Do this before making
|
||||||
|
// the domain fully qualified.
|
||||||
|
hasNdots := CountLabel(name) > c.Ndots
|
||||||
|
// Make the domain fully qualified.
|
||||||
|
name = Fqdn(name)
|
||||||
|
|
||||||
|
// Make a list of names based off search.
|
||||||
|
names := []string{}
|
||||||
|
|
||||||
|
// If name has enough dots, try that first.
|
||||||
|
if hasNdots {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
for _, s := range c.Search {
|
||||||
|
names = append(names, Fqdn(name+s))
|
||||||
|
}
|
||||||
|
// If we didn't have enough dots, try after suffixes.
|
||||||
|
if !hasNdots {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
|
188
vendor/github.com/miekg/dns/compress_generate.go
generated
vendored
Normal file
188
vendor/github.com/miekg/dns/compress_generate.go
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
//+build ignore
|
||||||
|
|
||||||
|
// compression_generate.go is meant to run with go generate. It will use
|
||||||
|
// go/{importer,types} to track down all the RR struct types. Then for each type
|
||||||
|
// it will look to see if there are (compressible) names, if so it will add that
|
||||||
|
// type to compressionLenHelperType and comressionLenSearchType which "fake" the
|
||||||
|
// compression so that Len() is fast.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"go/importer"
|
||||||
|
"go/types"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var packageHdr = `
|
||||||
|
// Code generated by "go run compress_generate.go"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package dns
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// getTypeStruct will take a type and the package scope, and return the
|
||||||
|
// (innermost) struct if the type is considered a RR type (currently defined as
|
||||||
|
// those structs beginning with a RR_Header, could be redefined as implementing
|
||||||
|
// the RR interface). The bool return value indicates if embedded structs were
|
||||||
|
// resolved.
|
||||||
|
func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
|
||||||
|
st, ok := t.Underlying().(*types.Struct)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
|
||||||
|
return st, false
|
||||||
|
}
|
||||||
|
if st.Field(0).Anonymous() {
|
||||||
|
st, _ := getTypeStruct(st.Field(0).Type(), scope)
|
||||||
|
return st, true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Import and type-check the package
|
||||||
|
pkg, err := importer.Default().Import("github.com/miekg/dns")
|
||||||
|
fatalIfErr(err)
|
||||||
|
scope := pkg.Scope()
|
||||||
|
|
||||||
|
var domainTypes []string // Types that have a domain name in them (either compressible or not).
|
||||||
|
var cdomainTypes []string // Types that have a compressible domain name in them (subset of domainType)
|
||||||
|
Names:
|
||||||
|
for _, name := range scope.Names() {
|
||||||
|
o := scope.Lookup(name)
|
||||||
|
if o == nil || !o.Exported() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
st, _ := getTypeStruct(o.Type(), scope)
|
||||||
|
if st == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if name == "PrivateRR" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" {
|
||||||
|
log.Fatalf("Constant Type%s does not exist.", o.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 1; i < st.NumFields(); i++ {
|
||||||
|
if _, ok := st.Field(i).Type().(*types.Slice); ok {
|
||||||
|
if st.Tag(i) == `dns:"domain-name"` {
|
||||||
|
domainTypes = append(domainTypes, o.Name())
|
||||||
|
continue Names
|
||||||
|
}
|
||||||
|
if st.Tag(i) == `dns:"cdomain-name"` {
|
||||||
|
cdomainTypes = append(cdomainTypes, o.Name())
|
||||||
|
domainTypes = append(domainTypes, o.Name())
|
||||||
|
continue Names
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case st.Tag(i) == `dns:"domain-name"`:
|
||||||
|
domainTypes = append(domainTypes, o.Name())
|
||||||
|
continue Names
|
||||||
|
case st.Tag(i) == `dns:"cdomain-name"`:
|
||||||
|
cdomainTypes = append(cdomainTypes, o.Name())
|
||||||
|
domainTypes = append(domainTypes, o.Name())
|
||||||
|
continue Names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
b.WriteString(packageHdr)
|
||||||
|
|
||||||
|
// compressionLenHelperType - all types that have domain-name/cdomain-name can be used for compressing names
|
||||||
|
|
||||||
|
fmt.Fprint(b, "func compressionLenHelperType(c map[string]int, r RR) {\n")
|
||||||
|
fmt.Fprint(b, "switch x := r.(type) {\n")
|
||||||
|
for _, name := range domainTypes {
|
||||||
|
o := scope.Lookup(name)
|
||||||
|
st, _ := getTypeStruct(o.Type(), scope)
|
||||||
|
|
||||||
|
fmt.Fprintf(b, "case *%s:\n", name)
|
||||||
|
for i := 1; i < st.NumFields(); i++ {
|
||||||
|
out := func(s string) { fmt.Fprintf(b, "compressionLenHelper(c, x.%s)\n", st.Field(i).Name()) }
|
||||||
|
|
||||||
|
if _, ok := st.Field(i).Type().(*types.Slice); ok {
|
||||||
|
switch st.Tag(i) {
|
||||||
|
case `dns:"domain-name"`:
|
||||||
|
fallthrough
|
||||||
|
case `dns:"cdomain-name"`:
|
||||||
|
// For HIP we need to slice over the elements in this slice.
|
||||||
|
fmt.Fprintf(b, `for i := range x.%s {
|
||||||
|
compressionLenHelper(c, x.%s[i])
|
||||||
|
}
|
||||||
|
`, st.Field(i).Name(), st.Field(i).Name())
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case st.Tag(i) == `dns:"cdomain-name"`:
|
||||||
|
fallthrough
|
||||||
|
case st.Tag(i) == `dns:"domain-name"`:
|
||||||
|
out(st.Field(i).Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintln(b, "}\n}\n\n")
|
||||||
|
|
||||||
|
// compressionLenSearchType - search cdomain-tags types for compressible names.
|
||||||
|
|
||||||
|
fmt.Fprint(b, "func compressionLenSearchType(c map[string]int, r RR) (int, bool) {\n")
|
||||||
|
fmt.Fprint(b, "switch x := r.(type) {\n")
|
||||||
|
for _, name := range cdomainTypes {
|
||||||
|
o := scope.Lookup(name)
|
||||||
|
st, _ := getTypeStruct(o.Type(), scope)
|
||||||
|
|
||||||
|
fmt.Fprintf(b, "case *%s:\n", name)
|
||||||
|
j := 1
|
||||||
|
for i := 1; i < st.NumFields(); i++ {
|
||||||
|
out := func(s string, j int) {
|
||||||
|
fmt.Fprintf(b, "k%d, ok%d := compressionLenSearch(c, x.%s)\n", j, j, st.Field(i).Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are no slice types with names that can be compressed.
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case st.Tag(i) == `dns:"cdomain-name"`:
|
||||||
|
out(st.Field(i).Name(), j)
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k := "k1"
|
||||||
|
ok := "ok1"
|
||||||
|
for i := 2; i < j; i++ {
|
||||||
|
k += fmt.Sprintf(" + k%d", i)
|
||||||
|
ok += fmt.Sprintf(" && ok%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(b, "return %s, %s\n", k, ok)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(b, "}\nreturn 0, false\n}\n\n")
|
||||||
|
|
||||||
|
// gofmt
|
||||||
|
res, err := format.Source(b.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
b.WriteTo(os.Stderr)
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Create("zcompress.go")
|
||||||
|
fatalIfErr(err)
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fatalIfErr(err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
14
vendor/github.com/miekg/dns/defaults.go
generated
vendored
14
vendor/github.com/miekg/dns/defaults.go
generated
vendored
|
@ -13,9 +13,12 @@ const hexDigit = "0123456789abcdef"
|
||||||
// SetReply creates a reply message from a request message.
|
// SetReply creates a reply message from a request message.
|
||||||
func (dns *Msg) SetReply(request *Msg) *Msg {
|
func (dns *Msg) SetReply(request *Msg) *Msg {
|
||||||
dns.Id = request.Id
|
dns.Id = request.Id
|
||||||
dns.RecursionDesired = request.RecursionDesired // Copy rd bit
|
|
||||||
dns.Response = true
|
dns.Response = true
|
||||||
dns.Opcode = OpcodeQuery
|
dns.Opcode = request.Opcode
|
||||||
|
if dns.Opcode == OpcodeQuery {
|
||||||
|
dns.RecursionDesired = request.RecursionDesired // Copy rd bit
|
||||||
|
dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
|
||||||
|
}
|
||||||
dns.Rcode = RcodeSuccess
|
dns.Rcode = RcodeSuccess
|
||||||
if len(request.Question) > 0 {
|
if len(request.Question) > 0 {
|
||||||
dns.Question = make([]Question, 1)
|
dns.Question = make([]Question, 1)
|
||||||
|
@ -270,8 +273,11 @@ func (t Type) String() string {
|
||||||
|
|
||||||
// String returns the string representation for the class c.
|
// String returns the string representation for the class c.
|
||||||
func (c Class) String() string {
|
func (c Class) String() string {
|
||||||
if c1, ok := ClassToString[uint16(c)]; ok {
|
if s, ok := ClassToString[uint16(c)]; ok {
|
||||||
return c1
|
// Only emit mnemonics when they are unambiguous, specically ANY is in both.
|
||||||
|
if _, ok := StringToType[s]; !ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "CLASS" + strconv.Itoa(int(c))
|
return "CLASS" + strconv.Itoa(int(c))
|
||||||
}
|
}
|
||||||
|
|
9
vendor/github.com/miekg/dns/dns.go
generated
vendored
9
vendor/github.com/miekg/dns/dns.go
generated
vendored
|
@ -6,9 +6,12 @@ const (
|
||||||
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
|
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
|
||||||
defaultTtl = 3600 // Default internal TTL.
|
defaultTtl = 3600 // Default internal TTL.
|
||||||
|
|
||||||
DefaultMsgSize = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes.
|
// DefaultMsgSize is the standard default for messages larger than 512 bytes.
|
||||||
MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet.
|
DefaultMsgSize = 4096
|
||||||
MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet.
|
// MinMsgSize is the minimal size of a DNS packet.
|
||||||
|
MinMsgSize = 512
|
||||||
|
// MaxMsgSize is the largest possible DNS packet.
|
||||||
|
MaxMsgSize = 65535
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents a DNS error.
|
// Error represents a DNS error.
|
||||||
|
|
76
vendor/github.com/miekg/dns/dnssec.go
generated
vendored
76
vendor/github.com/miekg/dns/dnssec.go
generated
vendored
|
@ -19,6 +19,8 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSSEC encryption algorithm codes.
|
// DNSSEC encryption algorithm codes.
|
||||||
|
@ -38,12 +40,14 @@ const (
|
||||||
ECCGOST
|
ECCGOST
|
||||||
ECDSAP256SHA256
|
ECDSAP256SHA256
|
||||||
ECDSAP384SHA384
|
ECDSAP384SHA384
|
||||||
|
ED25519
|
||||||
|
ED448
|
||||||
INDIRECT uint8 = 252
|
INDIRECT uint8 = 252
|
||||||
PRIVATEDNS uint8 = 253 // Private (experimental keys)
|
PRIVATEDNS uint8 = 253 // Private (experimental keys)
|
||||||
PRIVATEOID uint8 = 254
|
PRIVATEOID uint8 = 254
|
||||||
)
|
)
|
||||||
|
|
||||||
// Map for algorithm names.
|
// AlgorithmToString is a map of algorithm IDs to algorithm names.
|
||||||
var AlgorithmToString = map[uint8]string{
|
var AlgorithmToString = map[uint8]string{
|
||||||
RSAMD5: "RSAMD5",
|
RSAMD5: "RSAMD5",
|
||||||
DH: "DH",
|
DH: "DH",
|
||||||
|
@ -56,15 +60,17 @@ var AlgorithmToString = map[uint8]string{
|
||||||
ECCGOST: "ECC-GOST",
|
ECCGOST: "ECC-GOST",
|
||||||
ECDSAP256SHA256: "ECDSAP256SHA256",
|
ECDSAP256SHA256: "ECDSAP256SHA256",
|
||||||
ECDSAP384SHA384: "ECDSAP384SHA384",
|
ECDSAP384SHA384: "ECDSAP384SHA384",
|
||||||
|
ED25519: "ED25519",
|
||||||
|
ED448: "ED448",
|
||||||
INDIRECT: "INDIRECT",
|
INDIRECT: "INDIRECT",
|
||||||
PRIVATEDNS: "PRIVATEDNS",
|
PRIVATEDNS: "PRIVATEDNS",
|
||||||
PRIVATEOID: "PRIVATEOID",
|
PRIVATEOID: "PRIVATEOID",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of algorithm strings.
|
// StringToAlgorithm is the reverse of AlgorithmToString.
|
||||||
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
||||||
|
|
||||||
// Map of algorithm crypto hashes.
|
// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
|
||||||
var AlgorithmToHash = map[uint8]crypto.Hash{
|
var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||||
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
||||||
RSASHA1: crypto.SHA1,
|
RSASHA1: crypto.SHA1,
|
||||||
|
@ -73,6 +79,7 @@ var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||||
ECDSAP256SHA256: crypto.SHA256,
|
ECDSAP256SHA256: crypto.SHA256,
|
||||||
ECDSAP384SHA384: crypto.SHA384,
|
ECDSAP384SHA384: crypto.SHA384,
|
||||||
RSASHA512: crypto.SHA512,
|
RSASHA512: crypto.SHA512,
|
||||||
|
ED25519: crypto.Hash(0),
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSSEC hashing algorithm codes.
|
// DNSSEC hashing algorithm codes.
|
||||||
|
@ -85,7 +92,7 @@ const (
|
||||||
SHA512 // Experimental
|
SHA512 // Experimental
|
||||||
)
|
)
|
||||||
|
|
||||||
// Map for hash names.
|
// HashToString is a map of hash IDs to names.
|
||||||
var HashToString = map[uint8]string{
|
var HashToString = map[uint8]string{
|
||||||
SHA1: "SHA1",
|
SHA1: "SHA1",
|
||||||
SHA256: "SHA256",
|
SHA256: "SHA256",
|
||||||
|
@ -94,7 +101,7 @@ var HashToString = map[uint8]string{
|
||||||
SHA512: "SHA512",
|
SHA512: "SHA512",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of hash strings.
|
// StringToHash is a map of names to hash IDs.
|
||||||
var StringToHash = reverseInt8(HashToString)
|
var StringToHash = reverseInt8(HashToString)
|
||||||
|
|
||||||
// DNSKEY flag values.
|
// DNSKEY flag values.
|
||||||
|
@ -301,6 +308,21 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||||
return ErrAlg
|
return ErrAlg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch rr.Algorithm {
|
||||||
|
case ED25519:
|
||||||
|
// ed25519 signs the raw message and performs hashing internally.
|
||||||
|
// All other supported signature schemes operate over the pre-hashed
|
||||||
|
// message, and thus ed25519 must be handled separately here.
|
||||||
|
//
|
||||||
|
// The raw message is passed directly into sign and crypto.Hash(0) is
|
||||||
|
// used to signal to the crypto.Signer that the data has not been hashed.
|
||||||
|
signature, err := sign(k, append(signdata, wire...), crypto.Hash(0), rr.Algorithm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.Signature = toBase64(signature)
|
||||||
|
default:
|
||||||
h := hash.New()
|
h := hash.New()
|
||||||
h.Write(signdata)
|
h.Write(signdata)
|
||||||
h.Write(wire)
|
h.Write(wire)
|
||||||
|
@ -311,6 +333,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
rr.Signature = toBase64(signature)
|
rr.Signature = toBase64(signature)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -352,6 +375,9 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
||||||
// signature = append(signature, intToBytes(r1, 20)...)
|
// signature = append(signature, intToBytes(r1, 20)...)
|
||||||
// signature = append(signature, intToBytes(s1, 20)...)
|
// signature = append(signature, intToBytes(s1, 20)...)
|
||||||
// rr.Signature = signature
|
// rr.Signature = signature
|
||||||
|
|
||||||
|
case ED25519:
|
||||||
|
return signature, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
|
@ -456,6 +482,17 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||||
}
|
}
|
||||||
return ErrSig
|
return ErrSig
|
||||||
|
|
||||||
|
case ED25519:
|
||||||
|
pubkey := k.publicKeyED25519()
|
||||||
|
if pubkey == nil {
|
||||||
|
return ErrKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrSig
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ErrAlg
|
return ErrAlg
|
||||||
}
|
}
|
||||||
|
@ -515,7 +552,7 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
|
||||||
}
|
}
|
||||||
// Remainder
|
// Remainder
|
||||||
expo += uint64(keybuf[keyoff])
|
expo += uint64(keybuf[keyoff])
|
||||||
if expo > 2<<31 {
|
if expo > (2<<31)+1 {
|
||||||
// Larger expo than supported.
|
// Larger expo than supported.
|
||||||
// println("dns: F5 primes (or larger) are not supported")
|
// println("dns: F5 primes (or larger) are not supported")
|
||||||
return nil
|
return nil
|
||||||
|
@ -578,6 +615,17 @@ func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
|
||||||
return pubkey
|
return pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
|
||||||
|
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(keybuf) != ed25519.PublicKeySize {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return keybuf
|
||||||
|
}
|
||||||
|
|
||||||
type wireSlice [][]byte
|
type wireSlice [][]byte
|
||||||
|
|
||||||
func (p wireSlice) Len() int { return len(p) }
|
func (p wireSlice) Len() int { return len(p) }
|
||||||
|
@ -615,6 +663,10 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
|
||||||
switch x := r1.(type) {
|
switch x := r1.(type) {
|
||||||
case *NS:
|
case *NS:
|
||||||
x.Ns = strings.ToLower(x.Ns)
|
x.Ns = strings.ToLower(x.Ns)
|
||||||
|
case *MD:
|
||||||
|
x.Md = strings.ToLower(x.Md)
|
||||||
|
case *MF:
|
||||||
|
x.Mf = strings.ToLower(x.Mf)
|
||||||
case *CNAME:
|
case *CNAME:
|
||||||
x.Target = strings.ToLower(x.Target)
|
x.Target = strings.ToLower(x.Target)
|
||||||
case *SOA:
|
case *SOA:
|
||||||
|
@ -633,6 +685,18 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
|
||||||
x.Email = strings.ToLower(x.Email)
|
x.Email = strings.ToLower(x.Email)
|
||||||
case *MX:
|
case *MX:
|
||||||
x.Mx = strings.ToLower(x.Mx)
|
x.Mx = strings.ToLower(x.Mx)
|
||||||
|
case *RP:
|
||||||
|
x.Mbox = strings.ToLower(x.Mbox)
|
||||||
|
x.Txt = strings.ToLower(x.Txt)
|
||||||
|
case *AFSDB:
|
||||||
|
x.Hostname = strings.ToLower(x.Hostname)
|
||||||
|
case *RT:
|
||||||
|
x.Host = strings.ToLower(x.Host)
|
||||||
|
case *SIG:
|
||||||
|
x.SignerName = strings.ToLower(x.SignerName)
|
||||||
|
case *PX:
|
||||||
|
x.Map822 = strings.ToLower(x.Map822)
|
||||||
|
x.Mapx400 = strings.ToLower(x.Mapx400)
|
||||||
case *NAPTR:
|
case *NAPTR:
|
||||||
x.Replacement = strings.ToLower(x.Replacement)
|
x.Replacement = strings.ToLower(x.Replacement)
|
||||||
case *KX:
|
case *KX:
|
||||||
|
|
22
vendor/github.com/miekg/dns/dnssec_keygen.go
generated
vendored
22
vendor/github.com/miekg/dns/dnssec_keygen.go
generated
vendored
|
@ -8,6 +8,8 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generate generates a DNSKEY of the given bit size.
|
// Generate generates a DNSKEY of the given bit size.
|
||||||
|
@ -38,6 +40,10 @@ func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
|
||||||
if bits != 384 {
|
if bits != 384 {
|
||||||
return nil, ErrKeySize
|
return nil, ErrKeySize
|
||||||
}
|
}
|
||||||
|
case ED25519:
|
||||||
|
if bits != 256 {
|
||||||
|
return nil, ErrKeySize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch k.Algorithm {
|
switch k.Algorithm {
|
||||||
|
@ -75,6 +81,13 @@ func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
|
||||||
}
|
}
|
||||||
k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
|
k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
|
||||||
return priv, nil
|
return priv, nil
|
||||||
|
case ED25519:
|
||||||
|
pub, priv, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
k.setPublicKeyED25519(pub)
|
||||||
|
return priv, nil
|
||||||
default:
|
default:
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
}
|
}
|
||||||
|
@ -117,6 +130,15 @@ func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the public key for Ed25519
|
||||||
|
func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool {
|
||||||
|
if _K == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
k.PublicKey = toBase64(_K)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Set the public key (the values E and N) for RSA
|
// Set the public key (the values E and N) for RSA
|
||||||
// RFC 3110: Section 2. RSA Public KEY Resource Records
|
// RFC 3110: Section 2. RSA Public KEY Resource Records
|
||||||
func exponentToBuf(_E int) []byte {
|
func exponentToBuf(_E int) []byte {
|
||||||
|
|
52
vendor/github.com/miekg/dns/dnssec_keyscan.go
generated
vendored
52
vendor/github.com/miekg/dns/dnssec_keyscan.go
generated
vendored
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
@ -9,6 +10,8 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPrivateKey returns a PrivateKey by parsing the string s.
|
// NewPrivateKey returns a PrivateKey by parsing the string s.
|
||||||
|
@ -36,7 +39,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
}
|
}
|
||||||
// TODO(mg): check if the pubkey matches the private key
|
// TODO(mg): check if the pubkey matches the private key
|
||||||
algo, err := strconv.Atoi(strings.SplitN(m["algorithm"], " ", 2)[0])
|
algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
}
|
}
|
||||||
|
@ -86,6 +89,8 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
|
||||||
}
|
}
|
||||||
priv.PublicKey = *pub
|
priv.PublicKey = *pub
|
||||||
return priv, nil
|
return priv, nil
|
||||||
|
case ED25519:
|
||||||
|
return readPrivateKeyED25519(m)
|
||||||
default:
|
default:
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
}
|
}
|
||||||
|
@ -166,13 +171,56 @@ func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
|
||||||
|
var p ed25519.PrivateKey
|
||||||
|
// TODO: validate that the required flags are present
|
||||||
|
for k, v := range m {
|
||||||
|
switch k {
|
||||||
|
case "privatekey":
|
||||||
|
p1, err := fromBase64([]byte(v))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(p1) != 32 {
|
||||||
|
return nil, ErrPrivKey
|
||||||
|
}
|
||||||
|
// RFC 8080 and Golang's x/crypto/ed25519 differ as to how the
|
||||||
|
// private keys are represented. RFC 8080 specifies that private
|
||||||
|
// keys be stored solely as the seed value (p1 above) while the
|
||||||
|
// ed25519 package represents them as the seed value concatenated
|
||||||
|
// to the public key, which is derived from the seed value.
|
||||||
|
//
|
||||||
|
// ed25519.GenerateKey reads exactly 32 bytes from the passed in
|
||||||
|
// io.Reader and uses them as the seed. It also derives the
|
||||||
|
// public key and produces a compatible private key.
|
||||||
|
_, p, err = ed25519.GenerateKey(bytes.NewReader(p1))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case "created", "publish", "activate":
|
||||||
|
/* not used in Go (yet) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
// parseKey reads a private key from r. It returns a map[string]string,
|
// parseKey reads a private key from r. It returns a map[string]string,
|
||||||
// with the key-value pairs, or an error when the file is not correct.
|
// with the key-value pairs, or an error when the file is not correct.
|
||||||
func parseKey(r io.Reader, file string) (map[string]string, error) {
|
func parseKey(r io.Reader, file string) (map[string]string, error) {
|
||||||
s := scanInit(r)
|
s, cancel := scanInit(r)
|
||||||
m := make(map[string]string)
|
m := make(map[string]string)
|
||||||
c := make(chan lex)
|
c := make(chan lex)
|
||||||
k := ""
|
k := ""
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
// zlexer can send up to two tokens, the next one and possibly 1 remainders.
|
||||||
|
// Do a non-blocking read.
|
||||||
|
_, ok := <-c
|
||||||
|
_, ok = <-c
|
||||||
|
if !ok {
|
||||||
|
// too bad
|
||||||
|
}
|
||||||
|
}()
|
||||||
// Start the lexer
|
// Start the lexer
|
||||||
go klexer(s, c)
|
go klexer(s, c)
|
||||||
for l := range c {
|
for l := range c {
|
||||||
|
|
8
vendor/github.com/miekg/dns/dnssec_privkey.go
generated
vendored
8
vendor/github.com/miekg/dns/dnssec_privkey.go
generated
vendored
|
@ -7,6 +7,8 @@ import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
const format = "Private-key-format: v1.3\n"
|
const format = "Private-key-format: v1.3\n"
|
||||||
|
@ -79,6 +81,12 @@ func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
|
||||||
"Private_value(x): " + priv + "\n" +
|
"Private_value(x): " + priv + "\n" +
|
||||||
"Public_value(y): " + pub + "\n"
|
"Public_value(y): " + pub + "\n"
|
||||||
|
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
private := toBase64(p[:32])
|
||||||
|
return format +
|
||||||
|
"Algorithm: " + algorithm + "\n" +
|
||||||
|
"PrivateKey: " + private + "\n"
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
31
vendor/github.com/miekg/dns/doc.go
generated
vendored
31
vendor/github.com/miekg/dns/doc.go
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Package dns implements a full featured interface to the Domain Name System.
|
Package dns implements a full featured interface to the Domain Name System.
|
||||||
Server- and client-side programming is supported.
|
Server- and client-side programming is supported.
|
||||||
The package allows complete control over what is send out to the DNS. The package
|
The package allows complete control over what is sent out to the DNS. The package
|
||||||
API follows the less-is-more principle, by presenting a small, clean interface.
|
API follows the less-is-more principle, by presenting a small, clean interface.
|
||||||
|
|
||||||
The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
|
The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
|
||||||
|
@ -22,9 +22,9 @@ Or directly from a string:
|
||||||
|
|
||||||
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
|
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
|
||||||
|
|
||||||
Or when the default TTL (3600) and class (IN) suit you:
|
Or when the default origin (.) and TTL (3600) and class (IN) suit you:
|
||||||
|
|
||||||
mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
|
mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
|
||||||
|
|
||||||
Or even:
|
Or even:
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ The following is slightly more verbose, but more flexible:
|
||||||
m1.Question = make([]dns.Question, 1)
|
m1.Question = make([]dns.Question, 1)
|
||||||
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
||||||
|
|
||||||
After creating a message it can be send.
|
After creating a message it can be sent.
|
||||||
Basic use pattern for synchronous querying the DNS at a
|
Basic use pattern for synchronous querying the DNS at a
|
||||||
server configured on 127.0.0.1 and port 53:
|
server configured on 127.0.0.1 and port 53:
|
||||||
|
|
||||||
|
@ -63,7 +63,23 @@ class) is as easy as setting:
|
||||||
|
|
||||||
c.SingleInflight = true
|
c.SingleInflight = true
|
||||||
|
|
||||||
If these "advanced" features are not needed, a simple UDP query can be send,
|
More advanced options are available using a net.Dialer and the corresponding API.
|
||||||
|
For example it is possible to set a timeout, or to specify a source IP address
|
||||||
|
and port to use for the connection:
|
||||||
|
|
||||||
|
c := new(dns.Client)
|
||||||
|
laddr := net.UDPAddr{
|
||||||
|
IP: net.ParseIP("[::1]"),
|
||||||
|
Port: 12345,
|
||||||
|
Zone: "",
|
||||||
|
}
|
||||||
|
d := net.Dialer{
|
||||||
|
Timeout: 200 * time.Millisecond,
|
||||||
|
LocalAddr: &laddr,
|
||||||
|
}
|
||||||
|
in, rtt, err := c.ExchangeWithDialer(&d, m1, "8.8.8.8:53")
|
||||||
|
|
||||||
|
If these "advanced" features are not needed, a simple UDP query can be sent,
|
||||||
with:
|
with:
|
||||||
|
|
||||||
in, err := dns.Exchange(m1, "127.0.0.1:53")
|
in, err := dns.Exchange(m1, "127.0.0.1:53")
|
||||||
|
@ -152,6 +168,11 @@ Basic use pattern when querying with a TSIG name "axfr." (note that these key na
|
||||||
must be fully qualified - as they are domain names) and the base64 secret
|
must be fully qualified - as they are domain names) and the base64 secret
|
||||||
"so6ZGir4GPAqINNh9U5c3A==":
|
"so6ZGir4GPAqINNh9U5c3A==":
|
||||||
|
|
||||||
|
If an incoming message contains a TSIG record it MUST be the last record in
|
||||||
|
the additional section (RFC2845 3.2). This means that you should make the
|
||||||
|
call to SetTsig last, right before executing the query. If you make any
|
||||||
|
changes to the RRset after calling SetTsig() the signature will be incorrect.
|
||||||
|
|
||||||
c := new(dns.Client)
|
c := new(dns.Client)
|
||||||
c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
|
c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
|
|
98
vendor/github.com/miekg/dns/edns.go
generated
vendored
98
vendor/github.com/miekg/dns/edns.go
generated
vendored
|
@ -13,18 +13,18 @@ import (
|
||||||
const (
|
const (
|
||||||
EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
|
EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
|
||||||
EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
|
EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
|
||||||
EDNS0NSID = 0x3 // nsid (RFC5001)
|
EDNS0NSID = 0x3 // nsid (See RFC 5001)
|
||||||
EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
|
EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
|
||||||
EDNS0DHU = 0x6 // DS Hash Understood
|
EDNS0DHU = 0x6 // DS Hash Understood
|
||||||
EDNS0N3U = 0x7 // NSEC3 Hash Understood
|
EDNS0N3U = 0x7 // NSEC3 Hash Understood
|
||||||
EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
|
EDNS0SUBNET = 0x8 // client-subnet (See RFC 7871)
|
||||||
EDNS0EXPIRE = 0x9 // EDNS0 expire
|
EDNS0EXPIRE = 0x9 // EDNS0 expire
|
||||||
EDNS0COOKIE = 0xa // EDNS0 Cookie
|
EDNS0COOKIE = 0xa // EDNS0 Cookie
|
||||||
EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828)
|
EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (See RFC 7828)
|
||||||
EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
|
EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830)
|
||||||
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
|
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (See RFC 6891)
|
||||||
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
|
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (See RFC 6891)
|
||||||
_DO = 1 << 15 // dnssec ok
|
_DO = 1 << 15 // DNSSEC OK
|
||||||
)
|
)
|
||||||
|
|
||||||
// OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
|
// OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
|
||||||
|
@ -57,9 +57,6 @@ func (rr *OPT) String() string {
|
||||||
}
|
}
|
||||||
case *EDNS0_SUBNET:
|
case *EDNS0_SUBNET:
|
||||||
s += "\n; SUBNET: " + o.String()
|
s += "\n; SUBNET: " + o.String()
|
||||||
if o.(*EDNS0_SUBNET).DraftOption {
|
|
||||||
s += " (draft)"
|
|
||||||
}
|
|
||||||
case *EDNS0_COOKIE:
|
case *EDNS0_COOKIE:
|
||||||
s += "\n; COOKIE: " + o.String()
|
s += "\n; COOKIE: " + o.String()
|
||||||
case *EDNS0_UL:
|
case *EDNS0_UL:
|
||||||
|
@ -74,6 +71,8 @@ func (rr *OPT) String() string {
|
||||||
s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
|
s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
|
||||||
case *EDNS0_LOCAL:
|
case *EDNS0_LOCAL:
|
||||||
s += "\n; LOCAL OPT: " + o.String()
|
s += "\n; LOCAL OPT: " + o.String()
|
||||||
|
case *EDNS0_PADDING:
|
||||||
|
s += "\n; PADDING: " + o.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
@ -103,15 +102,12 @@ func (rr *OPT) SetVersion(v uint8) {
|
||||||
|
|
||||||
// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
|
// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
|
||||||
func (rr *OPT) ExtendedRcode() int {
|
func (rr *OPT) ExtendedRcode() int {
|
||||||
return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15
|
return int((rr.Hdr.Ttl & 0xFF000000) >> 24)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetExtendedRcode sets the EDNS extended RCODE field.
|
// SetExtendedRcode sets the EDNS extended RCODE field.
|
||||||
func (rr *OPT) SetExtendedRcode(v uint8) {
|
func (rr *OPT) SetExtendedRcode(v uint8) {
|
||||||
if v < RcodeBadVers { // Smaller than 16.. Use the 4 bits you have!
|
rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v) << 24)
|
||||||
return
|
|
||||||
}
|
|
||||||
rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPSize returns the UDP buffer size.
|
// UDPSize returns the UDP buffer size.
|
||||||
|
@ -157,7 +153,7 @@ type EDNS0 interface {
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// The nsid EDNS0 option is used to retrieve a nameserver
|
// EDNS0_NSID option is used to retrieve a nameserver
|
||||||
// identifier. When sending a request Nsid must be set to the empty string
|
// identifier. When sending a request Nsid must be set to the empty string
|
||||||
// The identifier is an opaque string encoded as hex.
|
// The identifier is an opaque string encoded as hex.
|
||||||
// Basic use pattern for creating an nsid option:
|
// Basic use pattern for creating an nsid option:
|
||||||
|
@ -182,12 +178,13 @@ func (e *EDNS0_NSID) pack() ([]byte, error) {
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID }
|
// Option implements the EDNS0 interface.
|
||||||
|
func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code.
|
||||||
func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
|
func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
|
||||||
func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
|
func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
|
||||||
|
|
||||||
// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
|
// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
|
||||||
// an idea of where the client lives. It can then give back a different
|
// an idea of where the client lives. See RFC 7871. It can then give back a different
|
||||||
// answer depending on the location or network topology.
|
// answer depending on the location or network topology.
|
||||||
// Basic use pattern for creating an subnet option:
|
// Basic use pattern for creating an subnet option:
|
||||||
//
|
//
|
||||||
|
@ -197,31 +194,25 @@ func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
|
||||||
// e := new(dns.EDNS0_SUBNET)
|
// e := new(dns.EDNS0_SUBNET)
|
||||||
// e.Code = dns.EDNS0SUBNET
|
// e.Code = dns.EDNS0SUBNET
|
||||||
// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
|
// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
|
||||||
// e.SourceNetMask = 32 // 32 for IPV4, 128 for IPv6
|
// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
|
||||||
// e.SourceScope = 0
|
// e.SourceScope = 0
|
||||||
// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
|
// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
|
||||||
// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
|
// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
|
||||||
// o.Option = append(o.Option, e)
|
// o.Option = append(o.Option, e)
|
||||||
//
|
//
|
||||||
// Note: the spec (draft-ietf-dnsop-edns-client-subnet-00) has some insane logic
|
// This code will parse all the available bits when unpacking (up to optlen).
|
||||||
// for which netmask applies to the address. This code will parse all the
|
// When packing it will apply SourceNetmask. If you need more advanced logic,
|
||||||
// available bits when unpacking (up to optlen). When packing it will apply
|
// patches welcome and good luck.
|
||||||
// SourceNetmask. If you need more advanced logic, patches welcome and good luck.
|
|
||||||
type EDNS0_SUBNET struct {
|
type EDNS0_SUBNET struct {
|
||||||
Code uint16 // Always EDNS0SUBNET
|
Code uint16 // Always EDNS0SUBNET
|
||||||
Family uint16 // 1 for IP, 2 for IP6
|
Family uint16 // 1 for IP, 2 for IP6
|
||||||
SourceNetmask uint8
|
SourceNetmask uint8
|
||||||
SourceScope uint8
|
SourceScope uint8
|
||||||
Address net.IP
|
Address net.IP
|
||||||
DraftOption bool // Set to true if using the old (0x50fa) option code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EDNS0_SUBNET) Option() uint16 {
|
// Option implements the EDNS0 interface.
|
||||||
if e.DraftOption {
|
func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
|
||||||
return EDNS0SUBNETDRAFT
|
|
||||||
}
|
|
||||||
return EDNS0SUBNET
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EDNS0_SUBNET) pack() ([]byte, error) {
|
func (e *EDNS0_SUBNET) pack() ([]byte, error) {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
|
@ -229,6 +220,12 @@ func (e *EDNS0_SUBNET) pack() ([]byte, error) {
|
||||||
b[2] = e.SourceNetmask
|
b[2] = e.SourceNetmask
|
||||||
b[3] = e.SourceScope
|
b[3] = e.SourceScope
|
||||||
switch e.Family {
|
switch e.Family {
|
||||||
|
case 0:
|
||||||
|
// "dig" sets AddressFamily to 0 if SourceNetmask is also 0
|
||||||
|
// We might don't need to complain either
|
||||||
|
if e.SourceNetmask != 0 {
|
||||||
|
return nil, errors.New("dns: bad address family")
|
||||||
|
}
|
||||||
case 1:
|
case 1:
|
||||||
if e.SourceNetmask > net.IPv4len*8 {
|
if e.SourceNetmask > net.IPv4len*8 {
|
||||||
return nil, errors.New("dns: bad netmask")
|
return nil, errors.New("dns: bad netmask")
|
||||||
|
@ -263,6 +260,13 @@ func (e *EDNS0_SUBNET) unpack(b []byte) error {
|
||||||
e.SourceNetmask = b[2]
|
e.SourceNetmask = b[2]
|
||||||
e.SourceScope = b[3]
|
e.SourceScope = b[3]
|
||||||
switch e.Family {
|
switch e.Family {
|
||||||
|
case 0:
|
||||||
|
// "dig" sets AddressFamily to 0 if SourceNetmask is also 0
|
||||||
|
// It's okay to accept such a packet
|
||||||
|
if e.SourceNetmask != 0 {
|
||||||
|
return errors.New("dns: bad address family")
|
||||||
|
}
|
||||||
|
e.Address = net.IPv4(0, 0, 0, 0)
|
||||||
case 1:
|
case 1:
|
||||||
if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
|
if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
|
||||||
return errors.New("dns: bad netmask")
|
return errors.New("dns: bad netmask")
|
||||||
|
@ -301,7 +305,7 @@ func (e *EDNS0_SUBNET) String() (s string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Cookie EDNS0 option
|
// The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
|
||||||
//
|
//
|
||||||
// o := new(dns.OPT)
|
// o := new(dns.OPT)
|
||||||
// o.Hdr.Name = "."
|
// o.Hdr.Name = "."
|
||||||
|
@ -332,6 +336,7 @@ func (e *EDNS0_COOKIE) pack() ([]byte, error) {
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
|
func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
|
||||||
func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
|
func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
|
||||||
func (e *EDNS0_COOKIE) String() string { return e.Cookie }
|
func (e *EDNS0_COOKIE) String() string { return e.Cookie }
|
||||||
|
@ -353,6 +358,7 @@ type EDNS0_UL struct {
|
||||||
Lease uint32
|
Lease uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
|
func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
|
||||||
func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) }
|
func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) }
|
||||||
|
|
||||||
|
@ -382,6 +388,7 @@ type EDNS0_LLQ struct {
|
||||||
LeaseLife uint32
|
LeaseLife uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
|
func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
|
||||||
|
|
||||||
func (e *EDNS0_LLQ) pack() ([]byte, error) {
|
func (e *EDNS0_LLQ) pack() ([]byte, error) {
|
||||||
|
@ -413,11 +420,13 @@ func (e *EDNS0_LLQ) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_DUA implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975.
|
||||||
type EDNS0_DAU struct {
|
type EDNS0_DAU struct {
|
||||||
Code uint16 // Always EDNS0DAU
|
Code uint16 // Always EDNS0DAU
|
||||||
AlgCode []uint8
|
AlgCode []uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
|
func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
|
||||||
func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
|
func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
|
||||||
func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
|
func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
|
||||||
|
@ -434,11 +443,13 @@ func (e *EDNS0_DAU) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975.
|
||||||
type EDNS0_DHU struct {
|
type EDNS0_DHU struct {
|
||||||
Code uint16 // Always EDNS0DHU
|
Code uint16 // Always EDNS0DHU
|
||||||
AlgCode []uint8
|
AlgCode []uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
|
func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
|
||||||
func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
|
func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
|
||||||
func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
|
func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
|
||||||
|
@ -455,11 +466,13 @@ func (e *EDNS0_DHU) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975.
|
||||||
type EDNS0_N3U struct {
|
type EDNS0_N3U struct {
|
||||||
Code uint16 // Always EDNS0N3U
|
Code uint16 // Always EDNS0N3U
|
||||||
AlgCode []uint8
|
AlgCode []uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
|
func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
|
||||||
func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
|
func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
|
||||||
func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
|
func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
|
||||||
|
@ -477,11 +490,13 @@ func (e *EDNS0_N3U) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_EXPIRE implementes the EDNS0 option as described in RFC 7314.
|
||||||
type EDNS0_EXPIRE struct {
|
type EDNS0_EXPIRE struct {
|
||||||
Code uint16 // Always EDNS0EXPIRE
|
Code uint16 // Always EDNS0EXPIRE
|
||||||
Expire uint32
|
Expire uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
|
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
|
||||||
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
|
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
|
||||||
|
|
||||||
|
@ -520,6 +535,7 @@ type EDNS0_LOCAL struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
|
func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
|
||||||
func (e *EDNS0_LOCAL) String() string {
|
func (e *EDNS0_LOCAL) String() string {
|
||||||
return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
|
return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
|
||||||
|
@ -543,15 +559,16 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
|
||||||
|
// the TCP connection alive. See RFC 7828.
|
||||||
type EDNS0_TCP_KEEPALIVE struct {
|
type EDNS0_TCP_KEEPALIVE struct {
|
||||||
Code uint16 // Always EDNSTCPKEEPALIVE
|
Code uint16 // Always EDNSTCPKEEPALIVE
|
||||||
Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
|
Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
|
||||||
Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
|
Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 {
|
// Option implements the EDNS0 interface.
|
||||||
return EDNS0TCPKEEPALIVE
|
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
|
func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
|
||||||
if e.Timeout != 0 && e.Length != 2 {
|
if e.Timeout != 0 && e.Length != 2 {
|
||||||
|
@ -595,3 +612,16 @@ func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDNS0_PADDING option is used to add padding to a request/response. The default
|
||||||
|
// value of padding SHOULD be 0x0 but other values MAY be used, for instance if
|
||||||
|
// compression is applied before encryption which may break signatures.
|
||||||
|
type EDNS0_PADDING struct {
|
||||||
|
Padding []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option implements the EDNS0 interface.
|
||||||
|
func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
|
||||||
|
func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
|
||||||
|
func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
|
||||||
|
func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
|
||||||
|
|
23
vendor/github.com/miekg/dns/fuzz.go
generated
vendored
Normal file
23
vendor/github.com/miekg/dns/fuzz.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// +build fuzz
|
||||||
|
|
||||||
|
package dns
|
||||||
|
|
||||||
|
func Fuzz(data []byte) int {
|
||||||
|
msg := new(Msg)
|
||||||
|
|
||||||
|
if err := msg.Unpack(data); err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if _, err := msg.Pack(); err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func FuzzNewRR(data []byte) int {
|
||||||
|
if _, err := NewRR(string(data)); err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
43
vendor/github.com/miekg/dns/labels.go
generated
vendored
43
vendor/github.com/miekg/dns/labels.go
generated
vendored
|
@ -42,7 +42,7 @@ func SplitDomainName(s string) (labels []string) {
|
||||||
|
|
||||||
// CompareDomainName compares the names s1 and s2 and
|
// CompareDomainName compares the names s1 and s2 and
|
||||||
// returns how many labels they have in common starting from the *right*.
|
// returns how many labels they have in common starting from the *right*.
|
||||||
// The comparison stops at the first inequality. The names are not downcased
|
// The comparison stops at the first inequality. The names are downcased
|
||||||
// before the comparison.
|
// before the comparison.
|
||||||
//
|
//
|
||||||
// www.miek.nl. and miek.nl. have two labels in common: miek and nl
|
// www.miek.nl. and miek.nl. have two labels in common: miek and nl
|
||||||
|
@ -50,23 +50,21 @@ func SplitDomainName(s string) (labels []string) {
|
||||||
//
|
//
|
||||||
// s1 and s2 must be syntactically valid domain names.
|
// s1 and s2 must be syntactically valid domain names.
|
||||||
func CompareDomainName(s1, s2 string) (n int) {
|
func CompareDomainName(s1, s2 string) (n int) {
|
||||||
s1 = Fqdn(s1)
|
// the first check: root label
|
||||||
s2 = Fqdn(s2)
|
if s1 == "." || s2 == "." {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
l1 := Split(s1)
|
l1 := Split(s1)
|
||||||
l2 := Split(s2)
|
l2 := Split(s2)
|
||||||
|
|
||||||
// the first check: root label
|
|
||||||
if l1 == nil || l2 == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
j1 := len(l1) - 1 // end
|
j1 := len(l1) - 1 // end
|
||||||
i1 := len(l1) - 2 // start
|
i1 := len(l1) - 2 // start
|
||||||
j2 := len(l2) - 1
|
j2 := len(l2) - 1
|
||||||
i2 := len(l2) - 2
|
i2 := len(l2) - 2
|
||||||
// the second check can be done here: last/only label
|
// the second check can be done here: last/only label
|
||||||
// before we fall through into the for-loop below
|
// before we fall through into the for-loop below
|
||||||
if s1[l1[j1]:] == s2[l2[j2]:] {
|
if equal(s1[l1[j1]:], s2[l2[j2]:]) {
|
||||||
n++
|
n++
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
|
@ -75,7 +73,7 @@ func CompareDomainName(s1, s2 string) (n int) {
|
||||||
if i1 < 0 || i2 < 0 {
|
if i1 < 0 || i2 < 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
|
if equal(s1[l1[i1]:l1[j1]], s2[l2[i2]:l2[j2]]) {
|
||||||
n++
|
n++
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
@ -166,3 +164,28 @@ func PrevLabel(s string, n int) (i int, start bool) {
|
||||||
}
|
}
|
||||||
return lab[len(lab)-n], false
|
return lab[len(lab)-n], false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// equal compares a and b while ignoring case. It returns true when equal otherwise false.
|
||||||
|
func equal(a, b string) bool {
|
||||||
|
// might be lifted into API function.
|
||||||
|
la := len(a)
|
||||||
|
lb := len(b)
|
||||||
|
if la != lb {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := la - 1; i >= 0; i-- {
|
||||||
|
ai := a[i]
|
||||||
|
bi := b[i]
|
||||||
|
if ai >= 'A' && ai <= 'Z' {
|
||||||
|
ai |= ('a' - 'A')
|
||||||
|
}
|
||||||
|
if bi >= 'A' && bi <= 'Z' {
|
||||||
|
bi |= ('a' - 'A')
|
||||||
|
}
|
||||||
|
if ai != bi {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
296
vendor/github.com/miekg/dns/msg.go
generated
vendored
296
vendor/github.com/miekg/dns/msg.go
generated
vendored
|
@ -9,42 +9,36 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
//go:generate go run msg_generate.go
|
//go:generate go run msg_generate.go
|
||||||
|
//go:generate go run compress_generate.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
const (
|
||||||
// Initialize default math/rand source using crypto/rand to provide better
|
maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
|
||||||
// security without the performance trade-off.
|
maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4
|
||||||
buf := make([]byte, 8)
|
)
|
||||||
_, err := crand.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
// Failed to read from cryptographic source, fallback to default initial
|
|
||||||
// seed (1) by returning early
|
|
||||||
return
|
|
||||||
}
|
|
||||||
seed := binary.BigEndian.Uint64(buf)
|
|
||||||
rand.Seed(int64(seed))
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
|
|
||||||
|
|
||||||
|
// Errors defined in this package.
|
||||||
var (
|
var (
|
||||||
ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
|
ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
|
||||||
ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
|
ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
|
||||||
ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used it too small for the message.
|
ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message.
|
||||||
ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being uses before it is initialized.
|
ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized.
|
||||||
ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
|
ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
|
||||||
ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
|
ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
|
||||||
ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
|
ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
|
||||||
ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
|
ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
|
||||||
ErrKey error = &Error{err: "bad key"}
|
ErrKey error = &Error{err: "bad key"}
|
||||||
ErrKeySize error = &Error{err: "bad key size"}
|
ErrKeySize error = &Error{err: "bad key size"}
|
||||||
|
ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
|
||||||
ErrNoSig error = &Error{err: "no signature found"}
|
ErrNoSig error = &Error{err: "no signature found"}
|
||||||
ErrPrivKey error = &Error{err: "bad private key"}
|
ErrPrivKey error = &Error{err: "bad private key"}
|
||||||
ErrRcode error = &Error{err: "bad rcode"}
|
ErrRcode error = &Error{err: "bad rcode"}
|
||||||
|
@ -64,13 +58,47 @@ var (
|
||||||
// For instance, to make it return a static value:
|
// For instance, to make it return a static value:
|
||||||
//
|
//
|
||||||
// dns.Id = func() uint16 { return 3 }
|
// dns.Id = func() uint16 { return 3 }
|
||||||
var Id func() uint16 = id
|
var Id = id
|
||||||
|
|
||||||
|
var (
|
||||||
|
idLock sync.Mutex
|
||||||
|
idRand *rand.Rand
|
||||||
|
)
|
||||||
|
|
||||||
// id returns a 16 bits random number to be used as a
|
// id returns a 16 bits random number to be used as a
|
||||||
// message id. The random provided should be good enough.
|
// message id. The random provided should be good enough.
|
||||||
func id() uint16 {
|
func id() uint16 {
|
||||||
id32 := rand.Uint32()
|
idLock.Lock()
|
||||||
return uint16(id32)
|
|
||||||
|
if idRand == nil {
|
||||||
|
// This (partially) works around
|
||||||
|
// https://github.com/golang/go/issues/11833 by only
|
||||||
|
// seeding idRand upon the first call to id.
|
||||||
|
|
||||||
|
var seed int64
|
||||||
|
var buf [8]byte
|
||||||
|
|
||||||
|
if _, err := crand.Read(buf[:]); err == nil {
|
||||||
|
seed = int64(binary.LittleEndian.Uint64(buf[:]))
|
||||||
|
} else {
|
||||||
|
seed = rand.Int63()
|
||||||
|
}
|
||||||
|
|
||||||
|
idRand = rand.New(rand.NewSource(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The call to idRand.Uint32 must be within the
|
||||||
|
// mutex lock because *rand.Rand is not safe for
|
||||||
|
// concurrent use.
|
||||||
|
//
|
||||||
|
// There is no added performance overhead to calling
|
||||||
|
// idRand.Uint32 inside a mutex lock over just
|
||||||
|
// calling rand.Uint32 as the global math/rand rng
|
||||||
|
// is internally protected by a sync.Mutex.
|
||||||
|
id := uint16(idRand.Uint32())
|
||||||
|
|
||||||
|
idLock.Unlock()
|
||||||
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgHdr is a a manually-unpacked version of (id, bits).
|
// MsgHdr is a a manually-unpacked version of (id, bits).
|
||||||
|
@ -241,7 +269,9 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
|
||||||
bsFresh = true
|
bsFresh = true
|
||||||
}
|
}
|
||||||
// Don't try to compress '.'
|
// Don't try to compress '.'
|
||||||
if compress && roBs[begin:] != "." {
|
// We should only compress when compress it true, but we should also still pick
|
||||||
|
// up names that can be used for *future* compression(s).
|
||||||
|
if compression != nil && roBs[begin:] != "." {
|
||||||
if p, ok := compression[roBs[begin:]]; !ok {
|
if p, ok := compression[roBs[begin:]]; !ok {
|
||||||
// Only offsets smaller than this can be used.
|
// Only offsets smaller than this can be used.
|
||||||
if offset < maxCompressionOffset {
|
if offset < maxCompressionOffset {
|
||||||
|
@ -305,6 +335,7 @@ func UnpackDomainName(msg []byte, off int) (string, int, error) {
|
||||||
s := make([]byte, 0, 64)
|
s := make([]byte, 0, 64)
|
||||||
off1 := 0
|
off1 := 0
|
||||||
lenmsg := len(msg)
|
lenmsg := len(msg)
|
||||||
|
maxLen := maxDomainNameWireOctets
|
||||||
ptr := 0 // number of pointers followed
|
ptr := 0 // number of pointers followed
|
||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
|
@ -329,8 +360,10 @@ Loop:
|
||||||
fallthrough
|
fallthrough
|
||||||
case '"', '\\':
|
case '"', '\\':
|
||||||
s = append(s, '\\', b)
|
s = append(s, '\\', b)
|
||||||
|
// presentation-format \X escapes add an extra byte
|
||||||
|
maxLen++
|
||||||
default:
|
default:
|
||||||
if b < 32 || b >= 127 { // unprintable use \DDD
|
if b < 32 || b >= 127 { // unprintable, use \DDD
|
||||||
var buf [3]byte
|
var buf [3]byte
|
||||||
bufs := strconv.AppendInt(buf[:0], int64(b), 10)
|
bufs := strconv.AppendInt(buf[:0], int64(b), 10)
|
||||||
s = append(s, '\\')
|
s = append(s, '\\')
|
||||||
|
@ -340,6 +373,8 @@ Loop:
|
||||||
for _, r := range bufs {
|
for _, r := range bufs {
|
||||||
s = append(s, r)
|
s = append(s, r)
|
||||||
}
|
}
|
||||||
|
// presentation-format \DDD escapes add 3 extra bytes
|
||||||
|
maxLen += 3
|
||||||
} else {
|
} else {
|
||||||
s = append(s, b)
|
s = append(s, b)
|
||||||
}
|
}
|
||||||
|
@ -364,6 +399,9 @@ Loop:
|
||||||
if ptr++; ptr > 10 {
|
if ptr++; ptr > 10 {
|
||||||
return "", lenmsg, &Error{err: "too many compression pointers"}
|
return "", lenmsg, &Error{err: "too many compression pointers"}
|
||||||
}
|
}
|
||||||
|
// pointer should guarantee that it advances and points forwards at least
|
||||||
|
// but the condition on previous three lines guarantees that it's
|
||||||
|
// at least loop-free
|
||||||
off = (c^0xC0)<<8 | int(c1)
|
off = (c^0xC0)<<8 | int(c1)
|
||||||
default:
|
default:
|
||||||
// 0x80 and 0x40 are reserved
|
// 0x80 and 0x40 are reserved
|
||||||
|
@ -375,6 +413,9 @@ Loop:
|
||||||
}
|
}
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
s = []byte(".")
|
s = []byte(".")
|
||||||
|
} else if len(s) >= maxLen {
|
||||||
|
// error if the name is too long, but don't throw it away
|
||||||
|
return string(s), lenmsg, ErrLongDomain
|
||||||
}
|
}
|
||||||
return string(s), off1, nil
|
return string(s), off1, nil
|
||||||
}
|
}
|
||||||
|
@ -571,8 +612,8 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
|
||||||
// If we cannot unpack the whole array, then it will return nil
|
// If we cannot unpack the whole array, then it will return nil
|
||||||
func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) {
|
func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) {
|
||||||
var r RR
|
var r RR
|
||||||
// Optimistically make dst be the length that was sent
|
// Don't pre-allocate, l may be under attacker control
|
||||||
dst := make([]RR, 0, l)
|
var dst []RR
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
off1 := off
|
off1 := off
|
||||||
r, off, err = UnpackRR(msg, off)
|
r, off, err = UnpackRR(msg, off)
|
||||||
|
@ -710,12 +751,10 @@ func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
|
||||||
|
|
||||||
// We need the uncompressed length here, because we first pack it and then compress it.
|
// We need the uncompressed length here, because we first pack it and then compress it.
|
||||||
msg = buf
|
msg = buf
|
||||||
compress := dns.Compress
|
uncompressedLen := compressedLen(dns, false)
|
||||||
dns.Compress = false
|
if packLen := uncompressedLen + 1; len(msg) < packLen {
|
||||||
if packLen := dns.Len() + 1; len(msg) < packLen {
|
|
||||||
msg = make([]byte, packLen)
|
msg = make([]byte, packLen)
|
||||||
}
|
}
|
||||||
dns.Compress = compress
|
|
||||||
|
|
||||||
// Pack it in: header and then the pieces.
|
// Pack it in: header and then the pieces.
|
||||||
off := 0
|
off := 0
|
||||||
|
@ -772,13 +811,19 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
|
||||||
dns.CheckingDisabled = (dh.Bits & _CD) != 0
|
dns.CheckingDisabled = (dh.Bits & _CD) != 0
|
||||||
dns.Rcode = int(dh.Bits & 0xF)
|
dns.Rcode = int(dh.Bits & 0xF)
|
||||||
|
|
||||||
|
// If we are at the end of the message we should return *just* the
|
||||||
|
// header. This can still be useful to the caller. 9.9.9.9 sends these
|
||||||
|
// when responding with REFUSED for instance.
|
||||||
if off == len(msg) {
|
if off == len(msg) {
|
||||||
return ErrTruncated
|
// reset sections before returning
|
||||||
|
dns.Question, dns.Answer, dns.Ns, dns.Extra = nil, nil, nil, nil
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimistically use the count given to us in the header
|
// Qdcount, Ancount, Nscount, Arcount can't be trusted, as they are
|
||||||
dns.Question = make([]Question, 0, int(dh.Qdcount))
|
// attacker controlled. This means we can't use them to pre-allocate
|
||||||
|
// slices.
|
||||||
|
dns.Question = nil
|
||||||
for i := 0; i < int(dh.Qdcount); i++ {
|
for i := 0; i < int(dh.Qdcount); i++ {
|
||||||
off1 := off
|
off1 := off
|
||||||
var q Question
|
var q Question
|
||||||
|
@ -868,72 +913,62 @@ func (dns *Msg) String() string {
|
||||||
// If dns.Compress is true compression it is taken into account. Len()
|
// If dns.Compress is true compression it is taken into account. Len()
|
||||||
// is provided to be a faster way to get the size of the resulting packet,
|
// is provided to be a faster way to get the size of the resulting packet,
|
||||||
// than packing it, measuring the size and discarding the buffer.
|
// than packing it, measuring the size and discarding the buffer.
|
||||||
func (dns *Msg) Len() int {
|
func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) }
|
||||||
|
|
||||||
|
// compressedLen returns the message length when in compressed wire format
|
||||||
|
// when compress is true, otherwise the uncompressed length is returned.
|
||||||
|
func compressedLen(dns *Msg, compress bool) int {
|
||||||
// We always return one more than needed.
|
// We always return one more than needed.
|
||||||
l := 12 // Message header is always 12 bytes
|
l := 12 // Message header is always 12 bytes
|
||||||
var compression map[string]int
|
if compress {
|
||||||
if dns.Compress {
|
compression := map[string]int{}
|
||||||
compression = make(map[string]int)
|
for _, r := range dns.Question {
|
||||||
|
l += r.len()
|
||||||
|
compressionLenHelper(compression, r.Name)
|
||||||
}
|
}
|
||||||
for i := 0; i < len(dns.Question); i++ {
|
l += compressionLenSlice(compression, dns.Answer)
|
||||||
l += dns.Question[i].len()
|
l += compressionLenSlice(compression, dns.Ns)
|
||||||
if dns.Compress {
|
l += compressionLenSlice(compression, dns.Extra)
|
||||||
compressionLenHelper(compression, dns.Question[i].Name)
|
} else {
|
||||||
|
for _, r := range dns.Question {
|
||||||
|
l += r.len()
|
||||||
|
}
|
||||||
|
for _, r := range dns.Answer {
|
||||||
|
if r != nil {
|
||||||
|
l += r.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(dns.Answer); i++ {
|
for _, r := range dns.Ns {
|
||||||
if dns.Answer[i] == nil {
|
if r != nil {
|
||||||
|
l += r.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, r := range dns.Extra {
|
||||||
|
if r != nil {
|
||||||
|
l += r.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func compressionLenSlice(c map[string]int, rs []RR) int {
|
||||||
|
var l int
|
||||||
|
for _, r := range rs {
|
||||||
|
if r == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
l += dns.Answer[i].len()
|
l += r.len()
|
||||||
if dns.Compress {
|
k, ok := compressionLenSearch(c, r.Header().Name)
|
||||||
k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
|
|
||||||
if ok {
|
if ok {
|
||||||
l += 1 - k
|
l += 1 - k
|
||||||
}
|
}
|
||||||
compressionLenHelper(compression, dns.Answer[i].Header().Name)
|
compressionLenHelper(c, r.Header().Name)
|
||||||
k, ok = compressionLenSearchType(compression, dns.Answer[i])
|
k, ok = compressionLenSearchType(c, r)
|
||||||
if ok {
|
if ok {
|
||||||
l += 1 - k
|
l += 1 - k
|
||||||
}
|
}
|
||||||
compressionLenHelperType(compression, dns.Answer[i])
|
compressionLenHelperType(c, r)
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(dns.Ns); i++ {
|
|
||||||
if dns.Ns[i] == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
l += dns.Ns[i].len()
|
|
||||||
if dns.Compress {
|
|
||||||
k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
|
|
||||||
if ok {
|
|
||||||
l += 1 - k
|
|
||||||
}
|
|
||||||
compressionLenHelper(compression, dns.Ns[i].Header().Name)
|
|
||||||
k, ok = compressionLenSearchType(compression, dns.Ns[i])
|
|
||||||
if ok {
|
|
||||||
l += 1 - k
|
|
||||||
}
|
|
||||||
compressionLenHelperType(compression, dns.Ns[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(dns.Extra); i++ {
|
|
||||||
if dns.Extra[i] == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
l += dns.Extra[i].len()
|
|
||||||
if dns.Compress {
|
|
||||||
k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
|
|
||||||
if ok {
|
|
||||||
l += 1 - k
|
|
||||||
}
|
|
||||||
compressionLenHelper(compression, dns.Extra[i].Header().Name)
|
|
||||||
k, ok = compressionLenSearchType(compression, dns.Extra[i])
|
|
||||||
if ok {
|
|
||||||
l += 1 - k
|
|
||||||
}
|
|
||||||
compressionLenHelperType(compression, dns.Extra[i])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -970,97 +1005,6 @@ func compressionLenSearch(c map[string]int, s string) (int, bool) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(miek): should add all types, because the all can be *used* for compression. Autogenerate from msg_generate and put in zmsg.go
|
|
||||||
func compressionLenHelperType(c map[string]int, r RR) {
|
|
||||||
switch x := r.(type) {
|
|
||||||
case *NS:
|
|
||||||
compressionLenHelper(c, x.Ns)
|
|
||||||
case *MX:
|
|
||||||
compressionLenHelper(c, x.Mx)
|
|
||||||
case *CNAME:
|
|
||||||
compressionLenHelper(c, x.Target)
|
|
||||||
case *PTR:
|
|
||||||
compressionLenHelper(c, x.Ptr)
|
|
||||||
case *SOA:
|
|
||||||
compressionLenHelper(c, x.Ns)
|
|
||||||
compressionLenHelper(c, x.Mbox)
|
|
||||||
case *MB:
|
|
||||||
compressionLenHelper(c, x.Mb)
|
|
||||||
case *MG:
|
|
||||||
compressionLenHelper(c, x.Mg)
|
|
||||||
case *MR:
|
|
||||||
compressionLenHelper(c, x.Mr)
|
|
||||||
case *MF:
|
|
||||||
compressionLenHelper(c, x.Mf)
|
|
||||||
case *MD:
|
|
||||||
compressionLenHelper(c, x.Md)
|
|
||||||
case *RT:
|
|
||||||
compressionLenHelper(c, x.Host)
|
|
||||||
case *RP:
|
|
||||||
compressionLenHelper(c, x.Mbox)
|
|
||||||
compressionLenHelper(c, x.Txt)
|
|
||||||
case *MINFO:
|
|
||||||
compressionLenHelper(c, x.Rmail)
|
|
||||||
compressionLenHelper(c, x.Email)
|
|
||||||
case *AFSDB:
|
|
||||||
compressionLenHelper(c, x.Hostname)
|
|
||||||
case *SRV:
|
|
||||||
compressionLenHelper(c, x.Target)
|
|
||||||
case *NAPTR:
|
|
||||||
compressionLenHelper(c, x.Replacement)
|
|
||||||
case *RRSIG:
|
|
||||||
compressionLenHelper(c, x.SignerName)
|
|
||||||
case *NSEC:
|
|
||||||
compressionLenHelper(c, x.NextDomain)
|
|
||||||
// HIP?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only search on compressing these types.
|
|
||||||
func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
|
|
||||||
switch x := r.(type) {
|
|
||||||
case *NS:
|
|
||||||
return compressionLenSearch(c, x.Ns)
|
|
||||||
case *MX:
|
|
||||||
return compressionLenSearch(c, x.Mx)
|
|
||||||
case *CNAME:
|
|
||||||
return compressionLenSearch(c, x.Target)
|
|
||||||
case *DNAME:
|
|
||||||
return compressionLenSearch(c, x.Target)
|
|
||||||
case *PTR:
|
|
||||||
return compressionLenSearch(c, x.Ptr)
|
|
||||||
case *SOA:
|
|
||||||
k, ok := compressionLenSearch(c, x.Ns)
|
|
||||||
k1, ok1 := compressionLenSearch(c, x.Mbox)
|
|
||||||
if !ok && !ok1 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return k + k1, true
|
|
||||||
case *MB:
|
|
||||||
return compressionLenSearch(c, x.Mb)
|
|
||||||
case *MG:
|
|
||||||
return compressionLenSearch(c, x.Mg)
|
|
||||||
case *MR:
|
|
||||||
return compressionLenSearch(c, x.Mr)
|
|
||||||
case *MF:
|
|
||||||
return compressionLenSearch(c, x.Mf)
|
|
||||||
case *MD:
|
|
||||||
return compressionLenSearch(c, x.Md)
|
|
||||||
case *RT:
|
|
||||||
return compressionLenSearch(c, x.Host)
|
|
||||||
case *MINFO:
|
|
||||||
k, ok := compressionLenSearch(c, x.Rmail)
|
|
||||||
k1, ok1 := compressionLenSearch(c, x.Email)
|
|
||||||
if !ok && !ok1 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return k + k1, true
|
|
||||||
case *AFSDB:
|
|
||||||
return compressionLenSearch(c, x.Hostname)
|
|
||||||
}
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy returns a new RR which is a deep-copy of r.
|
// Copy returns a new RR which is a deep-copy of r.
|
||||||
func Copy(r RR) RR { r1 := r.copy(); return r1 }
|
func Copy(r RR) RR { r1 := r.copy(); return r1 }
|
||||||
|
|
||||||
|
|
16
vendor/github.com/miekg/dns/msg_generate.go
generated
vendored
16
vendor/github.com/miekg/dns/msg_generate.go
generated
vendored
|
@ -18,8 +18,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var packageHdr = `
|
var packageHdr = `
|
||||||
// *** DO NOT MODIFY ***
|
// Code generated by "go run msg_generate.go"; DO NOT EDIT.
|
||||||
// AUTOGENERATED BY go generate from msg_generate.go
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
|
@ -139,8 +138,17 @@ return off, err
|
||||||
case st.Tag(i) == `dns:"base64"`:
|
case st.Tag(i) == `dns:"base64"`:
|
||||||
o("off, err = packStringBase64(rr.%s, msg, off)\n")
|
o("off, err = packStringBase64(rr.%s, msg, off)\n")
|
||||||
|
|
||||||
case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`): // Hack to fix empty salt length for NSEC3
|
case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`):
|
||||||
o("if rr.%s == \"-\" { /* do nothing, empty salt */ }\n")
|
// directly write instead of using o() so we get the error check in the correct place
|
||||||
|
field := st.Field(i).Name()
|
||||||
|
fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty
|
||||||
|
if rr.%s != "-" {
|
||||||
|
off, err = packStringHex(rr.%s, msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, field, field)
|
||||||
continue
|
continue
|
||||||
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
|
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
19
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
19
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
|
@ -96,7 +96,7 @@ func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte,
|
||||||
return hdr, len(msg), msg, err
|
return hdr, len(msg), msg, err
|
||||||
}
|
}
|
||||||
msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
|
msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
|
||||||
return hdr, off, msg, nil
|
return hdr, off, msg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// pack packs an RR header, returning the offset to the end of the header.
|
// pack packs an RR header, returning the offset to the end of the header.
|
||||||
|
@ -142,6 +142,11 @@ func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []b
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromBase32(s []byte) (buf []byte, err error) {
|
func fromBase32(s []byte) (buf []byte, err error) {
|
||||||
|
for i, b := range s {
|
||||||
|
if b >= 'a' && b <= 'z' {
|
||||||
|
s[i] = b - 32
|
||||||
|
}
|
||||||
|
}
|
||||||
buflen := base32.HexEncoding.DecodedLen(len(s))
|
buflen := base32.HexEncoding.DecodedLen(len(s))
|
||||||
buf = make([]byte, buflen)
|
buf = make([]byte, buflen)
|
||||||
n, err := base32.HexEncoding.Decode(buf, s)
|
n, err := base32.HexEncoding.Decode(buf, s)
|
||||||
|
@ -401,16 +406,13 @@ Option:
|
||||||
}
|
}
|
||||||
edns = append(edns, e)
|
edns = append(edns, e)
|
||||||
off += int(optlen)
|
off += int(optlen)
|
||||||
case EDNS0SUBNET, EDNS0SUBNETDRAFT:
|
case EDNS0SUBNET:
|
||||||
e := new(EDNS0_SUBNET)
|
e := new(EDNS0_SUBNET)
|
||||||
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
||||||
return nil, len(msg), err
|
return nil, len(msg), err
|
||||||
}
|
}
|
||||||
edns = append(edns, e)
|
edns = append(edns, e)
|
||||||
off += int(optlen)
|
off += int(optlen)
|
||||||
if code == EDNS0SUBNETDRAFT {
|
|
||||||
e.DraftOption = true
|
|
||||||
}
|
|
||||||
case EDNS0COOKIE:
|
case EDNS0COOKIE:
|
||||||
e := new(EDNS0_COOKIE)
|
e := new(EDNS0_COOKIE)
|
||||||
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
||||||
|
@ -453,6 +455,13 @@ Option:
|
||||||
}
|
}
|
||||||
edns = append(edns, e)
|
edns = append(edns, e)
|
||||||
off += int(optlen)
|
off += int(optlen)
|
||||||
|
case EDNS0PADDING:
|
||||||
|
e := new(EDNS0_PADDING)
|
||||||
|
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
||||||
|
return nil, len(msg), err
|
||||||
|
}
|
||||||
|
edns = append(edns, e)
|
||||||
|
off += int(optlen)
|
||||||
default:
|
default:
|
||||||
e := new(EDNS0_LOCAL)
|
e := new(EDNS0_LOCAL)
|
||||||
e.Code = code
|
e.Code = code
|
||||||
|
|
74
vendor/github.com/miekg/dns/nsecx.go
generated
vendored
74
vendor/github.com/miekg/dns/nsecx.go
generated
vendored
|
@ -48,62 +48,50 @@ func HashName(label string, ha uint8, iter uint16, salt string) string {
|
||||||
return toBase32(nsec3)
|
return toBase32(nsec3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Denialer is an interface that should be implemented by types that are used to denial
|
// Cover returns true if a name is covered by the NSEC3 record
|
||||||
// answers in DNSSEC.
|
|
||||||
type Denialer interface {
|
|
||||||
// Cover will check if the (unhashed) name is being covered by this NSEC or NSEC3.
|
|
||||||
Cover(name string) bool
|
|
||||||
// Match will check if the ownername matches the (unhashed) name for this NSEC3 or NSEC3.
|
|
||||||
Match(name string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cover implements the Denialer interface.
|
|
||||||
func (rr *NSEC) Cover(name string) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match implements the Denialer interface.
|
|
||||||
func (rr *NSEC) Match(name string) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cover implements the Denialer interface.
|
|
||||||
func (rr *NSEC3) Cover(name string) bool {
|
func (rr *NSEC3) Cover(name string) bool {
|
||||||
// FIXME(miek): check if the zones match
|
nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
|
||||||
// FIXME(miek): check if we're not dealing with parent nsec3
|
owner := strings.ToUpper(rr.Hdr.Name)
|
||||||
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
|
labelIndices := Split(owner)
|
||||||
labels := Split(rr.Hdr.Name)
|
if len(labelIndices) < 2 {
|
||||||
if len(labels) < 2 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the dot
|
ownerHash := owner[:labelIndices[1]-1]
|
||||||
if hash == rr.NextDomain {
|
ownerZone := owner[labelIndices[1]:]
|
||||||
return false // empty interval
|
if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
|
||||||
}
|
|
||||||
if hash > rr.NextDomain { // last name, points to apex
|
|
||||||
// hname > hash
|
|
||||||
// hname > rr.NextDomain
|
|
||||||
// TODO(miek)
|
|
||||||
}
|
|
||||||
if hname <= hash {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if hname >= rr.NextDomain {
|
|
||||||
|
nextHash := rr.NextDomain
|
||||||
|
if ownerHash == nextHash { // empty interval
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if ownerHash > nextHash { // end of zone
|
||||||
|
if nameHash > ownerHash { // covered since there is nothing after ownerHash
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
return nameHash < nextHash // if nameHash is before beginning of zone it is covered
|
||||||
|
}
|
||||||
|
if nameHash < ownerHash { // nameHash is before ownerHash, not covered
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match implements the Denialer interface.
|
// Match returns true if a name matches the NSEC3 record
|
||||||
func (rr *NSEC3) Match(name string) bool {
|
func (rr *NSEC3) Match(name string) bool {
|
||||||
// FIXME(miek): Check if we are in the same zone
|
nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
|
||||||
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
|
owner := strings.ToUpper(rr.Hdr.Name)
|
||||||
labels := Split(rr.Hdr.Name)
|
labelIndices := Split(owner)
|
||||||
if len(labels) < 2 {
|
if len(labelIndices) < 2 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the .
|
ownerHash := owner[:labelIndices[1]-1]
|
||||||
if hash == hname {
|
ownerZone := owner[labelIndices[1]:]
|
||||||
|
if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if ownerHash == nameHash {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
4
vendor/github.com/miekg/dns/reverse.go
generated
vendored
4
vendor/github.com/miekg/dns/reverse.go
generated
vendored
|
@ -6,10 +6,10 @@ var StringToType = reverseInt16(TypeToString)
|
||||||
// StringToClass is the reverse of ClassToString, needed for string parsing.
|
// StringToClass is the reverse of ClassToString, needed for string parsing.
|
||||||
var StringToClass = reverseInt16(ClassToString)
|
var StringToClass = reverseInt16(ClassToString)
|
||||||
|
|
||||||
// Map of opcodes strings.
|
// StringToOpcode is a map of opcodes to strings.
|
||||||
var StringToOpcode = reverseInt(OpcodeToString)
|
var StringToOpcode = reverseInt(OpcodeToString)
|
||||||
|
|
||||||
// Map of rcodes strings.
|
// StringToRcode is a map of rcodes to strings.
|
||||||
var StringToRcode = reverseInt(RcodeToString)
|
var StringToRcode = reverseInt(RcodeToString)
|
||||||
|
|
||||||
// Reverse a map
|
// Reverse a map
|
||||||
|
|
2
vendor/github.com/miekg/dns/sanitize.go
generated
vendored
2
vendor/github.com/miekg/dns/sanitize.go
generated
vendored
|
@ -3,7 +3,7 @@ package dns
|
||||||
// Dedup removes identical RRs from rrs. It preserves the original ordering.
|
// Dedup removes identical RRs from rrs. It preserves the original ordering.
|
||||||
// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies
|
// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies
|
||||||
// rrs.
|
// rrs.
|
||||||
// m is used to store the RRs temporay. If it is nil a new map will be allocated.
|
// m is used to store the RRs temporary. If it is nil a new map will be allocated.
|
||||||
func Dedup(rrs []RR, m map[string]RR) []RR {
|
func Dedup(rrs []RR, m map[string]RR) []RR {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
m = make(map[string]RR)
|
m = make(map[string]RR)
|
||||||
|
|
236
vendor/github.com/miekg/dns/scan.go
generated
vendored
236
vendor/github.com/miekg/dns/scan.go
generated
vendored
|
@ -1,23 +1,14 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type debugging bool
|
|
||||||
|
|
||||||
const debug debugging = false
|
|
||||||
|
|
||||||
func (d debugging) Printf(format string, args ...interface{}) {
|
|
||||||
if d {
|
|
||||||
log.Printf(format, args...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxTok = 2048 // Largest token we can return.
|
const maxTok = 2048 // Largest token we can return.
|
||||||
const maxUint16 = 1<<16 - 1
|
const maxUint16 = 1<<16 - 1
|
||||||
|
|
||||||
|
@ -38,7 +29,7 @@ const (
|
||||||
zOwner
|
zOwner
|
||||||
zClass
|
zClass
|
||||||
zDirOrigin // $ORIGIN
|
zDirOrigin // $ORIGIN
|
||||||
zDirTtl // $TTL
|
zDirTTL // $TTL
|
||||||
zDirInclude // $INCLUDE
|
zDirInclude // $INCLUDE
|
||||||
zDirGenerate // $GENERATE
|
zDirGenerate // $GENERATE
|
||||||
|
|
||||||
|
@ -51,13 +42,13 @@ const (
|
||||||
zExpectAny // Expect rrtype, ttl or class
|
zExpectAny // Expect rrtype, ttl or class
|
||||||
zExpectAnyNoClass // Expect rrtype or ttl
|
zExpectAnyNoClass // Expect rrtype or ttl
|
||||||
zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
|
zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
|
||||||
zExpectAnyNoTtl // Expect rrtype or class
|
zExpectAnyNoTTL // Expect rrtype or class
|
||||||
zExpectAnyNoTtlBl // Whitespace after _EXPECT_ANY_NOTTL
|
zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL
|
||||||
zExpectRrtype // Expect rrtype
|
zExpectRrtype // Expect rrtype
|
||||||
zExpectRrtypeBl // Whitespace BEFORE rrtype
|
zExpectRrtypeBl // Whitespace BEFORE rrtype
|
||||||
zExpectRdata // The first element of the rdata
|
zExpectRdata // The first element of the rdata
|
||||||
zExpectDirTtlBl // Space after directive $TTL
|
zExpectDirTTLBl // Space after directive $TTL
|
||||||
zExpectDirTtl // Directive $TTL
|
zExpectDirTTL // Directive $TTL
|
||||||
zExpectDirOriginBl // Space after directive $ORIGIN
|
zExpectDirOriginBl // Space after directive $ORIGIN
|
||||||
zExpectDirOrigin // Directive $ORIGIN
|
zExpectDirOrigin // Directive $ORIGIN
|
||||||
zExpectDirIncludeBl // Space after directive $INCLUDE
|
zExpectDirIncludeBl // Space after directive $INCLUDE
|
||||||
|
@ -105,6 +96,12 @@ type Token struct {
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ttlState describes the state necessary to fill in an omitted RR TTL
|
||||||
|
type ttlState struct {
|
||||||
|
ttl uint32 // ttl is the current default TTL
|
||||||
|
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
||||||
|
}
|
||||||
|
|
||||||
// NewRR reads the RR contained in the string s. Only the first RR is
|
// NewRR reads the RR contained in the string s. Only the first RR is
|
||||||
// returned. If s contains no RR, return nil with no error. The class
|
// returned. If s contains no RR, return nil with no error. The class
|
||||||
// defaults to IN and TTL defaults to 3600. The full zone file syntax
|
// defaults to IN and TTL defaults to 3600. The full zone file syntax
|
||||||
|
@ -120,7 +117,8 @@ func NewRR(s string) (RR, error) {
|
||||||
// ReadRR reads the RR contained in q.
|
// ReadRR reads the RR contained in q.
|
||||||
// See NewRR for more documentation.
|
// See NewRR for more documentation.
|
||||||
func ReadRR(q io.Reader, filename string) (RR, error) {
|
func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||||
r := <-parseZoneHelper(q, ".", filename, 1)
|
defttl := &ttlState{defaultTtl, false}
|
||||||
|
r := <-parseZoneHelper(q, ".", filename, defttl, 1)
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -132,10 +130,10 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
|
// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
|
||||||
// returned channel, which consist out the parsed RR, a potential comment or an error.
|
// returned channel, each consisting of either a parsed RR and optional comment
|
||||||
// If there is an error the RR is nil. The string file is only used
|
// or a nil RR and an error. The string file is only used
|
||||||
// in error reporting. The string origin is used as the initial origin, as
|
// in error reporting. The string origin is used as the initial origin, as
|
||||||
// if the file would start with: $ORIGIN origin .
|
// if the file would start with an $ORIGIN directive.
|
||||||
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
|
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
|
||||||
// The channel t is closed by ParseZone when the end of r is reached.
|
// The channel t is closed by ParseZone when the end of r is reached.
|
||||||
//
|
//
|
||||||
|
@ -157,25 +155,37 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||||
// The text "; this is comment" is returned in Token.Comment. Comments inside the
|
// The text "; this is comment" is returned in Token.Comment. Comments inside the
|
||||||
// RR are discarded. Comments on a line by themselves are discarded too.
|
// RR are discarded. Comments on a line by themselves are discarded too.
|
||||||
func ParseZone(r io.Reader, origin, file string) chan *Token {
|
func ParseZone(r io.Reader, origin, file string) chan *Token {
|
||||||
return parseZoneHelper(r, origin, file, 10000)
|
return parseZoneHelper(r, origin, file, nil, 10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token {
|
func parseZoneHelper(r io.Reader, origin, file string, defttl *ttlState, chansize int) chan *Token {
|
||||||
t := make(chan *Token, chansize)
|
t := make(chan *Token, chansize)
|
||||||
go parseZone(r, origin, file, t, 0)
|
go parseZone(r, origin, file, defttl, t, 0)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
func parseZone(r io.Reader, origin, f string, defttl *ttlState, t chan *Token, include int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if include == 0 {
|
if include == 0 {
|
||||||
close(t)
|
close(t)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s := scanInit(r)
|
s, cancel := scanInit(r)
|
||||||
c := make(chan lex)
|
c := make(chan lex)
|
||||||
// Start the lexer
|
// Start the lexer
|
||||||
go zlexer(s, c)
|
go zlexer(s, c)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
// zlexer can send up to three tokens, the next one and possibly 2 remainders.
|
||||||
|
// Do a non-blocking read.
|
||||||
|
_, ok := <-c
|
||||||
|
_, ok = <-c
|
||||||
|
_, ok = <-c
|
||||||
|
if !ok {
|
||||||
|
// too bad
|
||||||
|
}
|
||||||
|
}()
|
||||||
// 6 possible beginnings of a line, _ is a space
|
// 6 possible beginnings of a line, _ is a space
|
||||||
// 0. zRRTYPE -> all omitted until the rrtype
|
// 0. zRRTYPE -> all omitted until the rrtype
|
||||||
// 1. zOwner _ zRrtype -> class/ttl omitted
|
// 1. zOwner _ zRrtype -> class/ttl omitted
|
||||||
|
@ -186,18 +196,16 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
// After detecting these, we know the zRrtype so we can jump to functions
|
// After detecting these, we know the zRrtype so we can jump to functions
|
||||||
// handling the rdata for each of these types.
|
// handling the rdata for each of these types.
|
||||||
|
|
||||||
if origin == "" {
|
if origin != "" {
|
||||||
origin = "."
|
|
||||||
}
|
|
||||||
origin = Fqdn(origin)
|
origin = Fqdn(origin)
|
||||||
if _, ok := IsDomainName(origin); !ok {
|
if _, ok := IsDomainName(origin); !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
st := zExpectOwnerDir // initial state
|
st := zExpectOwnerDir // initial state
|
||||||
var h RR_Header
|
var h RR_Header
|
||||||
var defttl uint32 = defaultTtl
|
|
||||||
var prevName string
|
var prevName string
|
||||||
for l := range c {
|
for l := range c {
|
||||||
// Lexer spotted an error already
|
// Lexer spotted an error already
|
||||||
|
@ -209,31 +217,25 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
switch st {
|
switch st {
|
||||||
case zExpectOwnerDir:
|
case zExpectOwnerDir:
|
||||||
// We can also expect a directive, like $TTL or $ORIGIN
|
// We can also expect a directive, like $TTL or $ORIGIN
|
||||||
h.Ttl = defttl
|
if defttl != nil {
|
||||||
|
h.Ttl = defttl.ttl
|
||||||
|
}
|
||||||
h.Class = ClassINET
|
h.Class = ClassINET
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case zNewline:
|
case zNewline:
|
||||||
st = zExpectOwnerDir
|
st = zExpectOwnerDir
|
||||||
case zOwner:
|
case zOwner:
|
||||||
h.Name = l.token
|
h.Name = l.token
|
||||||
if l.token[0] == '@' {
|
name, ok := toAbsoluteName(l.token, origin)
|
||||||
h.Name = origin
|
|
||||||
prevName = h.Name
|
|
||||||
st = zExpectOwnerBl
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if h.Name[l.length-1] != '.' {
|
|
||||||
h.Name = appendOrigin(h.Name, origin)
|
|
||||||
}
|
|
||||||
_, ok := IsDomainName(l.token)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "bad owner name", l}}
|
t <- &Token{Error: &ParseError{f, "bad owner name", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
h.Name = name
|
||||||
prevName = h.Name
|
prevName = h.Name
|
||||||
st = zExpectOwnerBl
|
st = zExpectOwnerBl
|
||||||
case zDirTtl:
|
case zDirTTL:
|
||||||
st = zExpectDirTtlBl
|
st = zExpectDirTTLBl
|
||||||
case zDirOrigin:
|
case zDirOrigin:
|
||||||
st = zExpectDirOriginBl
|
st = zExpectDirOriginBl
|
||||||
case zDirInclude:
|
case zDirInclude:
|
||||||
|
@ -252,15 +254,16 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
// Discard, can happen when there is nothing on the
|
// Discard, can happen when there is nothing on the
|
||||||
// line except the RR type
|
// line except the RR type
|
||||||
case zString:
|
case zString:
|
||||||
ttl, ok := stringToTtl(l.token)
|
ttl, ok := stringToTTL(l.token)
|
||||||
if !ok {
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.Ttl = ttl
|
h.Ttl = ttl
|
||||||
// Don't about the defttl, we should take the $TTL value
|
if defttl == nil || !defttl.isByDirective {
|
||||||
// defttl = ttl
|
defttl = &ttlState{ttl, false}
|
||||||
st = zExpectAnyNoTtlBl
|
}
|
||||||
|
st = zExpectAnyNoTTLBl
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}}
|
t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}}
|
||||||
|
@ -278,25 +281,16 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
|
neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
|
||||||
l := <-c
|
switch l := <-c; l.value {
|
||||||
switch l.value {
|
|
||||||
case zBlank:
|
case zBlank:
|
||||||
l := <-c
|
l := <-c
|
||||||
if l.value == zString {
|
if l.value == zString {
|
||||||
if _, ok := IsDomainName(l.token); !ok || l.length == 0 || l.err {
|
name, ok := toAbsoluteName(l.token, origin)
|
||||||
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// a new origin is specified.
|
neworigin = name
|
||||||
if l.token[l.length-1] != '.' {
|
|
||||||
if origin != "." { // Prevent .. endings
|
|
||||||
neworigin = l.token + "." + origin
|
|
||||||
} else {
|
|
||||||
neworigin = l.token + origin
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
neworigin = l.token
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case zNewline, zEOF:
|
case zNewline, zEOF:
|
||||||
// Ok
|
// Ok
|
||||||
|
@ -305,24 +299,32 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Start with the new file
|
// Start with the new file
|
||||||
r1, e1 := os.Open(l.token)
|
includePath := l.token
|
||||||
|
if !filepath.IsAbs(includePath) {
|
||||||
|
includePath = filepath.Join(filepath.Dir(f), includePath)
|
||||||
|
}
|
||||||
|
r1, e1 := os.Open(includePath)
|
||||||
if e1 != nil {
|
if e1 != nil {
|
||||||
t <- &Token{Error: &ParseError{f, "failed to open `" + l.token + "'", l}}
|
msg := fmt.Sprintf("failed to open `%s'", l.token)
|
||||||
|
if !filepath.IsAbs(l.token) {
|
||||||
|
msg += fmt.Sprintf(" as `%s'", includePath)
|
||||||
|
}
|
||||||
|
t <- &Token{Error: &ParseError{f, msg, l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if include+1 > 7 {
|
if include+1 > 7 {
|
||||||
t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
|
t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
parseZone(r1, l.token, neworigin, t, include+1)
|
parseZone(r1, neworigin, includePath, defttl, t, include+1)
|
||||||
st = zExpectOwnerDir
|
st = zExpectOwnerDir
|
||||||
case zExpectDirTtlBl:
|
case zExpectDirTTLBl:
|
||||||
if l.value != zBlank {
|
if l.value != zBlank {
|
||||||
t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}}
|
t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
st = zExpectDirTtl
|
st = zExpectDirTTL
|
||||||
case zExpectDirTtl:
|
case zExpectDirTTL:
|
||||||
if l.value != zString {
|
if l.value != zString {
|
||||||
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
||||||
return
|
return
|
||||||
|
@ -331,12 +333,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
t <- &Token{Error: e}
|
t <- &Token{Error: e}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ttl, ok := stringToTtl(l.token)
|
ttl, ok := stringToTTL(l.token)
|
||||||
if !ok {
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defttl = ttl
|
defttl = &ttlState{ttl, true}
|
||||||
st = zExpectOwnerDir
|
st = zExpectOwnerDir
|
||||||
case zExpectDirOriginBl:
|
case zExpectDirOriginBl:
|
||||||
if l.value != zBlank {
|
if l.value != zBlank {
|
||||||
|
@ -352,19 +354,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
if e, _ := slurpRemainder(c, f); e != nil {
|
if e, _ := slurpRemainder(c, f); e != nil {
|
||||||
t <- &Token{Error: e}
|
t <- &Token{Error: e}
|
||||||
}
|
}
|
||||||
if _, ok := IsDomainName(l.token); !ok {
|
name, ok := toAbsoluteName(l.token, origin)
|
||||||
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if l.token[l.length-1] != '.' {
|
origin = name
|
||||||
if origin != "." { // Prevent .. endings
|
|
||||||
origin = l.token + "." + origin
|
|
||||||
} else {
|
|
||||||
origin = l.token + origin
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
origin = l.token
|
|
||||||
}
|
|
||||||
st = zExpectOwnerDir
|
st = zExpectOwnerDir
|
||||||
case zExpectDirGenerateBl:
|
case zExpectDirGenerateBl:
|
||||||
if l.value != zBlank {
|
if l.value != zBlank {
|
||||||
|
@ -391,20 +386,26 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
case zExpectAny:
|
case zExpectAny:
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case zRrtpe:
|
case zRrtpe:
|
||||||
|
if defttl == nil {
|
||||||
|
t <- &Token{Error: &ParseError{f, "missing TTL with no previous value", l}}
|
||||||
|
return
|
||||||
|
}
|
||||||
h.Rrtype = l.torc
|
h.Rrtype = l.torc
|
||||||
st = zExpectRdata
|
st = zExpectRdata
|
||||||
case zClass:
|
case zClass:
|
||||||
h.Class = l.torc
|
h.Class = l.torc
|
||||||
st = zExpectAnyNoClassBl
|
st = zExpectAnyNoClassBl
|
||||||
case zString:
|
case zString:
|
||||||
ttl, ok := stringToTtl(l.token)
|
ttl, ok := stringToTTL(l.token)
|
||||||
if !ok {
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.Ttl = ttl
|
h.Ttl = ttl
|
||||||
// defttl = ttl // don't set the defttl here
|
if defttl == nil || !defttl.isByDirective {
|
||||||
st = zExpectAnyNoTtlBl
|
defttl = &ttlState{ttl, false}
|
||||||
|
}
|
||||||
|
st = zExpectAnyNoTTLBl
|
||||||
default:
|
default:
|
||||||
t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
|
t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
|
||||||
return
|
return
|
||||||
|
@ -415,13 +416,13 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
st = zExpectAnyNoClass
|
st = zExpectAnyNoClass
|
||||||
case zExpectAnyNoTtlBl:
|
case zExpectAnyNoTTLBl:
|
||||||
if l.value != zBlank {
|
if l.value != zBlank {
|
||||||
t <- &Token{Error: &ParseError{f, "no blank before TTL", l}}
|
t <- &Token{Error: &ParseError{f, "no blank before TTL", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
st = zExpectAnyNoTtl
|
st = zExpectAnyNoTTL
|
||||||
case zExpectAnyNoTtl:
|
case zExpectAnyNoTTL:
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case zClass:
|
case zClass:
|
||||||
h.Class = l.torc
|
h.Class = l.torc
|
||||||
|
@ -436,13 +437,15 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||||
case zExpectAnyNoClass:
|
case zExpectAnyNoClass:
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case zString:
|
case zString:
|
||||||
ttl, ok := stringToTtl(l.token)
|
ttl, ok := stringToTTL(l.token)
|
||||||
if !ok {
|
if !ok {
|
||||||
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
t <- &Token{Error: &ParseError{f, "not a TTL", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.Ttl = ttl
|
h.Ttl = ttl
|
||||||
// defttl = ttl // don't set the def ttl anymore
|
if defttl == nil || !defttl.isByDirective {
|
||||||
|
defttl = &ttlState{ttl, false}
|
||||||
|
}
|
||||||
st = zExpectRrtypeBl
|
st = zExpectRrtypeBl
|
||||||
case zRrtpe:
|
case zRrtpe:
|
||||||
h.Rrtype = l.torc
|
h.Rrtype = l.torc
|
||||||
|
@ -505,14 +508,12 @@ func zlexer(s *scan, c chan lex) {
|
||||||
if stri >= maxTok {
|
if stri >= maxTok {
|
||||||
l.token = "token length insufficient for parsing"
|
l.token = "token length insufficient for parsing"
|
||||||
l.err = true
|
l.err = true
|
||||||
debug.Printf("[%+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if comi >= maxTok {
|
if comi >= maxTok {
|
||||||
l.token = "comment length insufficient for parsing"
|
l.token = "comment length insufficient for parsing"
|
||||||
l.err = true
|
l.err = true
|
||||||
debug.Printf("[%+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -547,7 +548,7 @@ func zlexer(s *scan, c chan lex) {
|
||||||
// escape $... start with a \ not a $, so this will work
|
// escape $... start with a \ not a $, so this will work
|
||||||
switch l.tokenUpper {
|
switch l.tokenUpper {
|
||||||
case "$TTL":
|
case "$TTL":
|
||||||
l.value = zDirTtl
|
l.value = zDirTTL
|
||||||
case "$ORIGIN":
|
case "$ORIGIN":
|
||||||
l.value = zDirOrigin
|
l.value = zDirOrigin
|
||||||
case "$INCLUDE":
|
case "$INCLUDE":
|
||||||
|
@ -555,7 +556,6 @@ func zlexer(s *scan, c chan lex) {
|
||||||
case "$GENERATE":
|
case "$GENERATE":
|
||||||
l.value = zDirGenerate
|
l.value = zDirGenerate
|
||||||
}
|
}
|
||||||
debug.Printf("[7 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
} else {
|
} else {
|
||||||
l.value = zString
|
l.value = zString
|
||||||
|
@ -577,6 +577,7 @@ func zlexer(s *scan, c chan lex) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.value = zRrtpe
|
l.value = zRrtpe
|
||||||
|
rrtype = true
|
||||||
l.torc = t
|
l.torc = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,16 +598,14 @@ func zlexer(s *scan, c chan lex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug.Printf("[6 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
}
|
}
|
||||||
stri = 0
|
stri = 0
|
||||||
// I reverse space stuff here
|
|
||||||
if !space && !commt {
|
if !space && !commt {
|
||||||
l.value = zBlank
|
l.value = zBlank
|
||||||
l.token = " "
|
l.token = " "
|
||||||
l.length = 1
|
l.length = 1
|
||||||
debug.Printf("[5 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
}
|
}
|
||||||
owner = false
|
owner = false
|
||||||
|
@ -629,7 +628,6 @@ func zlexer(s *scan, c chan lex) {
|
||||||
l.token = string(str[:stri])
|
l.token = string(str[:stri])
|
||||||
l.tokenUpper = strings.ToUpper(l.token)
|
l.tokenUpper = strings.ToUpper(l.token)
|
||||||
l.length = stri
|
l.length = stri
|
||||||
debug.Printf("[4 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
stri = 0
|
stri = 0
|
||||||
}
|
}
|
||||||
|
@ -667,7 +665,6 @@ func zlexer(s *scan, c chan lex) {
|
||||||
l.tokenUpper = l.token
|
l.tokenUpper = l.token
|
||||||
l.length = 1
|
l.length = 1
|
||||||
l.comment = string(com[:comi])
|
l.comment = string(com[:comi])
|
||||||
debug.Printf("[3 %+v %+v]", l.token, l.comment)
|
|
||||||
c <- l
|
c <- l
|
||||||
l.comment = ""
|
l.comment = ""
|
||||||
comi = 0
|
comi = 0
|
||||||
|
@ -693,14 +690,12 @@ func zlexer(s *scan, c chan lex) {
|
||||||
rrtype = true
|
rrtype = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug.Printf("[2 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
}
|
}
|
||||||
l.value = zNewline
|
l.value = zNewline
|
||||||
l.token = "\n"
|
l.token = "\n"
|
||||||
l.tokenUpper = l.token
|
l.tokenUpper = l.token
|
||||||
l.length = 1
|
l.length = 1
|
||||||
debug.Printf("[1 %+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
stri = 0
|
stri = 0
|
||||||
commt = false
|
commt = false
|
||||||
|
@ -746,7 +741,6 @@ func zlexer(s *scan, c chan lex) {
|
||||||
l.tokenUpper = strings.ToUpper(l.token)
|
l.tokenUpper = strings.ToUpper(l.token)
|
||||||
l.length = stri
|
l.length = stri
|
||||||
|
|
||||||
debug.Printf("[%+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
stri = 0
|
stri = 0
|
||||||
}
|
}
|
||||||
|
@ -782,7 +776,6 @@ func zlexer(s *scan, c chan lex) {
|
||||||
l.token = "extra closing brace"
|
l.token = "extra closing brace"
|
||||||
l.tokenUpper = l.token
|
l.tokenUpper = l.token
|
||||||
l.err = true
|
l.err = true
|
||||||
debug.Printf("[%+v]", l.token)
|
|
||||||
c <- l
|
c <- l
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -808,7 +801,12 @@ func zlexer(s *scan, c chan lex) {
|
||||||
l.tokenUpper = strings.ToUpper(l.token)
|
l.tokenUpper = strings.ToUpper(l.token)
|
||||||
l.length = stri
|
l.length = stri
|
||||||
l.value = zString
|
l.value = zString
|
||||||
debug.Printf("[%+v]", l.token)
|
c <- l
|
||||||
|
}
|
||||||
|
if brace != 0 {
|
||||||
|
l.token = "unbalanced brace"
|
||||||
|
l.tokenUpper = l.token
|
||||||
|
l.err = true
|
||||||
c <- l
|
c <- l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,8 +817,8 @@ func classToInt(token string) (uint16, bool) {
|
||||||
if len(token) < offset+1 {
|
if len(token) < offset+1 {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
class, ok := strconv.Atoi(token[offset:])
|
class, err := strconv.ParseUint(token[offset:], 10, 16)
|
||||||
if ok != nil || class > maxUint16 {
|
if err != nil {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
return uint16(class), true
|
return uint16(class), true
|
||||||
|
@ -832,15 +830,15 @@ func typeToInt(token string) (uint16, bool) {
|
||||||
if len(token) < offset+1 {
|
if len(token) < offset+1 {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
typ, ok := strconv.Atoi(token[offset:])
|
typ, err := strconv.ParseUint(token[offset:], 10, 16)
|
||||||
if ok != nil || typ > maxUint16 {
|
if err != nil {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
return uint16(typ), true
|
return uint16(typ), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse things like 2w, 2m, etc, Return the time in seconds.
|
// stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds.
|
||||||
func stringToTtl(token string) (uint32, bool) {
|
func stringToTTL(token string) (uint32, bool) {
|
||||||
s := uint32(0)
|
s := uint32(0)
|
||||||
i := uint32(0)
|
i := uint32(0)
|
||||||
for _, c := range token {
|
for _, c := range token {
|
||||||
|
@ -913,6 +911,34 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toAbsoluteName(name, origin string) (absolute string, ok bool) {
|
||||||
|
// check for an explicit origin reference
|
||||||
|
if name == "@" {
|
||||||
|
// require a nonempty origin
|
||||||
|
if origin == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return origin, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// require a valid domain name
|
||||||
|
_, ok = IsDomainName(name)
|
||||||
|
if !ok || name == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if name is already absolute
|
||||||
|
if name[len(name)-1] == '.' {
|
||||||
|
return name, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// require a nonempty origin
|
||||||
|
if origin == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return appendOrigin(name, origin), true
|
||||||
|
}
|
||||||
|
|
||||||
func appendOrigin(name, origin string) string {
|
func appendOrigin(name, origin string) string {
|
||||||
if origin == "." {
|
if origin == "." {
|
||||||
return name + origin
|
return name + origin
|
||||||
|
|
808
vendor/github.com/miekg/dns/scan_rr.go
generated
vendored
808
vendor/github.com/miekg/dns/scan_rr.go
generated
vendored
File diff suppressed because it is too large
Load diff
17
vendor/github.com/miekg/dns/scanner.go
generated
vendored
17
vendor/github.com/miekg/dns/scanner.go
generated
vendored
|
@ -4,6 +4,7 @@ package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"text/scanner"
|
"text/scanner"
|
||||||
)
|
)
|
||||||
|
@ -12,13 +13,18 @@ type scan struct {
|
||||||
src *bufio.Reader
|
src *bufio.Reader
|
||||||
position scanner.Position
|
position scanner.Position
|
||||||
eof bool // Have we just seen a eof
|
eof bool // Have we just seen a eof
|
||||||
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanInit(r io.Reader) *scan {
|
func scanInit(r io.Reader) (*scan, context.CancelFunc) {
|
||||||
s := new(scan)
|
s := new(scan)
|
||||||
s.src = bufio.NewReader(r)
|
s.src = bufio.NewReader(r)
|
||||||
s.position.Line = 1
|
s.position.Line = 1
|
||||||
return s
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
s.ctx = ctx
|
||||||
|
|
||||||
|
return s, cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokenText returns the next byte from the input
|
// tokenText returns the next byte from the input
|
||||||
|
@ -27,6 +33,13 @@ func (s *scan) tokenText() (byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
case <-s.ctx.Done():
|
||||||
|
return c, context.Canceled
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// delay the newline handling until the next token is delivered,
|
// delay the newline handling until the next token is delivered,
|
||||||
// fixes off-by-one errors when reporting a parse error.
|
// fixes off-by-one errors when reporting a parse error.
|
||||||
if s.eof == true {
|
if s.eof == true {
|
||||||
|
|
57
vendor/github.com/miekg/dns/server.go
generated
vendored
57
vendor/github.com/miekg/dns/server.go
generated
vendored
|
@ -285,7 +285,7 @@ type Server struct {
|
||||||
WriteTimeout time.Duration
|
WriteTimeout time.Duration
|
||||||
// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
|
// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
|
||||||
IdleTimeout func() time.Duration
|
IdleTimeout func() time.Duration
|
||||||
// Secret(s) for Tsig map[<zonename>]<base64 secret>.
|
// Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
|
||||||
TsigSecret map[string]string
|
TsigSecret map[string]string
|
||||||
// Unsafe instructs the server to disregard any sanity checks and directly hand the message to
|
// Unsafe instructs the server to disregard any sanity checks and directly hand the message to
|
||||||
// the handler. It will specifically not check if the query has the QR bit not set.
|
// the handler. It will specifically not check if the query has the QR bit not set.
|
||||||
|
@ -297,10 +297,7 @@ type Server struct {
|
||||||
// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
|
// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
|
||||||
DecorateWriter DecorateWriter
|
DecorateWriter DecorateWriter
|
||||||
|
|
||||||
// Graceful shutdown handling
|
// Shutdown handling
|
||||||
|
|
||||||
inFlight sync.WaitGroup
|
|
||||||
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
started bool
|
started bool
|
||||||
}
|
}
|
||||||
|
@ -412,10 +409,8 @@ func (srv *Server) ActivateAndServe() error {
|
||||||
return &Error{err: "bad listeners"}
|
return &Error{err: "bad listeners"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown gracefully shuts down a server. After a call to Shutdown, ListenAndServe and
|
// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
|
||||||
// ActivateAndServe will return. All in progress queries are completed before the server
|
// ActivateAndServe will return.
|
||||||
// is taken down. If the Shutdown is taking longer than the reading timeout an error
|
|
||||||
// is returned.
|
|
||||||
func (srv *Server) Shutdown() error {
|
func (srv *Server) Shutdown() error {
|
||||||
srv.lock.Lock()
|
srv.lock.Lock()
|
||||||
if !srv.started {
|
if !srv.started {
|
||||||
|
@ -431,19 +426,7 @@ func (srv *Server) Shutdown() error {
|
||||||
if srv.Listener != nil {
|
if srv.Listener != nil {
|
||||||
srv.Listener.Close()
|
srv.Listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
fin := make(chan bool)
|
|
||||||
go func() {
|
|
||||||
srv.inFlight.Wait()
|
|
||||||
fin <- true
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(srv.getReadTimeout()):
|
|
||||||
return &Error{err: "server shutdown is pending"}
|
|
||||||
case <-fin:
|
|
||||||
return nil
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
|
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
|
||||||
|
@ -477,13 +460,6 @@ func (srv *Server) serveTCP(l net.Listener) error {
|
||||||
// deadline is not used here
|
// deadline is not used here
|
||||||
for {
|
for {
|
||||||
rw, err := l.Accept()
|
rw, err := l.Accept()
|
||||||
if err != nil {
|
|
||||||
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m, err := reader.ReadTCP(rw, rtimeout)
|
|
||||||
srv.lock.RLock()
|
srv.lock.RLock()
|
||||||
if !srv.started {
|
if !srv.started {
|
||||||
srv.lock.RUnlock()
|
srv.lock.RUnlock()
|
||||||
|
@ -491,10 +467,19 @@ func (srv *Server) serveTCP(l net.Listener) error {
|
||||||
}
|
}
|
||||||
srv.lock.RUnlock()
|
srv.lock.RUnlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
srv.inFlight.Add(1)
|
return err
|
||||||
go srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
|
}
|
||||||
|
go func() {
|
||||||
|
m, err := reader.ReadTCP(rw, rtimeout)
|
||||||
|
if err != nil {
|
||||||
|
rw.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,17 +512,20 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
|
||||||
}
|
}
|
||||||
srv.lock.RUnlock()
|
srv.lock.RUnlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(m) < headerSize {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
srv.inFlight.Add(1)
|
|
||||||
go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
|
go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve a new connection.
|
// Serve a new connection.
|
||||||
func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) {
|
func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) {
|
||||||
defer srv.inFlight.Done()
|
|
||||||
|
|
||||||
w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
|
w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
|
||||||
if srv.DecorateWriter != nil {
|
if srv.DecorateWriter != nil {
|
||||||
w.writer = srv.DecorateWriter(w)
|
w.writer = srv.DecorateWriter(w)
|
||||||
|
@ -647,12 +635,9 @@ func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *S
|
||||||
conn.SetReadDeadline(time.Now().Add(timeout))
|
conn.SetReadDeadline(time.Now().Add(timeout))
|
||||||
m := make([]byte, srv.UDPSize)
|
m := make([]byte, srv.UDPSize)
|
||||||
n, s, err := ReadFromSessionUDP(conn, m)
|
n, s, err := ReadFromSessionUDP(conn, m)
|
||||||
if err != nil || n == 0 {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return nil, nil, ErrShortRead
|
|
||||||
}
|
|
||||||
m = m[:n]
|
m = m[:n]
|
||||||
return m, s, nil
|
return m, s, nil
|
||||||
}
|
}
|
||||||
|
|
8
vendor/github.com/miekg/dns/smimea.go
generated
vendored
8
vendor/github.com/miekg/dns/smimea.go
generated
vendored
|
@ -33,15 +33,15 @@ func (r *SMIMEA) Verify(cert *x509.Certificate) error {
|
||||||
return ErrSig // ErrSig, really?
|
return ErrSig // ErrSig, really?
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIMEAName returns the ownername of a SMIMEA resource record as per the
|
// SMIMEAName returns the ownername of a SMIMEA resource record as per the
|
||||||
// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
|
// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
|
||||||
func SMIMEAName(email_address string, domain_name string) (string, error) {
|
func SMIMEAName(email, domain string) (string, error) {
|
||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
hasher.Write([]byte(email_address))
|
hasher.Write([]byte(email))
|
||||||
|
|
||||||
// RFC Section 3: "The local-part is hashed using the SHA2-256
|
// RFC Section 3: "The local-part is hashed using the SHA2-256
|
||||||
// algorithm with the hash truncated to 28 octets and
|
// algorithm with the hash truncated to 28 octets and
|
||||||
// represented in its hexadecimal representation to become the
|
// represented in its hexadecimal representation to become the
|
||||||
// left-most label in the prepared domain name"
|
// left-most label in the prepared domain name"
|
||||||
return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain_name, nil
|
return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil
|
||||||
}
|
}
|
||||||
|
|
3
vendor/github.com/miekg/dns/tsig.go
generated
vendored
3
vendor/github.com/miekg/dns/tsig.go
generated
vendored
|
@ -208,6 +208,9 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
|
||||||
rr.Fudge = 300 // Standard (RFC) default.
|
rr.Fudge = 300 // Standard (RFC) default.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace message ID in header with original ID from TSIG
|
||||||
|
binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId)
|
||||||
|
|
||||||
if requestMAC != "" {
|
if requestMAC != "" {
|
||||||
m := new(macWireFmt)
|
m := new(macWireFmt)
|
||||||
m.MACSize = uint16(len(requestMAC) / 2)
|
m.MACSize = uint16(len(requestMAC) / 2)
|
||||||
|
|
178
vendor/github.com/miekg/dns/types.go
generated
vendored
178
vendor/github.com/miekg/dns/types.go
generated
vendored
|
@ -78,6 +78,7 @@ const (
|
||||||
TypeCDS uint16 = 59
|
TypeCDS uint16 = 59
|
||||||
TypeCDNSKEY uint16 = 60
|
TypeCDNSKEY uint16 = 60
|
||||||
TypeOPENPGPKEY uint16 = 61
|
TypeOPENPGPKEY uint16 = 61
|
||||||
|
TypeCSYNC uint16 = 62
|
||||||
TypeSPF uint16 = 99
|
TypeSPF uint16 = 99
|
||||||
TypeUINFO uint16 = 100
|
TypeUINFO uint16 = 100
|
||||||
TypeUID uint16 = 101
|
TypeUID uint16 = 101
|
||||||
|
@ -91,6 +92,7 @@ const (
|
||||||
TypeEUI64 uint16 = 109
|
TypeEUI64 uint16 = 109
|
||||||
TypeURI uint16 = 256
|
TypeURI uint16 = 256
|
||||||
TypeCAA uint16 = 257
|
TypeCAA uint16 = 257
|
||||||
|
TypeAVC uint16 = 258
|
||||||
|
|
||||||
TypeTKEY uint16 = 249
|
TypeTKEY uint16 = 249
|
||||||
TypeTSIG uint16 = 250
|
TypeTSIG uint16 = 250
|
||||||
|
@ -114,27 +116,27 @@ const (
|
||||||
ClassNONE = 254
|
ClassNONE = 254
|
||||||
ClassANY = 255
|
ClassANY = 255
|
||||||
|
|
||||||
// Message Response Codes.
|
// Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
|
||||||
RcodeSuccess = 0
|
RcodeSuccess = 0 // NoError - No Error [DNS]
|
||||||
RcodeFormatError = 1
|
RcodeFormatError = 1 // FormErr - Format Error [DNS]
|
||||||
RcodeServerFailure = 2
|
RcodeServerFailure = 2 // ServFail - Server Failure [DNS]
|
||||||
RcodeNameError = 3
|
RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS]
|
||||||
RcodeNotImplemented = 4
|
RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS]
|
||||||
RcodeRefused = 5
|
RcodeRefused = 5 // Refused - Query Refused [DNS]
|
||||||
RcodeYXDomain = 6
|
RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update]
|
||||||
RcodeYXRrset = 7
|
RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update]
|
||||||
RcodeNXRrset = 8
|
RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update]
|
||||||
RcodeNotAuth = 9
|
RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update]
|
||||||
RcodeNotZone = 10
|
RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG]
|
||||||
RcodeBadSig = 16 // TSIG
|
RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG]
|
||||||
RcodeBadVers = 16 // EDNS0
|
RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0]
|
||||||
RcodeBadKey = 17
|
RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG]
|
||||||
RcodeBadTime = 18
|
RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG]
|
||||||
RcodeBadMode = 19 // TKEY
|
RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY]
|
||||||
RcodeBadName = 20
|
RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY]
|
||||||
RcodeBadAlg = 21
|
RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY]
|
||||||
RcodeBadTrunc = 22 // TSIG
|
RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG]
|
||||||
RcodeBadCookie = 23 // DNS Cookies
|
RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies]
|
||||||
|
|
||||||
// Message Opcodes. There is no 3.
|
// Message Opcodes. There is no 3.
|
||||||
OpcodeQuery = 0
|
OpcodeQuery = 0
|
||||||
|
@ -144,7 +146,7 @@ const (
|
||||||
OpcodeUpdate = 5
|
OpcodeUpdate = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// Headers is the wire format for the DNS packet header.
|
// Header is the wire format for the DNS packet header.
|
||||||
type Header struct {
|
type Header struct {
|
||||||
Id uint16
|
Id uint16
|
||||||
Bits uint16
|
Bits uint16
|
||||||
|
@ -163,13 +165,14 @@ const (
|
||||||
_Z = 1 << 6 // Z
|
_Z = 1 << 6 // Z
|
||||||
_AD = 1 << 5 // authticated data
|
_AD = 1 << 5 // authticated data
|
||||||
_CD = 1 << 4 // checking disabled
|
_CD = 1 << 4 // checking disabled
|
||||||
|
)
|
||||||
|
|
||||||
|
// Various constants used in the LOC RR, See RFC 1887.
|
||||||
|
const (
|
||||||
LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
|
LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
|
||||||
LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
|
LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
|
||||||
|
|
||||||
LOC_HOURS = 60 * 1000
|
LOC_HOURS = 60 * 1000
|
||||||
LOC_DEGREES = 60 * LOC_HOURS
|
LOC_DEGREES = 60 * LOC_HOURS
|
||||||
|
|
||||||
LOC_ALTITUDEBASE = 100000
|
LOC_ALTITUDEBASE = 100000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -236,6 +239,7 @@ type ANY struct {
|
||||||
|
|
||||||
func (rr *ANY) String() string { return rr.Hdr.String() }
|
func (rr *ANY) String() string { return rr.Hdr.String() }
|
||||||
|
|
||||||
|
// CNAME RR. See RFC 1034.
|
||||||
type CNAME struct {
|
type CNAME struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Target string `dns:"cdomain-name"`
|
Target string `dns:"cdomain-name"`
|
||||||
|
@ -243,6 +247,7 @@ type CNAME struct {
|
||||||
|
|
||||||
func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) }
|
func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) }
|
||||||
|
|
||||||
|
// HINFO RR. See RFC 1034.
|
||||||
type HINFO struct {
|
type HINFO struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Cpu string
|
Cpu string
|
||||||
|
@ -253,6 +258,7 @@ func (rr *HINFO) String() string {
|
||||||
return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os})
|
return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MB RR. See RFC 1035.
|
||||||
type MB struct {
|
type MB struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mb string `dns:"cdomain-name"`
|
Mb string `dns:"cdomain-name"`
|
||||||
|
@ -260,6 +266,7 @@ type MB struct {
|
||||||
|
|
||||||
func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) }
|
func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) }
|
||||||
|
|
||||||
|
// MG RR. See RFC 1035.
|
||||||
type MG struct {
|
type MG struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mg string `dns:"cdomain-name"`
|
Mg string `dns:"cdomain-name"`
|
||||||
|
@ -267,6 +274,7 @@ type MG struct {
|
||||||
|
|
||||||
func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
|
func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
|
||||||
|
|
||||||
|
// MINFO RR. See RFC 1035.
|
||||||
type MINFO struct {
|
type MINFO struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Rmail string `dns:"cdomain-name"`
|
Rmail string `dns:"cdomain-name"`
|
||||||
|
@ -277,6 +285,7 @@ func (rr *MINFO) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
|
return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MR RR. See RFC 1035.
|
||||||
type MR struct {
|
type MR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mr string `dns:"cdomain-name"`
|
Mr string `dns:"cdomain-name"`
|
||||||
|
@ -286,6 +295,7 @@ func (rr *MR) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Mr)
|
return rr.Hdr.String() + sprintName(rr.Mr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MF RR. See RFC 1035.
|
||||||
type MF struct {
|
type MF struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mf string `dns:"cdomain-name"`
|
Mf string `dns:"cdomain-name"`
|
||||||
|
@ -295,6 +305,7 @@ func (rr *MF) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Mf)
|
return rr.Hdr.String() + sprintName(rr.Mf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MD RR. See RFC 1035.
|
||||||
type MD struct {
|
type MD struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Md string `dns:"cdomain-name"`
|
Md string `dns:"cdomain-name"`
|
||||||
|
@ -304,6 +315,7 @@ func (rr *MD) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Md)
|
return rr.Hdr.String() + sprintName(rr.Md)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MX RR. See RFC 1035.
|
||||||
type MX struct {
|
type MX struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -314,6 +326,7 @@ func (rr *MX) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AFSDB RR. See RFC 1183.
|
||||||
type AFSDB struct {
|
type AFSDB struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Subtype uint16
|
Subtype uint16
|
||||||
|
@ -324,6 +337,7 @@ func (rr *AFSDB) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X25 RR. See RFC 1183, Section 3.1.
|
||||||
type X25 struct {
|
type X25 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
PSDNAddress string
|
PSDNAddress string
|
||||||
|
@ -333,6 +347,7 @@ func (rr *X25) String() string {
|
||||||
return rr.Hdr.String() + rr.PSDNAddress
|
return rr.Hdr.String() + rr.PSDNAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RT RR. See RFC 1183, Section 3.3.
|
||||||
type RT struct {
|
type RT struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -343,6 +358,7 @@ func (rr *RT) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NS RR. See RFC 1035.
|
||||||
type NS struct {
|
type NS struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ns string `dns:"cdomain-name"`
|
Ns string `dns:"cdomain-name"`
|
||||||
|
@ -352,6 +368,7 @@ func (rr *NS) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Ns)
|
return rr.Hdr.String() + sprintName(rr.Ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PTR RR. See RFC 1035.
|
||||||
type PTR struct {
|
type PTR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ptr string `dns:"cdomain-name"`
|
Ptr string `dns:"cdomain-name"`
|
||||||
|
@ -361,6 +378,7 @@ func (rr *PTR) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Ptr)
|
return rr.Hdr.String() + sprintName(rr.Ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RP RR. See RFC 1138, Section 2.2.
|
||||||
type RP struct {
|
type RP struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mbox string `dns:"domain-name"`
|
Mbox string `dns:"domain-name"`
|
||||||
|
@ -371,6 +389,7 @@ func (rr *RP) String() string {
|
||||||
return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
|
return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SOA RR. See RFC 1035.
|
||||||
type SOA struct {
|
type SOA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ns string `dns:"cdomain-name"`
|
Ns string `dns:"cdomain-name"`
|
||||||
|
@ -391,6 +410,7 @@ func (rr *SOA) String() string {
|
||||||
" " + strconv.FormatInt(int64(rr.Minttl), 10)
|
" " + strconv.FormatInt(int64(rr.Minttl), 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TXT RR. See RFC 1035.
|
||||||
type TXT struct {
|
type TXT struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Txt []string `dns:"txt"`
|
Txt []string `dns:"txt"`
|
||||||
|
@ -523,6 +543,7 @@ func nextByte(b []byte, offset int) (byte, int) {
|
||||||
return b[offset+1], 2
|
return b[offset+1], 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPF RR. See RFC 4408, Section 3.1.1.
|
||||||
type SPF struct {
|
type SPF struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Txt []string `dns:"txt"`
|
Txt []string `dns:"txt"`
|
||||||
|
@ -530,6 +551,15 @@ type SPF struct {
|
||||||
|
|
||||||
func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
|
func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
|
||||||
|
|
||||||
|
// AVC RR. See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template.
|
||||||
|
type AVC struct {
|
||||||
|
Hdr RR_Header
|
||||||
|
Txt []string `dns:"txt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
|
||||||
|
|
||||||
|
// SRV RR. See RFC 2782.
|
||||||
type SRV struct {
|
type SRV struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Priority uint16
|
Priority uint16
|
||||||
|
@ -545,6 +575,7 @@ func (rr *SRV) String() string {
|
||||||
strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
|
strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NAPTR RR. See RFC 2915.
|
||||||
type NAPTR struct {
|
type NAPTR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Order uint16
|
Order uint16
|
||||||
|
@ -565,7 +596,7 @@ func (rr *NAPTR) String() string {
|
||||||
rr.Replacement
|
rr.Replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
// The CERT resource record, see RFC 4398.
|
// CERT RR. See RFC 4398.
|
||||||
type CERT struct {
|
type CERT struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Type uint16
|
Type uint16
|
||||||
|
@ -591,7 +622,7 @@ func (rr *CERT) String() string {
|
||||||
" " + rr.Certificate
|
" " + rr.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// The DNAME resource record, see RFC 2672.
|
// DNAME RR. See RFC 2672.
|
||||||
type DNAME struct {
|
type DNAME struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Target string `dns:"domain-name"`
|
Target string `dns:"domain-name"`
|
||||||
|
@ -601,6 +632,7 @@ func (rr *DNAME) String() string {
|
||||||
return rr.Hdr.String() + sprintName(rr.Target)
|
return rr.Hdr.String() + sprintName(rr.Target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A RR. See RFC 1035.
|
||||||
type A struct {
|
type A struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
A net.IP `dns:"a"`
|
A net.IP `dns:"a"`
|
||||||
|
@ -613,6 +645,7 @@ func (rr *A) String() string {
|
||||||
return rr.Hdr.String() + rr.A.String()
|
return rr.Hdr.String() + rr.A.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AAAA RR. See RFC 3596.
|
||||||
type AAAA struct {
|
type AAAA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
AAAA net.IP `dns:"aaaa"`
|
AAAA net.IP `dns:"aaaa"`
|
||||||
|
@ -625,6 +658,7 @@ func (rr *AAAA) String() string {
|
||||||
return rr.Hdr.String() + rr.AAAA.String()
|
return rr.Hdr.String() + rr.AAAA.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PX RR. See RFC 2163.
|
||||||
type PX struct {
|
type PX struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -636,6 +670,7 @@ func (rr *PX) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GPOS RR. See RFC 1712.
|
||||||
type GPOS struct {
|
type GPOS struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Longitude string
|
Longitude string
|
||||||
|
@ -647,6 +682,7 @@ func (rr *GPOS) String() string {
|
||||||
return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
|
return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LOC RR. See RFC RFC 1876.
|
||||||
type LOC struct {
|
type LOC struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Version uint8
|
Version uint8
|
||||||
|
@ -723,11 +759,12 @@ func (rr *LOC) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIG is identical to RRSIG and nowadays only used for SIG(0), RFC2931.
|
// SIG RR. See RFC 2535. The SIG RR is identical to RRSIG and nowadays only used for SIG(0), See RFC 2931.
|
||||||
type SIG struct {
|
type SIG struct {
|
||||||
RRSIG
|
RRSIG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RRSIG RR. See RFC 4034 and RFC 3755.
|
||||||
type RRSIG struct {
|
type RRSIG struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
TypeCovered uint16
|
TypeCovered uint16
|
||||||
|
@ -755,6 +792,7 @@ func (rr *RRSIG) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSEC RR. See RFC 4034 and RFC 3755.
|
||||||
type NSEC struct {
|
type NSEC struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
NextDomain string `dns:"domain-name"`
|
NextDomain string `dns:"domain-name"`
|
||||||
|
@ -782,14 +820,13 @@ func (rr *NSEC) len() int {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
type DLV struct {
|
// DLV RR. See RFC 4431.
|
||||||
DS
|
type DLV struct{ DS }
|
||||||
}
|
|
||||||
|
|
||||||
type CDS struct {
|
// CDS RR. See RFC 7344.
|
||||||
DS
|
type CDS struct{ DS }
|
||||||
}
|
|
||||||
|
|
||||||
|
// DS RR. See RFC 4034 and RFC 3658.
|
||||||
type DS struct {
|
type DS struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
KeyTag uint16
|
KeyTag uint16
|
||||||
|
@ -805,6 +842,7 @@ func (rr *DS) String() string {
|
||||||
" " + strings.ToUpper(rr.Digest)
|
" " + strings.ToUpper(rr.Digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KX RR. See RFC 2230.
|
||||||
type KX struct {
|
type KX struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -816,6 +854,7 @@ func (rr *KX) String() string {
|
||||||
" " + sprintName(rr.Exchanger)
|
" " + sprintName(rr.Exchanger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TA RR. See http://www.watson.org/~weiler/INI1999-19.pdf.
|
||||||
type TA struct {
|
type TA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
KeyTag uint16
|
KeyTag uint16
|
||||||
|
@ -831,6 +870,7 @@ func (rr *TA) String() string {
|
||||||
" " + strings.ToUpper(rr.Digest)
|
" " + strings.ToUpper(rr.Digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TALINK RR. See https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template.
|
||||||
type TALINK struct {
|
type TALINK struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
PreviousName string `dns:"domain-name"`
|
PreviousName string `dns:"domain-name"`
|
||||||
|
@ -842,6 +882,7 @@ func (rr *TALINK) String() string {
|
||||||
sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
|
sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SSHFP RR. See RFC RFC 4255.
|
||||||
type SSHFP struct {
|
type SSHFP struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Algorithm uint8
|
Algorithm uint8
|
||||||
|
@ -855,14 +896,17 @@ func (rr *SSHFP) String() string {
|
||||||
" " + strings.ToUpper(rr.FingerPrint)
|
" " + strings.ToUpper(rr.FingerPrint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KEY RR. See RFC RFC 2535.
|
||||||
type KEY struct {
|
type KEY struct {
|
||||||
DNSKEY
|
DNSKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CDNSKEY RR. See RFC 7344.
|
||||||
type CDNSKEY struct {
|
type CDNSKEY struct {
|
||||||
DNSKEY
|
DNSKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DNSKEY RR. See RFC 4034 and RFC 3755.
|
||||||
type DNSKEY struct {
|
type DNSKEY struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Flags uint16
|
Flags uint16
|
||||||
|
@ -878,6 +922,7 @@ func (rr *DNSKEY) String() string {
|
||||||
" " + rr.PublicKey
|
" " + rr.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template.
|
||||||
type RKEY struct {
|
type RKEY struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Flags uint16
|
Flags uint16
|
||||||
|
@ -893,6 +938,7 @@ func (rr *RKEY) String() string {
|
||||||
" " + rr.PublicKey
|
" " + rr.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSAPPTR RR. See RFC 1348.
|
||||||
type NSAPPTR struct {
|
type NSAPPTR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ptr string `dns:"domain-name"`
|
Ptr string `dns:"domain-name"`
|
||||||
|
@ -900,6 +946,7 @@ type NSAPPTR struct {
|
||||||
|
|
||||||
func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
|
func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
|
||||||
|
|
||||||
|
// NSEC3 RR. See RFC 5155.
|
||||||
type NSEC3 struct {
|
type NSEC3 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Hash uint8
|
Hash uint8
|
||||||
|
@ -938,6 +985,7 @@ func (rr *NSEC3) len() int {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSEC3PARAM RR. See RFC 5155.
|
||||||
type NSEC3PARAM struct {
|
type NSEC3PARAM struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Hash uint8
|
Hash uint8
|
||||||
|
@ -956,6 +1004,7 @@ func (rr *NSEC3PARAM) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TKEY RR. See RFC 2930.
|
||||||
type TKEY struct {
|
type TKEY struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Algorithm string `dns:"domain-name"`
|
Algorithm string `dns:"domain-name"`
|
||||||
|
@ -964,17 +1013,21 @@ type TKEY struct {
|
||||||
Mode uint16
|
Mode uint16
|
||||||
Error uint16
|
Error uint16
|
||||||
KeySize uint16
|
KeySize uint16
|
||||||
Key string
|
Key string `dns:"size-hex:KeySize"`
|
||||||
OtherLen uint16
|
OtherLen uint16
|
||||||
OtherData string
|
OtherData string `dns:"size-hex:OtherLen"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TKEY has no official presentation format, but this will suffice.
|
||||||
func (rr *TKEY) String() string {
|
func (rr *TKEY) String() string {
|
||||||
// It has no presentation format
|
s := "\n;; TKEY PSEUDOSECTION:\n"
|
||||||
return ""
|
s += rr.Hdr.String() + " " + rr.Algorithm + " " +
|
||||||
|
strconv.Itoa(int(rr.KeySize)) + " " + rr.Key + " " +
|
||||||
|
strconv.Itoa(int(rr.OtherLen)) + " " + rr.OtherData
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC3597 represents an unknown/generic RR.
|
// RFC3597 represents an unknown/generic RR. See RFC 3597.
|
||||||
type RFC3597 struct {
|
type RFC3597 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Rdata string `dns:"hex"`
|
Rdata string `dns:"hex"`
|
||||||
|
@ -998,6 +1051,7 @@ func rfc3597Header(h RR_Header) string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URI RR. See RFC 7553.
|
||||||
type URI struct {
|
type URI struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Priority uint16
|
Priority uint16
|
||||||
|
@ -1010,6 +1064,7 @@ func (rr *URI) String() string {
|
||||||
" " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target)
|
" " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DHCID RR. See RFC 4701.
|
||||||
type DHCID struct {
|
type DHCID struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Digest string `dns:"base64"`
|
Digest string `dns:"base64"`
|
||||||
|
@ -1017,6 +1072,7 @@ type DHCID struct {
|
||||||
|
|
||||||
func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
|
func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
|
||||||
|
|
||||||
|
// TLSA RR. See RFC 6698.
|
||||||
type TLSA struct {
|
type TLSA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Usage uint8
|
Usage uint8
|
||||||
|
@ -1033,6 +1089,7 @@ func (rr *TLSA) String() string {
|
||||||
" " + rr.Certificate
|
" " + rr.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SMIMEA RR. See RFC 8162.
|
||||||
type SMIMEA struct {
|
type SMIMEA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Usage uint8
|
Usage uint8
|
||||||
|
@ -1055,6 +1112,7 @@ func (rr *SMIMEA) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HIP RR. See RFC 8005.
|
||||||
type HIP struct {
|
type HIP struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
HitLength uint8
|
HitLength uint8
|
||||||
|
@ -1076,6 +1134,7 @@ func (rr *HIP) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NINFO RR. See https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template.
|
||||||
type NINFO struct {
|
type NINFO struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
ZSData []string `dns:"txt"`
|
ZSData []string `dns:"txt"`
|
||||||
|
@ -1083,6 +1142,7 @@ type NINFO struct {
|
||||||
|
|
||||||
func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
|
func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
|
||||||
|
|
||||||
|
// NID RR. See RFC RFC 6742.
|
||||||
type NID struct {
|
type NID struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -1096,6 +1156,7 @@ func (rr *NID) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L32 RR, See RFC 6742.
|
||||||
type L32 struct {
|
type L32 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -1110,6 +1171,7 @@ func (rr *L32) String() string {
|
||||||
" " + rr.Locator32.String()
|
" " + rr.Locator32.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L64 RR, See RFC 6742.
|
||||||
type L64 struct {
|
type L64 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -1123,6 +1185,7 @@ func (rr *L64) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LP RR. See RFC 6742.
|
||||||
type LP struct {
|
type LP struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Preference uint16
|
Preference uint16
|
||||||
|
@ -1133,6 +1196,7 @@ func (rr *LP) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EUI48 RR. See RFC 7043.
|
||||||
type EUI48 struct {
|
type EUI48 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Address uint64 `dns:"uint48"`
|
Address uint64 `dns:"uint48"`
|
||||||
|
@ -1140,6 +1204,7 @@ type EUI48 struct {
|
||||||
|
|
||||||
func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
|
func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
|
||||||
|
|
||||||
|
// EUI64 RR. See RFC 7043.
|
||||||
type EUI64 struct {
|
type EUI64 struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Address uint64
|
Address uint64
|
||||||
|
@ -1147,6 +1212,7 @@ type EUI64 struct {
|
||||||
|
|
||||||
func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
|
func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
|
||||||
|
|
||||||
|
// CAA RR. See RFC 6844.
|
||||||
type CAA struct {
|
type CAA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Flag uint8
|
Flag uint8
|
||||||
|
@ -1158,6 +1224,7 @@ func (rr *CAA) String() string {
|
||||||
return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value)
|
return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UID RR. Deprecated, IANA-Reserved.
|
||||||
type UID struct {
|
type UID struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Uid uint32
|
Uid uint32
|
||||||
|
@ -1165,6 +1232,7 @@ type UID struct {
|
||||||
|
|
||||||
func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
|
func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
|
||||||
|
|
||||||
|
// GID RR. Deprecated, IANA-Reserved.
|
||||||
type GID struct {
|
type GID struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Gid uint32
|
Gid uint32
|
||||||
|
@ -1172,6 +1240,7 @@ type GID struct {
|
||||||
|
|
||||||
func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
|
func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
|
||||||
|
|
||||||
|
// UINFO RR. Deprecated, IANA-Reserved.
|
||||||
type UINFO struct {
|
type UINFO struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Uinfo string
|
Uinfo string
|
||||||
|
@ -1179,6 +1248,7 @@ type UINFO struct {
|
||||||
|
|
||||||
func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
|
func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
|
||||||
|
|
||||||
|
// EID RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt.
|
||||||
type EID struct {
|
type EID struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Endpoint string `dns:"hex"`
|
Endpoint string `dns:"hex"`
|
||||||
|
@ -1186,6 +1256,7 @@ type EID struct {
|
||||||
|
|
||||||
func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
|
func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
|
||||||
|
|
||||||
|
// NIMLOC RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt.
|
||||||
type NIMLOC struct {
|
type NIMLOC struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Locator string `dns:"hex"`
|
Locator string `dns:"hex"`
|
||||||
|
@ -1193,6 +1264,7 @@ type NIMLOC struct {
|
||||||
|
|
||||||
func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
|
func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
|
||||||
|
|
||||||
|
// OPENPGPKEY RR. See RFC 7929.
|
||||||
type OPENPGPKEY struct {
|
type OPENPGPKEY struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
PublicKey string `dns:"base64"`
|
PublicKey string `dns:"base64"`
|
||||||
|
@ -1200,6 +1272,36 @@ type OPENPGPKEY struct {
|
||||||
|
|
||||||
func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
|
func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
|
||||||
|
|
||||||
|
// CSYNC RR. See RFC 7477.
|
||||||
|
type CSYNC struct {
|
||||||
|
Hdr RR_Header
|
||||||
|
Serial uint32
|
||||||
|
Flags uint16
|
||||||
|
TypeBitMap []uint16 `dns:"nsec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *CSYNC) String() string {
|
||||||
|
s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Serial), 10) + " " + strconv.Itoa(int(rr.Flags))
|
||||||
|
|
||||||
|
for i := 0; i < len(rr.TypeBitMap); i++ {
|
||||||
|
s += " " + Type(rr.TypeBitMap[i]).String()
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *CSYNC) len() int {
|
||||||
|
l := rr.Hdr.len() + 4 + 2
|
||||||
|
lastwindow := uint32(2 ^ 32 + 1)
|
||||||
|
for _, t := range rr.TypeBitMap {
|
||||||
|
window := t / 256
|
||||||
|
if uint32(window) != lastwindow {
|
||||||
|
l += 1 + 32
|
||||||
|
}
|
||||||
|
lastwindow = uint32(window)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
// TimeToString translates the RRSIG's incep. and expir. times to the
|
// TimeToString translates the RRSIG's incep. and expir. times to the
|
||||||
// string representation used when printing the record.
|
// string representation used when printing the record.
|
||||||
// It takes serial arithmetic (RFC 1982) into account.
|
// It takes serial arithmetic (RFC 1982) into account.
|
||||||
|
|
9
vendor/github.com/miekg/dns/types_generate.go
generated
vendored
9
vendor/github.com/miekg/dns/types_generate.go
generated
vendored
|
@ -23,11 +23,11 @@ var skipLen = map[string]struct{}{
|
||||||
"NSEC": {},
|
"NSEC": {},
|
||||||
"NSEC3": {},
|
"NSEC3": {},
|
||||||
"OPT": {},
|
"OPT": {},
|
||||||
|
"CSYNC": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
var packageHdr = `
|
var packageHdr = `
|
||||||
// *** DO NOT MODIFY ***
|
// Code generated by "go run types_generate.go"; DO NOT EDIT.
|
||||||
// AUTOGENERATED BY go generate from type_generate.go
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@ var TypeToString = map[uint16]string{
|
||||||
`))
|
`))
|
||||||
|
|
||||||
var headerFunc = template.Must(template.New("headerFunc").Parse(`
|
var headerFunc = template.Must(template.New("headerFunc").Parse(`
|
||||||
// Header() functions
|
|
||||||
{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr }
|
{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr }
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
@ -182,6 +181,8 @@ func main() {
|
||||||
fallthrough
|
fallthrough
|
||||||
case st.Tag(i) == `dns:"base64"`:
|
case st.Tag(i) == `dns:"base64"`:
|
||||||
o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
|
o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
|
||||||
|
case strings.HasPrefix(st.Tag(i), `dns:"size-hex:`): // this has an extra field where the length is stored
|
||||||
|
o("l += len(rr.%s)/2\n")
|
||||||
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
|
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
|
||||||
fallthrough
|
fallthrough
|
||||||
case st.Tag(i) == `dns:"hex"`:
|
case st.Tag(i) == `dns:"hex"`:
|
||||||
|
@ -197,7 +198,7 @@ func main() {
|
||||||
case st.Tag(i) == "":
|
case st.Tag(i) == "":
|
||||||
switch st.Field(i).Type().(*types.Basic).Kind() {
|
switch st.Field(i).Type().(*types.Basic).Kind() {
|
||||||
case types.Uint8:
|
case types.Uint8:
|
||||||
o("l += 1 // %s\n")
|
o("l++ // %s\n")
|
||||||
case types.Uint16:
|
case types.Uint16:
|
||||||
o("l += 2 // %s\n")
|
o("l += 2 // %s\n")
|
||||||
case types.Uint32:
|
case types.Uint32:
|
||||||
|
|
85
vendor/github.com/miekg/dns/udp.go
generated
vendored
85
vendor/github.com/miekg/dns/udp.go
generated
vendored
|
@ -1,10 +1,12 @@
|
||||||
// +build !windows,!plan9
|
// +build !windows
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"syscall"
|
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
"golang.org/x/net/ipv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SessionUDP holds the remote address and the associated
|
// SessionUDP holds the remote address and the associated
|
||||||
|
@ -17,29 +19,6 @@ type SessionUDP struct {
|
||||||
// RemoteAddr returns the remote network address.
|
// RemoteAddr returns the remote network address.
|
||||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
||||||
|
|
||||||
// setUDPSocketOptions sets the UDP socket options.
|
|
||||||
// This function is implemented on a per platform basis. See udp_*.go for more details
|
|
||||||
func setUDPSocketOptions(conn *net.UDPConn) error {
|
|
||||||
sa, err := getUDPSocketName(conn)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch sa.(type) {
|
|
||||||
case *syscall.SockaddrInet6:
|
|
||||||
v6only, err := getUDPSocketOptions6Only(conn)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
setUDPSocketOptions6(conn)
|
|
||||||
if !v6only {
|
|
||||||
setUDPSocketOptions4(conn)
|
|
||||||
}
|
|
||||||
case *syscall.SockaddrInet4:
|
|
||||||
setUDPSocketOptions4(conn)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
||||||
// net.UDPAddr.
|
// net.UDPAddr.
|
||||||
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||||
|
@ -51,8 +30,60 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||||
return n, &SessionUDP{raddr, oob[:oobn]}, err
|
return n, &SessionUDP{raddr, oob[:oobn]}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||||
n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
|
oob := correctSource(session.context)
|
||||||
|
n, _, err := conn.WriteMsgUDP(b, oob, session.raddr)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setUDPSocketOptions(conn *net.UDPConn) error {
|
||||||
|
// Try setting the flags for both families and ignore the errors unless they
|
||||||
|
// both error.
|
||||||
|
err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true)
|
||||||
|
err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
|
||||||
|
if err6 != nil && err4 != nil {
|
||||||
|
return err4
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseDstFromOOB takes oob data and returns the destination IP.
|
||||||
|
func parseDstFromOOB(oob []byte) net.IP {
|
||||||
|
// Start with IPv6 and then fallback to IPv4
|
||||||
|
// TODO(fastest963): Figure out a way to prefer one or the other. Looking at
|
||||||
|
// the lvl of the header for a 0 or 41 isn't cross-platform.
|
||||||
|
var dst net.IP
|
||||||
|
cm6 := new(ipv6.ControlMessage)
|
||||||
|
if cm6.Parse(oob) == nil {
|
||||||
|
dst = cm6.Dst
|
||||||
|
}
|
||||||
|
if dst == nil {
|
||||||
|
cm4 := new(ipv4.ControlMessage)
|
||||||
|
if cm4.Parse(oob) == nil {
|
||||||
|
dst = cm4.Dst
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
|
||||||
|
func correctSource(oob []byte) []byte {
|
||||||
|
dst := parseDstFromOOB(oob)
|
||||||
|
if dst == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// If the dst is definitely an IPv6, then use ipv6's ControlMessage to
|
||||||
|
// respond otherwise use ipv4's because ipv6's marshal ignores ipv4
|
||||||
|
// addresses.
|
||||||
|
if dst.To4() == nil {
|
||||||
|
cm := new(ipv6.ControlMessage)
|
||||||
|
cm.Src = dst
|
||||||
|
oob = cm.Marshal()
|
||||||
|
} else {
|
||||||
|
cm := new(ipv4.ControlMessage)
|
||||||
|
cm.Src = dst
|
||||||
|
oob = cm.Marshal()
|
||||||
|
}
|
||||||
|
return oob
|
||||||
|
}
|
||||||
|
|
82
vendor/github.com/miekg/dns/udp_linux.go
generated
vendored
82
vendor/github.com/miekg/dns/udp_linux.go
generated
vendored
|
@ -1,82 +0,0 @@
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package dns
|
|
||||||
|
|
||||||
// See:
|
|
||||||
// * http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket and
|
|
||||||
// * http://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/
|
|
||||||
//
|
|
||||||
// Why do we need this: When listening on 0.0.0.0 with UDP so kernel decides what is the outgoing
|
|
||||||
// interface, this might not always be the correct one. This code will make sure the egress
|
|
||||||
// packet's interface matched the ingress' one.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// setUDPSocketOptions4 prepares the v4 socket for sessions.
|
|
||||||
func setUDPSocketOptions4(conn *net.UDPConn) error {
|
|
||||||
file, err := conn.File()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Calling File() above results in the connection becoming blocking, we must fix that.
|
|
||||||
// See https://github.com/miekg/dns/issues/279
|
|
||||||
err = syscall.SetNonblock(int(file.Fd()), true)
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setUDPSocketOptions6 prepares the v6 socket for sessions.
|
|
||||||
func setUDPSocketOptions6(conn *net.UDPConn) error {
|
|
||||||
file, err := conn.File()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = syscall.SetNonblock(int(file.Fd()), true)
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getUDPSocketOption6Only return true if the socket is v6 only and false when it is v4/v6 combined
|
|
||||||
// (dualstack).
|
|
||||||
func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) {
|
|
||||||
file, err := conn.File()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
// dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections
|
|
||||||
v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
return v6only == 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
|
|
||||||
file, err := conn.File()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
return syscall.Getsockname(int(file.Fd()))
|
|
||||||
}
|
|
17
vendor/github.com/miekg/dns/udp_other.go
generated
vendored
17
vendor/github.com/miekg/dns/udp_other.go
generated
vendored
|
@ -1,17 +0,0 @@
|
||||||
// +build !linux,!plan9
|
|
||||||
|
|
||||||
package dns
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// These do nothing. See udp_linux.go for an example of how to implement this.
|
|
||||||
|
|
||||||
// We tried to adhire to some kind of naming scheme.
|
|
||||||
|
|
||||||
func setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
|
|
||||||
func setUDPSocketOptions6(conn *net.UDPConn) error { return nil }
|
|
||||||
func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
|
|
||||||
func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil }
|
|
34
vendor/github.com/miekg/dns/udp_plan9.go
generated
vendored
34
vendor/github.com/miekg/dns/udp_plan9.go
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
package dns
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setUDPSocketOptions(conn *net.UDPConn) error { return nil }
|
|
||||||
|
|
||||||
// SessionUDP holds the remote address and the associated
|
|
||||||
// out-of-band data.
|
|
||||||
type SessionUDP struct {
|
|
||||||
raddr *net.UDPAddr
|
|
||||||
context []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoteAddr returns the remote network address.
|
|
||||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
|
||||||
|
|
||||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
|
||||||
// net.UDPAddr.
|
|
||||||
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
|
||||||
oob := make([]byte, 40)
|
|
||||||
n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
|
|
||||||
if err != nil {
|
|
||||||
return n, nil, err
|
|
||||||
}
|
|
||||||
return n, &SessionUDP{raddr, oob[:oobn]}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
|
||||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
|
||||||
n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
|
|
||||||
return n, err
|
|
||||||
}
|
|
19
vendor/github.com/miekg/dns/udp_windows.go
generated
vendored
19
vendor/github.com/miekg/dns/udp_windows.go
generated
vendored
|
@ -4,12 +4,17 @@ package dns
|
||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|
||||||
|
// SessionUDP holds the remote address
|
||||||
type SessionUDP struct {
|
type SessionUDP struct {
|
||||||
raddr *net.UDPAddr
|
raddr *net.UDPAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoteAddr returns the remote network address.
|
||||||
|
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
||||||
|
|
||||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
||||||
// net.UDPAddr.
|
// net.UDPAddr.
|
||||||
|
// TODO(fastest963): Once go1.10 is released, use ReadMsgUDP.
|
||||||
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||||
n, raddr, err := conn.ReadFrom(b)
|
n, raddr, err := conn.ReadFrom(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,16 +24,14 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||||
return n, session, err
|
return n, session, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||||
|
// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
|
||||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||||
n, err := conn.WriteTo(b, session.raddr)
|
n, err := conn.WriteTo(b, session.raddr)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
|
||||||
|
// use the standard method in udp.go for these.
|
||||||
// setUDPSocketOptions sets the UDP socket options.
|
func setUDPSocketOptions(*net.UDPConn) error { return nil }
|
||||||
// This function is implemented on a per platform basis. See udp_*.go for more details
|
func parseDstFromOOB([]byte, net.IP) net.IP { return nil }
|
||||||
func setUDPSocketOptions(conn *net.UDPConn) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
15
vendor/github.com/miekg/dns/version.go
generated
vendored
Normal file
15
vendor/github.com/miekg/dns/version.go
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package dns
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Version is current version of this library.
|
||||||
|
var Version = V{1, 0, 4}
|
||||||
|
|
||||||
|
// V holds the version of this library.
|
||||||
|
type V struct {
|
||||||
|
Major, Minor, Patch int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v V) String() string {
|
||||||
|
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
|
||||||
|
}
|
60
vendor/github.com/miekg/dns/xfr.go
generated
vendored
60
vendor/github.com/miekg/dns/xfr.go
generated
vendored
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ type Transfer struct {
|
||||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
|
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
|
||||||
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
|
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
|
||||||
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
|
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
|
||||||
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
|
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||||
tsigTimersOnly bool
|
tsigTimersOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,18 +51,18 @@ func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
||||||
env = make(chan *Envelope)
|
env = make(chan *Envelope)
|
||||||
go func() {
|
go func() {
|
||||||
if q.Question[0].Qtype == TypeAXFR {
|
if q.Question[0].Qtype == TypeAXFR {
|
||||||
go t.inAxfr(q.Id, env)
|
go t.inAxfr(q, env)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if q.Question[0].Qtype == TypeIXFR {
|
if q.Question[0].Qtype == TypeIXFR {
|
||||||
go t.inIxfr(q.Id, env)
|
go t.inIxfr(q, env)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
|
func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
|
||||||
first := true
|
first := true
|
||||||
defer t.Close()
|
defer t.Close()
|
||||||
defer close(c)
|
defer close(c)
|
||||||
|
@ -76,11 +77,15 @@ func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
|
||||||
c <- &Envelope{nil, err}
|
c <- &Envelope{nil, err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if id != in.Id {
|
if q.Id != in.Id {
|
||||||
c <- &Envelope{in.Answer, ErrId}
|
c <- &Envelope{in.Answer, ErrId}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if first {
|
if first {
|
||||||
|
if in.Rcode != RcodeSuccess {
|
||||||
|
c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
|
||||||
|
return
|
||||||
|
}
|
||||||
if !isSOAFirst(in) {
|
if !isSOAFirst(in) {
|
||||||
c <- &Envelope{in.Answer, ErrSoa}
|
c <- &Envelope{in.Answer, ErrSoa}
|
||||||
return
|
return
|
||||||
|
@ -105,9 +110,11 @@ func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
|
func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
||||||
serial := uint32(0) // The first serial seen is the current server serial
|
serial := uint32(0) // The first serial seen is the current server serial
|
||||||
first := true
|
axfr := true
|
||||||
|
n := 0
|
||||||
|
qser := q.Ns[0].(*SOA).Serial
|
||||||
defer t.Close()
|
defer t.Close()
|
||||||
defer close(c)
|
defer close(c)
|
||||||
timeout := dnsTimeout
|
timeout := dnsTimeout
|
||||||
|
@ -121,17 +128,15 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
|
||||||
c <- &Envelope{nil, err}
|
c <- &Envelope{nil, err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if id != in.Id {
|
if q.Id != in.Id {
|
||||||
c <- &Envelope{in.Answer, ErrId}
|
c <- &Envelope{in.Answer, ErrId}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if first {
|
if in.Rcode != RcodeSuccess {
|
||||||
// A single SOA RR signals "no changes"
|
c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
|
||||||
if len(in.Answer) == 1 && isSOAFirst(in) {
|
|
||||||
c <- &Envelope{in.Answer, nil}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if n == 0 {
|
||||||
// Check if the returned answer is ok
|
// Check if the returned answer is ok
|
||||||
if !isSOAFirst(in) {
|
if !isSOAFirst(in) {
|
||||||
c <- &Envelope{in.Answer, ErrSoa}
|
c <- &Envelope{in.Answer, ErrSoa}
|
||||||
|
@ -139,21 +144,30 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
|
||||||
}
|
}
|
||||||
// This serial is important
|
// This serial is important
|
||||||
serial = in.Answer[0].(*SOA).Serial
|
serial = in.Answer[0].(*SOA).Serial
|
||||||
first = !first
|
// Check if there are no changes in zone
|
||||||
}
|
if qser >= serial {
|
||||||
|
|
||||||
// Now we need to check each message for SOA records, to see what we need to do
|
|
||||||
if !first {
|
|
||||||
t.tsigTimersOnly = true
|
|
||||||
// If the last record in the IXFR contains the servers' SOA, we should quit
|
|
||||||
if v, ok := in.Answer[len(in.Answer)-1].(*SOA); ok {
|
|
||||||
if v.Serial == serial {
|
|
||||||
c <- &Envelope{in.Answer, nil}
|
c <- &Envelope{in.Answer, nil}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Now we need to check each message for SOA records, to see what we need to do
|
||||||
|
t.tsigTimersOnly = true
|
||||||
|
for _, rr := range in.Answer {
|
||||||
|
if v, ok := rr.(*SOA); ok {
|
||||||
|
if v.Serial == serial {
|
||||||
|
n++
|
||||||
|
// quit if it's a full axfr or the the servers' SOA is repeated the third time
|
||||||
|
if axfr && n == 2 || n == 3 {
|
||||||
c <- &Envelope{in.Answer, nil}
|
c <- &Envelope{in.Answer, nil}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
} else if axfr {
|
||||||
|
// it's an ixfr
|
||||||
|
axfr = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c <- &Envelope{in.Answer, nil}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,3 +256,5 @@ func isSOALast(in *Msg) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const errXFR = "bad xfr rcode: %d"
|
||||||
|
|
118
vendor/github.com/miekg/dns/zcompress.go
generated
vendored
Normal file
118
vendor/github.com/miekg/dns/zcompress.go
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// Code generated by "go run compress_generate.go"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package dns
|
||||||
|
|
||||||
|
func compressionLenHelperType(c map[string]int, r RR) {
|
||||||
|
switch x := r.(type) {
|
||||||
|
case *AFSDB:
|
||||||
|
compressionLenHelper(c, x.Hostname)
|
||||||
|
case *CNAME:
|
||||||
|
compressionLenHelper(c, x.Target)
|
||||||
|
case *DNAME:
|
||||||
|
compressionLenHelper(c, x.Target)
|
||||||
|
case *HIP:
|
||||||
|
for i := range x.RendezvousServers {
|
||||||
|
compressionLenHelper(c, x.RendezvousServers[i])
|
||||||
|
}
|
||||||
|
case *KX:
|
||||||
|
compressionLenHelper(c, x.Exchanger)
|
||||||
|
case *LP:
|
||||||
|
compressionLenHelper(c, x.Fqdn)
|
||||||
|
case *MB:
|
||||||
|
compressionLenHelper(c, x.Mb)
|
||||||
|
case *MD:
|
||||||
|
compressionLenHelper(c, x.Md)
|
||||||
|
case *MF:
|
||||||
|
compressionLenHelper(c, x.Mf)
|
||||||
|
case *MG:
|
||||||
|
compressionLenHelper(c, x.Mg)
|
||||||
|
case *MINFO:
|
||||||
|
compressionLenHelper(c, x.Rmail)
|
||||||
|
compressionLenHelper(c, x.Email)
|
||||||
|
case *MR:
|
||||||
|
compressionLenHelper(c, x.Mr)
|
||||||
|
case *MX:
|
||||||
|
compressionLenHelper(c, x.Mx)
|
||||||
|
case *NAPTR:
|
||||||
|
compressionLenHelper(c, x.Replacement)
|
||||||
|
case *NS:
|
||||||
|
compressionLenHelper(c, x.Ns)
|
||||||
|
case *NSAPPTR:
|
||||||
|
compressionLenHelper(c, x.Ptr)
|
||||||
|
case *NSEC:
|
||||||
|
compressionLenHelper(c, x.NextDomain)
|
||||||
|
case *PTR:
|
||||||
|
compressionLenHelper(c, x.Ptr)
|
||||||
|
case *PX:
|
||||||
|
compressionLenHelper(c, x.Map822)
|
||||||
|
compressionLenHelper(c, x.Mapx400)
|
||||||
|
case *RP:
|
||||||
|
compressionLenHelper(c, x.Mbox)
|
||||||
|
compressionLenHelper(c, x.Txt)
|
||||||
|
case *RRSIG:
|
||||||
|
compressionLenHelper(c, x.SignerName)
|
||||||
|
case *RT:
|
||||||
|
compressionLenHelper(c, x.Host)
|
||||||
|
case *SIG:
|
||||||
|
compressionLenHelper(c, x.SignerName)
|
||||||
|
case *SOA:
|
||||||
|
compressionLenHelper(c, x.Ns)
|
||||||
|
compressionLenHelper(c, x.Mbox)
|
||||||
|
case *SRV:
|
||||||
|
compressionLenHelper(c, x.Target)
|
||||||
|
case *TALINK:
|
||||||
|
compressionLenHelper(c, x.PreviousName)
|
||||||
|
compressionLenHelper(c, x.NextName)
|
||||||
|
case *TKEY:
|
||||||
|
compressionLenHelper(c, x.Algorithm)
|
||||||
|
case *TSIG:
|
||||||
|
compressionLenHelper(c, x.Algorithm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
|
||||||
|
switch x := r.(type) {
|
||||||
|
case *AFSDB:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Hostname)
|
||||||
|
return k1, ok1
|
||||||
|
case *CNAME:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Target)
|
||||||
|
return k1, ok1
|
||||||
|
case *MB:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Mb)
|
||||||
|
return k1, ok1
|
||||||
|
case *MD:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Md)
|
||||||
|
return k1, ok1
|
||||||
|
case *MF:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Mf)
|
||||||
|
return k1, ok1
|
||||||
|
case *MG:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Mg)
|
||||||
|
return k1, ok1
|
||||||
|
case *MINFO:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Rmail)
|
||||||
|
k2, ok2 := compressionLenSearch(c, x.Email)
|
||||||
|
return k1 + k2, ok1 && ok2
|
||||||
|
case *MR:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Mr)
|
||||||
|
return k1, ok1
|
||||||
|
case *MX:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Mx)
|
||||||
|
return k1, ok1
|
||||||
|
case *NS:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Ns)
|
||||||
|
return k1, ok1
|
||||||
|
case *PTR:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Ptr)
|
||||||
|
return k1, ok1
|
||||||
|
case *RT:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Host)
|
||||||
|
return k1, ok1
|
||||||
|
case *SOA:
|
||||||
|
k1, ok1 := compressionLenSearch(c, x.Ns)
|
||||||
|
k2, ok2 := compressionLenSearch(c, x.Mbox)
|
||||||
|
return k1 + k2, ok1 && ok2
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
112
vendor/github.com/miekg/dns/zmsg.go
generated
vendored
112
vendor/github.com/miekg/dns/zmsg.go
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
// *** DO NOT MODIFY ***
|
// Code generated by "go run msg_generate.go"; DO NOT EDIT.
|
||||||
// AUTOGENERATED BY go generate from msg_generate.go
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
|
@ -61,6 +60,20 @@ func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bo
|
||||||
return off, nil
|
return off, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||||
|
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
headerEnd := off
|
||||||
|
off, err = packStringTxt(rr.Txt, msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
rr.Header().Rdlength = uint16(off - headerEnd)
|
||||||
|
return off, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||||
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -175,6 +188,28 @@ func (rr *CNAME) pack(msg []byte, off int, compression map[string]int, compress
|
||||||
return off, nil
|
return off, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rr *CSYNC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||||
|
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
headerEnd := off
|
||||||
|
off, err = packUint32(rr.Serial, msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
off, err = packUint16(rr.Flags, msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
off, err = packDataNsec(rr.TypeBitMap, msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return off, err
|
||||||
|
}
|
||||||
|
rr.Header().Rdlength = uint16(off - headerEnd)
|
||||||
|
return off, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||||
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -801,11 +836,13 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
if rr.Salt == "-" { /* do nothing, empty salt */
|
// Only pack salt if value is not "-", i.e. empty
|
||||||
}
|
if rr.Salt != "-" {
|
||||||
|
off, err = packStringHex(rr.Salt, msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
off, err = packUint8(rr.HashLength, msg, off)
|
off, err = packUint8(rr.HashLength, msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
|
@ -844,11 +881,13 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
if rr.Salt == "-" { /* do nothing, empty salt */
|
// Only pack salt if value is not "-", i.e. empty
|
||||||
}
|
if rr.Salt != "-" {
|
||||||
|
off, err = packStringHex(rr.Salt, msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rr.Header().Rdlength = uint16(off - headerEnd)
|
rr.Header().Rdlength = uint16(off - headerEnd)
|
||||||
return off, nil
|
return off, nil
|
||||||
}
|
}
|
||||||
|
@ -1285,7 +1324,7 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
off, err = packString(rr.Key, msg, off)
|
off, err = packStringHex(rr.Key, msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
|
@ -1293,7 +1332,7 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
off, err = packString(rr.OtherData, msg, off)
|
off, err = packStringHex(rr.OtherData, msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return off, err
|
return off, err
|
||||||
}
|
}
|
||||||
|
@ -1524,6 +1563,23 @@ func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
return rr, off, err
|
return rr, off, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
|
rr := new(AVC)
|
||||||
|
rr.Hdr = h
|
||||||
|
if noRdata(h) {
|
||||||
|
return rr, off, nil
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
rdStart := off
|
||||||
|
_ = rdStart
|
||||||
|
|
||||||
|
rr.Txt, off, err = unpackStringTxt(msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
|
||||||
func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
|
func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
rr := new(CAA)
|
rr := new(CAA)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
@ -1686,6 +1742,37 @@ func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
return rr, off, err
|
return rr, off, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unpackCSYNC(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
|
rr := new(CSYNC)
|
||||||
|
rr.Hdr = h
|
||||||
|
if noRdata(h) {
|
||||||
|
return rr, off, nil
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
rdStart := off
|
||||||
|
_ = rdStart
|
||||||
|
|
||||||
|
rr.Serial, off, err = unpackUint32(msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
if off == len(msg) {
|
||||||
|
return rr, off, nil
|
||||||
|
}
|
||||||
|
rr.Flags, off, err = unpackUint16(msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
if off == len(msg) {
|
||||||
|
return rr, off, nil
|
||||||
|
}
|
||||||
|
rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
|
||||||
|
if err != nil {
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
return rr, off, err
|
||||||
|
}
|
||||||
|
|
||||||
func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) {
|
func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
rr := new(DHCID)
|
rr := new(DHCID)
|
||||||
rr.Hdr = h
|
rr.Hdr = h
|
||||||
|
@ -3230,13 +3317,10 @@ func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
if off == len(msg) {
|
if off == len(msg) {
|
||||||
return rr, off, nil
|
return rr, off, nil
|
||||||
}
|
}
|
||||||
rr.Key, off, err = unpackString(msg, off)
|
rr.Key, off, err = unpackStringHex(msg, off, off+int(rr.KeySize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rr, off, err
|
return rr, off, err
|
||||||
}
|
}
|
||||||
if off == len(msg) {
|
|
||||||
return rr, off, nil
|
|
||||||
}
|
|
||||||
rr.OtherLen, off, err = unpackUint16(msg, off)
|
rr.OtherLen, off, err = unpackUint16(msg, off)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rr, off, err
|
return rr, off, err
|
||||||
|
@ -3244,7 +3328,7 @@ func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||||
if off == len(msg) {
|
if off == len(msg) {
|
||||||
return rr, off, nil
|
return rr, off, nil
|
||||||
}
|
}
|
||||||
rr.OtherData, off, err = unpackString(msg, off)
|
rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rr, off, err
|
return rr, off, err
|
||||||
}
|
}
|
||||||
|
@ -3463,11 +3547,13 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
|
||||||
TypeAAAA: unpackAAAA,
|
TypeAAAA: unpackAAAA,
|
||||||
TypeAFSDB: unpackAFSDB,
|
TypeAFSDB: unpackAFSDB,
|
||||||
TypeANY: unpackANY,
|
TypeANY: unpackANY,
|
||||||
|
TypeAVC: unpackAVC,
|
||||||
TypeCAA: unpackCAA,
|
TypeCAA: unpackCAA,
|
||||||
TypeCDNSKEY: unpackCDNSKEY,
|
TypeCDNSKEY: unpackCDNSKEY,
|
||||||
TypeCDS: unpackCDS,
|
TypeCDS: unpackCDS,
|
||||||
TypeCERT: unpackCERT,
|
TypeCERT: unpackCERT,
|
||||||
TypeCNAME: unpackCNAME,
|
TypeCNAME: unpackCNAME,
|
||||||
|
TypeCSYNC: unpackCSYNC,
|
||||||
TypeDHCID: unpackDHCID,
|
TypeDHCID: unpackDHCID,
|
||||||
TypeDLV: unpackDLV,
|
TypeDLV: unpackDLV,
|
||||||
TypeDNAME: unpackDNAME,
|
TypeDNAME: unpackDNAME,
|
||||||
|
|
97
vendor/github.com/miekg/dns/ztypes.go
generated
vendored
97
vendor/github.com/miekg/dns/ztypes.go
generated
vendored
|
@ -1,5 +1,4 @@
|
||||||
// *** DO NOT MODIFY ***
|
// Code generated by "go run types_generate.go"; DO NOT EDIT.
|
||||||
// AUTOGENERATED BY go generate from type_generate.go
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
|
@ -14,11 +13,13 @@ var TypeToRR = map[uint16]func() RR{
|
||||||
TypeAAAA: func() RR { return new(AAAA) },
|
TypeAAAA: func() RR { return new(AAAA) },
|
||||||
TypeAFSDB: func() RR { return new(AFSDB) },
|
TypeAFSDB: func() RR { return new(AFSDB) },
|
||||||
TypeANY: func() RR { return new(ANY) },
|
TypeANY: func() RR { return new(ANY) },
|
||||||
|
TypeAVC: func() RR { return new(AVC) },
|
||||||
TypeCAA: func() RR { return new(CAA) },
|
TypeCAA: func() RR { return new(CAA) },
|
||||||
TypeCDNSKEY: func() RR { return new(CDNSKEY) },
|
TypeCDNSKEY: func() RR { return new(CDNSKEY) },
|
||||||
TypeCDS: func() RR { return new(CDS) },
|
TypeCDS: func() RR { return new(CDS) },
|
||||||
TypeCERT: func() RR { return new(CERT) },
|
TypeCERT: func() RR { return new(CERT) },
|
||||||
TypeCNAME: func() RR { return new(CNAME) },
|
TypeCNAME: func() RR { return new(CNAME) },
|
||||||
|
TypeCSYNC: func() RR { return new(CSYNC) },
|
||||||
TypeDHCID: func() RR { return new(DHCID) },
|
TypeDHCID: func() RR { return new(DHCID) },
|
||||||
TypeDLV: func() RR { return new(DLV) },
|
TypeDLV: func() RR { return new(DLV) },
|
||||||
TypeDNAME: func() RR { return new(DNAME) },
|
TypeDNAME: func() RR { return new(DNAME) },
|
||||||
|
@ -86,12 +87,14 @@ var TypeToString = map[uint16]string{
|
||||||
TypeAFSDB: "AFSDB",
|
TypeAFSDB: "AFSDB",
|
||||||
TypeANY: "ANY",
|
TypeANY: "ANY",
|
||||||
TypeATMA: "ATMA",
|
TypeATMA: "ATMA",
|
||||||
|
TypeAVC: "AVC",
|
||||||
TypeAXFR: "AXFR",
|
TypeAXFR: "AXFR",
|
||||||
TypeCAA: "CAA",
|
TypeCAA: "CAA",
|
||||||
TypeCDNSKEY: "CDNSKEY",
|
TypeCDNSKEY: "CDNSKEY",
|
||||||
TypeCDS: "CDS",
|
TypeCDS: "CDS",
|
||||||
TypeCERT: "CERT",
|
TypeCERT: "CERT",
|
||||||
TypeCNAME: "CNAME",
|
TypeCNAME: "CNAME",
|
||||||
|
TypeCSYNC: "CSYNC",
|
||||||
TypeDHCID: "DHCID",
|
TypeDHCID: "DHCID",
|
||||||
TypeDLV: "DLV",
|
TypeDLV: "DLV",
|
||||||
TypeDNAME: "DNAME",
|
TypeDNAME: "DNAME",
|
||||||
|
@ -161,16 +164,17 @@ var TypeToString = map[uint16]string{
|
||||||
TypeNSAPPTR: "NSAP-PTR",
|
TypeNSAPPTR: "NSAP-PTR",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header() functions
|
|
||||||
func (rr *A) Header() *RR_Header { return &rr.Hdr }
|
func (rr *A) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
|
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
|
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
|
func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
|
||||||
|
func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
|
func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
|
func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
|
func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
|
func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
|
func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
|
||||||
|
func (rr *CSYNC) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
|
func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *DLV) Header() *RR_Header { return &rr.Hdr }
|
func (rr *DLV) Header() *RR_Header { return &rr.Hdr }
|
||||||
func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
|
func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
|
||||||
|
@ -252,9 +256,16 @@ func (rr *ANY) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
func (rr *AVC) len() int {
|
||||||
|
l := rr.Hdr.len()
|
||||||
|
for _, x := range rr.Txt {
|
||||||
|
l += len(x) + 1
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
func (rr *CAA) len() int {
|
func (rr *CAA) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Flag
|
l++ // Flag
|
||||||
l += len(rr.Tag) + 1
|
l += len(rr.Tag) + 1
|
||||||
l += len(rr.Value)
|
l += len(rr.Value)
|
||||||
return l
|
return l
|
||||||
|
@ -263,7 +274,7 @@ func (rr *CERT) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // Type
|
l += 2 // Type
|
||||||
l += 2 // KeyTag
|
l += 2 // KeyTag
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
|
l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -285,16 +296,16 @@ func (rr *DNAME) len() int {
|
||||||
func (rr *DNSKEY) len() int {
|
func (rr *DNSKEY) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // Flags
|
l += 2 // Flags
|
||||||
l += 1 // Protocol
|
l++ // Protocol
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
func (rr *DS) len() int {
|
func (rr *DS) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // KeyTag
|
l += 2 // KeyTag
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += 1 // DigestType
|
l++ // DigestType
|
||||||
l += len(rr.Digest)/2 + 1
|
l += len(rr.Digest)/2 + 1
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -333,10 +344,10 @@ func (rr *HINFO) len() int {
|
||||||
}
|
}
|
||||||
func (rr *HIP) len() int {
|
func (rr *HIP) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // HitLength
|
l++ // HitLength
|
||||||
l += 1 // PublicKeyAlgorithm
|
l++ // PublicKeyAlgorithm
|
||||||
l += 2 // PublicKeyLength
|
l += 2 // PublicKeyLength
|
||||||
l += len(rr.Hit)/2 + 1
|
l += len(rr.Hit) / 2
|
||||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||||
for _, x := range rr.RendezvousServers {
|
for _, x := range rr.RendezvousServers {
|
||||||
l += len(x) + 1
|
l += len(x) + 1
|
||||||
|
@ -363,10 +374,10 @@ func (rr *L64) len() int {
|
||||||
}
|
}
|
||||||
func (rr *LOC) len() int {
|
func (rr *LOC) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Version
|
l++ // Version
|
||||||
l += 1 // Size
|
l++ // Size
|
||||||
l += 1 // HorizPre
|
l++ // HorizPre
|
||||||
l += 1 // VertPre
|
l++ // VertPre
|
||||||
l += 4 // Latitude
|
l += 4 // Latitude
|
||||||
l += 4 // Longitude
|
l += 4 // Longitude
|
||||||
l += 4 // Altitude
|
l += 4 // Altitude
|
||||||
|
@ -455,11 +466,11 @@ func (rr *NSAPPTR) len() int {
|
||||||
}
|
}
|
||||||
func (rr *NSEC3PARAM) len() int {
|
func (rr *NSEC3PARAM) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Hash
|
l++ // Hash
|
||||||
l += 1 // Flags
|
l++ // Flags
|
||||||
l += 2 // Iterations
|
l += 2 // Iterations
|
||||||
l += 1 // SaltLength
|
l++ // SaltLength
|
||||||
l += len(rr.Salt)/2 + 1
|
l += len(rr.Salt) / 2
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
func (rr *OPENPGPKEY) len() int {
|
func (rr *OPENPGPKEY) len() int {
|
||||||
|
@ -487,8 +498,8 @@ func (rr *RFC3597) len() int {
|
||||||
func (rr *RKEY) len() int {
|
func (rr *RKEY) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // Flags
|
l += 2 // Flags
|
||||||
l += 1 // Protocol
|
l++ // Protocol
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -501,8 +512,8 @@ func (rr *RP) len() int {
|
||||||
func (rr *RRSIG) len() int {
|
func (rr *RRSIG) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // TypeCovered
|
l += 2 // TypeCovered
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += 1 // Labels
|
l++ // Labels
|
||||||
l += 4 // OrigTtl
|
l += 4 // OrigTtl
|
||||||
l += 4 // Expiration
|
l += 4 // Expiration
|
||||||
l += 4 // Inception
|
l += 4 // Inception
|
||||||
|
@ -519,9 +530,9 @@ func (rr *RT) len() int {
|
||||||
}
|
}
|
||||||
func (rr *SMIMEA) len() int {
|
func (rr *SMIMEA) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Usage
|
l++ // Usage
|
||||||
l += 1 // Selector
|
l++ // Selector
|
||||||
l += 1 // MatchingType
|
l++ // MatchingType
|
||||||
l += len(rr.Certificate)/2 + 1
|
l += len(rr.Certificate)/2 + 1
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -553,16 +564,16 @@ func (rr *SRV) len() int {
|
||||||
}
|
}
|
||||||
func (rr *SSHFP) len() int {
|
func (rr *SSHFP) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += 1 // Type
|
l++ // Type
|
||||||
l += len(rr.FingerPrint)/2 + 1
|
l += len(rr.FingerPrint)/2 + 1
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
func (rr *TA) len() int {
|
func (rr *TA) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 2 // KeyTag
|
l += 2 // KeyTag
|
||||||
l += 1 // Algorithm
|
l++ // Algorithm
|
||||||
l += 1 // DigestType
|
l++ // DigestType
|
||||||
l += len(rr.Digest)/2 + 1
|
l += len(rr.Digest)/2 + 1
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -580,16 +591,16 @@ func (rr *TKEY) len() int {
|
||||||
l += 2 // Mode
|
l += 2 // Mode
|
||||||
l += 2 // Error
|
l += 2 // Error
|
||||||
l += 2 // KeySize
|
l += 2 // KeySize
|
||||||
l += len(rr.Key) + 1
|
l += len(rr.Key) / 2
|
||||||
l += 2 // OtherLen
|
l += 2 // OtherLen
|
||||||
l += len(rr.OtherData) + 1
|
l += len(rr.OtherData) / 2
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
func (rr *TLSA) len() int {
|
func (rr *TLSA) len() int {
|
||||||
l := rr.Hdr.len()
|
l := rr.Hdr.len()
|
||||||
l += 1 // Usage
|
l++ // Usage
|
||||||
l += 1 // Selector
|
l++ // Selector
|
||||||
l += 1 // MatchingType
|
l++ // MatchingType
|
||||||
l += len(rr.Certificate)/2 + 1
|
l += len(rr.Certificate)/2 + 1
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -599,11 +610,11 @@ func (rr *TSIG) len() int {
|
||||||
l += 6 // TimeSigned
|
l += 6 // TimeSigned
|
||||||
l += 2 // Fudge
|
l += 2 // Fudge
|
||||||
l += 2 // MACSize
|
l += 2 // MACSize
|
||||||
l += len(rr.MAC)/2 + 1
|
l += len(rr.MAC) / 2
|
||||||
l += 2 // OrigId
|
l += 2 // OrigId
|
||||||
l += 2 // Error
|
l += 2 // Error
|
||||||
l += 2 // OtherLen
|
l += 2 // OtherLen
|
||||||
l += len(rr.OtherData)/2 + 1
|
l += len(rr.OtherData) / 2
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
func (rr *TXT) len() int {
|
func (rr *TXT) len() int {
|
||||||
|
@ -649,6 +660,11 @@ func (rr *AFSDB) copy() RR {
|
||||||
func (rr *ANY) copy() RR {
|
func (rr *ANY) copy() RR {
|
||||||
return &ANY{*rr.Hdr.copyHeader()}
|
return &ANY{*rr.Hdr.copyHeader()}
|
||||||
}
|
}
|
||||||
|
func (rr *AVC) copy() RR {
|
||||||
|
Txt := make([]string, len(rr.Txt))
|
||||||
|
copy(Txt, rr.Txt)
|
||||||
|
return &AVC{*rr.Hdr.copyHeader(), Txt}
|
||||||
|
}
|
||||||
func (rr *CAA) copy() RR {
|
func (rr *CAA) copy() RR {
|
||||||
return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
|
return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
|
||||||
}
|
}
|
||||||
|
@ -658,6 +674,11 @@ func (rr *CERT) copy() RR {
|
||||||
func (rr *CNAME) copy() RR {
|
func (rr *CNAME) copy() RR {
|
||||||
return &CNAME{*rr.Hdr.copyHeader(), rr.Target}
|
return &CNAME{*rr.Hdr.copyHeader(), rr.Target}
|
||||||
}
|
}
|
||||||
|
func (rr *CSYNC) copy() RR {
|
||||||
|
TypeBitMap := make([]uint16, len(rr.TypeBitMap))
|
||||||
|
copy(TypeBitMap, rr.TypeBitMap)
|
||||||
|
return &CSYNC{*rr.Hdr.copyHeader(), rr.Serial, rr.Flags, TypeBitMap}
|
||||||
|
}
|
||||||
func (rr *DHCID) copy() RR {
|
func (rr *DHCID) copy() RR {
|
||||||
return &DHCID{*rr.Hdr.copyHeader(), rr.Digest}
|
return &DHCID{*rr.Hdr.copyHeader(), rr.Digest}
|
||||||
}
|
}
|
||||||
|
|
181
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
Normal file
181
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||||
|
// https://ed25519.cr.yp.to/.
|
||||||
|
//
|
||||||
|
// These functions are also compatible with the “Ed25519” function defined in
|
||||||
|
// RFC 8032.
|
||||||
|
package ed25519
|
||||||
|
|
||||||
|
// This code is a port of the public domain, “ref10” implementation of ed25519
|
||||||
|
// from SUPERCOP.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
cryptorand "crypto/rand"
|
||||||
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519/internal/edwards25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||||
|
PublicKeySize = 32
|
||||||
|
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||||
|
PrivateKeySize = 64
|
||||||
|
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||||
|
SignatureSize = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Ed25519 public keys.
|
||||||
|
type PublicKey []byte
|
||||||
|
|
||||||
|
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||||
|
type PrivateKey []byte
|
||||||
|
|
||||||
|
// Public returns the PublicKey corresponding to priv.
|
||||||
|
func (priv PrivateKey) Public() crypto.PublicKey {
|
||||||
|
publicKey := make([]byte, PublicKeySize)
|
||||||
|
copy(publicKey, priv[32:])
|
||||||
|
return PublicKey(publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the given message with priv.
|
||||||
|
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
||||||
|
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
||||||
|
// indicate the message hasn't been hashed. This can be achieved by passing
|
||||||
|
// crypto.Hash(0) as the value for opts.
|
||||||
|
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||||
|
if opts.HashFunc() != crypto.Hash(0) {
|
||||||
|
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sign(priv, message), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, err error) {
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptorand.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey = make([]byte, PrivateKeySize)
|
||||||
|
publicKey = make([]byte, PublicKeySize)
|
||||||
|
_, err = io.ReadFull(rand, privateKey[:32])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
digest := sha512.Sum512(privateKey[:32])
|
||||||
|
digest[0] &= 248
|
||||||
|
digest[31] &= 127
|
||||||
|
digest[31] |= 64
|
||||||
|
|
||||||
|
var A edwards25519.ExtendedGroupElement
|
||||||
|
var hBytes [32]byte
|
||||||
|
copy(hBytes[:], digest[:])
|
||||||
|
edwards25519.GeScalarMultBase(&A, &hBytes)
|
||||||
|
var publicKeyBytes [32]byte
|
||||||
|
A.ToBytes(&publicKeyBytes)
|
||||||
|
|
||||||
|
copy(privateKey[32:], publicKeyBytes[:])
|
||||||
|
copy(publicKey, publicKeyBytes[:])
|
||||||
|
|
||||||
|
return publicKey, privateKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the message with privateKey and returns a signature. It will
|
||||||
|
// panic if len(privateKey) is not PrivateKeySize.
|
||||||
|
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||||
|
if l := len(privateKey); l != PrivateKeySize {
|
||||||
|
panic("ed25519: bad private key length: " + strconv.Itoa(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
h := sha512.New()
|
||||||
|
h.Write(privateKey[:32])
|
||||||
|
|
||||||
|
var digest1, messageDigest, hramDigest [64]byte
|
||||||
|
var expandedSecretKey [32]byte
|
||||||
|
h.Sum(digest1[:0])
|
||||||
|
copy(expandedSecretKey[:], digest1[:])
|
||||||
|
expandedSecretKey[0] &= 248
|
||||||
|
expandedSecretKey[31] &= 63
|
||||||
|
expandedSecretKey[31] |= 64
|
||||||
|
|
||||||
|
h.Reset()
|
||||||
|
h.Write(digest1[32:])
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(messageDigest[:0])
|
||||||
|
|
||||||
|
var messageDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
||||||
|
var R edwards25519.ExtendedGroupElement
|
||||||
|
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
||||||
|
|
||||||
|
var encodedR [32]byte
|
||||||
|
R.ToBytes(&encodedR)
|
||||||
|
|
||||||
|
h.Reset()
|
||||||
|
h.Write(encodedR[:])
|
||||||
|
h.Write(privateKey[32:])
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(hramDigest[:0])
|
||||||
|
var hramDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
||||||
|
|
||||||
|
var s [32]byte
|
||||||
|
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
||||||
|
|
||||||
|
signature := make([]byte, SignatureSize)
|
||||||
|
copy(signature[:], encodedR[:])
|
||||||
|
copy(signature[32:], s[:])
|
||||||
|
|
||||||
|
return signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||||
|
// will panic if len(publicKey) is not PublicKeySize.
|
||||||
|
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
||||||
|
if l := len(publicKey); l != PublicKeySize {
|
||||||
|
panic("ed25519: bad public key length: " + strconv.Itoa(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sig) != SignatureSize || sig[63]&224 != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var A edwards25519.ExtendedGroupElement
|
||||||
|
var publicKeyBytes [32]byte
|
||||||
|
copy(publicKeyBytes[:], publicKey)
|
||||||
|
if !A.FromBytes(&publicKeyBytes) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
edwards25519.FeNeg(&A.X, &A.X)
|
||||||
|
edwards25519.FeNeg(&A.T, &A.T)
|
||||||
|
|
||||||
|
h := sha512.New()
|
||||||
|
h.Write(sig[:32])
|
||||||
|
h.Write(publicKey[:])
|
||||||
|
h.Write(message)
|
||||||
|
var digest [64]byte
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
|
||||||
|
var hReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&hReduced, &digest)
|
||||||
|
|
||||||
|
var R edwards25519.ProjectiveGroupElement
|
||||||
|
var b [32]byte
|
||||||
|
copy(b[:], sig[32:])
|
||||||
|
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
|
||||||
|
|
||||||
|
var checkR [32]byte
|
||||||
|
R.ToBytes(&checkR)
|
||||||
|
return bytes.Equal(sig[:32], checkR[:])
|
||||||
|
}
|
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1771
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
1771
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
10
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
10
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
|
@ -93,5 +93,13 @@ func ReadPassword(fd int) ([]byte, error) {
|
||||||
windows.SetConsoleMode(windows.Handle(fd), old)
|
windows.SetConsoleMode(windows.Handle(fd), old)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return readPasswordLine(os.NewFile(uintptr(fd), "stdin"))
|
var h windows.Handle
|
||||||
|
p, _ := windows.GetCurrentProcess()
|
||||||
|
if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f := os.NewFile(uintptr(h), "stdin")
|
||||||
|
defer f.Close()
|
||||||
|
return readPasswordLine(f)
|
||||||
}
|
}
|
||||||
|
|
41
vendor/golang.org/x/net/bpf/asm.go
generated
vendored
Normal file
41
vendor/golang.org/x/net/bpf/asm.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Assemble converts insts into raw instructions suitable for loading
|
||||||
|
// into a BPF virtual machine.
|
||||||
|
//
|
||||||
|
// Currently, no optimization is attempted, the assembled program flow
|
||||||
|
// is exactly as provided.
|
||||||
|
func Assemble(insts []Instruction) ([]RawInstruction, error) {
|
||||||
|
ret := make([]RawInstruction, len(insts))
|
||||||
|
var err error
|
||||||
|
for i, inst := range insts {
|
||||||
|
ret[i], err = inst.Assemble()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("assembling instruction %d: %s", i+1, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disassemble attempts to parse raw back into
|
||||||
|
// Instructions. Unrecognized RawInstructions are assumed to be an
|
||||||
|
// extension not implemented by this package, and are passed through
|
||||||
|
// unchanged to the output. The allDecoded value reports whether insts
|
||||||
|
// contains no RawInstructions.
|
||||||
|
func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) {
|
||||||
|
insts = make([]Instruction, len(raw))
|
||||||
|
allDecoded = true
|
||||||
|
for i, r := range raw {
|
||||||
|
insts[i] = r.Disassemble()
|
||||||
|
if _, ok := insts[i].(RawInstruction); ok {
|
||||||
|
allDecoded = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return insts, allDecoded
|
||||||
|
}
|
218
vendor/golang.org/x/net/bpf/constants.go
generated
vendored
Normal file
218
vendor/golang.org/x/net/bpf/constants.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
// A Register is a register of the BPF virtual machine.
|
||||||
|
type Register uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RegA is the accumulator register. RegA is always the
|
||||||
|
// destination register of ALU operations.
|
||||||
|
RegA Register = iota
|
||||||
|
// RegX is the indirection register, used by LoadIndirect
|
||||||
|
// operations.
|
||||||
|
RegX
|
||||||
|
)
|
||||||
|
|
||||||
|
// An ALUOp is an arithmetic or logic operation.
|
||||||
|
type ALUOp uint16
|
||||||
|
|
||||||
|
// ALU binary operation types.
|
||||||
|
const (
|
||||||
|
ALUOpAdd ALUOp = iota << 4
|
||||||
|
ALUOpSub
|
||||||
|
ALUOpMul
|
||||||
|
ALUOpDiv
|
||||||
|
ALUOpOr
|
||||||
|
ALUOpAnd
|
||||||
|
ALUOpShiftLeft
|
||||||
|
ALUOpShiftRight
|
||||||
|
aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type.
|
||||||
|
ALUOpMod
|
||||||
|
ALUOpXor
|
||||||
|
)
|
||||||
|
|
||||||
|
// A JumpTest is a comparison operator used in conditional jumps.
|
||||||
|
type JumpTest uint16
|
||||||
|
|
||||||
|
// Supported operators for conditional jumps.
|
||||||
|
const (
|
||||||
|
// K == A
|
||||||
|
JumpEqual JumpTest = iota
|
||||||
|
// K != A
|
||||||
|
JumpNotEqual
|
||||||
|
// K > A
|
||||||
|
JumpGreaterThan
|
||||||
|
// K < A
|
||||||
|
JumpLessThan
|
||||||
|
// K >= A
|
||||||
|
JumpGreaterOrEqual
|
||||||
|
// K <= A
|
||||||
|
JumpLessOrEqual
|
||||||
|
// K & A != 0
|
||||||
|
JumpBitsSet
|
||||||
|
// K & A == 0
|
||||||
|
JumpBitsNotSet
|
||||||
|
)
|
||||||
|
|
||||||
|
// An Extension is a function call provided by the kernel that
|
||||||
|
// performs advanced operations that are expensive or impossible
|
||||||
|
// within the BPF virtual machine.
|
||||||
|
//
|
||||||
|
// Extensions are only implemented by the Linux kernel.
|
||||||
|
//
|
||||||
|
// TODO: should we prune this list? Some of these extensions seem
|
||||||
|
// either broken or near-impossible to use correctly, whereas other
|
||||||
|
// (len, random, ifindex) are quite useful.
|
||||||
|
type Extension int
|
||||||
|
|
||||||
|
// Extension functions available in the Linux kernel.
|
||||||
|
const (
|
||||||
|
// extOffset is the negative maximum number of instructions used
|
||||||
|
// to load instructions by overloading the K argument.
|
||||||
|
extOffset = -0x1000
|
||||||
|
// ExtLen returns the length of the packet.
|
||||||
|
ExtLen Extension = 1
|
||||||
|
// ExtProto returns the packet's L3 protocol type.
|
||||||
|
ExtProto Extension = 0
|
||||||
|
// ExtType returns the packet's type (skb->pkt_type in the kernel)
|
||||||
|
//
|
||||||
|
// TODO: better documentation. How nice an API do we want to
|
||||||
|
// provide for these esoteric extensions?
|
||||||
|
ExtType Extension = 4
|
||||||
|
// ExtPayloadOffset returns the offset of the packet payload, or
|
||||||
|
// the first protocol header that the kernel does not know how to
|
||||||
|
// parse.
|
||||||
|
ExtPayloadOffset Extension = 52
|
||||||
|
// ExtInterfaceIndex returns the index of the interface on which
|
||||||
|
// the packet was received.
|
||||||
|
ExtInterfaceIndex Extension = 8
|
||||||
|
// ExtNetlinkAttr returns the netlink attribute of type X at
|
||||||
|
// offset A.
|
||||||
|
ExtNetlinkAttr Extension = 12
|
||||||
|
// ExtNetlinkAttrNested returns the nested netlink attribute of
|
||||||
|
// type X at offset A.
|
||||||
|
ExtNetlinkAttrNested Extension = 16
|
||||||
|
// ExtMark returns the packet's mark value.
|
||||||
|
ExtMark Extension = 20
|
||||||
|
// ExtQueue returns the packet's assigned hardware queue.
|
||||||
|
ExtQueue Extension = 24
|
||||||
|
// ExtLinkLayerType returns the packet's hardware address type
|
||||||
|
// (e.g. Ethernet, Infiniband).
|
||||||
|
ExtLinkLayerType Extension = 28
|
||||||
|
// ExtRXHash returns the packets receive hash.
|
||||||
|
//
|
||||||
|
// TODO: figure out what this rxhash actually is.
|
||||||
|
ExtRXHash Extension = 32
|
||||||
|
// ExtCPUID returns the ID of the CPU processing the current
|
||||||
|
// packet.
|
||||||
|
ExtCPUID Extension = 36
|
||||||
|
// ExtVLANTag returns the packet's VLAN tag.
|
||||||
|
ExtVLANTag Extension = 44
|
||||||
|
// ExtVLANTagPresent returns non-zero if the packet has a VLAN
|
||||||
|
// tag.
|
||||||
|
//
|
||||||
|
// TODO: I think this might be a lie: it reads bit 0x1000 of the
|
||||||
|
// VLAN header, which changed meaning in recent revisions of the
|
||||||
|
// spec - this extension may now return meaningless information.
|
||||||
|
ExtVLANTagPresent Extension = 48
|
||||||
|
// ExtVLANProto returns 0x8100 if the frame has a VLAN header,
|
||||||
|
// 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some
|
||||||
|
// other value if no VLAN information is present.
|
||||||
|
ExtVLANProto Extension = 60
|
||||||
|
// ExtRand returns a uniformly random uint32.
|
||||||
|
ExtRand Extension = 56
|
||||||
|
)
|
||||||
|
|
||||||
|
// The following gives names to various bit patterns used in opcode construction.
|
||||||
|
|
||||||
|
const (
|
||||||
|
opMaskCls uint16 = 0x7
|
||||||
|
// opClsLoad masks
|
||||||
|
opMaskLoadDest = 0x01
|
||||||
|
opMaskLoadWidth = 0x18
|
||||||
|
opMaskLoadMode = 0xe0
|
||||||
|
// opClsALU
|
||||||
|
opMaskOperandSrc = 0x08
|
||||||
|
opMaskOperator = 0xf0
|
||||||
|
// opClsJump
|
||||||
|
opMaskJumpConst = 0x0f
|
||||||
|
opMaskJumpCond = 0xf0
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 |
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
opClsLoadA uint16 = iota
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 |
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
opClsLoadX
|
||||||
|
// +---+---+---+---+---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||||
|
// +---+---+---+---+---+---+---+---+
|
||||||
|
opClsStoreA
|
||||||
|
// +---+---+---+---+---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
|
||||||
|
// +---+---+---+---+---+---+---+---+
|
||||||
|
opClsStoreX
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
// | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 |
|
||||||
|
// +---------------+-----------------+---+---+---+
|
||||||
|
opClsALU
|
||||||
|
// +-----------------------------+---+---+---+---+
|
||||||
|
// | TestOperator (4b) | 0 | 1 | 0 | 1 |
|
||||||
|
// +-----------------------------+---+---+---+---+
|
||||||
|
opClsJump
|
||||||
|
// +---+-------------------------+---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 |
|
||||||
|
// +---+-------------------------+---+---+---+---+
|
||||||
|
opClsReturn
|
||||||
|
// +---+-------------------------+---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 |
|
||||||
|
// +---+-------------------------+---+---+---+---+
|
||||||
|
opClsMisc
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opAddrModeImmediate uint16 = iota << 5
|
||||||
|
opAddrModeAbsolute
|
||||||
|
opAddrModeIndirect
|
||||||
|
opAddrModeScratch
|
||||||
|
opAddrModePacketLen // actually an extension, not an addressing mode.
|
||||||
|
opAddrModeMemShift
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opLoadWidth4 uint16 = iota << 3
|
||||||
|
opLoadWidth2
|
||||||
|
opLoadWidth1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Operator defined by ALUOp*
|
||||||
|
|
||||||
|
const (
|
||||||
|
opALUSrcConstant uint16 = iota << 3
|
||||||
|
opALUSrcX
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opJumpAlways = iota << 4
|
||||||
|
opJumpEqual
|
||||||
|
opJumpGT
|
||||||
|
opJumpGE
|
||||||
|
opJumpSet
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opRetSrcConstant uint16 = iota << 4
|
||||||
|
opRetSrcA
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opMiscTAX = 0x00
|
||||||
|
opMiscTXA = 0x80
|
||||||
|
)
|
82
vendor/golang.org/x/net/bpf/doc.go
generated
vendored
Normal file
82
vendor/golang.org/x/net/bpf/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Package bpf implements marshaling and unmarshaling of programs for the
|
||||||
|
Berkeley Packet Filter virtual machine, and provides a Go implementation
|
||||||
|
of the virtual machine.
|
||||||
|
|
||||||
|
BPF's main use is to specify a packet filter for network taps, so that
|
||||||
|
the kernel doesn't have to expensively copy every packet it sees to
|
||||||
|
userspace. However, it's been repurposed to other areas where running
|
||||||
|
user code in-kernel is needed. For example, Linux's seccomp uses BPF
|
||||||
|
to apply security policies to system calls. For simplicity, this
|
||||||
|
documentation refers only to packets, but other uses of BPF have their
|
||||||
|
own data payloads.
|
||||||
|
|
||||||
|
BPF programs run in a restricted virtual machine. It has almost no
|
||||||
|
access to kernel functions, and while conditional branches are
|
||||||
|
allowed, they can only jump forwards, to guarantee that there are no
|
||||||
|
infinite loops.
|
||||||
|
|
||||||
|
The virtual machine
|
||||||
|
|
||||||
|
The BPF VM is an accumulator machine. Its main register, called
|
||||||
|
register A, is an implicit source and destination in all arithmetic
|
||||||
|
and logic operations. The machine also has 16 scratch registers for
|
||||||
|
temporary storage, and an indirection register (register X) for
|
||||||
|
indirect memory access. All registers are 32 bits wide.
|
||||||
|
|
||||||
|
Each run of a BPF program is given one packet, which is placed in the
|
||||||
|
VM's read-only "main memory". LoadAbsolute and LoadIndirect
|
||||||
|
instructions can fetch up to 32 bits at a time into register A for
|
||||||
|
examination.
|
||||||
|
|
||||||
|
The goal of a BPF program is to produce and return a verdict (uint32),
|
||||||
|
which tells the kernel what to do with the packet. In the context of
|
||||||
|
packet filtering, the returned value is the number of bytes of the
|
||||||
|
packet to forward to userspace, or 0 to ignore the packet. Other
|
||||||
|
contexts like seccomp define their own return values.
|
||||||
|
|
||||||
|
In order to simplify programs, attempts to read past the end of the
|
||||||
|
packet terminate the program execution with a verdict of 0 (ignore
|
||||||
|
packet). This means that the vast majority of BPF programs don't need
|
||||||
|
to do any explicit bounds checking.
|
||||||
|
|
||||||
|
In addition to the bytes of the packet, some BPF programs have access
|
||||||
|
to extensions, which are essentially calls to kernel utility
|
||||||
|
functions. Currently, the only extensions supported by this package
|
||||||
|
are the Linux packet filter extensions.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
|
||||||
|
This packet filter selects all ARP packets.
|
||||||
|
|
||||||
|
bpf.Assemble([]bpf.Instruction{
|
||||||
|
// Load "EtherType" field from the ethernet header.
|
||||||
|
bpf.LoadAbsolute{Off: 12, Size: 2},
|
||||||
|
// Skip over the next instruction if EtherType is not ARP.
|
||||||
|
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
|
||||||
|
// Verdict is "send up to 4k of the packet to userspace."
|
||||||
|
bpf.RetConstant{Val: 4096},
|
||||||
|
// Verdict is "ignore packet."
|
||||||
|
bpf.RetConstant{Val: 0},
|
||||||
|
})
|
||||||
|
|
||||||
|
This packet filter captures a random 1% sample of traffic.
|
||||||
|
|
||||||
|
bpf.Assemble([]bpf.Instruction{
|
||||||
|
// Get a 32-bit random number from the Linux kernel.
|
||||||
|
bpf.LoadExtension{Num: bpf.ExtRand},
|
||||||
|
// 1% dice roll?
|
||||||
|
bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
|
||||||
|
// Capture.
|
||||||
|
bpf.RetConstant{Val: 4096},
|
||||||
|
// Ignore.
|
||||||
|
bpf.RetConstant{Val: 0},
|
||||||
|
})
|
||||||
|
|
||||||
|
*/
|
||||||
|
package bpf // import "golang.org/x/net/bpf"
|
704
vendor/golang.org/x/net/bpf/instructions.go
generated
vendored
Normal file
704
vendor/golang.org/x/net/bpf/instructions.go
generated
vendored
Normal file
|
@ -0,0 +1,704 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// An Instruction is one instruction executed by the BPF virtual
|
||||||
|
// machine.
|
||||||
|
type Instruction interface {
|
||||||
|
// Assemble assembles the Instruction into a RawInstruction.
|
||||||
|
Assemble() (RawInstruction, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A RawInstruction is a raw BPF virtual machine instruction.
|
||||||
|
type RawInstruction struct {
|
||||||
|
// Operation to execute.
|
||||||
|
Op uint16
|
||||||
|
// For conditional jump instructions, the number of instructions
|
||||||
|
// to skip if the condition is true/false.
|
||||||
|
Jt uint8
|
||||||
|
Jf uint8
|
||||||
|
// Constant parameter. The meaning depends on the Op.
|
||||||
|
K uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil }
|
||||||
|
|
||||||
|
// Disassemble parses ri into an Instruction and returns it. If ri is
|
||||||
|
// not recognized by this package, ri itself is returned.
|
||||||
|
func (ri RawInstruction) Disassemble() Instruction {
|
||||||
|
switch ri.Op & opMaskCls {
|
||||||
|
case opClsLoadA, opClsLoadX:
|
||||||
|
reg := Register(ri.Op & opMaskLoadDest)
|
||||||
|
sz := 0
|
||||||
|
switch ri.Op & opMaskLoadWidth {
|
||||||
|
case opLoadWidth4:
|
||||||
|
sz = 4
|
||||||
|
case opLoadWidth2:
|
||||||
|
sz = 2
|
||||||
|
case opLoadWidth1:
|
||||||
|
sz = 1
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
switch ri.Op & opMaskLoadMode {
|
||||||
|
case opAddrModeImmediate:
|
||||||
|
if sz != 4 {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
return LoadConstant{Dst: reg, Val: ri.K}
|
||||||
|
case opAddrModeScratch:
|
||||||
|
if sz != 4 || ri.K > 15 {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
return LoadScratch{Dst: reg, N: int(ri.K)}
|
||||||
|
case opAddrModeAbsolute:
|
||||||
|
if ri.K > extOffset+0xffffffff {
|
||||||
|
return LoadExtension{Num: Extension(-extOffset + ri.K)}
|
||||||
|
}
|
||||||
|
return LoadAbsolute{Size: sz, Off: ri.K}
|
||||||
|
case opAddrModeIndirect:
|
||||||
|
return LoadIndirect{Size: sz, Off: ri.K}
|
||||||
|
case opAddrModePacketLen:
|
||||||
|
if sz != 4 {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
return LoadExtension{Num: ExtLen}
|
||||||
|
case opAddrModeMemShift:
|
||||||
|
return LoadMemShift{Off: ri.K}
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
|
case opClsStoreA:
|
||||||
|
if ri.Op != opClsStoreA || ri.K > 15 {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
return StoreScratch{Src: RegA, N: int(ri.K)}
|
||||||
|
|
||||||
|
case opClsStoreX:
|
||||||
|
if ri.Op != opClsStoreX || ri.K > 15 {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
return StoreScratch{Src: RegX, N: int(ri.K)}
|
||||||
|
|
||||||
|
case opClsALU:
|
||||||
|
switch op := ALUOp(ri.Op & opMaskOperator); op {
|
||||||
|
case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
|
||||||
|
if ri.Op&opMaskOperandSrc != 0 {
|
||||||
|
return ALUOpX{Op: op}
|
||||||
|
}
|
||||||
|
return ALUOpConstant{Op: op, Val: ri.K}
|
||||||
|
case aluOpNeg:
|
||||||
|
return NegateA{}
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
|
case opClsJump:
|
||||||
|
if ri.Op&opMaskJumpConst != opClsJump {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
switch ri.Op & opMaskJumpCond {
|
||||||
|
case opJumpAlways:
|
||||||
|
return Jump{Skip: ri.K}
|
||||||
|
case opJumpEqual:
|
||||||
|
if ri.Jt == 0 {
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpNotEqual,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jf,
|
||||||
|
SkipFalse: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpEqual,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jt,
|
||||||
|
SkipFalse: ri.Jf,
|
||||||
|
}
|
||||||
|
case opJumpGT:
|
||||||
|
if ri.Jt == 0 {
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpLessOrEqual,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jf,
|
||||||
|
SkipFalse: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpGreaterThan,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jt,
|
||||||
|
SkipFalse: ri.Jf,
|
||||||
|
}
|
||||||
|
case opJumpGE:
|
||||||
|
if ri.Jt == 0 {
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpLessThan,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jf,
|
||||||
|
SkipFalse: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpGreaterOrEqual,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jt,
|
||||||
|
SkipFalse: ri.Jf,
|
||||||
|
}
|
||||||
|
case opJumpSet:
|
||||||
|
return JumpIf{
|
||||||
|
Cond: JumpBitsSet,
|
||||||
|
Val: ri.K,
|
||||||
|
SkipTrue: ri.Jt,
|
||||||
|
SkipFalse: ri.Jf,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
|
case opClsReturn:
|
||||||
|
switch ri.Op {
|
||||||
|
case opClsReturn | opRetSrcA:
|
||||||
|
return RetA{}
|
||||||
|
case opClsReturn | opRetSrcConstant:
|
||||||
|
return RetConstant{Val: ri.K}
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
|
case opClsMisc:
|
||||||
|
switch ri.Op {
|
||||||
|
case opClsMisc | opMiscTAX:
|
||||||
|
return TAX{}
|
||||||
|
case opClsMisc | opMiscTXA:
|
||||||
|
return TXA{}
|
||||||
|
default:
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic("unreachable") // switch is exhaustive on the bit pattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConstant loads Val into register Dst.
|
||||||
|
type LoadConstant struct {
|
||||||
|
Dst Register
|
||||||
|
Val uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadConstant) Assemble() (RawInstruction, error) {
|
||||||
|
return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadConstant) String() string {
|
||||||
|
switch a.Dst {
|
||||||
|
case RegA:
|
||||||
|
return fmt.Sprintf("ld #%d", a.Val)
|
||||||
|
case RegX:
|
||||||
|
return fmt.Sprintf("ldx #%d", a.Val)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadScratch loads scratch[N] into register Dst.
|
||||||
|
type LoadScratch struct {
|
||||||
|
Dst Register
|
||||||
|
N int // 0-15
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadScratch) Assemble() (RawInstruction, error) {
|
||||||
|
if a.N < 0 || a.N > 15 {
|
||||||
|
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
||||||
|
}
|
||||||
|
return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadScratch) String() string {
|
||||||
|
switch a.Dst {
|
||||||
|
case RegA:
|
||||||
|
return fmt.Sprintf("ld M[%d]", a.N)
|
||||||
|
case RegX:
|
||||||
|
return fmt.Sprintf("ldx M[%d]", a.N)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAbsolute loads packet[Off:Off+Size] as an integer value into
|
||||||
|
// register A.
|
||||||
|
type LoadAbsolute struct {
|
||||||
|
Off uint32
|
||||||
|
Size int // 1, 2 or 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadAbsolute) Assemble() (RawInstruction, error) {
|
||||||
|
return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadAbsolute) String() string {
|
||||||
|
switch a.Size {
|
||||||
|
case 1: // byte
|
||||||
|
return fmt.Sprintf("ldb [%d]", a.Off)
|
||||||
|
case 2: // half word
|
||||||
|
return fmt.Sprintf("ldh [%d]", a.Off)
|
||||||
|
case 4: // word
|
||||||
|
if a.Off > extOffset+0xffffffff {
|
||||||
|
return LoadExtension{Num: Extension(a.Off + 0x1000)}.String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("ld [%d]", a.Off)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value
|
||||||
|
// into register A.
|
||||||
|
type LoadIndirect struct {
|
||||||
|
Off uint32
|
||||||
|
Size int // 1, 2 or 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadIndirect) Assemble() (RawInstruction, error) {
|
||||||
|
return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadIndirect) String() string {
|
||||||
|
switch a.Size {
|
||||||
|
case 1: // byte
|
||||||
|
return fmt.Sprintf("ldb [x + %d]", a.Off)
|
||||||
|
case 2: // half word
|
||||||
|
return fmt.Sprintf("ldh [x + %d]", a.Off)
|
||||||
|
case 4: // word
|
||||||
|
return fmt.Sprintf("ld [x + %d]", a.Off)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadMemShift multiplies the first 4 bits of the byte at packet[Off]
|
||||||
|
// by 4 and stores the result in register X.
|
||||||
|
//
|
||||||
|
// This instruction is mainly useful to load into X the length of an
|
||||||
|
// IPv4 packet header in a single instruction, rather than have to do
|
||||||
|
// the arithmetic on the header's first byte by hand.
|
||||||
|
type LoadMemShift struct {
|
||||||
|
Off uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadMemShift) Assemble() (RawInstruction, error) {
|
||||||
|
return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadMemShift) String() string {
|
||||||
|
return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadExtension invokes a linux-specific extension and stores the
|
||||||
|
// result in register A.
|
||||||
|
type LoadExtension struct {
|
||||||
|
Num Extension
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a LoadExtension) Assemble() (RawInstruction, error) {
|
||||||
|
if a.Num == ExtLen {
|
||||||
|
return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
|
||||||
|
}
|
||||||
|
return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a LoadExtension) String() string {
|
||||||
|
switch a.Num {
|
||||||
|
case ExtLen:
|
||||||
|
return "ld #len"
|
||||||
|
case ExtProto:
|
||||||
|
return "ld #proto"
|
||||||
|
case ExtType:
|
||||||
|
return "ld #type"
|
||||||
|
case ExtPayloadOffset:
|
||||||
|
return "ld #poff"
|
||||||
|
case ExtInterfaceIndex:
|
||||||
|
return "ld #ifidx"
|
||||||
|
case ExtNetlinkAttr:
|
||||||
|
return "ld #nla"
|
||||||
|
case ExtNetlinkAttrNested:
|
||||||
|
return "ld #nlan"
|
||||||
|
case ExtMark:
|
||||||
|
return "ld #mark"
|
||||||
|
case ExtQueue:
|
||||||
|
return "ld #queue"
|
||||||
|
case ExtLinkLayerType:
|
||||||
|
return "ld #hatype"
|
||||||
|
case ExtRXHash:
|
||||||
|
return "ld #rxhash"
|
||||||
|
case ExtCPUID:
|
||||||
|
return "ld #cpu"
|
||||||
|
case ExtVLANTag:
|
||||||
|
return "ld #vlan_tci"
|
||||||
|
case ExtVLANTagPresent:
|
||||||
|
return "ld #vlan_avail"
|
||||||
|
case ExtVLANProto:
|
||||||
|
return "ld #vlan_tpid"
|
||||||
|
case ExtRand:
|
||||||
|
return "ld #rand"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoreScratch stores register Src into scratch[N].
|
||||||
|
type StoreScratch struct {
|
||||||
|
Src Register
|
||||||
|
N int // 0-15
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a StoreScratch) Assemble() (RawInstruction, error) {
|
||||||
|
if a.N < 0 || a.N > 15 {
|
||||||
|
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
||||||
|
}
|
||||||
|
var op uint16
|
||||||
|
switch a.Src {
|
||||||
|
case RegA:
|
||||||
|
op = opClsStoreA
|
||||||
|
case RegX:
|
||||||
|
op = opClsStoreX
|
||||||
|
default:
|
||||||
|
return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src)
|
||||||
|
}
|
||||||
|
|
||||||
|
return RawInstruction{
|
||||||
|
Op: op,
|
||||||
|
K: uint32(a.N),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a StoreScratch) String() string {
|
||||||
|
switch a.Src {
|
||||||
|
case RegA:
|
||||||
|
return fmt.Sprintf("st M[%d]", a.N)
|
||||||
|
case RegX:
|
||||||
|
return fmt.Sprintf("stx M[%d]", a.N)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ALUOpConstant executes A = A <Op> Val.
|
||||||
|
type ALUOpConstant struct {
|
||||||
|
Op ALUOp
|
||||||
|
Val uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a ALUOpConstant) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsALU | opALUSrcConstant | uint16(a.Op),
|
||||||
|
K: a.Val,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a ALUOpConstant) String() string {
|
||||||
|
switch a.Op {
|
||||||
|
case ALUOpAdd:
|
||||||
|
return fmt.Sprintf("add #%d", a.Val)
|
||||||
|
case ALUOpSub:
|
||||||
|
return fmt.Sprintf("sub #%d", a.Val)
|
||||||
|
case ALUOpMul:
|
||||||
|
return fmt.Sprintf("mul #%d", a.Val)
|
||||||
|
case ALUOpDiv:
|
||||||
|
return fmt.Sprintf("div #%d", a.Val)
|
||||||
|
case ALUOpMod:
|
||||||
|
return fmt.Sprintf("mod #%d", a.Val)
|
||||||
|
case ALUOpAnd:
|
||||||
|
return fmt.Sprintf("and #%d", a.Val)
|
||||||
|
case ALUOpOr:
|
||||||
|
return fmt.Sprintf("or #%d", a.Val)
|
||||||
|
case ALUOpXor:
|
||||||
|
return fmt.Sprintf("xor #%d", a.Val)
|
||||||
|
case ALUOpShiftLeft:
|
||||||
|
return fmt.Sprintf("lsh #%d", a.Val)
|
||||||
|
case ALUOpShiftRight:
|
||||||
|
return fmt.Sprintf("rsh #%d", a.Val)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ALUOpX executes A = A <Op> X
|
||||||
|
type ALUOpX struct {
|
||||||
|
Op ALUOp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a ALUOpX) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsALU | opALUSrcX | uint16(a.Op),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a ALUOpX) String() string {
|
||||||
|
switch a.Op {
|
||||||
|
case ALUOpAdd:
|
||||||
|
return "add x"
|
||||||
|
case ALUOpSub:
|
||||||
|
return "sub x"
|
||||||
|
case ALUOpMul:
|
||||||
|
return "mul x"
|
||||||
|
case ALUOpDiv:
|
||||||
|
return "div x"
|
||||||
|
case ALUOpMod:
|
||||||
|
return "mod x"
|
||||||
|
case ALUOpAnd:
|
||||||
|
return "and x"
|
||||||
|
case ALUOpOr:
|
||||||
|
return "or x"
|
||||||
|
case ALUOpXor:
|
||||||
|
return "xor x"
|
||||||
|
case ALUOpShiftLeft:
|
||||||
|
return "lsh x"
|
||||||
|
case ALUOpShiftRight:
|
||||||
|
return "rsh x"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NegateA executes A = -A.
|
||||||
|
type NegateA struct{}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a NegateA) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsALU | uint16(aluOpNeg),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a NegateA) String() string {
|
||||||
|
return fmt.Sprintf("neg")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump skips the following Skip instructions in the program.
|
||||||
|
type Jump struct {
|
||||||
|
Skip uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a Jump) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsJump | opJumpAlways,
|
||||||
|
K: a.Skip,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a Jump) String() string {
|
||||||
|
return fmt.Sprintf("ja %d", a.Skip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// JumpIf skips the following Skip instructions in the program if A
|
||||||
|
// <Cond> Val is true.
|
||||||
|
type JumpIf struct {
|
||||||
|
Cond JumpTest
|
||||||
|
Val uint32
|
||||||
|
SkipTrue uint8
|
||||||
|
SkipFalse uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a JumpIf) Assemble() (RawInstruction, error) {
|
||||||
|
var (
|
||||||
|
cond uint16
|
||||||
|
flip bool
|
||||||
|
)
|
||||||
|
switch a.Cond {
|
||||||
|
case JumpEqual:
|
||||||
|
cond = opJumpEqual
|
||||||
|
case JumpNotEqual:
|
||||||
|
cond, flip = opJumpEqual, true
|
||||||
|
case JumpGreaterThan:
|
||||||
|
cond = opJumpGT
|
||||||
|
case JumpLessThan:
|
||||||
|
cond, flip = opJumpGE, true
|
||||||
|
case JumpGreaterOrEqual:
|
||||||
|
cond = opJumpGE
|
||||||
|
case JumpLessOrEqual:
|
||||||
|
cond, flip = opJumpGT, true
|
||||||
|
case JumpBitsSet:
|
||||||
|
cond = opJumpSet
|
||||||
|
case JumpBitsNotSet:
|
||||||
|
cond, flip = opJumpSet, true
|
||||||
|
default:
|
||||||
|
return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", a.Cond)
|
||||||
|
}
|
||||||
|
jt, jf := a.SkipTrue, a.SkipFalse
|
||||||
|
if flip {
|
||||||
|
jt, jf = jf, jt
|
||||||
|
}
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsJump | cond,
|
||||||
|
Jt: jt,
|
||||||
|
Jf: jf,
|
||||||
|
K: a.Val,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a JumpIf) String() string {
|
||||||
|
switch a.Cond {
|
||||||
|
// K == A
|
||||||
|
case JumpEqual:
|
||||||
|
return conditionalJump(a, "jeq", "jneq")
|
||||||
|
// K != A
|
||||||
|
case JumpNotEqual:
|
||||||
|
return fmt.Sprintf("jneq #%d,%d", a.Val, a.SkipTrue)
|
||||||
|
// K > A
|
||||||
|
case JumpGreaterThan:
|
||||||
|
return conditionalJump(a, "jgt", "jle")
|
||||||
|
// K < A
|
||||||
|
case JumpLessThan:
|
||||||
|
return fmt.Sprintf("jlt #%d,%d", a.Val, a.SkipTrue)
|
||||||
|
// K >= A
|
||||||
|
case JumpGreaterOrEqual:
|
||||||
|
return conditionalJump(a, "jge", "jlt")
|
||||||
|
// K <= A
|
||||||
|
case JumpLessOrEqual:
|
||||||
|
return fmt.Sprintf("jle #%d,%d", a.Val, a.SkipTrue)
|
||||||
|
// K & A != 0
|
||||||
|
case JumpBitsSet:
|
||||||
|
if a.SkipFalse > 0 {
|
||||||
|
return fmt.Sprintf("jset #%d,%d,%d", a.Val, a.SkipTrue, a.SkipFalse)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("jset #%d,%d", a.Val, a.SkipTrue)
|
||||||
|
// K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
|
||||||
|
case JumpBitsNotSet:
|
||||||
|
return JumpIf{Cond: JumpBitsSet, SkipTrue: a.SkipFalse, SkipFalse: a.SkipTrue, Val: a.Val}.String()
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func conditionalJump(inst JumpIf, positiveJump, negativeJump string) string {
|
||||||
|
if inst.SkipTrue > 0 {
|
||||||
|
if inst.SkipFalse > 0 {
|
||||||
|
return fmt.Sprintf("%s #%d,%d,%d", positiveJump, inst.Val, inst.SkipTrue, inst.SkipFalse)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s #%d,%d", positiveJump, inst.Val, inst.SkipTrue)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s #%d,%d", negativeJump, inst.Val, inst.SkipFalse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetA exits the BPF program, returning the value of register A.
|
||||||
|
type RetA struct{}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a RetA) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsReturn | opRetSrcA,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a RetA) String() string {
|
||||||
|
return fmt.Sprintf("ret a")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetConstant exits the BPF program, returning a constant value.
|
||||||
|
type RetConstant struct {
|
||||||
|
Val uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a RetConstant) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsReturn | opRetSrcConstant,
|
||||||
|
K: a.Val,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a RetConstant) String() string {
|
||||||
|
return fmt.Sprintf("ret #%d", a.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TXA copies the value of register X to register A.
|
||||||
|
type TXA struct{}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a TXA) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsMisc | opMiscTXA,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a TXA) String() string {
|
||||||
|
return fmt.Sprintf("txa")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TAX copies the value of register A to register X.
|
||||||
|
type TAX struct{}
|
||||||
|
|
||||||
|
// Assemble implements the Instruction Assemble method.
|
||||||
|
func (a TAX) Assemble() (RawInstruction, error) {
|
||||||
|
return RawInstruction{
|
||||||
|
Op: opClsMisc | opMiscTAX,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the instruction in assembler notation.
|
||||||
|
func (a TAX) String() string {
|
||||||
|
return fmt.Sprintf("tax")
|
||||||
|
}
|
||||||
|
|
||||||
|
func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) {
|
||||||
|
var (
|
||||||
|
cls uint16
|
||||||
|
sz uint16
|
||||||
|
)
|
||||||
|
switch dst {
|
||||||
|
case RegA:
|
||||||
|
cls = opClsLoadA
|
||||||
|
case RegX:
|
||||||
|
cls = opClsLoadX
|
||||||
|
default:
|
||||||
|
return RawInstruction{}, fmt.Errorf("invalid target register %v", dst)
|
||||||
|
}
|
||||||
|
switch loadSize {
|
||||||
|
case 1:
|
||||||
|
sz = opLoadWidth1
|
||||||
|
case 2:
|
||||||
|
sz = opLoadWidth2
|
||||||
|
case 4:
|
||||||
|
sz = opLoadWidth4
|
||||||
|
default:
|
||||||
|
return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz)
|
||||||
|
}
|
||||||
|
return RawInstruction{
|
||||||
|
Op: cls | sz | mode,
|
||||||
|
K: k,
|
||||||
|
}, nil
|
||||||
|
}
|
10
vendor/golang.org/x/net/bpf/setter.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/bpf/setter.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
// A Setter is a type which can attach a compiled BPF filter to itself.
|
||||||
|
type Setter interface {
|
||||||
|
SetBPF(filter []RawInstruction) error
|
||||||
|
}
|
140
vendor/golang.org/x/net/bpf/vm.go
generated
vendored
Normal file
140
vendor/golang.org/x/net/bpf/vm.go
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A VM is an emulated BPF virtual machine.
|
||||||
|
type VM struct {
|
||||||
|
filter []Instruction
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVM returns a new VM using the input BPF program.
|
||||||
|
func NewVM(filter []Instruction) (*VM, error) {
|
||||||
|
if len(filter) == 0 {
|
||||||
|
return nil, errors.New("one or more Instructions must be specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, ins := range filter {
|
||||||
|
check := len(filter) - (i + 1)
|
||||||
|
switch ins := ins.(type) {
|
||||||
|
// Check for out-of-bounds jumps in instructions
|
||||||
|
case Jump:
|
||||||
|
if check <= int(ins.Skip) {
|
||||||
|
return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip)
|
||||||
|
}
|
||||||
|
case JumpIf:
|
||||||
|
if check <= int(ins.SkipTrue) {
|
||||||
|
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
|
||||||
|
}
|
||||||
|
if check <= int(ins.SkipFalse) {
|
||||||
|
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
|
||||||
|
}
|
||||||
|
// Check for division or modulus by zero
|
||||||
|
case ALUOpConstant:
|
||||||
|
if ins.Val != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ins.Op {
|
||||||
|
case ALUOpDiv, ALUOpMod:
|
||||||
|
return nil, errors.New("cannot divide by zero using ALUOpConstant")
|
||||||
|
}
|
||||||
|
// Check for unknown extensions
|
||||||
|
case LoadExtension:
|
||||||
|
switch ins.Num {
|
||||||
|
case ExtLen:
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("extension %d not implemented", ins.Num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure last instruction is a return instruction
|
||||||
|
switch filter[len(filter)-1].(type) {
|
||||||
|
case RetA, RetConstant:
|
||||||
|
default:
|
||||||
|
return nil, errors.New("BPF program must end with RetA or RetConstant")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Though our VM works using disassembled instructions, we
|
||||||
|
// attempt to assemble the input filter anyway to ensure it is compatible
|
||||||
|
// with an operating system VM.
|
||||||
|
_, err := Assemble(filter)
|
||||||
|
|
||||||
|
return &VM{
|
||||||
|
filter: filter,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the VM's BPF program against the input bytes.
|
||||||
|
// Run returns the number of bytes accepted by the BPF program, and any errors
|
||||||
|
// which occurred while processing the program.
|
||||||
|
func (v *VM) Run(in []byte) (int, error) {
|
||||||
|
var (
|
||||||
|
// Registers of the virtual machine
|
||||||
|
regA uint32
|
||||||
|
regX uint32
|
||||||
|
regScratch [16]uint32
|
||||||
|
|
||||||
|
// OK is true if the program should continue processing the next
|
||||||
|
// instruction, or false if not, causing the loop to break
|
||||||
|
ok = true
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(mdlayher): implement:
|
||||||
|
// - NegateA:
|
||||||
|
// - would require a change from uint32 registers to int32
|
||||||
|
// registers
|
||||||
|
|
||||||
|
// TODO(mdlayher): add interop tests that check signedness of ALU
|
||||||
|
// operations against kernel implementation, and make sure Go
|
||||||
|
// implementation matches behavior
|
||||||
|
|
||||||
|
for i := 0; i < len(v.filter) && ok; i++ {
|
||||||
|
ins := v.filter[i]
|
||||||
|
|
||||||
|
switch ins := ins.(type) {
|
||||||
|
case ALUOpConstant:
|
||||||
|
regA = aluOpConstant(ins, regA)
|
||||||
|
case ALUOpX:
|
||||||
|
regA, ok = aluOpX(ins, regA, regX)
|
||||||
|
case Jump:
|
||||||
|
i += int(ins.Skip)
|
||||||
|
case JumpIf:
|
||||||
|
jump := jumpIf(ins, regA)
|
||||||
|
i += jump
|
||||||
|
case LoadAbsolute:
|
||||||
|
regA, ok = loadAbsolute(ins, in)
|
||||||
|
case LoadConstant:
|
||||||
|
regA, regX = loadConstant(ins, regA, regX)
|
||||||
|
case LoadExtension:
|
||||||
|
regA = loadExtension(ins, in)
|
||||||
|
case LoadIndirect:
|
||||||
|
regA, ok = loadIndirect(ins, in, regX)
|
||||||
|
case LoadMemShift:
|
||||||
|
regX, ok = loadMemShift(ins, in)
|
||||||
|
case LoadScratch:
|
||||||
|
regA, regX = loadScratch(ins, regScratch, regA, regX)
|
||||||
|
case RetA:
|
||||||
|
return int(regA), nil
|
||||||
|
case RetConstant:
|
||||||
|
return int(ins.Val), nil
|
||||||
|
case StoreScratch:
|
||||||
|
regScratch = storeScratch(ins, regScratch, regA, regX)
|
||||||
|
case TAX:
|
||||||
|
regX = regA
|
||||||
|
case TXA:
|
||||||
|
regA = regX
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, nil
|
||||||
|
}
|
174
vendor/golang.org/x/net/bpf/vm_instructions.go
generated
vendored
Normal file
174
vendor/golang.org/x/net/bpf/vm_instructions.go
generated
vendored
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package bpf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {
|
||||||
|
return aluOpCommon(ins.Op, regA, ins.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {
|
||||||
|
// Guard against division or modulus by zero by terminating
|
||||||
|
// the program, as the OS BPF VM does
|
||||||
|
if regX == 0 {
|
||||||
|
switch ins.Op {
|
||||||
|
case ALUOpDiv, ALUOpMod:
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aluOpCommon(ins.Op, regA, regX), true
|
||||||
|
}
|
||||||
|
|
||||||
|
func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
|
||||||
|
switch op {
|
||||||
|
case ALUOpAdd:
|
||||||
|
return regA + value
|
||||||
|
case ALUOpSub:
|
||||||
|
return regA - value
|
||||||
|
case ALUOpMul:
|
||||||
|
return regA * value
|
||||||
|
case ALUOpDiv:
|
||||||
|
// Division by zero not permitted by NewVM and aluOpX checks
|
||||||
|
return regA / value
|
||||||
|
case ALUOpOr:
|
||||||
|
return regA | value
|
||||||
|
case ALUOpAnd:
|
||||||
|
return regA & value
|
||||||
|
case ALUOpShiftLeft:
|
||||||
|
return regA << value
|
||||||
|
case ALUOpShiftRight:
|
||||||
|
return regA >> value
|
||||||
|
case ALUOpMod:
|
||||||
|
// Modulus by zero not permitted by NewVM and aluOpX checks
|
||||||
|
return regA % value
|
||||||
|
case ALUOpXor:
|
||||||
|
return regA ^ value
|
||||||
|
default:
|
||||||
|
return regA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func jumpIf(ins JumpIf, value uint32) int {
|
||||||
|
var ok bool
|
||||||
|
inV := uint32(ins.Val)
|
||||||
|
|
||||||
|
switch ins.Cond {
|
||||||
|
case JumpEqual:
|
||||||
|
ok = value == inV
|
||||||
|
case JumpNotEqual:
|
||||||
|
ok = value != inV
|
||||||
|
case JumpGreaterThan:
|
||||||
|
ok = value > inV
|
||||||
|
case JumpLessThan:
|
||||||
|
ok = value < inV
|
||||||
|
case JumpGreaterOrEqual:
|
||||||
|
ok = value >= inV
|
||||||
|
case JumpLessOrEqual:
|
||||||
|
ok = value <= inV
|
||||||
|
case JumpBitsSet:
|
||||||
|
ok = (value & inV) != 0
|
||||||
|
case JumpBitsNotSet:
|
||||||
|
ok = (value & inV) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return int(ins.SkipTrue)
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(ins.SkipFalse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
|
||||||
|
offset := int(ins.Off)
|
||||||
|
size := int(ins.Size)
|
||||||
|
|
||||||
|
return loadCommon(in, offset, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
|
||||||
|
switch ins.Dst {
|
||||||
|
case RegA:
|
||||||
|
regA = ins.Val
|
||||||
|
case RegX:
|
||||||
|
regX = ins.Val
|
||||||
|
}
|
||||||
|
|
||||||
|
return regA, regX
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadExtension(ins LoadExtension, in []byte) uint32 {
|
||||||
|
switch ins.Num {
|
||||||
|
case ExtLen:
|
||||||
|
return uint32(len(in))
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
|
||||||
|
offset := int(ins.Off) + int(regX)
|
||||||
|
size := int(ins.Size)
|
||||||
|
|
||||||
|
return loadCommon(in, offset, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {
|
||||||
|
offset := int(ins.Off)
|
||||||
|
|
||||||
|
if !inBounds(len(in), offset, 0) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask off high 4 bits and multiply low 4 bits by 4
|
||||||
|
return uint32(in[offset]&0x0f) * 4, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func inBounds(inLen int, offset int, size int) bool {
|
||||||
|
return offset+size <= inLen
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCommon(in []byte, offset int, size int) (uint32, bool) {
|
||||||
|
if !inBounds(len(in), offset, size) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch size {
|
||||||
|
case 1:
|
||||||
|
return uint32(in[offset]), true
|
||||||
|
case 2:
|
||||||
|
return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true
|
||||||
|
case 4:
|
||||||
|
return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid load size: %d", size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {
|
||||||
|
switch ins.Dst {
|
||||||
|
case RegA:
|
||||||
|
regA = regScratch[ins.N]
|
||||||
|
case RegX:
|
||||||
|
regX = regScratch[ins.N]
|
||||||
|
}
|
||||||
|
|
||||||
|
return regA, regX
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {
|
||||||
|
switch ins.Src {
|
||||||
|
case RegA:
|
||||||
|
regScratch[ins.N] = regA
|
||||||
|
case RegX:
|
||||||
|
regScratch[ins.N] = regX
|
||||||
|
}
|
||||||
|
|
||||||
|
return regScratch
|
||||||
|
}
|
2
vendor/golang.org/x/net/http2/ciphers.go
generated
vendored
2
vendor/golang.org/x/net/http2/ciphers.go
generated
vendored
|
@ -5,7 +5,7 @@
|
||||||
package http2
|
package http2
|
||||||
|
|
||||||
// A list of the possible cipher suite ids. Taken from
|
// A list of the possible cipher suite ids. Taken from
|
||||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
|
// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
|
cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
|
||||||
|
|
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
2
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
|
@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendHpackString appends s, as encoded in "String Literal"
|
// appendHpackString appends s, as encoded in "String Literal"
|
||||||
// representation, to dst and returns the the extended buffer.
|
// representation, to dst and returns the extended buffer.
|
||||||
//
|
//
|
||||||
// s will be encoded in Huffman codes only when it produces strictly
|
// s will be encoded in Huffman codes only when it produces strictly
|
||||||
// shorter byte string.
|
// shorter byte string.
|
||||||
|
|
2
vendor/golang.org/x/net/http2/http2.go
generated
vendored
2
vendor/golang.org/x/net/http2/http2.go
generated
vendored
|
@ -312,7 +312,7 @@ func mustUint31(v int32) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bodyAllowedForStatus reports whether a given response status code
|
// bodyAllowedForStatus reports whether a given response status code
|
||||||
// permits a body. See RFC 2616, section 4.4.
|
// permits a body. See RFC 7230, section 3.3.
|
||||||
func bodyAllowedForStatus(status int) bool {
|
func bodyAllowedForStatus(status int) bool {
|
||||||
switch {
|
switch {
|
||||||
case status >= 100 && status <= 199:
|
case status >= 100 && status <= 199:
|
||||||
|
|
8
vendor/golang.org/x/net/http2/server.go
generated
vendored
8
vendor/golang.org/x/net/http2/server.go
generated
vendored
|
@ -406,7 +406,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
|
||||||
// addresses during development.
|
// addresses during development.
|
||||||
//
|
//
|
||||||
// TODO: optionally enforce? Or enforce at the time we receive
|
// TODO: optionally enforce? Or enforce at the time we receive
|
||||||
// a new request, and verify the the ServerName matches the :authority?
|
// a new request, and verify the ServerName matches the :authority?
|
||||||
// But that precludes proxy situations, perhaps.
|
// But that precludes proxy situations, perhaps.
|
||||||
//
|
//
|
||||||
// So for now, do nothing here again.
|
// So for now, do nothing here again.
|
||||||
|
@ -2285,7 +2285,7 @@ func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) !=
|
||||||
func (rws *responseWriterState) declareTrailer(k string) {
|
func (rws *responseWriterState) declareTrailer(k string) {
|
||||||
k = http.CanonicalHeaderKey(k)
|
k = http.CanonicalHeaderKey(k)
|
||||||
if !ValidTrailerHeader(k) {
|
if !ValidTrailerHeader(k) {
|
||||||
// Forbidden by RFC 2616 14.40.
|
// Forbidden by RFC 7230, section 4.1.2.
|
||||||
rws.conn.logf("ignoring invalid trailer %q", k)
|
rws.conn.logf("ignoring invalid trailer %q", k)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2406,7 +2406,7 @@ const TrailerPrefix = "Trailer:"
|
||||||
// after the header has already been flushed. Because the Go
|
// after the header has already been flushed. Because the Go
|
||||||
// ResponseWriter interface has no way to set Trailers (only the
|
// ResponseWriter interface has no way to set Trailers (only the
|
||||||
// Header), and because we didn't want to expand the ResponseWriter
|
// Header), and because we didn't want to expand the ResponseWriter
|
||||||
// interface, and because nobody used trailers, and because RFC 2616
|
// interface, and because nobody used trailers, and because RFC 7230
|
||||||
// says you SHOULD (but not must) predeclare any trailers in the
|
// says you SHOULD (but not must) predeclare any trailers in the
|
||||||
// header, the official ResponseWriter rules said trailers in Go must
|
// header, the official ResponseWriter rules said trailers in Go must
|
||||||
// be predeclared, and then we reuse the same ResponseWriter.Header()
|
// be predeclared, and then we reuse the same ResponseWriter.Header()
|
||||||
|
@ -2790,7 +2790,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// foreachHeaderElement splits v according to the "#rule" construction
|
// foreachHeaderElement splits v according to the "#rule" construction
|
||||||
// in RFC 2616 section 2.1 and calls fn for each non-empty element.
|
// in RFC 7230 section 7 and calls fn for each non-empty element.
|
||||||
func foreachHeaderElement(v string, fn func(string)) {
|
func foreachHeaderElement(v string, fn func(string)) {
|
||||||
v = textproto.TrimString(v)
|
v = textproto.TrimString(v)
|
||||||
if v == "" {
|
if v == "" {
|
||||||
|
|
180
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
Normal file
180
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
// go generate gen.go
|
||||||
|
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
|
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
|
||||||
|
package iana // import "golang.org/x/net/internal/iana"
|
||||||
|
|
||||||
|
// Differentiated Services Field Codepoints (DSCP), Updated: 2017-05-12
|
||||||
|
const (
|
||||||
|
DiffServCS0 = 0x0 // CS0
|
||||||
|
DiffServCS1 = 0x20 // CS1
|
||||||
|
DiffServCS2 = 0x40 // CS2
|
||||||
|
DiffServCS3 = 0x60 // CS3
|
||||||
|
DiffServCS4 = 0x80 // CS4
|
||||||
|
DiffServCS5 = 0xa0 // CS5
|
||||||
|
DiffServCS6 = 0xc0 // CS6
|
||||||
|
DiffServCS7 = 0xe0 // CS7
|
||||||
|
DiffServAF11 = 0x28 // AF11
|
||||||
|
DiffServAF12 = 0x30 // AF12
|
||||||
|
DiffServAF13 = 0x38 // AF13
|
||||||
|
DiffServAF21 = 0x48 // AF21
|
||||||
|
DiffServAF22 = 0x50 // AF22
|
||||||
|
DiffServAF23 = 0x58 // AF23
|
||||||
|
DiffServAF31 = 0x68 // AF31
|
||||||
|
DiffServAF32 = 0x70 // AF32
|
||||||
|
DiffServAF33 = 0x78 // AF33
|
||||||
|
DiffServAF41 = 0x88 // AF41
|
||||||
|
DiffServAF42 = 0x90 // AF42
|
||||||
|
DiffServAF43 = 0x98 // AF43
|
||||||
|
DiffServEF = 0xb8 // EF
|
||||||
|
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
|
||||||
|
const (
|
||||||
|
NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
|
||||||
|
ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
|
||||||
|
ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
|
||||||
|
CongestionExperienced = 0x3 // CE (Congestion Experienced)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Protocol Numbers, Updated: 2016-06-22
|
||||||
|
const (
|
||||||
|
ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number
|
||||||
|
ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
|
||||||
|
ProtocolICMP = 1 // Internet Control Message
|
||||||
|
ProtocolIGMP = 2 // Internet Group Management
|
||||||
|
ProtocolGGP = 3 // Gateway-to-Gateway
|
||||||
|
ProtocolIPv4 = 4 // IPv4 encapsulation
|
||||||
|
ProtocolST = 5 // Stream
|
||||||
|
ProtocolTCP = 6 // Transmission Control
|
||||||
|
ProtocolCBT = 7 // CBT
|
||||||
|
ProtocolEGP = 8 // Exterior Gateway Protocol
|
||||||
|
ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
||||||
|
ProtocolBBNRCCMON = 10 // BBN RCC Monitoring
|
||||||
|
ProtocolNVPII = 11 // Network Voice Protocol
|
||||||
|
ProtocolPUP = 12 // PUP
|
||||||
|
ProtocolEMCON = 14 // EMCON
|
||||||
|
ProtocolXNET = 15 // Cross Net Debugger
|
||||||
|
ProtocolCHAOS = 16 // Chaos
|
||||||
|
ProtocolUDP = 17 // User Datagram
|
||||||
|
ProtocolMUX = 18 // Multiplexing
|
||||||
|
ProtocolDCNMEAS = 19 // DCN Measurement Subsystems
|
||||||
|
ProtocolHMP = 20 // Host Monitoring
|
||||||
|
ProtocolPRM = 21 // Packet Radio Measurement
|
||||||
|
ProtocolXNSIDP = 22 // XEROX NS IDP
|
||||||
|
ProtocolTRUNK1 = 23 // Trunk-1
|
||||||
|
ProtocolTRUNK2 = 24 // Trunk-2
|
||||||
|
ProtocolLEAF1 = 25 // Leaf-1
|
||||||
|
ProtocolLEAF2 = 26 // Leaf-2
|
||||||
|
ProtocolRDP = 27 // Reliable Data Protocol
|
||||||
|
ProtocolIRTP = 28 // Internet Reliable Transaction
|
||||||
|
ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
|
||||||
|
ProtocolNETBLT = 30 // Bulk Data Transfer Protocol
|
||||||
|
ProtocolMFENSP = 31 // MFE Network Services Protocol
|
||||||
|
ProtocolMERITINP = 32 // MERIT Internodal Protocol
|
||||||
|
ProtocolDCCP = 33 // Datagram Congestion Control Protocol
|
||||||
|
Protocol3PC = 34 // Third Party Connect Protocol
|
||||||
|
ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
|
||||||
|
ProtocolXTP = 36 // XTP
|
||||||
|
ProtocolDDP = 37 // Datagram Delivery Protocol
|
||||||
|
ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
|
||||||
|
ProtocolTPPP = 39 // TP++ Transport Protocol
|
||||||
|
ProtocolIL = 40 // IL Transport Protocol
|
||||||
|
ProtocolIPv6 = 41 // IPv6 encapsulation
|
||||||
|
ProtocolSDRP = 42 // Source Demand Routing Protocol
|
||||||
|
ProtocolIPv6Route = 43 // Routing Header for IPv6
|
||||||
|
ProtocolIPv6Frag = 44 // Fragment Header for IPv6
|
||||||
|
ProtocolIDRP = 45 // Inter-Domain Routing Protocol
|
||||||
|
ProtocolRSVP = 46 // Reservation Protocol
|
||||||
|
ProtocolGRE = 47 // Generic Routing Encapsulation
|
||||||
|
ProtocolDSR = 48 // Dynamic Source Routing Protocol
|
||||||
|
ProtocolBNA = 49 // BNA
|
||||||
|
ProtocolESP = 50 // Encap Security Payload
|
||||||
|
ProtocolAH = 51 // Authentication Header
|
||||||
|
ProtocolINLSP = 52 // Integrated Net Layer Security TUBA
|
||||||
|
ProtocolNARP = 54 // NBMA Address Resolution Protocol
|
||||||
|
ProtocolMOBILE = 55 // IP Mobility
|
||||||
|
ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
|
||||||
|
ProtocolSKIP = 57 // SKIP
|
||||||
|
ProtocolIPv6ICMP = 58 // ICMP for IPv6
|
||||||
|
ProtocolIPv6NoNxt = 59 // No Next Header for IPv6
|
||||||
|
ProtocolIPv6Opts = 60 // Destination Options for IPv6
|
||||||
|
ProtocolCFTP = 62 // CFTP
|
||||||
|
ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
|
||||||
|
ProtocolKRYPTOLAN = 65 // Kryptolan
|
||||||
|
ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
|
||||||
|
ProtocolIPPC = 67 // Internet Pluribus Packet Core
|
||||||
|
ProtocolSATMON = 69 // SATNET Monitoring
|
||||||
|
ProtocolVISA = 70 // VISA Protocol
|
||||||
|
ProtocolIPCV = 71 // Internet Packet Core Utility
|
||||||
|
ProtocolCPNX = 72 // Computer Protocol Network Executive
|
||||||
|
ProtocolCPHB = 73 // Computer Protocol Heart Beat
|
||||||
|
ProtocolWSN = 74 // Wang Span Network
|
||||||
|
ProtocolPVP = 75 // Packet Video Protocol
|
||||||
|
ProtocolBRSATMON = 76 // Backroom SATNET Monitoring
|
||||||
|
ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
|
||||||
|
ProtocolWBMON = 78 // WIDEBAND Monitoring
|
||||||
|
ProtocolWBEXPAK = 79 // WIDEBAND EXPAK
|
||||||
|
ProtocolISOIP = 80 // ISO Internet Protocol
|
||||||
|
ProtocolVMTP = 81 // VMTP
|
||||||
|
ProtocolSECUREVMTP = 82 // SECURE-VMTP
|
||||||
|
ProtocolVINES = 83 // VINES
|
||||||
|
ProtocolTTP = 84 // Transaction Transport Protocol
|
||||||
|
ProtocolIPTM = 84 // Internet Protocol Traffic Manager
|
||||||
|
ProtocolNSFNETIGP = 85 // NSFNET-IGP
|
||||||
|
ProtocolDGP = 86 // Dissimilar Gateway Protocol
|
||||||
|
ProtocolTCF = 87 // TCF
|
||||||
|
ProtocolEIGRP = 88 // EIGRP
|
||||||
|
ProtocolOSPFIGP = 89 // OSPFIGP
|
||||||
|
ProtocolSpriteRPC = 90 // Sprite RPC Protocol
|
||||||
|
ProtocolLARP = 91 // Locus Address Resolution Protocol
|
||||||
|
ProtocolMTP = 92 // Multicast Transport Protocol
|
||||||
|
ProtocolAX25 = 93 // AX.25 Frames
|
||||||
|
ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
|
||||||
|
ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
|
||||||
|
ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
|
||||||
|
ProtocolENCAP = 98 // Encapsulation Header
|
||||||
|
ProtocolGMTP = 100 // GMTP
|
||||||
|
ProtocolIFMP = 101 // Ipsilon Flow Management Protocol
|
||||||
|
ProtocolPNNI = 102 // PNNI over IP
|
||||||
|
ProtocolPIM = 103 // Protocol Independent Multicast
|
||||||
|
ProtocolARIS = 104 // ARIS
|
||||||
|
ProtocolSCPS = 105 // SCPS
|
||||||
|
ProtocolQNX = 106 // QNX
|
||||||
|
ProtocolAN = 107 // Active Networks
|
||||||
|
ProtocolIPComp = 108 // IP Payload Compression Protocol
|
||||||
|
ProtocolSNP = 109 // Sitara Networks Protocol
|
||||||
|
ProtocolCompaqPeer = 110 // Compaq Peer Protocol
|
||||||
|
ProtocolIPXinIP = 111 // IPX in IP
|
||||||
|
ProtocolVRRP = 112 // Virtual Router Redundancy Protocol
|
||||||
|
ProtocolPGM = 113 // PGM Reliable Transport Protocol
|
||||||
|
ProtocolL2TP = 115 // Layer Two Tunneling Protocol
|
||||||
|
ProtocolDDX = 116 // D-II Data Exchange (DDX)
|
||||||
|
ProtocolIATP = 117 // Interactive Agent Transfer Protocol
|
||||||
|
ProtocolSTP = 118 // Schedule Transfer Protocol
|
||||||
|
ProtocolSRP = 119 // SpectraLink Radio Protocol
|
||||||
|
ProtocolUTI = 120 // UTI
|
||||||
|
ProtocolSMP = 121 // Simple Message Protocol
|
||||||
|
ProtocolPTP = 123 // Performance Transparency Protocol
|
||||||
|
ProtocolISIS = 124 // ISIS over IPv4
|
||||||
|
ProtocolFIRE = 125 // FIRE
|
||||||
|
ProtocolCRTP = 126 // Combat Radio Transport Protocol
|
||||||
|
ProtocolCRUDP = 127 // Combat Radio User Datagram
|
||||||
|
ProtocolSSCOPMCE = 128 // SSCOPMCE
|
||||||
|
ProtocolIPLT = 129 // IPLT
|
||||||
|
ProtocolSPS = 130 // Secure Packet Shield
|
||||||
|
ProtocolPIPE = 131 // Private IP Encapsulation within IP
|
||||||
|
ProtocolSCTP = 132 // Stream Control Transmission Protocol
|
||||||
|
ProtocolFC = 133 // Fibre Channel
|
||||||
|
ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
|
||||||
|
ProtocolMobilityHeader = 135 // Mobility Header
|
||||||
|
ProtocolUDPLite = 136 // UDPLite
|
||||||
|
ProtocolMPLSinIP = 137 // MPLS-in-IP
|
||||||
|
ProtocolMANET = 138 // MANET Protocols
|
||||||
|
ProtocolHIP = 139 // Host Identity Protocol
|
||||||
|
ProtocolShim6 = 140 // Shim6 Protocol
|
||||||
|
ProtocolWESP = 141 // Wrapped Encapsulating Security Payload
|
||||||
|
ProtocolROHC = 142 // Robust Header Compression
|
||||||
|
ProtocolReserved = 255 // Reserved
|
||||||
|
)
|
293
vendor/golang.org/x/net/internal/iana/gen.go
generated
vendored
Normal file
293
vendor/golang.org/x/net/internal/iana/gen.go
generated
vendored
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
//go:generate go run gen.go
|
||||||
|
|
||||||
|
// This program generates internet protocol constants and tables by
|
||||||
|
// reading IANA protocol registries.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var registries = []struct {
|
||||||
|
url string
|
||||||
|
parse func(io.Writer, io.Reader) error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"https://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
||||||
|
parseDSCPRegistry,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"https://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
||||||
|
parseTOSTCByte,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
|
||||||
|
parseProtocolNumbers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var bb bytes.Buffer
|
||||||
|
fmt.Fprintf(&bb, "// go generate gen.go\n")
|
||||||
|
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
||||||
|
fmt.Fprintf(&bb, "// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\n")
|
||||||
|
fmt.Fprintf(&bb, `package iana // import "golang.org/x/net/internal/iana"`+"\n\n")
|
||||||
|
for _, r := range registries {
|
||||||
|
resp, err := http.Get(r.url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := r.parse(&bb, resp.Body); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&bb, "\n")
|
||||||
|
}
|
||||||
|
b, err := format.Source(bb.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile("const.go", b, 0644); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
||||||
|
dec := xml.NewDecoder(r)
|
||||||
|
var dr dscpRegistry
|
||||||
|
if err := dec.Decode(&dr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
drs := dr.escape()
|
||||||
|
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
||||||
|
fmt.Fprintf(w, "const (\n")
|
||||||
|
for _, dr := range drs {
|
||||||
|
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
||||||
|
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, ")\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type dscpRegistry struct {
|
||||||
|
XMLName xml.Name `xml:"registry"`
|
||||||
|
Title string `xml:"title"`
|
||||||
|
Updated string `xml:"updated"`
|
||||||
|
Note string `xml:"note"`
|
||||||
|
RegTitle string `xml:"registry>title"`
|
||||||
|
PoolRecords []struct {
|
||||||
|
Name string `xml:"name"`
|
||||||
|
Space string `xml:"space"`
|
||||||
|
} `xml:"registry>record"`
|
||||||
|
Records []struct {
|
||||||
|
Name string `xml:"name"`
|
||||||
|
Space string `xml:"space"`
|
||||||
|
} `xml:"registry>registry>record"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type canonDSCPRecord struct {
|
||||||
|
OrigName string
|
||||||
|
Name string
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
||||||
|
drs := make([]canonDSCPRecord, len(drr.Records))
|
||||||
|
sr := strings.NewReplacer(
|
||||||
|
"+", "",
|
||||||
|
"-", "",
|
||||||
|
"/", "",
|
||||||
|
".", "",
|
||||||
|
" ", "",
|
||||||
|
)
|
||||||
|
for i, dr := range drr.Records {
|
||||||
|
s := strings.TrimSpace(dr.Name)
|
||||||
|
drs[i].OrigName = s
|
||||||
|
drs[i].Name = sr.Replace(s)
|
||||||
|
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
drs[i].Value = int(n) << 2
|
||||||
|
}
|
||||||
|
return drs
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
||||||
|
dec := xml.NewDecoder(r)
|
||||||
|
var ttb tosTCByte
|
||||||
|
if err := dec.Decode(&ttb); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
trs := ttb.escape()
|
||||||
|
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
||||||
|
fmt.Fprintf(w, "const (\n")
|
||||||
|
for _, tr := range trs {
|
||||||
|
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
||||||
|
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, ")\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tosTCByte struct {
|
||||||
|
XMLName xml.Name `xml:"registry"`
|
||||||
|
Title string `xml:"title"`
|
||||||
|
Updated string `xml:"updated"`
|
||||||
|
Note string `xml:"note"`
|
||||||
|
RegTitle string `xml:"registry>title"`
|
||||||
|
Records []struct {
|
||||||
|
Binary string `xml:"binary"`
|
||||||
|
Keyword string `xml:"keyword"`
|
||||||
|
} `xml:"registry>record"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type canonTOSTCByteRecord struct {
|
||||||
|
OrigKeyword string
|
||||||
|
Keyword string
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
||||||
|
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
||||||
|
sr := strings.NewReplacer(
|
||||||
|
"Capable", "",
|
||||||
|
"(", "",
|
||||||
|
")", "",
|
||||||
|
"+", "",
|
||||||
|
"-", "",
|
||||||
|
"/", "",
|
||||||
|
".", "",
|
||||||
|
" ", "",
|
||||||
|
)
|
||||||
|
for i, tr := range ttb.Records {
|
||||||
|
s := strings.TrimSpace(tr.Keyword)
|
||||||
|
trs[i].OrigKeyword = s
|
||||||
|
ss := strings.Split(s, " ")
|
||||||
|
if len(ss) > 1 {
|
||||||
|
trs[i].Keyword = strings.Join(ss[1:], " ")
|
||||||
|
} else {
|
||||||
|
trs[i].Keyword = ss[0]
|
||||||
|
}
|
||||||
|
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
||||||
|
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
trs[i].Value = int(n)
|
||||||
|
}
|
||||||
|
return trs
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseProtocolNumbers(w io.Writer, r io.Reader) error {
|
||||||
|
dec := xml.NewDecoder(r)
|
||||||
|
var pn protocolNumbers
|
||||||
|
if err := dec.Decode(&pn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
prs := pn.escape()
|
||||||
|
prs = append([]canonProtocolRecord{{
|
||||||
|
Name: "IP",
|
||||||
|
Descr: "IPv4 encapsulation, pseudo protocol number",
|
||||||
|
Value: 0,
|
||||||
|
}}, prs...)
|
||||||
|
fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated)
|
||||||
|
fmt.Fprintf(w, "const (\n")
|
||||||
|
for _, pr := range prs {
|
||||||
|
if pr.Name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "Protocol%s = %d", pr.Name, pr.Value)
|
||||||
|
s := pr.Descr
|
||||||
|
if s == "" {
|
||||||
|
s = pr.OrigName
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "// %s\n", s)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, ")\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type protocolNumbers struct {
|
||||||
|
XMLName xml.Name `xml:"registry"`
|
||||||
|
Title string `xml:"title"`
|
||||||
|
Updated string `xml:"updated"`
|
||||||
|
RegTitle string `xml:"registry>title"`
|
||||||
|
Note string `xml:"registry>note"`
|
||||||
|
Records []struct {
|
||||||
|
Value string `xml:"value"`
|
||||||
|
Name string `xml:"name"`
|
||||||
|
Descr string `xml:"description"`
|
||||||
|
} `xml:"registry>record"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type canonProtocolRecord struct {
|
||||||
|
OrigName string
|
||||||
|
Name string
|
||||||
|
Descr string
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pn *protocolNumbers) escape() []canonProtocolRecord {
|
||||||
|
prs := make([]canonProtocolRecord, len(pn.Records))
|
||||||
|
sr := strings.NewReplacer(
|
||||||
|
"-in-", "in",
|
||||||
|
"-within-", "within",
|
||||||
|
"-over-", "over",
|
||||||
|
"+", "P",
|
||||||
|
"-", "",
|
||||||
|
"/", "",
|
||||||
|
".", "",
|
||||||
|
" ", "",
|
||||||
|
)
|
||||||
|
for i, pr := range pn.Records {
|
||||||
|
if strings.Contains(pr.Name, "Deprecated") ||
|
||||||
|
strings.Contains(pr.Name, "deprecated") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
prs[i].OrigName = pr.Name
|
||||||
|
s := strings.TrimSpace(pr.Name)
|
||||||
|
switch pr.Name {
|
||||||
|
case "ISIS over IPv4":
|
||||||
|
prs[i].Name = "ISIS"
|
||||||
|
case "manet":
|
||||||
|
prs[i].Name = "MANET"
|
||||||
|
default:
|
||||||
|
prs[i].Name = sr.Replace(s)
|
||||||
|
}
|
||||||
|
ss := strings.Split(pr.Descr, "\n")
|
||||||
|
for i := range ss {
|
||||||
|
ss[i] = strings.TrimSpace(ss[i])
|
||||||
|
}
|
||||||
|
if len(ss) > 1 {
|
||||||
|
prs[i].Descr = strings.Join(ss, " ")
|
||||||
|
} else {
|
||||||
|
prs[i].Descr = ss[0]
|
||||||
|
}
|
||||||
|
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
||||||
|
}
|
||||||
|
return prs
|
||||||
|
}
|
11
vendor/golang.org/x/net/internal/socket/cmsghdr.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/cmsghdr.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *cmsghdr) len() int { return int(h.Len) }
|
||||||
|
func (h *cmsghdr) lvl() int { return int(h.Level) }
|
||||||
|
func (h *cmsghdr) typ() int { return int(h.Type) }
|
13
vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd netbsd openbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||||
|
h.Len = uint32(l)
|
||||||
|
h.Level = int32(lvl)
|
||||||
|
h.Type = int32(typ)
|
||||||
|
}
|
14
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm mips mipsle 386
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||||
|
h.Len = uint32(l)
|
||||||
|
h.Level = int32(lvl)
|
||||||
|
h.Type = int32(typ)
|
||||||
|
}
|
14
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||||
|
h.Len = uint64(l)
|
||||||
|
h.Level = int32(lvl)
|
||||||
|
h.Type = int32(typ)
|
||||||
|
}
|
14
vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||||
|
h.Len = uint32(l)
|
||||||
|
h.Level = int32(lvl)
|
||||||
|
h.Type = int32(typ)
|
||||||
|
}
|
17
vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
generated
vendored
Normal file
17
vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
type cmsghdr struct{}
|
||||||
|
|
||||||
|
const sizeofCmsghdr = 0
|
||||||
|
|
||||||
|
func (h *cmsghdr) len() int { return 0 }
|
||||||
|
func (h *cmsghdr) lvl() int { return 0 }
|
||||||
|
func (h *cmsghdr) typ() int { return 0 }
|
||||||
|
|
||||||
|
func (h *cmsghdr) set(l, lvl, typ int) {}
|
44
vendor/golang.org/x/net/internal/socket/defs_darwin.go
generated
vendored
Normal file
44
vendor/golang.org/x/net/internal/socket/defs_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
44
vendor/golang.org/x/net/internal/socket/defs_dragonfly.go
generated
vendored
Normal file
44
vendor/golang.org/x/net/internal/socket/defs_dragonfly.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
44
vendor/golang.org/x/net/internal/socket/defs_freebsd.go
generated
vendored
Normal file
44
vendor/golang.org/x/net/internal/socket/defs_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
49
vendor/golang.org/x/net/internal/socket/defs_linux.go
generated
vendored
Normal file
49
vendor/golang.org/x/net/internal/socket/defs_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <linux/in.h>
|
||||||
|
#include <linux/in6.h>
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <sys/socket.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type mmsghdr C.struct_mmsghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofMmsghdr = C.sizeof_struct_mmsghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
47
vendor/golang.org/x/net/internal/socket/defs_netbsd.go
generated
vendored
Normal file
47
vendor/golang.org/x/net/internal/socket/defs_netbsd.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type mmsghdr C.struct_mmsghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofMmsghdr = C.sizeof_struct_mmsghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
44
vendor/golang.org/x/net/internal/socket/defs_openbsd.go
generated
vendored
Normal file
44
vendor/golang.org/x/net/internal/socket/defs_openbsd.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
44
vendor/golang.org/x/net/internal/socket/defs_solaris.go
generated
vendored
Normal file
44
vendor/golang.org/x/net/internal/socket/defs_solaris.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
sysAF_UNSPEC = C.AF_UNSPEC
|
||||||
|
sysAF_INET = C.AF_INET
|
||||||
|
sysAF_INET6 = C.AF_INET6
|
||||||
|
|
||||||
|
sysSOCK_RAW = C.SOCK_RAW
|
||||||
|
)
|
||||||
|
|
||||||
|
type iovec C.struct_iovec
|
||||||
|
|
||||||
|
type msghdr C.struct_msghdr
|
||||||
|
|
||||||
|
type cmsghdr C.struct_cmsghdr
|
||||||
|
|
||||||
|
type sockaddrInet C.struct_sockaddr_in
|
||||||
|
|
||||||
|
type sockaddrInet6 C.struct_sockaddr_in6
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofIovec = C.sizeof_struct_iovec
|
||||||
|
sizeofMsghdr = C.sizeof_struct_msghdr
|
||||||
|
sizeofCmsghdr = C.sizeof_struct_cmsghdr
|
||||||
|
|
||||||
|
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
|
||||||
|
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
||||||
|
)
|
31
vendor/golang.org/x/net/internal/socket/error_unix.go
generated
vendored
Normal file
31
vendor/golang.org/x/net/internal/socket/error_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
var (
|
||||||
|
errEAGAIN error = syscall.EAGAIN
|
||||||
|
errEINVAL error = syscall.EINVAL
|
||||||
|
errENOENT error = syscall.ENOENT
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnoErr returns common boxed Errno values, to prevent allocations
|
||||||
|
// at runtime.
|
||||||
|
func errnoErr(errno syscall.Errno) error {
|
||||||
|
switch errno {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case syscall.EAGAIN:
|
||||||
|
return errEAGAIN
|
||||||
|
case syscall.EINVAL:
|
||||||
|
return errEINVAL
|
||||||
|
case syscall.ENOENT:
|
||||||
|
return errENOENT
|
||||||
|
}
|
||||||
|
return errno
|
||||||
|
}
|
26
vendor/golang.org/x/net/internal/socket/error_windows.go
generated
vendored
Normal file
26
vendor/golang.org/x/net/internal/socket/error_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
var (
|
||||||
|
errERROR_IO_PENDING error = syscall.ERROR_IO_PENDING
|
||||||
|
errEINVAL error = syscall.EINVAL
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnoErr returns common boxed Errno values, to prevent allocations
|
||||||
|
// at runtime.
|
||||||
|
func errnoErr(errno syscall.Errno) error {
|
||||||
|
switch errno {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case syscall.ERROR_IO_PENDING:
|
||||||
|
return errERROR_IO_PENDING
|
||||||
|
case syscall.EINVAL:
|
||||||
|
return errEINVAL
|
||||||
|
}
|
||||||
|
return errno
|
||||||
|
}
|
19
vendor/golang.org/x/net/internal/socket/iovec_32bit.go
generated
vendored
Normal file
19
vendor/golang.org/x/net/internal/socket/iovec_32bit.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm mips mipsle 386
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (v *iovec) set(b []byte) {
|
||||||
|
l := len(b)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v.Base = (*byte)(unsafe.Pointer(&b[0]))
|
||||||
|
v.Len = uint32(l)
|
||||||
|
}
|
19
vendor/golang.org/x/net/internal/socket/iovec_64bit.go
generated
vendored
Normal file
19
vendor/golang.org/x/net/internal/socket/iovec_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (v *iovec) set(b []byte) {
|
||||||
|
l := len(b)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v.Base = (*byte)(unsafe.Pointer(&b[0]))
|
||||||
|
v.Len = uint64(l)
|
||||||
|
}
|
19
vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
generated
vendored
Normal file
19
vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (v *iovec) set(b []byte) {
|
||||||
|
l := len(b)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v.Base = (*int8)(unsafe.Pointer(&b[0]))
|
||||||
|
v.Len = uint64(l)
|
||||||
|
}
|
11
vendor/golang.org/x/net/internal/socket/iovec_stub.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/iovec_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
type iovec struct{}
|
||||||
|
|
||||||
|
func (v *iovec) set(b []byte) {}
|
21
vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
generated
vendored
Normal file
21
vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux,!netbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
type mmsghdr struct{}
|
||||||
|
|
||||||
|
type mmsghdrs []mmsghdr
|
||||||
|
|
||||||
|
func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
|
||||||
|
return nil
|
||||||
|
}
|
42
vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
generated
vendored
Normal file
42
vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux netbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
type mmsghdrs []mmsghdr
|
||||||
|
|
||||||
|
func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
|
||||||
|
for i := range hs {
|
||||||
|
vs := make([]iovec, len(ms[i].Buffers))
|
||||||
|
var sa []byte
|
||||||
|
if parseFn != nil {
|
||||||
|
sa = make([]byte, sizeofSockaddrInet6)
|
||||||
|
}
|
||||||
|
if marshalFn != nil {
|
||||||
|
sa = marshalFn(ms[i].Addr)
|
||||||
|
}
|
||||||
|
hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
|
||||||
|
for i := range hs {
|
||||||
|
ms[i].N = int(hs[i].Len)
|
||||||
|
ms[i].NN = hs[i].Hdr.controllen()
|
||||||
|
ms[i].Flags = hs[i].Hdr.flags()
|
||||||
|
if parseFn != nil {
|
||||||
|
var err error
|
||||||
|
ms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
39
vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
generated
vendored
Normal file
39
vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd netbsd openbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||||
|
for i := range vs {
|
||||||
|
vs[i].set(bs[i])
|
||||||
|
}
|
||||||
|
h.setIov(vs)
|
||||||
|
if len(oob) > 0 {
|
||||||
|
h.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
h.Controllen = uint32(len(oob))
|
||||||
|
}
|
||||||
|
if sa != nil {
|
||||||
|
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||||
|
h.Namelen = uint32(len(sa))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) name() []byte {
|
||||||
|
if h.Name != nil && h.Namelen > 0 {
|
||||||
|
return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) controllen() int {
|
||||||
|
return int(h.Controllen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) flags() int {
|
||||||
|
return int(h.Flags)
|
||||||
|
}
|
16
vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
generated
vendored
Normal file
16
vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd netbsd
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *msghdr) setIov(vs []iovec) {
|
||||||
|
l := len(vs)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.Iov = &vs[0]
|
||||||
|
h.Iovlen = int32(l)
|
||||||
|
}
|
36
vendor/golang.org/x/net/internal/socket/msghdr_linux.go
generated
vendored
Normal file
36
vendor/golang.org/x/net/internal/socket/msghdr_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||||
|
for i := range vs {
|
||||||
|
vs[i].set(bs[i])
|
||||||
|
}
|
||||||
|
h.setIov(vs)
|
||||||
|
if len(oob) > 0 {
|
||||||
|
h.setControl(oob)
|
||||||
|
}
|
||||||
|
if sa != nil {
|
||||||
|
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||||
|
h.Namelen = uint32(len(sa))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) name() []byte {
|
||||||
|
if h.Name != nil && h.Namelen > 0 {
|
||||||
|
return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) controllen() int {
|
||||||
|
return int(h.Controllen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) flags() int {
|
||||||
|
return int(h.Flags)
|
||||||
|
}
|
24
vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
generated
vendored
Normal file
24
vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm mips mipsle 386
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (h *msghdr) setIov(vs []iovec) {
|
||||||
|
l := len(vs)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.Iov = &vs[0]
|
||||||
|
h.Iovlen = uint32(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) setControl(b []byte) {
|
||||||
|
h.Control = (*byte)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Controllen = uint32(len(b))
|
||||||
|
}
|
24
vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
generated
vendored
Normal file
24
vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (h *msghdr) setIov(vs []iovec) {
|
||||||
|
l := len(vs)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.Iov = &vs[0]
|
||||||
|
h.Iovlen = uint64(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) setControl(b []byte) {
|
||||||
|
h.Control = (*byte)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Controllen = uint64(len(b))
|
||||||
|
}
|
14
vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
func (h *msghdr) setIov(vs []iovec) {
|
||||||
|
l := len(vs)
|
||||||
|
if l == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.Iov = &vs[0]
|
||||||
|
h.Iovlen = uint32(l)
|
||||||
|
}
|
36
vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
generated
vendored
Normal file
36
vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||||
|
for i := range vs {
|
||||||
|
vs[i].set(bs[i])
|
||||||
|
}
|
||||||
|
if len(vs) > 0 {
|
||||||
|
h.Iov = &vs[0]
|
||||||
|
h.Iovlen = int32(len(vs))
|
||||||
|
}
|
||||||
|
if len(oob) > 0 {
|
||||||
|
h.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
|
||||||
|
h.Accrightslen = int32(len(oob))
|
||||||
|
}
|
||||||
|
if sa != nil {
|
||||||
|
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||||
|
h.Namelen = uint32(len(sa))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) controllen() int {
|
||||||
|
return int(h.Accrightslen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *msghdr) flags() int {
|
||||||
|
return int(NativeEndian.Uint32(h.Pad_cgo_2[:]))
|
||||||
|
}
|
14
vendor/golang.org/x/net/internal/socket/msghdr_stub.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/msghdr_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
type msghdr struct{}
|
||||||
|
|
||||||
|
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {}
|
||||||
|
func (h *msghdr) name() []byte { return nil }
|
||||||
|
func (h *msghdr) controllen() int { return 0 }
|
||||||
|
func (h *msghdr) flags() int { return 0 }
|
66
vendor/golang.org/x/net/internal/socket/rawconn.go
generated
vendored
Normal file
66
vendor/golang.org/x/net/internal/socket/rawconn.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Conn represents a raw connection.
|
||||||
|
type Conn struct {
|
||||||
|
network string
|
||||||
|
c syscall.RawConn
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConn returns a new raw connection.
|
||||||
|
func NewConn(c net.Conn) (*Conn, error) {
|
||||||
|
var err error
|
||||||
|
var cc Conn
|
||||||
|
switch c := c.(type) {
|
||||||
|
case *net.TCPConn:
|
||||||
|
cc.network = "tcp"
|
||||||
|
cc.c, err = c.SyscallConn()
|
||||||
|
case *net.UDPConn:
|
||||||
|
cc.network = "udp"
|
||||||
|
cc.c, err = c.SyscallConn()
|
||||||
|
case *net.IPConn:
|
||||||
|
cc.network = "ip"
|
||||||
|
cc.c, err = c.SyscallConn()
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unknown connection type")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &cc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Option) get(c *Conn, b []byte) (int, error) {
|
||||||
|
var operr error
|
||||||
|
var n int
|
||||||
|
fn := func(s uintptr) {
|
||||||
|
n, operr = getsockopt(s, o.Level, o.Name, b)
|
||||||
|
}
|
||||||
|
if err := c.c.Control(fn); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return n, os.NewSyscallError("getsockopt", operr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Option) set(c *Conn, b []byte) error {
|
||||||
|
var operr error
|
||||||
|
fn := func(s uintptr) {
|
||||||
|
operr = setsockopt(s, o.Level, o.Name, b)
|
||||||
|
}
|
||||||
|
if err := c.c.Control(fn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.NewSyscallError("setsockopt", operr)
|
||||||
|
}
|
74
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
Normal file
74
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
hs := make(mmsghdrs, len(ms))
|
||||||
|
var parseFn func([]byte, string) (net.Addr, error)
|
||||||
|
if c.network != "tcp" {
|
||||||
|
parseFn = parseInetAddr
|
||||||
|
}
|
||||||
|
if err := hs.pack(ms, parseFn, nil); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var operr error
|
||||||
|
var n int
|
||||||
|
fn := func(s uintptr) bool {
|
||||||
|
n, operr = recvmmsg(s, hs, flags)
|
||||||
|
if operr == syscall.EAGAIN {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if err := c.c.Read(fn); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
if operr != nil {
|
||||||
|
return n, os.NewSyscallError("recvmmsg", operr)
|
||||||
|
}
|
||||||
|
if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
hs := make(mmsghdrs, len(ms))
|
||||||
|
var marshalFn func(net.Addr) []byte
|
||||||
|
if c.network != "tcp" {
|
||||||
|
marshalFn = marshalInetAddr
|
||||||
|
}
|
||||||
|
if err := hs.pack(ms, nil, marshalFn); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var operr error
|
||||||
|
var n int
|
||||||
|
fn := func(s uintptr) bool {
|
||||||
|
n, operr = sendmmsg(s, hs, flags)
|
||||||
|
if operr == syscall.EAGAIN {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if err := c.c.Write(fn); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
if operr != nil {
|
||||||
|
return n, os.NewSyscallError("sendmmsg", operr)
|
||||||
|
}
|
||||||
|
if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
77
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
Normal file
77
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||||
|
var h msghdr
|
||||||
|
vs := make([]iovec, len(m.Buffers))
|
||||||
|
var sa []byte
|
||||||
|
if c.network != "tcp" {
|
||||||
|
sa = make([]byte, sizeofSockaddrInet6)
|
||||||
|
}
|
||||||
|
h.pack(vs, m.Buffers, m.OOB, sa)
|
||||||
|
var operr error
|
||||||
|
var n int
|
||||||
|
fn := func(s uintptr) bool {
|
||||||
|
n, operr = recvmsg(s, &h, flags)
|
||||||
|
if operr == syscall.EAGAIN {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if err := c.c.Read(fn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if operr != nil {
|
||||||
|
return os.NewSyscallError("recvmsg", operr)
|
||||||
|
}
|
||||||
|
if c.network != "tcp" {
|
||||||
|
var err error
|
||||||
|
m.Addr, err = parseInetAddr(sa[:], c.network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.N = n
|
||||||
|
m.NN = h.controllen()
|
||||||
|
m.Flags = h.flags()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||||
|
var h msghdr
|
||||||
|
vs := make([]iovec, len(m.Buffers))
|
||||||
|
var sa []byte
|
||||||
|
if m.Addr != nil {
|
||||||
|
sa = marshalInetAddr(m.Addr)
|
||||||
|
}
|
||||||
|
h.pack(vs, m.Buffers, m.OOB, sa)
|
||||||
|
var operr error
|
||||||
|
var n int
|
||||||
|
fn := func(s uintptr) bool {
|
||||||
|
n, operr = sendmsg(s, &h, flags)
|
||||||
|
if operr == syscall.EAGAIN {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if err := c.c.Write(fn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if operr != nil {
|
||||||
|
return os.NewSyscallError("sendmsg", operr)
|
||||||
|
}
|
||||||
|
m.N = n
|
||||||
|
m.NN = len(m.OOB)
|
||||||
|
return nil
|
||||||
|
}
|
18
vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
generated
vendored
Normal file
18
vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
18
vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
generated
vendored
Normal file
18
vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
25
vendor/golang.org/x/net/internal/socket/rawconn_stub.go
generated
vendored
Normal file
25
vendor/golang.org/x/net/internal/socket/rawconn_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.9
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
62
vendor/golang.org/x/net/internal/socket/reflect.go
generated
vendored
Normal file
62
vendor/golang.org/x/net/internal/socket/reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.9
|
||||||
|
|
||||||
|
package socket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Conn represents a raw connection.
|
||||||
|
type Conn struct {
|
||||||
|
c net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConn returns a new raw connection.
|
||||||
|
func NewConn(c net.Conn) (*Conn, error) {
|
||||||
|
return &Conn{c: c}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Option) get(c *Conn, b []byte) (int, error) {
|
||||||
|
s, err := socketOf(c.c)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
n, err := getsockopt(s, o.Level, o.Name, b)
|
||||||
|
return n, os.NewSyscallError("getsockopt", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Option) set(c *Conn, b []byte) error {
|
||||||
|
s, err := socketOf(c.c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.NewSyscallError("setsockopt", setsockopt(s, o.Level, o.Name, b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func socketOf(c net.Conn) (uintptr, error) {
|
||||||
|
switch c.(type) {
|
||||||
|
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
||||||
|
v := reflect.ValueOf(c)
|
||||||
|
switch e := v.Elem(); e.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
fd := e.FieldByName("conn").FieldByName("fd")
|
||||||
|
switch e := fd.Elem(); e.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
sysfd := e.FieldByName("sysfd")
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return uintptr(sysfd.Uint()), nil
|
||||||
|
}
|
||||||
|
return uintptr(sysfd.Int()), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, errors.New("invalid type")
|
||||||
|
}
|
285
vendor/golang.org/x/net/internal/socket/socket.go
generated
vendored
Normal file
285
vendor/golang.org/x/net/internal/socket/socket.go
generated
vendored
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package socket provides a portable interface for socket system
|
||||||
|
// calls.
|
||||||
|
package socket // import "golang.org/x/net/internal/socket"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An Option represents a sticky socket option.
|
||||||
|
type Option struct {
|
||||||
|
Level int // level
|
||||||
|
Name int // name; must be equal or greater than 1
|
||||||
|
Len int // length of value in bytes; must be equal or greater than 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get reads a value for the option from the kernel.
|
||||||
|
// It returns the number of bytes written into b.
|
||||||
|
func (o *Option) Get(c *Conn, b []byte) (int, error) {
|
||||||
|
if o.Name < 1 || o.Len < 1 {
|
||||||
|
return 0, errors.New("invalid option")
|
||||||
|
}
|
||||||
|
if len(b) < o.Len {
|
||||||
|
return 0, errors.New("short buffer")
|
||||||
|
}
|
||||||
|
return o.get(c, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt returns an integer value for the option.
|
||||||
|
//
|
||||||
|
// The Len field of Option must be either 1 or 4.
|
||||||
|
func (o *Option) GetInt(c *Conn) (int, error) {
|
||||||
|
if o.Len != 1 && o.Len != 4 {
|
||||||
|
return 0, errors.New("invalid option")
|
||||||
|
}
|
||||||
|
var b []byte
|
||||||
|
var bb [4]byte
|
||||||
|
if o.Len == 1 {
|
||||||
|
b = bb[:1]
|
||||||
|
} else {
|
||||||
|
b = bb[:4]
|
||||||
|
}
|
||||||
|
n, err := o.get(c, b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if n != o.Len {
|
||||||
|
return 0, errors.New("invalid option length")
|
||||||
|
}
|
||||||
|
if o.Len == 1 {
|
||||||
|
return int(b[0]), nil
|
||||||
|
}
|
||||||
|
return int(NativeEndian.Uint32(b[:4])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set writes the option and value to the kernel.
|
||||||
|
func (o *Option) Set(c *Conn, b []byte) error {
|
||||||
|
if o.Name < 1 || o.Len < 1 {
|
||||||
|
return errors.New("invalid option")
|
||||||
|
}
|
||||||
|
if len(b) < o.Len {
|
||||||
|
return errors.New("short buffer")
|
||||||
|
}
|
||||||
|
return o.set(c, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetInt writes the option and value to the kernel.
|
||||||
|
//
|
||||||
|
// The Len field of Option must be either 1 or 4.
|
||||||
|
func (o *Option) SetInt(c *Conn, v int) error {
|
||||||
|
if o.Len != 1 && o.Len != 4 {
|
||||||
|
return errors.New("invalid option")
|
||||||
|
}
|
||||||
|
var b []byte
|
||||||
|
if o.Len == 1 {
|
||||||
|
b = []byte{byte(v)}
|
||||||
|
} else {
|
||||||
|
var bb [4]byte
|
||||||
|
NativeEndian.PutUint32(bb[:o.Len], uint32(v))
|
||||||
|
b = bb[:4]
|
||||||
|
}
|
||||||
|
return o.set(c, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func controlHeaderLen() int {
|
||||||
|
return roundup(sizeofCmsghdr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func controlMessageLen(dataLen int) int {
|
||||||
|
return roundup(sizeofCmsghdr) + dataLen
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControlMessageSpace returns the whole length of control message.
|
||||||
|
func ControlMessageSpace(dataLen int) int {
|
||||||
|
return roundup(sizeofCmsghdr) + roundup(dataLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ControlMessage represents the head message in a stream of control
|
||||||
|
// messages.
|
||||||
|
//
|
||||||
|
// A control message comprises of a header, data and a few padding
|
||||||
|
// fields to conform to the interface to the kernel.
|
||||||
|
//
|
||||||
|
// See RFC 3542 for further information.
|
||||||
|
type ControlMessage []byte
|
||||||
|
|
||||||
|
// Data returns the data field of the control message at the head on
|
||||||
|
// m.
|
||||||
|
func (m ControlMessage) Data(dataLen int) []byte {
|
||||||
|
l := controlHeaderLen()
|
||||||
|
if len(m) < l || len(m) < l+dataLen {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return m[l : l+dataLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next returns the control message at the next on m.
|
||||||
|
//
|
||||||
|
// Next works only for standard control messages.
|
||||||
|
func (m ControlMessage) Next(dataLen int) ControlMessage {
|
||||||
|
l := ControlMessageSpace(dataLen)
|
||||||
|
if len(m) < l {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return m[l:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalHeader marshals the header fields of the control message at
|
||||||
|
// the head on m.
|
||||||
|
func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
|
||||||
|
if len(m) < controlHeaderLen() {
|
||||||
|
return errors.New("short message")
|
||||||
|
}
|
||||||
|
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||||
|
h.set(controlMessageLen(dataLen), lvl, typ)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseHeader parses and returns the header fields of the control
|
||||||
|
// message at the head on m.
|
||||||
|
func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
|
||||||
|
l := controlHeaderLen()
|
||||||
|
if len(m) < l {
|
||||||
|
return 0, 0, 0, errors.New("short message")
|
||||||
|
}
|
||||||
|
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||||
|
return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal marshals the control message at the head on m, and returns
|
||||||
|
// the next control message.
|
||||||
|
func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
|
||||||
|
l := len(data)
|
||||||
|
if len(m) < ControlMessageSpace(l) {
|
||||||
|
return nil, errors.New("short message")
|
||||||
|
}
|
||||||
|
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||||
|
h.set(controlMessageLen(l), lvl, typ)
|
||||||
|
if l > 0 {
|
||||||
|
copy(m.Data(l), data)
|
||||||
|
}
|
||||||
|
return m.Next(l), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses m as a single or multiple control messages.
|
||||||
|
//
|
||||||
|
// Parse works for both standard and compatible messages.
|
||||||
|
func (m ControlMessage) Parse() ([]ControlMessage, error) {
|
||||||
|
var ms []ControlMessage
|
||||||
|
for len(m) >= controlHeaderLen() {
|
||||||
|
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||||
|
l := h.len()
|
||||||
|
if l <= 0 {
|
||||||
|
return nil, errors.New("invalid header length")
|
||||||
|
}
|
||||||
|
if uint64(l) < uint64(controlHeaderLen()) {
|
||||||
|
return nil, errors.New("invalid message length")
|
||||||
|
}
|
||||||
|
if uint64(l) > uint64(len(m)) {
|
||||||
|
return nil, errors.New("short buffer")
|
||||||
|
}
|
||||||
|
// On message reception:
|
||||||
|
//
|
||||||
|
// |<- ControlMessageSpace --------------->|
|
||||||
|
// |<- controlMessageLen ---------->| |
|
||||||
|
// |<- controlHeaderLen ->| | |
|
||||||
|
// +---------------+------+---------+------+
|
||||||
|
// | Header | PadH | Data | PadD |
|
||||||
|
// +---------------+------+---------+------+
|
||||||
|
//
|
||||||
|
// On compatible message reception:
|
||||||
|
//
|
||||||
|
// | ... |<- controlMessageLen ----------->|
|
||||||
|
// | ... |<- controlHeaderLen ->| |
|
||||||
|
// +-----+---------------+------+----------+
|
||||||
|
// | ... | Header | PadH | Data |
|
||||||
|
// +-----+---------------+------+----------+
|
||||||
|
ms = append(ms, ControlMessage(m[:l]))
|
||||||
|
ll := l - controlHeaderLen()
|
||||||
|
if len(m) >= ControlMessageSpace(ll) {
|
||||||
|
m = m[ControlMessageSpace(ll):]
|
||||||
|
} else {
|
||||||
|
m = m[controlMessageLen(ll):]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewControlMessage returns a new stream of control messages.
|
||||||
|
func NewControlMessage(dataLen []int) ControlMessage {
|
||||||
|
var l int
|
||||||
|
for i := range dataLen {
|
||||||
|
l += ControlMessageSpace(dataLen[i])
|
||||||
|
}
|
||||||
|
return make([]byte, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Message represents an IO message.
|
||||||
|
type Message struct {
|
||||||
|
// When writing, the Buffers field must contain at least one
|
||||||
|
// byte to write.
|
||||||
|
// When reading, the Buffers field will always contain a byte
|
||||||
|
// to read.
|
||||||
|
Buffers [][]byte
|
||||||
|
|
||||||
|
// OOB contains protocol-specific control or miscellaneous
|
||||||
|
// ancillary data known as out-of-band data.
|
||||||
|
OOB []byte
|
||||||
|
|
||||||
|
// Addr specifies a destination address when writing.
|
||||||
|
// It can be nil when the underlying protocol of the raw
|
||||||
|
// connection uses connection-oriented communication.
|
||||||
|
// After a successful read, it may contain the source address
|
||||||
|
// on the received packet.
|
||||||
|
Addr net.Addr
|
||||||
|
|
||||||
|
N int // # of bytes read or written from/to Buffers
|
||||||
|
NN int // # of bytes read or written from/to OOB
|
||||||
|
Flags int // protocol-specific information on the received message
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecvMsg wraps recvmsg system call.
|
||||||
|
//
|
||||||
|
// The provided flags is a set of platform-dependent flags, such as
|
||||||
|
// syscall.MSG_PEEK.
|
||||||
|
func (c *Conn) RecvMsg(m *Message, flags int) error {
|
||||||
|
return c.recvMsg(m, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMsg wraps sendmsg system call.
|
||||||
|
//
|
||||||
|
// The provided flags is a set of platform-dependent flags, such as
|
||||||
|
// syscall.MSG_DONTROUTE.
|
||||||
|
func (c *Conn) SendMsg(m *Message, flags int) error {
|
||||||
|
return c.sendMsg(m, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecvMsgs wraps recvmmsg system call.
|
||||||
|
//
|
||||||
|
// It returns the number of processed messages.
|
||||||
|
//
|
||||||
|
// The provided flags is a set of platform-dependent flags, such as
|
||||||
|
// syscall.MSG_PEEK.
|
||||||
|
//
|
||||||
|
// Only Linux supports this.
|
||||||
|
func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return c.recvMsgs(ms, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMsgs wraps sendmmsg system call.
|
||||||
|
//
|
||||||
|
// It returns the number of processed messages.
|
||||||
|
//
|
||||||
|
// The provided flags is a set of platform-dependent flags, such as
|
||||||
|
// syscall.MSG_DONTROUTE.
|
||||||
|
//
|
||||||
|
// Only Linux supports this.
|
||||||
|
func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
|
||||||
|
return c.sendMsgs(ms, flags)
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue