summaryrefslogtreecommitdiff
path: root/src/anyrtpproxy
diff options
context:
space:
mode:
Diffstat (limited to 'src/anyrtpproxy')
-rw-r--r--src/anyrtpproxy/Makefile68
-rw-r--r--src/anyrtpproxy/anyrtpproxy.cpp372
-rw-r--r--src/anyrtpproxy/callIdQueue.cpp76
-rw-r--r--src/anyrtpproxy/callIdQueue.h72
-rw-r--r--src/anyrtpproxy/commandHandler.cpp268
-rw-r--r--src/anyrtpproxy/commandHandler.h89
-rw-r--r--src/anyrtpproxy/connectionList.cpp89
-rw-r--r--src/anyrtpproxy/connectionList.h64
-rw-r--r--src/anyrtpproxy/options.cpp308
-rw-r--r--src/anyrtpproxy/options.h129
-rw-r--r--src/anyrtpproxy/portWindow.cpp85
-rw-r--r--src/anyrtpproxy/portWindow.h63
12 files changed, 1683 insertions, 0 deletions
diff --git a/src/anyrtpproxy/Makefile b/src/anyrtpproxy/Makefile
new file mode 100644
index 0000000..948a4c8
--- /dev/null
+++ b/src/anyrtpproxy/Makefile
@@ -0,0 +1,68 @@
+C = gcc
+CFLAGS = -g -Wall
+CFLAGS += -DSOCKETS_NAMESPACE=sockets
+CFLAGS += -DSOCKETS_NAMESPACE_STR='"sockets"'
+C++ = g++
+CCFLAGS = -g -Wall
+CCFLAGS += -DSOCKETS_NAMESPACE=sockets
+CCFLAGS += -DSOCKETS_NAMESPACE_STR='"sockets"'
+LD = g++
+LDFLAGS = -g -Wall -O2 -lpthread -lssl -lboost_serialization
+
+OBJS = anyrtpproxy.o \
+ ../signalController.o \
+ ../PracticalSocket.o \
+ ../log.o \
+ ../buffer.o \
+ ../rtpSessionTable.o \
+ ../rtpSession.o \
+ connectionList.o \
+ ../syncSocketHandler.o \
+ ../syncClientSocket.o \
+ ../syncQueue.o \
+ ../syncSocket.o \
+ ../seqWindow.o \
+ ../connectionParam.o \
+ ../routingTable.o \
+ ../syncBuffer.o \
+ ../syncCommand.o \
+ ../syncRouteCommand.o \
+ ../syncRtpCommand.o \
+ ../syncConnectionCommand.o \
+ ../networkAddress.o \
+ ../networkPrefix.o \
+ ../Sockets/libSockets.a \
+ commandHandler.o \
+ portWindow.o \
+ callIdQueue.o \
+ options.o
+
+EXECUTABLE = anyrtpproxy
+
+all: $(EXECUTABLE)
+
+anyrtpproxy: $(OBJS)
+ $(LD) $(OBJS) -o $@ $(LDFLAGS)
+
+options.o: options.cpp options.h
+ $(C++) $(CCFLAGS) $< -c
+
+portWindow.o: portWindow.cpp portWindow.h
+ $(C++) $(CCFLAGS) $< -c
+
+connectionList.o: connectionList.cpp connectionList.h
+ $(C++) $(CCFLAGS) $< -c
+
+commandHandler.o: commandHandler.cpp commandHandler.h
+ $(C++) $(CCFLAGS) $< -c
+
+callIdQueue.o: callIdQueue.cpp callIdQueue.h
+ $(C++) $(CCFLAGS) $< -c
+
+anyrtpproxy.o: anyrtpproxy.cpp
+ $(C++) $(CCFLAGS) $< -c
+
+clean:
+ rm -f *.o
+ rm -f $(EXECUTABLE)
+
diff --git a/src/anyrtpproxy/anyrtpproxy.cpp b/src/anyrtpproxy/anyrtpproxy.cpp
new file mode 100644
index 0000000..d29e4d4
--- /dev/null
+++ b/src/anyrtpproxy/anyrtpproxy.cpp
@@ -0,0 +1,372 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <iostream>
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "../datatypes.h"
+
+#include "../log.h"
+#include "../signalController.h"
+#include "../PracticalSocket.h"
+#include "../buffer.h"
+#include "connectionList.h"
+#include "../rtpSessionTable.h"
+#include "../syncCommand.h"
+#include "../syncQueue.h"
+#include "../syncSocketHandler.h"
+#include "../syncListenSocket.h"
+
+#include "../syncSocket.h"
+#include "../syncClientSocket.h"
+#include "../threadUtils.hpp"
+
+#include "commandHandler.h"
+#include "callIdQueue.h"
+
+#include "options.h"
+#include "portWindow.h"
+#include <map>
+
+
+#define MAX_PACKET_SIZE 1500
+
+
+class ThreadParam
+{
+public:
+ ThreadParam(SyncQueue & queue_,OptionConnectTo & connto_)
+ : queue(queue_),connto(connto_)
+ {};
+ SyncQueue & queue;
+ OptionConnectTo & connto;
+};
+
+class ListenerThreadParam
+{
+public:
+ ListenerThreadParam(UDPSocket& s1, UDPSocket& s2, std::string c, int d, SyncQueue& q) : sock1_(s1), sock2_(s2), call_id_(c),
+ dir_(d), running_(true), queue_(q)
+ {};
+
+ UDPSocket& sock1_;
+ UDPSocket& sock2_;
+ std::string call_id_;
+ int dir_;
+ bool running_;
+ SyncQueue& queue_;
+};
+
+void* listener(void* p)
+{
+ ListenerThreadParam* param = reinterpret_cast<ListenerThreadParam*>(p);
+
+ cLog.msg(Log::PRIO_NOTICE) << "listener(" << param->call_id_ << "/" << param->dir_ << ") started";
+
+ try
+ {
+ Buffer buf(u_int32_t(MAX_PACKET_SIZE));
+ string remote_addr;
+ u_int16_t remote_port;
+ while(1) {
+ buf.setLength(MAX_PACKET_SIZE);
+ u_int32_t len=0;
+ if(param->dir_ == 1)
+ len = param->sock1_.recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_addr, remote_port, 1000);
+ else if(param->dir_ == 2)
+ len = param->sock2_.recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_addr, remote_port, 1000);
+ else break;
+
+ RtpSession& session = gRtpSessionTable.getSession(param->call_id_);
+ if(session.isDead()) {
+ cLog.msg(Log::PRIO_NOTICE) << "listener(" << param->call_id_ << "/" << param->dir_ << ") session is dead, exiting";
+ break;
+ }
+
+ if(!len)
+ continue;
+ buf.setLength(len);
+
+ if((param->dir_ == 1 && (remote_port != session.getRemotePort1() || remote_addr != session.getRemoteAddr1())) ||
+ (param->dir_ == 2 && (remote_port != session.getRemotePort2() || remote_addr != session.getRemoteAddr2())))
+ {
+ if(gOpt.getNat() ||
+ (!gOpt.getNoNatOnce() && ((param->dir_ == 1 && !session.getSeen1()) ||
+ (param->dir_ == 2 && !session.getSeen2()))))
+ {
+ cLog.msg(Log::PRIO_NOTICE) << "listener(" << param->call_id_ << "/" << param->dir_ << ") setting remote host to "
+ << remote_addr << ":" << remote_port;
+ if(param->dir_ == 1) {
+ session.setRemotePort1(remote_port);
+ session.setRemoteAddr1(remote_addr);
+ }
+ if(param->dir_ == 2) {
+ session.setRemotePort2(remote_port);
+ session.setRemoteAddr2(remote_addr);
+ }
+
+ if(!gOpt.getNat()) { // with nat enabled sync is not needed
+ SyncCommand sc(param->call_id_);
+ param->queue_.push(sc);
+ }
+ }
+ else
+ continue;
+ }
+ session.setSeen1();
+ session.setSeen2();
+
+ if(param->dir_ == 1)
+ param->sock2_.sendTo(buf.getBuf(), buf.getLength(), session.getRemoteAddr2(), session.getRemotePort2());
+ else if(param->dir_ == 2)
+ param->sock1_.sendTo(buf.getBuf(), buf.getLength(), session.getRemoteAddr1(), session.getRemotePort1());
+ else break;
+ }
+ }
+ catch(std::exception &e)
+ {
+ cLog.msg(Log::PRIO_ERR) << "listener(" << param->call_id_ << "/" << param->dir_ << ") exiting because: " << e.what();
+ }
+ param->running_ = false;
+ gCallIdQueue.push(param->call_id_);
+ pthread_exit(NULL);
+}
+
+class ListenerData
+{
+public:
+ ListenerData(ListenerThreadParam lp1, ListenerThreadParam lp2) : param1_(lp1), param2_(lp2)
+ {};
+
+ UDPSocket* sock1_;
+ UDPSocket* sock2_;
+ pthread_t thread1_;
+ pthread_t thread2_;
+ ListenerThreadParam param1_;
+ ListenerThreadParam param2_;
+};
+
+void* listenerManager(void* p)
+{
+ SyncQueue* queue_ = reinterpret_cast<SyncQueue*>(p);
+
+ std::map<std::string, ListenerData*> listenerMap;
+ while(1)
+ {
+ try
+ {
+ std::string call_id = gCallIdQueue.front(); // waits for semaphor and returns next call_id
+ gCallIdQueue.pop();
+
+ RtpSession& session = gRtpSessionTable.getSession(call_id);
+ if(!session.isComplete())
+ continue;
+
+ std::map<std::string, ListenerData*>::iterator it;
+ it = listenerMap.find(call_id);
+ if(it == listenerMap.end()) // listener Threads not existing yet
+ {
+ UDPSocket* sock1 = new UDPSocket(session.getLocalAddr(), session.getLocalPort1());
+ UDPSocket* sock2 = new UDPSocket(session.getLocalAddr(), session.getLocalPort2());
+
+ ListenerData* ld = new ListenerData(ListenerThreadParam(*sock1, *sock2, call_id, 1, *queue_),
+ ListenerThreadParam(*sock1, *sock2, call_id, 2, *queue_));
+ ld->sock1_ = sock1;
+ ld->sock2_ = sock2;
+ pthread_create(&(ld->thread1_), NULL, listener, &(ld->param1_));
+ pthread_create(&(ld->thread2_), NULL, listener, &(ld->param2_));
+
+ std::pair<std::map<std::string, ListenerData*>::iterator, bool> ret;
+ ret = listenerMap.insert(std::map<std::string, ListenerData*>::value_type(call_id, ld));
+ continue;
+ }
+
+ if(!it->second->param1_.running_ && !it->second->param2_.running_)
+ {
+ cLog.msg(Log::PRIO_NOTICE) << "listenerManager both threads for '" << call_id << "' exited, cleaning up";
+ pthread_join(it->second->thread1_, NULL);
+ pthread_join(it->second->thread2_, NULL);
+ delete it->second->sock1_;
+ delete it->second->sock2_;
+ delete it->second;
+ listenerMap.erase(it);
+ gRtpSessionTable.delSession(call_id);
+ continue;
+ }
+ // TODO: reinit if session changed
+ }
+ catch(std::exception &e)
+ {
+ cLog.msg(Log::PRIO_ERR) << "listenerManager restarting after exception: " << e.what();
+ usleep(500); // in case of an hard error don't block cpu (this is ugly)
+ }
+ }
+ cLog.msg(Log::PRIO_ERR) << "listenerManager exiting because of unknown reason";
+ pthread_exit(NULL);
+}
+
+void chrootAndDrop(string const& chrootdir, string const& username)
+{
+ if (getuid() != 0)
+ {
+ std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl;
+ exit(-1);
+ }
+
+ struct passwd *pw = getpwnam(username.c_str());
+ if(pw) {
+ if(chroot(chrootdir.c_str()))
+ {
+ std::cerr << "can't chroot to " << chrootdir << std::endl;
+ exit(-1);
+ }
+ std::cout << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
+ chdir("/");
+ if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid))
+ {
+ std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+ exit(-1);
+ }
+ std::cout << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+ }
+ else
+ {
+ std::cerr << "unknown user " << username << std::endl;
+ exit(-1);
+ }
+}
+
+void daemonize()
+{
+ pid_t pid;
+
+ pid = fork();
+ if(pid) exit(0);
+ setsid();
+ pid = fork();
+ if(pid) exit(0);
+
+ std::cout << "running in background now..." << std::endl;
+
+ int fd;
+ for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
+ close(fd);
+ fd=open("/dev/null",O_RDWR); // stdin
+ dup(fd); // stdout
+ dup(fd); // stderr
+ umask(027);
+}
+
+void* syncConnector(void* p )
+{
+ ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
+
+ SocketHandler h;
+ ConnectionList cl;
+ SyncClientSocket sock(h,cl);
+ sock.Open( param->connto.host, param->connto.port);
+ h.Add(&sock);
+ while (h.GetCount())
+ {
+ h.Select();
+ }
+ pthread_exit(NULL);
+}
+
+void* syncListener(void* p )
+{
+ ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
+ ConnectionList cl;
+
+ SyncSocketHandler h(param->queue);
+ SyncListenSocket<SyncSocket,ConnectionList> l(h,cl);
+
+ if (l.Bind(gOpt.getLocalSyncPort()))
+ pthread_exit(NULL);
+
+ Utility::ResolveLocal(); // resolve local hostname
+ h.Add(&l);
+ h.Select(1,0);
+ while (1) {
+ h.Select(1,0);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ std::cout << "anyrtpproxy" << std::endl;
+ if(!gOpt.parse(argc, argv))
+ {
+ gOpt.printUsage();
+ exit(-1);
+ }
+
+ if(gOpt.getChroot())
+ chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
+ if(gOpt.getDaemonize())
+ daemonize();
+
+ cLog.setLogName("anyrtpproxy");
+ cLog.msg(Log::PRIO_NOTICE) << "anyrtpproxy started...";
+
+ SignalController sig;
+ sig.init();
+
+ SyncQueue queue;
+
+ pthread_t listenerManagerThread;
+ pthread_create(&listenerManagerThread, NULL, listenerManager, &queue);
+ pthread_detach(listenerManagerThread);
+
+ pthread_t syncListenerThread;
+
+ ConnectToList connect_to = gOpt.getConnectTo();
+ ThreadParam p( queue,*(new OptionConnectTo()));
+ if ( gOpt.getLocalSyncPort())
+ pthread_create(&syncListenerThread, NULL, syncListener, &p);
+
+ std::list<pthread_t> connectThreads;
+ for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it)
+ {
+ connectThreads.push_back(pthread_t());
+ ThreadParam * point = new ThreadParam(queue,*it);
+ pthread_create(& connectThreads.back(), NULL, syncConnector, point);
+ }
+
+ PortWindow port_window(gOpt.getRtpStartPort(),gOpt.getRtpEndPort());
+ CommandHandler cmd(queue, gOpt.getControlInterface().addr_, gOpt.getControlInterface().port_,port_window);
+
+ int ret = sig.run();
+ return ret;
+}
+
diff --git a/src/anyrtpproxy/callIdQueue.cpp b/src/anyrtpproxy/callIdQueue.cpp
new file mode 100644
index 0000000..bc90f08
--- /dev/null
+++ b/src/anyrtpproxy/callIdQueue.cpp
@@ -0,0 +1,76 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "callIdQueue.h"
+
+CallIdQueue* CallIdQueue::inst = NULL;
+Mutex CallIdQueue::instMutex;
+CallIdQueue& gCallIdQueue = CallIdQueue::instance();
+
+CallIdQueue& CallIdQueue::instance()
+{
+ Lock lock(instMutex);
+ static instanceCleaner c;
+ if(!inst)
+ inst = new CallIdQueue();
+
+ return *inst;
+}
+
+CallIdQueue::CallIdQueue()
+{
+}
+
+CallIdQueue::~CallIdQueue()
+{
+ while(!callids_.empty())
+ pop();
+}
+
+std::string& CallIdQueue::front()
+{
+ sem_.down();
+ Lock lock(mutex_);
+ return callids_.front();
+}
+
+void CallIdQueue::push(std::string c)
+{
+ Lock lock(mutex_);
+ callids_.push(c);
+ sem_.up();
+}
+
+void CallIdQueue::pop()
+{
+ Lock lock(mutex_);
+ callids_.pop();
+}
+
diff --git a/src/anyrtpproxy/callIdQueue.h b/src/anyrtpproxy/callIdQueue.h
new file mode 100644
index 0000000..67e543d
--- /dev/null
+++ b/src/anyrtpproxy/callIdQueue.h
@@ -0,0 +1,72 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __CALLID_QUEUE_H__
+#define __CALLID_QUEUE_H__
+
+#include <queue>
+#include <string>
+
+#include "../threadUtils.hpp"
+
+class CallIdQueue
+{
+public:
+ static CallIdQueue& instance();
+
+ std::string& front();
+ void push(std::string c);
+ void pop();
+
+private:
+ CallIdQueue();
+ ~CallIdQueue();
+
+ void operator=(const CallIdQueue &src);
+ CallIdQueue(const CallIdQueue &src);
+
+ static CallIdQueue* inst;
+ static ::Mutex instMutex;
+ class instanceCleaner {
+ public: ~instanceCleaner() {
+ if(CallIdQueue::inst != 0)
+ delete CallIdQueue::inst;
+ }
+ };
+ friend class instanceCleaner;
+
+ ::Mutex mutex_;
+ Semaphore sem_;
+ std::queue<std::string> callids_;
+};
+
+extern CallIdQueue& gCallIdQueue;
+
+#endif
diff --git a/src/anyrtpproxy/commandHandler.cpp b/src/anyrtpproxy/commandHandler.cpp
new file mode 100644
index 0000000..032d001
--- /dev/null
+++ b/src/anyrtpproxy/commandHandler.cpp
@@ -0,0 +1,268 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sstream>
+#include <vector>
+
+#include <iomanip>
+#include <iostream>
+
+#include "commandHandler.h"
+#include "../buffer.h"
+#include "../log.h"
+#include "../syncQueue.h"
+#include "../syncCommand.h"
+#include "../rtpSessionTable.h"
+#include "callIdQueue.h"
+
+#define MAX_COMMAND_LENGTH 1000
+
+CommandHandler::CommandHandler(SyncQueue& q, u_int16_t lp,PortWindow & pw) : queue_(q), running_(true), control_sock_(lp),
+ local_address_("0.0.0.0"), local_port_(lp),port_window_(pw)
+{
+ pthread_create(&thread_, NULL, run, this);
+}
+
+CommandHandler::CommandHandler(SyncQueue& q, string la, u_int16_t lp,PortWindow & pw) : queue_(q), running_(true), control_sock_(la, lp),
+ local_address_(la), local_port_(lp),port_window_(pw)
+{
+ pthread_create(&thread_, NULL, run, this);
+}
+
+CommandHandler::~CommandHandler()
+{
+ pthread_cancel(thread_);
+ pthread_join(thread_, NULL);
+}
+
+void* CommandHandler::run(void* s)
+{
+ CommandHandler* self = reinterpret_cast<CommandHandler*>(s);
+
+ Buffer buf(u_int32_t(MAX_COMMAND_LENGTH));
+ try
+ {
+ string remote_host;
+ u_int16_t remote_port;
+
+ int len;
+ while(1)
+ {
+ buf.setLength(MAX_COMMAND_LENGTH);
+ len = self->control_sock_.recvFrom(buf.getBuf(), buf.getLength(), remote_host, remote_port);
+ buf.setLength(len);
+
+ std::string ret = self->handle(std::string(reinterpret_cast<char*>(buf.getBuf()), buf.getLength())); // TODO: reinterpret is ugly
+
+ cLog.msg(Log::PRIO_DEBUG) << "CommandHandler received Command from " << remote_host << ":" << remote_port
+ << ", ret='" << ret << "'";
+
+ self->control_sock_.sendTo(ret.c_str(), ret.length(), remote_host, remote_port);
+ }
+ }
+ catch(SocketException &e)
+ {
+ self->running_ = false;
+ pthread_exit(NULL);
+ }
+ self->running_ = false;
+ pthread_exit(NULL);
+}
+
+bool CommandHandler::isRunning()
+{
+ return running_;
+}
+
+
+
+std::string CommandHandler::handle(std::string command)
+{
+ istringstream iss(command);
+ ostringstream oss;
+ std::string cookie;
+ std::string cmd;
+
+ iss >> cookie;
+ oss << cookie << " ";
+
+ if(iss.bad() || iss.eof()) {
+ oss << RET_ERR_SYNTAX;
+ return oss.str();
+ }
+ iss >> cmd;
+
+ std::vector<std::string> params;
+ while(!iss.bad() && !iss.eof()) {
+ std::string tmp;
+ iss >> tmp;
+ params.push_back(tmp);
+ }
+
+ switch(std::toupper(cmd[0]))
+ {
+ case CMD_REQUEST:
+ if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; }
+ oss << handleRequest(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]);
+ break;
+ case CMD_RESPONSE:
+ if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; }
+ oss << handleResponse(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]);
+ break;
+ case CMD_DELETE:
+ if(params.size() < 2) { oss << RET_ERR_SYNTAX; break; }
+ oss << handleDelete(params[0], params[1], (params.size() < 3) ? "" : params[2]);
+ break;
+ case CMD_VERSION:
+ if(cmd.length() > 1 && cmd[1] == 'F') {
+ if(params.size() < 1) { oss << RET_ERR_SYNTAX; break; }
+ oss << handleVersionF(params[0]);
+ break;
+ }
+ oss << handleVersion();
+ break;
+ case CMD_INFO:
+ oss << handleInfo();
+ break;
+ default:
+ oss << RET_ERR_SYNTAX;
+ break;
+ }
+
+ return oss.str();
+}
+
+string CommandHandler::handleRequest(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag)
+{
+ std::cout << "received request[" << modifiers << "] command ('" << call_id << "','" << addr << "','" << port
+ << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+ try
+ {
+ bool is_new;
+ RtpSession& session = gRtpSessionTable.getOrNewSession(call_id, is_new);
+ if(is_new)
+ {
+ u_int16_t port1 = port_window_.newPort(); // TODO: get next available port
+ u_int16_t port2 = port_window_.newPort(); // TODO: get next available port
+ if( !port1 || !port2)
+ {
+ if( port1) port_window_.freePort(port1);
+ if( port2) port_window_.freePort(port2);
+ throw std::runtime_error("no free port found");
+ }
+
+ session.setLocalAddr("0.0.0.0"); // TODO: read this from config
+ session.setLocalPort1(port1);
+ session.setLocalPort2(port2);
+ }
+ istringstream iss(port);
+ u_int16_t rport;
+ iss >> rport;
+ session.setRemotePort1(rport);
+ session.setRemoteAddr1(addr);
+
+ ostringstream oss;
+ oss << session.getLocalPort2();
+ return oss.str();
+ }
+ catch(std::exception& e)
+ {
+ return RET_ERR_UNKNOWN; // TODO: change to corret error value
+ }
+}
+
+string CommandHandler::handleResponse(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag)
+{
+ std::cout << "received response[" << modifiers << "] command ('" << call_id << "','" << addr << "','" << port
+ << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+ try
+ {
+ RtpSession& session = gRtpSessionTable.getSession(call_id);
+ istringstream iss(port);
+ u_int16_t rport;
+ iss >> rport;
+ session.setRemotePort2(rport);
+ session.setRemoteAddr2(addr);
+ session.isComplete(true);
+ SyncCommand sc(call_id);
+ queue_.push(sc);
+
+ ostringstream oss;
+ oss << session.getLocalPort1();
+ return oss.str();
+ }
+ catch(std::exception& e)
+ {
+ return RET_ERR_UNKNOWN; // TODO: change to corret error value
+ }
+}
+
+string CommandHandler::handleDelete(string call_id, string from_tag, string to_tag)
+{
+ std::cout << "received delete command ('" << call_id << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+ try
+ {
+ RtpSession& session = gRtpSessionTable.getSession(call_id);
+ session.isDead(true);
+ SyncCommand sc(call_id);
+ queue_.push(sc);
+
+ return RET_OK;
+ }
+ catch(std::exception& e)
+ {
+ return RET_ERR_UNKNOWN; // TODO: change to corret error value
+ }
+}
+
+string CommandHandler::handleVersion()
+{
+ std::cout << "received version command" << std::endl;
+ return BASE_VERSION;
+}
+
+string CommandHandler::handleVersionF(string date_code)
+{
+ std::cout << "received version[F] command ('" << date_code << "')" << std::endl;
+ if(!date_code.compare(SUP_VERSION))
+ return "1";
+
+ return "0";
+}
+
+string CommandHandler::handleInfo()
+{
+ std::cout << "received info command, ignoring" << std::endl;
+ return RET_OK;
+}
+
diff --git a/src/anyrtpproxy/commandHandler.h b/src/anyrtpproxy/commandHandler.h
new file mode 100644
index 0000000..97082ca
--- /dev/null
+++ b/src/anyrtpproxy/commandHandler.h
@@ -0,0 +1,89 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _COMMAND_HANDLER_H_
+#define _COMMAND_HANDLER_H_
+
+#include <string>
+#include "../datatypes.h"
+#include "../PracticalSocket.h"
+#include "../syncQueue.h"
+#include "portWindow.h"
+
+using std::string;
+
+class CommandHandler
+{
+public:
+ CommandHandler(SyncQueue& q, u_int16_t lp, PortWindow &);
+ CommandHandler(SyncQueue& q, string la, u_int16_t lp, PortWindow &);
+ ~CommandHandler();
+
+ bool isRunning();
+
+ #define CMD_REQUEST 'U'
+ #define CMD_RESPONSE 'L'
+ #define CMD_DELETE 'D'
+ #define CMD_VERSION 'V'
+ #define CMD_INFO 'I'
+
+ #define RET_OK "0"
+ #define RET_ERR_SYNTAX "E1"
+ #define RET_ERR_UNKNOWN "E2"
+
+ #define BASE_VERSION "20040107"
+ #define SUP_VERSION "20050322"
+
+private:
+ CommandHandler(const CommandHandler &c);
+ void operator=(const CommandHandler &c);
+
+ static void* run(void* s);
+ string handle(string command);
+
+ string handleRequest(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag);
+ string handleResponse(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag);
+ string handleDelete(string call_id, string from_tag, string to_tag);
+ string handleVersion();
+ string handleVersionF(string date_code);
+ string handleInfo();
+
+ pthread_t thread_;
+ SyncQueue& queue_;
+
+ bool running_;
+ UDPSocket control_sock_;
+ string local_address_;
+ u_int16_t local_port_;
+ PortWindow& port_window_;
+};
+
+
+#endif
diff --git a/src/anyrtpproxy/connectionList.cpp b/src/anyrtpproxy/connectionList.cpp
new file mode 100644
index 0000000..c8bbfa7
--- /dev/null
+++ b/src/anyrtpproxy/connectionList.cpp
@@ -0,0 +1,89 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "connectionList.h"
+
+ConnectionList::ConnectionList()
+{
+}
+
+ConnectionList::~ConnectionList()
+{
+}
+
+void ConnectionList::addConnection(ConnectionParam &conn, u_int16_t mux )
+{
+}
+
+const ConnectionMap::iterator ConnectionList::getEnd()
+{
+ return connections_.end();
+}
+
+ConnectionMap::iterator ConnectionList::getBeginUnlocked()
+{
+ return connections_.begin();
+}
+
+ConnectionMap::iterator ConnectionList::getEndUnlocked()
+{
+ return connections_.end();
+}
+
+const ConnectionMap::iterator ConnectionList::getConnection(u_int16_t mux)
+{
+ Lock lock(mutex_);
+ ConnectionMap::iterator it = connections_.find(mux);
+ return it;
+}
+
+
+ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux)
+{
+ ConnectionMap::iterator it = connections_.find(mux);
+ return it->second;
+}
+
+void ConnectionList::clear()
+{
+ Lock lock(mutex_);
+ connections_.clear();
+}
+
+bool ConnectionList::empty()
+{
+ Lock lock(mutex_);
+ return connections_.empty();
+}
+
+Mutex& ConnectionList::getMutex()
+{
+ return mutex_;
+}
diff --git a/src/anyrtpproxy/connectionList.h b/src/anyrtpproxy/connectionList.h
new file mode 100644
index 0000000..6b02b22
--- /dev/null
+++ b/src/anyrtpproxy/connectionList.h
@@ -0,0 +1,64 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CONNECTION_LIST_H
+#define _CONNECTION_LIST_H
+
+#include <map>
+
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+#include "../connectionParam.h"
+#include "../networkAddress.h"
+typedef std::map<u_int16_t, ConnectionParam> ConnectionMap;
+
+class ConnectionList
+{
+public:
+ ConnectionList();
+ ~ConnectionList();
+ void addConnection(ConnectionParam &conn, u_int16_t mux);
+ const ConnectionMap::iterator getConnection(u_int16_t mux);
+ const ConnectionMap::iterator getEnd();
+ ConnectionMap::iterator getEndUnlocked();
+ ConnectionMap::iterator getBeginUnlocked();
+ ConnectionParam & getOrNewConnectionUnlocked(u_int16_t mux);
+ bool empty();
+ void clear();
+ Mutex& getMutex();
+
+private:
+ ConnectionList(const ConnectionList &s);
+ void operator=(const ConnectionList &s);
+ ConnectionMap connections_;
+ Mutex mutex_;
+};
+
+#endif
diff --git a/src/anyrtpproxy/options.cpp b/src/anyrtpproxy/options.cpp
new file mode 100644
index 0000000..bdddf75
--- /dev/null
+++ b/src/anyrtpproxy/options.cpp
@@ -0,0 +1,308 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <iostream>
+#include <queue>
+#include <string>
+#include <sstream>
+
+#include "options.h"
+
+Options* Options::inst = NULL;
+Mutex Options::instMutex;
+Options& gOpt = Options::instance();
+
+Options& Options::instance()
+{
+ Lock lock(instMutex);
+ static instanceCleaner c;
+ if(!inst)
+ inst = new Options();
+
+ return *inst;
+}
+
+Options::Options() : control_interface_("0.0.0.0", 22222)
+
+{
+ progname_ = "anyrtpproxy";
+ chroot_ = false;
+ username_ = "nobody";
+ chroot_dir_ = "/var/run";
+ daemonize_ = true;
+ local_sync_port_ = 0;
+ rtp_start_port_ = 34000;
+ rtp_end_port_ = 35000;
+ no_nat_once_ = false;
+ nat_ = false;
+}
+
+Options::~Options()
+{
+}
+
+#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
+ else if(str == SHORT || str == LONG) \
+ VALUE = true;
+
+#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
+ else if(str == SHORT || str == LONG) \
+ VALUE = false;
+
+#define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE) \
+ else if(str == SHORT || str == LONG) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return false; \
+ std::stringstream tmp; \
+ tmp << argv[i+1]; \
+ tmp >> VALUE; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2) \
+ else if(str == SHORT || str == LONG) \
+ { \
+ if(argc < 2 || \
+ argv[i+1][0] == '-' || argv[i+2][0] == '-') \
+ return false; \
+ std::stringstream tmp; \
+ tmp << argv[i+1] << " " << argv[i+2]; \
+ tmp >> VALUE1; \
+ tmp >> VALUE2; \
+ argc-=2; \
+ i+=2; \
+ }
+
+#define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \
+ else if(str == SHORT || str == LONG) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return false; \
+ VALUE = std::string(argv[i+1]); \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \
+ else if(str == SHORT || str == LONG) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return false; \
+ VALUE = Buffer(std::string(argv[i+1])); \
+ for(size_t j=0; j < strlen(argv[i+1]); ++j) \
+ argv[i+1][j] = '#'; \
+ argc--; \
+ i++; \
+ }
+
+#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST) \
+ else if(str == SHORT || str == LONG) \
+ { \
+ if(argc < 1 || argv[i+1][0] == '-') \
+ return false; \
+ std::stringstream tmp(argv[i+1]); \
+ /* LIST.clear(); */ \
+ while (tmp.good()) \
+ { \
+ std::string tmp_line; \
+ getline(tmp,tmp_line,','); \
+ LIST.push(tmp_line); \
+ } \
+ argc--; \
+ i++; \
+ }
+
+bool Options::parse(int argc, char* argv[])
+{
+ Lock lock(mutex);
+
+ progname_ = argv[0];
+ std::queue<std::string> host_port_queue;
+ argc--;
+ for(int i=1; argc > 0; ++i)
+ {
+ std::string str(argv[i]);
+ argc--;
+
+ if(str == "-h" || str == "--help")
+ return false;
+ PARSE_BOOL_PARAM("-t","--chroot", chroot_)
+ PARSE_BOOL_PARAM("-n","--nat", nat_)
+ PARSE_BOOL_PARAM("-o","--no-nat-once", no_nat_once_)
+ PARSE_SCALAR_PARAM("-u","--user", username_)
+ PARSE_SCALAR_PARAM("-c","--chroot-dir", chroot_dir_)
+ PARSE_INVERSE_BOOL_PARAM("-d","--nodaemonize", daemonize_)
+ PARSE_STRING_PARAM("-s","--control", control_interface_)
+ PARSE_SCALAR_PARAM2("-p","--port-range", rtp_start_port_, rtp_end_port_)
+ PARSE_CSLIST_PARAM("-M","--sync-hosts", host_port_queue)
+ PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_port_)
+// PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_addr_)
+ else
+ return false;
+ }
+ while(!host_port_queue.empty())
+ {
+ std::stringstream tmp_stream(host_port_queue.front());
+ OptionConnectTo oct;
+ getline(tmp_stream,oct.host,':');
+ if(!tmp_stream.good())
+ return false;
+ tmp_stream >> oct.port;
+ host_port_queue.pop();
+ connect_to_.push_back(oct);
+ }
+
+ return sanityCheck();
+}
+
+bool Options::sanityCheck()
+{
+ if(!control_interface_.port_) control_interface_.port_ = 22220;
+ return true;
+}
+
+void Options::printUsage()
+{
+ std::cout << "USAGE: anyrtpproxy" << std::endl;
+ std::cout << " [-h|--help] prints this..." << std::endl;
+ std::cout << " [-t|--chroot] chroot and drop priviledges" << std::endl;
+ std::cout << " [-u|--username] <username> in case of chroot run as this user" << std::endl;
+ std::cout << " [-c|--chroot-dir] <directory> directory to make a chroot to" << std::endl;
+ std::cout << " [-d|--nodaemonize] don't run in background" << std::endl;
+ std::cout << " [-s|--control] <addr[:port]> the address/port to listen on for control commands" << std::endl;
+ std::cout << " [-p|--port-range] <start> <end> port range used to relay rtp connections" << std::endl;
+ std::cout << " [-n|--nat] enable permantent automatic nat detection(use only with anytun)" << std::endl;
+ std::cout << " [-o|--no-nat-once] disable automatic nat detection for new connections" << std::endl;
+// std::cout << " [-I|--sync-interface] <ip-address> local unicast(sync) ip address to bind to" << std::endl;
+ std::cout << " [-S|--sync-port] <port> local unicast(sync) port to bind to" << std::endl;
+ std::cout << " [-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]"<< std::endl;
+ std::cout << " List of Remote Sync Hosts/Ports"<< std::endl;
+}
+
+void Options::printOptions()
+{
+ Lock lock(mutex);
+ std::cout << "Options:" << std::endl;
+ std::cout << "chroot='" << chroot_ << "'" << std::endl;
+ std::cout << "username='" << username_ << "'" << std::endl;
+ std::cout << "chroot-dir='" << chroot_dir_ << "'" << std::endl;
+ std::cout << "daemonize='" << daemonize_ << "'" << std::endl;
+ std::cout << "control-interface='" << control_interface_.toString() << "'" << std::endl;
+}
+
+std::string Options::getProgname()
+{
+ Lock lock(mutex);
+ return progname_;
+}
+
+bool Options::getChroot()
+{
+ Lock lock(mutex);
+ return chroot_;
+}
+
+bool Options::getNat()
+{
+ Lock lock(mutex);
+ return nat_;
+}
+
+bool Options::getNoNatOnce()
+{
+ Lock lock(mutex);
+ return no_nat_once_;
+}
+
+std::string Options::getUsername()
+{
+ Lock lock(mutex);
+ return username_;
+}
+
+std::string Options::getChrootDir()
+{
+ Lock lock(mutex);
+ return chroot_dir_;
+}
+
+bool Options::getDaemonize()
+{
+ Lock lock(mutex);
+ return daemonize_;
+}
+
+Host Options::getControlInterface()
+{
+ Lock lock(mutex);
+ return control_interface_;
+}
+
+u_int16_t Options::getLocalSyncPort()
+{
+ return local_sync_port_;
+}
+
+Options& Options::setLocalSyncPort(u_int16_t l)
+{
+ local_sync_port_ = l;
+ return *this;
+}
+
+u_int16_t Options::getRtpStartPort()
+{
+ return rtp_start_port_;
+}
+
+Options& Options::setRtpStartPort(u_int16_t l)
+{
+ rtp_start_port_ = l;
+ return *this;
+}
+
+u_int16_t Options::getRtpEndPort()
+{
+ return rtp_end_port_;
+}
+
+Options& Options::setRtpEndPort(u_int16_t l)
+{
+ rtp_end_port_ = l;
+ return *this;
+}
+
+ConnectToList Options::getConnectTo()
+{
+ Lock lock(mutex);
+ return connect_to_;
+}
+
diff --git a/src/anyrtpproxy/options.h b/src/anyrtpproxy/options.h
new file mode 100644
index 0000000..b6ac957
--- /dev/null
+++ b/src/anyrtpproxy/options.h
@@ -0,0 +1,129 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _OPTIONS_H_
+#define _OPTIONS_H_
+
+#include "../threadUtils.hpp"
+#include <list>
+#include <sstream>
+
+typedef struct OptionConnectTo
+{
+ std::string host;
+ uint16_t port;
+};
+
+typedef std::list<OptionConnectTo> ConnectToList;
+
+class Host
+{
+public:
+ Host(std::string addr, u_int16_t port) : addr_(addr), port_(port) {}
+ Host(std::string addr_port)
+ {
+ std::istringstream iss(addr_port);
+ getline(iss, addr_, ':');
+ if(!(iss >> port_)) port_ = 0;
+ }
+ std::string toString() const
+ {
+ std::ostringstream oss;
+ oss << addr_ << ":" << port_;
+ return oss.str();
+ }
+
+ std::string addr_;
+ u_int16_t port_;
+};
+
+typedef std::list<Host> HostList;
+
+class Options
+{
+public:
+ static Options& instance();
+
+ bool parse(int argc, char* argv[]);
+ void printUsage();
+ void printOptions();
+
+ std::string getProgname();
+ bool getChroot();
+ bool getNat();
+ bool getNoNatOnce();
+ std::string getUsername();
+ std::string getChrootDir();
+ bool getDaemonize();
+ Host getControlInterface();
+ u_int16_t getLocalSyncPort();
+ Options& setLocalSyncPort(u_int16_t l);
+ u_int16_t getRtpStartPort();
+ Options& setRtpStartPort(u_int16_t l);
+ u_int16_t getRtpEndPort();
+ Options& setRtpEndPort(u_int16_t l);
+ ConnectToList getConnectTo();
+
+private:
+ Options();
+ ~Options();
+ Options(const Options &l);
+ void operator=(const Options &l);
+ bool sanityCheck();
+
+ static Options* inst;
+ static ::Mutex instMutex;
+ class instanceCleaner {
+ public: ~instanceCleaner() {
+ if(Options::inst != 0)
+ delete Options::inst;
+ }
+ };
+ friend class instanceCleaner;
+
+ ::Mutex mutex;
+
+ std::string progname_;
+ bool chroot_;
+ bool nat_;
+ bool no_nat_once_;
+ std::string username_;
+ std::string chroot_dir_;
+ bool daemonize_;
+ u_int16_t local_sync_port_;
+ u_int16_t rtp_start_port_;
+ u_int16_t rtp_end_port_;
+ ConnectToList connect_to_;
+ Host control_interface_;
+};
+
+extern Options& gOpt;
+
+#endif
diff --git a/src/anyrtpproxy/portWindow.cpp b/src/anyrtpproxy/portWindow.cpp
new file mode 100644
index 0000000..3d96a06
--- /dev/null
+++ b/src/anyrtpproxy/portWindow.cpp
@@ -0,0 +1,85 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "portWindow.h"
+
+PortWindow::PortWindow(u_int16_t start, u_int16_t end) : start_port_(start), end_port_(end)
+{
+}
+
+PortWindow::~PortWindow()
+{
+}
+
+PortWindow::PortSet::size_type PortWindow::getLength()
+{
+ Lock lock(mutex_);
+ return ports_.size();
+}
+
+bool PortWindow::hasPort(u_int16_t port)
+{
+ Lock lock(mutex_);
+
+ PortSet::const_iterator it=ports_.find(port);
+ if(it == ports_.end())
+ return false;
+ return true;
+}
+
+bool PortWindow::freePort(u_int16_t port)
+{
+ Lock lock(mutex_);
+
+ PortSet::iterator it=ports_.find(port);
+ if(it == ports_.end())
+ return false;
+ ports_.erase(it);
+ return true;
+}
+
+u_int16_t PortWindow::newPort()
+{
+ Lock lock(mutex_);
+ u_int16_t port= start_port_;
+ while (port<end_port_ && ports_.find(port) !=ports_.end())
+ port++;
+ if (port>=end_port_)
+ return 0;
+ ports_.insert(port);
+ return port;
+}
+
+void PortWindow::clear()
+{
+ Lock lock(mutex_);
+ ports_.clear();
+}
+
diff --git a/src/anyrtpproxy/portWindow.h b/src/anyrtpproxy/portWindow.h
new file mode 100644
index 0000000..c97e94f
--- /dev/null
+++ b/src/anyrtpproxy/portWindow.h
@@ -0,0 +1,63 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _PORT_WINDOW_H_
+#define _PORT_WINDOW_H_
+
+#include <set>
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+
+class PortWindow
+{
+public:
+ typedef std::set<u_int16_t> PortSet;
+
+ PortWindow(u_int16_t,u_int16_t);
+ ~PortWindow();
+
+ PortSet::size_type getLength();
+ bool hasPort(u_int16_t);
+ bool freePort(u_int16_t);
+ u_int16_t newPort();
+ void clear();
+
+
+private:
+ u_int16_t start_port_;
+ u_int16_t end_port_;
+ ::Mutex mutex_;
+ PortSet ports_;
+
+ PortWindow(const PortWindow &s);
+ void operator=(const PortWindow &s);
+};
+
+#endif