diff --git a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp index 8904579cb62595e359cfdf6565b3a8b1c771e015..1d5318c6a252a07e369453563f06b418dcf30423 100644 --- a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp +++ b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.cpp @@ -19,6 +19,7 @@ * @author Castor Dev team, castor-dev@cern.ch *****************************************************************************/ +#include "castor/exception/Exception.hpp" #include "castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp" #include "castor/utils/utils.hpp" #include "h/common.h" @@ -129,7 +130,19 @@ void castor::tape::tapeserver::daemon::VdqmConnectionHandler:: //------------------------------------------------------------------------------ // connectionIsAuthorized //------------------------------------------------------------------------------ -bool castor::tape::tapeserver::daemon::VdqmConnectionHandler::connectionIsAuthorized() throw() { +bool castor::tape::tapeserver::daemon::VdqmConnectionHandler:: + connectionIsAuthorized() throw() { + try { + const std::string peerHost = getPeerHostName(m_fd); + const std::string thisHost = getSockHostName(m_fd); + + log::Param params[] = { + log::Param("peerHost", peerHost), + log::Param("thisHost", thisHost)}; + m_log(LOG_INFO, "Received connection" ,params); + } catch(...) { + } + // isadminhost fills in peerHost char peerHost[CA_MAXHOSTNAMELEN+1]; memset(peerHost, '\0', sizeof(peerHost)); @@ -164,6 +177,117 @@ bool castor::tape::tapeserver::daemon::VdqmConnectionHandler::connectionIsAuthor } } +//------------------------------------------------------------------------------ +// getPeerHostName +//------------------------------------------------------------------------------ +std::string castor::tape::tapeserver::daemon::VdqmConnectionHandler:: + getPeerHostName(const int sockFd) { + try { + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + getPeerName(sockFd, (struct sockaddr *)&addr, &addrLen); + + char host[NI_MAXHOST]; + getNameInfo((struct sockaddr *)&addr, addrLen, host, sizeof(host), NULL, 0, + NI_NAMEREQD); + + return host; + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "getPeerHostName() failed: " << ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// getPeerName +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::VdqmConnectionHandler::getPeerName( + const int sockFd, struct sockaddr *const addr, socklen_t *const addrLen) { + if(getpeername(sockFd, addr, addrLen)) { + const std::string errMsg = castor::utils::errnoToString(errno); + castor::exception::Exception ex; + ex.getMessage() << "getpeername failed: sockFd=" << sockFd << ": " << + errMsg; + throw ex; + } +} + +//------------------------------------------------------------------------------ +// getNameInfo +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::VdqmConnectionHandler::getNameInfo( + const struct sockaddr *const sa, + const socklen_t saLen, + char *const host, + const size_t hostLen, + char *const serv, + const size_t servLen, + const int flags) { + const int rc = getnameinfo(sa, saLen, host, hostLen, serv, servLen, flags); + if(rc) { + const std::string errMsg = getNameInfoRcToString(rc); + castor::exception::Exception ex; + ex.getMessage() << "getnameinfo failed: " << errMsg; + throw ex; + } +} + +//------------------------------------------------------------------------------ +// getNameInfoRcToString +//------------------------------------------------------------------------------ +const char *castor::tape::tapeserver::daemon::VdqmConnectionHandler:: + getNameInfoRcToString(const int rc) { + switch(rc) { + case 0: return "Success"; + case EAI_AGAIN: return "Try again"; + case EAI_BADFLAGS: return "Invalid flags"; + case EAI_FAIL: return "Non-recoverable error"; + case EAI_FAMILY: return "Invalid address family"; + case EAI_MEMORY: return "Out of memory"; + case EAI_NONAME: return "Name does not resolve"; + case EAI_OVERFLOW: return "Either host of serv buffer was too small"; + case EAI_SYSTEM: return "System error"; + default: return "Unknown"; + } +} + +//------------------------------------------------------------------------------ +// getSockHostName +//------------------------------------------------------------------------------ +std::string castor::tape::tapeserver::daemon::VdqmConnectionHandler:: + getSockHostName(const int sockFd) { + try { + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + getSockName(sockFd, (struct sockaddr *)&addr, &addrLen); + + char host[NI_MAXHOST]; + getNameInfo((struct sockaddr *)&addr, addrLen, host, sizeof(host), NULL, 0, + NI_NAMEREQD); + + return host; + } catch(castor::exception::Exception &ne) { + castor::exception::Exception ex; + ex.getMessage() << "getSockHostName() failed: " << ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// getSockName +//------------------------------------------------------------------------------ +void castor::tape::tapeserver::daemon::VdqmConnectionHandler::getSockName( + const int sockFd, struct sockaddr *const addr, socklen_t *const addrLen) { + if(getsockname(sockFd, addr, addrLen)) { + const std::string errMsg = castor::utils::errnoToString(errno); + castor::exception::Exception ex; + ex.getMessage() << "getsockname failed: sockFd=" << sockFd << ": " << + errMsg; + throw ex; + } +} + //------------------------------------------------------------------------------ // logVdqmJobReception //------------------------------------------------------------------------------ diff --git a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp index 9520ff40e3acc423526e1641afbfaa23166773a3..ab9cca627f3e75456961d708eec13ed188915574 100644 --- a/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp +++ b/castor/tape/tapeserver/daemon/VdqmConnectionHandler.hpp @@ -133,6 +133,75 @@ private: */ bool connectionIsAuthorized() throw(); + /** + * Returns the host name of the peer the specified socket. + * + * @param sockFd The file descriptor of the socket. + */ + std::string getPeerHostName(const int sockFd); + + /** + * C++ wrapper around the C function getpeername(). This wrapper converts an + * error into an exception. + * + * @param sockFd The file descriptor of the socket. + * @param addr Out parameter: The peer address. + * @param addrLen In/Out parameter: The length of the peer address passed in and + * the final length when passed back out. + */ + void getPeerName(const int sockFd, struct sockaddr *const addr, + socklen_t *const addrLen); + + /** + * C++ wrapper around the C function getaddrinfo(). This wrapper converts an + * error into an exception. + * + * @param sa See the manual page of getnameinfo(). + * @param saLen See the manual page of getnameinfo(). + * @param host See the manual page of getnameinfo(). + * @param hostLen See the manual page of getnameinfo(). + * @param serv See the manual page of getnameinfo(). + * @param servLen See the manual page of getnameinfo(). + * @param flags See the manual page of getnameinfo(). + */ + void getNameInfo( + const struct sockaddr *const sa, + const socklen_t saLen, + char *const host, + const size_t hostLen, + char *const serv, + const size_t servLen, + const int flags); + + /** + * Thread-safe method that returns a string reprsentation of the specified + * integer value returned by a call to the C function getnameinfo(). + * + * @param rc The integer return value; + * @return The string representation of the integer return value. + */ + const char *getNameInfoRcToString(const int rc); + + /** + * Returns the host name of this end (as apposed to the peer end) of the + * specified socket. + * + * @param sockFd The file descriptor of the socket. + */ + std::string getSockHostName(const int sockFd); + + /** + * C++ wrapper around the C function getsockname(). This wrapper converts an + * error into an exception. + * + * @param sockFd The file descriptor of the socket. + * @param addr Out parameter: The address. + * @param addrLen In/Out parameter: The length of the address passed in and + * the final length when passed back out. + */ + void getSockName(const int sockFd, struct sockaddr *const addr, + socklen_t *const addrLen); + /** * Logs the reception of the specified job message from the vdqmd daemon. */