Browse Source

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)
tags/5.0.3
Jens Harbott 1 year ago
parent
commit
16297a3014
1 changed files with 10 additions and 4 deletions
  1. 10
    4
      designate/service.py

+ 10
- 4
designate/service.py View File

@@ -321,6 +321,9 @@ class DNSService(object):
321 321
 
322 322
                 LOG.debug("Handling TCP Request from: %(host)s:%(port)d" %
323 323
                           {'host': addr[0], 'port': addr[1]})
324
+                if len(addr) == 4:
325
+                    LOG.debug("Flow info: %(host)s scope: %(port)d" %
326
+                              {'host': addr[2], 'port': addr[3]})
324 327
 
325 328
                 # Dispatch a thread to handle the connection
326 329
                 self.tg.add_thread(self._dns_handle_tcp_conn, addr, client)
@@ -349,25 +352,28 @@ class DNSService(object):
349 352
     def _dns_handle_tcp_conn(self, addr, client):
350 353
         """
351 354
         Handle a DNS Query over TCP. Multiple queries can be pipelined
352
-        though the same TCP connection but they will be processed
355
+        through the same TCP connection but they will be processed
353 356
         sequentially.
354 357
         See https://tools.ietf.org/html/draft-ietf-dnsop-5966bis-03
355 358
         Raises no exception: it's to be run in an eventlet green thread
356 359
 
357
-        :param addr: Tuple of the client's (IP addr, Port)
360
+        :param addr: Tuple of the client's (IPv4 addr, Port) or
361
+                     (IPv6 addr, Port, Flow info, Scope ID)
358 362
         :type addr: tuple
359 363
         :param client: Client socket
360 364
         :type client: socket
361 365
         :raises: None
362 366
         """
363
-        host, port = addr
367
+        host, port = addr[:2]
364 368
         try:
365 369
             # The whole loop lives in a try/except block. On exceptions, the
366
-            # connection is closed: there would be little chance to save save
370
+            # connection is closed: there would be little chance to save
367 371
             # the connection after a struct error, a socket error.
368 372
             while True:
369 373
                 # Decode the first 2 bytes containing the query length
370 374
                 expected_length_raw = client.recv(2)
375
+                if len(expected_length_raw) == 0:
376
+                    break
371 377
                 (expected_length, ) = struct.unpack('!H', expected_length_raw)
372 378
 
373 379
                 # Keep receiving data until we've got all the data we expect

Loading…
Cancel
Save