From 6ac1fb46df8a42bdc0cb2578e5828dc0a4a7624d Mon Sep 17 00:00:00 2001 From: Reinhard Pfau Date: Sun, 31 May 2009 23:51:00 +0200 Subject: [PATCH] moved peer info fetch into UnixIOSocket; cleaned up interfaces --- asyncio/async_socket.cpp | 115 +++++++++++++++++++++--------------- asyncio/async_socket.hpp | 34 +++++------ unittest/test_simpleio_basics.cpp | 5 +- 3 files changed, 85 insertions(+), 69 deletions(-) diff --git a/asyncio/async_socket.cpp b/asyncio/async_socket.cpp index 9b23f60..3e477d4 100644 --- a/asyncio/async_socket.cpp +++ b/asyncio/async_socket.cpp @@ -19,7 +19,8 @@ on this file might be covered by the GNU General Public License. */ /** @file * - * (c) Copyright 2008 by Intra2net AG + * @copyright Copyright 2008-2009 by Intra2net AG + * @contact Intra2net Opensource Team \ * * @todo unlink unix server socket on close. */ @@ -85,7 +86,7 @@ ServerSocketBaseImplementation::ServerSocketBaseImplementation() * @brief handled incoming connections on the server port. * * accepts the new connection, stores the peer address in an internal buffer - * and calls a (derived) acceptNewConnection method to create an apropriate + * and calls a (derived) acceptNewConnection method to create an appropriate * IO class instance. * If no io instance is created the connection is closed. */ @@ -163,11 +164,11 @@ void ServerSocketBaseImplementation::doWrite() /** * @brief sets a function which is called when a new connection was established. * - * The function gets a (shared) pointer to the new connetion as parameter and is + * The function gets a (shared) pointer to the new connection as parameter and is * expected to store it when it accepts the connection. - * (Else the conenction gets deleted after the function was called.) + * (Else the connection gets deleted after the function was called.) * - * @param func the function which hsould be called on new conenctions. + * @param func the function which should be called on new connections. */ void ServerSocketBaseImplementation::setNewConnectionBaseCallback( const NewConnectionBaseCallbackFunc& func) @@ -204,33 +205,32 @@ IOImplementationPtr ServerSocketBaseImplementation::acceptNewConnection( UnixIOSocket::UnixIOSocket() -: m_peer_pid(0) -, m_peer_uid(0) -, m_peer_gid(0) +: m_peer_pid((unsigned int)-1) +, m_peer_uid((unsigned int)-1) +, m_peer_gid((unsigned int)-1) { } // eo UnixIOSocket::UnixIOSocket() UnixIOSocket::UnixIOSocket(const std::string& path) -: m_peer_pid(0) -, m_peer_uid(0) -, m_peer_gid(0) +: m_peer_pid((unsigned int)-1) +, m_peer_uid((unsigned int)-1) +, m_peer_gid((unsigned int)-1) { - open(path); + open(path); } // eo UnixIOSocket::UnixIOSocket(const std::string&) -UnixIOSocket::UnixIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, unsigned int peer_uid, unsigned int peer_gid) +UnixIOSocket::UnixIOSocket(int fd,const std::string& path) : IOImplementation(fd,fd) , m_path(path) -, m_peer_pid(peer_pid) -, m_peer_uid(peer_uid) -, m_peer_gid(peer_gid) +, m_peer_pid((unsigned int)-1) +, m_peer_uid((unsigned int)-1) +, m_peer_gid((unsigned int)-1) { -} // eo UnixIOSocket::UnixIOSocket(int,const std::string&,unsigned,unsigned,unsigned) + update_peer_information(fd); +} // eo UnixIOSocket::UnixIOSocket(int,const std::string&) /** @@ -276,6 +276,42 @@ bool UnixIOSocket::open(const std::string& path) } // eo UnixIOSocket::open(const std::string&,int) +/** + * @brief update the peer info (pid,gid,uid). + * @param fd the socket to update the information for. + * @return @a true if succesfully determined the peer info. + * + * @note if the peer info could not be detected the values are set to + * (unsigned int)(-1). + */ +bool UnixIOSocket::update_peer_information(int fd) +{ + m_peer_pid=(unsigned int)-1; + m_peer_gid=(unsigned int)-1; + m_peer_uid=(unsigned int)-1; + + //TODO add more versions of getting the peer information here... + // BSD systems seems to have SO_PEERCRED,too (does someone know how it is used there?) + + #ifdef __linux__ + { // the linux way to get peer info (pid,gid,uid): + struct ucred cred; + socklen_t cred_len = sizeof(cred); + if (getsockopt(fd,SOL_SOCKET,SO_PEERCRED,&cred,&cred_len) == 0) + { + m_peer_pid= cred.pid; + m_peer_uid= cred.uid; + m_peer_gid= cred.gid; + return true; + } + } + #else + #warning dont know how to determine peer info. + #endif + return false; +} // end of UnixIOSocketupdate_peer_information(int) + + /* ** implementation of UnixServerSocketBase */ @@ -320,6 +356,8 @@ bool UnixServerSocketBase::open(const std::string& path, int mode) addr.m_addr_un.sun_family= AF_UNIX; strncpy(addr.m_addr_un.sun_path, path.c_str(), PATH_MAX); Utils::unlink(path); // just in case... + // NOTE this is a place which might require some updates for multithreaded + // usage! (setting the umask affects all threads...) mode_t old_mask= ::umask( (mode & 0777) ^ 0777); if (::bind(fd,(sockaddr*)&addr.m_addr_un, SUN_LEN(&addr.m_addr_un)) < 0) { @@ -353,8 +391,8 @@ bool UnixServerSocketBase::open(const std::string& path, int mode) * It also tries to determine the peer pid, uid and gid. * * @param fd the file descriptor of a freshly accepted connection. - * @param addr conatins "pointer to struct sockaddr" - * @return @a a (shared) pointer to the new connection isntance; empty if none was + * @param addr contains "pointer to struct sockaddr" + * @return @a a (shared) pointer to the new connection instance; empty if none was * created. */ IOImplementationPtr UnixServerSocketBase::acceptNewConnection(int fd, boost::any addr) @@ -374,25 +412,9 @@ IOImplementationPtr UnixServerSocketBase::acceptNewConnection(int fd, boost::any } struct sockaddr_un *un_ptr = reinterpret_cast(addr_ptr); std::string peer_path( un_ptr->sun_path ); - unsigned peer_pid=0; - unsigned peer_gid=0; - unsigned peer_uid=0; -#ifdef __linux__ - { // the linux way to get peer info (pid,gid,uid): - struct ucred cred; - socklen_t cred_len = sizeof(cred); - if (getsockopt(fd,SOL_SOCKET,SO_PEERCRED,&cred,&cred_len) == 0) - { - peer_pid= cred.pid; - peer_uid= cred.uid; - peer_gid= cred.gid; - } - } -#else -#error dont know how to determine peer info. -#endif - UnixIOSocketPtr ptr( createIOSocket(fd, peer_path, peer_pid, peer_uid, peer_gid) ); + UnixIOSocketPtr ptr( createIOSocket(fd, peer_path) ); + return ptr; } // eo UnixServerSocketBase::acceptNewConnection(int,boost::any); @@ -404,20 +426,17 @@ IOImplementationPtr UnixServerSocketBase::acceptNewConnection(int fd, boost::any * * @param fd file descriptor for the socket * @param path path as delivered by peer. - * @param peer_pid peer pid. - * @param peer_uid peer uid. - * @param peer_gid peer gid. * @return (shared) pointer to the new io instance. */ UnixIOSocketPtr UnixServerSocketBase::createIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, - unsigned int peer_uid, unsigned int peer_gid) + int fd, const std::string& path +) { - return UnixIOSocketPtr( - new UnixIOSocket(fd, path, peer_pid, peer_uid, peer_gid) + return UnixIOSocketPtr + ( + new UnixIOSocket(fd, path) ); -} // eo UnixServerSocketBase::createIOSocket(int,const std::string&,unsigned,unsigned,unsigned) +} // eo UnixServerSocketBase::createIOSocket(int,const std::string&) diff --git a/asyncio/async_socket.hpp b/asyncio/async_socket.hpp index 0849689..3121f70 100644 --- a/asyncio/async_socket.hpp +++ b/asyncio/async_socket.hpp @@ -20,13 +20,15 @@ on this file might be covered by the GNU General Public License. /** @file * @brief socket classes for the AsyncIo framework. * - * (c) Copyright 2008 by Intra2net AG + * @copyright Copyright 2008-2009 by Intra2net AG + * @contact Intra2net Opensource Team \ */ -#ifndef __SIMPLEIO__SIMPLESOCKET_HPP__ -#define __SIMPLEIO__SIMPLESOCKET_HPP__ +#ifndef __ASYNC_SOCKET_HPP__ +#define __ASYNC_SOCKET_HPP__ #include "async_io.hpp" +#include "asyncio_system_tools.hpp" #include #include @@ -91,7 +93,7 @@ class UnixServerSocket; /** - * @brief spezialized IO class for unix domain sockets. + * @brief specialized IO class for unix domain sockets. * */ class UnixIOSocket @@ -107,9 +109,9 @@ class UnixIOSocket friend class UnixServerSocketBase; friend class UnixServerSocket; - UnixIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, unsigned int peer_uid, unsigned int peer_gid); + UnixIOSocket(int fd, const std::string& path); + + bool update_peer_information(int fd); protected: @@ -125,7 +127,7 @@ typedef boost::shared_ptr< UnixIOSocket > UnixIOSocketPtr; /** - * @brief spezialized server socket class for unix domain sockets. + * @brief specialized server socket class for unix domain sockets. * */ class UnixServerSocketBase @@ -141,10 +143,7 @@ class UnixServerSocketBase virtual IOImplementationPtr acceptNewConnection(int fd, boost::any addr); - virtual UnixIOSocketPtr createIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, - unsigned int peer_uid, unsigned int peer_gid); + virtual UnixIOSocketPtr createIOSocket(int fd, const std::string& path); protected: @@ -156,7 +155,7 @@ class UnixServerSocketBase /** * @brief unix server socket class which "produces" connections of a determined type. * - + @param IOClass the type of the connections. + * @param IOClass the type of the connections. */ template< class IOClass @@ -205,12 +204,10 @@ class UnixServerSocket protected: virtual UnixIOSocketPtr createIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, - unsigned int peer_uid, unsigned int peer_gid) + int fd, const std::string& path) { return UnixIOSocketPtr( - new IOClass(fd, path, peer_pid, peer_uid, peer_gid) + new IOClass(fd, path) ); } @@ -222,7 +219,8 @@ class UnixServerSocket }; // eo class UnixServerSocket -}// eo namespace AsyncIo + +}// end of namespace AsyncIo #endif diff --git a/unittest/test_simpleio_basics.cpp b/unittest/test_simpleio_basics.cpp index a82a75d..51549bb 100644 --- a/unittest/test_simpleio_basics.cpp +++ b/unittest/test_simpleio_basics.cpp @@ -237,10 +237,9 @@ class TestUnixIOSocket TestUnixIOSocket( - int fd, const std::string& path, - unsigned int peer_pid, unsigned int peer_uid, unsigned int peer_gid + int fd, const std::string& path ) - : UnixIOSocket(fd, path, peer_pid, peer_uid, peer_gid) + : UnixIOSocket(fd, path) { m_signal_read.connect( boost::bind(&TestUnixIOSocket::slotReceivedData, this) ); } // eo TestUnixIOSocket() -- 1.7.1