Fix servicing IPv6 based TCP connections
When a connection is received via IPv6, the address is a 4-tuple instead of a 2-tuple for IPv4, so handle this accordingly. Also handle the end of the TCP connection gracefully instead of emitting an "Invalid packet" warning every time. [1] https://docs.python.org/2/library/socket.html Change-Id: I935bbea1d58af8a5b41b5d29f12de4dcb7cf6301 Closes-Bug: 1734101
This commit is contained in:
parent
64c2609395
commit
5e45b15419
|
@ -321,6 +321,9 @@ class DNSService(object):
|
|||
|
||||
LOG.debug("Handling TCP Request from: %(host)s:%(port)d" %
|
||||
{'host': addr[0], 'port': addr[1]})
|
||||
if len(addr) == 4:
|
||||
LOG.debug("Flow info: %(host)s scope: %(port)d" %
|
||||
{'host': addr[2], 'port': addr[3]})
|
||||
|
||||
# Dispatch a thread to handle the connection
|
||||
self.tg.add_thread(self._dns_handle_tcp_conn, addr, client)
|
||||
|
@ -349,25 +352,28 @@ class DNSService(object):
|
|||
def _dns_handle_tcp_conn(self, addr, client):
|
||||
"""
|
||||
Handle a DNS Query over TCP. Multiple queries can be pipelined
|
||||
though the same TCP connection but they will be processed
|
||||
through the same TCP connection but they will be processed
|
||||
sequentially.
|
||||
See https://tools.ietf.org/html/draft-ietf-dnsop-5966bis-03
|
||||
Raises no exception: it's to be run in an eventlet green thread
|
||||
|
||||
:param addr: Tuple of the client's (IP addr, Port)
|
||||
:param addr: Tuple of the client's (IPv4 addr, Port) or
|
||||
(IPv6 addr, Port, Flow info, Scope ID)
|
||||
:type addr: tuple
|
||||
:param client: Client socket
|
||||
:type client: socket
|
||||
:raises: None
|
||||
"""
|
||||
host, port = addr
|
||||
host, port = addr[:2]
|
||||
try:
|
||||
# The whole loop lives in a try/except block. On exceptions, the
|
||||
# connection is closed: there would be little chance to save save
|
||||
# connection is closed: there would be little chance to save
|
||||
# the connection after a struct error, a socket error.
|
||||
while True:
|
||||
# Decode the first 2 bytes containing the query length
|
||||
expected_length_raw = client.recv(2)
|
||||
if len(expected_length_raw) == 0:
|
||||
break
|
||||
(expected_length, ) = struct.unpack('!H', expected_length_raw)
|
||||
|
||||
# Keep receiving data until we've got all the data we expect
|
||||
|
|
Loading…
Reference in New Issue