#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
+#include <boost/bind.hpp>
+
#include "command_client.hxx"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
using namespace std;
namespace libt2n
{
+command_client::command_client(client_connection& _c)
+ : c(_c)
+{
+ // for reconnects
+ c.add_callback(new_connection,bind(&command_client::read_hello, boost::ref(*this)));
+
+ read_hello();
+}
+
+void command_client::read_hello()
+{
+ // TODO: fix timeout
+ string resultpacket;
+ while(!c.get_packet(resultpacket))
+ c.fill_buffer();
+
+ istringstream hello(resultpacket);
+
+ char chk[5];
+ hello.read(chk,4);
+ chk[4]=0;
+ if (hello.fail() || hello.eof() || string("T2Nv") != chk)
+ throw t2n_version_mismatch("illegal hello received (T2N)");
+
+ int prot_version;
+ hello >> prot_version;
+ if (hello.fail() || hello.eof() || prot_version != PROTOCOL_VERSION)
+ throw t2n_version_mismatch("not compatible with the server protocol version");
+
+ hello.read(chk,1);
+ if (hello.fail() || hello.eof() || chk[0] != ';')
+ throw t2n_version_mismatch("illegal hello received (1. ;)");
+
+ hello.read(chk,4);
+ if (hello.fail() || hello.eof() || *((int*)chk) != 1)
+ throw t2n_version_mismatch("host byte order not matching");
+
+ hello.read(chk,1);
+ if (hello.fail() || hello.eof() || chk[0] != ';')
+ throw t2n_version_mismatch("illegal hello received (2. ;)");
+}
+
void command_client::send_command(command* cmd, result_container &res)
{
ostringstream ofs;
private:
client_connection &c;
+ void read_hello();
+
public:
- command_client(client_connection& _c)
- : c(_c)
- { }
+ command_client(client_connection& _c);
void send_command(command* cmd, result_container &res);
};
#include "container.hxx"
#include "log.hxx"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
using namespace std;
namespace libt2n
: s(_s)
{
// register callback
- s.add_callback(new_connection,bind(&command_server::new_connection_callback, boost::ref(*this), _1));
+ s.add_callback(new_connection,bind(&command_server::send_hello, boost::ref(*this), _1));
}
-void command_server::new_connection_callback(unsigned int conn_id)
+void command_server::send_hello(unsigned int conn_id)
{
- cerr << "new connection callback: " << conn_id << endl;
+ server_connection* sc=s.get_connection(conn_id);
+
+ ostringstream hello;
+
+ hello << "T2Nv" << PROTOCOL_VERSION << ';';
+
+ int byteordercheck=1;
+ hello.write((char*)&byteordercheck,sizeof(byteordercheck));
+
+ hello << ';';
+
+ sc->write(hello.str());
}
/// handle a command including deserialization and answering
void handle(long long usec_timeout=-1);
- void new_connection_callback(unsigned int conn_id);
+ void send_hello(unsigned int conn_id);
};
}
#include <sstream>
#include <iostream>
+#include <netinet/in.h>
+
#include "connection.hxx"
namespace libt2n
// max packet size is unsigned int
// no size information -> no packet
- if (buffer.size() < sizeof(unsigned int))
+ if (buffer.size() < sizeof(packet_size_indicator))
return 0;
- packet_size_indicator psize=*((packet_size_indicator*)(buffer.data()));
+ packet_size_indicator psize=ntohl(*((packet_size_indicator*)(buffer.data())));
// enough data for one packet in buffer?
- if (buffer.size() < sizeof(unsigned int)+psize)
+ if (buffer.size() < sizeof(packet_size_indicator)+psize)
return 0;
// ok, full packet there
if ((psize=bytes_available()))
{
- data.assign(buffer,sizeof(unsigned int),psize);
- buffer.erase(0,sizeof(unsigned int)+psize);
+ data.assign(buffer,sizeof(packet_size_indicator),psize);
+ buffer.erase(0,sizeof(packet_size_indicator)+psize);
return true;
}
else
void connection::write(const std::string& data)
{
// prepend packet size to data
- packet_size_indicator psize=data.size();
+ packet_size_indicator psize=htonl(data.size());
std::string send_data(data);
send_data.insert(0,(char*)&psize,sizeof(packet_size_indicator));
#include <string>
-#include "types.hxx"
+#include <netinet/in.h>
+#include "types.hxx"
namespace libt2n
{
std::string buffer;
- typedef unsigned int packet_size_indicator;
+ typedef uint32_t packet_size_indicator;
packet_size_indicator bytes_available();