From df0a8e845086fe4cb097d8ce2618764e0258bbc1 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 31 Jul 2014 20:13:29 -0400 Subject: [PATCH] Linux routing table now works. --- make-linux.mk | 2 + osnet/LinuxRoutingTable.cpp | 90 ++++++++++++++++--------------------- osnet/LinuxRoutingTable.hpp | 2 +- 3 files changed, 42 insertions(+), 52 deletions(-) diff --git a/make-linux.mk b/make-linux.mk index 3fe4480ce..c2678cf17 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 67a5b22d1..736323be4 100644 --- a/osnet/LinuxRoutingTable.cpp +++ b/osnet/LinuxRoutingTable.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -41,8 +42,8 @@ #include #include -#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 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 rtab(get(true,true)); + Utils::snprintf(metstr,sizeof(metstr),"%d",metric); - for(std::vector::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 rtab(get(true,true)); std::vector::iterator bestEntry(rtab.end()); for(std::vector::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(" \n"); - std::vector ents(rt.get()); - for(std::vector::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(" \n"); - ents = rt.get(); - for(std::vector::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(" \n"); - ents = rt.get(); - for(std::vector::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 9a5d3fd6d..3c3c10086 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 {