Imported Upstream version 0.3.3
[anytun.git] / src / anytun-controld.cpp
1 /*
2  *  anytun
3  *
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.
12  *
13  *
14  *  Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, 
15  *                          Christian Pointner <satp@wirdorange.org>
16  *
17  *  This file is part of Anytun.
18  *
19  *  Anytun is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License as published by
21  *  the Free Software Foundation, either version 3 of the License, or
22  *  any later version.
23  *
24  *  Anytun is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
31  */
32
33 #include <iostream>
34 #include <fstream>
35 #include <poll.h>
36 #include <fcntl.h>
37 #include <pwd.h>
38 #include <grp.h>
39 #include <string>
40
41 #include "datatypes.h"
42
43 #include "log.h"
44 #include "signalController.h"
45 #include "options.h"
46 #include "resolver.h"
47
48 #include "syncServer.h"
49 #include "daemonService.h"
50 #include <vector>
51
52 std::list<std::string> config_;
53
54 void syncOnConnect(SyncTcpConnection * connptr)
55 {
56         for(std::list<std::string>::const_iterator it=config_.begin(); it!=config_.end();++it)
57         {
58     connptr->Send(*it);
59   }
60 }
61
62 void syncListener()
63 {
64  boost::asio::io_service io_service;
65   try
66   {
67     SyncServer server(gOpt.getBindToAddr(), gOpt.getBindToPort(), boost::bind(syncOnConnect, _1));
68     server.run();
69   }
70   catch(std::runtime_error& e) {
71     cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what();
72   }
73   catch(std::exception& e) {
74     cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what();
75   }
76 }
77
78 int main(int argc, char* argv[])
79 {
80   DaemonService service;
81   try 
82   {
83     try 
84     {
85       if(!gOpt.parse(argc, argv))
86         exit(0);
87
88       StringList targets = gOpt.getLogTargets();
89       for(StringList::const_iterator it = targets.begin();it != targets.end(); ++it)
90         cLog.addTarget(*it);
91     }
92     catch(syntax_error& e)
93     {
94       std::cerr << e << std::endl;
95       gOpt.printUsage();
96       exit(-1);
97     }
98        
99     cLog.msg(Log::PRIO_NOTICE) << "anytun-controld started..."; 
100     gOpt.parse_post(); // print warnings
101
102
103     std::ifstream file( gOpt.getFileName().c_str() );
104     if( file.is_open() )
105     {
106         std::string line;
107         while (!file.eof()) {
108         getline (file,line);
109         config_.push_back(line);
110                         }
111       file.close();
112     } else {
113       std::cout << "ERROR: unable to open file!" << std::endl;
114       exit(-1);
115     }
116     
117     service.initPrivs(gOpt.getUsername(), gOpt.getGroupname());
118     if(gOpt.getDaemonize())
119       service.daemonize();
120
121     if(gOpt.getChrootDir() != "")
122       service.chroot(gOpt.getChrootDir());
123     service.dropPrivs();
124
125     gSignalController.init(service);
126     gResolver.init();
127
128     boost::thread * syncListenerThread;
129     syncListenerThread = new boost::thread(boost::bind(syncListener));
130     
131     int ret = gSignalController.run();
132     
133     return ret;
134   }
135   catch(std::runtime_error& e)
136   {
137     if(service.isDaemonized())
138       cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what();
139     else
140       std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl;
141   }
142   catch(std::exception& e)
143   {
144     if(service.isDaemonized())
145       cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what();
146     else
147       std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
148   }
149 }
150