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
(cherry picked from commit 5e45b15419
)
This commit is contained in:
parent
7c2a3be3e4
commit
16297a3014
|
@ -321,6 +321,9 @@ class DNSService(object):
|
||||||
|
|
||||||
LOG.debug("Handling TCP Request from: %(host)s:%(port)d" %
|
LOG.debug("Handling TCP Request from: %(host)s:%(port)d" %
|
||||||
{'host': addr[0], 'port': addr[1]})
|
{'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
|
# Dispatch a thread to handle the connection
|
||||||
self.tg.add_thread(self._dns_handle_tcp_conn, addr, client)
|
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):
|
def _dns_handle_tcp_conn(self, addr, client):
|
||||||
"""
|
"""
|
||||||
Handle a DNS Query over TCP. Multiple queries can be pipelined
|
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.
|
sequentially.
|
||||||
See https://tools.ietf.org/html/draft-ietf-dnsop-5966bis-03
|
See https://tools.ietf.org/html/draft-ietf-dnsop-5966bis-03
|
||||||
Raises no exception: it's to be run in an eventlet green thread
|
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
|
:type addr: tuple
|
||||||
:param client: Client socket
|
:param client: Client socket
|
||||||
:type client: socket
|
:type client: socket
|
||||||
:raises: None
|
:raises: None
|
||||||
"""
|
"""
|
||||||
host, port = addr
|
host, port = addr[:2]
|
||||||
try:
|
try:
|
||||||
# The whole loop lives in a try/except block. On exceptions, the
|
# 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.
|
# the connection after a struct error, a socket error.
|
||||||
while True:
|
while True:
|
||||||
# Decode the first 2 bytes containing the query length
|
# Decode the first 2 bytes containing the query length
|
||||||
expected_length_raw = client.recv(2)
|
expected_length_raw = client.recv(2)
|
||||||
|
if len(expected_length_raw) == 0:
|
||||||
|
break
|
||||||
(expected_length, ) = struct.unpack('!H', expected_length_raw)
|
(expected_length, ) = struct.unpack('!H', expected_length_raw)
|
||||||
|
|
||||||
# Keep receiving data until we've got all the data we expect
|
# Keep receiving data until we've got all the data we expect
|
||||||
|
|
Loading…
Reference in New Issue