Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
96ecf3ff
Commit
96ecf3ff
authored
Mar 21, 2018
by
Vladislav Vaintroub
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-15501 : Make `proxy_protocol_networks` variable read-write.
parent
865cec92
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
151 additions
and
29 deletions
+151
-29
sql/mysqld.cc
sql/mysqld.cc
+2
-2
sql/proxy_protocol.cc
sql/proxy_protocol.cc
+113
-24
sql/proxy_protocol.h
sql/proxy_protocol.h
+5
-1
sql/sys_vars.cc
sql/sys_vars.cc
+19
-2
tests/mysql_client_test.c
tests/mysql_client_test.c
+12
-0
No files found.
sql/mysqld.cc
View file @
96ecf3ff
...
...
@@ -2322,7 +2322,7 @@ void clean_up(bool print_message)
my_free
(
const_cast
<
char
*>
(
relay_log_index
));
#endif
free_list
(
opt_plugin_load_list_ptr
);
cleanup
_proxy_protocol_networks
();
destroy
_proxy_protocol_networks
();
/*
The following lines may never be executed as the main thread may have
...
...
@@ -2718,7 +2718,7 @@ static void network_init(void)
if
(
MYSQL_CALLBACK_ELSE
(
thread_scheduler
,
init
,
(),
0
))
unireg_abort
(
1
);
/* purecov: inspected */
if
(
se
t_proxy_protocol_networks
(
my_proxy_protocol_networks
))
if
(
ini
t_proxy_protocol_networks
(
my_proxy_protocol_networks
))
unireg_abort
(
1
);
set_ports
();
...
...
sql/proxy_protocol.cc
View file @
96ecf3ff
...
...
@@ -23,11 +23,14 @@
#include <violite.h>
#include <proxy_protocol.h>
#include <log.h>
#include <my_pthread.h>
#define PROXY_PROTOCOL_V1_SIGNATURE "PROXY"
#define PROXY_PROTOCOL_V2_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
#define MAX_PROXY_HEADER_LEN 256
static
mysql_rwlock_t
lock
;
/*
Parse proxy protocol version 1 header (text)
*/
...
...
@@ -341,31 +344,41 @@ static int parse_subnet(char *addr_str, struct subnet *subnet)
@param[in] subnets_str : networks in CIDR format,
separated by comma and/or space
@param[out] out_subnets : parsed subnets;
@param[out] out_count : number of parsed subnets
@return 0 if success, otherwise -1
*/
int
set_proxy_protocol_networks
(
const
char
*
subnets_str
)
static
int
parse_networks
(
const
char
*
subnets_str
,
subnet
**
out_subnets
,
size_t
*
out_count
)
{
int
ret
=
-
1
;
subnet
*
subnets
=
0
;
size_t
count
=
0
;
const
char
*
p
=
subnets_str
;
size_t
max_subnets
;
if
(
!
subnets_str
||
!*
subnets_str
)
return
0
;
{
ret
=
0
;
goto
end
;
}
size_t
max_subnets
=
MY_MAX
(
3
,
strlen
(
subnets_str
)
/
2
);
proxy_protocol_
subnets
=
(
subnet
*
)
my_malloc
(
max_subnets
*
sizeof
(
subnet
),
MY_ZEROFILL
);
max_subnets
=
MY_MAX
(
3
,
strlen
(
subnets_str
)
/
2
);
subnets
=
(
subnet
*
)
my_malloc
(
max_subnets
*
sizeof
(
subnet
),
MY_ZEROFILL
);
/* Check for special case '*'. */
if
(
strcmp
(
subnets_str
,
"*"
)
==
0
)
{
proxy_protocol_subnets
[
0
].
family
=
AF_INET
;
proxy_protocol_subnets
[
1
].
family
=
AF_INET6
;
proxy_protocol_subnets
[
2
].
family
=
AF_UNIX
;
proxy_protocol_subnet_count
=
3
;
return
0
;
subnets
[
0
].
family
=
AF_INET
;
subnets
[
1
].
family
=
AF_INET6
;
subnets
[
2
].
family
=
AF_UNIX
;
count
=
3
;
ret
=
0
;
goto
end
;
}
char
token
[
256
];
const
char
*
p
=
subnets_str
;
for
(
proxy_protocol_subnet_count
=
0
;;
proxy_protocol_subnet_count
++
)
for
(
count
=
0
;;
count
++
)
{
while
(
*
p
&&
(
*
p
==
','
||
*
p
==
' '
))
p
++
;
...
...
@@ -378,17 +391,74 @@ int set_proxy_protocol_networks(const char *subnets_str)
token
[
cnt
++
]
=
0
;
if
(
cnt
==
sizeof
(
token
))
return
-
1
;
goto
end
;
if
(
parse_subnet
(
token
,
&
proxy_protocol_subnets
[
proxy_protocol_subnet_
count
]))
if
(
parse_subnet
(
token
,
&
subnets
[
count
]))
{
sql_print_error
(
"Error parsing proxy_protocol_networks parameter, near '%s'"
,
token
);
return
-
1
;
my_printf_error
(
ER_PARSE_ERROR
,
"Error parsing proxy_protocol_networks parameter, near '%s'"
,
MYF
(
0
)
,
token
);
goto
end
;
}
}
ret
=
0
;
end:
if
(
ret
)
{
my_free
(
subnets
);
*
out_subnets
=
NULL
;
*
out_count
=
0
;
return
ret
;
}
*
out_subnets
=
subnets
;
*
out_count
=
count
;
return
0
;
}
/**
Check validity of proxy_protocol_networks parameter
@param[in] in - input string
@return : true, if input is list of CIDR-style networks
separated by command or space
*/
bool
proxy_protocol_networks_valid
(
const
char
*
in
)
{
subnet
*
new_subnets
;
size_t
new_count
;
int
ret
=
parse_networks
(
in
,
&
new_subnets
,
&
new_count
);
my_free
(
new_subnets
);
return
!
ret
;
}
/**
Set 'proxy_protocol_networks' parameter.
@param[in] spec : networks in CIDR format,
separated by comma and/or space
@return 0 if success, otherwise -1
*/
int
set_proxy_protocol_networks
(
const
char
*
spec
)
{
subnet
*
new_subnets
;
subnet
*
old_subnet
=
0
;
size_t
new_count
;
int
ret
=
parse_networks
(
spec
,
&
new_subnets
,
&
new_count
);
if
(
ret
)
return
ret
;
mysql_rwlock_wrlock
(
&
lock
);
old_subnet
=
proxy_protocol_subnets
;
proxy_protocol_subnets
=
new_subnets
;
proxy_protocol_subnet_count
=
new_count
;
mysql_rwlock_unlock
(
&
lock
);
my_free
(
old_subnet
);
return
ret
;
}
/**
Compare memory areas, in memcmp().similar fashion.
The difference to memcmp() is that size parameter is the
...
...
@@ -477,18 +547,37 @@ bool is_proxy_protocol_allowed(const sockaddr *addr)
DBUG_ASSERT
(
0
);
}
bool
ret
=
false
;
mysql_rwlock_rdlock
(
&
lock
);
for
(
size_t
i
=
0
;
i
<
proxy_protocol_subnet_count
;
i
++
)
{
if
(
addr_matches_subnet
(
normalized_addr
,
&
proxy_protocol_subnets
[
i
]))
return
true
;
{
ret
=
true
;
break
;
}
}
mysql_rwlock_unlock
(
&
lock
);
return
false
;
return
ret
;
}
void
cleanup_proxy_protocol_networks
(
)
int
init_proxy_protocol_networks
(
const
char
*
spec
)
{
my_free
(
proxy_protocol_subnets
);
proxy_protocol_subnets
=
0
;
proxy_protocol_subnet_count
=
0
;
#ifdef HAVE_PSI_INTERFACE
static
PSI_rwlock_key
psi_rwlock_key
;
static
PSI_rwlock_info
psi_rwlock_info
=
{
&
psi_rwlock_key
,
"rwlock"
,
0
};
mysql_rwlock_register
(
"proxy_protocol"
,
&
psi_rwlock_info
,
1
);
#endif
mysql_rwlock_init
(
psi_rwlock_key
,
&
lock
);
return
set_proxy_protocol_networks
(
spec
);
}
void
destroy_proxy_protocol_networks
()
{
my_free
(
proxy_protocol_subnets
);
mysql_rwlock_destroy
(
&
lock
);
}
sql/proxy_protocol.h
View file @
96ecf3ff
...
...
@@ -11,5 +11,9 @@ extern bool has_proxy_protocol_header(NET *net);
extern
int
parse_proxy_protocol_header
(
NET
*
net
,
proxy_peer_info
*
peer_info
);
extern
bool
is_proxy_protocol_allowed
(
const
sockaddr
*
remote_addr
);
extern
int
init_proxy_protocol_networks
(
const
char
*
spec
);
extern
void
destroy_proxy_protocol_networks
();
extern
int
set_proxy_protocol_networks
(
const
char
*
spec
);
extern
void
cleanup_proxy_protocol_networks
();
extern
bool
proxy_protocol_networks_valid
(
const
char
*
spec
);
sql/sys_vars.cc
View file @
96ecf3ff
...
...
@@ -4416,7 +4416,22 @@ static Sys_var_charptr Sys_license(
READ_ONLY
GLOBAL_VAR
(
license
),
NO_CMD_LINE
,
IN_SYSTEM_CHARSET
,
DEFAULT
(
STRINGIFY_ARG
(
LICENSE
)));
#include <proxy_protocol.h>
char
*
my_proxy_protocol_networks
;
static
bool
check_proxy_protocol_networks
(
sys_var
*
,
THD
*
,
set_var
*
var
)
{
if
(
!
var
->
value
)
return
false
;
return
!
proxy_protocol_networks_valid
(
var
->
save_result
.
string_value
.
str
);
}
static
bool
fix_proxy_protocol_networks
(
sys_var
*
,
THD
*
,
enum_var_type
)
{
return
(
bool
)
set_proxy_protocol_networks
(
my_proxy_protocol_networks
);
}
static
Sys_var_charptr
Sys_proxy_protocol_networks
(
"proxy_protocol_networks"
,
"Enable proxy protocol for these source "
"networks. The syntax is a comma separated list of IPv4 and IPv6 "
...
...
@@ -4424,8 +4439,10 @@ static Sys_var_charptr Sys_proxy_protocol_networks(
"a single host.
\"
*
\"
represents all networks and must the only "
"directive on the line. String
\"
localhost
\"
represents non-TCP "
"local connections (Unix domain socket, Windows named pipe or shared memory)."
,
READ_ONLY
GLOBAL_VAR
(
my_proxy_protocol_networks
),
CMD_LINE
(
REQUIRED_ARG
),
IN_FS_CHARSET
,
DEFAULT
(
""
));
GLOBAL_VAR
(
my_proxy_protocol_networks
),
CMD_LINE
(
REQUIRED_ARG
),
IN_FS_CHARSET
,
DEFAULT
(
""
),
NO_MUTEX_GUARD
,
NOT_IN_BINLOG
,
ON_CHECK
(
check_proxy_protocol_networks
),
ON_UPDATE
(
fix_proxy_protocol_networks
));
static
bool
check_log_path
(
sys_var
*
self
,
THD
*
thd
,
set_var
*
var
)
{
...
...
tests/mysql_client_test.c
View file @
96ecf3ff
...
...
@@ -20220,6 +20220,18 @@ static void test_proxy_header_ignore()
mysql_optionsv
(
m
,
MARIADB_OPT_PROXY_HEADER
,
&
v2_header
,
16
);
DIE_UNLESS
(
mysql_real_connect
(
m
,
opt_host
,
"root"
,
""
,
NULL
,
opt_port
,
opt_unix_socket
,
0
)
==
m
);
mysql_close
(
m
);
/* test for connection denied with empty proxy_protocol_networks */
int
rc
=
mysql_query
(
mysql
,
"select @@proxy_protocol_networks into @sv_proxy_protocol_networks"
);
myquery
(
rc
);
mysql_query
(
mysql
,
"set global proxy_protocol_networks=default"
);
myquery
(
rc
);
m
=
mysql_client_init
(
NULL
);
mysql_optionsv
(
m
,
MARIADB_OPT_PROXY_HEADER
,
&
v2_header
,
16
);
DIE_UNLESS
(
mysql_real_connect
(
m
,
opt_host
,
"root"
,
""
,
NULL
,
opt_port
,
opt_unix_socket
,
0
)
==
0
);
mysql_close
(
m
);
mysql_query
(
mysql
,
"set global proxy_protocol_networks= @sv_proxy_protocol_networks"
);
myquery
(
rc
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment