Commit e6982f80 authored by Seblu's avatar Seblu

fix race cond on connection

del sigpipe from connection
fix memleak from server
parent f0770771
......@@ -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;
}
......@@ -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";
......@@ -189,5 +190,7 @@ void *Server::start_client(void *voidconn) {
S.threads_.erase(t);
pthread_mutex_unlock(&S.threads_mutex_);
delete conn;
return 0;
}
This diff is collapsed.
......@@ -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
*/
......@@ -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();
......@@ -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:
......
......@@ -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
*/
......@@ -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());
}
/*******************************************************************************
......@@ -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);
}
......@@ -45,6 +45,7 @@ enum {
ERR_SRV = 8,
ERR_THREAD = 9,
ERR_PARSE = 10,
ERR_SCREENSZ = 11,
ERR_NOMEM = 41,
ERR_UNKNOWN = 42
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment