├── tests ├── .gitignore ├── dnsdist.conf ├── __init__.py ├── test_usage.py └── test_stdout.py ├── pdns_protobuf_receiver ├── __init__.py ├── protobuf.py ├── dnsmessage.proto ├── receiver.py └── dnsmessage_pb2.py ├── Dockerfile ├── .github └── workflows │ ├── build.yml │ ├── testing.yml │ └── publish.yml ├── LICENSE ├── setup.j2 └── README.md /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /__pycache__/ 2 | -------------------------------------------------------------------------------- /pdns_protobuf_receiver/__init__.py: -------------------------------------------------------------------------------- 1 | from pdns_protobuf_receiver.receiver import start_receiver -------------------------------------------------------------------------------- /tests/dnsdist.conf: -------------------------------------------------------------------------------- 1 | setLocal('127.0.0.1:53') 2 | 3 | rl = newRemoteLogger("127.0.0.1:50001") 4 | addAction(AllRule(),RemoteLogAction(rl)) 5 | addResponseAction(AllRule(),RemoteLogResponseAction(rl)) 6 | 7 | newServer('8.8.8.8') -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-alpine 2 | 3 | LABEL name="PDNS protobuf receiver" \ 4 | description="PDNS protobuf receiver" \ 5 | url="https://github.com/dmachard/pdns-protobuf-receiver" \ 6 | maintainer="d.machard@gmail.com" 7 | 8 | WORKDIR /home/pdnspb 9 | 10 | COPY . /home/pdnspb/ 11 | 12 | RUN true \ 13 | && adduser -D pdnspb \ 14 | && pip install --no-cache-dir dnspython protobuf\ 15 | && cd /home/pdnspb \ 16 | && chown -R pdnspb:pdnspb /home/pdnspb \ 17 | && true 18 | 19 | USER pdnspb 20 | 21 | EXPOSE 50001/tcp 22 | 23 | ENTRYPOINT ["python", "-c", "import pdns_protobuf_receiver; pdns_protobuf_receiver.start_receiver()"] -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_run: 5 | workflows: 6 | - Testing 7 | types: 8 | - completed 9 | 10 | jobs: 11 | python-package: 12 | runs-on: ubuntu-20.04 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions/setup-python@v2 16 | 17 | - name: Install dependencies 18 | run: | 19 | python -m pip install --upgrade pip setuptools wheel 20 | pip install twine jinja2 21 | 22 | - name: Build Python package 23 | run: | 24 | python -c 'import jinja2;jinja2.Template(open("setup.j2").read()).stream(version="${{ steps.pkg_version.outputs.data }}").dump("setup.py")' 25 | python setup.py sdist bdist_wheel 26 | 27 | docker-image: 28 | runs-on: ubuntu-20.04 29 | steps: 30 | - uses: actions/checkout@v2 31 | 32 | - name: Build the Docker image 33 | run: | 34 | docker build . --file Dockerfile -t pdns-protobuf-receiver -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Denis MACHARD 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/testing.yml: -------------------------------------------------------------------------------- 1 | name: Testing 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-20.04 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: actions/setup-python@v2 17 | 18 | - name: Install dnsdist 19 | run: | 20 | sudo apt-get install -y dnsdist net-tools 21 | 22 | - name: Configure dnsdist to activate protobuf 23 | run: | 24 | sudo systemctl stop dnsdist 25 | sudo cp -rf tests/dnsdist.conf /etc/dnsdist/ 26 | sudo cat /etc/dnsdist/dnsdist.conf 27 | sudo mkdir -p /var/run/dnsdist 28 | sudo chown _dnsdist._dnsdist /var/run/dnsdist/ 29 | sudo systemctl start dnsdist 30 | sudo systemctl status dnsdist 31 | sudo netstat -anp | grep dnsdist 32 | 33 | - name: Run Python tests 34 | run: | 35 | sudo python3 -m pip install --upgrade protobuf 36 | sudo python3 -m pip install --upgrade dnspython 37 | sudo python3 -m unittest tests.test_stdout -v 38 | sudo python3 -m unittest tests.test_usage -v 39 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. -------------------------------------------------------------------------------- /tests/test_usage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import time 26 | import unittest 27 | import subprocess 28 | import dns.resolver 29 | 30 | 31 | class TestUsage(unittest.TestCase): 32 | def test1_print_usage(self): 33 | """test print usage""" 34 | cmd = ["python3", "-c", 35 | "import pdns_protobuf_receiver; pdns_protobuf_receiver.start_receiver()", 36 | "-h"] 37 | with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: 38 | o = proc.stdout.read() 39 | print(o) 40 | self.assertRegex(o, b"show this help message and exit") -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish-pypi: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-python@v2 13 | 14 | - name: Install dependencies 15 | run: | 16 | python -m pip install --upgrade pip setuptools wheel 17 | pip install twine 18 | pip install dnslib protobuf 19 | 20 | - id: pkg_version 21 | run: echo "##[set-output name=data;]$(echo ${{ github.event.release.tag_name }} | cut -c2-)" 22 | 23 | - name: Build Python package 24 | run: | 25 | python -c 'import jinja2;jinja2.Template(open("setup.j2").read()).stream(version="${{ steps.pkg_version.outputs.data }}").dump("setup.py")' 26 | python setup.py sdist bdist_wheel 27 | 28 | - name: Twine check 29 | run: | 30 | twine check dist/* 31 | 32 | - name: Upload to PyPI 33 | run: | 34 | twine upload dist/* -u ${{ secrets.PYPI_LOGIN }} -p ${{ secrets.PYPI_PASSWORD }} 35 | 36 | publish-dockerhub: 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v2 40 | 41 | - name: Build the Docker image 42 | run: | 43 | docker build . --file Dockerfile -t pdns-protobuf-receiver 44 | 45 | - name: Tag image 46 | run: | 47 | docker tag pdns-protobuf-receiver dmachard/pdns-protobuf-receiver:${{ github.event.release.tag_name }} 48 | docker tag pdns-protobuf-receiver dmachard/pdns-protobuf-receiver:latest 49 | 50 | - name: Upload to DockerHub 51 | run: | 52 | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} -p ${{ secrets.DOCKERHUB_PASSWORD }} 53 | docker push dmachard/pdns-protobuf-receiver:latest 54 | docker push dmachard/pdns-protobuf-receiver:${{ github.event.release.tag_name }} -------------------------------------------------------------------------------- /setup.j2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import setuptools 26 | 27 | with open("README.md", "r") as fh: 28 | LONG_DESCRIPTION = fh.read() 29 | 30 | KEYWORDS = ('protobuf pdns receiver json') 31 | 32 | setuptools.setup( 33 | name="pdns_protobuf_receiver", 34 | version="{{ version }}", 35 | author="Denis MACHARD", 36 | author_email="d.machard@gmail.com", 37 | description="Python PDNS protobuf receiver to JSON stream", 38 | long_description=LONG_DESCRIPTION, 39 | long_description_content_type="text/markdown", 40 | url="https://github.com/dmachard/pdns-protobuf-receiver", 41 | packages=['pdns_protobuf_receiver'], 42 | include_package_data=True, 43 | platforms='any', 44 | keywords=KEYWORDS, 45 | classifiers=[ 46 | "License :: OSI Approved :: MIT License", 47 | "Programming Language :: Python :: 3", 48 | "Operating System :: OS Independent", 49 | "Topic :: Software Development :: Libraries", 50 | ], 51 | entry_points={'console_scripts': ['pdns_protobuf_receiver = pdns_protobuf_receiver.receiver:start_receiver']}, 52 | install_requires=[ 53 | "dnspython", 54 | "protobuf" 55 | ] 56 | ) 57 | -------------------------------------------------------------------------------- /tests/test_stdout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import time 26 | import unittest 27 | import subprocess 28 | import dns.resolver 29 | 30 | my_resolver = dns.resolver.Resolver(configure=False) 31 | my_resolver.nameservers = ['127.0.0.1'] 32 | 33 | class TestStdout(unittest.TestCase): 34 | def test1_listening(self): 35 | """test listening tcp socket""" 36 | cmd = ["python3", "-c", 37 | "import pdns_protobuf_receiver; pdns_protobuf_receiver.start_receiver()", "-v"] 38 | with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: 39 | time.sleep(2) 40 | proc.kill() 41 | 42 | o = proc.stdout.read() 43 | print(o) 44 | self.assertRegex(o, b"listening") 45 | 46 | def test2_protobuf(self): 47 | """test to receive protobuf message""" 48 | cmd = ["python3", "-c", 49 | "import pdns_protobuf_receiver; pdns_protobuf_receiver.start_receiver()", "-v"] 50 | 51 | with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: 52 | for i in range(10): 53 | r = my_resolver.resolve('www.github.com', 'a') 54 | time.sleep(1) 55 | 56 | proc.kill() 57 | 58 | o = proc.stdout.read() 59 | print(o) 60 | self.assertRegex(o, b"CLIENT_QUERY") 61 | -------------------------------------------------------------------------------- /pdns_protobuf_receiver/protobuf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import struct 26 | 27 | 28 | class ProtoBufHandler(object): 29 | def __init__(self): 30 | """prepare the class""" 31 | self.buf = b"" 32 | 33 | self.datalen = None 34 | 35 | def pending_nb_bytes(self): 36 | """pending number of bytes""" 37 | if self.datalen is not None: 38 | return self.datalen 39 | return 2 40 | 41 | def append(self, data): 42 | """append data to the buffer""" 43 | self.buf = b"".join([self.buf, data]) 44 | 45 | def process_data(self): 46 | """process incoming data""" 47 | if self.datalen is None: 48 | # need more data ? 49 | if len(self.buf) < 2: 50 | return False 51 | 52 | # enough data, decode frame length 53 | (self.datalen,) = struct.unpack("!H", self.buf[:2]) 54 | self.buf = self.buf[2:] 55 | 56 | # need more data ? 57 | if len(self.buf) < self.datalen: 58 | return False 59 | 60 | # we have received enough data, the protobuf payload is complete 61 | return True 62 | 63 | else: 64 | # need more data ? 65 | if len(self.buf) < self.datalen: 66 | return False 67 | 68 | # we have received enough data, the protobuf payload is complete 69 | return True 70 | 71 | def decode(self): 72 | """decode""" 73 | pl = self.buf[: self.datalen] 74 | self.buf = self.buf[self.datalen :] 75 | 76 | # reset to process next data 77 | self.datalen = None 78 | 79 | return pl 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ Important notice 2 | 3 | **This project is no longer maintained.** 4 | 5 | 👉 Please use [DNS-collector](https://github.com/dmachard/DNS-collector) instead, which provides a more complete and up-to-date solution. 6 | 7 | # PowerDNS protobuf receiver 8 | 9 | ![](https://github.com/dmachard/pdns-protobuf-receiver/workflows/Publish/badge.svg) 10 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 11 | ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pdns-protobuf-receiver) 12 | 13 | The `pdns_protobuf_receiver` is a daemon in Python 3 that acts a protobuf server for PowerDNS's products. You can use it to collect DNS queries and responses and to log to syslog or a json remote tcp collector. 14 | 15 | ## Table of contents 16 | * [Installation](#installation) 17 | * [Execute receiver](#execute-receiver) 18 | * [Startup options](#startup-options) 19 | * [Output JSON format](#output-json-format) 20 | * [PowerDNS configuration](#powerdns-configuration) 21 | * [About](#about) 22 | 23 | ## Installation 24 | 25 | ### PyPI 26 | 27 | From pypi, deploy the `pdns_protobuf_receiver` with the pip command. 28 | Only Python3 is supported. 29 | 30 | ```python 31 | pip install pdns-protobuf-receiver 32 | ``` 33 | 34 | After installation, you will have `pdns_protobuf_receiver` binary available 35 | 36 | ### Docker Hub 37 | 38 | Pull the pdns-protobuf-receiver image from Docker Hub. 39 | 40 | ```bash 41 | docker pull dmachard/pdns-protobuf-receiver:latest 42 | ``` 43 | 44 | Deploy the container 45 | 46 | ```bash 47 | docker run -d -p 50001:50001 --name=pdns-pb01 dmachard/pdns-protobuf-receiver 48 | ``` 49 | 50 | Follow containers logs 51 | 52 | ```bash 53 | docker logs pdns-pb01 -f 54 | ``` 55 | 56 | ## Execute receiver 57 | 58 | The receiver is listening by default on the 0.0.0.0 interface and 50001 tcp port 59 | 60 | If you want to print DNS queries and responses to stdout in JSON format, then execute the `pdns_protobuf` receiver as below: 61 | 62 | ``` 63 | # pdns_protobuf_receiver -v 64 | 2020-05-29 18:39:08,579 Start pdns protobuf receiver... 65 | 2020-05-29 18:39:08,580 Using selector: EpollSelector 66 | ``` 67 | 68 | If you want to resend protobuf message to your remote tcp collector 69 | Start the pdns_protobuf receiver as below: 70 | 71 | ``` 72 | # pdns_protobuf_receiver -j 10.0.0.235:6000 -v 73 | 2020-05-29 18:39:08,579 Start pdns protobuf receiver... 74 | 2020-05-29 18:39:08,580 Using selector: EpollSelector 75 | 2020-05-29 18:39:08,580 Connecting to 10.0.0.235 6000 76 | 2020-05-29 18:39:08,585 Connected to 10.0.0.235 6000 77 | ``` 78 | 79 | ## Startup options 80 | 81 | Command line options are: 82 | 83 | ``` 84 | usage: -c [-h] [-l L] [-j J] [-v] 85 | 86 | optional arguments: 87 | -h, --help show this help message and exit 88 | -l L listen protobuf dns message on tcp/ip address 89 | -j J write JSON payload to tcp/ip address 90 | -v verbose mode 91 | ``` 92 | 93 | ## JSON log format 94 | 95 | Each events generated by the `pdns_protbuf` receiver will have the following format: 96 | 97 | ```json 98 | { 99 | "dns_message": "AUTH_QUERY", 100 | "socket_family": "IPv6", 101 | "socket protocol": "UDP", 102 | "from_address": "0.0.0.0", 103 | "to_address": "184.26.161.130", 104 | "query_time": "2020-05-29 13:46:23.322", 105 | "response_time": "1970-01-01 01:00:00.000", 106 | "latency": 0, 107 | "query_type": "A", 108 | "query_name": "a13-130.akagtm.org.", 109 | "return_code": "NOERROR", 110 | "bytes": 4 111 | } 112 | ``` 113 | 114 | Keys description: 115 | - dns_message: PDNS message type (CLIENT_QUERY, CLIENT_RESPONSE, ...) 116 | - socket_family: IP protocol used (IPv4 or IPv6) 117 | - socket_protocol: transport protocol used (UDP or TCP) 118 | - from_address: the querier IP address 119 | - to_address: the destination IP address 120 | - query_time: time of query reception 121 | - response_time: time of response reception 122 | - latency: difference between query and response time 123 | - query_type: the query type (A, AAAA, NS, ...) 124 | - query_name: the query name 125 | - return_code: the response code sent back to the client (NXDOMAIN, NOERROR, ...) 126 | - bytes: size in bytes of the query or response 127 | 128 | ## PowerDNS configuration 129 | 130 | You need to configure dnsdist or pdns-recursor to active remote logging. 131 | 132 | ### dnsdist 133 | 134 | Configure the dnsdist `/etc/dnsdist/dnsdist.conf` and add the following lines 135 | Set the newRemoteLogger function with the address of your pdns_protobuf_receiver 136 | instance. 137 | 138 | ``` 139 | rl = newRemoteLogger("10.0.0.97:50001") 140 | addAction(AllRule(),RemoteLogAction(rl)) 141 | addResponseAction(AllRule(),RemoteLogResponseAction(rl)) 142 | ``` 143 | 144 | Restart dnsdist. 145 | 146 | ### pdns-recursor 147 | 148 | Configure the powerdns recursor `/etc/pdns-recursor/recursor.conf` and add the following line 149 | 150 | ``` 151 | lua-config-file=/etc/pdns-recursor/recursor.lua 152 | ``` 153 | 154 | Create the LUA file `/etc/pdns-recursor/recursor.lua` 155 | Set the protobufServer or outgoingProtobufServer functions with the address of your pdns_protobuf receiver instance. 156 | 157 | ``` 158 | protobufServer("10.0.0.97:50001", {logQueries=true, 159 | logResponses=true, 160 | exportTypes={'A', 'AAAA', 161 | 'CNAME', 'MX', 162 | 'PTR', 'NS', 163 | 'SPF', 'SRV', 164 | 'TXT'}} ) 165 | outgoingProtobufServer("10.0.0.97:50001", {logQueries=true, 166 | logResponses=true, 167 | exportTypes={'A', 'AAAA', 168 | 'CNAME', 'MX', 169 | 'PTR', 'NS', 170 | 'SPF', 'SRV', 171 | 'TXT'}}) 172 | ``` 173 | 174 | Restart the recursor. 175 | 176 | ## About 177 | 178 | | | | 179 | | ------------- | ------------- | 180 | | Original Author | Denis Machard | 181 | | | | 182 | 183 | -------------------------------------------------------------------------------- /pdns_protobuf_receiver/dnsmessage.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * This file describes the message format used by the protobuf logging feature in PowerDNS and dnsdist. 3 | * 4 | * MIT License 5 | * 6 | * Copyright (c) 2016-now PowerDNS.COM B.V. and its contributors. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in all 16 | * copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | * SOFTWARE. 25 | */ 26 | syntax = "proto2"; 27 | 28 | message PBDNSMessage { 29 | enum Type { 30 | DNSQueryType = 1; // Query received by the service 31 | DNSResponseType = 2; // Response returned by the service 32 | DNSOutgoingQueryType = 3; // Query sent out by the service to a remote server 33 | DNSIncomingResponseType = 4; // Response returned by the remote server 34 | } 35 | enum SocketFamily { 36 | INET = 1; // IPv4 (RFC 791) 37 | INET6 = 2; // IPv6 (RFC 2460) 38 | } 39 | enum SocketProtocol { 40 | UDP = 1; // User Datagram Protocol (RFC 768) 41 | TCP = 2; // Transmission Control Protocol (RFC 793) 42 | } 43 | enum PolicyType { 44 | UNKNOWN = 1; // No RPZ policy applied, or unknown type 45 | QNAME = 2; // Policy matched on the QName 46 | CLIENTIP = 3; // Policy matched on the client IP 47 | RESPONSEIP = 4; // Policy matched on one of the IPs contained in the answer 48 | NSDNAME = 5; // Policy matched on the name of one nameserver involved 49 | NSIP = 6; // Policy matched on the IP of one nameserver involved 50 | } 51 | required Type type = 1; // Type of event 52 | optional bytes messageId = 2; // UUID, shared by the query and the response 53 | optional bytes serverIdentity = 3; // ID of the server emitting the protobuf message 54 | optional SocketFamily socketFamily = 4; 55 | optional SocketProtocol socketProtocol = 5; 56 | optional bytes from = 6; // DNS requestor (client) as 4 (IPv4) or 16 (IPv6) raw bytes in network byte order 57 | optional bytes to = 7; // DNS responder (server) as 4 (IPv4) or 16 (IPv6) raw bytes in network byte order 58 | optional uint64 inBytes = 8; // Size of the query or response on the wire 59 | optional uint32 timeSec = 9; // Time of message reception (seconds since epoch) 60 | optional uint32 timeUsec = 10; // Time of message reception (additional micro-seconds) 61 | optional uint32 id = 11; // ID of the query/response as found in the DNS header 62 | 63 | message DNSQuestion { 64 | optional string qName = 1; // Fully qualified DNS name (with trailing dot) 65 | optional uint32 qType = 2; // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 66 | optional uint32 qClass = 3; // Typically 1 (IN), see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2 67 | } 68 | optional DNSQuestion question = 12; // DNS query received from client 69 | 70 | message DNSResponse { 71 | // See exportTypes in https://docs.powerdns.com/recursor/lua-config/protobuf.html#protobufServer 72 | // for the list of supported resource record types. 73 | message DNSRR { 74 | optional string name = 1; // Fully qualified DNS name (with trailing dot) 75 | optional uint32 type = 2; // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 76 | optional uint32 class = 3; // Typically 1 (IN), see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2 77 | optional uint32 ttl = 4; // TTL in seconds 78 | optional bytes rdata = 5; // raw address bytes in network byte order for A & AAAA; text representation for others, with fully qualified (trailing dot) domain names 79 | optional bool udr = 6; // True if this is the first time this RR has been seen for this question 80 | } 81 | optional uint32 rcode = 1; // DNS Response code, or 65536 for a network error including a timeout 82 | repeated DNSRR rrs = 2; // DNS resource records in response 83 | optional string appliedPolicy = 3; // Filtering policy (RPZ or Lua) applied 84 | repeated string tags = 4; // Additional tags applied 85 | optional uint32 queryTimeSec = 5; // Time of the corresponding query reception (seconds since epoch) 86 | optional uint32 queryTimeUsec = 6; // Time of the corresponding query reception (additional micro-seconds) 87 | optional PolicyType appliedPolicyType = 7; // Type of the filtering policy (RPZ or Lua) applied 88 | optional string appliedPolicyTrigger = 8; // The RPZ trigger 89 | optional string appliedPolicyHit = 9; // The value (qname or IP) that caused the hit 90 | } 91 | 92 | optional DNSResponse response = 13; 93 | optional bytes originalRequestorSubnet = 14; // EDNS Client Subnet value (4 or 16 raw bytes in network byte order) 94 | optional string requestorId = 15; // Username of the requestor 95 | optional bytes initialRequestId = 16; // UUID of the incoming query that initiated this outgoing query or incoming response 96 | optional bytes deviceId = 17; // Device ID of the requestor (could be mac address IP address or e.g. IMEI, format implementation dependent) 97 | optional bool newlyObservedDomain = 18; // True if the domain has not been seen before 98 | optional string deviceName = 19; // Device name of the requestor 99 | optional uint32 fromPort = 20; // Source port of the DNS query (client) 100 | optional uint32 toPort = 21; // Destination port of the DNS query (server) 101 | } 102 | 103 | message PBDNSMessageList { 104 | repeated PBDNSMessage msg = 1; 105 | } 106 | -------------------------------------------------------------------------------- /pdns_protobuf_receiver/receiver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # MIT License 4 | 5 | # Copyright (c) 2020 Denis MACHARD 6 | 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import argparse 26 | import logging 27 | import asyncio 28 | import socket 29 | import json 30 | import sys 31 | 32 | import dns.rdatatype 33 | import dns.rcode 34 | 35 | from datetime import datetime, timezone 36 | 37 | # wget https://raw.githubusercontent.com/PowerDNS/dnsmessage/master/dnsmessage.proto 38 | # wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.2/protoc-3.12.2-linux-x86_64.zip 39 | # python3 -m pip install protobuf 40 | # protoc --python_out=. dnstap_pb2.proto 41 | 42 | from pdns_protobuf_receiver.dnsmessage_pb2 import PBDNSMessage 43 | from pdns_protobuf_receiver import protobuf 44 | 45 | parser = argparse.ArgumentParser() 46 | parser.add_argument( 47 | "-l", 48 | default="0.0.0.0:50001", 49 | help="listen protobuf dns message on tcp/ip address ", 50 | ) 51 | parser.add_argument("-j", help="write JSON payload to tcp/ip address ") 52 | parser.add_argument("-v", action="store_true", help="verbose mode") 53 | 54 | PBDNSMESSAGE_TYPE = { 55 | 1: "CLIENT_QUERY", 56 | 2: "CLIENT_RESPONSE", 57 | 3: "AUTH_QUERY", 58 | 4: "AUTH_RESPONSE", 59 | } 60 | PBDNSMESSAGE_SOCKETFAMILY = {1: "IPv4", 2: "IPv6"} 61 | 62 | PBDNSMESSAGE_SOCKETPROTOCOL = {1: "UDP", 2: "TCP"} 63 | 64 | 65 | async def cb_onpayload(dns_pb2, payload, tcp_writer, debug_mode, loop): 66 | """on dnsmessage protobuf2""" 67 | dns_pb2.ParseFromString(payload) 68 | 69 | dns_msg = {} 70 | dns_msg["dns_message"] = PBDNSMESSAGE_TYPE[dns_pb2.type] 71 | dns_msg["socket_family"] = PBDNSMESSAGE_SOCKETFAMILY[dns_pb2.socketFamily] 72 | dns_msg["socket protocol"] = PBDNSMESSAGE_SOCKETPROTOCOL[dns_pb2.socketProtocol] 73 | 74 | dns_msg["from_address"] = "0.0.0.0" 75 | from_addr = getattr(dns_pb2, "from") 76 | if len(from_addr): 77 | if dns_pb2.socketFamily == PBDNSMessage.SocketFamily.INET: 78 | dns_msg["from_address"] = socket.inet_ntop(socket.AF_INET, from_addr) 79 | if dns_pb2.socketFamily == PBDNSMessage.SocketFamily.INET6: 80 | dns_msg["from_address"] = socket.inet_ntop(socket.AF_INET6, from_addr) 81 | 82 | dns_msg["to_address"] = "0.0.0.0" 83 | to_addr = getattr(dns_pb2, "to") 84 | if len(to_addr): 85 | if dns_pb2.socketFamily == PBDNSMessage.SocketFamily.INET: 86 | dns_msg["to_address"] = socket.inet_ntop(socket.AF_INET, to_addr) 87 | if dns_pb2.socketFamily == PBDNSMessage.SocketFamily.INET6: 88 | dns_msg["to_address"] = socket.inet_ntop(socket.AF_INET6, to_addr) 89 | 90 | time_req = 0 91 | time_rsp = 0 92 | time_latency = 0 93 | 94 | if dns_pb2.type in [ 95 | PBDNSMessage.Type.DNSQueryType, 96 | PBDNSMessage.Type.DNSOutgoingQueryType, 97 | ]: 98 | utime_req = "%s" % dns_pb2.timeUsec 99 | time_req = "%s.%s" % (dns_pb2.timeSec, utime_req.zfill(6)) 100 | 101 | if dns_pb2.type in [ 102 | PBDNSMessage.Type.DNSResponseType, 103 | PBDNSMessage.Type.DNSIncomingResponseType, 104 | ]: 105 | utime_rsp = "%s" % dns_pb2.timeUsec 106 | time_rsp = "%s.%s" % (dns_pb2.timeSec, utime_rsp.zfill(6)) 107 | 108 | utime_req = "%s" % dns_pb2.response.queryTimeUsec 109 | time_req = "%s.%s" % (dns_pb2.response.queryTimeSec, utime_req.zfill(6)) 110 | 111 | time_latency = round(float(time_rsp) - float(time_req), 6) 112 | 113 | dns_msg["query_time"] = datetime.fromtimestamp( 114 | float(time_req), tz=timezone.utc 115 | ).isoformat() 116 | dns_msg["response_time"] = datetime.fromtimestamp( 117 | float(time_rsp), tz=timezone.utc 118 | ).isoformat() 119 | 120 | dns_msg["latency"] = time_latency 121 | 122 | dns_msg["query_type"] = dns.rdatatype.to_text(dns_pb2.question.qType) 123 | dns_msg["query_name"] = dns_pb2.question.qName 124 | 125 | if dns_pb2.response.rcode == 65536: 126 | dns_msg["return_code"] = "NETWORK_ERROR" 127 | else: 128 | dns_msg["return_code"] = dns.rcode.to_text(dns_pb2.response.rcode) 129 | dns_msg["bytes"] = dns_pb2.inBytes 130 | 131 | dns_json = json.dumps(dns_msg) 132 | 133 | if debug_mode: 134 | logging.info(dns_json) 135 | 136 | else: 137 | if tcp_writer.transport._conn_lost: 138 | # exit if we lost the connection with the remote collector 139 | loop.stop() 140 | raise Exception("connection lost with remote") 141 | else: 142 | tcp_writer.write(dns_json.encode() + b"\n") 143 | 144 | 145 | async def cb_onconnect(reader, writer, tcp_writer, debug_mode): 146 | logging.debug("connect accepted") 147 | 148 | loop = asyncio.get_event_loop() 149 | protobuf_streamer = protobuf.ProtoBufHandler() 150 | dns_pb2 = PBDNSMessage() 151 | 152 | running = True 153 | while running: 154 | try: 155 | while not protobuf_streamer.process_data(): 156 | # read data 157 | data = await reader.read(protobuf_streamer.pending_nb_bytes()) 158 | if not data: 159 | break 160 | 161 | # append data to the buffer 162 | protobuf_streamer.append(data=data) 163 | 164 | # dns message is complete so get the payload 165 | payload = protobuf_streamer.decode() 166 | 167 | # create a task to decode it 168 | loop.create_task( 169 | cb_onpayload(dns_pb2, payload, tcp_writer, debug_mode, loop) 170 | ) 171 | 172 | except Exception as e: 173 | running = False 174 | logging.error("something happened: %s" % e) 175 | 176 | 177 | async def handle_remoteclient(host, port): 178 | logging.debug("Connecting to %s %s" % (host, port)) 179 | tcp_reader, tcp_writer = await asyncio.open_connection(host, int(port)) 180 | logging.debug("Connected to %s %s" % (host, port)) 181 | return tcp_writer 182 | 183 | 184 | def start_receiver(): 185 | """start dnstap receiver""" 186 | # parse arguments 187 | args = parser.parse_args() 188 | 189 | # configure logs 190 | level = logging.INFO 191 | if args.v: 192 | level = logging.DEBUG 193 | logging.basicConfig( 194 | format="%(asctime)s %(message)s", stream=sys.stdout, level=level 195 | ) 196 | 197 | logging.debug("Start pdns protobuf receiver...") 198 | 199 | try: 200 | listen_ip, listen_port = args.l.split(":") 201 | except Exception as e: 202 | logging.error("bad listen ip:port provided - %s", args.l) 203 | sys.exit(1) 204 | 205 | if args.j is None: 206 | debug_mode = True 207 | remote_host = None 208 | remote_port = None 209 | else: 210 | debug_mode = False 211 | try: 212 | remote_host, remote_port = args.j.split(":") 213 | except Exception as e: 214 | logging.error("bad remote ip:port provided -%s", args.j) 215 | sys.exit(1) 216 | 217 | # run until complete 218 | loop = asyncio.get_event_loop() 219 | 220 | # create connection to the remote json collector ? 221 | if not debug_mode: 222 | task = loop.create_task(handle_remoteclient(remote_host, remote_port)) 223 | loop.run_until_complete(task) 224 | tcp_writer = task.result() 225 | else: 226 | tcp_writer = None 227 | 228 | # asynchronous server socket 229 | socket_server = asyncio.start_server( 230 | lambda r, w: cb_onconnect(r, w, tcp_writer, debug_mode), 231 | host=listen_ip, 232 | port=listen_port, 233 | ) 234 | 235 | # run until complete 236 | abstract_server = loop.run_until_complete(socket_server) 237 | 238 | # set some tcp socket options 239 | sock = abstract_server.sockets[0] 240 | 241 | # force to use tcp keepalive 242 | # It activates after 1 second (TCP_KEEPIDLE,) of idleness, 243 | # then sends a keepalive ping once every 3 seconds (TCP_KEEPINTVL), 244 | # and closes the connection after 10 failed ping (TCP_KEEPCNT) 245 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 246 | sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 10) 247 | sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30) 248 | sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5) 249 | 250 | logging.debug("server listening") 251 | 252 | # run event loop 253 | try: 254 | loop.run_forever() 255 | except KeyboardInterrupt: 256 | pass 257 | 258 | if not debug_mode: 259 | tcp_writer.close() 260 | logging.debug("connection done") 261 | -------------------------------------------------------------------------------- /pdns_protobuf_receiver/dnsmessage_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: dnsmessage.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor.FileDescriptor( 17 | name='dnsmessage.proto', 18 | package='', 19 | syntax='proto2', 20 | serialized_options=None, 21 | create_key=_descriptor._internal_create_key, 22 | serialized_pb=b'\n\x10\x64nsmessage.proto\"\xdc\t\n\x0cPBDNSMessage\x12 \n\x04type\x18\x01 \x02(\x0e\x32\x12.PBDNSMessage.Type\x12\x11\n\tmessageId\x18\x02 \x01(\x0c\x12\x16\n\x0eserverIdentity\x18\x03 \x01(\x0c\x12\x30\n\x0csocketFamily\x18\x04 \x01(\x0e\x32\x1a.PBDNSMessage.SocketFamily\x12\x34\n\x0esocketProtocol\x18\x05 \x01(\x0e\x32\x1c.PBDNSMessage.SocketProtocol\x12\x0c\n\x04\x66rom\x18\x06 \x01(\x0c\x12\n\n\x02to\x18\x07 \x01(\x0c\x12\x0f\n\x07inBytes\x18\x08 \x01(\x04\x12\x0f\n\x07timeSec\x18\t \x01(\r\x12\x10\n\x08timeUsec\x18\n \x01(\r\x12\n\n\x02id\x18\x0b \x01(\r\x12+\n\x08question\x18\x0c \x01(\x0b\x32\x19.PBDNSMessage.DNSQuestion\x12+\n\x08response\x18\r \x01(\x0b\x32\x19.PBDNSMessage.DNSResponse\x12\x1f\n\x17originalRequestorSubnet\x18\x0e \x01(\x0c\x12\x13\n\x0brequestorId\x18\x0f \x01(\t\x12\x18\n\x10initialRequestId\x18\x10 \x01(\x0c\x12\x10\n\x08\x64\x65viceId\x18\x11 \x01(\x0c\x12\x1b\n\x13newlyObservedDomain\x18\x12 \x01(\x08\x12\x12\n\ndeviceName\x18\x13 \x01(\t\x12\x10\n\x08\x66romPort\x18\x14 \x01(\r\x12\x0e\n\x06toPort\x18\x15 \x01(\r\x1a;\n\x0b\x44NSQuestion\x12\r\n\x05qName\x18\x01 \x01(\t\x12\r\n\x05qType\x18\x02 \x01(\r\x12\x0e\n\x06qClass\x18\x03 \x01(\r\x1a\xe6\x02\n\x0b\x44NSResponse\x12\r\n\x05rcode\x18\x01 \x01(\r\x12,\n\x03rrs\x18\x02 \x03(\x0b\x32\x1f.PBDNSMessage.DNSResponse.DNSRR\x12\x15\n\rappliedPolicy\x18\x03 \x01(\t\x12\x0c\n\x04tags\x18\x04 \x03(\t\x12\x14\n\x0cqueryTimeSec\x18\x05 \x01(\r\x12\x15\n\rqueryTimeUsec\x18\x06 \x01(\r\x12\x33\n\x11\x61ppliedPolicyType\x18\x07 \x01(\x0e\x32\x18.PBDNSMessage.PolicyType\x12\x1c\n\x14\x61ppliedPolicyTrigger\x18\x08 \x01(\t\x12\x18\n\x10\x61ppliedPolicyHit\x18\t \x01(\t\x1a[\n\x05\x44NSRR\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\r\x12\r\n\x05\x63lass\x18\x03 \x01(\r\x12\x0b\n\x03ttl\x18\x04 \x01(\r\x12\r\n\x05rdata\x18\x05 \x01(\x0c\x12\x0b\n\x03udr\x18\x06 \x01(\x08\"d\n\x04Type\x12\x10\n\x0c\x44NSQueryType\x10\x01\x12\x13\n\x0f\x44NSResponseType\x10\x02\x12\x18\n\x14\x44NSOutgoingQueryType\x10\x03\x12\x1b\n\x17\x44NSIncomingResponseType\x10\x04\"#\n\x0cSocketFamily\x12\x08\n\x04INET\x10\x01\x12\t\n\x05INET6\x10\x02\"\"\n\x0eSocketProtocol\x12\x07\n\x03UDP\x10\x01\x12\x07\n\x03TCP\x10\x02\"Y\n\nPolicyType\x12\x0b\n\x07UNKNOWN\x10\x01\x12\t\n\x05QNAME\x10\x02\x12\x0c\n\x08\x43LIENTIP\x10\x03\x12\x0e\n\nRESPONSEIP\x10\x04\x12\x0b\n\x07NSDNAME\x10\x05\x12\x08\n\x04NSIP\x10\x06\".\n\x10PBDNSMessageList\x12\x1a\n\x03msg\x18\x01 \x03(\x0b\x32\r.PBDNSMessage' 23 | ) 24 | 25 | 26 | 27 | _PBDNSMESSAGE_TYPE = _descriptor.EnumDescriptor( 28 | name='Type', 29 | full_name='PBDNSMessage.Type', 30 | filename=None, 31 | file=DESCRIPTOR, 32 | create_key=_descriptor._internal_create_key, 33 | values=[ 34 | _descriptor.EnumValueDescriptor( 35 | name='DNSQueryType', index=0, number=1, 36 | serialized_options=None, 37 | type=None, 38 | create_key=_descriptor._internal_create_key), 39 | _descriptor.EnumValueDescriptor( 40 | name='DNSResponseType', index=1, number=2, 41 | serialized_options=None, 42 | type=None, 43 | create_key=_descriptor._internal_create_key), 44 | _descriptor.EnumValueDescriptor( 45 | name='DNSOutgoingQueryType', index=2, number=3, 46 | serialized_options=None, 47 | type=None, 48 | create_key=_descriptor._internal_create_key), 49 | _descriptor.EnumValueDescriptor( 50 | name='DNSIncomingResponseType', index=3, number=4, 51 | serialized_options=None, 52 | type=None, 53 | create_key=_descriptor._internal_create_key), 54 | ], 55 | containing_type=None, 56 | serialized_options=None, 57 | serialized_start=1001, 58 | serialized_end=1101, 59 | ) 60 | _sym_db.RegisterEnumDescriptor(_PBDNSMESSAGE_TYPE) 61 | 62 | _PBDNSMESSAGE_SOCKETFAMILY = _descriptor.EnumDescriptor( 63 | name='SocketFamily', 64 | full_name='PBDNSMessage.SocketFamily', 65 | filename=None, 66 | file=DESCRIPTOR, 67 | create_key=_descriptor._internal_create_key, 68 | values=[ 69 | _descriptor.EnumValueDescriptor( 70 | name='INET', index=0, number=1, 71 | serialized_options=None, 72 | type=None, 73 | create_key=_descriptor._internal_create_key), 74 | _descriptor.EnumValueDescriptor( 75 | name='INET6', index=1, number=2, 76 | serialized_options=None, 77 | type=None, 78 | create_key=_descriptor._internal_create_key), 79 | ], 80 | containing_type=None, 81 | serialized_options=None, 82 | serialized_start=1103, 83 | serialized_end=1138, 84 | ) 85 | _sym_db.RegisterEnumDescriptor(_PBDNSMESSAGE_SOCKETFAMILY) 86 | 87 | _PBDNSMESSAGE_SOCKETPROTOCOL = _descriptor.EnumDescriptor( 88 | name='SocketProtocol', 89 | full_name='PBDNSMessage.SocketProtocol', 90 | filename=None, 91 | file=DESCRIPTOR, 92 | create_key=_descriptor._internal_create_key, 93 | values=[ 94 | _descriptor.EnumValueDescriptor( 95 | name='UDP', index=0, number=1, 96 | serialized_options=None, 97 | type=None, 98 | create_key=_descriptor._internal_create_key), 99 | _descriptor.EnumValueDescriptor( 100 | name='TCP', index=1, number=2, 101 | serialized_options=None, 102 | type=None, 103 | create_key=_descriptor._internal_create_key), 104 | ], 105 | containing_type=None, 106 | serialized_options=None, 107 | serialized_start=1140, 108 | serialized_end=1174, 109 | ) 110 | _sym_db.RegisterEnumDescriptor(_PBDNSMESSAGE_SOCKETPROTOCOL) 111 | 112 | _PBDNSMESSAGE_POLICYTYPE = _descriptor.EnumDescriptor( 113 | name='PolicyType', 114 | full_name='PBDNSMessage.PolicyType', 115 | filename=None, 116 | file=DESCRIPTOR, 117 | create_key=_descriptor._internal_create_key, 118 | values=[ 119 | _descriptor.EnumValueDescriptor( 120 | name='UNKNOWN', index=0, number=1, 121 | serialized_options=None, 122 | type=None, 123 | create_key=_descriptor._internal_create_key), 124 | _descriptor.EnumValueDescriptor( 125 | name='QNAME', index=1, number=2, 126 | serialized_options=None, 127 | type=None, 128 | create_key=_descriptor._internal_create_key), 129 | _descriptor.EnumValueDescriptor( 130 | name='CLIENTIP', index=2, number=3, 131 | serialized_options=None, 132 | type=None, 133 | create_key=_descriptor._internal_create_key), 134 | _descriptor.EnumValueDescriptor( 135 | name='RESPONSEIP', index=3, number=4, 136 | serialized_options=None, 137 | type=None, 138 | create_key=_descriptor._internal_create_key), 139 | _descriptor.EnumValueDescriptor( 140 | name='NSDNAME', index=4, number=5, 141 | serialized_options=None, 142 | type=None, 143 | create_key=_descriptor._internal_create_key), 144 | _descriptor.EnumValueDescriptor( 145 | name='NSIP', index=5, number=6, 146 | serialized_options=None, 147 | type=None, 148 | create_key=_descriptor._internal_create_key), 149 | ], 150 | containing_type=None, 151 | serialized_options=None, 152 | serialized_start=1176, 153 | serialized_end=1265, 154 | ) 155 | _sym_db.RegisterEnumDescriptor(_PBDNSMESSAGE_POLICYTYPE) 156 | 157 | 158 | _PBDNSMESSAGE_DNSQUESTION = _descriptor.Descriptor( 159 | name='DNSQuestion', 160 | full_name='PBDNSMessage.DNSQuestion', 161 | filename=None, 162 | file=DESCRIPTOR, 163 | containing_type=None, 164 | create_key=_descriptor._internal_create_key, 165 | fields=[ 166 | _descriptor.FieldDescriptor( 167 | name='qName', full_name='PBDNSMessage.DNSQuestion.qName', index=0, 168 | number=1, type=9, cpp_type=9, label=1, 169 | has_default_value=False, default_value=b"".decode('utf-8'), 170 | message_type=None, enum_type=None, containing_type=None, 171 | is_extension=False, extension_scope=None, 172 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 173 | _descriptor.FieldDescriptor( 174 | name='qType', full_name='PBDNSMessage.DNSQuestion.qType', index=1, 175 | number=2, type=13, cpp_type=3, label=1, 176 | has_default_value=False, default_value=0, 177 | message_type=None, enum_type=None, containing_type=None, 178 | is_extension=False, extension_scope=None, 179 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 180 | _descriptor.FieldDescriptor( 181 | name='qClass', full_name='PBDNSMessage.DNSQuestion.qClass', index=2, 182 | number=3, type=13, cpp_type=3, label=1, 183 | has_default_value=False, default_value=0, 184 | message_type=None, enum_type=None, containing_type=None, 185 | is_extension=False, extension_scope=None, 186 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 187 | ], 188 | extensions=[ 189 | ], 190 | nested_types=[], 191 | enum_types=[ 192 | ], 193 | serialized_options=None, 194 | is_extendable=False, 195 | syntax='proto2', 196 | extension_ranges=[], 197 | oneofs=[ 198 | ], 199 | serialized_start=579, 200 | serialized_end=638, 201 | ) 202 | 203 | _PBDNSMESSAGE_DNSRESPONSE_DNSRR = _descriptor.Descriptor( 204 | name='DNSRR', 205 | full_name='PBDNSMessage.DNSResponse.DNSRR', 206 | filename=None, 207 | file=DESCRIPTOR, 208 | containing_type=None, 209 | create_key=_descriptor._internal_create_key, 210 | fields=[ 211 | _descriptor.FieldDescriptor( 212 | name='name', full_name='PBDNSMessage.DNSResponse.DNSRR.name', index=0, 213 | number=1, type=9, cpp_type=9, label=1, 214 | has_default_value=False, default_value=b"".decode('utf-8'), 215 | message_type=None, enum_type=None, containing_type=None, 216 | is_extension=False, extension_scope=None, 217 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 218 | _descriptor.FieldDescriptor( 219 | name='type', full_name='PBDNSMessage.DNSResponse.DNSRR.type', index=1, 220 | number=2, type=13, cpp_type=3, label=1, 221 | has_default_value=False, default_value=0, 222 | message_type=None, enum_type=None, containing_type=None, 223 | is_extension=False, extension_scope=None, 224 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 225 | _descriptor.FieldDescriptor( 226 | name='class', full_name='PBDNSMessage.DNSResponse.DNSRR.class', index=2, 227 | number=3, type=13, cpp_type=3, label=1, 228 | has_default_value=False, default_value=0, 229 | message_type=None, enum_type=None, containing_type=None, 230 | is_extension=False, extension_scope=None, 231 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 232 | _descriptor.FieldDescriptor( 233 | name='ttl', full_name='PBDNSMessage.DNSResponse.DNSRR.ttl', index=3, 234 | number=4, type=13, cpp_type=3, label=1, 235 | has_default_value=False, default_value=0, 236 | message_type=None, enum_type=None, containing_type=None, 237 | is_extension=False, extension_scope=None, 238 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 239 | _descriptor.FieldDescriptor( 240 | name='rdata', full_name='PBDNSMessage.DNSResponse.DNSRR.rdata', index=4, 241 | number=5, type=12, cpp_type=9, label=1, 242 | has_default_value=False, default_value=b"", 243 | message_type=None, enum_type=None, containing_type=None, 244 | is_extension=False, extension_scope=None, 245 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 246 | _descriptor.FieldDescriptor( 247 | name='udr', full_name='PBDNSMessage.DNSResponse.DNSRR.udr', index=5, 248 | number=6, type=8, cpp_type=7, label=1, 249 | has_default_value=False, default_value=False, 250 | message_type=None, enum_type=None, containing_type=None, 251 | is_extension=False, extension_scope=None, 252 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 253 | ], 254 | extensions=[ 255 | ], 256 | nested_types=[], 257 | enum_types=[ 258 | ], 259 | serialized_options=None, 260 | is_extendable=False, 261 | syntax='proto2', 262 | extension_ranges=[], 263 | oneofs=[ 264 | ], 265 | serialized_start=908, 266 | serialized_end=999, 267 | ) 268 | 269 | _PBDNSMESSAGE_DNSRESPONSE = _descriptor.Descriptor( 270 | name='DNSResponse', 271 | full_name='PBDNSMessage.DNSResponse', 272 | filename=None, 273 | file=DESCRIPTOR, 274 | containing_type=None, 275 | create_key=_descriptor._internal_create_key, 276 | fields=[ 277 | _descriptor.FieldDescriptor( 278 | name='rcode', full_name='PBDNSMessage.DNSResponse.rcode', index=0, 279 | number=1, type=13, cpp_type=3, label=1, 280 | has_default_value=False, default_value=0, 281 | message_type=None, enum_type=None, containing_type=None, 282 | is_extension=False, extension_scope=None, 283 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 284 | _descriptor.FieldDescriptor( 285 | name='rrs', full_name='PBDNSMessage.DNSResponse.rrs', index=1, 286 | number=2, type=11, cpp_type=10, label=3, 287 | has_default_value=False, default_value=[], 288 | message_type=None, enum_type=None, containing_type=None, 289 | is_extension=False, extension_scope=None, 290 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 291 | _descriptor.FieldDescriptor( 292 | name='appliedPolicy', full_name='PBDNSMessage.DNSResponse.appliedPolicy', index=2, 293 | number=3, type=9, cpp_type=9, label=1, 294 | has_default_value=False, default_value=b"".decode('utf-8'), 295 | message_type=None, enum_type=None, containing_type=None, 296 | is_extension=False, extension_scope=None, 297 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 298 | _descriptor.FieldDescriptor( 299 | name='tags', full_name='PBDNSMessage.DNSResponse.tags', index=3, 300 | number=4, type=9, cpp_type=9, label=3, 301 | has_default_value=False, default_value=[], 302 | message_type=None, enum_type=None, containing_type=None, 303 | is_extension=False, extension_scope=None, 304 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 305 | _descriptor.FieldDescriptor( 306 | name='queryTimeSec', full_name='PBDNSMessage.DNSResponse.queryTimeSec', index=4, 307 | number=5, type=13, cpp_type=3, label=1, 308 | has_default_value=False, default_value=0, 309 | message_type=None, enum_type=None, containing_type=None, 310 | is_extension=False, extension_scope=None, 311 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 312 | _descriptor.FieldDescriptor( 313 | name='queryTimeUsec', full_name='PBDNSMessage.DNSResponse.queryTimeUsec', index=5, 314 | number=6, type=13, cpp_type=3, label=1, 315 | has_default_value=False, default_value=0, 316 | message_type=None, enum_type=None, containing_type=None, 317 | is_extension=False, extension_scope=None, 318 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 319 | _descriptor.FieldDescriptor( 320 | name='appliedPolicyType', full_name='PBDNSMessage.DNSResponse.appliedPolicyType', index=6, 321 | number=7, type=14, cpp_type=8, label=1, 322 | has_default_value=False, default_value=1, 323 | message_type=None, enum_type=None, containing_type=None, 324 | is_extension=False, extension_scope=None, 325 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 326 | _descriptor.FieldDescriptor( 327 | name='appliedPolicyTrigger', full_name='PBDNSMessage.DNSResponse.appliedPolicyTrigger', index=7, 328 | number=8, type=9, cpp_type=9, label=1, 329 | has_default_value=False, default_value=b"".decode('utf-8'), 330 | message_type=None, enum_type=None, containing_type=None, 331 | is_extension=False, extension_scope=None, 332 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 333 | _descriptor.FieldDescriptor( 334 | name='appliedPolicyHit', full_name='PBDNSMessage.DNSResponse.appliedPolicyHit', index=8, 335 | number=9, type=9, cpp_type=9, label=1, 336 | has_default_value=False, default_value=b"".decode('utf-8'), 337 | message_type=None, enum_type=None, containing_type=None, 338 | is_extension=False, extension_scope=None, 339 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 340 | ], 341 | extensions=[ 342 | ], 343 | nested_types=[_PBDNSMESSAGE_DNSRESPONSE_DNSRR, ], 344 | enum_types=[ 345 | ], 346 | serialized_options=None, 347 | is_extendable=False, 348 | syntax='proto2', 349 | extension_ranges=[], 350 | oneofs=[ 351 | ], 352 | serialized_start=641, 353 | serialized_end=999, 354 | ) 355 | 356 | _PBDNSMESSAGE = _descriptor.Descriptor( 357 | name='PBDNSMessage', 358 | full_name='PBDNSMessage', 359 | filename=None, 360 | file=DESCRIPTOR, 361 | containing_type=None, 362 | create_key=_descriptor._internal_create_key, 363 | fields=[ 364 | _descriptor.FieldDescriptor( 365 | name='type', full_name='PBDNSMessage.type', index=0, 366 | number=1, type=14, cpp_type=8, label=2, 367 | has_default_value=False, default_value=1, 368 | message_type=None, enum_type=None, containing_type=None, 369 | is_extension=False, extension_scope=None, 370 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 371 | _descriptor.FieldDescriptor( 372 | name='messageId', full_name='PBDNSMessage.messageId', index=1, 373 | number=2, type=12, cpp_type=9, label=1, 374 | has_default_value=False, default_value=b"", 375 | message_type=None, enum_type=None, containing_type=None, 376 | is_extension=False, extension_scope=None, 377 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 378 | _descriptor.FieldDescriptor( 379 | name='serverIdentity', full_name='PBDNSMessage.serverIdentity', index=2, 380 | number=3, type=12, cpp_type=9, label=1, 381 | has_default_value=False, default_value=b"", 382 | message_type=None, enum_type=None, containing_type=None, 383 | is_extension=False, extension_scope=None, 384 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 385 | _descriptor.FieldDescriptor( 386 | name='socketFamily', full_name='PBDNSMessage.socketFamily', index=3, 387 | number=4, type=14, cpp_type=8, label=1, 388 | has_default_value=False, default_value=1, 389 | message_type=None, enum_type=None, containing_type=None, 390 | is_extension=False, extension_scope=None, 391 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 392 | _descriptor.FieldDescriptor( 393 | name='socketProtocol', full_name='PBDNSMessage.socketProtocol', index=4, 394 | number=5, type=14, cpp_type=8, label=1, 395 | has_default_value=False, default_value=1, 396 | message_type=None, enum_type=None, containing_type=None, 397 | is_extension=False, extension_scope=None, 398 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 399 | _descriptor.FieldDescriptor( 400 | name='from', full_name='PBDNSMessage.from', index=5, 401 | number=6, type=12, cpp_type=9, label=1, 402 | has_default_value=False, default_value=b"", 403 | message_type=None, enum_type=None, containing_type=None, 404 | is_extension=False, extension_scope=None, 405 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 406 | _descriptor.FieldDescriptor( 407 | name='to', full_name='PBDNSMessage.to', index=6, 408 | number=7, type=12, cpp_type=9, label=1, 409 | has_default_value=False, default_value=b"", 410 | message_type=None, enum_type=None, containing_type=None, 411 | is_extension=False, extension_scope=None, 412 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 413 | _descriptor.FieldDescriptor( 414 | name='inBytes', full_name='PBDNSMessage.inBytes', index=7, 415 | number=8, type=4, cpp_type=4, label=1, 416 | has_default_value=False, default_value=0, 417 | message_type=None, enum_type=None, containing_type=None, 418 | is_extension=False, extension_scope=None, 419 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 420 | _descriptor.FieldDescriptor( 421 | name='timeSec', full_name='PBDNSMessage.timeSec', index=8, 422 | number=9, type=13, cpp_type=3, label=1, 423 | has_default_value=False, default_value=0, 424 | message_type=None, enum_type=None, containing_type=None, 425 | is_extension=False, extension_scope=None, 426 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 427 | _descriptor.FieldDescriptor( 428 | name='timeUsec', full_name='PBDNSMessage.timeUsec', index=9, 429 | number=10, type=13, cpp_type=3, label=1, 430 | has_default_value=False, default_value=0, 431 | message_type=None, enum_type=None, containing_type=None, 432 | is_extension=False, extension_scope=None, 433 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 434 | _descriptor.FieldDescriptor( 435 | name='id', full_name='PBDNSMessage.id', index=10, 436 | number=11, type=13, cpp_type=3, label=1, 437 | has_default_value=False, default_value=0, 438 | message_type=None, enum_type=None, containing_type=None, 439 | is_extension=False, extension_scope=None, 440 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 441 | _descriptor.FieldDescriptor( 442 | name='question', full_name='PBDNSMessage.question', index=11, 443 | number=12, type=11, cpp_type=10, label=1, 444 | has_default_value=False, default_value=None, 445 | message_type=None, enum_type=None, containing_type=None, 446 | is_extension=False, extension_scope=None, 447 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 448 | _descriptor.FieldDescriptor( 449 | name='response', full_name='PBDNSMessage.response', index=12, 450 | number=13, type=11, cpp_type=10, label=1, 451 | has_default_value=False, default_value=None, 452 | message_type=None, enum_type=None, containing_type=None, 453 | is_extension=False, extension_scope=None, 454 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 455 | _descriptor.FieldDescriptor( 456 | name='originalRequestorSubnet', full_name='PBDNSMessage.originalRequestorSubnet', index=13, 457 | number=14, type=12, cpp_type=9, label=1, 458 | has_default_value=False, default_value=b"", 459 | message_type=None, enum_type=None, containing_type=None, 460 | is_extension=False, extension_scope=None, 461 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 462 | _descriptor.FieldDescriptor( 463 | name='requestorId', full_name='PBDNSMessage.requestorId', index=14, 464 | number=15, type=9, cpp_type=9, label=1, 465 | has_default_value=False, default_value=b"".decode('utf-8'), 466 | message_type=None, enum_type=None, containing_type=None, 467 | is_extension=False, extension_scope=None, 468 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 469 | _descriptor.FieldDescriptor( 470 | name='initialRequestId', full_name='PBDNSMessage.initialRequestId', index=15, 471 | number=16, type=12, cpp_type=9, label=1, 472 | has_default_value=False, default_value=b"", 473 | message_type=None, enum_type=None, containing_type=None, 474 | is_extension=False, extension_scope=None, 475 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 476 | _descriptor.FieldDescriptor( 477 | name='deviceId', full_name='PBDNSMessage.deviceId', index=16, 478 | number=17, type=12, cpp_type=9, label=1, 479 | has_default_value=False, default_value=b"", 480 | message_type=None, enum_type=None, containing_type=None, 481 | is_extension=False, extension_scope=None, 482 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 483 | _descriptor.FieldDescriptor( 484 | name='newlyObservedDomain', full_name='PBDNSMessage.newlyObservedDomain', index=17, 485 | number=18, type=8, cpp_type=7, label=1, 486 | has_default_value=False, default_value=False, 487 | message_type=None, enum_type=None, containing_type=None, 488 | is_extension=False, extension_scope=None, 489 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 490 | _descriptor.FieldDescriptor( 491 | name='deviceName', full_name='PBDNSMessage.deviceName', index=18, 492 | number=19, type=9, cpp_type=9, label=1, 493 | has_default_value=False, default_value=b"".decode('utf-8'), 494 | message_type=None, enum_type=None, containing_type=None, 495 | is_extension=False, extension_scope=None, 496 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 497 | _descriptor.FieldDescriptor( 498 | name='fromPort', full_name='PBDNSMessage.fromPort', index=19, 499 | number=20, type=13, cpp_type=3, label=1, 500 | has_default_value=False, default_value=0, 501 | message_type=None, enum_type=None, containing_type=None, 502 | is_extension=False, extension_scope=None, 503 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 504 | _descriptor.FieldDescriptor( 505 | name='toPort', full_name='PBDNSMessage.toPort', index=20, 506 | number=21, type=13, cpp_type=3, label=1, 507 | has_default_value=False, default_value=0, 508 | message_type=None, enum_type=None, containing_type=None, 509 | is_extension=False, extension_scope=None, 510 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 511 | ], 512 | extensions=[ 513 | ], 514 | nested_types=[_PBDNSMESSAGE_DNSQUESTION, _PBDNSMESSAGE_DNSRESPONSE, ], 515 | enum_types=[ 516 | _PBDNSMESSAGE_TYPE, 517 | _PBDNSMESSAGE_SOCKETFAMILY, 518 | _PBDNSMESSAGE_SOCKETPROTOCOL, 519 | _PBDNSMESSAGE_POLICYTYPE, 520 | ], 521 | serialized_options=None, 522 | is_extendable=False, 523 | syntax='proto2', 524 | extension_ranges=[], 525 | oneofs=[ 526 | ], 527 | serialized_start=21, 528 | serialized_end=1265, 529 | ) 530 | 531 | 532 | _PBDNSMESSAGELIST = _descriptor.Descriptor( 533 | name='PBDNSMessageList', 534 | full_name='PBDNSMessageList', 535 | filename=None, 536 | file=DESCRIPTOR, 537 | containing_type=None, 538 | create_key=_descriptor._internal_create_key, 539 | fields=[ 540 | _descriptor.FieldDescriptor( 541 | name='msg', full_name='PBDNSMessageList.msg', index=0, 542 | number=1, type=11, cpp_type=10, label=3, 543 | has_default_value=False, default_value=[], 544 | message_type=None, enum_type=None, containing_type=None, 545 | is_extension=False, extension_scope=None, 546 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 547 | ], 548 | extensions=[ 549 | ], 550 | nested_types=[], 551 | enum_types=[ 552 | ], 553 | serialized_options=None, 554 | is_extendable=False, 555 | syntax='proto2', 556 | extension_ranges=[], 557 | oneofs=[ 558 | ], 559 | serialized_start=1267, 560 | serialized_end=1313, 561 | ) 562 | 563 | _PBDNSMESSAGE_DNSQUESTION.containing_type = _PBDNSMESSAGE 564 | _PBDNSMESSAGE_DNSRESPONSE_DNSRR.containing_type = _PBDNSMESSAGE_DNSRESPONSE 565 | _PBDNSMESSAGE_DNSRESPONSE.fields_by_name['rrs'].message_type = _PBDNSMESSAGE_DNSRESPONSE_DNSRR 566 | _PBDNSMESSAGE_DNSRESPONSE.fields_by_name['appliedPolicyType'].enum_type = _PBDNSMESSAGE_POLICYTYPE 567 | _PBDNSMESSAGE_DNSRESPONSE.containing_type = _PBDNSMESSAGE 568 | _PBDNSMESSAGE.fields_by_name['type'].enum_type = _PBDNSMESSAGE_TYPE 569 | _PBDNSMESSAGE.fields_by_name['socketFamily'].enum_type = _PBDNSMESSAGE_SOCKETFAMILY 570 | _PBDNSMESSAGE.fields_by_name['socketProtocol'].enum_type = _PBDNSMESSAGE_SOCKETPROTOCOL 571 | _PBDNSMESSAGE.fields_by_name['question'].message_type = _PBDNSMESSAGE_DNSQUESTION 572 | _PBDNSMESSAGE.fields_by_name['response'].message_type = _PBDNSMESSAGE_DNSRESPONSE 573 | _PBDNSMESSAGE_TYPE.containing_type = _PBDNSMESSAGE 574 | _PBDNSMESSAGE_SOCKETFAMILY.containing_type = _PBDNSMESSAGE 575 | _PBDNSMESSAGE_SOCKETPROTOCOL.containing_type = _PBDNSMESSAGE 576 | _PBDNSMESSAGE_POLICYTYPE.containing_type = _PBDNSMESSAGE 577 | _PBDNSMESSAGELIST.fields_by_name['msg'].message_type = _PBDNSMESSAGE 578 | DESCRIPTOR.message_types_by_name['PBDNSMessage'] = _PBDNSMESSAGE 579 | DESCRIPTOR.message_types_by_name['PBDNSMessageList'] = _PBDNSMESSAGELIST 580 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 581 | 582 | PBDNSMessage = _reflection.GeneratedProtocolMessageType('PBDNSMessage', (_message.Message,), { 583 | 584 | 'DNSQuestion' : _reflection.GeneratedProtocolMessageType('DNSQuestion', (_message.Message,), { 585 | 'DESCRIPTOR' : _PBDNSMESSAGE_DNSQUESTION, 586 | '__module__' : 'dnsmessage_pb2' 587 | # @@protoc_insertion_point(class_scope:PBDNSMessage.DNSQuestion) 588 | }) 589 | , 590 | 591 | 'DNSResponse' : _reflection.GeneratedProtocolMessageType('DNSResponse', (_message.Message,), { 592 | 593 | 'DNSRR' : _reflection.GeneratedProtocolMessageType('DNSRR', (_message.Message,), { 594 | 'DESCRIPTOR' : _PBDNSMESSAGE_DNSRESPONSE_DNSRR, 595 | '__module__' : 'dnsmessage_pb2' 596 | # @@protoc_insertion_point(class_scope:PBDNSMessage.DNSResponse.DNSRR) 597 | }) 598 | , 599 | 'DESCRIPTOR' : _PBDNSMESSAGE_DNSRESPONSE, 600 | '__module__' : 'dnsmessage_pb2' 601 | # @@protoc_insertion_point(class_scope:PBDNSMessage.DNSResponse) 602 | }) 603 | , 604 | 'DESCRIPTOR' : _PBDNSMESSAGE, 605 | '__module__' : 'dnsmessage_pb2' 606 | # @@protoc_insertion_point(class_scope:PBDNSMessage) 607 | }) 608 | _sym_db.RegisterMessage(PBDNSMessage) 609 | _sym_db.RegisterMessage(PBDNSMessage.DNSQuestion) 610 | _sym_db.RegisterMessage(PBDNSMessage.DNSResponse) 611 | _sym_db.RegisterMessage(PBDNSMessage.DNSResponse.DNSRR) 612 | 613 | PBDNSMessageList = _reflection.GeneratedProtocolMessageType('PBDNSMessageList', (_message.Message,), { 614 | 'DESCRIPTOR' : _PBDNSMESSAGELIST, 615 | '__module__' : 'dnsmessage_pb2' 616 | # @@protoc_insertion_point(class_scope:PBDNSMessageList) 617 | }) 618 | _sym_db.RegisterMessage(PBDNSMessageList) 619 | 620 | 621 | # @@protoc_insertion_point(module_scope) 622 | --------------------------------------------------------------------------------