Loading sls/trunk/src/client.cc +1 −1 Original line number Diff line number Diff line Loading @@ -80,6 +80,6 @@ Client::~Client() {} static Client *login_fail(Connection &c) { std::cout << "CId " << c.getid() << ": Bad authentification.\n"; c.sendln("Bad authentification."); c.sendln("KO"); return 0; } sls/trunk/src/server.cc +4 −1 Original line number Diff line number Diff line Loading @@ -179,7 +179,8 @@ void *Server::start_client(void *voidconn) { } // stop connexion conn->disconnect(); try { conn->disconnect(); } catch (...) {} // Print closing connection std::cout << "CId " << conn->getid() << ": Closed.\n"; Loading @@ -189,5 +190,7 @@ void *Server::start_client(void *voidconn) { S.threads_.erase(t); pthread_mutex_unlock(&S.threads_mutex_); delete conn; return 0; } sls/trunk/src/sll/connection.cc +167 −176 Original line number Diff line number Diff line Loading @@ -51,7 +51,13 @@ Connection::Connection(int fd) : socket_fd_(fd), local_port_(-1), remote_port_(- if (socket_fd_ >= 0) { id_ = getconnid(); setallinfo_(); try { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); } catch (...) { } } } Loading @@ -64,17 +70,50 @@ Connection::~Connection() { pthread_mutex_destroy(&w_mutex_); } /** * Disconnect socket */ void Connection::disconnect() { // lock connection mutex pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); 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_); } /** * Create connection with @param addr on port @param port */ void Connection::connect(const char *addr, int port) { if (socket_fd_ >= 0) throw Error(ERR_NET, "Connection already established but trying to connect"); // check args if (addr == 0 || *addr == 0) throw Error(ERR_NET, "Trying to connect on a bad address"); if (port <= 0) throw Error(ERR_NET, "Trying to Connect on a bad port number"); if (port <= 0 || port >= 65536) throw Error(ERR_NET, "Trying to connect on a bad port number"); // take connection mutex pthread_mutex_lock(&c_mutex_); // check already existant connection if (socket_fd_ >= 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "Connection already established but trying to connect"); } // take read and write mutex pthread_mutex_lock(&r_mutex_); pthread_mutex_lock(&w_mutex_); Loading Loading @@ -113,7 +152,18 @@ void Connection::connect(const char *addr, int port) { } // set infos setallinfo_(); try { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); } catch (...) { pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); Loading @@ -124,11 +174,21 @@ void Connection::connect(const char *addr, int port) { * Listen on @param port with queue size of max @param max */ void Connection::listen(int port, int max) { if (socket_fd_ >= 0) throw Error(ERR_NET, "Connection already established but trying to listen"); // check arg if (port <= 0 || port >= 65536) throw Error(ERR_NET, "Trying to listen on a bad port number"); if (max <= 0) throw Error(ERR_NET, "Trying to listen with bad wait queue size"); // lock // take connection mutex pthread_mutex_lock(&c_mutex_); if (socket_fd_ >= 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "Connection already established but trying to listen"); } // lock read and write mutex pthread_mutex_lock(&r_mutex_); pthread_mutex_lock(&w_mutex_); Loading Loading @@ -168,67 +228,46 @@ void Connection::listen(int port, int max) { } // set all infos setallinfo_(); try { setlocalip_(); setlocalport_(); } catch (...) { pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } /** * Disconnect socket */ void Connection::disconnect() { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to disconnect"); // lock all mutex pthread_mutex_lock(&c_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_); } /** * Return the connection sate * Cannot be const, du to mutex locking * * @return see description */ bool Connection::connected() { // get connection mutex pthread_mutex_lock(&c_mutex_); bool ret = (socket_fd_ >= 0); pthread_mutex_unlock(&c_mutex_); return ret; } /** * Accept new connection on a listening socket * * @return null on error, else a new connection */ Connection *Connection::accept() { if (socket_fd_ < 0) // keep the socket fd pthread_mutex_lock(&c_mutex_); int socket_fd = socket_fd_; pthread_mutex_unlock(&c_mutex_); // test socket validity if (socket_fd < 0) 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) { if ((r_fd = ::accept(socket_fd, (struct sockaddr *) &r_addr, &r_sin_size)) == -1) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, (string) "accept: " + strerror(errno)); } Loading @@ -243,51 +282,59 @@ Connection *Connection::accept() { * Send data on @param buf of size @param len on socket */ void Connection::send(const char* buf, size_t len) { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send data"); // lock mutex for operation pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); int ret = ::send(socket_fd_, buf, len, 0); pthread_mutex_unlock(&w_mutex_); if (ret == -1 && errno == ECONNRESET) throw Error(ERR_NET, "Connection reset by peer"); if (ret == -1) throw Error(ERR_NET, "send: " + (string) strerror(errno)); // 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 send data"); } /** * Send data on @param buf of size @param len followed by '\n' on socket */ void Connection::sendln(const char* buf, size_t len) { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send line"); // send is a write operation int ret = ::send(socket_fd_, buf, len, MSG_NOSIGNAL); pthread_mutex_lock(&w_mutex_); // write data int ret = ::send(socket_fd_, buf, len, 0); // treat error if (ret == -1) { pthread_mutex_unlock(&w_mutex_); if (errno == ECONNRESET) int errno__ = errno; pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&r_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); pthread_mutex_unlock(&r_mutex_); if (errno__ == ECONNRESET)// || errno__ == EPIPE) throw Error(ERR_NET, "Connection reset by peer"); throw Error(ERR_NET, "sendln: " + (string) strerror(errno)); else throw Error(ERR_NET, "send: " + (string) strerror(errno__)); } // write '\n' ret = ::send(socket_fd_, "\n", 1, 0); // release the mutex pthread_mutex_unlock(&w_mutex_); if (ret == -1) throw Error(ERR_NET, "sendln: " + (string) strerror(errno)); } /** * Receive a line */ string Connection::recvln() { if (socket_fd_ < 0) // 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"); } pthread_mutex_lock(&r_mutex_); do { // check EOL char size_t offset = rbuf_.find('\n'); Loading @@ -298,26 +345,26 @@ string Connection::recvln() { return s; } // do poll fd here ? // read data static char local_buf[MAX_LINE_SIZE]; int ret = ::recv(socket_fd_, local_buf, MAX_LINE_SIZE, 0); int ret = ::recv(socket_fd, local_buf, MAX_LINE_SIZE, 0); if (ret == 0) { if (ret == -1 || ret == 0) { pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); pthread_mutex_unlock(&r_mutex_); throw Error(ERR_NET, "Connection reset by peer"); } if (ret == -1) { *local_buf = 0; // unlock before error pthread_mutex_unlock(&r_mutex_); if (ret == 0) throw Error(ERR_NET, "Connection reset by peer"); else throw Error(ERR_NET, (string) "recvln: " + strerror(errno)); } else local_buf[ret] = 0; local_buf[ret] = 0; // add read data in buffer rbuf_ += local_buf; Loading @@ -327,10 +374,14 @@ string Connection::recvln() { } string Connection::getlocalip() { if (socket_fd_ < 0) // get local ip is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get local ip"); } pthread_mutex_lock(&c_mutex_); if (local_ip_.empty()) setlocalip_(); string ip = local_ip_; Loading @@ -339,10 +390,14 @@ string Connection::getlocalip() { } int Connection::getlocalport() { if (socket_fd_ < 0) // get local port is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get local port"); } pthread_mutex_lock(&c_mutex_); if (local_port_ == -1) setlocalport_(); int port = local_port_; Loading @@ -351,10 +406,14 @@ int Connection::getlocalport() { } string Connection::getremoteip() { if (socket_fd_ < 0) // get remote ip is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get remote ip"); } pthread_mutex_lock(&c_mutex_); if (remote_ip_.empty()) setremoteip_(); string ip = remote_ip_; Loading @@ -363,10 +422,14 @@ string Connection::getremoteip() { } int Connection::getremoteport() { if (socket_fd_ < 0) // get remote port is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get remote port"); } pthread_mutex_lock(&c_mutex_); if (remote_port_ == -1) setremoteport_(); int port = remote_port_; Loading @@ -379,89 +442,17 @@ unsigned long int Connection::getid() { } int Connection::getsocket() { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to get socket fd"); // get socket is a conn op pthread_mutex_lock(&c_mutex_); int ret = socket_fd_; int socket_fd = socket_fd_; pthread_mutex_unlock(&c_mutex_); return ret; if (socket_fd < 0) throw Error(ERR_NET, "No connection established but trying to get socket fd"); return socket_fd; } /******************************************************************************* ** Protected method ******************************************************************************/ /** * Reserve a socket * No mutex used ! */ void Connection::socket_() { assert(socket_fd_ == -1); int yes = 1; if ((socket_fd_ = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) throw Error(ERR_NET, (string) "Unable to open socket: " + strerror(errno)); if (::setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) throw Error(ERR_NET, (string) "Unable to set socket options: " + strerror(errno)); } /** * Free a socket * No mutex used ! */ void Connection::disconnect_() { assert(socket_fd_ >= 0); close(socket_fd_); socket_fd_ = -1; } /** * Set local ip * No mutex used ! */ void Connection::setlocalip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len); local_ip_ = inet_ntoa(addr.sin_addr); } /** * Set local port * No mutex used ! */ void Connection::setlocalport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len); local_port_ = ntohs(addr.sin_port); } /** * Set remote ip * No mutex used ! */ void Connection::setremoteip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len); remote_ip_ = inet_ntoa(addr.sin_addr); } /** * Set remote port * No mutex used ! */ void Connection::setremoteport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len); remote_port_ = ntohs(addr.sin_port); } sls/trunk/src/sll/connection.hh +12 −14 Original line number Diff line number Diff line Loading @@ -2,17 +2,17 @@ This file is part of SLS. Copyright (C) 2008 Sebastien LUTTRINGER <contact@seblu.net> SLS is free software; you can redistribute it and/or modify SLL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. SLS is distributed in the hope that it will be useful, SLL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SLS; if not, write to the Free Software along with SLL; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ Loading @@ -35,15 +35,14 @@ public: void listen(int port, int max); void disconnect(); bool connected(); inline bool connected(); Connection *accept(); // send methods inline void send(const string &data); void send(const char* buf, size_t len); inline void send(const string &data); inline void sendln(const string &data); void sendln(const char* buf, size_t len); // recv methods string recvln(); Loading @@ -61,14 +60,13 @@ public: // protected methods protected: void socket_(); void disconnect_(); inline void setallinfo_(); void setlocalip_(); void setlocalport_(); void setremoteip_(); void setremoteport_(); inline void socket_(); inline void disconnect_(); inline void setlocalip_(); inline void setlocalport_(); inline void setremoteip_(); inline void setremoteport_(); // Protected datas protected: Loading sls/trunk/src/sll/connection.hxx +101 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ # include "error.hh" #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> /******************************************************************************* ** Public method ******************************************************************************/ /** * Return the connection sate * Cannot be const, du to mutex locking * * @return see description */ bool Connection::connected() { // get connection mutex pthread_mutex_lock(&c_mutex_); bool ret = (socket_fd_ >= 0); pthread_mutex_unlock(&c_mutex_); return ret; } /** * Send @param data on socket */ Loading @@ -31,7 +56,8 @@ void Connection::send(const string &data) { * Send @param data followed by '\n' on socket */ void Connection::sendln(const string &data) { sendln(data.c_str(), data.length()); string tosend = data + "\n"; send(tosend.c_str(), tosend.length()); } /******************************************************************************* Loading @@ -39,11 +65,79 @@ void Connection::sendln(const string &data) { ******************************************************************************/ /** * Set all information about a connection * Free a socket * No mutex used ! */ void Connection::setallinfo_() { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); void Connection::disconnect_() { assert(socket_fd_ >= 0); close(socket_fd_); socket_fd_ = -1; } /** * Reserve a socket * No mutex used ! */ void Connection::socket_() { assert(socket_fd_ == -1); int yes = 1; if ((socket_fd_ = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) throw Error(ERR_NET, (string) "Unable to open socket: " + strerror(errno)); if (::setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) throw Error(ERR_NET, (string) "Unable to set socket options: " + strerror(errno)); } /** * Set local ip * No mutex used ! */ void Connection::setlocalip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set local ip: " + strerror(errno)); local_ip_ = inet_ntoa(addr.sin_addr); } /** * Set local port * No mutex used ! */ void Connection::setlocalport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set local port: " + strerror(errno)); local_port_ = ntohs(addr.sin_port); } /** * Set remote ip * No mutex used ! */ void Connection::setremoteip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set remote ip: " + strerror(errno)); remote_ip_ = inet_ntoa(addr.sin_addr); } /** * Set remote port * No mutex used ! */ void Connection::setremoteport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set remote port: " + strerror(errno)); remote_port_ = ntohs(addr.sin_port); } Loading
sls/trunk/src/client.cc +1 −1 Original line number Diff line number Diff line Loading @@ -80,6 +80,6 @@ Client::~Client() {} static Client *login_fail(Connection &c) { std::cout << "CId " << c.getid() << ": Bad authentification.\n"; c.sendln("Bad authentification."); c.sendln("KO"); return 0; }
sls/trunk/src/server.cc +4 −1 Original line number Diff line number Diff line Loading @@ -179,7 +179,8 @@ void *Server::start_client(void *voidconn) { } // stop connexion conn->disconnect(); try { conn->disconnect(); } catch (...) {} // Print closing connection std::cout << "CId " << conn->getid() << ": Closed.\n"; Loading @@ -189,5 +190,7 @@ void *Server::start_client(void *voidconn) { S.threads_.erase(t); pthread_mutex_unlock(&S.threads_mutex_); delete conn; return 0; }
sls/trunk/src/sll/connection.cc +167 −176 Original line number Diff line number Diff line Loading @@ -51,7 +51,13 @@ Connection::Connection(int fd) : socket_fd_(fd), local_port_(-1), remote_port_(- if (socket_fd_ >= 0) { id_ = getconnid(); setallinfo_(); try { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); } catch (...) { } } } Loading @@ -64,17 +70,50 @@ Connection::~Connection() { pthread_mutex_destroy(&w_mutex_); } /** * Disconnect socket */ void Connection::disconnect() { // lock connection mutex pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); 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_); } /** * Create connection with @param addr on port @param port */ void Connection::connect(const char *addr, int port) { if (socket_fd_ >= 0) throw Error(ERR_NET, "Connection already established but trying to connect"); // check args if (addr == 0 || *addr == 0) throw Error(ERR_NET, "Trying to connect on a bad address"); if (port <= 0) throw Error(ERR_NET, "Trying to Connect on a bad port number"); if (port <= 0 || port >= 65536) throw Error(ERR_NET, "Trying to connect on a bad port number"); // take connection mutex pthread_mutex_lock(&c_mutex_); // check already existant connection if (socket_fd_ >= 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "Connection already established but trying to connect"); } // take read and write mutex pthread_mutex_lock(&r_mutex_); pthread_mutex_lock(&w_mutex_); Loading Loading @@ -113,7 +152,18 @@ void Connection::connect(const char *addr, int port) { } // set infos setallinfo_(); try { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); } catch (...) { pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); Loading @@ -124,11 +174,21 @@ void Connection::connect(const char *addr, int port) { * Listen on @param port with queue size of max @param max */ void Connection::listen(int port, int max) { if (socket_fd_ >= 0) throw Error(ERR_NET, "Connection already established but trying to listen"); // check arg if (port <= 0 || port >= 65536) throw Error(ERR_NET, "Trying to listen on a bad port number"); if (max <= 0) throw Error(ERR_NET, "Trying to listen with bad wait queue size"); // lock // take connection mutex pthread_mutex_lock(&c_mutex_); if (socket_fd_ >= 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "Connection already established but trying to listen"); } // lock read and write mutex pthread_mutex_lock(&r_mutex_); pthread_mutex_lock(&w_mutex_); Loading Loading @@ -168,67 +228,46 @@ void Connection::listen(int port, int max) { } // set all infos setallinfo_(); try { setlocalip_(); setlocalport_(); } catch (...) { pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); throw; } /** * Disconnect socket */ void Connection::disconnect() { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to disconnect"); // lock all mutex pthread_mutex_lock(&c_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_); } /** * Return the connection sate * Cannot be const, du to mutex locking * * @return see description */ bool Connection::connected() { // get connection mutex pthread_mutex_lock(&c_mutex_); bool ret = (socket_fd_ >= 0); pthread_mutex_unlock(&c_mutex_); return ret; } /** * Accept new connection on a listening socket * * @return null on error, else a new connection */ Connection *Connection::accept() { if (socket_fd_ < 0) // keep the socket fd pthread_mutex_lock(&c_mutex_); int socket_fd = socket_fd_; pthread_mutex_unlock(&c_mutex_); // test socket validity if (socket_fd < 0) 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) { if ((r_fd = ::accept(socket_fd, (struct sockaddr *) &r_addr, &r_sin_size)) == -1) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, (string) "accept: " + strerror(errno)); } Loading @@ -243,51 +282,59 @@ Connection *Connection::accept() { * Send data on @param buf of size @param len on socket */ void Connection::send(const char* buf, size_t len) { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send data"); // lock mutex for operation pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); int ret = ::send(socket_fd_, buf, len, 0); pthread_mutex_unlock(&w_mutex_); if (ret == -1 && errno == ECONNRESET) throw Error(ERR_NET, "Connection reset by peer"); if (ret == -1) throw Error(ERR_NET, "send: " + (string) strerror(errno)); // 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 send data"); } /** * Send data on @param buf of size @param len followed by '\n' on socket */ void Connection::sendln(const char* buf, size_t len) { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send line"); // send is a write operation int ret = ::send(socket_fd_, buf, len, MSG_NOSIGNAL); pthread_mutex_lock(&w_mutex_); // write data int ret = ::send(socket_fd_, buf, len, 0); // treat error if (ret == -1) { pthread_mutex_unlock(&w_mutex_); if (errno == ECONNRESET) int errno__ = errno; pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&r_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); pthread_mutex_unlock(&r_mutex_); if (errno__ == ECONNRESET)// || errno__ == EPIPE) throw Error(ERR_NET, "Connection reset by peer"); throw Error(ERR_NET, "sendln: " + (string) strerror(errno)); else throw Error(ERR_NET, "send: " + (string) strerror(errno__)); } // write '\n' ret = ::send(socket_fd_, "\n", 1, 0); // release the mutex pthread_mutex_unlock(&w_mutex_); if (ret == -1) throw Error(ERR_NET, "sendln: " + (string) strerror(errno)); } /** * Receive a line */ string Connection::recvln() { if (socket_fd_ < 0) // 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"); } pthread_mutex_lock(&r_mutex_); do { // check EOL char size_t offset = rbuf_.find('\n'); Loading @@ -298,26 +345,26 @@ string Connection::recvln() { return s; } // do poll fd here ? // read data static char local_buf[MAX_LINE_SIZE]; int ret = ::recv(socket_fd_, local_buf, MAX_LINE_SIZE, 0); int ret = ::recv(socket_fd, local_buf, MAX_LINE_SIZE, 0); if (ret == 0) { if (ret == -1 || ret == 0) { pthread_mutex_lock(&c_mutex_); pthread_mutex_lock(&w_mutex_); disconnect_(); pthread_mutex_unlock(&r_mutex_); pthread_mutex_unlock(&c_mutex_); pthread_mutex_unlock(&r_mutex_); throw Error(ERR_NET, "Connection reset by peer"); } if (ret == -1) { *local_buf = 0; // unlock before error pthread_mutex_unlock(&r_mutex_); if (ret == 0) throw Error(ERR_NET, "Connection reset by peer"); else throw Error(ERR_NET, (string) "recvln: " + strerror(errno)); } else local_buf[ret] = 0; local_buf[ret] = 0; // add read data in buffer rbuf_ += local_buf; Loading @@ -327,10 +374,14 @@ string Connection::recvln() { } string Connection::getlocalip() { if (socket_fd_ < 0) // get local ip is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get local ip"); } pthread_mutex_lock(&c_mutex_); if (local_ip_.empty()) setlocalip_(); string ip = local_ip_; Loading @@ -339,10 +390,14 @@ string Connection::getlocalip() { } int Connection::getlocalport() { if (socket_fd_ < 0) // get local port is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get local port"); } pthread_mutex_lock(&c_mutex_); if (local_port_ == -1) setlocalport_(); int port = local_port_; Loading @@ -351,10 +406,14 @@ int Connection::getlocalport() { } string Connection::getremoteip() { if (socket_fd_ < 0) // get remote ip is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get remote ip"); } pthread_mutex_lock(&c_mutex_); if (remote_ip_.empty()) setremoteip_(); string ip = remote_ip_; Loading @@ -363,10 +422,14 @@ string Connection::getremoteip() { } int Connection::getremoteport() { if (socket_fd_ < 0) // get remote port is a conn op pthread_mutex_lock(&c_mutex_); if (socket_fd_ < 0) { pthread_mutex_unlock(&c_mutex_); throw Error(ERR_NET, "No connection established but trying to get remote port"); } pthread_mutex_lock(&c_mutex_); if (remote_port_ == -1) setremoteport_(); int port = remote_port_; Loading @@ -379,89 +442,17 @@ unsigned long int Connection::getid() { } int Connection::getsocket() { if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to get socket fd"); // get socket is a conn op pthread_mutex_lock(&c_mutex_); int ret = socket_fd_; int socket_fd = socket_fd_; pthread_mutex_unlock(&c_mutex_); return ret; if (socket_fd < 0) throw Error(ERR_NET, "No connection established but trying to get socket fd"); return socket_fd; } /******************************************************************************* ** Protected method ******************************************************************************/ /** * Reserve a socket * No mutex used ! */ void Connection::socket_() { assert(socket_fd_ == -1); int yes = 1; if ((socket_fd_ = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) throw Error(ERR_NET, (string) "Unable to open socket: " + strerror(errno)); if (::setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) throw Error(ERR_NET, (string) "Unable to set socket options: " + strerror(errno)); } /** * Free a socket * No mutex used ! */ void Connection::disconnect_() { assert(socket_fd_ >= 0); close(socket_fd_); socket_fd_ = -1; } /** * Set local ip * No mutex used ! */ void Connection::setlocalip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len); local_ip_ = inet_ntoa(addr.sin_addr); } /** * Set local port * No mutex used ! */ void Connection::setlocalport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getsockname(socket_fd_, (struct sockaddr*) &addr, &len); local_port_ = ntohs(addr.sin_port); } /** * Set remote ip * No mutex used ! */ void Connection::setremoteip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len); remote_ip_ = inet_ntoa(addr.sin_addr); } /** * Set remote port * No mutex used ! */ void Connection::setremoteport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; ::getpeername(socket_fd_, (struct sockaddr*) &addr, &len); remote_port_ = ntohs(addr.sin_port); }
sls/trunk/src/sll/connection.hh +12 −14 Original line number Diff line number Diff line Loading @@ -2,17 +2,17 @@ This file is part of SLS. Copyright (C) 2008 Sebastien LUTTRINGER <contact@seblu.net> SLS is free software; you can redistribute it and/or modify SLL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. SLS is distributed in the hope that it will be useful, SLL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SLS; if not, write to the Free Software along with SLL; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ Loading @@ -35,15 +35,14 @@ public: void listen(int port, int max); void disconnect(); bool connected(); inline bool connected(); Connection *accept(); // send methods inline void send(const string &data); void send(const char* buf, size_t len); inline void send(const string &data); inline void sendln(const string &data); void sendln(const char* buf, size_t len); // recv methods string recvln(); Loading @@ -61,14 +60,13 @@ public: // protected methods protected: void socket_(); void disconnect_(); inline void setallinfo_(); void setlocalip_(); void setlocalport_(); void setremoteip_(); void setremoteport_(); inline void socket_(); inline void disconnect_(); inline void setlocalip_(); inline void setlocalport_(); inline void setremoteip_(); inline void setremoteport_(); // Protected datas protected: Loading
sls/trunk/src/sll/connection.hxx +101 −7 Original line number Diff line number Diff line Loading @@ -16,10 +16,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ # include "error.hh" #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> /******************************************************************************* ** Public method ******************************************************************************/ /** * Return the connection sate * Cannot be const, du to mutex locking * * @return see description */ bool Connection::connected() { // get connection mutex pthread_mutex_lock(&c_mutex_); bool ret = (socket_fd_ >= 0); pthread_mutex_unlock(&c_mutex_); return ret; } /** * Send @param data on socket */ Loading @@ -31,7 +56,8 @@ void Connection::send(const string &data) { * Send @param data followed by '\n' on socket */ void Connection::sendln(const string &data) { sendln(data.c_str(), data.length()); string tosend = data + "\n"; send(tosend.c_str(), tosend.length()); } /******************************************************************************* Loading @@ -39,11 +65,79 @@ void Connection::sendln(const string &data) { ******************************************************************************/ /** * Set all information about a connection * Free a socket * No mutex used ! */ void Connection::setallinfo_() { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); void Connection::disconnect_() { assert(socket_fd_ >= 0); close(socket_fd_); socket_fd_ = -1; } /** * Reserve a socket * No mutex used ! */ void Connection::socket_() { assert(socket_fd_ == -1); int yes = 1; if ((socket_fd_ = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) throw Error(ERR_NET, (string) "Unable to open socket: " + strerror(errno)); if (::setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) throw Error(ERR_NET, (string) "Unable to set socket options: " + strerror(errno)); } /** * Set local ip * No mutex used ! */ void Connection::setlocalip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set local ip: " + strerror(errno)); local_ip_ = inet_ntoa(addr.sin_addr); } /** * Set local port * No mutex used ! */ void Connection::setlocalport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getsockname(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set local port: " + strerror(errno)); local_port_ = ntohs(addr.sin_port); } /** * Set remote ip * No mutex used ! */ void Connection::setremoteip_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set remote ip: " + strerror(errno)); remote_ip_ = inet_ntoa(addr.sin_addr); } /** * Set remote port * No mutex used ! */ void Connection::setremoteport_() { struct sockaddr_in addr; socklen_t len = sizeof addr; if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to set remote port: " + strerror(errno)); remote_port_ = ntohs(addr.sin_port); }