/* This file is part of SLL. Copyright (C) 2008 Sebastien LUTTRINGER 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. 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 SLLo; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ # include "error.hh" #include #include #include #include #include /******************************************************************************* ** 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 */ void Connection::send(const string &data) { send(data.c_str(), data.length()); } /** * Send @param data followed by '\n' on socket */ void Connection::sendln(const string &data) { string tosend = data + "\n"; send(tosend.c_str(), tosend.length()); } /******************************************************************************* ** Protected method ******************************************************************************/ /** * Free a socket * No mutex used ! */ 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 get 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 get 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; // get socket if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to get remote ip: " + strerror(errno)); remote_ip_ = inet_ntoa(addr.sin_addr); } /** * Set remote hostname * No mutex used ! */ void Connection::setremotehostname_() { struct sockaddr_in addr; socklen_t len = sizeof addr; // get sockaddr_in if (::getpeername(socket_fd_, (struct sockaddr*) &addr, &len) != 0) throw Error(ERR_NET, (string) "Unable to get remote ip: " + strerror(errno)); if (remote_ip_.empty()) remote_ip_ = inet_ntoa(addr.sin_addr); // get hostname struct hostent *h; if ((h = ::gethostbyaddr(&addr.sin_addr, sizeof addr.sin_addr, AF_INET)) == 0) throw Error(ERR_NET, (string) "Unable to get remote hostname: " + hstrerror(h_errno)); remote_hostname_ = h->h_name; } /** * 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 get remote port: " + strerror(errno)); remote_port_ = ntohs(addr.sin_port); }