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:
Esa Korhonen
2017-03-15 14:00:44 +02:00
parent ab7b1c227e
commit 9dbabb666a
2 changed files with 28 additions and 41 deletions

View File

@ -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);
} }
/** /**

View File

@ -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)
{}
}; };