hgext/zeroconf/Zeroconf.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 23 Feb 2023 04:28:24 +0100
changeset 50192 6794f927bc48
parent 49293 e3143ab9dadb
child 51167 b79f13d6ef25
permissions -rw-r--r--
narrow: enforce that narrow spec is written within a transaction
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
""" Multicast DNS Service Discovery for Python, v0.12
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
    Copyright (C) 2003, Paul Scott-Murphy
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
    This module provides a framework for the use of DNS Service Discovery
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
    using IP multicast.  It has been tested against the JRendezvous
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
    implementation from <a href="http://strangeberry.com">StrangeBerry</a>,
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
    and against the mDNSResponder from Mac OS X 10.3.8.
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
    This library is free software; you can redistribute it and/or
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
    modify it under the terms of the GNU Lesser General Public
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
    License as published by the Free Software Foundation; either
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
    version 2.1 of the License, or (at your option) any later version.
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
    This library is distributed in the hope that it will be useful,
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    Lesser General Public License for more details.
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    You should have received a copy of the GNU Lesser General Public
15782
7de7630053cb Remove FSF mailing address from GPL headers
Martin Geisler <mg@aragost.com>
parents: 14494
diff changeset
    20
    License along with this library; if not, see
7de7630053cb Remove FSF mailing address from GPL headers
Martin Geisler <mg@aragost.com>
parents: 14494
diff changeset
    21
    <http://www.gnu.org/licenses/>.
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
    22
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
"""
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
"""0.12 update - allow selection of binding interface
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    26
         typo fix - Thanks A. M. Kuchlingi
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    27
         removed all use of word 'Rendezvous' - this is an API change"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
"""0.11 update - correction to comments for addListener method
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
                 support for new record types seen from OS X
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    31
                  - IPv6 address
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    32
                  - hostinfo
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    33
                 ignore unknown DNS record types
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    34
                 fixes to name decoding
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
    35
                 works alongside other processes using port 5353 (e.g. Mac OS X)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    36
                 tested against Mac OS X 10.3.2's mDNSResponder
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    37
                 corrections to removal of list entries for service browser"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
"""0.10 update - Jonathon Paisley contributed these corrections:
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
                 always multicast replies, even when query is unicast
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    41
                 correct a pointer encoding problem
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    42
                 can now write records in any order
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    43
                 traceback shown on failure
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    44
                 better TXT record parsing
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    45
                 server is now separate from name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    46
                 can cancel a service browser
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    48
                 modified some unit tests to accommodate these changes"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
"""0.09 update - remove all records on service unregistration
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
                 fix DOS security problem with readName"""
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
"""0.08 update - changed licensing to LGPL"""
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
"""0.07 update - faster shutdown on engine
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
                 pointer encoding of outgoing names
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    57
                 ServiceBrowser now works
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    58
                 new unit tests"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
"""0.06 update - small improvements with unit tests
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                 added defined exception types
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    62
                 new style objects
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    63
                 fixed hostname/interface problem
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    64
                 fixed socket timeout problem
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    65
                 fixed addServiceListener() typo bug
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    66
                 using select() for socket reads
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    67
                 tested on Debian unstable with Python 2.2.2"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 15782
diff changeset
    69
"""0.05 update - ensure case insensitivity on domain names
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
                 support for unicast DNS queries"""
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
"""0.04 update - added some unit tests
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
                 added __ne__ adjuncts where required
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    74
                 ensure names end in '.local.'
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
    75
                 timeout on receiving socket for clean shutdown"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    77
__author__ = b"Paul Scott-Murphy"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    78
__email__ = b"paul at scott dash murphy dot com"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    79
__version__ = b"0.12"
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
34447
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
    81
import errno
28422
e2c6092ad422 zeroconf: replace reduce+add with itertools.chain
timeless <timeless@mozdev.org>
parents: 28421
diff changeset
    82
import itertools
28296
a73394e7b47c zeroconf: use absolute_import
timeless <timeless@mozdev.org>
parents: 28295
diff changeset
    83
import select
a73394e7b47c zeroconf: use absolute_import
timeless <timeless@mozdev.org>
parents: 28295
diff changeset
    84
import socket
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
import struct
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
import threading
28296
a73394e7b47c zeroconf: use absolute_import
timeless <timeless@mozdev.org>
parents: 28295
diff changeset
    87
import time
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
import traceback
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
42551
8306b6c29add py3: hack around inconsistency of type of name passed to DNSQuestion
Pulkit Goyal <7895pulkit@gmail.com>
parents: 42550
diff changeset
    90
from mercurial import pycompat
8306b6c29add py3: hack around inconsistency of type of name passed to DNSQuestion
Pulkit Goyal <7895pulkit@gmail.com>
parents: 42550
diff changeset
    91
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    92
__all__ = [b"Zeroconf", b"ServiceInfo", b"ServiceBrowser"]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
# hook for threads
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    96
globals()[b'_GLOBAL_DONE'] = 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
# Some timing constants
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
_UNREGISTER_TIME = 125
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
_CHECK_TIME = 175
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
_REGISTER_TIME = 225
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
_LISTENER_TIME = 200
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
_BROWSER_TIME = 500
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
# Some DNS constants
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   107
41519
a36f462cf533 zeroconf: Python 3 porting of vendored library
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41365
diff changeset
   108
_MDNS_ADDR = r'224.0.0.251'
28297
f6d07520c665 zeroconf: omit semicolons
timeless <timeless@mozdev.org>
parents: 28296
diff changeset
   109
_MDNS_PORT = 5353
f6d07520c665 zeroconf: omit semicolons
timeless <timeless@mozdev.org>
parents: 28296
diff changeset
   110
_DNS_PORT = 53
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   111
_DNS_TTL = 60 * 60  # one hour default TTL
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   112
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   113
_MAX_MSG_TYPICAL = 1460  # unused
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
_MAX_MSG_ABSOLUTE = 8972
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   116
_FLAGS_QR_MASK = 0x8000  # query response mask
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   117
_FLAGS_QR_QUERY = 0x0000  # query
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   118
_FLAGS_QR_RESPONSE = 0x8000  # response
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   120
_FLAGS_AA = 0x0400  # Authoritative answer
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   121
_FLAGS_TC = 0x0200  # Truncated
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   122
_FLAGS_RD = 0x0100  # Recursion desired
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   123
_FLAGS_RA = 0x8000  # Recursion available
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   124
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   125
_FLAGS_Z = 0x0040  # Zero
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   126
_FLAGS_AD = 0x0020  # Authentic data
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   127
_FLAGS_CD = 0x0010  # Checking disabled
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   129
_CLASS_IN = 1
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   130
_CLASS_CS = 2
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   131
_CLASS_CH = 3
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   132
_CLASS_HS = 4
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   133
_CLASS_NONE = 254
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
_CLASS_ANY = 255
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   135
_CLASS_MASK = 0x7FFF
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   136
_CLASS_UNIQUE = 0x8000
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   137
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   138
_TYPE_A = 1
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   139
_TYPE_NS = 2
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   140
_TYPE_MD = 3
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
_TYPE_MF = 4
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   142
_TYPE_CNAME = 5
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   143
_TYPE_SOA = 6
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   144
_TYPE_MB = 7
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
_TYPE_MG = 8
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
_TYPE_MR = 9
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   147
_TYPE_NULL = 10
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
_TYPE_WKS = 11
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   149
_TYPE_PTR = 12
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   150
_TYPE_HINFO = 13
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   151
_TYPE_MINFO = 14
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   152
_TYPE_MX = 15
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   153
_TYPE_TXT = 16
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   154
_TYPE_AAAA = 28
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
_TYPE_SRV = 33
27637
b502138f5faa cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents: 17537
diff changeset
   156
_TYPE_ANY = 255
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
# Mapping constants to names
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   160
_CLASSES = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   161
    _CLASS_IN: b"in",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   162
    _CLASS_CS: b"cs",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   163
    _CLASS_CH: b"ch",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   164
    _CLASS_HS: b"hs",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   165
    _CLASS_NONE: b"none",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   166
    _CLASS_ANY: b"any",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   167
}
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   169
_TYPES = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   170
    _TYPE_A: b"a",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   171
    _TYPE_NS: b"ns",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   172
    _TYPE_MD: b"md",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   173
    _TYPE_MF: b"mf",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   174
    _TYPE_CNAME: b"cname",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   175
    _TYPE_SOA: b"soa",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   176
    _TYPE_MB: b"mb",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   177
    _TYPE_MG: b"mg",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   178
    _TYPE_MR: b"mr",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   179
    _TYPE_NULL: b"null",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   180
    _TYPE_WKS: b"wks",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
    _TYPE_PTR: b"ptr",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   182
    _TYPE_HINFO: b"hinfo",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   183
    _TYPE_MINFO: b"minfo",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   184
    _TYPE_MX: b"mx",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   185
    _TYPE_TXT: b"txt",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   186
    _TYPE_AAAA: b"quada",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   187
    _TYPE_SRV: b"srv",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   188
    _TYPE_ANY: b"any",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   189
}
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   190
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   191
# utility functions
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   193
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
def currentTimeMillis():
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   195
    """Current system time in milliseconds"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   196
    return time.time() * 1000
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   197
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   198
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   199
# Exceptions
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   200
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   201
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   202
class NonLocalNameException(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   203
    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   205
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   206
class NonUniqueNameException(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   207
    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   208
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   209
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
class NamePartTooLongException(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   211
    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   213
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   214
class AbstractMethodException(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   215
    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   216
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   217
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   218
class BadTypeInNameException(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   219
    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   221
11435
7c58cde598fe zeroconf: Use BadDomainName exception instead of string exceptions
Javi Merino <cibervicho@gmail.com>
parents: 10514
diff changeset
   222
class BadDomainName(Exception):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   223
    def __init__(self, pos):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   224
        Exception.__init__(self, b"at position %s" % pos)
11435
7c58cde598fe zeroconf: Use BadDomainName exception instead of string exceptions
Javi Merino <cibervicho@gmail.com>
parents: 10514
diff changeset
   225
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   226
11435
7c58cde598fe zeroconf: Use BadDomainName exception instead of string exceptions
Javi Merino <cibervicho@gmail.com>
parents: 10514
diff changeset
   227
class BadDomainNameCircular(BadDomainName):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   228
    pass
11435
7c58cde598fe zeroconf: Use BadDomainName exception instead of string exceptions
Javi Merino <cibervicho@gmail.com>
parents: 10514
diff changeset
   229
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   230
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   231
# implementation classes
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   232
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   233
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   234
class DNSEntry:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   235
    """A DNS entry"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   236
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   237
    def __init__(self, name, type, clazz):
41519
a36f462cf533 zeroconf: Python 3 porting of vendored library
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41365
diff changeset
   238
        self.key = name.lower()
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   239
        self.name = name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   240
        self.type = type
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   241
        self.clazz = clazz & _CLASS_MASK
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   242
        self.unique = (clazz & _CLASS_UNIQUE) != 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   243
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   244
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   245
        """Equality test on name, type, and class"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   246
        if isinstance(other, DNSEntry):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   247
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   248
                self.name == other.name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   249
                and self.type == other.type
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   250
                and self.clazz == other.clazz
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   251
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   252
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   253
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   254
    def __ne__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   255
        """Non-equality test"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   256
        return not self.__eq__(other)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   257
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   258
    def getClazz(self, clazz):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   259
        """Class accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   260
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   261
            return _CLASSES[clazz]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   262
        except KeyError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
            return b"?(%s)" % clazz
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   264
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   265
    def getType(self, type):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   266
        """Type accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   267
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   268
            return _TYPES[type]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   269
        except KeyError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
            return b"?(%s)" % type
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   271
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   272
    def toString(self, hdr, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   273
        """String representation with additional information"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   274
        result = b"%s[%s,%s" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   275
            hdr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   276
            self.getType(self.type),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   277
            self.getClazz(self.clazz),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   278
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   279
        if self.unique:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   280
            result += b"-unique,"
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   281
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   282
            result += b","
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   283
        result += self.name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   284
        if other is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   285
            result += b",%s]" % other
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   286
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   287
            result += b"]"
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   288
        return result
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   289
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   290
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   291
class DNSQuestion(DNSEntry):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   292
    """A DNS question entry"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   293
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   294
    def __init__(self, name, type, clazz):
49293
e3143ab9dadb zeroconf: constant-fold a `pycompat.ispy3`
Manuel Jacob <me@manueljacob.de>
parents: 49053
diff changeset
   295
        if isinstance(name, str):
42551
8306b6c29add py3: hack around inconsistency of type of name passed to DNSQuestion
Pulkit Goyal <7895pulkit@gmail.com>
parents: 42550
diff changeset
   296
            name = name.encode('ascii')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   297
        if not name.endswith(b".local."):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   298
            raise NonLocalNameException(name)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   299
        DNSEntry.__init__(self, name, type, clazz)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   300
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   301
    def answeredBy(self, rec):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   302
        """Returns true if the question is answered by the record"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   303
        return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   304
            self.clazz == rec.clazz
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   305
            and (self.type == rec.type or self.type == _TYPE_ANY)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   306
            and self.name == rec.name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   307
        )
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   308
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   309
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   310
        """String representation"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   311
        return DNSEntry.toString(self, b"question", None)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   312
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   313
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   314
class DNSRecord(DNSEntry):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   315
    """A DNS record - like a DNS entry, but has a TTL"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   316
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   317
    def __init__(self, name, type, clazz, ttl):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   318
        DNSEntry.__init__(self, name, type, clazz)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   319
        self.ttl = ttl
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   320
        self.created = currentTimeMillis()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   321
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   322
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   323
        """Tests equality as per DNSRecord"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   324
        if isinstance(other, DNSRecord):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   325
            return DNSEntry.__eq__(self, other)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   326
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   327
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   328
    def suppressedBy(self, msg):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   329
        """Returns true if any answer in a message can suffice for the
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   330
        information held in this record."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   331
        for record in msg.answers:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   332
            if self.suppressedByAnswer(record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   333
                return 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   334
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   335
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   336
    def suppressedByAnswer(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   337
        """Returns true if another record has same name, type and class,
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   338
        and if its TTL is at least half of this record's."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   339
        if self == other and other.ttl > (self.ttl / 2):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   340
            return 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   341
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   342
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   343
    def getExpirationTime(self, percent):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   344
        """Returns the time at which this record will have expired
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   345
        by a certain percentage."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   346
        return self.created + (percent * self.ttl * 10)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   347
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   348
    def getRemainingTTL(self, now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   349
        """Returns the remaining TTL in seconds."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   350
        return max(0, (self.getExpirationTime(100) - now) / 1000)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   351
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   352
    def isExpired(self, now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   353
        """Returns true if this record has expired."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   354
        return self.getExpirationTime(100) <= now
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   355
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   356
    def isStale(self, now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   357
        """Returns true if this record is at least half way expired."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   358
        return self.getExpirationTime(50) <= now
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   359
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   360
    def resetTTL(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   361
        """Sets this record's TTL and created time to that of
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   362
        another record."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   363
        self.created = other.created
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   364
        self.ttl = other.ttl
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   365
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   366
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   367
        """Abstract method"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   368
        raise AbstractMethodException
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   369
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   370
    def toString(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   371
        """String representation with additional information"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   372
        arg = b"%s/%s,%s" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   373
            self.ttl,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   374
            self.getRemainingTTL(currentTimeMillis()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   375
            other,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   376
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   377
        return DNSEntry.toString(self, b"record", arg)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   378
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   379
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   380
class DNSAddress(DNSRecord):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   381
    """A DNS address record"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   382
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   383
    def __init__(self, name, type, clazz, ttl, address):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   384
        DNSRecord.__init__(self, name, type, clazz, ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   385
        self.address = address
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   387
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   388
        """Used in constructing an outgoing packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   389
        out.writeString(self.address, len(self.address))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   390
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   391
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   392
        """Tests equality on address"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   393
        if isinstance(other, DNSAddress):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   394
            return self.address == other.address
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   395
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   396
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   397
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   398
        """String representation"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   399
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   400
            return socket.inet_ntoa(self.address)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   401
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   402
            return self.address
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   403
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   404
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   405
class DNSHinfo(DNSRecord):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   406
    """A DNS host information record"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   407
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   408
    def __init__(self, name, type, clazz, ttl, cpu, os):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   409
        DNSRecord.__init__(self, name, type, clazz, ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   410
        self.cpu = cpu
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   411
        self.os = os
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   412
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   413
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   414
        """Used in constructing an outgoing packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   415
        out.writeString(self.cpu, len(self.cpu))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   416
        out.writeString(self.os, len(self.os))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   417
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   418
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   419
        """Tests equality on cpu and os"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   420
        if isinstance(other, DNSHinfo):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   421
            return self.cpu == other.cpu and self.os == other.os
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   422
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   423
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   424
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   425
        """String representation"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   426
        return self.cpu + b" " + self.os
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   427
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   428
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   429
class DNSPointer(DNSRecord):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   430
    """A DNS pointer record"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   431
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   432
    def __init__(self, name, type, clazz, ttl, alias):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   433
        DNSRecord.__init__(self, name, type, clazz, ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   434
        self.alias = alias
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   435
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   436
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   437
        """Used in constructing an outgoing packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   438
        out.writeName(self.alias)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   439
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   440
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   441
        """Tests equality on alias"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   442
        if isinstance(other, DNSPointer):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   443
            return self.alias == other.alias
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   444
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   445
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   446
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   447
        """String representation"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   448
        return self.toString(self.alias)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   449
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   450
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   451
class DNSText(DNSRecord):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   452
    """A DNS text record"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   453
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   454
    def __init__(self, name, type, clazz, ttl, text):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   455
        DNSRecord.__init__(self, name, type, clazz, ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   456
        self.text = text
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   457
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   458
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   459
        """Used in constructing an outgoing packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   460
        out.writeString(self.text, len(self.text))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   461
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   462
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   463
        """Tests equality on text"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   464
        if isinstance(other, DNSText):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   465
            return self.text == other.text
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   466
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   467
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   468
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   469
        """String representation"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   470
        if len(self.text) > 10:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   471
            return self.toString(self.text[:7] + b"...")
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   472
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   473
            return self.toString(self.text)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   474
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   475
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   476
class DNSService(DNSRecord):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   477
    """A DNS service record"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   478
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   479
    def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   480
        DNSRecord.__init__(self, name, type, clazz, ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   481
        self.priority = priority
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   482
        self.weight = weight
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   483
        self.port = port
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   484
        self.server = server
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   485
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   486
    def write(self, out):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   487
        """Used in constructing an outgoing packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   488
        out.writeShort(self.priority)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   489
        out.writeShort(self.weight)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   490
        out.writeShort(self.port)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   491
        out.writeName(self.server)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   492
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   493
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   494
        """Tests equality on priority, weight, port and server"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   495
        if isinstance(other, DNSService):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   496
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   497
                self.priority == other.priority
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   498
                and self.weight == other.weight
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   499
                and self.port == other.port
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   500
                and self.server == other.server
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   501
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   502
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   503
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   504
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   505
        """String representation"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   506
        return self.toString(b"%s:%s" % (self.server, self.port))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   507
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   508
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   509
class DNSIncoming:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   510
    """Object representation of an incoming DNS packet"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   511
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   512
    def __init__(self, data):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   513
        """Constructor from string holding bytes of packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   514
        self.offset = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   515
        self.data = data
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   516
        self.questions = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   517
        self.answers = []
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   518
        self.numquestions = 0
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   519
        self.numanswers = 0
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   520
        self.numauthorities = 0
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   521
        self.numadditionals = 0
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   522
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   523
        self.readHeader()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   524
        self.readQuestions()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   525
        self.readOthers()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   526
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   527
    def readHeader(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   528
        """Reads header portion of packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   529
        format = b'!HHHHHH'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   530
        length = struct.calcsize(format)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   531
        info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   532
            format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   533
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   534
        self.offset += length
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   535
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   536
        self.id = info[0]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   537
        self.flags = info[1]
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   538
        self.numquestions = info[2]
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   539
        self.numanswers = info[3]
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   540
        self.numauthorities = info[4]
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   541
        self.numadditionals = info[5]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   542
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   543
    def readQuestions(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   544
        """Reads questions section of packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   545
        format = b'!HH'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   546
        length = struct.calcsize(format)
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
   547
        for i in range(0, self.numquestions):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   548
            name = self.readName()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   549
            info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   550
                format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   551
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   552
            self.offset += length
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   553
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   554
            try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   555
                question = DNSQuestion(name, info[0], info[1])
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   556
                self.questions.append(question)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   557
            except NonLocalNameException:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   558
                pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   559
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   560
    def readInt(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   561
        """Reads an integer from the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   562
        format = b'!I'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   563
        length = struct.calcsize(format)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   564
        info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   565
            format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   566
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   567
        self.offset += length
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   568
        return info[0]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   569
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   570
    def readCharacterString(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   571
        """Reads a character string from the packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   572
        length = ord(self.data[self.offset])
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   573
        self.offset += 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   574
        return self.readString(length)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   575
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   576
    def readString(self, len):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   577
        """Reads a string of a given length from the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   578
        format = b'!%ds' % len
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   579
        length = struct.calcsize(format)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   580
        info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   581
            format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   582
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   583
        self.offset += length
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   584
        return info[0]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   585
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   586
    def readUnsignedShort(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   587
        """Reads an unsigned short from the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   588
        format = b'!H'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   589
        length = struct.calcsize(format)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   590
        info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   591
            format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   592
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   593
        self.offset += length
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   594
        return info[0]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   595
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   596
    def readOthers(self):
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
   597
        """Reads answers, authorities and additionals section of the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   598
        format = b'!HHiH'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   599
        length = struct.calcsize(format)
28504
3c90090320ad zeroconf: remove leftover camelcase identifier
Martin von Zweigbergk <martinvonz@google.com>
parents: 28422
diff changeset
   600
        n = self.numanswers + self.numauthorities + self.numadditionals
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   601
        for i in range(0, n):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   602
            domain = self.readName()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   603
            info = struct.unpack(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   604
                format, self.data[self.offset : self.offset + length]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   605
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   606
            self.offset += length
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   607
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   608
            rec = None
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   609
            if info[0] == _TYPE_A:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   610
                rec = DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   611
                    domain, info[0], info[1], info[2], self.readString(4)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   612
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   613
            elif info[0] == _TYPE_CNAME or info[0] == _TYPE_PTR:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   614
                rec = DNSPointer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   615
                    domain, info[0], info[1], info[2], self.readName()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   616
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   617
            elif info[0] == _TYPE_TXT:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   618
                rec = DNSText(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   619
                    domain, info[0], info[1], info[2], self.readString(info[3])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   620
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   621
            elif info[0] == _TYPE_SRV:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   622
                rec = DNSService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   623
                    domain,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   624
                    info[0],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   625
                    info[1],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   626
                    info[2],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   627
                    self.readUnsignedShort(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   628
                    self.readUnsignedShort(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   629
                    self.readUnsignedShort(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   630
                    self.readName(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   631
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   632
            elif info[0] == _TYPE_HINFO:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   633
                rec = DNSHinfo(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   634
                    domain,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   635
                    info[0],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   636
                    info[1],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   637
                    info[2],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   638
                    self.readCharacterString(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   639
                    self.readCharacterString(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   640
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   641
            elif info[0] == _TYPE_AAAA:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   642
                rec = DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   643
                    domain, info[0], info[1], info[2], self.readString(16)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   644
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   645
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   646
                # Try to ignore types we don't know about
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   647
                # this may mean the rest of the name is
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   648
                # unable to be parsed, and may show errors
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   649
                # so this is left for debugging.  New types
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   650
                # encountered need to be parsed properly.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   651
                #
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   652
                # print "UNKNOWN TYPE = " + str(info[0])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   653
                # raise BadTypeInNameException
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   654
                self.offset += info[3]
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   655
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   656
            if rec is not None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   657
                self.answers.append(rec)
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   658
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   659
    def isQuery(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   660
        """Returns true if this is a query"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   661
        return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   662
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   663
    def isResponse(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   664
        """Returns true if this is a response"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   665
        return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_RESPONSE
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   666
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   667
    def readUTF(self, offset, len):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   668
        """Reads a UTF-8 string of a given length from the packet"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   669
        return self.data[offset : offset + len].decode('utf-8')
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   670
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   671
    def readName(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   672
        """Reads a domain name from the packet"""
42550
683aeef12830 py3: add r'' prefixes and do ('%d' % int) instead of str(int)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 41519
diff changeset
   673
        result = r''
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   674
        off = self.offset
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   675
        next = -1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   676
        first = off
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   677
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   678
        while True:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   679
            len = ord(self.data[off : off + 1])
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   680
            off += 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   681
            if len == 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   682
                break
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   683
            t = len & 0xC0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   684
            if t == 0x00:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
   685
                result = ''.join((result, self.readUTF(off, len) + '.'))
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   686
                off += len
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   687
            elif t == 0xC0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   688
                if next < 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   689
                    next = off + 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   690
                off = ((len & 0x3F) << 8) | ord(self.data[off : off + 1])
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   691
                if off >= first:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   692
                    raise BadDomainNameCircular(off)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   693
                first = off
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   694
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   695
                raise BadDomainName(off)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   696
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   697
        if next >= 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   698
            self.offset = next
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   699
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   700
            self.offset = off
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   701
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   702
        return result
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   703
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   704
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   705
class DNSOutgoing:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   706
    """Object representation of an outgoing packet"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   707
28302
e96a3ae025ed zeroconf: remove whitespace around = for named parameters
timeless <timeless@mozdev.org>
parents: 28301
diff changeset
   708
    def __init__(self, flags, multicast=1):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   709
        self.finished = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   710
        self.id = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   711
        self.multicast = multicast
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   712
        self.flags = flags
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   713
        self.names = {}
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   714
        self.data = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   715
        self.size = 12
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   716
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   717
        self.questions = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   718
        self.answers = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   719
        self.authorities = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   720
        self.additionals = []
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   721
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   722
    def addQuestion(self, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   723
        """Adds a question"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   724
        self.questions.append(record)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   725
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   726
    def addAnswer(self, inp, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   727
        """Adds an answer"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   728
        if not record.suppressedBy(inp):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   729
            self.addAnswerAtTime(record, 0)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   730
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   731
    def addAnswerAtTime(self, record, now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   732
        """Adds an answer if if does not expire by a certain time"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   733
        if record is not None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   734
            if now == 0 or not record.isExpired(now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   735
                self.answers.append((record, now))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   736
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   737
    def addAuthoritativeAnswer(self, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   738
        """Adds an authoritative answer"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   739
        self.authorities.append(record)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   740
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   741
    def addAdditionalAnswer(self, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   742
        """Adds an additional answer"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   743
        self.additionals.append(record)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   744
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   745
    def writeByte(self, value):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   746
        """Writes a single byte to the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   747
        format = b'!c'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   748
        self.data.append(struct.pack(format, chr(value)))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   749
        self.size += 1
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   750
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   751
    def insertShort(self, index, value):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   752
        """Inserts an unsigned short in a certain position in the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   753
        format = b'!H'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   754
        self.data.insert(index, struct.pack(format, value))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   755
        self.size += 2
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   756
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   757
    def writeShort(self, value):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   758
        """Writes an unsigned short to the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   759
        format = b'!H'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   760
        self.data.append(struct.pack(format, value))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   761
        self.size += 2
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   762
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   763
    def writeInt(self, value):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   764
        """Writes an unsigned integer to the packet"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   765
        format = b'!I'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   766
        self.data.append(struct.pack(format, int(value)))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   767
        self.size += 4
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   768
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   769
    def writeString(self, value, length):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   770
        """Writes a string to the packet"""
47864
ad2c37075f46 zeroconf: fix an issue concatenating bytes and str
Matt Harbison <matt_harbison@yahoo.com>
parents: 44956
diff changeset
   771
        format = '!' + str(length) + 's'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   772
        self.data.append(struct.pack(format, value))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   773
        self.size += length
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   774
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   775
    def writeUTF(self, s):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   776
        """Writes a UTF-8 string of a given length to the packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   777
        utfstr = s.encode('utf-8')
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   778
        length = len(utfstr)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   779
        if length > 64:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   780
            raise NamePartTooLongException
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   781
        self.writeByte(length)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   782
        self.writeString(utfstr, length)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   783
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   784
    def writeName(self, name):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   785
        """Writes a domain name to the packet"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   786
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   787
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   788
            # Find existing instance of this name in packet
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   789
            #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   790
            index = self.names[name]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   791
        except KeyError:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   792
            # No record of this name already, so write it
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   793
            # out as normal, recording the location of the name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   794
            # for future pointers to it.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   795
            #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   796
            self.names[name] = self.size
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   797
            parts = name.split(b'.')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   798
            if parts[-1] == b'':
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   799
                parts = parts[:-1]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   800
            for part in parts:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   801
                self.writeUTF(part)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   802
            self.writeByte(0)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   803
            return
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   804
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   805
        # An index was found, so write a pointer to it
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   806
        #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   807
        self.writeByte((index >> 8) | 0xC0)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   808
        self.writeByte(index)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   809
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   810
    def writeQuestion(self, question):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   811
        """Writes a question to the packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   812
        self.writeName(question.name)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   813
        self.writeShort(question.type)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   814
        self.writeShort(question.clazz)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   815
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   816
    def writeRecord(self, record, now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   817
        """Writes a record (answer, authoritative answer, additional) to
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   818
        the packet"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   819
        self.writeName(record.name)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   820
        self.writeShort(record.type)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   821
        if record.unique and self.multicast:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   822
            self.writeShort(record.clazz | _CLASS_UNIQUE)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   823
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   824
            self.writeShort(record.clazz)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   825
        if now == 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   826
            self.writeInt(record.ttl)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   827
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   828
            self.writeInt(record.getRemainingTTL(now))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   829
        index = len(self.data)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   830
        # Adjust size for the short we will write before this record
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   831
        #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   832
        self.size += 2
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   833
        record.write(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   834
        self.size -= 2
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   835
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   836
        length = len(b''.join(self.data[index:]))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   837
        self.insertShort(index, length)  # Here is the short we adjusted for
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   838
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   839
    def packet(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   840
        """Returns a string containing the packet's bytes
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   841
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   842
        No further parts should be added to the packet once this
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   843
        is done."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   844
        if not self.finished:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   845
            self.finished = 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   846
            for question in self.questions:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   847
                self.writeQuestion(question)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   848
            for answer, time_ in self.answers:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   849
                self.writeRecord(answer, time_)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   850
            for authority in self.authorities:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   851
                self.writeRecord(authority, 0)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   852
            for additional in self.additionals:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   853
                self.writeRecord(additional, 0)
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   854
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   855
            self.insertShort(0, len(self.additionals))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   856
            self.insertShort(0, len(self.authorities))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   857
            self.insertShort(0, len(self.answers))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   858
            self.insertShort(0, len(self.questions))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   859
            self.insertShort(0, self.flags)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   860
            if self.multicast:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   861
                self.insertShort(0, 0)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   862
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   863
                self.insertShort(0, self.id)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   864
        return b''.join(self.data)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   865
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   866
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   867
class DNSCache:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   868
    """A cache of DNS entries"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   869
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   870
    def __init__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   871
        self.cache = {}
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   872
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   873
    def add(self, entry):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   874
        """Adds an entry"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   875
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   876
            list = self.cache[entry.key]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   877
        except KeyError:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   878
            list = self.cache[entry.key] = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   879
        list.append(entry)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   880
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   881
    def remove(self, entry):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   882
        """Removes an entry"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   883
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   884
            list = self.cache[entry.key]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   885
            list.remove(entry)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   886
        except KeyError:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   887
            pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   888
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   889
    def get(self, entry):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   890
        """Gets an entry by key.  Will return None if there is no
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   891
        matching entry."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   892
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   893
            list = self.cache[entry.key]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   894
            return list[list.index(entry)]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   895
        except (KeyError, ValueError):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   896
            return None
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   897
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   898
    def getByDetails(self, name, type, clazz):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   899
        """Gets an entry by details.  Will return None if there is
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   900
        no matching entry."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   901
        entry = DNSEntry(name, type, clazz)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   902
        return self.get(entry)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   903
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   904
    def entriesWithName(self, name):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   905
        """Returns a list of entries whose key matches the name."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   906
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   907
            return self.cache[name]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   908
        except KeyError:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   909
            return []
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   910
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   911
    def entries(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   912
        """Returns a list of all entries"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   913
        try:
28422
e2c6092ad422 zeroconf: replace reduce+add with itertools.chain
timeless <timeless@mozdev.org>
parents: 28421
diff changeset
   914
            return list(itertools.chain.from_iterable(self.cache.values()))
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   915
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   916
            return []
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   917
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   918
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   919
class Engine(threading.Thread):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   920
    """An engine wraps read access to sockets, allowing objects that
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   921
    need to receive data from sockets to be called back when the
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   922
    sockets are ready.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   923
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   924
    A reader needs a handle_read() method, which is called when the socket
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   925
    it is interested in is ready for reading.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   926
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   927
    Writers are not implemented here, because we only send short
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   928
    packets.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   929
    """
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   930
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   931
    def __init__(self, zeroconf):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   932
        threading.Thread.__init__(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   933
        self.zeroconf = zeroconf
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   934
        self.readers = {}  # maps socket to reader
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   935
        self.timeout = 5
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   936
        self.condition = threading.Condition()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   937
        self.start()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   938
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   939
    def run(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   940
        while not globals()[b'_GLOBAL_DONE']:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   941
            rs = self.getReaders()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   942
            if len(rs) == 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   943
                # No sockets to manage, but we wait for the timeout
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   944
                # or addition of a socket
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   945
                #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   946
                self.condition.acquire()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   947
                self.condition.wait(self.timeout)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   948
                self.condition.release()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   949
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   950
                try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   951
                    rr, wr, er = select.select(rs, [], [], self.timeout)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   952
                    for sock in rr:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   953
                        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   954
                            self.readers[sock].handle_read()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   955
                        except Exception:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   956
                            if not globals()[b'_GLOBAL_DONE']:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   957
                                traceback.print_exc()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   958
                except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   959
                    pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   960
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   961
    def getReaders(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   962
        self.condition.acquire()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   963
        result = self.readers.keys()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   964
        self.condition.release()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   965
        return result
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   966
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   967
    def addReader(self, reader, socket):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   968
        self.condition.acquire()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   969
        self.readers[socket] = reader
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   970
        self.condition.notify()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   971
        self.condition.release()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   972
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   973
    def delReader(self, socket):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   974
        self.condition.acquire()
28301
fd8a4d2d6541 zeroconf: del is not a function
timeless <timeless@mozdev.org>
parents: 28300
diff changeset
   975
        del self.readers[socket]
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   976
        self.condition.notify()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   977
        self.condition.release()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   978
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   979
    def notify(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   980
        self.condition.acquire()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   981
        self.condition.notify()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   982
        self.condition.release()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   983
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
   984
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   985
class Listener:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   986
    """A Listener is used by this module to listen on the multicast
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   987
    group to which DNS messages are sent, allowing the implementation
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   988
    to cache information as it arrives.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   989
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   990
    It requires registration with an Engine object in order to have
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   991
    the read() method called when a socket is available for reading."""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   992
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   993
    def __init__(self, zeroconf):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   994
        self.zeroconf = zeroconf
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   995
        self.zeroconf.engine.addReader(self, self.zeroconf.socket)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   996
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
   997
    def handle_read(self):
34447
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
   998
        sock = self.zeroconf.socket
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
   999
        try:
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1000
            data, (addr, port) = sock.recvfrom(_MAX_MSG_ABSOLUTE)
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1001
        except socket.error as e:
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1002
            if e.errno == errno.EBADF:
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1003
                # some other thread may close the socket
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1004
                return
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1005
            else:
5385b76fd1fd zeroconf: do not crash if socket being read is closed by another thread
Jun Wu <quark@fb.com>
parents: 28504
diff changeset
  1006
                raise
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1007
        self.data = data
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1008
        msg = DNSIncoming(data)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1009
        if msg.isQuery():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1010
            # Always multicast responses
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1011
            #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1012
            if port == _MDNS_PORT:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1013
                self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1014
            # If it's not a multicast query, reply via unicast
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1015
            # and multicast
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1016
            #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1017
            elif port == _DNS_PORT:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1018
                self.zeroconf.handleQuery(msg, addr, port)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1019
                self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1020
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1021
            self.zeroconf.handleResponse(msg)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1022
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1023
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1024
class Reaper(threading.Thread):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1025
    """A Reaper is used by this module to remove cache entries that
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1026
    have expired."""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1027
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1028
    def __init__(self, zeroconf):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1029
        threading.Thread.__init__(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1030
        self.zeroconf = zeroconf
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1031
        self.start()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1032
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1033
    def run(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1034
        while True:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1035
            self.zeroconf.wait(10 * 1000)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1036
            if globals()[b'_GLOBAL_DONE']:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1037
                return
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1038
            now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1039
            for record in self.zeroconf.cache.entries():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1040
                if record.isExpired(now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1041
                    self.zeroconf.updateRecord(now, record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1042
                    self.zeroconf.cache.remove(record)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1043
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1044
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1045
class ServiceBrowser(threading.Thread):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1046
    """Used to browse for a service of a specific type.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1047
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1048
    The listener object will have its addService() and
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1049
    removeService() methods called when this browser
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1050
    discovers changes in the services availability."""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1051
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1052
    def __init__(self, zeroconf, type, listener):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1053
        """Creates a browser for a specific type"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1054
        threading.Thread.__init__(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1055
        self.zeroconf = zeroconf
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1056
        self.type = type
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1057
        self.listener = listener
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1058
        self.services = {}
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1059
        self.nexttime = currentTimeMillis()
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1060
        self.delay = _BROWSER_TIME
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1061
        self.list = []
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1062
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1063
        self.done = 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1064
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1065
        self.zeroconf.addListener(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1066
            self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1067
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1068
        self.start()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1069
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1070
    def updateRecord(self, zeroconf, now, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1071
        """Callback invoked by Zeroconf when new information arrives.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1072
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1073
        Updates information required by browser in the Zeroconf cache."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1074
        if record.type == _TYPE_PTR and record.name == self.type:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1075
            expired = record.isExpired(now)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1076
            try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1077
                oldrecord = self.services[record.alias.lower()]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1078
                if not expired:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1079
                    oldrecord.resetTTL(record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1080
                else:
28301
fd8a4d2d6541 zeroconf: del is not a function
timeless <timeless@mozdev.org>
parents: 28300
diff changeset
  1081
                    del self.services[record.alias.lower()]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1082
                    callback = lambda x: self.listener.removeService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1083
                        x, self.type, record.alias
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1084
                    )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1085
                    self.list.append(callback)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1086
                    return
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1087
            except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1088
                if not expired:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1089
                    self.services[record.alias.lower()] = record
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1090
                    callback = lambda x: self.listener.addService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1091
                        x, self.type, record.alias
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1092
                    )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1093
                    self.list.append(callback)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1094
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1095
            expires = record.getExpirationTime(75)
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1096
            if expires < self.nexttime:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1097
                self.nexttime = expires
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1098
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1099
    def cancel(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1100
        self.done = 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1101
        self.zeroconf.notifyAll()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1102
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1103
    def run(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1104
        while True:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1105
            event = None
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1106
            now = currentTimeMillis()
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1107
            if len(self.list) == 0 and self.nexttime > now:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1108
                self.zeroconf.wait(self.nexttime - now)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1109
            if globals()[b'_GLOBAL_DONE'] or self.done:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1110
                return
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1111
            now = currentTimeMillis()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1112
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1113
            if self.nexttime <= now:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1114
                out = DNSOutgoing(_FLAGS_QR_QUERY)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1115
                out.addQuestion(DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1116
                for record in self.services.values():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1117
                    if not record.isExpired(now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1118
                        out.addAnswerAtTime(record, now)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1119
                self.zeroconf.send(out)
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1120
                self.nexttime = now + self.delay
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1121
                self.delay = min(20 * 1000, self.delay * 2)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1122
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1123
            if len(self.list) > 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1124
                event = self.list.pop(0)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1125
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1126
            if event is not None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1127
                event(self.zeroconf)
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1128
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1129
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
  1130
class ServiceInfo:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1131
    """Service information"""
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1132
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1133
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1134
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1135
        type,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1136
        name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1137
        address=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1138
        port=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1139
        weight=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1140
        priority=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1141
        properties=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1142
        server=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1143
    ):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1144
        """Create a service description.
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1145
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1146
        type: fully qualified service type name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1147
        name: fully qualified service name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1148
        address: IP address as unsigned short, network byte order
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1149
        port: port that the service runs on
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1150
        weight: weight of the service
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1151
        priority: priority of the service
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1152
        properties: dictionary of properties (or a string holding the bytes for
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1153
                    the text field)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1154
        server: fully qualified name for service host (defaults to name)"""
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1155
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1156
        if not name.endswith(type):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1157
            raise BadTypeInNameException
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1158
        self.type = type
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1159
        self.name = name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1160
        self.address = address
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1161
        self.port = port
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1162
        self.weight = weight
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1163
        self.priority = priority
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1164
        if server:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1165
            self.server = server
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1166
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1167
            self.server = name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1168
        self.setProperties(properties)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1169
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1170
    def setProperties(self, properties):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1171
        """Sets properties and text of this info from a dictionary"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1172
        if isinstance(properties, dict):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1173
            self.properties = properties
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1174
            list = []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1175
            result = b''
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1176
            for key in properties:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1177
                value = properties[key]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1178
                if value is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1179
                    suffix = b''
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1180
                elif isinstance(value, str):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1181
                    suffix = value
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1182
                elif isinstance(value, int):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1183
                    if value:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1184
                        suffix = b'true'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1185
                    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1186
                        suffix = b'false'
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1187
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1188
                    suffix = b''
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1189
                list.append(b'='.join((key, suffix)))
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1190
            for item in list:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1191
                result = b''.join(
43677
0f82b29f7494 zeroconf: fix traceback under py3
Kim Alvefur <zash@zash.se>
parents: 43077
diff changeset
  1192
                    (
0f82b29f7494 zeroconf: fix traceback under py3
Kim Alvefur <zash@zash.se>
parents: 43077
diff changeset
  1193
                        result,
0f82b29f7494 zeroconf: fix traceback under py3
Kim Alvefur <zash@zash.se>
parents: 43077
diff changeset
  1194
                        struct.pack(b'!c', pycompat.bytechr(len(item))),
0f82b29f7494 zeroconf: fix traceback under py3
Kim Alvefur <zash@zash.se>
parents: 43077
diff changeset
  1195
                        item,
0f82b29f7494 zeroconf: fix traceback under py3
Kim Alvefur <zash@zash.se>
parents: 43077
diff changeset
  1196
                    )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1197
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1198
            self.text = result
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1199
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1200
            self.text = properties
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1201
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1202
    def setText(self, text):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1203
        """Sets properties and text given a text field"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1204
        self.text = text
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1205
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1206
            result = {}
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1207
            end = len(text)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1208
            index = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1209
            strs = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1210
            while index < end:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1211
                length = ord(text[index])
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1212
                index += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1213
                strs.append(text[index : index + length])
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1214
                index += length
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1215
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1216
            for s in strs:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1217
                eindex = s.find(b'=')
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1218
                if eindex == -1:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1219
                    # No equals sign at all
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1220
                    key = s
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1221
                    value = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1222
                else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1223
                    key = s[:eindex]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1224
                    value = s[eindex + 1 :]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1225
                    if value == b'true':
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1226
                        value = 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1227
                    elif value == b'false' or not value:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1228
                        value = 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1229
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1230
                # Only update non-existent properties
28420
d03b7800672c zeroconf: compare singleton using is
timeless <timeless@mozdev.org>
parents: 28419
diff changeset
  1231
                if key and result.get(key) is None:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1232
                    result[key] = value
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1233
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1234
            self.properties = result
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1235
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1236
            traceback.print_exc()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1237
            self.properties = None
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1238
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1239
    def getType(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1240
        """Type accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1241
        return self.type
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1242
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1243
    def getName(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1244
        """Name accessor"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1245
        if self.type is not None and self.name.endswith(b"." + self.type):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1246
            return self.name[: len(self.name) - len(self.type) - 1]
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1247
        return self.name
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1248
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1249
    def getAddress(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1250
        """Address accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1251
        return self.address
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1252
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1253
    def getPort(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1254
        """Port accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1255
        return self.port
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1256
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1257
    def getPriority(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1258
        """Priority accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1259
        return self.priority
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1260
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1261
    def getWeight(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1262
        """Weight accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1263
        return self.weight
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1264
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1265
    def getProperties(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1266
        """Properties accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1267
        return self.properties
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1268
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1269
    def getText(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1270
        """Text accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1271
        return self.text
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1272
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1273
    def getServer(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1274
        """Server accessor"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1275
        return self.server
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1276
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1277
    def updateRecord(self, zeroconf, now, record):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1278
        """Updates service information from a DNS record"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1279
        if record is not None and not record.isExpired(now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1280
            if record.type == _TYPE_A:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1281
                # if record.name == self.name:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1282
                if record.name == self.server:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1283
                    self.address = record.address
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1284
            elif record.type == _TYPE_SRV:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1285
                if record.name == self.name:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1286
                    self.server = record.server
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1287
                    self.port = record.port
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1288
                    self.weight = record.weight
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1289
                    self.priority = record.priority
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1290
                    # self.address = None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1291
                    self.updateRecord(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1292
                        zeroconf,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1293
                        now,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1294
                        zeroconf.cache.getByDetails(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1295
                            self.server, _TYPE_A, _CLASS_IN
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1296
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1297
                    )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1298
            elif record.type == _TYPE_TXT:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1299
                if record.name == self.name:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1300
                    self.setText(record.text)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1301
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1302
    def request(self, zeroconf, timeout):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1303
        """Returns true if the service could be discovered on the
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1304
        network, and updates this object with details discovered.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1305
        """
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1306
        now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1307
        delay = _LISTENER_TIME
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1308
        next = now + delay
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1309
        last = now + timeout
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1310
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1311
            zeroconf.addListener(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1312
                self, DNSQuestion(self.name, _TYPE_ANY, _CLASS_IN)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1313
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1314
            while (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1315
                self.server is None or self.address is None or self.text is None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1316
            ):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1317
                if last <= now:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1318
                    return 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1319
                if next <= now:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1320
                    out = DNSOutgoing(_FLAGS_QR_QUERY)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1321
                    out.addQuestion(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1322
                        DNSQuestion(self.name, _TYPE_SRV, _CLASS_IN)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1323
                    )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1324
                    out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1325
                        zeroconf.cache.getByDetails(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1326
                            self.name, _TYPE_SRV, _CLASS_IN
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1327
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1328
                        now,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1329
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1330
                    out.addQuestion(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1331
                        DNSQuestion(self.name, _TYPE_TXT, _CLASS_IN)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1332
                    )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1333
                    out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1334
                        zeroconf.cache.getByDetails(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1335
                            self.name, _TYPE_TXT, _CLASS_IN
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1336
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1337
                        now,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1338
                    )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1339
                    if self.server is not None:
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1340
                        out.addQuestion(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1341
                            DNSQuestion(self.server, _TYPE_A, _CLASS_IN)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1342
                        )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1343
                        out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1344
                            zeroconf.cache.getByDetails(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1345
                                self.server, _TYPE_A, _CLASS_IN
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1346
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1347
                            now,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1348
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1349
                    zeroconf.send(out)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1350
                    next = now + delay
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1351
                    delay = delay * 2
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1352
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1353
                zeroconf.wait(min(next, last) - now)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1354
                now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1355
            result = 1
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1356
        finally:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1357
            zeroconf.removeListener(self)
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1358
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1359
        return result
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1360
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1361
    def __eq__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1362
        """Tests equality of service name"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1363
        if isinstance(other, ServiceInfo):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1364
            return other.name == self.name
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1365
        return 0
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1366
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1367
    def __ne__(self, other):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1368
        """Non-equality test"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1369
        return not self.__eq__(other)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1370
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1371
    def __repr__(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1372
        """String representation"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1373
        result = b"service[%s,%s:%s," % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1374
            self.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1375
            socket.inet_ntoa(self.getAddress()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1376
            self.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1377
        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1378
        if self.text is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1379
            result += b"None"
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1380
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1381
            if len(self.text) < 20:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1382
                result += self.text
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1383
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1384
                result += self.text[:17] + b"..."
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1385
        result += b"]"
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1386
        return result
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1387
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1388
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
  1389
class Zeroconf:
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1390
    """Implementation of Zeroconf Multicast DNS Service Discovery
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1391
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1392
    Supports registration, unregistration, queries and browsing.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1393
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1394
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1395
    def __init__(self, bindaddress=None):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1396
        """Creates an instance of the Zeroconf class, establishing
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1397
        multicast communications, listening and reaping threads."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1398
        globals()[b'_GLOBAL_DONE'] = 0
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1399
        if bindaddress is None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1400
            self.intf = socket.gethostbyname(socket.gethostname())
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1401
        else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1402
            self.intf = bindaddress
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1403
        self.group = (b'', _MDNS_PORT)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1404
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1405
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1406
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1407
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1408
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1409
            # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1410
            # multicast UDP sockets (p 731, "TCP/IP Illustrated,
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1411
            # Volume 2"), but some BSD-derived systems require
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1412
            # SO_REUSEPORT to be specified explicitly.  Also, not all
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1413
            # versions of Python have SO_REUSEPORT available.  So
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1414
            # if you're on a BSD-based system, and haven't upgraded
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1415
            # to Python 2.3 yet, you may find this library doesn't
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1416
            # work as expected.
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1417
            #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1418
            pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1419
        self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, b"\xff")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1420
        self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, b"\x01")
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1421
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1422
            self.socket.bind(self.group)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1423
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1424
            # Some versions of linux raise an exception even though
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1425
            # SO_REUSEADDR and SO_REUSEPORT have been set, so ignore it
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1426
            pass
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1427
        self.socket.setsockopt(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1428
            socket.SOL_IP,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1429
            socket.IP_ADD_MEMBERSHIP,
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
  1430
            socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1431
        )
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1432
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1433
        self.listeners = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1434
        self.browsers = []
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1435
        self.services = {}
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1436
        self.servicetypes = {}
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1437
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1438
        self.cache = DNSCache()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1439
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1440
        self.condition = threading.Condition()
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1441
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1442
        self.engine = Engine(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1443
        self.listener = Listener(self)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1444
        self.reaper = Reaper(self)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1445
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1446
    def isLoopback(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1447
        return self.intf.startswith(b"127.0.0.1")
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1448
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1449
    def isLinklocal(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1450
        return self.intf.startswith(b"169.254.")
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1451
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1452
    def wait(self, timeout):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1453
        """Calling thread waits for a given number of milliseconds or
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1454
        until notified."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1455
        self.condition.acquire()
28300
15c5f50e7e13 zeroconf: add whitespace around operator
timeless <timeless@mozdev.org>
parents: 28299
diff changeset
  1456
        self.condition.wait(timeout / 1000)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1457
        self.condition.release()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1458
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1459
    def notifyAll(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1460
        """Notifies all waiting threads"""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1461
        self.condition.acquire()
49053
7d1daa1ef286 zeroconf: fix deprecation warning with python 3.10
Julien Cristau <jcristau@debian.org>
parents: 48946
diff changeset
  1462
        self.condition.notify_all()
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1463
        self.condition.release()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1464
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1465
    def getServiceInfo(self, type, name, timeout=3000):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1466
        """Returns network's service information for a particular
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1467
        name and type, or None if no service matches by the timeout,
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1468
        which defaults to 3 seconds."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1469
        info = ServiceInfo(type, name)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1470
        if info.request(self, timeout):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1471
            return info
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1472
        return None
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1473
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1474
    def addServiceListener(self, type, listener):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1475
        """Adds a listener for a particular service type.  This object
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1476
        will then have its updateRecord method called when information
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1477
        arrives for that type."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1478
        self.removeServiceListener(listener)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1479
        self.browsers.append(ServiceBrowser(self, type, listener))
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1480
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1481
    def removeServiceListener(self, listener):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1482
        """Removes a listener from the set that is currently listening."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1483
        for browser in self.browsers:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1484
            if browser.listener == listener:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1485
                browser.cancel()
28301
fd8a4d2d6541 zeroconf: del is not a function
timeless <timeless@mozdev.org>
parents: 28300
diff changeset
  1486
                del browser
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1487
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1488
    def registerService(self, info, ttl=_DNS_TTL):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1489
        """Registers service information to the network with a default TTL
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1490
        of 60 seconds.  Zeroconf will then respond to requests for
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1491
        information for that service.  The name of the service may be
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1492
        changed if needed to make it unique on the network."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1493
        self.checkService(info)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1494
        self.services[info.name.lower()] = info
28421
6d72cc613fc4 zeroconf: replace has_key with in
timeless <timeless@mozdev.org>
parents: 28420
diff changeset
  1495
        if info.type in self.servicetypes:
28300
15c5f50e7e13 zeroconf: add whitespace around operator
timeless <timeless@mozdev.org>
parents: 28299
diff changeset
  1496
            self.servicetypes[info.type] += 1
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1497
        else:
28300
15c5f50e7e13 zeroconf: add whitespace around operator
timeless <timeless@mozdev.org>
parents: 28299
diff changeset
  1498
            self.servicetypes[info.type] = 1
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1499
        now = currentTimeMillis()
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1500
        nexttime = now
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1501
        i = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1502
        while i < 3:
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1503
            if now < nexttime:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1504
                self.wait(nexttime - now)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1505
                now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1506
                continue
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1507
            out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1508
            out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1509
                DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, ttl, info.name), 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1510
            )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1511
            out.addAnswerAtTime(
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1512
                DNSService(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1513
                    info.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1514
                    _TYPE_SRV,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1515
                    _CLASS_IN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1516
                    ttl,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1517
                    info.priority,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1518
                    info.weight,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1519
                    info.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1520
                    info.server,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1521
                ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1522
                0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1523
            )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1524
            out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1525
                DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1526
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1527
            if info.address:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1528
                out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1529
                    DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1530
                        info.server, _TYPE_A, _CLASS_IN, ttl, info.address
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1531
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1532
                    0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1533
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1534
            self.send(out)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1535
            i += 1
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1536
            nexttime += _REGISTER_TIME
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1537
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1538
    def unregisterService(self, info):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1539
        """Unregister a service."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1540
        try:
28301
fd8a4d2d6541 zeroconf: del is not a function
timeless <timeless@mozdev.org>
parents: 28300
diff changeset
  1541
            del self.services[info.name.lower()]
28300
15c5f50e7e13 zeroconf: add whitespace around operator
timeless <timeless@mozdev.org>
parents: 28299
diff changeset
  1542
            if self.servicetypes[info.type] > 1:
15c5f50e7e13 zeroconf: add whitespace around operator
timeless <timeless@mozdev.org>
parents: 28299
diff changeset
  1543
                self.servicetypes[info.type] -= 1
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1544
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1545
                del self.servicetypes[info.type]
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1546
        except KeyError:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1547
            pass
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1548
        now = currentTimeMillis()
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1549
        nexttime = now
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1550
        i = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1551
        while i < 3:
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1552
            if now < nexttime:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1553
                self.wait(nexttime - now)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1554
                now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1555
                continue
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1556
            out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1557
            out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1558
                DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1559
            )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1560
            out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1561
                DNSService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1562
                    info.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1563
                    _TYPE_SRV,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1564
                    _CLASS_IN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1565
                    0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1566
                    info.priority,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1567
                    info.weight,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1568
                    info.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1569
                    info.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1570
                ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1571
                0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1572
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1573
            out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1574
                DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1575
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1576
            if info.address:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1577
                out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1578
                    DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1579
                        info.server, _TYPE_A, _CLASS_IN, 0, info.address
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1580
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1581
                    0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1582
                )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1583
            self.send(out)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1584
            i += 1
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1585
            nexttime += _UNREGISTER_TIME
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1586
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1587
    def unregisterAllServices(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1588
        """Unregister all registered services."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1589
        if len(self.services) > 0:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1590
            now = currentTimeMillis()
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1591
            nexttime = now
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1592
            i = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1593
            while i < 3:
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1594
                if now < nexttime:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1595
                    self.wait(nexttime - now)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1596
                    now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1597
                    continue
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1598
                out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1599
                for info in self.services.values():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1600
                    out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1601
                        DNSPointer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1602
                            info.type, _TYPE_PTR, _CLASS_IN, 0, info.name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1603
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1604
                        0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1605
                    )
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1606
                    out.addAnswerAtTime(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1607
                        DNSService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1608
                            info.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1609
                            _TYPE_SRV,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1610
                            _CLASS_IN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1611
                            0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1612
                            info.priority,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1613
                            info.weight,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1614
                            info.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1615
                            info.server,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1616
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1617
                        0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1618
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1619
                    out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1620
                        DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1621
                        0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1622
                    )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1623
                    if info.address:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1624
                        out.addAnswerAtTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1625
                            DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1626
                                info.server, _TYPE_A, _CLASS_IN, 0, info.address
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1627
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1628
                            0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1629
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1630
                self.send(out)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1631
                i += 1
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1632
                nexttime += _UNREGISTER_TIME
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1633
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1634
    def checkService(self, info):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1635
        """Checks the network for a unique service name, modifying the
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1636
        ServiceInfo passed in if it is not unique."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1637
        now = currentTimeMillis()
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1638
        nexttime = now
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1639
        i = 0
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1640
        while i < 3:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1641
            for record in self.cache.entriesWithName(info.type):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1642
                if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1643
                    record.type == _TYPE_PTR
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1644
                    and not record.isExpired(now)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1645
                    and record.alias == info.name
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1646
                ):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1647
                    if info.name.find(b'.') < 0:
44956
ba7eda4fcf8e zeroconf: fix non existant formatting in the vendored zeroconf module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43735
diff changeset
  1648
                        info.name = b"%s.[%s:%d].%s" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1649
                            info.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1650
                            info.address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1651
                            info.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1652
                            info.type,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1653
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1654
                        self.checkService(info)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1655
                        return
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1656
                    raise NonUniqueNameException
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1657
            if now < nexttime:
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1658
                self.wait(nexttime - now)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1659
                now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1660
                continue
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1661
            out = DNSOutgoing(_FLAGS_QR_QUERY | _FLAGS_AA)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1662
            self.debug = out
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1663
            out.addQuestion(DNSQuestion(info.type, _TYPE_PTR, _CLASS_IN))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1664
            out.addAuthoritativeAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1665
                DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, _DNS_TTL, info.name)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1666
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1667
            self.send(out)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1668
            i += 1
28419
eb9d0e828c30 zeroconf: remove camelcase in identifiers
timeless <timeless@mozdev.org>
parents: 28302
diff changeset
  1669
            nexttime += _CHECK_TIME
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1670
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1671
    def addListener(self, listener, question):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1672
        """Adds a listener for a given question.  The listener will have
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1673
        its updateRecord method called when information is available to
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1674
        answer the question."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1675
        now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1676
        self.listeners.append(listener)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1677
        if question is not None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1678
            for record in self.cache.entriesWithName(question.name):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1679
                if question.answeredBy(record) and not record.isExpired(now):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1680
                    listener.updateRecord(self, now, record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1681
        self.notifyAll()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1682
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1683
    def removeListener(self, listener):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1684
        """Removes a listener."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1685
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1686
            self.listeners.remove(listener)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1687
            self.notifyAll()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1688
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1689
            pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1690
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1691
    def updateRecord(self, now, rec):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1692
        """Used to notify listeners of new information that has updated
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1693
        a record."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1694
        for listener in self.listeners:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1695
            listener.updateRecord(self, now, rec)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1696
        self.notifyAll()
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1697
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1698
    def handleResponse(self, msg):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1699
        """Deal with incoming response packets.  All answers
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1700
        are held in the cache, and listeners are notified."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1701
        now = currentTimeMillis()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1702
        for record in msg.answers:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1703
            expired = record.isExpired(now)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1704
            if record in self.cache.entries():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1705
                if expired:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1706
                    self.cache.remove(record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1707
                else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1708
                    entry = self.cache.get(record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1709
                    if entry is not None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1710
                        entry.resetTTL(record)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1711
                        record = entry
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1712
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1713
                self.cache.add(record)
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1714
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1715
            self.updateRecord(now, record)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1716
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1717
    def handleQuery(self, msg, addr, port):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1718
        """Deal with incoming query packets.  Provides a response if
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1719
        possible."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1720
        out = None
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1721
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1722
        # Support unicast client responses
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1723
        #
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1724
        if port != _MDNS_PORT:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1725
            out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1726
            for question in msg.questions:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1727
                out.addQuestion(question)
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7071
diff changeset
  1728
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1729
        for question in msg.questions:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1730
            if question.type == _TYPE_PTR:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1731
                if question.name == b"_services._dns-sd._udp.local.":
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1732
                    for stype in self.servicetypes.keys():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1733
                        if out is None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1734
                            out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1735
                        out.addAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1736
                            msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1737
                            DNSPointer(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1738
                                b"_services._dns-sd._udp.local.",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1739
                                _TYPE_PTR,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1740
                                _CLASS_IN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1741
                                _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1742
                                stype,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1743
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1744
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1745
                for service in self.services.values():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1746
                    if question.name == service.type:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1747
                        if out is None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1748
                            out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1749
                        out.addAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1750
                            msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1751
                            DNSPointer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1752
                                service.type,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1753
                                _TYPE_PTR,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1754
                                _CLASS_IN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1755
                                _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1756
                                service.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1757
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1758
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1759
            else:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1760
                try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1761
                    if out is None:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1762
                        out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7071
diff changeset
  1763
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1764
                    # Answer A record queries for any service addresses we know
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1765
                    if question.type == _TYPE_A or question.type == _TYPE_ANY:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1766
                        for service in self.services.values():
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1767
                            if service.server == question.name.lower():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1768
                                out.addAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1769
                                    msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1770
                                    DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1771
                                        question.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1772
                                        _TYPE_A,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1773
                                        _CLASS_IN | _CLASS_UNIQUE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1774
                                        _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1775
                                        service.address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1776
                                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1777
                                )
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7071
diff changeset
  1778
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1779
                    service = self.services.get(question.name.lower(), None)
35629
31451f3f4b56 style: remove multiple statement on a single line in zeroconf
Boris Feld <boris.feld@octobus.net>
parents: 34447
diff changeset
  1780
                    if not service:
31451f3f4b56 style: remove multiple statement on a single line in zeroconf
Boris Feld <boris.feld@octobus.net>
parents: 34447
diff changeset
  1781
                        continue
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7071
diff changeset
  1782
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1783
                    if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1784
                        out.addAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1785
                            msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1786
                            DNSService(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1787
                                question.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1788
                                _TYPE_SRV,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1789
                                _CLASS_IN | _CLASS_UNIQUE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1790
                                _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1791
                                service.priority,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1792
                                service.weight,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1793
                                service.port,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1794
                                service.server,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1795
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1796
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1797
                    if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1798
                        out.addAnswer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1799
                            msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1800
                            DNSText(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1801
                                question.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1802
                                _TYPE_TXT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1803
                                _CLASS_IN | _CLASS_UNIQUE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1804
                                _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1805
                                service.text,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1806
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1807
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1808
                    if question.type == _TYPE_SRV:
28299
acea9dd8cf7e zeroconf: wrap long lines
timeless <timeless@mozdev.org>
parents: 28298
diff changeset
  1809
                        out.addAdditionalAnswer(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1810
                            DNSAddress(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1811
                                service.server,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1812
                                _TYPE_A,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1813
                                _CLASS_IN | _CLASS_UNIQUE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1814
                                _DNS_TTL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1815
                                service.address,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1816
                            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1817
                        )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1818
                except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1819
                    traceback.print_exc()
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7071
diff changeset
  1820
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1821
        if out is not None and out.answers:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1822
            out.id = msg.id
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1823
            self.send(out, addr, port)
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1824
28302
e96a3ae025ed zeroconf: remove whitespace around = for named parameters
timeless <timeless@mozdev.org>
parents: 28301
diff changeset
  1825
    def send(self, out, addr=_MDNS_ADDR, port=_MDNS_PORT):
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1826
        """Sends an outgoing packet."""
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1827
        # This is a quick test to see if we can parse the packets we generate
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1828
        # temp = DNSIncoming(out.packet())
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1829
        try:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1830
            self.socket.sendto(out.packet(), 0, (addr, port))
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1831
        except Exception:
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1832
            # Ignore this, it may be a temporary loss of network connection
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1833
            pass
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1834
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1835
    def close(self):
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1836
        """Ends the background threads, and prevent this instance from
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1837
        servicing further queries."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1838
        if globals()[b'_GLOBAL_DONE'] == 0:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1839
            globals()[b'_GLOBAL_DONE'] = 1
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1840
            self.notifyAll()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1841
            self.engine.notify()
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1842
            self.unregisterAllServices()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1843
            self.socket.setsockopt(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1844
                socket.SOL_IP,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1845
                socket.IP_DROP_MEMBERSHIP,
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43077
diff changeset
  1846
                socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1847
            )
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1848
            self.socket.close()
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1849
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1850
7071
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1851
# Test a few module features, including service registration, service
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1852
# query (for Zoe), and service unregistration.
643c751e60b2 zeroconf: initial implementation
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1853
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1854
if __name__ == '__main__':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1855
    print(b"Multicast DNS Service Discovery for Python, version", __version__)
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1856
    r = Zeroconf()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1857
    print(b"1. Testing registration of a service...")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1858
    desc = {b'version': b'0.10', b'a': b'test value', b'b': b'another value'}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1859
    info = ServiceInfo(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1860
        b"_http._tcp.local.",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1861
        b"My Service Name._http._tcp.local.",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1862
        socket.inet_aton(b"127.0.0.1"),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1863
        1234,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1864
        0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1865
        0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1866
        desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1867
    )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1868
    print(b"   Registering service...")
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1869
    r.registerService(info)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1870
    print(b"   Registration done.")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1871
    print(b"2. Testing query of service information...")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1872
    print(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1873
        b"   Getting ZOE service:",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1874
        str(r.getServiceInfo(b"_http._tcp.local.", b"ZOE._http._tcp.local.")),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1875
    )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1876
    print(b"   Query done.")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1877
    print(b"3. Testing query of own service...")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1878
    print(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1879
        b"   Getting self:",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1880
        str(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1881
            r.getServiceInfo(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1882
                b"_http._tcp.local.", b"My Service Name._http._tcp.local."
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1883
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1884
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42551
diff changeset
  1885
    )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1886
    print(b"   Query done.")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1887
    print(b"4. Testing unregister of service information...")
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1888
    r.unregisterService(info)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1889
    print(b"   Unregister done.")
28298
c318e8fd0e62 zeroconf: drop tabs
timeless <timeless@mozdev.org>
parents: 28297
diff changeset
  1890
    r.close()