Imported Upstream version 0.3.4
[anytun.git] / src / syncClient.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 #include <sstream>
33 #include <iostream>
34 #include <string>
35 #include "connectionList.h"
36 #include "syncCommand.h"
37
38 #include <boost/archive/text_oarchive.hpp>
39 #include <boost/archive/text_iarchive.hpp>
40
41
42 #include "log.h"
43 #include "syncClient.h"
44 #include "syncTcpConnection.h"
45 #include "buffer.h"
46 #include <boost/array.hpp>
47
48
49 SyncClient::SyncClient(std::string hostname,std::string port)
50   :hostname_(hostname),port_(port)
51 {
52 }
53
54 void SyncClient::run()
55 {
56   bool connected(false);
57   for(;;) {
58     try {
59       boost::asio::io_service io_service;
60       SyncTcpConnection::proto::resolver resolver(io_service);
61       SyncTcpConnection::proto::resolver::query query(hostname_, port_);
62       SyncTcpConnection::proto::resolver::iterator endpoint_iterator = resolver.resolve(query);
63       SyncTcpConnection::proto::resolver::iterator end;
64
65       SyncTcpConnection::proto::socket socket(io_service);
66       boost::system::error_code error = boost::asio::error::host_not_found;
67       while(error && endpoint_iterator != end) {
68         socket.close();
69         socket.connect(*endpoint_iterator++, error);
70       }
71       if(error) {
72         throw boost::system::system_error(error);
73       }
74       if(!connected) {
75         cLog.msg(Log::PRIO_NOTICE) << "sync: connected to " << hostname_ <<":"<< port_;
76       }
77       connected=true;
78       readAndProcess(socket); //endless loop
79     } catch(std::exception& e) {
80       if(connected) {
81         cLog.msg(Log::PRIO_NOTICE) << "sync: connection to " << hostname_ <<":"<< port_<< " lost ("<< e.what() << ") retrying every 10sec";
82       }
83       connected=false;
84       boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
85     }
86   }
87 }
88
89 void SyncClient::readAndProcess(SyncTcpConnection::proto::socket& socket)
90 {
91   ConnectionList& cl_(gConnectionList);
92   size_t message_lenght ;
93   for(;;) {
94     std::stringstream message_lenght_stream;
95     readExactly(socket,5,message_lenght_stream);
96     message_lenght_stream >> message_lenght;
97     std::stringstream void_stream;
98     readExactly(socket,1,void_stream); //skip space
99     std::stringstream sync_command_stream;
100     readExactly(socket,message_lenght, sync_command_stream);
101     //cLog.msg(Log::PRIO_NOTICE) << "recieved sync inforamtaion "<<tmp.str()<< std::endl;
102     boost::archive::text_iarchive ia(sync_command_stream);
103     SyncCommand scom(cl_);
104     ia >> scom;
105   }
106 }
107
108 void SyncClient::readExactly(SyncTcpConnection::proto::socket& socket,size_t toread, std::iostream& result)
109 {
110   size_t hasread = 0;
111   while(toread > hasread) {
112     //TODO read bigger buffers
113     boost::array<char, 1> buf;
114     boost::system::error_code error;
115     size_t len = socket.read_some(boost::asio::buffer(buf), error);
116     if(error == boost::asio::error::eof) {
117       break;  // Connection closed cleanly by peer.
118     } else if(error) {
119       throw boost::system::system_error(error);  // Some other error.
120     }
121     //for (size_t pos=0; pos<len; pos++)
122     result<<buf[0];
123     hasread+=len;
124   }
125 }