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