Linux routing table now works.

This commit is contained in:
Adam Ierymenko 2014-07-31 20:13:29 -04:00
parent 526435859f
commit df0a8e8450
3 changed files with 42 additions and 52 deletions

View File

@ -42,6 +42,8 @@ STRIP=strip --strip-all
CXXFLAGS=$(CFLAGS) -fno-rtti
OBJS+=osnet/LinuxRoutingTable.o
include objects.mk
all: one

View File

@ -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

View File

@ -28,7 +28,7 @@
#ifndef ZT_LINUXROUTINGTABLE_HPP
#define ZT_LINUXROUTINGTABLE_HPP
#include "../RoutingTable.hpp"
#include "../node/RoutingTable.hpp"
namespace ZeroTier {