switched from PracticalSocket to libasio
[anytun.git] / src / anytun-controld.cpp
blob4f59743852ffaa28be8f17a40c87a386cd76fa5b
1 /*
2 * anytun
4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include <iostream>
33 #include <fstream>
34 #include <poll.h>
35 #include <fcntl.h>
36 #include <pwd.h>
37 #include <grp.h>
39 #include "datatypes.h"
41 #include "log.h"
42 #include "signalController.h"
43 #include "anyCtrOptions.h"
45 #include "anyCtrSocket.h"
46 #include "Sockets/ListenSocket.h"
47 #include "Sockets/SocketHandler.h"
50 class ThreadParam
52 public:
53 ThreadParam() : addr(""), port(0) {};
54 std::string addr;
55 u_int16_t port;
59 void* syncListener(void* p )
61 ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
62 SOCKETS_NAMESPACE::SocketHandler h;
63 SOCKETS_NAMESPACE::ListenSocket<MuxSocket> l(h,true);
65 if( l.Bind(param->addr, param->port) )
66 pthread_exit(NULL);
68 Utility::ResolveLocal(); // resolve local hostname
69 h.Add(&l);
70 h.Select(1,0);
71 while (1) {
72 h.Select(1,0);
76 void chrootAndDrop(std::string const& chrootdir, std::string const& username)
78 if (getuid() != 0)
80 std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl;
81 exit(-1);
84 struct passwd *pw = getpwnam(username.c_str());
85 if(pw) {
86 if(chroot(chrootdir.c_str()))
88 std::cerr << "can't chroot to " << chrootdir << std::endl;
89 exit(-1);
91 cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
92 chdir("/");
93 if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid))
95 std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
96 exit(-1);
98 cLog.msg(Log::PRIO_NOTICE) << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
100 else
102 std::cerr << "unknown user " << username << std::endl;
103 exit(-1);
107 void daemonize()
109 pid_t pid;
111 pid = fork();
112 if(pid) exit(0);
113 setsid();
114 pid = fork();
115 if(pid) exit(0);
117 // std::cout << "running in background now..." << std::endl;
119 int fd;
120 // for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
121 for (fd=0;fd<=2;fd++) // close all file descriptors
122 close(fd);
123 fd=open("/dev/null",O_RDWR); // stdin
124 dup(fd); // stdout
125 dup(fd); // stderr
126 umask(027);
129 int main(int argc, char* argv[])
131 if(!gOpt.parse(argc, argv))
133 gOpt.printUsage();
134 exit(-1);
137 std::ifstream file( gOpt.getFileName().c_str() );
138 if( file.is_open() )
139 file.close();
140 else
142 std::cout << "ERROR: unable to open file!" << std::endl;
143 exit(-1);
146 std::ofstream pidFile;
147 if(gOpt.getPidFile() != "") {
148 pidFile.open(gOpt.getPidFile().c_str());
149 if(!pidFile.is_open()) {
150 std::cout << "can't open pid file" << std::endl;
154 if(gOpt.getChroot())
155 chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
156 if(gOpt.getDaemonize())
157 daemonize();
159 if(pidFile.is_open()) {
160 pid_t pid = getpid();
161 pidFile << pid;
162 pidFile.close();
165 SignalController sig;
166 sig.init();
168 ThreadParam p;
169 p.addr = gOpt.getBindToAddr();
170 p.port = gOpt.getBindToPort();
171 pthread_t syncListenerThread;
172 pthread_create(&syncListenerThread, NULL, syncListener, &p);
174 int ret = sig.run();
176 pthread_cancel(syncListenerThread);
178 pthread_join(syncListenerThread, NULL);
180 return ret;