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