diff options
-rw-r--r-- | anyrtpproxy/anyrtpproxy.cpp | 158 | ||||
-rw-r--r-- | anyrtpproxy/options.cpp | 116 | ||||
-rw-r--r-- | anyrtpproxy/options.h | 43 | ||||
-rw-r--r-- | signalController.cpp | 6 |
4 files changed, 241 insertions, 82 deletions
diff --git a/anyrtpproxy/anyrtpproxy.cpp b/anyrtpproxy/anyrtpproxy.cpp index b5998e2..311dc4f 100644 --- a/anyrtpproxy/anyrtpproxy.cpp +++ b/anyrtpproxy/anyrtpproxy.cpp @@ -1,5 +1,9 @@ #include <iostream> +#include <fcntl.h> +#include <pwd.h> +#include <grp.h> + #include "../datatypes.h" #include "../log.h" @@ -8,93 +12,95 @@ #include "../buffer.h" #include "options.h" +#include <list> #define MAX_PACKET_SIZE 1500 -void* worker(void* dont_use_me) +void* worker(void* l) { + IfListElement* interface = reinterpret_cast<IfListElement*>(l); + try { + UDPSocket recv_sock(interface->host_, interface->port_); + UDPSocket send_sock; + IfList remote_host_list = gOpt.getRemoteHosts(); + + cLog.msg(Log::PRIO_NOTICE) << "worker listening on: " << interface->toString(); - UDPSocket sock("127.0.0.1", 22222); Buffer buf(u_int32_t(MAX_PACKET_SIZE)); - while(1) { string remote_host; u_int16_t remote_port; buf.setLength(MAX_PACKET_SIZE); - u_int32_t len = sock.recvFrom(buf.getBuf(), buf.getLength(), remote_host, remote_port); + u_int32_t len = recv_sock.recvFrom(buf.getBuf(), buf.getLength(), remote_host, remote_port); buf.setLength(len); - std::cout << "Received UDP Packet from: " << remote_host << ":" << remote_port << std::endl; - std::cout << buf.getHexDump() << std::endl; - -// sendTo(buf, len, addr, port); + IfList::const_iterator it = remote_host_list.begin(); + for(;it != remote_host_list.end(); it++) + send_sock.sendTo(buf.getBuf(), buf.getLength(), it->host_, it->port_); } } catch(std::exception &e) { - std::cout << "an error happend: " << e.what() << std::endl; + cLog.msg(Log::PRIO_ERR) << "worker(" << interface->toString() << ") exiting because: " << e.what() << std::endl; } 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; - -// 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); + 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); -// } + 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); +} int main(int argc, char* argv[]) @@ -106,28 +112,28 @@ int main(int argc, char* argv[]) exit(-1); } -// if(gOpt.chroot) -// chrootAndDrop(gOpt.getChrootDir, gOpt.getUsername); -// if(testSetPid(gOpt.pidFilename)) -// { -// std::cout << "exiting..." << std::endl; -// return -1; -// } -// if(gOpt.daemonize) -// daemonize(gOpt.pidFilename); - + 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(); + - pthread_t workerThread; - pthread_create(&workerThread, NULL, worker, NULL); - pthread_detach(workerThread); - + IfList listeners(gOpt.getLocalInterfaces()); + IfList::iterator it = listeners.begin(); + for(;it != listeners.end();++it) + { + pthread_t workerThread; + pthread_create(&workerThread, NULL, worker, static_cast<void*>(&(*it))); + pthread_detach(workerThread); + } int ret = sig.run(); - + return ret; } diff --git a/anyrtpproxy/options.cpp b/anyrtpproxy/options.cpp index 6901a07..6665f3d 100644 --- a/anyrtpproxy/options.cpp +++ b/anyrtpproxy/options.cpp @@ -51,7 +51,13 @@ Options& Options::instance() Options::Options() { - progname_ = "plain_tool"; + progname_ = "anyrtpproxy"; + chroot_ = false; + username_ = "nobody"; + chroot_dir_ = "/var/run"; + daemonize_ = true; + local_interfaces_.push_back(IfListElement("0.0.0.0", 22221)); + remote_hosts_.push_back(IfListElement("127.0.0.1", 22222)); } Options::~Options() @@ -108,11 +114,12 @@ Options::~Options() 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); \ + LIST.push_back(tmp_line); \ } \ argc--; \ i++; \ @@ -131,9 +138,30 @@ bool Options::parse(int argc, char* argv[]) if(str == "-h" || str == "--help") return false; + PARSE_BOOL_PARAM("-t","--chroot", chroot_) + PARSE_SCALAR_PARAM("-u","--user", username_) + PARSE_SCALAR_PARAM("-c","--chroot-dir", chroot_dir_) + PARSE_INVERSE_BOOL_PARAM("-d","--nodaemonize", daemonize_) + PARSE_SCALAR_PARAM("-c","--chroot-dir", chroot_dir_) + PARSE_CSLIST_PARAM("-l","--listen", local_interfaces_) + PARSE_CSLIST_PARAM("-r","--hosts", remote_hosts_) else return false; } + + return sanityCheck(); +} + +bool Options::sanityCheck() +{ + IfList::iterator it=local_interfaces_.begin(); + for(u_int32_t i=0; it != local_interfaces_.end(); ++it, ++i) + if(!it->port_) it->port_ = 22221; + + it=remote_hosts_.begin(); + for(u_int32_t i=0; it != remote_hosts_.end(); ++it, ++i) + if(!it->port_) it->port_ = 22222; + return true; } @@ -148,6 +176,26 @@ 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 << "local interfaces='"; + IfList::const_iterator it=local_interfaces_.begin(); + for(u_int32_t i=0; it != local_interfaces_.end(); ++it, ++i) + { + if(i) std::cout << "','"; + std::cout << it->toString(); + } + std::cout << "'" << std::endl; + std::cout << "remote hosts='"; + it=remote_hosts_.begin(); + for(u_int32_t i=0; it != remote_hosts_.end(); ++it, ++i) + { + if(i) std::cout << "','"; + std::cout << it->toString(); + } + std::cout << "'" << std::endl; } std::string Options::getProgname() @@ -163,3 +211,67 @@ Options& Options::setProgname(std::string p) progname_ = p; return *this; } + +bool Options::getChroot() +{ + Lock lock(mutex); + return chroot_; +} + +Options& Options::setChroot(bool c) +{ + Lock lock(mutex); + chroot_ = c; + return *this; +} + +std::string Options::getUsername() +{ + Lock lock(mutex); + return username_; +} + +Options& Options::setUsername(std::string u) +{ + Lock lock(mutex); + username_ = u; + return *this; +} + +std::string Options::getChrootDir() +{ + Lock lock(mutex); + return chroot_dir_; +} + +Options& Options::setChrootDir(std::string c) +{ + Lock lock(mutex); + chroot_dir_ = c; + return *this; +} + +bool Options::getDaemonize() +{ + Lock lock(mutex); + return daemonize_; +} + +Options& Options::setDaemonize(bool d) +{ + Lock lock(mutex); + daemonize_ = d; + return *this; +} + +IfList Options::getLocalInterfaces() +{ + Lock lock(mutex); + return local_interfaces_; +} + +IfList Options::getRemoteHosts() +{ + Lock lock(mutex); + return remote_hosts_; +} diff --git a/anyrtpproxy/options.h b/anyrtpproxy/options.h index f4aeb5d..48df36a 100644 --- a/anyrtpproxy/options.h +++ b/anyrtpproxy/options.h @@ -32,6 +32,31 @@ #define _OPTIONS_H_ #include "../threadUtils.hpp" +#include <list> +#include <sstream> + +class IfListElement +{ +public: + IfListElement(std::string host, u_int16_t port) : host_(host), port_(port) {} + IfListElement(std::string host_port) + { + std::istringstream iss(host_port); + getline(iss, host_, ':'); + if(!(iss >> port_)) port_ = 0; + } + std::string toString() const + { + std::ostringstream oss; + oss << host_ << ":" << port_; + return oss.str(); + } + + std::string host_; + u_int16_t port_; +}; + +typedef std::list<IfListElement> IfList; class Options { @@ -44,13 +69,23 @@ public: std::string getProgname(); Options& setProgname(std::string p); - + bool getChroot(); + Options& setChroot(bool c); + std::string getUsername(); + Options& setUsername(std::string u); + std::string getChrootDir(); + Options& setChrootDir(std::string c); + bool getDaemonize(); + Options& setDaemonize(bool d); + IfList getLocalInterfaces(); + IfList getRemoteHosts(); private: Options(); ~Options(); Options(const Options &l); void operator=(const Options &l); + bool sanityCheck(); static Options* inst; static Mutex instMutex; @@ -65,6 +100,12 @@ private: Mutex mutex; std::string progname_; + bool chroot_; + std::string username_; + std::string chroot_dir_; + bool daemonize_; + IfList local_interfaces_; + IfList remote_hosts_; }; extern Options& gOpt; diff --git a/signalController.cpp b/signalController.cpp index be51d59..f77abf6 100644 --- a/signalController.cpp +++ b/signalController.cpp @@ -40,14 +40,14 @@ int SigIntHandler::handle() { - cLog.msg(Log::PRIO_NOTICE) << "SIG-Int caught"; + cLog.msg(Log::PRIO_NOTICE) << "SIG-Int caught, exiting"; return 1; } int SigQuitHandler::handle() { - cLog.msg(Log::PRIO_NOTICE) << "SIG-Quit caught"; + cLog.msg(Log::PRIO_NOTICE) << "SIG-Quit caught, exiting"; return 1; } @@ -61,7 +61,7 @@ int SigHupHandler::handle() int SigTermHandler::handle() { - cLog.msg(Log::PRIO_NOTICE) << "SIG-Term caught"; + cLog.msg(Log::PRIO_NOTICE) << "SIG-Term caughtm, exiting"; return 1; } |