Last major commit for version 0.2.2

* Fix so that "route-ttl" in ndppd.conf works

  * Fix a typo in ndppd.conf.5

  * Update "ndppd.conf" to reflect the big changes

  * Fix a bug with config loader

  * Fix so that "auto" will never forward a Neighbor Solicitation
    Message out through the "proxy" interface
This commit is contained in:
Daniel Adolfsson 2012-02-07 12:36:09 +01:00
parent d51acba693
commit 13b81fdd97
8 changed files with 113 additions and 62 deletions

View File

@ -1,3 +1,16 @@
2012-02-06 Daniel Adolfsson <daniel@priv.nu>
* Version 0.2.2
* Removed "libconfuse" dependency.
* New "auto" configuration to detect outgoing interface, for forwarding
Neighbor Solicitation Messages.
* Improved logging.
* Bug fixes related to memory management.
2012-01-26 Daniel Adolfsson <daniel@priv.nu>
* Author changed e-mail address; updated copyright info.

View File

@ -1,29 +1,33 @@
# route-ttl <integer> (NEW)
# This tells 'ndppd' how often to reload the route file /proc/net/ipv6_route.
# Default value is '30000' (30 seconds).
route-ttl 30000
# proxy <interface>
# This sets up a listener, that will listen for any Neighbor Solicitation
# messages, and respond to them according to a set of rules (see below).
# <interface> is required.
# You may have several 'proxy' sections.
# <interface> is required. You may have several 'proxy' sections.
proxy eth0 {
# router = <yes|no|true|false>
# router <yes|no|true|false>
# This option turns on or off the router flag for Neighbor Advertisement
# messages. Default value is 'true'.
router = yes
router yes
# timeout = <integer>
# timeout <integer>
# Controls how long to wait for a Neighbor Advertisment message before
# invalidating the entry, in milliseconds. Default value is '500'.
timeout = 500
timeout 500
# ttl = <integer>
# ttl <integer>
# Controls how long a valid or invalid entry remains in the cache, in
# milliseconds. Default value is '30000' (30 seconds).
ttl = 30000
ttl 30000
# rule <ip>[/<mask>]
# This is a rule that the target address is to match against. If no netmask
@ -31,22 +35,28 @@ proxy eth0 {
# addresses may or may not overlap.
rule 1111:: {
# Only one of 'static', 'auto' and 'interface' may be specified. Please
# read 'ndppd.conf' manpage for details about the methods below.
# iface = <interface>
# By setting this option, ndppd will forward the Neighbor Solicitation
# message to this interface and wait for a response. Only if a client
# responds with a Neighbor Advertisement message will the proxy respond.
# 'auto' should work in most cases.
# Note that if you do not provide an interface, this rule will match
# and immediately send a response through the proxy. It's recommended
# that you use the "iface" option as much as possible.
# static (NEW)
# 'ndppd' will immediately answer any Neighbor Solicitation Messages
# (if they match the IP rule).
# Using a prefix <= /120 without an interface will trigger a notice.
# iface <interface>
# 'ndppd' will forward the Neighbor Solicitation Message through the
# specified interface - and only respond if a matching Neighbor
# Advertisement Message is received.
iface = eth1
}
# auto (NEW)
# Same as above, but instead of manually specifying the outgoing
# interface, 'ndppd' will check for a matching route in /proc/net/ipv6_route.
rule 1111::1/96 {
iface = eth2
auto
# Note that before version 0.2.2 of 'ndppd', if you didn't choose a
# method, it defaulted to 'static'. For compatibility reasons we choose
# to keep this behavior - for now (it may be removed in a future version).
}
}

View File

@ -79,7 +79,7 @@ If this option is specified
.B ndppd
will attempt to detect which interface to use in order to forward
Neighbor Solicitation Messages, by reading the routing table
.BR /proc/sys/ipv6_route .
.BR /proc/net/ipv6_route .
.IP "static"
.B (NEW)
This option tells

View File

@ -103,29 +103,17 @@ bool conf::is_block() const
return _is_block;
}
const char* conf::skip(const char* str, bool all)
const char* conf::skip(const char* str, bool newlines)
{
if (!all) {
while (*str && (*str != '\n') && isspace(*str))
str++;
return str;
}
while (*str) {
while (*str && isspace(*str))
while (*str && isspace(*str) && ((*str != '\n') || newlines))
str++;
if (!*str)
break;
if ((*str == '#') || ((*str == '/') && (*(str + 1) == '/'))) {
while (*str && (*str != '\n'))
while (*str && (*str != '\n')) {
str++;
continue;
}
if ((*str == '/') && (*(str + 1) == '*')) {
} else if ((*str == '/') && (*(str + 1) == '*')) {
while (*str) {
if ((*str == '*') && (*(str + 1) == '/')) {
str += 2;
@ -133,11 +121,10 @@ const char* conf::skip(const char* str, bool all)
}
str++;
}
continue;
}
} else {
break;
}
}
return str;
}
@ -158,20 +145,23 @@ bool conf::parse_block(const char** str)
return true;
}
while (*p && isalpha(*p)) {
while (isalnum(*p) || (*p == '_') || (*p == '-')) {
ss << *p++;
}
p = skip(p);
p = skip(p, false);
if (*p == '=') {
p++;
p = skip(p, false);
}
ptr<conf> cf(new conf);
if (cf->parse(&p)) {
_map.insert(std::pair<std::string, ptr<conf> >(ss.str(), cf));
} else {
return false;
}
}
@ -186,18 +176,14 @@ bool conf::parse(const char** str)
p = skip(p, false);
if (!*p) {
return false;
} else if ((*p == '\'') || (*p == '"')) {
for (char e = *p++; *p && (*p != e); p++)
ss <<* p;
} else if (isalnum(*p)) {
while (*p && (isalnum(*p) || strchr(":/.",* p)))
ss <<* p++;
if ((*p == '\'') || (*p == '"')) {
for (char e = *p++; *p && (*p != e) && (*p != '\n'); p++)
ss << *p;
p = skip(p, false);
} else {
_value = "";
*str = p;
return true;
while (*p && isgraph(*p) && (*p != '{') && (*p != '}')) {
ss << *p++;
}
}
_value = ss.str();
@ -207,11 +193,13 @@ bool conf::parse(const char** str)
if (*p == '{') {
p++;
if (!parse_block(&p))
if (!parse_block(&p)) {
return false;
}
if (*p != '}')
if (*p != '}') {
return false;
}
p++;
}

View File

@ -56,17 +56,22 @@ int daemonize()
bool configure(const std::string& path)
{
ptr<conf> cf;
ptr<conf> cf, x_cf;
if (!(cf = conf::load(path)))
return false;
if (!(x_cf = cf->find("route-ttl")))
route::ttl(30000);
else
route::ttl(*x_cf);
std::vector<ptr<conf> >::const_iterator p_it;
std::vector<ptr<conf> > proxies(cf->find_all("proxy"));
for (p_it = proxies.begin(); p_it != proxies.end(); p_it++) {
ptr<conf> pr_cf =* p_it, x_cf;
ptr<conf> pr_cf = *p_it;
if (pr_cf->empty()) {
logger::error() << "'proxy' section is missing interface name";
@ -221,7 +226,7 @@ int main(int argc, char* argv[], char* env[])
if (!configure(config_path))
return -1;
route::load("/proc/net/ipv6_route");
//route::load("/proc/net/ipv6_route");
// Time stuff.
@ -247,6 +252,7 @@ int main(int argc, char* argv[], char* env[])
t1.tv_sec = t2.tv_sec;
t1.tv_usec = t2.tv_usec;
route::update(elapsed_time);
session::update_all(elapsed_time);
}

View File

@ -105,8 +105,10 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
if (ru->is_auto()) {
ptr<iface> ifa = route::find_and_open(taddr);
// TODO: Check if it's a good interface.
if (ifa) {
// If we could find a route matching our rule in /proc/net/ipv6_route,
// and it's not the same interface as the one pr (proxy) is using.
if (ifa && (ifa != ru->ifa())) {
se->add_iface(ifa);
continue;
}

View File

@ -24,6 +24,10 @@ NDPPD_NS_BEGIN
std::list<ptr<route> > route::_routes;
int route::_ttl;
int route::_c_ttl;
route::route(const address& addr, const std::string& ifname) :
_addr(addr), _ifname(ifname)
{
@ -112,6 +116,14 @@ void route::load(const std::string& path)
}
}
void route::update(int elapsed_time)
{
if ((_c_ttl -= elapsed_time) <= 0) {
load("/proc/net/ipv6_route");
_c_ttl = _ttl;
}
}
ptr<route> route::create(const address& addr, const std::string& ifname)
{
ptr<route> rt(new route(addr, ifname));
@ -162,5 +174,15 @@ const address& route::addr() const
return _addr;
}
int route::ttl()
{
return _ttl;
}
void route::ttl(int ttl)
{
_ttl = ttl;
}
NDPPD_NS_END

View File

@ -33,6 +33,12 @@ public:
static void load(const std::string& path);
static void update(int elapsed_time);
static int ttl();
static void ttl(int ttl);
const std::string& ifname() const;
const address& addr() const;
@ -40,6 +46,10 @@ public:
ptr<iface> ifa();
private:
static int _ttl;
static int _c_ttl;
address _addr;
std::string _ifname;