MINOR: lua: add ip addresses and network manipulation function

Add two functions core.parse_addr() and core.match_addr() where are used
for matching networks.
This commit is contained in:
Thierry FOURNIER / OZON.IO 2016-11-10 20:38:11 +01:00 committed by Willy Tarreau
parent 65192f35d2
commit 62fec75183
3 changed files with 109 additions and 0 deletions

View File

@ -582,6 +582,28 @@ Core class
Give back the hand at the HAProxy scheduler. It is used when the LUA Give back the hand at the HAProxy scheduler. It is used when the LUA
processing consumes a lot of processing time. processing consumes a lot of processing time.
.. js:function:: core.parse_addr(address)
**context**: body, init, task, action, sample-fetch, converter
:param network: is a string describing an ipv4 or ipv6 address and optionally
its network length, like this: "127.0.0.1/8" or "aaaa::1234/32".
:returns: a userdata containing network or nil if an error occurs.
Parse ipv4 or ipv6 adresses and its facultative associated network.
.. js:function:: core.match_addr(addr1, addr2)
**context**: body, init, task, action, sample-fetch, converter
:param addr1: is an address created with "core.parse_addr".
:param addr2: is an address created with "core.parse_addr".
:returns: boolean, true if the network of the addresses matche, else returns
false.
Match two networks. For example "127.0.0.1/32" matchs "127.0.0.0/8". The order
of network is not important.
.. _proxy_class: .. _proxy_class:
Proxy class Proxy class

View File

@ -150,6 +150,20 @@ struct hlua_concat {
int len; int len;
}; };
struct hlua_addr {
union {
struct {
struct in_addr ip;
struct in_addr mask;
} v4;
struct {
struct in6_addr ip;
struct in6_addr mask;
} v6;
} addr;
int type;
};
#else /* USE_LUA */ #else /* USE_LUA */
/* Empty struct for compilation compatibility */ /* Empty struct for compilation compatibility */

View File

@ -906,6 +906,77 @@ int hlua_fcn_post_init(lua_State *L)
return 1; return 1;
} }
int hlua_parse_addr(lua_State *L)
{
struct hlua_addr *addr;
const char *str = luaL_checkstring(L, 1);
unsigned char mask;
addr = lua_newuserdata(L, sizeof(struct hlua_addr));
if (!addr) {
lua_pushnil(L);
return 1;
}
if (str2net(str, PAT_MF_NO_DNS, &addr->addr.v4.ip, &addr->addr.v4.mask)) {
addr->type = AF_INET;
return 1;
}
if (str62net(str, &addr->addr.v6.ip, &mask)) {
len2mask6(mask, &addr->addr.v6.mask);
addr->type = AF_INET6;
return 1;
}
lua_pop(L, 1);
lua_pushnil(L);
return 1;
}
int hlua_match_addr(lua_State *L)
{
struct hlua_addr *addr1;
struct hlua_addr *addr2;
if (!lua_isuserdata(L, 1) ||
!lua_isuserdata(L, 2)) {
lua_pushboolean(L, 0);
return 1;
}
addr1 = lua_touserdata(L, 1);
addr2 = lua_touserdata(L, 2);
if (addr1->type != addr2->type) {
lua_pushboolean(L, 0);
return 1;
}
if (addr1->type == AF_INET) {
if ((addr1->addr.v4.ip.s_addr & addr2->addr.v4.mask.s_addr) ==
(addr2->addr.v4.ip.s_addr & addr1->addr.v4.mask.s_addr)) {
lua_pushboolean(L, 1);
return 1;
}
} else {
if (((addr1->addr.v6.ip.s6_addr32[0] & addr2->addr.v6.mask.s6_addr32[0]) ==
(addr2->addr.v6.ip.s6_addr32[0] & addr1->addr.v6.mask.s6_addr32[0])) &&
((addr1->addr.v6.ip.s6_addr32[1] & addr2->addr.v6.mask.s6_addr32[1]) ==
(addr2->addr.v6.ip.s6_addr32[1] & addr1->addr.v6.mask.s6_addr32[1])) &&
((addr1->addr.v6.ip.s6_addr32[2] & addr2->addr.v6.mask.s6_addr32[2]) ==
(addr2->addr.v6.ip.s6_addr32[2] & addr1->addr.v6.mask.s6_addr32[2])) &&
((addr1->addr.v6.ip.s6_addr32[3] & addr2->addr.v6.mask.s6_addr32[3]) ==
(addr2->addr.v6.ip.s6_addr32[3] & addr1->addr.v6.mask.s6_addr32[3]))) {
lua_pushboolean(L, 1);
return 1;
}
}
lua_pushboolean(L, 0);
return 1;
}
int hlua_fcn_reg_core_fcn(lua_State *L) int hlua_fcn_reg_core_fcn(lua_State *L)
{ {
if (!hlua_concat_init(L)) if (!hlua_concat_init(L))
@ -918,6 +989,8 @@ int hlua_fcn_reg_core_fcn(lua_State *L)
hlua_class_function(L, "asctime_date", hlua_asctime_date); hlua_class_function(L, "asctime_date", hlua_asctime_date);
hlua_class_function(L, "concat", hlua_concat_new); hlua_class_function(L, "concat", hlua_concat_new);
hlua_class_function(L, "get_info", hlua_get_info); hlua_class_function(L, "get_info", hlua_get_info);
hlua_class_function(L, "parse_addr", hlua_parse_addr);
hlua_class_function(L, "match_addr", hlua_match_addr);
/* Create listener object. */ /* Create listener object. */
lua_newtable(L); lua_newtable(L);