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:
parent
d51acba693
commit
13b81fdd97
13
ChangeLog
13
ChangeLog
@ -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>
|
2012-01-26 Daniel Adolfsson <daniel@priv.nu>
|
||||||
|
|
||||||
* Author changed e-mail address; updated copyright info.
|
* Author changed e-mail address; updated copyright info.
|
||||||
|
@ -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>
|
# proxy <interface>
|
||||||
# This sets up a listener, that will listen for any Neighbor Solicitation
|
# 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).
|
# messages, and respond to them according to a set of rules (see below).
|
||||||
# <interface> is required.
|
# <interface> is required. You may have several 'proxy' sections.
|
||||||
|
|
||||||
# You may have several 'proxy' sections.
|
|
||||||
|
|
||||||
proxy eth0 {
|
proxy eth0 {
|
||||||
|
|
||||||
# router = <yes|no|true|false>
|
# router <yes|no|true|false>
|
||||||
# This option turns on or off the router flag for Neighbor Advertisement
|
# This option turns on or off the router flag for Neighbor Advertisement
|
||||||
# messages. Default value is 'true'.
|
# messages. Default value is 'true'.
|
||||||
|
|
||||||
router = yes
|
router yes
|
||||||
|
|
||||||
# timeout = <integer>
|
# timeout <integer>
|
||||||
# Controls how long to wait for a Neighbor Advertisment message before
|
# Controls how long to wait for a Neighbor Advertisment message before
|
||||||
# invalidating the entry, in milliseconds. Default value is '500'.
|
# 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
|
# Controls how long a valid or invalid entry remains in the cache, in
|
||||||
# milliseconds. Default value is '30000' (30 seconds).
|
# milliseconds. Default value is '30000' (30 seconds).
|
||||||
|
|
||||||
ttl = 30000
|
ttl 30000
|
||||||
|
|
||||||
# rule <ip>[/<mask>]
|
# rule <ip>[/<mask>]
|
||||||
# This is a rule that the target address is to match against. If no netmask
|
# 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.
|
# addresses may or may not overlap.
|
||||||
|
|
||||||
rule 1111:: {
|
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>
|
# 'auto' should work in most cases.
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Note that if you do not provide an interface, this rule will match
|
# static (NEW)
|
||||||
# and immediately send a response through the proxy. It's recommended
|
# 'ndppd' will immediately answer any Neighbor Solicitation Messages
|
||||||
# that you use the "iface" option as much as possible.
|
# (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 {
|
auto
|
||||||
iface = eth2
|
|
||||||
|
# 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).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ If this option is specified
|
|||||||
.B ndppd
|
.B ndppd
|
||||||
will attempt to detect which interface to use in order to forward
|
will attempt to detect which interface to use in order to forward
|
||||||
Neighbor Solicitation Messages, by reading the routing table
|
Neighbor Solicitation Messages, by reading the routing table
|
||||||
.BR /proc/sys/ipv6_route .
|
.BR /proc/net/ipv6_route .
|
||||||
.IP "static"
|
.IP "static"
|
||||||
.B (NEW)
|
.B (NEW)
|
||||||
This option tells
|
This option tells
|
||||||
|
54
src/conf.cc
54
src/conf.cc
@ -103,29 +103,17 @@ bool conf::is_block() const
|
|||||||
return _is_block;
|
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) {
|
||||||
while (*str && isspace(*str))
|
while (*str && isspace(*str) && ((*str != '\n') || newlines))
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
if (!*str)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((*str == '#') || ((*str == '/') && (*(str + 1) == '/'))) {
|
if ((*str == '#') || ((*str == '/') && (*(str + 1) == '/'))) {
|
||||||
while (*str && (*str != '\n'))
|
while (*str && (*str != '\n')) {
|
||||||
str++;
|
str++;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
} else if ((*str == '/') && (*(str + 1) == '*')) {
|
||||||
if ((*str == '/') && (*(str + 1) == '*')) {
|
|
||||||
while (*str) {
|
while (*str) {
|
||||||
if ((*str == '*') && (*(str + 1) == '/')) {
|
if ((*str == '*') && (*(str + 1) == '/')) {
|
||||||
str += 2;
|
str += 2;
|
||||||
@ -133,11 +121,10 @@ const char* conf::skip(const char* str, bool all)
|
|||||||
}
|
}
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
continue;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@ -158,20 +145,23 @@ bool conf::parse_block(const char** str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*p && isalpha(*p)) {
|
while (isalnum(*p) || (*p == '_') || (*p == '-')) {
|
||||||
ss << *p++;
|
ss << *p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = skip(p);
|
p = skip(p, false);
|
||||||
|
|
||||||
if (*p == '=') {
|
if (*p == '=') {
|
||||||
p++;
|
p++;
|
||||||
|
p = skip(p, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<conf> cf(new conf);
|
ptr<conf> cf(new conf);
|
||||||
|
|
||||||
if (cf->parse(&p)) {
|
if (cf->parse(&p)) {
|
||||||
_map.insert(std::pair<std::string, ptr<conf> >(ss.str(), cf));
|
_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);
|
p = skip(p, false);
|
||||||
|
|
||||||
if (!*p) {
|
if ((*p == '\'') || (*p == '"')) {
|
||||||
return false;
|
for (char e = *p++; *p && (*p != e) && (*p != '\n'); p++)
|
||||||
} else if ((*p == '\'') || (*p == '"')) {
|
|
||||||
for (char e = *p++; *p && (*p != e); p++)
|
|
||||||
ss << *p;
|
ss << *p;
|
||||||
} else if (isalnum(*p)) {
|
p = skip(p, false);
|
||||||
while (*p && (isalnum(*p) || strchr(":/.",* p)))
|
|
||||||
ss <<* p++;
|
|
||||||
} else {
|
} else {
|
||||||
_value = "";
|
while (*p && isgraph(*p) && (*p != '{') && (*p != '}')) {
|
||||||
*str = p;
|
ss << *p++;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_value = ss.str();
|
_value = ss.str();
|
||||||
@ -207,11 +193,13 @@ bool conf::parse(const char** str)
|
|||||||
if (*p == '{') {
|
if (*p == '{') {
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
if (!parse_block(&p))
|
if (!parse_block(&p)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (*p != '}')
|
if (*p != '}') {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
12
src/ndppd.cc
12
src/ndppd.cc
@ -56,17 +56,22 @@ int daemonize()
|
|||||||
|
|
||||||
bool configure(const std::string& path)
|
bool configure(const std::string& path)
|
||||||
{
|
{
|
||||||
ptr<conf> cf;
|
ptr<conf> cf, x_cf;
|
||||||
|
|
||||||
if (!(cf = conf::load(path)))
|
if (!(cf = conf::load(path)))
|
||||||
return false;
|
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> >::const_iterator p_it;
|
||||||
|
|
||||||
std::vector<ptr<conf> > proxies(cf->find_all("proxy"));
|
std::vector<ptr<conf> > proxies(cf->find_all("proxy"));
|
||||||
|
|
||||||
for (p_it = proxies.begin(); p_it != proxies.end(); p_it++) {
|
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()) {
|
if (pr_cf->empty()) {
|
||||||
logger::error() << "'proxy' section is missing interface name";
|
logger::error() << "'proxy' section is missing interface name";
|
||||||
@ -221,7 +226,7 @@ int main(int argc, char* argv[], char* env[])
|
|||||||
if (!configure(config_path))
|
if (!configure(config_path))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
route::load("/proc/net/ipv6_route");
|
//route::load("/proc/net/ipv6_route");
|
||||||
|
|
||||||
// Time stuff.
|
// Time stuff.
|
||||||
|
|
||||||
@ -247,6 +252,7 @@ int main(int argc, char* argv[], char* env[])
|
|||||||
t1.tv_sec = t2.tv_sec;
|
t1.tv_sec = t2.tv_sec;
|
||||||
t1.tv_usec = t2.tv_usec;
|
t1.tv_usec = t2.tv_usec;
|
||||||
|
|
||||||
|
route::update(elapsed_time);
|
||||||
session::update_all(elapsed_time);
|
session::update_all(elapsed_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +105,10 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
|
|||||||
|
|
||||||
if (ru->is_auto()) {
|
if (ru->is_auto()) {
|
||||||
ptr<iface> ifa = route::find_and_open(taddr);
|
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);
|
se->add_iface(ifa);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
22
src/route.cc
22
src/route.cc
@ -24,6 +24,10 @@ NDPPD_NS_BEGIN
|
|||||||
|
|
||||||
std::list<ptr<route> > route::_routes;
|
std::list<ptr<route> > route::_routes;
|
||||||
|
|
||||||
|
int route::_ttl;
|
||||||
|
|
||||||
|
int route::_c_ttl;
|
||||||
|
|
||||||
route::route(const address& addr, const std::string& ifname) :
|
route::route(const address& addr, const std::string& ifname) :
|
||||||
_addr(addr), _ifname(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> route::create(const address& addr, const std::string& ifname)
|
||||||
{
|
{
|
||||||
ptr<route> rt(new route(addr, ifname));
|
ptr<route> rt(new route(addr, ifname));
|
||||||
@ -162,5 +174,15 @@ const address& route::addr() const
|
|||||||
return _addr;
|
return _addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int route::ttl()
|
||||||
|
{
|
||||||
|
return _ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void route::ttl(int ttl)
|
||||||
|
{
|
||||||
|
_ttl = ttl;
|
||||||
|
}
|
||||||
|
|
||||||
NDPPD_NS_END
|
NDPPD_NS_END
|
||||||
|
|
||||||
|
10
src/route.h
10
src/route.h
@ -33,6 +33,12 @@ public:
|
|||||||
|
|
||||||
static void load(const std::string& path);
|
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 std::string& ifname() const;
|
||||||
|
|
||||||
const address& addr() const;
|
const address& addr() const;
|
||||||
@ -40,6 +46,10 @@ public:
|
|||||||
ptr<iface> ifa();
|
ptr<iface> ifa();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static int _ttl;
|
||||||
|
|
||||||
|
static int _c_ttl;
|
||||||
|
|
||||||
address _addr;
|
address _addr;
|
||||||
|
|
||||||
std::string _ifname;
|
std::string _ifname;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user