diff options
Diffstat (limited to 'src/anyrtpproxy')
-rw-r--r-- | src/anyrtpproxy/Makefile | 68 | ||||
-rw-r--r-- | src/anyrtpproxy/anyrtpproxy.cpp | 372 | ||||
-rw-r--r-- | src/anyrtpproxy/callIdQueue.cpp | 76 | ||||
-rw-r--r-- | src/anyrtpproxy/callIdQueue.h | 72 | ||||
-rw-r--r-- | src/anyrtpproxy/commandHandler.cpp | 268 | ||||
-rw-r--r-- | src/anyrtpproxy/commandHandler.h | 89 | ||||
-rw-r--r-- | src/anyrtpproxy/connectionList.cpp | 89 | ||||
-rw-r--r-- | src/anyrtpproxy/connectionList.h | 64 | ||||
-rw-r--r-- | src/anyrtpproxy/options.cpp | 308 | ||||
-rw-r--r-- | src/anyrtpproxy/options.h | 129 | ||||
-rw-r--r-- | src/anyrtpproxy/portWindow.cpp | 85 | ||||
-rw-r--r-- | src/anyrtpproxy/portWindow.h | 63 |
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 |