1 # Copyright (C) Internet Systems Consortium, Inc. ("ISC") 2 # 3 # SPDX-License-Identifier: MPL-2.0 4 # 5 # This Source Code Form is subject to the terms of the Mozilla Public 6 # License, v. 2.0. If a copy of the MPL was not distributed with this 7 # file, you can obtain one at https://mozilla.org/MPL/2.0/. 8 # 9 # See the COPYRIGHT file distributed with this work for additional 10 # information regarding copyright ownership. 11 12 import socket 13 import ssl 14 15 from h2.config import H2Configuration 16 from h2.connection import H2Connection 17 from h2.settings import SettingCodes 18 19 import dns.message 20 21 22 def test_settings_frame_flood(ns1, named_httpsport): 23 msg = dns.message.make_query(".", "SOA") 24 wire = msg.to_wire() 25 26 with socket.create_connection((ns1.ip, named_httpsport), timeout=10) as sock: 27 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) 28 ctx.check_hostname = False 29 ctx.verify_mode = ssl.CERT_NONE 30 ctx.set_alpn_protocols(["h2"]) 31 32 with ctx.wrap_socket(sock, server_hostname=ns1.ip) as tls: 33 config = H2Configuration(client_side=True, header_encoding="utf-8") 34 conn = H2Connection(config=config) 35 conn.initiate_connection() 36 tls.sendall(conn.data_to_send()) 37 38 stream_id = conn.get_next_available_stream_id() 39 conn.send_headers( 40 stream_id, 41 [ 42 (":method", "POST"), 43 (":path", "/dns-query"), 44 (":scheme", "https"), 45 (":authority", f"{ns1.ip}:{named_httpsport}"), 46 ("content-type", "application/dns-message"), 47 ("accept", "application/dns-message"), 48 ("content-length", str(len(wire))), 49 ], 50 ) 51 conn.send_data(stream_id, wire, end_stream=True) 52 tls.sendall(conn.data_to_send()) 53 54 for i in range(4096): 55 try: 56 conn.update_settings( 57 { 58 SettingCodes.MAX_CONCURRENT_STREAMS: (i % 100) + 1, 59 SettingCodes.INITIAL_WINDOW_SIZE: i + 1, 60 } 61 ) 62 tls.sendall(conn.data_to_send()) 63 except Exception: # pylint: disable=broad-except 64 break 65 66 if i % 500 == 0: 67 tls.settimeout(0.05) 68 try: 69 while (data := tls.recv(65535)) != b"": 70 conn.receive_data(data) 71 tls.sendall(conn.data_to_send()) 72 except Exception: # pylint: disable=broad-except 73 pass 74