diff --git a/sld/trunk/Makefile.am b/sld/trunk/Makefile.am index 251a5d14243649f4df5ec32129c3c0f8a61812b9..69c2643a1197d0362f01083113d093c7b4e0798b 100644 --- a/sld/trunk/Makefile.am +++ b/sld/trunk/Makefile.am @@ -21,6 +21,7 @@ sld_SOURCES= src/sld.cc \ src/daemon.cc \ src/log.cc \ src/sll/error.cc \ + src/sll/buffer.cc \ src/sll/connection.cc \ src/sll/cypher.cc @@ -30,6 +31,7 @@ noinst_HEADER= src/sld.hh \ src/log.hh \ src/sll/slm.hh \ src/sll/error.hh \ + src/sll/buffer.hh \ src/sll/connection.hh \ src/sll/connection.hxx \ src/sll/cypher.hh diff --git a/sld/trunk/src/sll/connection.cc b/sld/trunk/src/sll/connection.cc index 25e3eddc76cc38bace2d21c07414fd7396fa2e7c..ecc8abe66a691a19755448e1cc5612ab0b4d03f7 100644 --- a/sld/trunk/src/sll/connection.cc +++ b/sld/trunk/src/sll/connection.cc @@ -44,7 +44,8 @@ unsigned long int Connection::getconnid() { * * @param fd socket of the connection (-1) is not exist */ -Connection::Connection(int fd) : socket_fd_(fd), local_port_(-1), remote_port_(-1), id_(0) { +Connection::Connection(int fd, bool bufferized) + : socket_fd_(fd), local_port_(-1), remote_port_(-1), id_(0), bufferized_(bufferized) { pthread_mutex_init(&c_mutex_, 0); pthread_mutex_init(&r_mutex_, 0); pthread_mutex_init(&w_mutex_, 0); @@ -74,14 +75,8 @@ void Connection::disconnect() { throw Error(ERR_NET, "No connection established but trying to disconnect"); } - // lock all mutex - pthread_mutex_lock(&r_mutex_); - pthread_mutex_lock(&w_mutex_); - disconnect_(); - pthread_mutex_unlock(&w_mutex_); - pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); } @@ -282,7 +277,7 @@ Connection *Connection::accept() { /** * Send data on @param buf of size @param len on socket */ -void Connection::send(const char* buf, size_t len) { +void Connection::send(const void* buf, size_t len) { // lock mutex for operation pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); @@ -297,24 +292,59 @@ void Connection::send(const char* buf, size_t len) { throw Error(ERR_NET, "No connection established but trying to send data"); } - // send is a write operation - int ret = ::send(socket_fd_, buf, len, MSG_NOSIGNAL); + // call send + try { send_(socket_fd, buf, len); } + catch (...) { + pthread_mutex_lock(&c_mutex_); + pthread_mutex_lock(&r_mutex_); + disconnect_(); + pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); + pthread_mutex_unlock(&c_mutex_); + throw; + } + + // release the mutex + pthread_mutex_unlock(&w_mutex_); +} + +/** + * Free read buffer and send write buffer if connected + * + */ +void Connection::flush() { + if (!bufferized_) + return; - // treat error - if (ret == -1) { - int errno__ = errno; + // lock mutex for operation + pthread_mutex_lock(&c_mutex_); + pthread_mutex_lock(&w_mutex_); + + // retreive socket_fd and free conn mutex + int socket_fd = socket_fd_; + pthread_mutex_unlock(&c_mutex_); + + // test socket validity + if (socket_fd < 0) { + pthread_mutex_unlock(&w_mutex_); + throw Error(ERR_NET, "No connection established but trying to flush data"); + } + + // call send + try { send_(socket_fd, rbuf_.c_str(), rbuf_.length()); } + catch (...) { pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&r_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); - if (errno__ == ECONNRESET || errno__ == EPIPE) - throw Error(ERR_NET, "Connection reset by peer"); - else - throw Error(ERR_NET, "send: " + (string) strerror(errno__)); + throw; } + // clean read buffer + rbuf_.clear(); + // release the mutex pthread_mutex_unlock(&w_mutex_); } @@ -322,9 +352,53 @@ void Connection::send(const char* buf, size_t len) { /** * Receive raw data */ -char *Connection::recv(size_t size) { - assert(0); - return 0; +int Connection::recv(void *buf, size_t size) { + // lock mutex for operation + pthread_mutex_lock(&c_mutex_); + pthread_mutex_lock(&r_mutex_); + + int socket_fd = socket_fd_; + pthread_mutex_unlock(&c_mutex_); + + // test socket validity + if (socket_fd < 0) { + pthread_mutex_unlock(&r_mutex_); + throw Error(ERR_NET, "No connection established but trying to receive line"); + } + + int ret = 0; + + if (rbuf_.size() > 0) { + size_t msize = (rbuf.length() > size) ? size : rbuf.length(); + + memcpy(buf, rbuf_.c_str(), msize); + ret += msize; + rbuf_.remove(0, msize); + } + + if (ret < size) { + static char local_buf[MAX_LINE_SIZE]; + + try { ret = recv_(socket_fd, local_buf, MAX_LINE_SIZE); } + catch (...) { + pthread_mutex_lock(&c_mutex_); + pthread_mutex_lock(&w_mutex_); + *local_buf = 0; + disconnect_(); + pthread_mutex_unlock(&w_mutex_); + pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&c_mutex_); + throw; + } + local_buf[ret] = 0; + } + + + // add read data in buffer + rbuf_ += local_buf; + + } while (1); + return ret; } /** @@ -356,22 +430,17 @@ string Connection::recvln() { // read data static char local_buf[MAX_LINE_SIZE]; - int ret = ::recv(socket_fd, local_buf, MAX_LINE_SIZE, 0); - if (ret == -1 || ret == 0) { + try { recv_(socket_fd, local_buf, MAX_LINE_SIZE); } + catch (...) { pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); + *local_buf = 0; disconnect_(); pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); - - *local_buf = 0; - - if (ret == 0) - throw Error(ERR_NET, "Connection reset by peer"); - else - throw Error(ERR_NET, (string) "recvln: " + strerror(errno)); + throw; } local_buf[ret] = 0; @@ -379,11 +448,7 @@ string Connection::recvln() { rbuf_ += local_buf; } while (1); - assert(1); -} - -void Connection::flush() { - assert(0); + abort(); } string Connection::getlocalip() { @@ -509,10 +574,6 @@ int Connection::getremoteport() { return port; } -unsigned long int Connection::getid() { - return id_; -} - int Connection::getsocket() { // get socket is a conn op pthread_mutex_lock(&c_mutex_); @@ -525,6 +586,14 @@ int Connection::getsocket() { return socket_fd; } +unsigned long int Connection::getid() const { + return id_; +} + +bool Connection::isbufferized() const { + return bufferized_; +} + /******************************************************************************* ** Protected method ******************************************************************************/ diff --git a/sld/trunk/src/sll/connection.hh b/sld/trunk/src/sll/connection.hh index 89bffbccf180fe445eacc778f2ab3c60b298faa3..7269abcc34efb816d9989970f32c7bcd5b84d6f3 100644 --- a/sld/trunk/src/sll/connection.hh +++ b/sld/trunk/src/sll/connection.hh @@ -28,7 +28,7 @@ public: // public methods public: - Connection(int fd = -1); + Connection(int fd = -1, bool bufferized = false); virtual ~Connection(); void connect(const char *addr, int port); @@ -40,12 +40,12 @@ public: Connection *accept(); // send methods - void send(const char* buf, size_t len); + void send(const void* buf, size_t len); inline void send(const string &data); inline void sendln(const string &data); // recv methods - char *recv(size_t size); + int recv(void *buf, size_t size); string recvln(); // buffer methods @@ -60,15 +60,19 @@ public: string getremotehostname(); int getremoteport(); - unsigned long int getid(); - int getsocket(); + unsigned long int getid() const; + bool isbufferized() const; + // protected methods protected: inline void socket_(); inline void disconnect_(); + inline void send_(int socket_fd, const void *buf, size_t size); + inline int recv_(int socket_fd, void *buf, size_t size); + inline void setlocalip_(); inline void setlocalport_(); inline void setremoteip_(); @@ -90,6 +94,8 @@ protected: unsigned long int id_; + bool bufferized_; + string rbuf_; // read buffer string wbuf_; // write buffer diff --git a/sld/trunk/src/sll/connection.hxx b/sld/trunk/src/sll/connection.hxx index 3a606fb3aa6246152fb04e14073d011865672530..49dd25d087fa43c561299755a9e7b173a89af986 100644 --- a/sld/trunk/src/sll/connection.hxx +++ b/sld/trunk/src/sll/connection.hxx @@ -70,10 +70,13 @@ void Connection::sendln(const string &data) { * No mutex used ! */ void Connection::disconnect_() { - assert(socket_fd_ >= 0); + if (socket_fd_ < 0) + return; close(socket_fd_); socket_fd_ = -1; + rbuf_.clear(); + wbuf_.clear(); } /** @@ -91,6 +94,32 @@ void Connection::socket_() { throw Error(ERR_NET, (string) "Unable to set socket options: " + strerror(errno)); } +/** + * Send @param size byte of @param buf into socket @param socket + * No mutex used! + */ +void Connection::send_(int socket_fd, const void *buf, size_t size) { + if (::send(socket_fd, buf, size, MSG_NOSIGNAL)) { + if (errno == ECONNRESET || errno == EPIPE) + throw Error(ERR_NET, "Connection reset by peer"); + else + throw Error(ERR_NET, "send: " + (string) strerror(errno)); + } +} + +/** + * Send @param size byte of @param buf into socket @param socket + * No mutex used! + */ +int Connection::recv_(int socket_fd, void *buf, size_t size) { + int ret = ::recv(socket_fd, buf, size, 0); + if (ret == 0) + throw Error(ERR_NET, "Connection reset by peer"); + else if (ret == -1) + throw Error(ERR_NET, (string) "recvln: " + strerror(errno)); + return ret; +} + /** * Set local ip * No mutex used ! diff --git a/sll/trunk/connection.cc b/sll/trunk/connection.cc index 25e3eddc76cc38bace2d21c07414fd7396fa2e7c..4410a6747300bbbbf7d72f5c08e4a7b275a5a67f 100644 --- a/sll/trunk/connection.cc +++ b/sll/trunk/connection.cc @@ -323,7 +323,8 @@ void Connection::send(const char* buf, size_t len) { * Receive raw data */ char *Connection::recv(size_t size) { - assert(0); + abort(); + size = size + 1; return 0; } diff --git a/sls/trunk/src/client.cc b/sls/trunk/src/client.cc index 18f81844b3a1bf22cde9836ec927ef086cae9b44..0a6910b3557baa4beba494fd82c804e704e8bfd2 100644 --- a/sls/trunk/src/client.cc +++ b/sls/trunk/src/client.cc @@ -58,6 +58,9 @@ Client *Client::login(Connection &c) { return login_fail(c); } + // send succefull login + c.sendln("OK"); + // Print succefful login std::cout << "CId " << c.getid() << ": " << real_client->type() << " " << loginbuf << " logged from " << c.getremoteip() diff --git a/sls/trunk/src/client_console.cc b/sls/trunk/src/client_console.cc index 646f12037e42f4da2e810d111e8892696f2a436a..2fbabaea19c27b1346102f275ccf9ccaffb0ee1c 100644 --- a/sls/trunk/src/client_console.cc +++ b/sls/trunk/src/client_console.cc @@ -80,10 +80,7 @@ bool Console::trust(const char *login, const char *pass) { // register as logged in DB - // send validation - c_.sendln("OK"); - - return true; + return false; } /** @@ -99,7 +96,7 @@ string Console::type() { * @param cmd string to parse */ void Console::parse(const string &cmd) { - if (!cmd.empty()) + if (cmd.empty()) throw Error(ERR_PARSE, "Empty command"); // FIXME } diff --git a/sls/trunk/src/client_daemon.cc b/sls/trunk/src/client_daemon.cc index d28a5b631f4c9ee9b9547c239005b36b8bc347c5..b597ddc632e844a884feca8a9853c26f2cfe8a9b 100644 --- a/sls/trunk/src/client_daemon.cc +++ b/sls/trunk/src/client_daemon.cc @@ -19,6 +19,8 @@ #include "sls.hh" #include "client_daemon.hh" +#include + /******************************************************************************* ** Public methods *******************************************************************************/ @@ -28,6 +30,11 @@ void Daemon::exec() { send_script(); // starting scripts + while (1) { + c_.sendln("STATUS"); + sleep(1); + } + c_.sendln("EXIT"); } @@ -64,9 +71,6 @@ bool Daemon::trust(const char *login, const char *pass) { // register as logged in DB - // Send logging accepted - c_.sendln("OK"); - return true; } diff --git a/sls/trunk/src/option.cc b/sls/trunk/src/option.cc index 3c813f6113789873e4bf6e2adcae8565bfe72f5b..55e701255de63f18865aa4882b5392318d430efe 100644 --- a/sls/trunk/src/option.cc +++ b/sls/trunk/src/option.cc @@ -97,7 +97,7 @@ Option &Option::load(int argc, char *argv[]) { logfile = optarg; break; case 'V': - std::cerr << "Version: " << VERSION << std::endl; + std::cout << "Version: " << VERSION << std::endl; exit(ERR_NO); case 'D': daemon = false; diff --git a/sls/trunk/src/sll/connection.cc b/sls/trunk/src/sll/connection.cc index d78aa7752092db4bb30eb3dad884009f6ce55071..25e3eddc76cc38bace2d21c07414fd7396fa2e7c 100644 --- a/sls/trunk/src/sll/connection.cc +++ b/sls/trunk/src/sll/connection.cc @@ -106,14 +106,14 @@ void Connection::connect(const char *addr, int port) { } // take read and write mutex - pthread_mutex_lock(&r_mutex_); pthread_mutex_lock(&w_mutex_); + pthread_mutex_lock(&r_mutex_); // retrieve remote host info struct hostent *h = gethostbyname(addr); if (h == 0) { - pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, (string) "Unable to resolve: " + addr + ": " + hstrerror(h_errno)); } @@ -121,8 +121,8 @@ void Connection::connect(const char *addr, int port) { // create socket try { socket_(); } catch (...) { - pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } @@ -138,8 +138,8 @@ void Connection::connect(const char *addr, int port) { if (::connect(socket_fd_, (struct sockaddr *) &daddr, sizeof daddr) == -1) { int errno__ = errno; disconnect_(); - pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, (string) "Unable to connect to " + addr + ": " + strerror(errno__)); } @@ -152,14 +152,14 @@ void Connection::connect(const char *addr, int port) { setremoteport_(); } catch (...) { - pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } - pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); } @@ -243,26 +243,34 @@ void Connection::listen(int port, int max) { * @return null on error, else a new connection */ Connection *Connection::accept() { - // keep the socket fd + // accept is a read/write op pthread_mutex_lock(&c_mutex_); + pthread_mutex_lock(&r_mutex_); + pthread_mutex_lock(&w_mutex_); + + // get the socket fd int socket_fd = socket_fd_; pthread_mutex_unlock(&c_mutex_); // test socket validity - if (socket_fd < 0) + if (socket_fd < 0) { + pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); throw Error(ERR_NET, "No connection established but trying to accept"); + } struct sockaddr_in r_addr; socklen_t r_sin_size = sizeof r_addr; int r_fd; - // accept is a read/write operation - pthread_mutex_lock(&r_mutex_); - pthread_mutex_lock(&w_mutex_); - if ((r_fd = ::accept(socket_fd, (struct sockaddr *) &r_addr, &r_sin_size)) == -1) { + int errno__ = errno; + pthread_mutex_lock(&c_mutex_); + disconnect_(); + pthread_mutex_unlock(&r_mutex_); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&c_mutex_); - throw Error(ERR_NET, (string) "accept: " + strerror(errno)); + throw Error(ERR_NET, (string) "accept: " + strerror(errno__)); } pthread_mutex_unlock(&r_mutex_); @@ -299,8 +307,8 @@ void Connection::send(const char* buf, size_t len) { pthread_mutex_lock(&r_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); - pthread_mutex_unlock(&c_mutex_); pthread_mutex_unlock(&w_mutex_); + pthread_mutex_unlock(&c_mutex_); if (errno__ == ECONNRESET || errno__ == EPIPE) throw Error(ERR_NET, "Connection reset by peer"); else @@ -354,9 +362,9 @@ string Connection::recvln() { pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); disconnect_(); + pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); - pthread_mutex_unlock(&r_mutex_); *local_buf = 0; diff --git a/sls/trunk/src/sll/cypher.cc b/sls/trunk/src/sll/cypher.cc index 01485946e13cf3d7666353a9ccfe1d7b71a10f29..b9aa4e2c2d77056e7322883152556aaf5e23d3ae 100644 --- a/sls/trunk/src/sll/cypher.cc +++ b/sls/trunk/src/sll/cypher.cc @@ -52,7 +52,7 @@ string Cypher::sha1_64(const char *data, size_t size) { BIO_get_mem_ptr(b64, &bptr); if (bptr->length > 0) - ret.insert(0, bptr->data, bptr->length); + ret.insert(0, bptr->data, bptr->length - 1); else throw Error(ERR_CYPHER, "Unable to compute sha1_64");