Add sqlite function for ipv6 cidr testing

This commit is contained in:
Benau
2019-10-25 09:20:36 +08:00
parent 4be93daa83
commit 0217eaf173
3 changed files with 95 additions and 2 deletions

View File

@@ -40,6 +40,7 @@
#include "network/race_event_manager.hpp"
#include "network/server_config.hpp"
#include "network/stk_host.hpp"
#include "network/stk_ipv6.hpp"
#include "network/stk_peer.hpp"
#include "online/online_profile.hpp"
#include "online/xml_request.hpp"
@@ -59,6 +60,48 @@
#include <iostream>
#include <iterator>
#ifdef ENABLE_SQLITE3
// ----------------------------------------------------------------------------
void insideIPv6CIDRSQL(sqlite3_context* context, int argc,
sqlite3_value** argv)
{
if (argc != 2)
{
sqlite3_result_int(context, 0);
return;
}
char* ipv6_cidr = (char*)sqlite3_value_text(argv[0]);
char* ipv6_in = (char*)sqlite3_value_text(argv[1]);
if (ipv6_cidr == NULL || ipv6_in == NULL)
{
sqlite3_result_int(context, 0);
return;
}
sqlite3_result_int(context, insideIPv6CIDR(ipv6_cidr, ipv6_in));
} // insideIPv6CIDRSQL
// ----------------------------------------------------------------------------
/*
Copy below code so it can be use as loadable extension to be used in sqlite3
command interface (together with andIPv6 and insideIPv6CIDR from stk_ipv6)
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
// ----------------------------------------------------------------------------
sqlite3_extension_init(sqlite3* db, char** pzErrMsg,
const sqlite3_api_routines* pApi)
{
SQLITE_EXTENSION_INIT2(pApi)
sqlite3_create_function(db, "insideIPv6CIDR", 2, SQLITE_UTF8, NULL,
insideIPv6CIDRSQL, NULL, NULL);
return 0;
} // sqlite3_extension_init
*/
#endif
/** This is the central game setup protocol running in the server. It is
* mostly a finite state machine. Note that all nodes in ellipses and light
* grey background are actual states; nodes in boxes and white background
@@ -202,7 +245,8 @@ void ServerLobby::initDatabase()
// Return zero to let caller return SQLITE_BUSY immediately
return 0;
}, NULL);
sqlite3_create_function(m_db, "insideIPv6CIDR", 2, SQLITE_UTF8, NULL,
&insideIPv6CIDRSQL, NULL, NULL);
checkTableExists(ServerConfig::m_ip_ban_table, m_ip_ban_table_exists);
checkTableExists(ServerConfig::m_online_id_ban_table,
m_online_id_ban_table_exists);

View File

@@ -15,6 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <string.h>
#ifdef WIN32
#ifdef __GNUC__
# include <ws2tcpip.h> // Mingw / gcc on windows
@@ -26,6 +27,7 @@
extern "C"
{
WINSOCK_API_LINKAGE PCSTR WSAAPI inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize);
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
}
#else
@@ -126,7 +128,53 @@ extern "C" int getaddrinfo_compat(const char* hostname,
#else
return getaddrinfo(hostname, servname, hints, res);
#endif
}
} // getaddrinfo_compat
// ----------------------------------------------------------------------------
void andIPv6(struct in6_addr* ipv6, const struct in6_addr* mask)
{
for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
ipv6->s6_addr[i] &= mask->s6_addr[i];
} // andIPv6
// ----------------------------------------------------------------------------
extern "C" int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in)
{
const char* mask_location = strchr(ipv6_cidr, '/');
if (mask_location == NULL)
return 0;
struct in6_addr v6_in;
if (inet_pton(AF_INET6, ipv6_in, &v6_in) != 1)
return 0;
char ipv6[INET6_ADDRSTRLEN] = {};
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
struct in6_addr cidr;
if (inet_pton(AF_INET6, ipv6, &cidr) != 1)
return 0;
int mask_length = atoi(mask_location + 1);
if (mask_length > 128 || mask_length <= 0)
return 0;
struct in6_addr mask = {};
for (int i = mask_length, j = 0; i > 0; i -= 8, j++)
{
if (i >= 8)
mask.s6_addr[j] = 0xff;
else
mask.s6_addr[j] = (unsigned long)(0xffU << (8 - i));
}
andIPv6(&cidr, &mask);
andIPv6(&v6_in, &mask);
for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
{
if (cidr.s6_addr[i] != v6_in.s6_addr[i])
return 0;
}
return 1;
} // andIPv6
#ifndef ENABLE_IPV6
#include "network/stk_ipv6.hpp"

View File

@@ -29,6 +29,7 @@ void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea);
void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6);
int getaddrinfo_compat(const char* hostname, const char* servname,
const struct addrinfo* hints, struct addrinfo** res);
int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in);
#ifdef __cplusplus
}
#endif