From 1ff488c7c9e43bf31f09891239b12d9d5fe624c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Wed, 16 Jan 2008 15:25:17 +0000 Subject: [PATCH] fix probleme de mauvaise connexion makefile.am utiliser _HEADERS --- slc/trunk/Makefile.am | 1 + slc/trunk/src/sll/connection.cc | 287 +++++++++++++++---------------- slc/trunk/src/sll/connection.hh | 22 +-- slc/trunk/src/sll/connection.hxx | 84 ++++++++- 4 files changed, 238 insertions(+), 156 deletions(-) diff --git a/slc/trunk/Makefile.am b/slc/trunk/Makefile.am index 939ddd8..5429848 100644 --- a/slc/trunk/Makefile.am +++ b/slc/trunk/Makefile.am @@ -30,6 +30,7 @@ noinst_SOURCES= src/slc.hh \ src/screen.hh \ src/history.hh \ src/sll/error.hh \ + src/sll/connection.hxx \ src/sll/connection.hh diff --git a/slc/trunk/src/sll/connection.cc b/slc/trunk/src/sll/connection.cc index a3ee8ca..f6b745d 100644 --- a/slc/trunk/src/sll/connection.cc +++ b/slc/trunk/src/sll/connection.cc @@ -51,7 +51,7 @@ Connection::Connection(int fd) : socket_fd_(fd), local_port_(-1), remote_port_(- if (socket_fd_ >= 0) { id_ = getconnid(); - setallinfo_(); + setconninfo_(); } } @@ -64,17 +64,68 @@ 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_); +} + +/** + * 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; +} + /** * 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_); @@ -113,7 +164,7 @@ void Connection::connect(const char *addr, int port) { } // set infos - setallinfo_(); + setconninfo_(); pthread_mutex_unlock(&w_mutex_); pthread_mutex_unlock(&r_mutex_); @@ -124,11 +175,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_); @@ -168,67 +229,37 @@ void Connection::listen(int port, int max) { } // set all infos - setallinfo_(); - - pthread_mutex_unlock(&w_mutex_); - pthread_mutex_unlock(&r_mutex_); - pthread_mutex_unlock(&c_mutex_); -} - -/** - * 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_(); + setconninfo_(); 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)); } @@ -243,9 +274,16 @@ 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) + // 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 send data"); + // send is a write operation pthread_mutex_lock(&w_mutex_); int ret = ::send(socket_fd_, buf, len, 0); pthread_mutex_unlock(&w_mutex_); @@ -260,12 +298,19 @@ void Connection::send(const char* buf, size_t len) { * 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) + // 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 send line"); + // send is a write op pthread_mutex_lock(&w_mutex_); // write data - int ret = ::send(socket_fd_, buf, len, 0); + int ret = ::send(socket_fd, buf, len, 0); if (ret == -1) { pthread_mutex_unlock(&w_mutex_); if (errno == ECONNRESET) @@ -274,7 +319,7 @@ void Connection::sendln(const char* buf, size_t len) { } // write '\n' - ret = ::send(socket_fd_, "\n", 1, 0); + ret = ::send(socket_fd, "\n", 1, 0); pthread_mutex_unlock(&w_mutex_); if (ret == -1) throw Error(ERR_NET, "sendln: " + (string) strerror(errno)); @@ -284,9 +329,16 @@ void Connection::sendln(const char* buf, size_t len) { * Receive a line */ string Connection::recvln() { - 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 receive line"); + // recv is a read opearation pthread_mutex_lock(&r_mutex_); do { // check EOL char @@ -298,13 +350,16 @@ 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) { + 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"); } @@ -327,10 +382,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_; @@ -339,10 +398,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_; @@ -351,10 +414,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_; @@ -363,10 +430,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_; @@ -379,89 +450,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); -} diff --git a/slc/trunk/src/sll/connection.hh b/slc/trunk/src/sll/connection.hh index 194cd85..1581700 100644 --- a/slc/trunk/src/sll/connection.hh +++ b/slc/trunk/src/sll/connection.hh @@ -2,17 +2,17 @@ This file is part of SLS. Copyright (C) 2008 Sebastien LUTTRINGER - 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 */ @@ -61,14 +61,14 @@ 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 setconninfo_(); + inline void setlocalip_(); + inline void setlocalport_(); + inline void setremoteip_(); + inline void setremoteport_(); // Protected datas protected: diff --git a/slc/trunk/src/sll/connection.hxx b/slc/trunk/src/sll/connection.hxx index 937ae30..c5fdf3e 100644 --- a/slc/trunk/src/sll/connection.hxx +++ b/slc/trunk/src/sll/connection.hxx @@ -16,6 +16,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +# include "error.hh" + +#include +#include +#include +#include + /******************************************************************************* ** Public method ******************************************************************************/ @@ -41,9 +48,84 @@ void Connection::sendln(const string &data) { /** * Set all information about a connection */ -void Connection::setallinfo_() { +void Connection::setconninfo_() { setlocalip_(); setlocalport_(); setremoteip_(); setremoteport_(); } + +/** + * Free a socket + * No mutex used ! + */ +void Connection::disconnect_() { + if (socket_fd_ == -1) + return; + + 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; + + ::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); +} -- GitLab