2
2
3
3
"""
4
4
ID: issue-5508
5
- ISSUE: 5508
5
+ ISSUE: https://github.com/FirebirdSQL/firebird/issues/ 5508
6
6
TITLE: Allow to enforce IPv4 or IPv6 in URL-like connection strings
7
7
DESCRIPTION:
8
- NOTES:
9
- [04.02.2022] pcisar
10
- Test may fail with IPv6.
11
- For example it fails on my Linux OpenSuSE Tumbleweed with regular setup (IPv6 should not be disabled).
12
- Test should IMHO check IPv4/IPv6 availability on test host before runs inet6:// check.
13
8
JIRA: CORE-5229
14
9
FBTEST: bugs.core_5229
15
- """
10
+ NOTES:
11
+ [04.02.2022] pcisar
12
+ Test may fail with IPv6.
13
+ For example it fails on my Linux OpenSuSE Tumbleweed with regular setup (IPv6 should not be disabled).
14
+ Test should IMHO check IPv4/IPv6 availability on test host before runs inet6:// check.
15
+ [13.06.2024] pzotov
16
+ 1. Added check for ability to use IPv6.
17
+ 2. Attempt to specify explicitly IPv6 address "[::1]" in ES/EDS causes error:
18
+ ========
19
+ Statement failed, SQLSTATE = 42000
20
+ External Data Source provider 'inet6://[' not found
21
+ ========
22
+ Sent report to Vlad et al, waiting for fix.
23
+ Currently no concrete address is specified in ES/EDS.
16
24
25
+ Checked on 3.0.12.33744, 4.0.5.3103, 5.0.1.1411, 6.0.0.368
26
+ """
17
27
import pytest
18
28
from firebird .qa import *
19
29
20
30
db = db_factory ()
21
31
22
32
act = python_act ('db' )
23
33
24
- expected_stdout = """
25
- PROCOTOL_WHEN_CONNECT_FROM_OS TCPv4
26
- PROCOTOL_WHEN_CONNECT_FROM_ISQL TCPv4
27
- PROTOCOL_WHEN_CONNECT_BY_ES_EDS TCPv4
28
- PROCOTOL_WHEN_CONNECT_FROM_ISQL TCPv6
29
- PROTOCOL_WHEN_CONNECT_BY_ES_EDS TCPv6
30
- """
34
+ #------------------------------------------
35
+ # https://stackoverflow.com/questions/66246308/detect-if-ipv6-is-supported-os-agnostic-no-external-program/66249915#66249915
36
+ # https://stackoverflow.com/a/66249915
37
+
38
+ def check_ipv6_avail ():
39
+ import socket
40
+ import errno
41
+
42
+ # On Windows, the E* constants will use the WSAE* values
43
+ # So no need to hardcode an opaque integer in the sets.
44
+ _ADDR_NOT_AVAIL = {errno .EADDRNOTAVAIL , errno .EAFNOSUPPORT }
45
+ _ADDR_IN_USE = {errno .EADDRINUSE }
46
+
47
+ res = - 1
48
+ if not socket .has_ipv6 :
49
+ # If the socket library has no support for IPv6, then the
50
+ # question is moot as we can't use IPv6 anyways.
51
+ return res
52
+
53
+ sock = None
54
+ try :
55
+ #with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as sock:
56
+ # sock.bind(("::1", 0))
57
+ sock = socket .socket (socket .AF_INET6 , socket .SOCK_STREAM )
58
+ sock .bind (("::1" , 0 ))
59
+ #sock.shutdown(socket.SHUT_RDWR) # [Errno 107] Transport endpoint is not connected
60
+ sock .close ()
61
+ res = 0
62
+ except socket .error as x :
63
+ # sysctl net.ipv6.conf.all.disable_ipv6=1
64
+ # sysctl net.ipv6.conf.default.disable_ipv6=1
65
+ # sock.bind(("::1", 0)) --> socket.error: [Errno 99] Cannot assign requested address
66
+ #print(x)
67
+ res = - 2
68
+ except OSError as e :
69
+ if e .errno in _ADDR_NOT_AVAIL :
70
+ res = - 3
71
+ elif e .errno in _ADDR_IN_USE :
72
+ # This point shouldn't ever be reached. But just in case...
73
+ res = - 4
74
+ else :
75
+ # Other errors should be inspected
76
+ res = - 5
77
+
78
+ return res
79
+ #------------------------------------------
31
80
32
- @pytest .mark .skip ("FIXME: see notes" )
33
81
@pytest .mark .es_eds
34
82
@pytest .mark .version ('>=3.0.1' )
35
83
def test_1 (act : Action ):
84
+
85
+ if (res := check_ipv6_avail ()) < 0 :
86
+ pytest .skip (f"IPv6 not avail, retcode: { res } " )
87
+
36
88
sql_chk = f"""
37
89
set list on;
38
- select mon$remote_protocol as procotol_when_connect_from_os
39
- from mon$attachments where mon$attachment_id = current_connection;
40
-
41
90
commit;
42
- connect 'inet4://{ act .db .db_path } ';
91
+ connect 'inet4://127.0.0.1/ { act .db .db_path } ';
43
92
44
93
select mon$remote_protocol as procotol_when_connect_from_isql
45
94
from mon$attachments where mon$attachment_id = current_connection;
@@ -50,7 +99,7 @@ def test_1(act: Action):
50
99
begin
51
100
for
52
101
execute statement (stt)
53
- on external 'inet4://{ act .db .db_path } '
102
+ on external 'inet4://127.0.0.1/ { act .db .db_path } '
54
103
as user '{ act .db .user } ' password '{ act .db .password } '
55
104
into protocol_when_connect_by_es_eds
56
105
do
@@ -61,6 +110,8 @@ def test_1(act: Action):
61
110
commit;
62
111
63
112
-- since 27.10.2019:
113
+ -- inet6://[::1]/employee
114
+ -- connect 'inet6://[::1]/{ act .db .db_path } ';
64
115
connect 'inet6://{ act .db .db_path } ';
65
116
66
117
select mon$remote_protocol as procotol_when_connect_from_isql
@@ -72,6 +123,7 @@ def test_1(act: Action):
72
123
begin
73
124
for
74
125
execute statement (stt)
126
+ --on external 'inet6://[::1]/{ act .db .db_path } ' -- currently fails with
75
127
on external 'inet6://{ act .db .db_path } '
76
128
as user '{ act .db .user } ' password '{ act .db .password } '
77
129
into protocol_when_connect_by_es_eds
@@ -81,23 +133,16 @@ def test_1(act: Action):
81
133
^
82
134
set term ;^
83
135
commit;
136
+ """
137
+
138
+ expected_stdout = """
139
+ PROCOTOL_WHEN_CONNECT_FROM_ISQL TCPv4
140
+ PROTOCOL_WHEN_CONNECT_BY_ES_EDS TCPv4
141
+ PROCOTOL_WHEN_CONNECT_FROM_ISQL TCPv6
142
+ PROTOCOL_WHEN_CONNECT_BY_ES_EDS TCPv6
143
+ """
84
144
85
- -- ||||||||||||||||||||||||||||
86
- -- ###################################||| FB 4.0+, SS and SC |||##############################
87
- -- ||||||||||||||||||||||||||||
88
- -- If we check SS or SC and ExtConnPoolLifeTime > 0 (config parameter FB 4.0+) then current
89
- -- DB (bugs.core_NNNN.fdb) will be 'captured' by firebird.exe process and fbt_run utility
90
- -- will not able to drop this database at the final point of test.
91
- -- Moreover, DB file will be hold until all activity in firebird.exe completed and AFTER this
92
- -- we have to wait for <ExtConnPoolLifeTime> seconds after it (discussion and small test see
93
- -- in the letter to hvlad and dimitr 13.10.2019 11:10).
94
- -- This means that one need to kill all connections to prevent from exception on cleanup phase:
95
- -- SQLCODE: -901 / lock time-out on wait transaction / object <this_test_DB> is in use
96
- -- #############################################################################################
97
- delete from mon$attachments where mon$attachment_id != current_connection;
98
- commit;
99
- """
100
145
act .expected_stdout = expected_stdout
101
- act .isql (switches = ['-q' , f'inet4 ://{ act .db .db_path } ' ], input = sql_chk , connect_db = False )
146
+ act .isql (switches = ['-q' , f'inet ://{ act .db .db_path } ' ], input = sql_chk , connect_db = False )
102
147
assert act .clean_stdout == act .clean_expected_stdout
103
148
0 commit comments