summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--make-linux.mk2
-rw-r--r--osnet/LinuxRoutingTable.cpp90
-rw-r--r--osnet/LinuxRoutingTable.hpp2
3 files changed, 42 insertions, 52 deletions
diff --git a/make-linux.mk b/make-linux.mk
index 3fe4480c..c2678cf1 100644
--- a/make-linux.mk
+++ b/make-linux.mk
@@ -42,6 +42,8 @@ STRIP=strip --strip-all
CXXFLAGS=$(CFLAGS) -fno-rtti
+OBJS+=osnet/LinuxRoutingTable.o
+
include objects.mk
all: one
diff --git a/osnet/LinuxRoutingTable.cpp b/osnet/LinuxRoutingTable.cpp
index 67a5b22d..736323be 100644
--- a/osnet/LinuxRoutingTable.cpp
+++ b/osnet/LinuxRoutingTable.cpp
@@ -33,6 +33,7 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -41,8 +42,8 @@
#include <algorithm>
#include <utility>
-#include "../Constants.hpp"
-#include "../Utils.hpp"
+#include "../node/Constants.hpp"
+#include "../node/Utils.hpp"
#include "LinuxRoutingTable.hpp"
#define ZT_LINUX_IP_COMMAND "/sbin/ip"
@@ -168,24 +169,50 @@ std::vector<RoutingTable::Entry> LinuxRoutingTable::get(bool includeLinkLocal,bo
RoutingTable::Entry LinuxRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric)
{
+ char metstr[128];
+
if ((!gateway)&&((!device)||(!device[0])))
return RoutingTable::Entry();
- std::vector<RoutingTable::Entry> rtab(get(true,true));
+ Utils::snprintf(metstr,sizeof(metstr),"%d",metric);
- for(std::vector<RoutingTable::Entry>::iterator e(rtab.begin());e!=rtab.end();++e) {
- if (e->destination == destination) {
- if (((!device)||(!device[0]))||(!strcmp(device,e->device))) {
+ if (metric < 0) {
+ long pid = (long)vfork();
+ if (pid == 0) {
+ if (gateway) {
+ if ((device)&&(device[0])) {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),"dev",device,(const char *)0);
+ } else {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),(const char *)0);
+ }
+ } else {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"dev",device,(const char *)0);
}
+ ::_exit(-1);
+ } else if (pid > 0) {
+ int exitcode = -1;
+ ::waitpid(pid,&exitcode,0);
+ }
+ } else {
+ long pid = (long)vfork();
+ if (pid == 0) {
+ if (gateway) {
+ if ((device)&&(device[0])) {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),"dev",device,(const char *)0);
+ } else {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),(const char *)0);
+ }
+ } else {
+ ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"dev",device,(const char *)0);
+ }
+ ::_exit(-1);
+ } else if (pid > 0) {
+ int exitcode = -1;
+ ::waitpid(pid,&exitcode,0);
}
}
- if (metric < 0)
- return RoutingTable::Entry();
-
-
-
- rtab = get(true,true);
+ std::vector<RoutingTable::Entry> rtab(get(true,true));
std::vector<RoutingTable::Entry>::iterator bestEntry(rtab.end());
for(std::vector<RoutingTable::Entry>::iterator e(rtab.begin());e!=rtab.end();++e) {
if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) {
@@ -206,42 +233,3 @@ RoutingTable::Entry LinuxRoutingTable::set(const InetAddress &destination,const
}
} // namespace ZeroTier
-
-// Enable and build to test routing table interface
-//#if 0
-using namespace ZeroTier;
-int main(int argc,char **argv)
-{
- LinuxRoutingTable rt;
-
- printf("<destination> <gateway> <interface> <metric>\n");
- std::vector<RoutingTable::Entry> ents(rt.get());
- for(std::vector<RoutingTable::Entry>::iterator e(ents.begin());e!=ents.end();++e)
- printf("%s\n",e->toString().c_str());
- printf("\n");
-
- printf("adding 1.1.1.0 and 2.2.2.0...\n");
- rt.set(InetAddress("1.1.1.0",24),InetAddress("1.2.3.4",0),(const char *)0,1);
- rt.set(InetAddress("2.2.2.0",24),InetAddress(),"en0",1);
- printf("\n");
-
- printf("<destination> <gateway> <interface> <metric>\n");
- ents = rt.get();
- for(std::vector<RoutingTable::Entry>::iterator e(ents.begin());e!=ents.end();++e)
- printf("%s\n",e->toString().c_str());
- printf("\n");
-
- printf("deleting 1.1.1.0 and 2.2.2.0...\n");
- rt.set(InetAddress("1.1.1.0",24),InetAddress("1.2.3.4",0),(const char *)0,-1);
- rt.set(InetAddress("2.2.2.0",24),InetAddress(),"en0",-1);
- printf("\n");
-
- printf("<destination> <gateway> <interface> <metric>\n");
- ents = rt.get();
- for(std::vector<RoutingTable::Entry>::iterator e(ents.begin());e!=ents.end();++e)
- printf("%s\n",e->toString().c_str());
- printf("\n");
-
- return 0;
-}
-//#endif
diff --git a/osnet/LinuxRoutingTable.hpp b/osnet/LinuxRoutingTable.hpp
index 9a5d3fd6..3c3c1008 100644
--- a/osnet/LinuxRoutingTable.hpp
+++ b/osnet/LinuxRoutingTable.hpp
@@ -28,7 +28,7 @@
#ifndef ZT_LINUXROUTINGTABLE_HPP
#define ZT_LINUXROUTINGTABLE_HPP
-#include "../RoutingTable.hpp"
+#include "../node/RoutingTable.hpp"
namespace ZeroTier {