Rebase NamedServerFilter to develop
Fix conflicts due to ipv6 changes. Change SourceHost->m_address to string. SourceHost generation is now cleaner.
This commit is contained in:
@ -73,12 +73,6 @@ RegexHintFilter::RegexHintFilter(string user, SourceHost* source,
|
|||||||
RegexHintFilter::~RegexHintFilter()
|
RegexHintFilter::~RegexHintFilter()
|
||||||
{
|
{
|
||||||
delete m_source;
|
delete m_source;
|
||||||
pcre2_code_free(m_regex);
|
|
||||||
if (m_source)
|
|
||||||
{
|
|
||||||
MXS_FREE(m_source->address);
|
|
||||||
}
|
|
||||||
MXS_FREE(m_source);
|
|
||||||
for (unsigned int i = 0; i < m_mapping.size(); i++)
|
for (unsigned int i = 0; i < m_mapping.size(); i++)
|
||||||
{
|
{
|
||||||
pcre2_code_free(m_mapping.at(i).m_regex);
|
pcre2_code_free(m_mapping.at(i).m_regex);
|
||||||
@ -158,11 +152,11 @@ RegexHintFSession* RegexHintFilter::newSession(MXS_SESSION* session)
|
|||||||
bool session_active = true;
|
bool session_active = true;
|
||||||
|
|
||||||
/* Check client IP against 'source' host option */
|
/* Check client IP against 'source' host option */
|
||||||
if (m_source && m_source->m_address &&
|
if (m_source && m_source->m_address.length() &&
|
||||||
(remote = session_get_remote(session)) != NULL)
|
(remote = session_get_remote(session)) != NULL)
|
||||||
{
|
{
|
||||||
session_active =
|
session_active =
|
||||||
check_source_host(remote, &(session->client_dcb->ipv4));
|
check_source_host(remote, &(session->client_dcb->ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check client user against 'user' option */
|
/* Check client user against 'user' option */
|
||||||
@ -319,7 +313,7 @@ void RegexHintFilter::diagnostics(DCB* dcb)
|
|||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"\t\tReplacement limited to connections from %s\n",
|
"\t\tReplacement limited to connections from %s\n",
|
||||||
m_source->m_address);
|
m_source->m_address.c_str());
|
||||||
}
|
}
|
||||||
if (m_user.length())
|
if (m_user.length())
|
||||||
{
|
{
|
||||||
@ -470,17 +464,17 @@ void RegexHintFilter::form_regex_server_mapping(MXS_CONFIG_PARAMETER* params, in
|
|||||||
* @param ipv4 The client IPv4 struct
|
* @param ipv4 The client IPv4 struct
|
||||||
* @return 1 for match, 0 otherwise
|
* @return 1 for match, 0 otherwise
|
||||||
*/
|
*/
|
||||||
int RegexHintFilter::check_source_host(const char* remote, const struct sockaddr_in* ipv4)
|
int RegexHintFilter::check_source_host(const char* remote, const struct sockaddr_storage *ip)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct sockaddr_in check_ipv4;
|
struct sockaddr_in check_ipv4;
|
||||||
|
|
||||||
memcpy(&check_ipv4, ipv4, sizeof(check_ipv4));
|
memcpy(&check_ipv4, ip, sizeof(check_ipv4));
|
||||||
|
|
||||||
switch (m_source->m_netmask)
|
switch (m_source->m_netmask)
|
||||||
{
|
{
|
||||||
case 32:
|
case 32:
|
||||||
ret = strcmp(m_source->m_address, remote) == 0 ? 1 : 0;
|
ret = (m_source->m_address == remote) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
/* Class C check */
|
/* Class C check */
|
||||||
@ -507,7 +501,7 @@ int RegexHintFilter::check_source_host(const char* remote, const struct sockaddr
|
|||||||
MXS_INFO("Client IP %s matches host source %s%s",
|
MXS_INFO("Client IP %s matches host source %s%s",
|
||||||
remote,
|
remote,
|
||||||
m_source->m_netmask < 32 ? "with wildcards " : "",
|
m_source->m_netmask < 32 ? "with wildcards " : "",
|
||||||
m_source->m_address);
|
m_source->m_address.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -580,39 +574,33 @@ bool RegexHintFilter::validate_ip_address(const char* host)
|
|||||||
SourceHost* RegexHintFilter::set_source_address(const char* input_host)
|
SourceHost* RegexHintFilter::set_source_address(const char* input_host)
|
||||||
{
|
{
|
||||||
ss_dassert(input_host);
|
ss_dassert(input_host);
|
||||||
int netmask = 32;
|
|
||||||
int bytes = 0;
|
|
||||||
struct sockaddr_in serv_addr;
|
|
||||||
|
|
||||||
if (!input_host)
|
if (!input_host)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceHost* source_host = new SourceHost();
|
|
||||||
|
|
||||||
if (!validate_ip_address(input_host))
|
if (!validate_ip_address(input_host))
|
||||||
{
|
{
|
||||||
MXS_WARNING("The given 'source' parameter source=%s"
|
MXS_WARNING("The given 'source' parameter '%s' is not a valid IPv4 address.",
|
||||||
" is not a valid IP address: it will not be used.",
|
|
||||||
input_host);
|
input_host);
|
||||||
|
return NULL;
|
||||||
source_host->m_address = NULL;
|
|
||||||
return source_host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
source_host->m_address = input_host;
|
string address(input_host);
|
||||||
|
struct sockaddr_in ipv4 = {};
|
||||||
|
int netmask = 32;
|
||||||
|
|
||||||
/* If no wildcards don't check it, set netmask to 32 and return */
|
/* If no wildcards, leave netmask to 32 and return */
|
||||||
if (!strchr(input_host, '%'))
|
if (!strchr(input_host, '%'))
|
||||||
{
|
{
|
||||||
source_host->m_netmask = netmask;
|
return new SourceHost(address, ipv4, netmask);
|
||||||
return source_host;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char format_host[strlen(input_host) + 1];
|
char format_host[strlen(input_host) + 1];
|
||||||
char* p = (char*)input_host;
|
char* p = (char*)input_host;
|
||||||
char* out = format_host;
|
char* out = format_host;
|
||||||
|
int bytes = 0;
|
||||||
|
|
||||||
while (*p && bytes <= 3)
|
while (*p && bytes <= 3)
|
||||||
{
|
{
|
||||||
@ -636,7 +624,6 @@ SourceHost* RegexHintFilter::set_source_address(const char* input_host)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*out = '\0';
|
*out = '\0';
|
||||||
source_host->m_netmask = netmask;
|
|
||||||
|
|
||||||
struct addrinfo *ai = NULL, hint = {};
|
struct addrinfo *ai = NULL, hint = {};
|
||||||
hint.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
|
hint.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
|
||||||
@ -646,28 +633,26 @@ SourceHost* RegexHintFilter::set_source_address(const char* input_host)
|
|||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
ss_dassert(ai->ai_family == AF_INET);
|
ss_dassert(ai->ai_family == AF_INET);
|
||||||
memcpy(&source_host->ipv4, ai->ai_addr, ai->ai_addrlen);
|
memcpy(&ipv4, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
|
||||||
/* if netmask < 32 there are % wildcards */
|
/* if netmask < 32 there are % wildcards */
|
||||||
if (source_host->m_netmask < 32)
|
if (netmask < 32)
|
||||||
{
|
{
|
||||||
/* let's zero the last IP byte: a.b.c.0 we may have set above to 1*/
|
/* let's zero the last IP byte: a.b.c.0 we may have set above to 1*/
|
||||||
source_host->m_ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
MXS_INFO("Input %s is valid with netmask %d", source_host->address, source_host->netmask);
|
MXS_INFO("Input %s is valid with netmask %d", address.c_str(), netmask);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXS_WARNING("Found invalid IP address for parameter 'source=%s': %s",
|
MXS_WARNING("Found invalid IP address for parameter 'source=%s': %s",
|
||||||
input_host, gai_strerror(rc));
|
input_host, gai_strerror(rc));
|
||||||
MXS_FREE(source_host->address);
|
|
||||||
MXS_FREE(source_host);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return source_host;
|
return new SourceHost(address, ipv4, netmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <maxscale/filter.hh>
|
#include <maxscale/filter.hh>
|
||||||
#include <maxscale/buffer.hh>
|
#include <maxscale/buffer.hh>
|
||||||
@ -42,7 +43,7 @@ private:
|
|||||||
MappingArray m_mapping; /* Regular expression to serverlist mapping */
|
MappingArray m_mapping; /* Regular expression to serverlist mapping */
|
||||||
const int m_ovector_size; /* Given to pcre2_match_data_create() */
|
const int m_ovector_size; /* Given to pcre2_match_data_create() */
|
||||||
|
|
||||||
int check_source_host(const char *remote, const struct sockaddr_in *ipv4);
|
int check_source_host(const char *remote, const struct sockaddr_storage *ip);
|
||||||
public:
|
public:
|
||||||
/* Total statements diverted statistics. Unreliable due to lockless yet
|
/* Total statements diverted statistics. Unreliable due to lockless yet
|
||||||
* shared access. */
|
* shared access. */
|
||||||
@ -106,11 +107,12 @@ struct RegexToServers
|
|||||||
/* Container for address-specific filtering */
|
/* Container for address-specific filtering */
|
||||||
struct SourceHost
|
struct SourceHost
|
||||||
{
|
{
|
||||||
const char *m_address;
|
string m_address;
|
||||||
struct sockaddr_in m_ipv4;
|
struct sockaddr_in m_ipv4;
|
||||||
int m_netmask;
|
int m_netmask;
|
||||||
SourceHost()
|
SourceHost(string address, const struct sockaddr_in& ipv4, int netmask)
|
||||||
: m_address(NULL)
|
: m_address(address),
|
||||||
{};
|
m_ipv4(ipv4),
|
||||||
|
m_netmask(netmask)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user