def test_close(kresd_sock, query_before): """Establish a connection and wait for timeout from kresd.""" if query_before: utils.ping_alive(kresd_sock) time.sleep(utils.MAX_TIMEOUT) with utils.expect_kresd_close(): utils.ping_alive(kresd_sock)
def test_prefix_cuts_message(kresd_sock, datalen, send_query): """Prefix is shorter than the DNS message.""" wire, _ = utils.prepare_wire() assert datalen < len(wire) invalid_buff = utils.prepare_buffer(wire, datalen) send_query(kresd_sock, invalid_buff) # buffer breaks parsing of TCP stream with utils.expect_kresd_close(): utils.ping_alive(kresd_sock)
def test_slow_lorris(kresd_sock, query_before): """Simulate slow-lorris attack by sending byte after byte with delays in between.""" if query_before: utils.ping_alive(kresd_sock) buff, _ = utils.get_msgbuff() end_time = time.time() + utils.MAX_TIMEOUT with utils.expect_kresd_close(): for i in range(len(buff)): b = buff[i:i+1] kresd_sock.send(b) if time.time() > end_time: break time.sleep(1)
def test_query_flood_garbage(make_kresd_sock, glength, gcount, delay, query_before): """Flood resolver with prefixed garbage.""" sock1 = make_kresd_sock() if query_before: utils.ping_alive(sock1) gbuff = utils.get_prefixed_garbage(glength) buff = gbuff * gcount end_time = time.time() + utils.MAX_TIMEOUT with utils.expect_kresd_close(rst_ok=True): # connection must be closed while time.time() < end_time: sock1.sendall(buff) time.sleep(delay) sock2 = make_kresd_sock() utils.ping_alive(sock2) # resolver must stay alive
def test_prefix_greater_than_message(kresd_sock, send_query): """Prefix is greater than the length of the entire DNS message.""" wire, invalid_msgid = utils.prepare_wire() datalen = len(wire) + 16 invalid_buff = utils.prepare_buffer(wire, datalen) send_query(kresd_sock, invalid_buff) valid_buff, _ = utils.get_msgbuff() kresd_sock.sendall(valid_buff) # invalid_buff is answered (treats additional data as trailing garbage) answer = utils.receive_parse_answer(kresd_sock) assert answer.id == invalid_msgid # parsing stream is broken by the invalid_buff, valid query is never answered with utils.expect_kresd_close(): utils.receive_parse_answer(kresd_sock)
def test_query_flood_no_recv(make_kresd_sock): """Flood resolver with queries but don't read any data.""" # A use-case for TCP_USER_TIMEOUT socket option? See RFC 793 and RFC 5482 # It seems it doesn't works as expected. libuv doesn't return any error # (neither on uv_write() call, not in the callback) when kresd sends answers, # so kresd can't recognize that client didn't read any answers. At a certain # point, kresd stops receiving queries from the client (whilst client keep # sending) and closes connection due to timeout. buff = flood_buffer(10000) sock1 = make_kresd_sock() end_time = time.time() + utils.MAX_TIMEOUT with utils.expect_kresd_close(rst_ok=True): # connection must be closed while time.time() < end_time: sock1.sendall(buff) time.sleep(0.5) sock2 = make_kresd_sock() utils.ping_alive(sock2) # resolver must stay alive