1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// --------------------------------------------------------------------------
//
// File
// Name: Socket.cpp
// Purpose: Socket related stuff
// Created: 2003/07/31
//
// --------------------------------------------------------------------------
#include "Box.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#ifndef WIN32
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <string.h>
#include <stdio.h>
#include "autogen_ConnectionException.h"
#include "autogen_ServerException.h"
#include "Socket.h"
#include "MemLeakFindOn.h"
// --------------------------------------------------------------------------
//
// Function
// Name: Socket::NameLookupToSockAddr(SocketAllAddr &, int,
// char *, int)
// Purpose: Sets up a sockaddr structure given a name and type
// Created: 2003/07/31
//
// --------------------------------------------------------------------------
void Socket::NameLookupToSockAddr(SocketAllAddr &addr, int &sockDomain,
enum Type Type, const std::string& rName, int Port,
int &rSockAddrLenOut)
{
int sockAddrLen = 0;
switch(Type)
{
case TypeINET:
sockDomain = AF_INET;
{
// Lookup hostname
struct hostent *phost = ::gethostbyname(rName.c_str());
if(phost != NULL)
{
if(phost->h_addr_list[0] != 0)
{
sockAddrLen = sizeof(addr.sa_inet);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
addr.sa_inet.sin_len = sizeof(addr.sa_inet);
#endif
addr.sa_inet.sin_family = PF_INET;
addr.sa_inet.sin_port = htons(Port);
addr.sa_inet.sin_addr = *((in_addr*)phost->h_addr_list[0]);
for(unsigned int l = 0; l < sizeof(addr.sa_inet.sin_zero); ++l)
{
addr.sa_inet.sin_zero[l] = 0;
}
}
else
{
THROW_EXCEPTION(ConnectionException, SocketNameLookupError);
}
}
else
{
THROW_EXCEPTION(ConnectionException, SocketNameLookupError);
}
}
break;
#ifndef WIN32
case TypeUNIX:
sockDomain = AF_UNIX;
{
// Check length of name is OK
unsigned int nameLen = rName.length();
if(nameLen >= (sizeof(addr.sa_unix.sun_path) - 1))
{
THROW_EXCEPTION(ServerException, SocketNameUNIXPathTooLong);
}
sockAddrLen = nameLen + (((char*)(&(addr.sa_unix.sun_path[0]))) - ((char*)(&addr.sa_unix)));
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
addr.sa_unix.sun_len = sockAddrLen;
#endif
addr.sa_unix.sun_family = PF_UNIX;
::strncpy(addr.sa_unix.sun_path, rName.c_str(),
sizeof(addr.sa_unix.sun_path) - 1);
addr.sa_unix.sun_path[sizeof(addr.sa_unix.sun_path)-1] = 0;
}
break;
#endif
default:
THROW_EXCEPTION(CommonException, BadArguments)
break;
}
// Return size of structure to caller
rSockAddrLenOut = sockAddrLen;
}
// --------------------------------------------------------------------------
//
// Function
// Name: Socket::LogIncomingConnection(const struct sockaddr *, socklen_t)
// Purpose: Writes a message logging the connection to syslog
// Created: 2003/08/01
//
// --------------------------------------------------------------------------
void Socket::LogIncomingConnection(const struct sockaddr *addr, socklen_t addrlen)
{
BOX_INFO("Incoming connection from " <<
IncomingConnectionLogMessage(addr, addrlen));
}
// --------------------------------------------------------------------------
//
// Function
// Name: Socket::IncomingConnectionLogMessage(const struct sockaddr *, socklen_t)
// Purpose: Returns a string for use in log messages
// Created: 2003/08/01
//
// --------------------------------------------------------------------------
std::string Socket::IncomingConnectionLogMessage(const struct sockaddr *addr, socklen_t addrlen)
{
if(addr == NULL) {THROW_EXCEPTION(CommonException, BadArguments)}
switch(addr->sa_family)
{
case AF_UNIX:
return std::string("local (UNIX socket)");
break;
case AF_INET:
{
sockaddr_in *a = (sockaddr_in*)addr;
std::ostringstream oss;
oss << inet_ntoa(a->sin_addr) << " port " <<
ntohs(a->sin_port);
return oss.str();
}
break;
default:
{
std::ostringstream oss;
oss << "unknown socket type " << addr->sa_family;
return oss.str();
}
break;
}
// Dummy.
return std::string();
}
|